mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-09-30 12:27:29 +09:00
parent
470a6e4401
commit
13fcc4a046
949 changed files with 95662 additions and 444 deletions
|
|
@ -35,10 +35,10 @@ EPlatformDisabledState PlatformDisabledState();
|
|||
void PreInit();
|
||||
#endif
|
||||
|
||||
#if defined(MOZ_ACCESSIBILITY_ATK)
|
||||
#if defined(MOZ_ACCESSIBILITY_ATK) || defined(XP_MACOSX)
|
||||
/**
|
||||
* Is platform accessibility enabled.
|
||||
* Only used on linux with atk.
|
||||
* Only used on linux with atk and MacOS for now.
|
||||
*/
|
||||
bool ShouldA11yBeEnabled();
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -96,6 +96,10 @@ elif CONFIG['MOZ_WIDGET_TOOLKIT'] == 'windows':
|
|||
'/accessible/windows/ia2',
|
||||
'/accessible/windows/msaa',
|
||||
]
|
||||
elif CONFIG['MOZ_WIDGET_TOOLKIT'] == 'cocoa':
|
||||
LOCAL_INCLUDES += [
|
||||
'/accessible/mac',
|
||||
]
|
||||
else:
|
||||
LOCAL_INCLUDES += [
|
||||
'/accessible/other',
|
||||
|
|
|
|||
|
|
@ -52,6 +52,10 @@ elif CONFIG['MOZ_WIDGET_TOOLKIT'] == 'windows':
|
|||
'/accessible/windows/ia2',
|
||||
'/accessible/windows/msaa',
|
||||
]
|
||||
elif CONFIG['MOZ_WIDGET_TOOLKIT'] == 'cocoa':
|
||||
LOCAL_INCLUDES += [
|
||||
'/accessible/mac',
|
||||
]
|
||||
else:
|
||||
LOCAL_INCLUDES += [
|
||||
'/accessible/other',
|
||||
|
|
|
|||
|
|
@ -32,6 +32,10 @@ elif CONFIG['MOZ_WIDGET_TOOLKIT'] == 'windows':
|
|||
'/accessible/windows/ia2',
|
||||
'/accessible/windows/msaa',
|
||||
]
|
||||
elif CONFIG['MOZ_WIDGET_TOOLKIT'] == 'cocoa':
|
||||
LOCAL_INCLUDES += [
|
||||
'/accessible/mac',
|
||||
]
|
||||
else:
|
||||
LOCAL_INCLUDES += [
|
||||
'/accessible/other',
|
||||
|
|
|
|||
|
|
@ -19,6 +19,10 @@ else:
|
|||
LOCAL_INCLUDES += [
|
||||
'/accessible/atk',
|
||||
]
|
||||
elif CONFIG['MOZ_WIDGET_TOOLKIT'] == 'cocoa':
|
||||
LOCAL_INCLUDES += [
|
||||
'/accessible/mac',
|
||||
]
|
||||
else:
|
||||
LOCAL_INCLUDES += [
|
||||
'/accessible/other',
|
||||
|
|
|
|||
|
|
@ -28,6 +28,10 @@ if CONFIG['ACCESSIBILITY']:
|
|||
LOCAL_INCLUDES += [
|
||||
'/accessible/atk',
|
||||
]
|
||||
elif CONFIG['MOZ_WIDGET_TOOLKIT'] == 'cocoa':
|
||||
LOCAL_INCLUDES += [
|
||||
'/accessible/mac',
|
||||
]
|
||||
else:
|
||||
LOCAL_INCLUDES += [
|
||||
'/accessible/other',
|
||||
|
|
|
|||
22
accessible/mac/ARIAGridAccessibleWrap.h
Normal file
22
accessible/mac/ARIAGridAccessibleWrap.h
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim:expandtab:shiftwidth=2:tabstop=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/. */
|
||||
|
||||
#ifndef MOZILLA_A11Y_ARIAGRIDACCESSIBLEWRAP_H
|
||||
#define MOZILLA_A11Y_ARIAGRIDACCESSIBLEWRAP_H
|
||||
|
||||
#include "ARIAGridAccessible.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace a11y {
|
||||
|
||||
typedef class ARIAGridAccessible ARIAGridAccessibleWrap;
|
||||
typedef class ARIAGridCellAccessible ARIAGridCellAccessibleWrap;
|
||||
|
||||
} // namespace a11y
|
||||
} // namespace mozilla
|
||||
|
||||
#endif
|
||||
103
accessible/mac/AccessibleWrap.h
Normal file
103
accessible/mac/AccessibleWrap.h
Normal file
|
|
@ -0,0 +1,103 @@
|
|||
/* -*- 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/. */
|
||||
|
||||
/* For documentation of the accessibility architecture,
|
||||
* see http://lxr.mozilla.org/seamonkey/source/accessible/accessible-docs.html
|
||||
*/
|
||||
|
||||
#ifndef _AccessibleWrap_H_
|
||||
#define _AccessibleWrap_H_
|
||||
|
||||
#include <objc/objc.h>
|
||||
|
||||
#include "Accessible.h"
|
||||
#include "States.h"
|
||||
|
||||
#include "nsCOMPtr.h"
|
||||
|
||||
#include "nsTArray.h"
|
||||
|
||||
#if defined(__OBJC__)
|
||||
@class mozAccessible;
|
||||
#endif
|
||||
|
||||
namespace mozilla {
|
||||
namespace a11y {
|
||||
|
||||
class AccessibleWrap : public Accessible
|
||||
{
|
||||
public: // construction, destruction
|
||||
AccessibleWrap(nsIContent* aContent, DocAccessible* aDoc);
|
||||
virtual ~AccessibleWrap();
|
||||
|
||||
/**
|
||||
* Get the native Obj-C object (mozAccessible).
|
||||
*/
|
||||
virtual void GetNativeInterface(void** aOutAccessible) override;
|
||||
|
||||
/**
|
||||
* The objective-c |Class| type that this accessible's native object
|
||||
* should be instantied with. used on runtime to determine the
|
||||
* right type for this accessible's associated native object.
|
||||
*/
|
||||
virtual Class GetNativeType ();
|
||||
|
||||
virtual void Shutdown () override;
|
||||
|
||||
virtual bool InsertChildAt(uint32_t aIdx, Accessible* aChild) override;
|
||||
virtual bool RemoveChild(Accessible* aAccessible) override;
|
||||
|
||||
virtual nsresult HandleAccEvent(AccEvent* aEvent) override;
|
||||
|
||||
protected:
|
||||
|
||||
/**
|
||||
* Return true if the parent doesn't have children to expose to AT.
|
||||
*/
|
||||
bool AncestorIsFlat();
|
||||
|
||||
/**
|
||||
* Get the native object. Create it if needed.
|
||||
*/
|
||||
#if defined(__OBJC__)
|
||||
mozAccessible* GetNativeObject();
|
||||
#else
|
||||
id GetNativeObject();
|
||||
#endif
|
||||
|
||||
private:
|
||||
|
||||
/**
|
||||
* Our native object. Private because its creation is done lazily.
|
||||
* Don't access it directly. Ever. Unless you are GetNativeObject() or
|
||||
* Shutdown()
|
||||
*/
|
||||
#if defined(__OBJC__)
|
||||
// if we are in Objective-C, we use the actual Obj-C class.
|
||||
mozAccessible* mNativeObject;
|
||||
#else
|
||||
id mNativeObject;
|
||||
#endif
|
||||
|
||||
/**
|
||||
* We have created our native. This does not mean there is one.
|
||||
* This can never go back to false.
|
||||
* We need it because checking whether we need a native object cost time.
|
||||
*/
|
||||
bool mNativeInited;
|
||||
};
|
||||
|
||||
#if defined(__OBJC__)
|
||||
void FireNativeEvent(mozAccessible* aNativeAcc, uint32_t aEventType);
|
||||
#else
|
||||
void FireNativeEvent(id aNativeAcc, uint32_t aEventType);
|
||||
#endif
|
||||
|
||||
Class GetTypeFromRole(roles::Role aRole);
|
||||
|
||||
} // namespace a11y
|
||||
} // namespace mozilla
|
||||
|
||||
#endif
|
||||
256
accessible/mac/AccessibleWrap.mm
Normal file
256
accessible/mac/AccessibleWrap.mm
Normal file
|
|
@ -0,0 +1,256 @@
|
|||
/* -*- Mode: 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/. */
|
||||
|
||||
#include "DocAccessible.h"
|
||||
#include "nsObjCExceptions.h"
|
||||
|
||||
#include "Accessible-inl.h"
|
||||
#include "nsAccUtils.h"
|
||||
#include "Role.h"
|
||||
|
||||
#import "mozAccessible.h"
|
||||
#import "mozActionElements.h"
|
||||
#import "mozHTMLAccessible.h"
|
||||
#import "mozTableAccessible.h"
|
||||
#import "mozTextAccessible.h"
|
||||
|
||||
using namespace mozilla;
|
||||
using namespace mozilla::a11y;
|
||||
|
||||
AccessibleWrap::
|
||||
AccessibleWrap(nsIContent* aContent, DocAccessible* aDoc) :
|
||||
Accessible(aContent, aDoc), mNativeObject(nil),
|
||||
mNativeInited(false)
|
||||
{
|
||||
}
|
||||
|
||||
AccessibleWrap::~AccessibleWrap()
|
||||
{
|
||||
}
|
||||
|
||||
mozAccessible*
|
||||
AccessibleWrap::GetNativeObject()
|
||||
{
|
||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
|
||||
|
||||
if (!mNativeInited && !mNativeObject && !IsDefunct() && !AncestorIsFlat()) {
|
||||
uintptr_t accWrap = reinterpret_cast<uintptr_t>(this);
|
||||
mNativeObject = [[GetNativeType() alloc] initWithAccessible:accWrap];
|
||||
}
|
||||
|
||||
mNativeInited = true;
|
||||
|
||||
return mNativeObject;
|
||||
|
||||
NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
|
||||
}
|
||||
|
||||
void
|
||||
AccessibleWrap::GetNativeInterface(void** aOutInterface)
|
||||
{
|
||||
*aOutInterface = static_cast<void*>(GetNativeObject());
|
||||
}
|
||||
|
||||
// overridden in subclasses to create the right kind of object. by default we create a generic
|
||||
// 'mozAccessible' node.
|
||||
Class
|
||||
AccessibleWrap::GetNativeType ()
|
||||
{
|
||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
|
||||
|
||||
if (IsXULTabpanels())
|
||||
return [mozPaneAccessible class];
|
||||
|
||||
if (IsTable())
|
||||
return [mozTableAccessible class];
|
||||
|
||||
if (IsTableRow())
|
||||
return [mozTableRowAccessible class];
|
||||
|
||||
if (IsTableCell())
|
||||
return [mozTableCellAccessible class];
|
||||
|
||||
return GetTypeFromRole(Role());
|
||||
|
||||
NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
|
||||
}
|
||||
|
||||
// this method is very important. it is fired when an accessible object "dies". after this point
|
||||
// the object might still be around (because some 3rd party still has a ref to it), but it is
|
||||
// in fact 'dead'.
|
||||
void
|
||||
AccessibleWrap::Shutdown ()
|
||||
{
|
||||
// this ensure we will not try to re-create the native object.
|
||||
mNativeInited = true;
|
||||
|
||||
// we really intend to access the member directly.
|
||||
if (mNativeObject) {
|
||||
[mNativeObject expire];
|
||||
[mNativeObject release];
|
||||
mNativeObject = nil;
|
||||
}
|
||||
|
||||
Accessible::Shutdown();
|
||||
}
|
||||
|
||||
nsresult
|
||||
AccessibleWrap::HandleAccEvent(AccEvent* aEvent)
|
||||
{
|
||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT;
|
||||
|
||||
nsresult rv = Accessible::HandleAccEvent(aEvent);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
if (IPCAccessibilityActive()) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
uint32_t eventType = aEvent->GetEventType();
|
||||
|
||||
// ignore everything but focus-changed, value-changed, caret, selection
|
||||
// and document load complete events for now.
|
||||
if (eventType != nsIAccessibleEvent::EVENT_FOCUS &&
|
||||
eventType != nsIAccessibleEvent::EVENT_VALUE_CHANGE &&
|
||||
eventType != nsIAccessibleEvent::EVENT_TEXT_VALUE_CHANGE &&
|
||||
eventType != nsIAccessibleEvent::EVENT_TEXT_CARET_MOVED &&
|
||||
eventType != nsIAccessibleEvent::EVENT_TEXT_SELECTION_CHANGED &&
|
||||
eventType != nsIAccessibleEvent::EVENT_DOCUMENT_LOAD_COMPLETE)
|
||||
return NS_OK;
|
||||
|
||||
Accessible* accessible = aEvent->GetAccessible();
|
||||
NS_ENSURE_STATE(accessible);
|
||||
|
||||
mozAccessible *nativeAcc = nil;
|
||||
accessible->GetNativeInterface((void**)&nativeAcc);
|
||||
if (!nativeAcc)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
FireNativeEvent(nativeAcc, eventType);
|
||||
|
||||
return NS_OK;
|
||||
|
||||
NS_OBJC_END_TRY_ABORT_BLOCK_NSRESULT;
|
||||
}
|
||||
|
||||
bool
|
||||
AccessibleWrap::InsertChildAt(uint32_t aIdx, Accessible* aAccessible)
|
||||
{
|
||||
bool inserted = Accessible::InsertChildAt(aIdx, aAccessible);
|
||||
if (inserted && mNativeObject)
|
||||
[mNativeObject appendChild:aAccessible];
|
||||
|
||||
return inserted;
|
||||
}
|
||||
|
||||
bool
|
||||
AccessibleWrap::RemoveChild(Accessible* aAccessible)
|
||||
{
|
||||
bool removed = Accessible::RemoveChild(aAccessible);
|
||||
|
||||
if (removed && mNativeObject)
|
||||
[mNativeObject invalidateChildren];
|
||||
|
||||
return removed;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// AccessibleWrap protected
|
||||
|
||||
bool
|
||||
AccessibleWrap::AncestorIsFlat()
|
||||
{
|
||||
// We don't create a native object if we're child of a "flat" accessible;
|
||||
// for example, on OS X buttons shouldn't have any children, because that
|
||||
// makes the OS confused.
|
||||
//
|
||||
// To maintain a scripting environment where the XPCOM accessible hierarchy
|
||||
// look the same on all platforms, we still let the C++ objects be created
|
||||
// though.
|
||||
|
||||
Accessible* parent = Parent();
|
||||
while (parent) {
|
||||
if (nsAccUtils::MustPrune(parent))
|
||||
return true;
|
||||
|
||||
parent = parent->Parent();
|
||||
}
|
||||
// no parent was flat
|
||||
return false;
|
||||
}
|
||||
|
||||
void
|
||||
a11y::FireNativeEvent(mozAccessible* aNativeAcc, uint32_t aEventType)
|
||||
{
|
||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK;
|
||||
|
||||
switch (aEventType) {
|
||||
case nsIAccessibleEvent::EVENT_FOCUS:
|
||||
[aNativeAcc didReceiveFocus];
|
||||
break;
|
||||
case nsIAccessibleEvent::EVENT_VALUE_CHANGE:
|
||||
case nsIAccessibleEvent::EVENT_TEXT_VALUE_CHANGE:
|
||||
[aNativeAcc valueDidChange];
|
||||
break;
|
||||
case nsIAccessibleEvent::EVENT_TEXT_CARET_MOVED:
|
||||
case nsIAccessibleEvent::EVENT_TEXT_SELECTION_CHANGED:
|
||||
[aNativeAcc selectedTextDidChange];
|
||||
break;
|
||||
case nsIAccessibleEvent::EVENT_DOCUMENT_LOAD_COMPLETE:
|
||||
[aNativeAcc documentLoadComplete];
|
||||
break;
|
||||
}
|
||||
|
||||
NS_OBJC_END_TRY_ABORT_BLOCK;
|
||||
}
|
||||
|
||||
Class
|
||||
a11y::GetTypeFromRole(roles::Role aRole)
|
||||
{
|
||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
|
||||
|
||||
switch (aRole) {
|
||||
case roles::COMBOBOX:
|
||||
case roles::PUSHBUTTON:
|
||||
case roles::SPLITBUTTON:
|
||||
case roles::TOGGLE_BUTTON:
|
||||
{
|
||||
return [mozButtonAccessible class];
|
||||
}
|
||||
|
||||
case roles::PAGETAB:
|
||||
return [mozButtonAccessible class];
|
||||
|
||||
case roles::CHECKBUTTON:
|
||||
return [mozCheckboxAccessible class];
|
||||
|
||||
case roles::HEADING:
|
||||
return [mozHeadingAccessible class];
|
||||
|
||||
case roles::PAGETABLIST:
|
||||
return [mozTabsAccessible class];
|
||||
|
||||
case roles::ENTRY:
|
||||
case roles::STATICTEXT:
|
||||
case roles::CAPTION:
|
||||
case roles::ACCEL_LABEL:
|
||||
case roles::PASSWORD_TEXT:
|
||||
// normal textfield (static or editable)
|
||||
return [mozTextAccessible class];
|
||||
|
||||
case roles::TEXT_LEAF:
|
||||
return [mozTextLeafAccessible class];
|
||||
|
||||
case roles::LINK:
|
||||
return [mozLinkAccessible class];
|
||||
|
||||
default:
|
||||
return [mozAccessible class];
|
||||
}
|
||||
|
||||
return nil;
|
||||
|
||||
NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
|
||||
}
|
||||
22
accessible/mac/ApplicationAccessibleWrap.h
Normal file
22
accessible/mac/ApplicationAccessibleWrap.h
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/* vim:expandtab:shiftwidth=4:tabstop=4:
|
||||
*/
|
||||
/* 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/. */
|
||||
|
||||
#ifndef mozilla_a11y_ApplicationAccessibleWrap_h__
|
||||
#define mozilla_a11y_ApplicationAccessibleWrap_h__
|
||||
|
||||
#include "ApplicationAccessible.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace a11y {
|
||||
|
||||
typedef ApplicationAccessible ApplicationAccessibleWrap;
|
||||
|
||||
} // namespace a11y
|
||||
} // namespace mozilla
|
||||
|
||||
#endif
|
||||
|
||||
25
accessible/mac/DocAccessibleWrap.h
Normal file
25
accessible/mac/DocAccessibleWrap.h
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
/* -*- Mode: 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/. */
|
||||
|
||||
#ifndef mozilla_a11y_DocAccessibleWrap_h__
|
||||
#define mozilla_a11y_DocAccessibleWrap_h__
|
||||
|
||||
#include "DocAccessible.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace a11y {
|
||||
|
||||
class DocAccessibleWrap : public DocAccessible
|
||||
{
|
||||
public:
|
||||
DocAccessibleWrap(nsIDocument* aDocument, nsIPresShell* aPresShell);
|
||||
virtual ~DocAccessibleWrap();
|
||||
|
||||
};
|
||||
|
||||
} // namespace a11y
|
||||
} // namespace mozilla
|
||||
|
||||
#endif
|
||||
21
accessible/mac/DocAccessibleWrap.mm
Normal file
21
accessible/mac/DocAccessibleWrap.mm
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
/* -*- Mode: 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/. */
|
||||
|
||||
#include "DocAccessibleWrap.h"
|
||||
|
||||
#import "mozAccessible.h"
|
||||
|
||||
using namespace mozilla::a11y;
|
||||
|
||||
DocAccessibleWrap::
|
||||
DocAccessibleWrap(nsIDocument* aDocument, nsIPresShell* aPresShell) :
|
||||
DocAccessible(aDocument, aPresShell)
|
||||
{
|
||||
}
|
||||
|
||||
DocAccessibleWrap::~DocAccessibleWrap()
|
||||
{
|
||||
}
|
||||
|
||||
24
accessible/mac/HTMLTableAccessibleWrap.h
Normal file
24
accessible/mac/HTMLTableAccessibleWrap.h
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim:expandtab:shiftwidth=2:tabstop=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/. */
|
||||
|
||||
#ifndef mozilla_a11y_HTMLTableAccessibleWrap_h__
|
||||
#define mozilla_a11y_HTMLTableAccessibleWrap_h__
|
||||
|
||||
#include "HTMLTableAccessible.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace a11y {
|
||||
|
||||
typedef class HTMLTableAccessible HTMLTableAccessibleWrap;
|
||||
typedef class HTMLTableCellAccessible HTMLTableCellAccessibleWrap;
|
||||
typedef class HTMLTableHeaderCellAccessible HTMLTableHeaderCellAccessibleWrap;
|
||||
|
||||
} // namespace a11y
|
||||
} // namespace mozilla
|
||||
|
||||
#endif
|
||||
|
||||
20
accessible/mac/HyperTextAccessibleWrap.h
Normal file
20
accessible/mac/HyperTextAccessibleWrap.h
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
/* -*- Mode: 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/. */
|
||||
|
||||
#ifndef mozilla_a11y_HyperTextAccessibleWrap_h__
|
||||
#define mozilla_a11y_HyperTextAccessibleWrap_h__
|
||||
|
||||
#include "HyperTextAccessible.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace a11y {
|
||||
|
||||
typedef class HyperTextAccessible HyperTextAccessibleWrap;
|
||||
|
||||
} // namespace a11y
|
||||
} // namespace mozilla
|
||||
|
||||
#endif
|
||||
|
||||
22
accessible/mac/ImageAccessibleWrap.h
Normal file
22
accessible/mac/ImageAccessibleWrap.h
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim:expandtab:shiftwidth=2:tabstop=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/. */
|
||||
|
||||
#ifndef mozilla_a11y_ImageAccessibleWrap_h__
|
||||
#define mozilla_a11y_ImageAccessibleWrap_h__
|
||||
|
||||
#include "ImageAccessible.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace a11y {
|
||||
|
||||
typedef class ImageAccessible ImageAccessibleWrap;
|
||||
|
||||
} // namespace a11y
|
||||
} // namespace mozilla
|
||||
|
||||
#endif
|
||||
|
||||
26
accessible/mac/MacUtils.h
Normal file
26
accessible/mac/MacUtils.h
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
/* -*- 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/. */
|
||||
|
||||
#ifndef _MacUtils_H_
|
||||
#define _MacUtils_H_
|
||||
|
||||
@class NSString;
|
||||
class nsString;
|
||||
|
||||
namespace mozilla {
|
||||
namespace a11y {
|
||||
namespace utils {
|
||||
|
||||
/**
|
||||
* Get a localized string from the string bundle.
|
||||
* Return nil if not found.
|
||||
*/
|
||||
NSString* LocalizedString(const nsString& aString);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
32
accessible/mac/MacUtils.mm
Normal file
32
accessible/mac/MacUtils.mm
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
/* -*- 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 "MacUtils.h"
|
||||
|
||||
#include "Accessible.h"
|
||||
|
||||
#include "nsCocoaUtils.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace a11y {
|
||||
namespace utils {
|
||||
|
||||
/**
|
||||
* Get a localized string from the a11y string bundle.
|
||||
* Return nil if not found.
|
||||
*/
|
||||
NSString*
|
||||
LocalizedString(const nsString& aString)
|
||||
{
|
||||
nsString text;
|
||||
|
||||
Accessible::TranslateString(aString, text);
|
||||
|
||||
return text.IsEmpty() ? nil : nsCocoaUtils::ToNSString(text);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
174
accessible/mac/Platform.mm
Normal file
174
accessible/mac/Platform.mm
Normal file
|
|
@ -0,0 +1,174 @@
|
|||
/* -*- 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 <Cocoa/Cocoa.h>
|
||||
|
||||
#include "Platform.h"
|
||||
#include "ProxyAccessible.h"
|
||||
#include "DocAccessibleParent.h"
|
||||
#include "mozTableAccessible.h"
|
||||
|
||||
#include "nsAppShell.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace a11y {
|
||||
|
||||
// Mac a11y whitelisting
|
||||
static bool sA11yShouldBeEnabled = false;
|
||||
|
||||
bool
|
||||
ShouldA11yBeEnabled()
|
||||
{
|
||||
EPlatformDisabledState disabledState = PlatformDisabledState();
|
||||
return (disabledState == ePlatformIsForceEnabled) || ((disabledState == ePlatformIsEnabled) && sA11yShouldBeEnabled);
|
||||
}
|
||||
|
||||
void
|
||||
PlatformInit()
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
PlatformShutdown()
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
ProxyCreated(ProxyAccessible* aProxy, uint32_t)
|
||||
{
|
||||
// Pass in dummy state for now as retrieving proxy state requires IPC.
|
||||
// Note that we can use ProxyAccessible::IsTable* functions here because they
|
||||
// do not use IPC calls but that might change after bug 1210477.
|
||||
Class type;
|
||||
if (aProxy->IsTable())
|
||||
type = [mozTableAccessible class];
|
||||
else if (aProxy->IsTableRow())
|
||||
type = [mozTableRowAccessible class];
|
||||
else if (aProxy->IsTableCell())
|
||||
type = [mozTableCellAccessible class];
|
||||
else
|
||||
type = GetTypeFromRole(aProxy->Role());
|
||||
|
||||
uintptr_t accWrap = reinterpret_cast<uintptr_t>(aProxy) | IS_PROXY;
|
||||
mozAccessible* mozWrapper = [[type alloc] initWithAccessible:accWrap];
|
||||
aProxy->SetWrapper(reinterpret_cast<uintptr_t>(mozWrapper));
|
||||
|
||||
mozAccessible* nativeParent = nullptr;
|
||||
if (aProxy->IsDoc() && aProxy->AsDoc()->IsTopLevel()) {
|
||||
// If proxy is top level, the parent we need to invalidate the children of
|
||||
// will be a non-remote accessible.
|
||||
Accessible* outerDoc = aProxy->OuterDocOfRemoteBrowser();
|
||||
if (outerDoc) {
|
||||
nativeParent = GetNativeFromGeckoAccessible(outerDoc);
|
||||
}
|
||||
} else {
|
||||
// Non-top level proxies need proxy parents' children invalidated.
|
||||
ProxyAccessible* parent = aProxy->Parent();
|
||||
nativeParent = GetNativeFromProxy(parent);
|
||||
NS_ASSERTION(parent, "a non-top-level proxy is missing a parent?");
|
||||
}
|
||||
|
||||
if (nativeParent) {
|
||||
[nativeParent invalidateChildren];
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ProxyDestroyed(ProxyAccessible* aProxy)
|
||||
{
|
||||
mozAccessible* nativeParent = nil;
|
||||
if (aProxy->IsDoc() && aProxy->AsDoc()->IsTopLevel()) {
|
||||
// Invalidate native parent in parent process's children on proxy destruction
|
||||
Accessible* outerDoc = aProxy->OuterDocOfRemoteBrowser();
|
||||
if (outerDoc) {
|
||||
nativeParent = GetNativeFromGeckoAccessible(outerDoc);
|
||||
}
|
||||
} else {
|
||||
if (!aProxy->Document()->IsShutdown()) {
|
||||
// Only do if the document has not been shut down, else parent will return
|
||||
// garbage since we don't shut down children from top down.
|
||||
ProxyAccessible* parent = aProxy->Parent();
|
||||
// Invalidate proxy parent's children.
|
||||
if (parent) {
|
||||
nativeParent = GetNativeFromProxy(parent);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mozAccessible* wrapper = GetNativeFromProxy(aProxy);
|
||||
[wrapper expire];
|
||||
[wrapper release];
|
||||
aProxy->SetWrapper(0);
|
||||
|
||||
if (nativeParent) {
|
||||
[nativeParent invalidateChildren];
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ProxyEvent(ProxyAccessible* aProxy, uint32_t aEventType)
|
||||
{
|
||||
// ignore everything but focus-changed, value-changed, caret and selection
|
||||
// events for now.
|
||||
if (aEventType != nsIAccessibleEvent::EVENT_FOCUS &&
|
||||
aEventType != nsIAccessibleEvent::EVENT_VALUE_CHANGE &&
|
||||
aEventType != nsIAccessibleEvent::EVENT_TEXT_VALUE_CHANGE &&
|
||||
aEventType != nsIAccessibleEvent::EVENT_TEXT_CARET_MOVED &&
|
||||
aEventType != nsIAccessibleEvent::EVENT_TEXT_SELECTION_CHANGED)
|
||||
return;
|
||||
|
||||
mozAccessible* wrapper = GetNativeFromProxy(aProxy);
|
||||
if (wrapper)
|
||||
FireNativeEvent(wrapper, aEventType);
|
||||
}
|
||||
|
||||
void
|
||||
ProxyStateChangeEvent(ProxyAccessible* aProxy, uint64_t, bool)
|
||||
{
|
||||
// mac doesn't care about state change events
|
||||
}
|
||||
|
||||
void
|
||||
ProxyCaretMoveEvent(ProxyAccessible* aTarget, int32_t aOffset)
|
||||
{
|
||||
mozAccessible* wrapper = GetNativeFromProxy(aTarget);
|
||||
if (wrapper)
|
||||
[wrapper selectedTextDidChange];
|
||||
}
|
||||
|
||||
void
|
||||
ProxyTextChangeEvent(ProxyAccessible*, const nsString&, int32_t, uint32_t,
|
||||
bool, bool)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
ProxyShowHideEvent(ProxyAccessible*, ProxyAccessible*, bool, bool)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
ProxySelectionEvent(ProxyAccessible*, ProxyAccessible*, uint32_t)
|
||||
{
|
||||
}
|
||||
} // namespace a11y
|
||||
} // namespace mozilla
|
||||
|
||||
@interface GeckoNSApplication(a11y)
|
||||
-(void)accessibilitySetValue:(id)value forAttribute:(NSString*)attribute;
|
||||
@end
|
||||
|
||||
@implementation GeckoNSApplication(a11y)
|
||||
|
||||
-(void)accessibilitySetValue:(id)value forAttribute:(NSString*)attribute
|
||||
{
|
||||
if ([attribute isEqualToString:@"AXEnhancedUserInterface"])
|
||||
mozilla::a11y::sA11yShouldBeEnabled = ([value intValue] == 1);
|
||||
|
||||
return [super accessibilitySetValue:value forAttribute:attribute];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
34
accessible/mac/RootAccessibleWrap.h
Normal file
34
accessible/mac/RootAccessibleWrap.h
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
/* -*- Mode: 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/. */
|
||||
|
||||
/* For documentation of the accessibility architecture,
|
||||
* see http://lxr.mozilla.org/seamonkey/source/accessible/accessible-docs.html
|
||||
*/
|
||||
|
||||
#ifndef mozilla_a11y_RootAccessibleWrap_h__
|
||||
#define mozilla_a11y_RootAccessibleWrap_h__
|
||||
|
||||
#include "RootAccessible.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace a11y {
|
||||
|
||||
class RootAccessibleWrap : public RootAccessible
|
||||
{
|
||||
public:
|
||||
RootAccessibleWrap(nsIDocument* aDocument, nsIPresShell* aPresShell);
|
||||
virtual ~RootAccessibleWrap();
|
||||
|
||||
Class GetNativeType ();
|
||||
|
||||
// let's our native accessible get in touch with the
|
||||
// native cocoa view that is our accessible parent.
|
||||
void GetNativeWidget (void **aOutView);
|
||||
};
|
||||
|
||||
} // namespace a11y
|
||||
} // namespace mozilla
|
||||
|
||||
#endif
|
||||
53
accessible/mac/RootAccessibleWrap.mm
Normal file
53
accessible/mac/RootAccessibleWrap.mm
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
/* -*- Mode: 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/. */
|
||||
|
||||
#include "RootAccessibleWrap.h"
|
||||
|
||||
#include "mozDocAccessible.h"
|
||||
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsObjCExceptions.h"
|
||||
#include "nsIFrame.h"
|
||||
#include "nsView.h"
|
||||
#include "nsIWidget.h"
|
||||
|
||||
using namespace mozilla::a11y;
|
||||
|
||||
RootAccessibleWrap::
|
||||
RootAccessibleWrap(nsIDocument* aDocument, nsIPresShell* aPresShell) :
|
||||
RootAccessible(aDocument, aPresShell)
|
||||
{
|
||||
}
|
||||
|
||||
RootAccessibleWrap::~RootAccessibleWrap()
|
||||
{
|
||||
}
|
||||
|
||||
Class
|
||||
RootAccessibleWrap::GetNativeType()
|
||||
{
|
||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
|
||||
|
||||
return [mozRootAccessible class];
|
||||
|
||||
NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
|
||||
}
|
||||
|
||||
void
|
||||
RootAccessibleWrap::GetNativeWidget(void** aOutView)
|
||||
{
|
||||
nsIFrame *frame = GetFrame();
|
||||
if (frame) {
|
||||
nsView *view = frame->GetView();
|
||||
if (view) {
|
||||
nsIWidget *widget = view->GetWidget();
|
||||
if (widget) {
|
||||
*aOutView = (void**)widget->GetNativeData (NS_NATIVE_WIDGET);
|
||||
NS_ASSERTION (*aOutView,
|
||||
"Couldn't get the native NSView parent we need to connect the accessibility hierarchy!");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
19
accessible/mac/TextLeafAccessibleWrap.h
Normal file
19
accessible/mac/TextLeafAccessibleWrap.h
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
/* -*- Mode: 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/. */
|
||||
|
||||
#ifndef mozilla_a11y_TextLeafAccessibleWrap_h__
|
||||
#define mozilla_a11y_TextLeafAccessibleWrap_h__
|
||||
|
||||
#include "TextLeafAccessible.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace a11y {
|
||||
|
||||
typedef class TextLeafAccessible TextLeafAccessibleWrap;
|
||||
|
||||
} // namespace a11y
|
||||
} // namespace mozilla
|
||||
|
||||
#endif
|
||||
20
accessible/mac/XULListboxAccessibleWrap.h
Normal file
20
accessible/mac/XULListboxAccessibleWrap.h
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
/* -*- Mode: 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/. */
|
||||
|
||||
#ifndef mozilla_a11y_XULListboxAccessibleWrap_h__
|
||||
#define mozilla_a11y_XULListboxAccessibleWrap_h__
|
||||
|
||||
#include "XULListboxAccessible.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace a11y {
|
||||
|
||||
typedef class XULListboxAccessible XULListboxAccessibleWrap;
|
||||
typedef class XULListCellAccessible XULListCellAccessibleWrap;
|
||||
|
||||
} // namespace a11y
|
||||
} // namespace mozilla
|
||||
|
||||
#endif
|
||||
19
accessible/mac/XULMenuAccessibleWrap.h
Normal file
19
accessible/mac/XULMenuAccessibleWrap.h
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
/* -*- Mode: 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/. */
|
||||
|
||||
#ifndef mozilla_a11y_XULMenuAccessibleWrap_h__
|
||||
#define mozilla_a11y_XULMenuAccessibleWrap_h__
|
||||
|
||||
#include "XULMenuAccessible.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace a11y {
|
||||
|
||||
typedef class XULMenuitemAccessible XULMenuitemAccessibleWrap;
|
||||
|
||||
} // namespace a11y
|
||||
} // namespace mozilla
|
||||
|
||||
#endif
|
||||
20
accessible/mac/XULTreeGridAccessibleWrap.h
Normal file
20
accessible/mac/XULTreeGridAccessibleWrap.h
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
/* -*- Mode: 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/. */
|
||||
|
||||
#ifndef mozilla_a11y_XULTreeGridAccessibleWrap_h__
|
||||
#define mozilla_a11y_XULTreeGridAccessibleWrap_h__
|
||||
|
||||
#include "XULTreeGridAccessible.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace a11y {
|
||||
|
||||
typedef class XULTreeGridAccessible XULTreeGridAccessibleWrap;
|
||||
typedef class XULTreeGridCellAccessible XULTreeGridCellAccessibleWrap;
|
||||
|
||||
} // namespace a11y
|
||||
} // namespace mozilla
|
||||
|
||||
#endif
|
||||
44
accessible/mac/moz.build
Normal file
44
accessible/mac/moz.build
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
|
||||
# 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/.
|
||||
|
||||
EXPORTS += [
|
||||
'mozAccessibleProtocol.h',
|
||||
]
|
||||
|
||||
EXPORTS.mozilla.a11y += [
|
||||
'AccessibleWrap.h',
|
||||
'HyperTextAccessibleWrap.h',
|
||||
]
|
||||
|
||||
SOURCES += [
|
||||
'AccessibleWrap.mm',
|
||||
'DocAccessibleWrap.mm',
|
||||
'MacUtils.mm',
|
||||
'mozAccessible.mm',
|
||||
'mozActionElements.mm',
|
||||
'mozDocAccessible.mm',
|
||||
'mozHTMLAccessible.mm',
|
||||
'mozTableAccessible.mm',
|
||||
'mozTextAccessible.mm',
|
||||
'Platform.mm',
|
||||
'RootAccessibleWrap.mm',
|
||||
]
|
||||
|
||||
LOCAL_INCLUDES += [
|
||||
'/accessible/base',
|
||||
'/accessible/generic',
|
||||
'/accessible/html',
|
||||
'/accessible/ipc',
|
||||
'/accessible/ipc/other',
|
||||
'/accessible/xul',
|
||||
'/layout/generic',
|
||||
'/layout/xul',
|
||||
'/widget',
|
||||
'/widget/cocoa',
|
||||
]
|
||||
|
||||
FINAL_LIBRARY = 'xul'
|
||||
|
||||
include('/ipc/chromium/chromium-config.mozbuild')
|
||||
181
accessible/mac/mozAccessible.h
Normal file
181
accessible/mac/mozAccessible.h
Normal file
|
|
@ -0,0 +1,181 @@
|
|||
/* -*- 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/. */
|
||||
|
||||
#include "AccessibleWrap.h"
|
||||
#include "ProxyAccessible.h"
|
||||
|
||||
#import <Cocoa/Cocoa.h>
|
||||
|
||||
#import "mozAccessibleProtocol.h"
|
||||
|
||||
@class mozRootAccessible;
|
||||
|
||||
/**
|
||||
* All mozAccessibles are either abstract objects (that correspond to XUL
|
||||
* widgets, HTML frames, etc) or are attached to a certain view; for example
|
||||
* a document view. When we hand an object off to an AT, we always want
|
||||
* to give it the represented view, in the latter case.
|
||||
*/
|
||||
|
||||
namespace mozilla {
|
||||
namespace a11y {
|
||||
|
||||
inline id <mozAccessible>
|
||||
GetObjectOrRepresentedView(id <mozAccessible> aObject)
|
||||
{
|
||||
return [aObject hasRepresentedView] ? [aObject representedView] : aObject;
|
||||
}
|
||||
|
||||
inline mozAccessible*
|
||||
GetNativeFromGeckoAccessible(Accessible* aAccessible)
|
||||
{
|
||||
mozAccessible* native = nil;
|
||||
aAccessible->GetNativeInterface((void**)&native);
|
||||
return native;
|
||||
}
|
||||
|
||||
inline mozAccessible*
|
||||
GetNativeFromProxy(const ProxyAccessible* aProxy)
|
||||
{
|
||||
return reinterpret_cast<mozAccessible*>(aProxy->GetWrapper());
|
||||
}
|
||||
|
||||
} // a11y
|
||||
} // mozilla
|
||||
|
||||
// This is OR'd with the Accessible owner to indicate the wrap-ee is a proxy.
|
||||
static const uintptr_t IS_PROXY = 1;
|
||||
|
||||
@interface mozAccessible : NSObject <mozAccessible>
|
||||
{
|
||||
/**
|
||||
* Weak reference; it owns us.
|
||||
*/
|
||||
uintptr_t mGeckoAccessible;
|
||||
|
||||
/**
|
||||
* Strong ref to array of children
|
||||
*/
|
||||
NSMutableArray* mChildren;
|
||||
|
||||
/**
|
||||
* Weak reference to the parent
|
||||
*/
|
||||
mozAccessible* mParent;
|
||||
|
||||
/**
|
||||
* The role of our gecko accessible.
|
||||
*/
|
||||
mozilla::a11y::role mRole;
|
||||
}
|
||||
|
||||
// return the Accessible for this mozAccessible if it exists.
|
||||
- (mozilla::a11y::AccessibleWrap*)getGeckoAccessible;
|
||||
|
||||
// return the ProxyAccessible for this mozAccessible if it exists.
|
||||
- (mozilla::a11y::ProxyAccessible*)getProxyAccessible;
|
||||
|
||||
// inits with the gecko owner.
|
||||
- (id)initWithAccessible:(uintptr_t)aGeckoObj;
|
||||
|
||||
// our accessible parent (AXParent)
|
||||
- (id <mozAccessible>)parent;
|
||||
|
||||
// a lazy cache of our accessible children (AXChildren). updated
|
||||
- (NSArray*)children;
|
||||
|
||||
// returns the size of this accessible.
|
||||
- (NSValue*)size;
|
||||
|
||||
// returns the position, in cocoa coordinates.
|
||||
- (NSValue*)position;
|
||||
|
||||
// can be overridden to report another role name.
|
||||
- (NSString*)role;
|
||||
|
||||
// a subrole is a more specialized variant of the role. for example,
|
||||
// the role might be "textfield", while the subrole is "password textfield".
|
||||
- (NSString*)subrole;
|
||||
|
||||
// Return the role description, as there are a few exceptions.
|
||||
- (NSString*)roleDescription;
|
||||
|
||||
// returns the native window we're inside.
|
||||
- (NSWindow*)window;
|
||||
|
||||
// the value of this element.
|
||||
- (id)value;
|
||||
|
||||
// name that is associated with this accessible (for buttons, etc)
|
||||
- (NSString*)title;
|
||||
|
||||
// the accessible description (help text) of this particular instance.
|
||||
- (NSString*)help;
|
||||
|
||||
- (BOOL)isEnabled;
|
||||
|
||||
// information about focus.
|
||||
- (BOOL)isFocused;
|
||||
- (BOOL)canBeFocused;
|
||||
|
||||
// returns NO if for some reason we were unable to focus the element.
|
||||
- (BOOL)focus;
|
||||
|
||||
// notifications sent out to listening accessible providers.
|
||||
- (void)didReceiveFocus;
|
||||
- (void)valueDidChange;
|
||||
- (void)selectedTextDidChange;
|
||||
- (void)documentLoadComplete;
|
||||
|
||||
// internal method to retrieve a child at a given index.
|
||||
- (id)childAt:(uint32_t)i;
|
||||
|
||||
#pragma mark -
|
||||
|
||||
// invalidates and removes all our children from our cached array.
|
||||
- (void)invalidateChildren;
|
||||
|
||||
/**
|
||||
* Append a child if they are already cached.
|
||||
*/
|
||||
- (void)appendChild:(mozilla::a11y::Accessible*)aAccessible;
|
||||
|
||||
// makes ourselves "expired". after this point, we might be around if someone
|
||||
// has retained us (e.g., a third-party), but we really contain no information.
|
||||
- (void)expire;
|
||||
- (BOOL)isExpired;
|
||||
|
||||
#ifdef DEBUG
|
||||
- (void)printHierarchy;
|
||||
- (void)printHierarchyWithLevel:(unsigned)numSpaces;
|
||||
|
||||
- (void)sanityCheckChildren;
|
||||
- (void)sanityCheckChildren:(NSArray*)theChildren;
|
||||
#endif
|
||||
|
||||
// ---- NSAccessibility methods ---- //
|
||||
|
||||
// whether to skip this element when traversing the accessibility
|
||||
// hierarchy.
|
||||
- (BOOL)accessibilityIsIgnored;
|
||||
|
||||
// called by third-parties to determine the deepest child element under the mouse
|
||||
- (id)accessibilityHitTest:(NSPoint)point;
|
||||
|
||||
// returns the deepest unignored focused accessible element
|
||||
- (id)accessibilityFocusedUIElement;
|
||||
|
||||
// a mozAccessible needs to at least provide links to its parent and
|
||||
// children.
|
||||
- (NSArray*)accessibilityAttributeNames;
|
||||
|
||||
// value for the specified attribute
|
||||
- (id)accessibilityAttributeValue:(NSString*)attribute;
|
||||
|
||||
- (BOOL)accessibilityIsAttributeSettable:(NSString*)attribute;
|
||||
- (void)accessibilitySetValue:(id)value forAttribute:(NSString*)attribute;
|
||||
|
||||
@end
|
||||
|
||||
1197
accessible/mac/mozAccessible.mm
Normal file
1197
accessible/mac/mozAccessible.mm
Normal file
File diff suppressed because it is too large
Load diff
69
accessible/mac/mozAccessibleProtocol.h
Normal file
69
accessible/mac/mozAccessibleProtocol.h
Normal file
|
|
@ -0,0 +1,69 @@
|
|||
/* -*- 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 <Cocoa/Cocoa.h>
|
||||
|
||||
#import "mozView.h"
|
||||
|
||||
/* This protocol's primary use is so widget/cocoa can talk back to us
|
||||
properly.
|
||||
|
||||
ChildView owns the topmost mozRootAccessible, and needs to take care of setting up
|
||||
that parent/child relationship.
|
||||
|
||||
This protocol is thus used to make sure it knows it's talking to us, and not
|
||||
just some random |id|.
|
||||
*/
|
||||
|
||||
@protocol mozAccessible
|
||||
|
||||
// returns whether this accessible is the root accessible. there is one
|
||||
// root accessible per window.
|
||||
- (BOOL)isRoot;
|
||||
|
||||
// some mozAccessibles implement accessibility support in place of another object. for example,
|
||||
// ChildView gets its support from us.
|
||||
//
|
||||
// instead of returning a mozAccessible to the OS when it wants an object, we need to pass the view we represent, so the
|
||||
// OS doesn't get confused and think we return some random object.
|
||||
- (BOOL)hasRepresentedView;
|
||||
- (id)representedView;
|
||||
|
||||
#ifdef DEBUG
|
||||
// debug utility that will print the native accessibility tree, starting
|
||||
// at this node.
|
||||
- (void)printHierarchy;
|
||||
#endif
|
||||
|
||||
/*** general ***/
|
||||
|
||||
// returns the accessible at the specified point.
|
||||
- (id)accessibilityHitTest:(NSPoint)point;
|
||||
|
||||
// whether this element is flagged as ignored.
|
||||
- (BOOL)accessibilityIsIgnored;
|
||||
|
||||
// currently focused UI element (possibly a child accessible)
|
||||
- (id)accessibilityFocusedUIElement;
|
||||
|
||||
/*** attributes ***/
|
||||
|
||||
// all supported attributes
|
||||
- (NSArray*)accessibilityAttributeNames;
|
||||
|
||||
// value for given attribute.
|
||||
- (id)accessibilityAttributeValue:(NSString*)attribute;
|
||||
|
||||
// whether a particular attribute can be modified
|
||||
- (BOOL)accessibilityIsAttributeSettable:(NSString*)attribute;
|
||||
|
||||
/*** actions ***/
|
||||
|
||||
- (NSArray*)accessibilityActionNames;
|
||||
- (NSString*)accessibilityActionDescription:(NSString*)action;
|
||||
- (void)accessibilityPerformAction:(NSString*)action;
|
||||
|
||||
@end
|
||||
|
||||
37
accessible/mac/mozActionElements.h
Normal file
37
accessible/mac/mozActionElements.h
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
/* -*- 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 <Cocoa/Cocoa.h>
|
||||
#import "mozAccessible.h"
|
||||
|
||||
/* Simple subclasses for things like checkboxes, buttons, etc. */
|
||||
|
||||
@interface mozButtonAccessible : mozAccessible
|
||||
{
|
||||
}
|
||||
- (BOOL)hasPopup;
|
||||
- (void)click;
|
||||
- (BOOL)isTab;
|
||||
@end
|
||||
|
||||
@interface mozCheckboxAccessible : mozButtonAccessible
|
||||
// returns one of the constants defined in CheckboxValue
|
||||
- (int)isChecked;
|
||||
@end
|
||||
|
||||
/* Class for tabs - not individual tabs */
|
||||
@interface mozTabsAccessible : mozAccessible
|
||||
{
|
||||
NSMutableArray* mTabs;
|
||||
}
|
||||
-(id)tabs;
|
||||
@end
|
||||
|
||||
/**
|
||||
* Accessible for a PANE
|
||||
*/
|
||||
@interface mozPaneAccessible : mozAccessible
|
||||
|
||||
@end
|
||||
340
accessible/mac/mozActionElements.mm
Normal file
340
accessible/mac/mozActionElements.mm
Normal file
|
|
@ -0,0 +1,340 @@
|
|||
/* -*- 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 "mozActionElements.h"
|
||||
|
||||
#import "MacUtils.h"
|
||||
#include "Accessible-inl.h"
|
||||
#include "DocAccessible.h"
|
||||
#include "XULTabAccessible.h"
|
||||
|
||||
#include "nsDeckFrame.h"
|
||||
#include "nsObjCExceptions.h"
|
||||
|
||||
using namespace mozilla::a11y;
|
||||
|
||||
enum CheckboxValue {
|
||||
// these constants correspond to the values in the OS
|
||||
kUnchecked = 0,
|
||||
kChecked = 1,
|
||||
kMixed = 2
|
||||
};
|
||||
|
||||
@implementation mozButtonAccessible
|
||||
|
||||
- (NSArray*)accessibilityAttributeNames
|
||||
{
|
||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
|
||||
|
||||
static NSArray *attributes = nil;
|
||||
if (!attributes) {
|
||||
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,
|
||||
#if DEBUG
|
||||
@"AXMozDescription",
|
||||
#endif
|
||||
nil];
|
||||
}
|
||||
return attributes;
|
||||
|
||||
NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
|
||||
}
|
||||
|
||||
- (id)accessibilityAttributeValue:(NSString *)attribute
|
||||
{
|
||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
|
||||
|
||||
if ([attribute isEqualToString:NSAccessibilityChildrenAttribute]) {
|
||||
if ([self hasPopup])
|
||||
return [self children];
|
||||
return nil;
|
||||
}
|
||||
|
||||
if ([attribute isEqualToString:NSAccessibilityRoleDescriptionAttribute]) {
|
||||
if ([self isTab])
|
||||
return utils::LocalizedString(NS_LITERAL_STRING("tab"));
|
||||
|
||||
return NSAccessibilityRoleDescription([self role], nil);
|
||||
}
|
||||
|
||||
return [super accessibilityAttributeValue:attribute];
|
||||
|
||||
NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
|
||||
}
|
||||
|
||||
- (BOOL)accessibilityIsIgnored
|
||||
{
|
||||
return ![self getGeckoAccessible] && ![self getProxyAccessible];
|
||||
}
|
||||
|
||||
- (NSArray*)accessibilityActionNames
|
||||
{
|
||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
|
||||
|
||||
if ([self isEnabled]) {
|
||||
if ([self hasPopup])
|
||||
return [NSArray arrayWithObjects:NSAccessibilityPressAction,
|
||||
NSAccessibilityShowMenuAction,
|
||||
nil];
|
||||
return [NSArray arrayWithObject:NSAccessibilityPressAction];
|
||||
}
|
||||
return nil;
|
||||
|
||||
NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
|
||||
}
|
||||
|
||||
- (NSString*)accessibilityActionDescription:(NSString*)action
|
||||
{
|
||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
|
||||
|
||||
if ([action isEqualToString:NSAccessibilityPressAction]) {
|
||||
if ([self isTab])
|
||||
return utils::LocalizedString(NS_LITERAL_STRING("switch"));
|
||||
|
||||
return @"press button"; // XXX: localize this later?
|
||||
}
|
||||
|
||||
if ([self hasPopup]) {
|
||||
if ([action isEqualToString:NSAccessibilityShowMenuAction])
|
||||
return @"show menu";
|
||||
}
|
||||
|
||||
return nil;
|
||||
|
||||
NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
|
||||
}
|
||||
|
||||
- (void)accessibilityPerformAction:(NSString*)action
|
||||
{
|
||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK;
|
||||
|
||||
if ([self isEnabled] && [action isEqualToString:NSAccessibilityPressAction]) {
|
||||
// TODO: this should bring up the menu, but currently doesn't.
|
||||
// once msaa and atk have merged better, they will implement
|
||||
// the action needed to show the menu.
|
||||
[self click];
|
||||
}
|
||||
|
||||
NS_OBJC_END_TRY_ABORT_BLOCK;
|
||||
}
|
||||
|
||||
- (void)click
|
||||
{
|
||||
// both buttons and checkboxes have only one action. we should really stop using arbitrary
|
||||
// arrays with actions, and define constants for these actions.
|
||||
if (AccessibleWrap* accWrap = [self getGeckoAccessible])
|
||||
accWrap->DoAction(0);
|
||||
else if (ProxyAccessible* proxy = [self getProxyAccessible])
|
||||
proxy->DoAction(0);
|
||||
}
|
||||
|
||||
- (BOOL)isTab
|
||||
{
|
||||
if (AccessibleWrap* accWrap = [self getGeckoAccessible])
|
||||
return accWrap->Role() == roles::PAGETAB;
|
||||
|
||||
if (ProxyAccessible* proxy = [self getProxyAccessible])
|
||||
return proxy->Role() == roles::PAGETAB;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
- (BOOL)hasPopup
|
||||
{
|
||||
if (AccessibleWrap* accWrap = [self getGeckoAccessible])
|
||||
return accWrap->NativeState() & states::HASPOPUP;
|
||||
|
||||
if (ProxyAccessible* proxy = [self getProxyAccessible])
|
||||
return proxy->NativeState() & states::HASPOPUP;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@implementation mozCheckboxAccessible
|
||||
|
||||
- (NSString*)accessibilityActionDescription:(NSString*)action
|
||||
{
|
||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
|
||||
|
||||
if ([action isEqualToString:NSAccessibilityPressAction]) {
|
||||
if ([self isChecked] != kUnchecked)
|
||||
return @"uncheck checkbox"; // XXX: localize this later?
|
||||
|
||||
return @"check checkbox"; // XXX: localize this later?
|
||||
}
|
||||
|
||||
return nil;
|
||||
|
||||
NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
|
||||
}
|
||||
|
||||
- (int)isChecked
|
||||
{
|
||||
uint64_t state = 0;
|
||||
if (AccessibleWrap* accWrap = [self getGeckoAccessible])
|
||||
state = accWrap->NativeState();
|
||||
else if (ProxyAccessible* proxy = [self getProxyAccessible])
|
||||
state = proxy->NativeState();
|
||||
|
||||
// check if we're checked or in a mixed state
|
||||
if (state & states::CHECKED) {
|
||||
return (state & states::MIXED) ? kMixed : kChecked;
|
||||
}
|
||||
|
||||
return kUnchecked;
|
||||
}
|
||||
|
||||
- (id)value
|
||||
{
|
||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
|
||||
|
||||
return [NSNumber numberWithInt:[self isChecked]];
|
||||
|
||||
NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@implementation mozTabsAccessible
|
||||
|
||||
- (void)dealloc
|
||||
{
|
||||
[mTabs release];
|
||||
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
- (NSArray*)accessibilityAttributeNames
|
||||
{
|
||||
// standard attributes that are shared and supported by root accessible (AXMain) elements.
|
||||
static NSMutableArray* attributes = nil;
|
||||
|
||||
if (!attributes) {
|
||||
attributes = [[super accessibilityAttributeNames] mutableCopy];
|
||||
[attributes addObject:NSAccessibilityContentsAttribute];
|
||||
[attributes addObject:NSAccessibilityTabsAttribute];
|
||||
}
|
||||
|
||||
return attributes;
|
||||
}
|
||||
|
||||
- (id)accessibilityAttributeValue:(NSString *)attribute
|
||||
{
|
||||
if ([attribute isEqualToString:NSAccessibilityContentsAttribute])
|
||||
return [super children];
|
||||
if ([attribute isEqualToString:NSAccessibilityTabsAttribute])
|
||||
return [self tabs];
|
||||
|
||||
return [super accessibilityAttributeValue:attribute];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the selected tab (the mozAccessible)
|
||||
*/
|
||||
- (id)value
|
||||
{
|
||||
mozAccessible* nativeAcc = nil;
|
||||
if (AccessibleWrap* accWrap = [self getGeckoAccessible]) {
|
||||
if (Accessible* accTab = accWrap->GetSelectedItem(0)) {
|
||||
accTab->GetNativeInterface((void**)&nativeAcc);
|
||||
}
|
||||
} else if (ProxyAccessible* proxy = [self getProxyAccessible]) {
|
||||
if (ProxyAccessible* proxyTab = proxy->GetSelectedItem(0)) {
|
||||
nativeAcc = GetNativeFromProxy(proxyTab);
|
||||
}
|
||||
}
|
||||
|
||||
return nativeAcc;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the mozAccessibles that are the tabs.
|
||||
*/
|
||||
- (id)tabs
|
||||
{
|
||||
if (mTabs)
|
||||
return mTabs;
|
||||
|
||||
NSArray* children = [self children];
|
||||
NSEnumerator* enumerator = [children objectEnumerator];
|
||||
mTabs = [[NSMutableArray alloc] init];
|
||||
|
||||
id obj;
|
||||
while ((obj = [enumerator nextObject]))
|
||||
if ([obj isTab])
|
||||
[mTabs addObject:obj];
|
||||
|
||||
return mTabs;
|
||||
}
|
||||
|
||||
- (void)invalidateChildren
|
||||
{
|
||||
[super invalidateChildren];
|
||||
|
||||
[mTabs release];
|
||||
mTabs = nil;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@implementation mozPaneAccessible
|
||||
|
||||
- (NSUInteger)accessibilityArrayAttributeCount:(NSString*)attribute
|
||||
{
|
||||
AccessibleWrap* accWrap = [self getGeckoAccessible];
|
||||
ProxyAccessible* proxy = [self getProxyAccessible];
|
||||
if (!accWrap && !proxy)
|
||||
return 0;
|
||||
|
||||
// By default this calls -[[mozAccessible children] count].
|
||||
// Since we don't cache mChildren. This is faster.
|
||||
if ([attribute isEqualToString:NSAccessibilityChildrenAttribute]) {
|
||||
if (accWrap)
|
||||
return accWrap->ChildCount() ? 1 : 0;
|
||||
|
||||
return proxy->ChildrenCount() ? 1 : 0;
|
||||
}
|
||||
|
||||
return [super accessibilityArrayAttributeCount:attribute];
|
||||
}
|
||||
|
||||
- (NSArray*)children
|
||||
{
|
||||
if (![self getGeckoAccessible])
|
||||
return nil;
|
||||
|
||||
nsDeckFrame* deckFrame = do_QueryFrame([self getGeckoAccessible]->GetFrame());
|
||||
nsIFrame* selectedFrame = deckFrame ? deckFrame->GetSelectedBox() : nullptr;
|
||||
|
||||
Accessible* selectedAcc = nullptr;
|
||||
if (selectedFrame) {
|
||||
nsINode* node = selectedFrame->GetContent();
|
||||
selectedAcc = [self getGeckoAccessible]->Document()->GetAccessible(node);
|
||||
}
|
||||
|
||||
if (selectedAcc) {
|
||||
mozAccessible *curNative = GetNativeFromGeckoAccessible(selectedAcc);
|
||||
if (curNative)
|
||||
return [NSArray arrayWithObjects:GetObjectOrRepresentedView(curNative), nil];
|
||||
}
|
||||
|
||||
return nil;
|
||||
}
|
||||
|
||||
@end
|
||||
31
accessible/mac/mozDocAccessible.h
Normal file
31
accessible/mac/mozDocAccessible.h
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
/* -*- 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 <Cocoa/Cocoa.h>
|
||||
#import "mozAccessible.h"
|
||||
|
||||
// our protocol that we implement (so cocoa widgets can talk to us)
|
||||
#import "mozAccessibleProtocol.h"
|
||||
|
||||
/*
|
||||
The root accessible. There is one per window.
|
||||
Created by the RootAccessibleWrap.
|
||||
*/
|
||||
@interface mozRootAccessible : mozAccessible
|
||||
{
|
||||
// the mozView that we're representing.
|
||||
// all outside communication goes through the mozView.
|
||||
// in reality, it's just piping all calls to us, and we're
|
||||
// doing its dirty work!
|
||||
//
|
||||
// whenever someone asks who we are (e.g., a child asking
|
||||
// for its parent, or our parent asking for its child), we'll
|
||||
// respond the mozView. it is absolutely necessary for third-
|
||||
// party tools that we do this!
|
||||
//
|
||||
// /hwaara
|
||||
id <mozView, mozAccessible> mParallelView; // weak ref
|
||||
}
|
||||
@end
|
||||
111
accessible/mac/mozDocAccessible.mm
Normal file
111
accessible/mac/mozDocAccessible.mm
Normal file
|
|
@ -0,0 +1,111 @@
|
|||
/* -*- 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/. */
|
||||
|
||||
#include "RootAccessibleWrap.h"
|
||||
|
||||
#import "mozDocAccessible.h"
|
||||
|
||||
#import "mozView.h"
|
||||
|
||||
// This must be included last:
|
||||
#include "nsObjCExceptions.h"
|
||||
|
||||
using namespace mozilla::a11y;
|
||||
|
||||
static id <mozAccessible, mozView>
|
||||
getNativeViewFromRootAccessible(Accessible* aAccessible)
|
||||
{
|
||||
RootAccessibleWrap* root =
|
||||
static_cast<RootAccessibleWrap*>(aAccessible->AsRoot());
|
||||
id <mozAccessible, mozView> nativeView = nil;
|
||||
root->GetNativeWidget ((void**)&nativeView);
|
||||
return nativeView;
|
||||
}
|
||||
|
||||
#pragma mark -
|
||||
|
||||
@implementation mozRootAccessible
|
||||
|
||||
- (NSArray*)accessibilityAttributeNames
|
||||
{
|
||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
|
||||
|
||||
// if we're expired, we don't support any attributes.
|
||||
if (![self getGeckoAccessible])
|
||||
return [NSArray array];
|
||||
|
||||
// standard attributes that are shared and supported by root accessible (AXMain) elements.
|
||||
static NSMutableArray* attributes = nil;
|
||||
|
||||
if (!attributes) {
|
||||
attributes = [[super accessibilityAttributeNames] mutableCopy];
|
||||
[attributes addObject:NSAccessibilityMainAttribute];
|
||||
[attributes addObject:NSAccessibilityMinimizedAttribute];
|
||||
}
|
||||
|
||||
return attributes;
|
||||
|
||||
NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
|
||||
}
|
||||
|
||||
- (id)accessibilityAttributeValue:(NSString *)attribute
|
||||
{
|
||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
|
||||
|
||||
if ([attribute isEqualToString:NSAccessibilityMainAttribute])
|
||||
return [NSNumber numberWithBool:[[self window] isMainWindow]];
|
||||
if ([attribute isEqualToString:NSAccessibilityMinimizedAttribute])
|
||||
return [NSNumber numberWithBool:[[self window] isMiniaturized]];
|
||||
|
||||
return [super accessibilityAttributeValue:attribute];
|
||||
|
||||
NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
|
||||
}
|
||||
|
||||
|
||||
// return the AXParent that our parallell NSView tells us about.
|
||||
- (id)parent
|
||||
{
|
||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
|
||||
|
||||
if (!mParallelView)
|
||||
mParallelView = (id<mozView, mozAccessible>)[self representedView];
|
||||
|
||||
if (mParallelView)
|
||||
return [mParallelView accessibilityAttributeValue:NSAccessibilityParentAttribute];
|
||||
|
||||
NSAssert(mParallelView, @"we're a root accessible w/o native view?");
|
||||
return [super parent];
|
||||
|
||||
NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
|
||||
}
|
||||
|
||||
- (BOOL)hasRepresentedView
|
||||
{
|
||||
return YES;
|
||||
}
|
||||
|
||||
// this will return our parallell NSView. see mozDocAccessible.h
|
||||
- (id)representedView
|
||||
{
|
||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
|
||||
|
||||
if (mParallelView)
|
||||
return (id)mParallelView;
|
||||
|
||||
mParallelView = getNativeViewFromRootAccessible ([self getGeckoAccessible]);
|
||||
|
||||
NSAssert(mParallelView, @"can't return root accessible's native parallel view.");
|
||||
return mParallelView;
|
||||
|
||||
NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
|
||||
}
|
||||
|
||||
- (BOOL)isRoot
|
||||
{
|
||||
return YES;
|
||||
}
|
||||
|
||||
@end
|
||||
16
accessible/mac/mozHTMLAccessible.h
Normal file
16
accessible/mac/mozHTMLAccessible.h
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
/* -*- Mode: Objective-C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim:expandtab:shiftwidth=2:tabstop=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"
|
||||
|
||||
@interface mozHeadingAccessible : mozAccessible
|
||||
|
||||
@end
|
||||
|
||||
@interface mozLinkAccessible : mozAccessible
|
||||
|
||||
@end
|
||||
141
accessible/mac/mozHTMLAccessible.mm
Normal file
141
accessible/mac/mozHTMLAccessible.mm
Normal file
|
|
@ -0,0 +1,141 @@
|
|||
/* -*- Mode: Objective-C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim:expandtab:shiftwidth=2:tabstop=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 "mozHTMLAccessible.h"
|
||||
|
||||
#import "Accessible-inl.h"
|
||||
#import "HyperTextAccessible.h"
|
||||
|
||||
#import "nsCocoaUtils.h"
|
||||
|
||||
using namespace mozilla::a11y;
|
||||
|
||||
@implementation mozHeadingAccessible
|
||||
|
||||
- (NSString*)title
|
||||
{
|
||||
nsAutoString title;
|
||||
if (AccessibleWrap* accWrap = [self getGeckoAccessible]) {
|
||||
mozilla::ErrorResult rv;
|
||||
// XXX use the flattening API when there are available
|
||||
// see bug 768298
|
||||
accWrap->GetContent()->GetTextContent(title, rv);
|
||||
} else if (ProxyAccessible* proxy = [self getProxyAccessible]) {
|
||||
proxy->Title(title);
|
||||
}
|
||||
|
||||
return nsCocoaUtils::ToNSString(title);
|
||||
}
|
||||
|
||||
- (id)value
|
||||
{
|
||||
uint32_t level = 0;
|
||||
if (AccessibleWrap* accWrap = [self getGeckoAccessible]) {
|
||||
level = accWrap->GetLevelInternal();
|
||||
} else if (ProxyAccessible* proxy = [self getProxyAccessible]) {
|
||||
level = proxy->GetLevelInternal();
|
||||
}
|
||||
|
||||
return [NSNumber numberWithInt:level];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@interface mozLinkAccessible ()
|
||||
-(NSURL*)url;
|
||||
@end
|
||||
|
||||
@implementation mozLinkAccessible
|
||||
|
||||
- (NSArray*)accessibilityAttributeNames
|
||||
{
|
||||
// if we're expired, we don't support any attributes.
|
||||
if (![self getGeckoAccessible] && ![self getProxyAccessible])
|
||||
return [NSArray array];
|
||||
|
||||
static NSMutableArray* attributes = nil;
|
||||
|
||||
if (!attributes) {
|
||||
attributes = [[super accessibilityAttributeNames] mutableCopy];
|
||||
[attributes addObject:NSAccessibilityURLAttribute];
|
||||
}
|
||||
|
||||
return attributes;
|
||||
}
|
||||
|
||||
- (id)accessibilityAttributeValue:(NSString *)attribute
|
||||
{
|
||||
if ([attribute isEqualToString:NSAccessibilityURLAttribute])
|
||||
return [self url];
|
||||
|
||||
return [super accessibilityAttributeValue:attribute];
|
||||
}
|
||||
|
||||
- (NSArray*)accessibilityActionNames
|
||||
{
|
||||
// if we're expired, we don't support any attributes.
|
||||
if (![self getGeckoAccessible] && ![self getProxyAccessible])
|
||||
return [NSArray array];
|
||||
|
||||
static NSArray* actionNames = nil;
|
||||
|
||||
if (!actionNames) {
|
||||
actionNames = [[NSArray alloc] initWithObjects:NSAccessibilityPressAction,
|
||||
nil];
|
||||
}
|
||||
|
||||
return actionNames;
|
||||
}
|
||||
|
||||
- (void)accessibilityPerformAction:(NSString*)action
|
||||
{
|
||||
AccessibleWrap* accWrap = [self getGeckoAccessible];
|
||||
ProxyAccessible* proxy = [self getProxyAccessible];
|
||||
if (!accWrap && !proxy) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ([action isEqualToString:NSAccessibilityPressAction]) {
|
||||
if (accWrap) {
|
||||
accWrap->DoAction(0);
|
||||
} else if (proxy) {
|
||||
proxy->DoAction(0);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
[super accessibilityPerformAction:action];
|
||||
|
||||
}
|
||||
|
||||
- (NSString*)customDescription
|
||||
{
|
||||
return @"";
|
||||
}
|
||||
|
||||
- (NSString*)value
|
||||
{
|
||||
return @"";
|
||||
}
|
||||
|
||||
- (NSURL*)url
|
||||
{
|
||||
nsAutoString value;
|
||||
if (AccessibleWrap* accWrap = [self getGeckoAccessible]) {
|
||||
accWrap->Value(value);
|
||||
} else if (ProxyAccessible* proxy = [self getProxyAccessible]) {
|
||||
proxy->Value(value);
|
||||
}
|
||||
|
||||
NSString* urlString = value.IsEmpty() ? nil : nsCocoaUtils::ToNSString(value);
|
||||
if (!urlString)
|
||||
return nil;
|
||||
|
||||
return [NSURL URLWithString:urlString];
|
||||
}
|
||||
|
||||
@end
|
||||
28
accessible/mac/mozTableAccessible.h
Normal file
28
accessible/mac/mozTableAccessible.h
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
/* -*- Mode: Objective-C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim:expandtab:shiftwidth=2:tabstop=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"
|
||||
|
||||
@interface mozTablePartAccessible : mozAccessible
|
||||
- (BOOL)isLayoutTablePart;
|
||||
- (NSString*)role;
|
||||
@end
|
||||
|
||||
@interface mozTableAccessible : mozTablePartAccessible
|
||||
- (NSArray*)additionalAccessibilityAttributeNames;
|
||||
- (id)accessibilityAttributeValue:(NSString*)attribute;
|
||||
@end
|
||||
|
||||
@interface mozTableRowAccessible : mozTablePartAccessible
|
||||
- (NSArray*)additionalAccessibilityAttributeNames;
|
||||
- (id)accessibilityAttributeValue:(NSString*)attribute;
|
||||
@end
|
||||
|
||||
@interface mozTableCellAccessible : mozTablePartAccessible
|
||||
- (NSArray*)additionalAccessibilityAttributeNames;
|
||||
- (id)accessibilityAttributeValue:(NSString*)attribute;
|
||||
@end
|
||||
281
accessible/mac/mozTableAccessible.mm
Normal file
281
accessible/mac/mozTableAccessible.mm
Normal file
|
|
@ -0,0 +1,281 @@
|
|||
/* -*- Mode: Objective-C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim:expandtab:shiftwidth=2:tabstop=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 "Accessible-inl.h"
|
||||
#import "mozTableAccessible.h"
|
||||
#import "TableAccessible.h"
|
||||
#import "TableCellAccessible.h"
|
||||
#import "nsCocoaUtils.h"
|
||||
|
||||
using namespace mozilla::a11y;
|
||||
|
||||
// convert an array of Gecko accessibles to an NSArray of native accessibles
|
||||
static inline NSMutableArray*
|
||||
ConvertToNSArray(nsTArray<Accessible*>& aArray)
|
||||
{
|
||||
NSMutableArray* nativeArray = [[NSMutableArray alloc] init];
|
||||
|
||||
// iterate through the list, and get each native accessible.
|
||||
size_t totalCount = aArray.Length();
|
||||
for (size_t i = 0; i < totalCount; i++) {
|
||||
Accessible* curAccessible = aArray.ElementAt(i);
|
||||
mozAccessible* curNative = GetNativeFromGeckoAccessible(curAccessible);
|
||||
if (curNative)
|
||||
[nativeArray addObject:GetObjectOrRepresentedView(curNative)];
|
||||
}
|
||||
|
||||
return nativeArray;
|
||||
}
|
||||
|
||||
// convert an array of Gecko proxy accessibles to an NSArray of native accessibles
|
||||
static inline NSMutableArray*
|
||||
ConvertToNSArray(nsTArray<ProxyAccessible*>& aArray)
|
||||
{
|
||||
NSMutableArray* nativeArray = [[NSMutableArray alloc] init];
|
||||
|
||||
// iterate through the list, and get each native accessible.
|
||||
size_t totalCount = aArray.Length();
|
||||
for (size_t i = 0; i < totalCount; i++) {
|
||||
ProxyAccessible* curAccessible = aArray.ElementAt(i);
|
||||
mozAccessible* curNative = GetNativeFromProxy(curAccessible);
|
||||
if (curNative)
|
||||
[nativeArray addObject:GetObjectOrRepresentedView(curNative)];
|
||||
}
|
||||
|
||||
return nativeArray;
|
||||
}
|
||||
|
||||
@implementation mozTablePartAccessible
|
||||
- (BOOL)isLayoutTablePart;
|
||||
{
|
||||
if (Accessible* accWrap = [self getGeckoAccessible]) {
|
||||
while (accWrap) {
|
||||
if (accWrap->IsTable()) {
|
||||
return accWrap->AsTable()->IsProbablyLayoutTable();
|
||||
}
|
||||
accWrap = accWrap->Parent();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
if (ProxyAccessible* proxy = [self getProxyAccessible]) {
|
||||
while (proxy) {
|
||||
if (proxy->IsTable()) {
|
||||
return proxy->TableIsProbablyForLayout();
|
||||
}
|
||||
proxy = proxy->Parent();
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
- (NSString*)role
|
||||
{
|
||||
return [self isLayoutTablePart] ? NSAccessibilityGroupRole : [super role];
|
||||
}
|
||||
@end
|
||||
|
||||
@implementation mozTableAccessible
|
||||
- (NSArray*)additionalAccessibilityAttributeNames
|
||||
{
|
||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
|
||||
|
||||
NSArray* additionalAttributes = [super additionalAccessibilityAttributeNames];
|
||||
if ([self isLayoutTablePart]) {
|
||||
return additionalAttributes;
|
||||
}
|
||||
|
||||
static NSArray* tableAttrs = nil;
|
||||
if (!tableAttrs) {
|
||||
NSMutableArray* tempArray = [NSMutableArray new];
|
||||
[tempArray addObject:NSAccessibilityRowCountAttribute];
|
||||
[tempArray addObject:NSAccessibilityColumnCountAttribute];
|
||||
[tempArray addObject:NSAccessibilityRowsAttribute];
|
||||
tableAttrs = [[NSArray alloc] initWithArray:tempArray];
|
||||
[tempArray release];
|
||||
}
|
||||
|
||||
return [additionalAttributes arrayByAddingObjectsFromArray:tableAttrs];
|
||||
|
||||
NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
|
||||
}
|
||||
|
||||
- (id)accessibilityAttributeValue:(NSString*)attribute
|
||||
{
|
||||
if (AccessibleWrap* accWrap = [self getGeckoAccessible]) {
|
||||
TableAccessible* table = accWrap->AsTable();
|
||||
if ([attribute isEqualToString:NSAccessibilityRowCountAttribute])
|
||||
return @(table->RowCount());
|
||||
if ([attribute isEqualToString:NSAccessibilityColumnCountAttribute])
|
||||
return @(table->ColCount());
|
||||
if ([attribute isEqualToString:NSAccessibilityRowsAttribute]) {
|
||||
// Create a new array with the list of table rows.
|
||||
NSMutableArray* nativeArray = [[NSMutableArray alloc] init];
|
||||
uint32_t totalCount = accWrap->ChildCount();
|
||||
for (uint32_t i = 0; i < totalCount; i++) {
|
||||
if (accWrap->GetChildAt(i)->IsTableRow()) {
|
||||
mozAccessible* curNative =
|
||||
GetNativeFromGeckoAccessible(accWrap->GetChildAt(i));
|
||||
if (curNative)
|
||||
[nativeArray addObject:GetObjectOrRepresentedView(curNative)];
|
||||
}
|
||||
}
|
||||
return nativeArray;
|
||||
}
|
||||
} else if (ProxyAccessible* proxy = [self getProxyAccessible]) {
|
||||
if ([attribute isEqualToString:NSAccessibilityRowCountAttribute])
|
||||
return @(proxy->TableRowCount());
|
||||
if ([attribute isEqualToString:NSAccessibilityColumnCountAttribute])
|
||||
return @(proxy->TableColumnCount());
|
||||
if ([attribute isEqualToString:NSAccessibilityRowsAttribute]) {
|
||||
// Create a new array with the list of table rows.
|
||||
NSMutableArray* nativeArray = [[NSMutableArray alloc] init];
|
||||
uint32_t totalCount = proxy->ChildrenCount();
|
||||
for (uint32_t i = 0; i < totalCount; i++) {
|
||||
if (proxy->ChildAt(i)->IsTableRow()) {
|
||||
mozAccessible* curNative =
|
||||
GetNativeFromProxy(proxy->ChildAt(i));
|
||||
if (curNative)
|
||||
[nativeArray addObject:GetObjectOrRepresentedView(curNative)];
|
||||
}
|
||||
}
|
||||
return nativeArray;
|
||||
}
|
||||
}
|
||||
|
||||
return [super accessibilityAttributeValue:attribute];
|
||||
}
|
||||
@end
|
||||
|
||||
@implementation mozTableRowAccessible
|
||||
- (NSArray*)additionalAccessibilityAttributeNames
|
||||
{
|
||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
|
||||
|
||||
NSArray* additionalAttributes = [super additionalAccessibilityAttributeNames];
|
||||
if ([self isLayoutTablePart]) {
|
||||
return additionalAttributes;
|
||||
}
|
||||
|
||||
static NSArray* tableRowAttrs = nil;
|
||||
if (!tableRowAttrs) {
|
||||
NSMutableArray* tempArray = [NSMutableArray new];
|
||||
[tempArray addObject:NSAccessibilityIndexAttribute];
|
||||
tableRowAttrs = [[NSArray alloc] initWithArray:tempArray];
|
||||
[tempArray release];
|
||||
}
|
||||
|
||||
return [additionalAttributes arrayByAddingObjectsFromArray:tableRowAttrs];
|
||||
|
||||
NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
|
||||
}
|
||||
|
||||
- (id)accessibilityAttributeValue:(NSString*)attribute
|
||||
{
|
||||
if (AccessibleWrap* accWrap = [self getGeckoAccessible]) {
|
||||
if ([attribute isEqualToString:NSAccessibilityIndexAttribute]) {
|
||||
// Count the number of rows before that one to obtain the row index.
|
||||
uint32_t index = 0;
|
||||
Accessible* parent = accWrap->Parent();
|
||||
if (parent) {
|
||||
for (int32_t i = accWrap->IndexInParent() - 1; i >= 0; i--) {
|
||||
if (parent->GetChildAt(i)->IsTableRow()) {
|
||||
index++;
|
||||
}
|
||||
}
|
||||
}
|
||||
return [NSNumber numberWithUnsignedInteger:index];
|
||||
}
|
||||
} else if (ProxyAccessible* proxy = [self getProxyAccessible]) {
|
||||
if ([attribute isEqualToString:NSAccessibilityIndexAttribute]) {
|
||||
// Count the number of rows before that one to obtain the row index.
|
||||
uint32_t index = 0;
|
||||
ProxyAccessible* parent = proxy->Parent();
|
||||
if (parent) {
|
||||
for (int32_t i = proxy->IndexInParent() - 1; i >= 0; i--) {
|
||||
if (parent->ChildAt(i)->IsTableRow()) {
|
||||
index++;
|
||||
}
|
||||
}
|
||||
}
|
||||
return [NSNumber numberWithUnsignedInteger:index];
|
||||
}
|
||||
}
|
||||
|
||||
return [super accessibilityAttributeValue:attribute];
|
||||
}
|
||||
@end
|
||||
|
||||
@implementation mozTableCellAccessible
|
||||
- (NSArray*)additionalAccessibilityAttributeNames
|
||||
{
|
||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
|
||||
|
||||
NSArray* additionalAttributes = [super additionalAccessibilityAttributeNames];
|
||||
if ([self isLayoutTablePart]) {
|
||||
return additionalAttributes;
|
||||
}
|
||||
|
||||
static NSArray* tableCellAttrs = nil;
|
||||
if (!tableCellAttrs) {
|
||||
NSMutableArray* tempArray = [NSMutableArray new];
|
||||
[tempArray addObject:NSAccessibilityRowIndexRangeAttribute];
|
||||
[tempArray addObject:NSAccessibilityColumnIndexRangeAttribute];
|
||||
[tempArray addObject:NSAccessibilityRowHeaderUIElementsAttribute];
|
||||
[tempArray addObject:NSAccessibilityColumnHeaderUIElementsAttribute];
|
||||
tableCellAttrs = [[NSArray alloc] initWithArray:tempArray];
|
||||
[tempArray release];
|
||||
}
|
||||
|
||||
return [additionalAttributes arrayByAddingObjectsFromArray:tableCellAttrs];
|
||||
|
||||
NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
|
||||
}
|
||||
|
||||
- (id)accessibilityAttributeValue:(NSString*)attribute
|
||||
{
|
||||
if (AccessibleWrap* accWrap = [self getGeckoAccessible]) {
|
||||
TableCellAccessible* cell = accWrap->AsTableCell();
|
||||
if ([attribute isEqualToString:NSAccessibilityRowIndexRangeAttribute])
|
||||
return [NSValue valueWithRange:NSMakeRange(cell->RowIdx(),
|
||||
cell->RowExtent())];
|
||||
if ([attribute isEqualToString:NSAccessibilityColumnIndexRangeAttribute])
|
||||
return [NSValue valueWithRange:NSMakeRange(cell->ColIdx(),
|
||||
cell->ColExtent())];
|
||||
if ([attribute isEqualToString:NSAccessibilityRowHeaderUIElementsAttribute]) {
|
||||
AutoTArray<Accessible*, 10> headerCells;
|
||||
cell->RowHeaderCells(&headerCells);
|
||||
return ConvertToNSArray(headerCells);
|
||||
}
|
||||
if ([attribute isEqualToString:NSAccessibilityColumnHeaderUIElementsAttribute]) {
|
||||
AutoTArray<Accessible*, 10> headerCells;
|
||||
cell->ColHeaderCells(&headerCells);
|
||||
return ConvertToNSArray(headerCells);
|
||||
}
|
||||
} else if (ProxyAccessible* proxy = [self getProxyAccessible]) {
|
||||
if ([attribute isEqualToString:NSAccessibilityRowIndexRangeAttribute])
|
||||
return [NSValue valueWithRange:NSMakeRange(proxy->RowIdx(),
|
||||
proxy->RowExtent())];
|
||||
if ([attribute isEqualToString:NSAccessibilityColumnIndexRangeAttribute])
|
||||
return [NSValue valueWithRange:NSMakeRange(proxy->ColIdx(),
|
||||
proxy->ColExtent())];
|
||||
if ([attribute isEqualToString:NSAccessibilityRowHeaderUIElementsAttribute]) {
|
||||
nsTArray<ProxyAccessible*> headerCells;
|
||||
proxy->RowHeaderCells(&headerCells);
|
||||
return ConvertToNSArray(headerCells);
|
||||
}
|
||||
if ([attribute isEqualToString:NSAccessibilityColumnHeaderUIElementsAttribute]) {
|
||||
nsTArray<ProxyAccessible*> headerCells;
|
||||
proxy->ColHeaderCells(&headerCells);
|
||||
return ConvertToNSArray(headerCells);
|
||||
}
|
||||
}
|
||||
|
||||
return [super accessibilityAttributeValue:attribute];
|
||||
}
|
||||
@end
|
||||
17
accessible/mac/mozTextAccessible.h
Normal file
17
accessible/mac/mozTextAccessible.h
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
/* 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 "HyperTextAccessible.h"
|
||||
|
||||
@interface mozTextAccessible : mozAccessible
|
||||
{
|
||||
}
|
||||
@end
|
||||
|
||||
@interface mozTextLeafAccessible : mozAccessible
|
||||
{
|
||||
}
|
||||
@end
|
||||
627
accessible/mac/mozTextAccessible.mm
Normal file
627
accessible/mac/mozTextAccessible.mm
Normal file
|
|
@ -0,0 +1,627 @@
|
|||
/* -*- 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/. */
|
||||
|
||||
#include "Accessible-inl.h"
|
||||
#include "HyperTextAccessible-inl.h"
|
||||
#include "TextLeafAccessible.h"
|
||||
|
||||
#include "nsCocoaUtils.h"
|
||||
#include "nsObjCExceptions.h"
|
||||
|
||||
#import "mozTextAccessible.h"
|
||||
|
||||
using namespace mozilla;
|
||||
using namespace mozilla::a11y;
|
||||
|
||||
inline bool
|
||||
ToNSRange(id aValue, NSRange* aRange)
|
||||
{
|
||||
NS_PRECONDITION(aRange, "aRange is nil");
|
||||
|
||||
if ([aValue isKindOfClass:[NSValue class]] &&
|
||||
strcmp([(NSValue*)aValue objCType], @encode(NSRange)) == 0) {
|
||||
*aRange = [aValue rangeValue];
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
inline NSString*
|
||||
ToNSString(id aValue)
|
||||
{
|
||||
if ([aValue isKindOfClass:[NSString class]]) {
|
||||
return aValue;
|
||||
}
|
||||
|
||||
return nil;
|
||||
}
|
||||
|
||||
@interface mozTextAccessible ()
|
||||
- (NSString*)subrole;
|
||||
- (NSString*)selectedText;
|
||||
- (NSValue*)selectedTextRange;
|
||||
- (NSValue*)visibleCharacterRange;
|
||||
- (long)textLength;
|
||||
- (BOOL)isReadOnly;
|
||||
- (NSNumber*)caretLineNumber;
|
||||
- (void)setText:(NSString*)newText;
|
||||
- (NSString*)text;
|
||||
- (NSString*)stringFromRange:(NSRange*)range;
|
||||
@end
|
||||
|
||||
@implementation mozTextAccessible
|
||||
|
||||
- (BOOL)accessibilityIsIgnored
|
||||
{
|
||||
return ![self getGeckoAccessible] && ![self getProxyAccessible];
|
||||
}
|
||||
|
||||
- (NSArray*)accessibilityAttributeNames
|
||||
{
|
||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
|
||||
|
||||
static NSMutableArray* supportedAttributes = nil;
|
||||
if (!supportedAttributes) {
|
||||
// text-specific attributes to supplement the standard one
|
||||
supportedAttributes = [[NSMutableArray alloc] initWithObjects:
|
||||
NSAccessibilitySelectedTextAttribute, // required
|
||||
NSAccessibilitySelectedTextRangeAttribute, // required
|
||||
NSAccessibilityNumberOfCharactersAttribute, // required
|
||||
NSAccessibilityVisibleCharacterRangeAttribute, // required
|
||||
NSAccessibilityInsertionPointLineNumberAttribute,
|
||||
@"AXRequired",
|
||||
@"AXInvalid",
|
||||
nil
|
||||
];
|
||||
[supportedAttributes addObjectsFromArray:[super accessibilityAttributeNames]];
|
||||
}
|
||||
return supportedAttributes;
|
||||
|
||||
NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
|
||||
}
|
||||
|
||||
- (id)accessibilityAttributeValue:(NSString*)attribute
|
||||
{
|
||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
|
||||
|
||||
if ([attribute isEqualToString:NSAccessibilityNumberOfCharactersAttribute])
|
||||
return [NSNumber numberWithInt:[self textLength]];
|
||||
|
||||
if ([attribute isEqualToString:NSAccessibilityInsertionPointLineNumberAttribute])
|
||||
return [self caretLineNumber];
|
||||
|
||||
if ([attribute isEqualToString:NSAccessibilitySelectedTextRangeAttribute])
|
||||
return [self selectedTextRange];
|
||||
|
||||
if ([attribute isEqualToString:NSAccessibilitySelectedTextAttribute])
|
||||
return [self selectedText];
|
||||
|
||||
if ([attribute isEqualToString:NSAccessibilityTitleAttribute])
|
||||
return @"";
|
||||
|
||||
if ([attribute isEqualToString:NSAccessibilityValueAttribute]) {
|
||||
// Apple's SpeechSynthesisServer expects AXValue to return an AXStaticText
|
||||
// object's AXSelectedText attribute. See bug 674612 for details.
|
||||
// Also if there is no selected text, we return the full text.
|
||||
// See bug 369710 for details.
|
||||
if ([[self role] isEqualToString:NSAccessibilityStaticTextRole]) {
|
||||
NSString* selectedText = [self selectedText];
|
||||
return (selectedText && [selectedText length]) ? selectedText : [self text];
|
||||
}
|
||||
|
||||
return [self text];
|
||||
}
|
||||
|
||||
if (AccessibleWrap* accWrap = [self getGeckoAccessible]) {
|
||||
if ([attribute isEqualToString:@"AXRequired"]) {
|
||||
return [NSNumber numberWithBool:!!(accWrap->State() & states::REQUIRED)];
|
||||
}
|
||||
|
||||
if ([attribute isEqualToString:@"AXInvalid"]) {
|
||||
return [NSNumber numberWithBool:!!(accWrap->State() & states::INVALID)];
|
||||
}
|
||||
} else if (ProxyAccessible* proxy = [self getProxyAccessible]) {
|
||||
if ([attribute isEqualToString:@"AXRequired"]) {
|
||||
return [NSNumber numberWithBool:!!(proxy->State() & states::REQUIRED)];
|
||||
}
|
||||
|
||||
if ([attribute isEqualToString:@"AXInvalid"]) {
|
||||
return [NSNumber numberWithBool:!!(proxy->State() & states::INVALID)];
|
||||
}
|
||||
}
|
||||
|
||||
if ([attribute isEqualToString:NSAccessibilityVisibleCharacterRangeAttribute])
|
||||
return [self visibleCharacterRange];
|
||||
|
||||
// let mozAccessible handle all other attributes
|
||||
return [super accessibilityAttributeValue:attribute];
|
||||
|
||||
NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
|
||||
}
|
||||
|
||||
- (NSArray*)accessibilityParameterizedAttributeNames
|
||||
{
|
||||
static NSArray* supportedParametrizedAttributes = nil;
|
||||
// text specific parametrized attributes
|
||||
if (!supportedParametrizedAttributes) {
|
||||
supportedParametrizedAttributes = [[NSArray alloc] initWithObjects:
|
||||
NSAccessibilityStringForRangeParameterizedAttribute,
|
||||
NSAccessibilityLineForIndexParameterizedAttribute,
|
||||
NSAccessibilityRangeForLineParameterizedAttribute,
|
||||
NSAccessibilityAttributedStringForRangeParameterizedAttribute,
|
||||
NSAccessibilityBoundsForRangeParameterizedAttribute,
|
||||
#if DEBUG
|
||||
NSAccessibilityRangeForPositionParameterizedAttribute,
|
||||
NSAccessibilityRangeForIndexParameterizedAttribute,
|
||||
NSAccessibilityRTFForRangeParameterizedAttribute,
|
||||
NSAccessibilityStyleRangeForIndexParameterizedAttribute,
|
||||
#endif
|
||||
nil
|
||||
];
|
||||
}
|
||||
return supportedParametrizedAttributes;
|
||||
}
|
||||
|
||||
- (id)accessibilityAttributeValue:(NSString*)attribute forParameter:(id)parameter
|
||||
{
|
||||
AccessibleWrap* accWrap = [self getGeckoAccessible];
|
||||
ProxyAccessible* proxy = [self getProxyAccessible];
|
||||
|
||||
HyperTextAccessible* textAcc = accWrap? accWrap->AsHyperText() : nullptr;
|
||||
if (!textAcc && !proxy)
|
||||
return nil;
|
||||
|
||||
if ([attribute isEqualToString:NSAccessibilityStringForRangeParameterizedAttribute]) {
|
||||
NSRange range;
|
||||
if (!ToNSRange(parameter, &range)) {
|
||||
#if DEBUG
|
||||
NSLog(@"%@: range not set", attribute);
|
||||
#endif
|
||||
return @"";
|
||||
}
|
||||
|
||||
return [self stringFromRange:&range];
|
||||
}
|
||||
|
||||
if ([attribute isEqualToString:NSAccessibilityRangeForLineParameterizedAttribute]) {
|
||||
// XXX: actually get the integer value for the line #
|
||||
return [NSValue valueWithRange:NSMakeRange(0, [self textLength])];
|
||||
}
|
||||
|
||||
if ([attribute isEqualToString:NSAccessibilityAttributedStringForRangeParameterizedAttribute]) {
|
||||
NSRange range;
|
||||
if (!ToNSRange(parameter, &range)) {
|
||||
#if DEBUG
|
||||
NSLog(@"%@: range not set", attribute);
|
||||
#endif
|
||||
return @"";
|
||||
}
|
||||
|
||||
return [[[NSAttributedString alloc] initWithString:[self stringFromRange:&range]] autorelease];
|
||||
}
|
||||
|
||||
if ([attribute isEqualToString:NSAccessibilityLineForIndexParameterizedAttribute]) {
|
||||
// XXX: actually return the line #
|
||||
return [NSNumber numberWithInt:0];
|
||||
}
|
||||
|
||||
if ([attribute isEqualToString:NSAccessibilityBoundsForRangeParameterizedAttribute]) {
|
||||
NSRange range;
|
||||
if (!ToNSRange(parameter, &range)) {
|
||||
#if DEBUG
|
||||
NSLog(@"%@:no range", attribute);
|
||||
#endif
|
||||
return nil;
|
||||
}
|
||||
|
||||
int32_t start = range.location;
|
||||
int32_t end = start + range.length;
|
||||
DesktopIntRect bounds;
|
||||
if (textAcc) {
|
||||
bounds =
|
||||
DesktopIntRect::FromUnknownRect(textAcc->TextBounds(start, end));
|
||||
} else if (proxy) {
|
||||
bounds =
|
||||
DesktopIntRect::FromUnknownRect(proxy->TextBounds(start, end));
|
||||
}
|
||||
|
||||
return [NSValue valueWithRect:nsCocoaUtils::GeckoRectToCocoaRect(bounds)];
|
||||
}
|
||||
|
||||
#if DEBUG
|
||||
NSLog(@"unhandled attribute:%@ forParameter:%@", attribute, parameter);
|
||||
#endif
|
||||
|
||||
return nil;
|
||||
}
|
||||
|
||||
- (BOOL)accessibilityIsAttributeSettable:(NSString*)attribute
|
||||
{
|
||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_RETURN;
|
||||
|
||||
if ([attribute isEqualToString:NSAccessibilityValueAttribute])
|
||||
return ![self isReadOnly];
|
||||
|
||||
if ([attribute isEqualToString:NSAccessibilitySelectedTextAttribute] ||
|
||||
[attribute isEqualToString:NSAccessibilitySelectedTextRangeAttribute] ||
|
||||
[attribute isEqualToString:NSAccessibilityVisibleCharacterRangeAttribute])
|
||||
return YES;
|
||||
|
||||
return [super accessibilityIsAttributeSettable:attribute];
|
||||
|
||||
NS_OBJC_END_TRY_ABORT_BLOCK_RETURN(NO);
|
||||
}
|
||||
|
||||
- (void)accessibilitySetValue:(id)value forAttribute:(NSString *)attribute
|
||||
{
|
||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK;
|
||||
|
||||
AccessibleWrap* accWrap = [self getGeckoAccessible];
|
||||
ProxyAccessible* proxy = [self getProxyAccessible];
|
||||
|
||||
HyperTextAccessible* textAcc = accWrap? accWrap->AsHyperText() : nullptr;
|
||||
if (!textAcc && !proxy)
|
||||
return;
|
||||
|
||||
if ([attribute isEqualToString:NSAccessibilityValueAttribute]) {
|
||||
[self setText:ToNSString(value)];
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if ([attribute isEqualToString:NSAccessibilitySelectedTextAttribute]) {
|
||||
NSString* stringValue = ToNSString(value);
|
||||
if (!stringValue)
|
||||
return;
|
||||
|
||||
int32_t start = 0, end = 0;
|
||||
nsString text;
|
||||
if (textAcc) {
|
||||
textAcc->SelectionBoundsAt(0, &start, &end);
|
||||
textAcc->DeleteText(start, end - start);
|
||||
nsCocoaUtils::GetStringForNSString(stringValue, text);
|
||||
textAcc->InsertText(text, start);
|
||||
} else if (proxy) {
|
||||
nsString data;
|
||||
proxy->SelectionBoundsAt(0, data, &start, &end);
|
||||
proxy->DeleteText(start, end - start);
|
||||
nsCocoaUtils::GetStringForNSString(stringValue, text);
|
||||
proxy->InsertText(text, start);
|
||||
}
|
||||
}
|
||||
|
||||
if ([attribute isEqualToString:NSAccessibilitySelectedTextRangeAttribute]) {
|
||||
NSRange range;
|
||||
if (!ToNSRange(value, &range))
|
||||
return;
|
||||
|
||||
if (textAcc) {
|
||||
textAcc->SetSelectionBoundsAt(0, range.location,
|
||||
range.location + range.length);
|
||||
} else if (proxy) {
|
||||
proxy->SetSelectionBoundsAt(0, range.location,
|
||||
range.location + range.length);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if ([attribute isEqualToString:NSAccessibilityVisibleCharacterRangeAttribute]) {
|
||||
NSRange range;
|
||||
if (!ToNSRange(value, &range))
|
||||
return;
|
||||
|
||||
if (textAcc) {
|
||||
textAcc->ScrollSubstringTo(range.location, range.location + range.length,
|
||||
nsIAccessibleScrollType::SCROLL_TYPE_TOP_EDGE);
|
||||
} else if (proxy) {
|
||||
proxy->ScrollSubstringTo(range.location, range.location + range.length,
|
||||
nsIAccessibleScrollType::SCROLL_TYPE_TOP_EDGE);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
[super accessibilitySetValue:value forAttribute:attribute];
|
||||
|
||||
NS_OBJC_END_TRY_ABORT_BLOCK;
|
||||
}
|
||||
|
||||
- (NSString*)subrole
|
||||
{
|
||||
if(mRole == roles::PASSWORD_TEXT)
|
||||
return NSAccessibilitySecureTextFieldSubrole;
|
||||
|
||||
return nil;
|
||||
}
|
||||
|
||||
#pragma mark -
|
||||
|
||||
- (BOOL)isReadOnly
|
||||
{
|
||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_RETURN;
|
||||
|
||||
if ([[self role] isEqualToString:NSAccessibilityStaticTextRole])
|
||||
return YES;
|
||||
|
||||
AccessibleWrap* accWrap = [self getGeckoAccessible];
|
||||
HyperTextAccessible* textAcc = accWrap? accWrap->AsHyperText() : nullptr;
|
||||
if (textAcc)
|
||||
return (accWrap->State() & states::READONLY) == 0;
|
||||
|
||||
if (ProxyAccessible* proxy = [self getProxyAccessible])
|
||||
return (proxy->State() & states::READONLY) == 0;
|
||||
|
||||
return NO;
|
||||
|
||||
NS_OBJC_END_TRY_ABORT_BLOCK_RETURN(NO);
|
||||
}
|
||||
|
||||
- (NSNumber*)caretLineNumber
|
||||
{
|
||||
AccessibleWrap* accWrap = [self getGeckoAccessible];
|
||||
HyperTextAccessible* textAcc = accWrap? accWrap->AsHyperText() : nullptr;
|
||||
|
||||
int32_t lineNumber = -1;
|
||||
if (textAcc) {
|
||||
lineNumber = textAcc->CaretLineNumber() - 1;
|
||||
} else if (ProxyAccessible* proxy = [self getProxyAccessible]) {
|
||||
lineNumber = proxy->CaretLineNumber() - 1;
|
||||
}
|
||||
|
||||
return (lineNumber >= 0) ? [NSNumber numberWithInt:lineNumber] : nil;
|
||||
}
|
||||
|
||||
- (void)setText:(NSString*)aNewString
|
||||
{
|
||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK;
|
||||
|
||||
AccessibleWrap* accWrap = [self getGeckoAccessible];
|
||||
HyperTextAccessible* textAcc = accWrap? accWrap->AsHyperText() : nullptr;
|
||||
|
||||
nsString text;
|
||||
nsCocoaUtils::GetStringForNSString(aNewString, text);
|
||||
if (textAcc) {
|
||||
textAcc->ReplaceText(text);
|
||||
} else if (ProxyAccessible* proxy = [self getProxyAccessible]) {
|
||||
proxy->ReplaceText(text);
|
||||
}
|
||||
|
||||
NS_OBJC_END_TRY_ABORT_BLOCK;
|
||||
}
|
||||
|
||||
- (NSString*)text
|
||||
{
|
||||
AccessibleWrap* accWrap = [self getGeckoAccessible];
|
||||
ProxyAccessible* proxy = [self getProxyAccessible];
|
||||
HyperTextAccessible* textAcc = accWrap? accWrap->AsHyperText() : nullptr;
|
||||
if (!textAcc && !proxy)
|
||||
return nil;
|
||||
|
||||
// A password text field returns an empty value
|
||||
if (mRole == roles::PASSWORD_TEXT)
|
||||
return @"";
|
||||
|
||||
nsAutoString text;
|
||||
if (textAcc) {
|
||||
textAcc->TextSubstring(0, nsIAccessibleText::TEXT_OFFSET_END_OF_TEXT, text);
|
||||
} else if (proxy) {
|
||||
proxy->TextSubstring(0, nsIAccessibleText::TEXT_OFFSET_END_OF_TEXT, text);
|
||||
}
|
||||
|
||||
return nsCocoaUtils::ToNSString(text);
|
||||
}
|
||||
|
||||
- (long)textLength
|
||||
{
|
||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_RETURN;
|
||||
|
||||
AccessibleWrap* accWrap = [self getGeckoAccessible];
|
||||
ProxyAccessible* proxy = [self getProxyAccessible];
|
||||
HyperTextAccessible* textAcc = accWrap? accWrap->AsHyperText() : nullptr;
|
||||
if (!textAcc && !proxy)
|
||||
return 0;
|
||||
|
||||
return textAcc ? textAcc->CharacterCount() : proxy->CharacterCount();
|
||||
|
||||
NS_OBJC_END_TRY_ABORT_BLOCK_RETURN(0);
|
||||
}
|
||||
|
||||
- (long)selectedTextLength
|
||||
{
|
||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_RETURN;
|
||||
|
||||
AccessibleWrap* accWrap = [self getGeckoAccessible];
|
||||
ProxyAccessible* proxy = [self getProxyAccessible];
|
||||
HyperTextAccessible* textAcc = accWrap? accWrap->AsHyperText() : nullptr;
|
||||
if (!textAcc && !proxy)
|
||||
return 0;
|
||||
|
||||
int32_t start = 0, end = 0;
|
||||
if (textAcc) {
|
||||
textAcc->SelectionBoundsAt(0, &start, &end);
|
||||
} else if (proxy) {
|
||||
nsString data;
|
||||
proxy->SelectionBoundsAt(0, data, &start, &end);
|
||||
}
|
||||
return (end - start);
|
||||
|
||||
NS_OBJC_END_TRY_ABORT_BLOCK_RETURN(0);
|
||||
}
|
||||
|
||||
- (NSString*)selectedText
|
||||
{
|
||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
|
||||
|
||||
AccessibleWrap* accWrap = [self getGeckoAccessible];
|
||||
ProxyAccessible* proxy = [self getProxyAccessible];
|
||||
HyperTextAccessible* textAcc = accWrap? accWrap->AsHyperText() : nullptr;
|
||||
if (!textAcc && !proxy)
|
||||
return nil;
|
||||
|
||||
int32_t start = 0, end = 0;
|
||||
nsAutoString selText;
|
||||
if (textAcc) {
|
||||
textAcc->SelectionBoundsAt(0, &start, &end);
|
||||
if (start != end) {
|
||||
textAcc->TextSubstring(start, end, selText);
|
||||
}
|
||||
} else if (proxy) {
|
||||
proxy->SelectionBoundsAt(0, selText, &start, &end);
|
||||
}
|
||||
|
||||
return nsCocoaUtils::ToNSString(selText);
|
||||
|
||||
NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
|
||||
}
|
||||
|
||||
- (NSValue*)selectedTextRange
|
||||
{
|
||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
|
||||
|
||||
AccessibleWrap* accWrap = [self getGeckoAccessible];
|
||||
ProxyAccessible* proxy = [self getProxyAccessible];
|
||||
HyperTextAccessible* textAcc = accWrap? accWrap->AsHyperText() : nullptr;
|
||||
|
||||
int32_t start = 0;
|
||||
int32_t end = 0;
|
||||
int32_t count = 0;
|
||||
if (textAcc) {
|
||||
count = textAcc->SelectionCount();
|
||||
if (count) {
|
||||
textAcc->SelectionBoundsAt(0, &start, &end);
|
||||
return [NSValue valueWithRange:NSMakeRange(start, end - start)];
|
||||
}
|
||||
|
||||
start = textAcc->CaretOffset();
|
||||
return [NSValue valueWithRange:NSMakeRange(start != -1 ? start : 0, 0)];
|
||||
}
|
||||
|
||||
if (proxy) {
|
||||
count = proxy->SelectionCount();
|
||||
if (count) {
|
||||
nsString data;
|
||||
proxy->SelectionBoundsAt(0, data, &start, &end);
|
||||
return [NSValue valueWithRange:NSMakeRange(start, end - start)];
|
||||
}
|
||||
|
||||
start = proxy->CaretOffset();
|
||||
return [NSValue valueWithRange:NSMakeRange(start != -1 ? start : 0, 0)];
|
||||
}
|
||||
|
||||
return [NSValue valueWithRange:NSMakeRange(0, 0)];
|
||||
|
||||
NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
|
||||
}
|
||||
|
||||
- (NSValue*)visibleCharacterRange
|
||||
{
|
||||
// XXX this won't work with Textarea and such as we actually don't give
|
||||
// the visible character range.
|
||||
AccessibleWrap* accWrap = [self getGeckoAccessible];
|
||||
ProxyAccessible* proxy = [self getProxyAccessible];
|
||||
HyperTextAccessible* textAcc = accWrap? accWrap->AsHyperText() : nullptr;
|
||||
if (!textAcc && !proxy)
|
||||
return 0;
|
||||
|
||||
return [NSValue valueWithRange:
|
||||
NSMakeRange(0, textAcc ?
|
||||
textAcc->CharacterCount() : proxy->CharacterCount())];
|
||||
}
|
||||
|
||||
- (void)valueDidChange
|
||||
{
|
||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK;
|
||||
|
||||
NSAccessibilityPostNotification(GetObjectOrRepresentedView(self),
|
||||
NSAccessibilityValueChangedNotification);
|
||||
|
||||
NS_OBJC_END_TRY_ABORT_BLOCK;
|
||||
}
|
||||
|
||||
- (void)selectedTextDidChange
|
||||
{
|
||||
NSAccessibilityPostNotification(GetObjectOrRepresentedView(self),
|
||||
NSAccessibilitySelectedTextChangedNotification);
|
||||
}
|
||||
|
||||
- (NSString*)stringFromRange:(NSRange*)range
|
||||
{
|
||||
NS_PRECONDITION(range, "no range");
|
||||
|
||||
AccessibleWrap* accWrap = [self getGeckoAccessible];
|
||||
ProxyAccessible* proxy = [self getProxyAccessible];
|
||||
HyperTextAccessible* textAcc = accWrap? accWrap->AsHyperText() : nullptr;
|
||||
if (!textAcc && !proxy)
|
||||
return nil;
|
||||
|
||||
nsAutoString text;
|
||||
if (textAcc) {
|
||||
textAcc->TextSubstring(range->location,
|
||||
range->location + range->length, text);
|
||||
} else if (proxy) {
|
||||
proxy->TextSubstring(range->location,
|
||||
range->location + range->length, text);
|
||||
}
|
||||
|
||||
return nsCocoaUtils::ToNSString(text);
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@implementation mozTextLeafAccessible
|
||||
|
||||
- (NSArray*)accessibilityAttributeNames
|
||||
{
|
||||
static NSMutableArray* supportedAttributes = nil;
|
||||
if (!supportedAttributes) {
|
||||
supportedAttributes = [[super accessibilityAttributeNames] mutableCopy];
|
||||
[supportedAttributes removeObject:NSAccessibilityChildrenAttribute];
|
||||
}
|
||||
|
||||
return supportedAttributes;
|
||||
}
|
||||
|
||||
- (id)accessibilityAttributeValue:(NSString*)attribute
|
||||
{
|
||||
if ([attribute isEqualToString:NSAccessibilityTitleAttribute])
|
||||
return @"";
|
||||
|
||||
if ([attribute isEqualToString:NSAccessibilityValueAttribute])
|
||||
return [self text];
|
||||
|
||||
return [super accessibilityAttributeValue:attribute];
|
||||
}
|
||||
|
||||
- (NSString*)text
|
||||
{
|
||||
if (AccessibleWrap* accWrap = [self getGeckoAccessible]) {
|
||||
return nsCocoaUtils::ToNSString(accWrap->AsTextLeaf()->Text());
|
||||
}
|
||||
|
||||
if (ProxyAccessible* proxy = [self getProxyAccessible]) {
|
||||
nsString text;
|
||||
proxy->Text(&text);
|
||||
return nsCocoaUtils::ToNSString(text);
|
||||
}
|
||||
|
||||
return nil;
|
||||
}
|
||||
|
||||
- (long)textLength
|
||||
{
|
||||
if (AccessibleWrap* accWrap = [self getGeckoAccessible]) {
|
||||
return accWrap->AsTextLeaf()->Text().Length();
|
||||
}
|
||||
|
||||
if (ProxyAccessible* proxy = [self getProxyAccessible]) {
|
||||
nsString text;
|
||||
proxy->Text(&text);
|
||||
return text.Length();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@end
|
||||
|
|
@ -9,6 +9,8 @@ if 'gtk' in toolkit:
|
|||
DIRS += ['atk']
|
||||
elif toolkit == 'windows':
|
||||
DIRS += ['windows']
|
||||
elif toolkit == 'cocoa':
|
||||
DIRS += ['mac']
|
||||
else:
|
||||
DIRS += ['other']
|
||||
|
||||
|
|
|
|||
|
|
@ -42,6 +42,10 @@ elif CONFIG['MOZ_WIDGET_TOOLKIT'] == 'windows':
|
|||
LOCAL_INCLUDES += [
|
||||
'/accessible/windows/msaa',
|
||||
]
|
||||
elif CONFIG['MOZ_WIDGET_TOOLKIT'] == 'cocoa':
|
||||
LOCAL_INCLUDES += [
|
||||
'/accessible/mac',
|
||||
]
|
||||
else:
|
||||
LOCAL_INCLUDES += [
|
||||
'/accessible/other',
|
||||
|
|
|
|||
|
|
@ -37,6 +37,10 @@ elif CONFIG['MOZ_WIDGET_TOOLKIT'] == 'windows':
|
|||
'/accessible/windows/ia2',
|
||||
'/accessible/windows/msaa',
|
||||
]
|
||||
elif CONFIG['MOZ_WIDGET_TOOLKIT'] == 'cocoa':
|
||||
LOCAL_INCLUDES += [
|
||||
'/accessible/mac',
|
||||
]
|
||||
else:
|
||||
LOCAL_INCLUDES += [
|
||||
'/accessible/other',
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue