2006-09-11 19:44:00 +04:00
|
|
|
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
2012-05-21 15:12:37 +04:00
|
|
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
2006-09-11 19:44:00 +04:00
|
|
|
|
2012-05-27 13:01:40 +04:00
|
|
|
#include "DocAccessible.h"
|
2008-02-22 23:13:17 +03:00
|
|
|
#include "nsObjCExceptions.h"
|
2006-11-15 14:08:14 +03:00
|
|
|
|
2012-04-13 18:17:03 +04:00
|
|
|
#include "Accessible-inl.h"
|
2012-07-28 08:21:40 +04:00
|
|
|
#include "nsAccUtils.h"
|
2012-01-12 07:07:35 +04:00
|
|
|
#include "Role.h"
|
2017-07-29 09:20:21 +03:00
|
|
|
#include "gfxPlatform.h"
|
2012-01-12 07:07:35 +04:00
|
|
|
|
2020-05-29 01:41:04 +03:00
|
|
|
#import "MOXMathAccessibles.h"
|
2020-06-26 07:00:49 +03:00
|
|
|
#import "MOXWebAreaAccessible.h"
|
2006-09-11 19:44:00 +04:00
|
|
|
#import "mozAccessible.h"
|
2006-11-15 14:08:14 +03:00
|
|
|
#import "mozActionElements.h"
|
2012-01-24 02:37:21 +04:00
|
|
|
#import "mozHTMLAccessible.h"
|
2020-03-13 01:16:39 +03:00
|
|
|
#import "mozSelectableElements.h"
|
2015-10-01 17:00:00 +03:00
|
|
|
#import "mozTableAccessible.h"
|
2006-11-15 14:08:14 +03:00
|
|
|
#import "mozTextAccessible.h"
|
2006-09-11 19:44:00 +04:00
|
|
|
|
2015-05-29 20:42:23 +03:00
|
|
|
using namespace mozilla;
|
2012-01-12 07:07:35 +04:00
|
|
|
using namespace mozilla::a11y;
|
|
|
|
|
2012-05-29 05:18:45 +04:00
|
|
|
AccessibleWrap::AccessibleWrap(nsIContent* aContent, DocAccessible* aDoc)
|
2015-06-08 17:59:19 +03:00
|
|
|
: Accessible(aContent, aDoc), mNativeObject(nil), mNativeInited(false) {}
|
2006-09-11 19:44:00 +04:00
|
|
|
|
2012-05-29 05:18:45 +04:00
|
|
|
AccessibleWrap::~AccessibleWrap() {}
|
2006-09-11 19:44:00 +04:00
|
|
|
|
2012-05-29 05:18:45 +04:00
|
|
|
mozAccessible* AccessibleWrap::GetNativeObject() {
|
2011-12-13 18:17:59 +04:00
|
|
|
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
|
2015-06-08 17:59:19 +03:00
|
|
|
|
2020-03-03 20:47:09 +03:00
|
|
|
if (!mNativeInited && !mNativeObject) {
|
|
|
|
// We don't creat OSX accessibles for xul tooltips, defunct accessibles,
|
2020-06-26 21:04:39 +03:00
|
|
|
// <br> (whitespace) elements, or pruned children.
|
2020-05-12 21:39:06 +03:00
|
|
|
//
|
|
|
|
// We also 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();
|
|
|
|
bool mustBePruned = parent && nsAccUtils::MustPrune(parent);
|
2020-06-26 21:04:39 +03:00
|
|
|
if (!IsXULTooltip() && !IsDefunct() && !mustBePruned && Role() != roles::WHITESPACE) {
|
2020-05-27 18:50:47 +03:00
|
|
|
mNativeObject = [[GetNativeType() alloc] initWithAccessible:this];
|
2020-03-03 20:47:09 +03:00
|
|
|
}
|
2015-05-29 20:42:23 +03:00
|
|
|
}
|
2015-06-08 17:59:19 +03:00
|
|
|
|
2011-12-15 18:47:04 +04:00
|
|
|
mNativeInited = true;
|
2015-06-08 17:59:19 +03:00
|
|
|
|
2011-12-15 18:47:04 +04:00
|
|
|
return mNativeObject;
|
2015-06-08 17:59:19 +03:00
|
|
|
|
2011-12-15 18:47:04 +04:00
|
|
|
NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
|
2006-09-11 19:44:00 +04:00
|
|
|
}
|
|
|
|
|
2014-10-22 04:49:28 +04:00
|
|
|
void AccessibleWrap::GetNativeInterface(void** aOutInterface) {
|
2011-12-15 18:47:04 +04:00
|
|
|
*aOutInterface = static_cast<void*>(GetNativeObject());
|
2006-09-11 19:44:00 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
// overridden in subclasses to create the right kind of object. by default we create a generic
|
|
|
|
// 'mozAccessible' node.
|
2015-06-08 17:59:19 +03:00
|
|
|
Class AccessibleWrap::GetNativeType() {
|
2008-02-22 23:13:17 +03:00
|
|
|
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
|
|
|
|
|
2012-06-29 03:04:50 +04:00
|
|
|
if (IsXULTabpanels()) return [mozPaneAccessible class];
|
2012-12-28 12:15:02 +04:00
|
|
|
|
2015-10-01 17:00:00 +03:00
|
|
|
if (IsTable()) return [mozTableAccessible class];
|
|
|
|
|
|
|
|
if (IsTableRow()) return [mozTableRowAccessible class];
|
|
|
|
|
|
|
|
if (IsTableCell()) return [mozTableCellAccessible class];
|
|
|
|
|
2015-05-29 20:42:23 +03:00
|
|
|
return GetTypeFromRole(Role());
|
2008-02-22 23:13:17 +03:00
|
|
|
|
|
|
|
NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
|
2006-09-11 19:44:00 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
// 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'.
|
2012-05-29 05:18:45 +04:00
|
|
|
void AccessibleWrap::Shutdown() {
|
2011-12-15 18:47:04 +04:00
|
|
|
// this ensure we will not try to re-create the native object.
|
|
|
|
mNativeInited = true;
|
|
|
|
|
|
|
|
// we really intend to access the member directly.
|
2011-12-13 18:17:59 +04:00
|
|
|
if (mNativeObject) {
|
|
|
|
[mNativeObject expire];
|
|
|
|
[mNativeObject release];
|
|
|
|
mNativeObject = nil;
|
2006-09-11 19:44:00 +04:00
|
|
|
}
|
2011-12-15 18:47:04 +04:00
|
|
|
|
2012-05-29 05:18:45 +04:00
|
|
|
Accessible::Shutdown();
|
2006-09-11 19:44:00 +04:00
|
|
|
}
|
|
|
|
|
2012-05-29 05:18:45 +04:00
|
|
|
nsresult AccessibleWrap::HandleAccEvent(AccEvent* aEvent) {
|
2008-02-22 23:13:17 +03:00
|
|
|
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT;
|
|
|
|
|
2012-05-29 05:18:45 +04:00
|
|
|
nsresult rv = Accessible::HandleAccEvent(aEvent);
|
2007-07-05 20:02:55 +04:00
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
|
2015-08-05 16:57:13 +03:00
|
|
|
if (IPCAccessibilityActive()) {
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2012-08-22 19:56:38 +04:00
|
|
|
uint32_t eventType = aEvent->GetEventType();
|
2020-03-27 20:12:33 +03:00
|
|
|
|
|
|
|
mozAccessible* nativeAcc = nil;
|
2007-07-05 20:02:55 +04:00
|
|
|
|
2020-03-13 01:16:39 +03:00
|
|
|
switch (eventType) {
|
|
|
|
case nsIAccessibleEvent::EVENT_FOCUS:
|
|
|
|
case nsIAccessibleEvent::EVENT_VALUE_CHANGE:
|
|
|
|
case nsIAccessibleEvent::EVENT_TEXT_VALUE_CHANGE:
|
|
|
|
case nsIAccessibleEvent::EVENT_TEXT_CARET_MOVED:
|
|
|
|
case nsIAccessibleEvent::EVENT_TEXT_SELECTION_CHANGED:
|
|
|
|
case nsIAccessibleEvent::EVENT_DOCUMENT_LOAD_COMPLETE:
|
|
|
|
case nsIAccessibleEvent::EVENT_MENUPOPUP_START:
|
|
|
|
case nsIAccessibleEvent::EVENT_MENUPOPUP_END:
|
2020-04-10 20:53:41 +03:00
|
|
|
case nsIAccessibleEvent::EVENT_REORDER:
|
2020-03-27 20:12:33 +03:00
|
|
|
if (Accessible* accessible = aEvent->GetAccessible()) {
|
|
|
|
accessible->GetNativeInterface((void**)&nativeAcc);
|
|
|
|
if (!nativeAcc) {
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
}
|
|
|
|
}
|
2020-03-13 01:16:39 +03:00
|
|
|
break;
|
|
|
|
case nsIAccessibleEvent::EVENT_SELECTION:
|
|
|
|
case nsIAccessibleEvent::EVENT_SELECTION_ADD:
|
|
|
|
case nsIAccessibleEvent::EVENT_SELECTION_REMOVE: {
|
|
|
|
AccSelChangeEvent* selEvent = downcast_accEvent(aEvent);
|
|
|
|
// The "widget" is the selected widget's container. In OSX
|
|
|
|
// it is the target of the selection changed event.
|
2020-03-27 20:12:33 +03:00
|
|
|
if (Accessible* accessible = selEvent->Widget()) {
|
|
|
|
accessible->GetNativeInterface((void**)&nativeAcc);
|
|
|
|
if (!nativeAcc) {
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
}
|
|
|
|
}
|
2020-03-13 01:16:39 +03:00
|
|
|
break;
|
|
|
|
}
|
2020-04-02 19:42:46 +03:00
|
|
|
case nsIAccessibleEvent::EVENT_STATE_CHANGE:
|
|
|
|
if (Accessible* accessible = aEvent->GetAccessible()) {
|
|
|
|
accessible->GetNativeInterface((void**)&nativeAcc);
|
|
|
|
if (nativeAcc) {
|
|
|
|
AccStateChangeEvent* event = downcast_accEvent(aEvent);
|
|
|
|
[nativeAcc stateChanged:event->GetState() isEnabled:event->IsStateEnabled()];
|
|
|
|
return NS_OK;
|
|
|
|
} else {
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
2020-03-13 01:16:39 +03:00
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
2007-07-05 20:02:55 +04:00
|
|
|
|
2020-03-27 20:12:33 +03:00
|
|
|
if (nativeAcc) {
|
2020-04-10 01:57:47 +03:00
|
|
|
[nativeAcc handleAccessibleEvent:eventType];
|
2020-03-13 01:16:39 +03:00
|
|
|
}
|
2007-07-05 20:02:55 +04:00
|
|
|
|
|
|
|
return NS_OK;
|
2008-02-22 23:13:17 +03:00
|
|
|
|
|
|
|
NS_OBJC_END_TRY_ABORT_BLOCK_NSRESULT;
|
2007-07-05 20:02:55 +04:00
|
|
|
}
|
|
|
|
|
2010-04-27 10:52:03 +04:00
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
2012-05-29 05:18:45 +04:00
|
|
|
// AccessibleWrap protected
|
2010-04-27 10:52:03 +04:00
|
|
|
|
2015-06-08 17:59:19 +03:00
|
|
|
Class a11y::GetTypeFromRole(roles::Role aRole) {
|
2015-05-29 20:42:23 +03:00
|
|
|
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
|
|
|
|
|
|
|
|
switch (aRole) {
|
|
|
|
case roles::COMBOBOX:
|
2020-05-16 00:31:08 +03:00
|
|
|
return [mozPopupButtonAccessible class];
|
2020-06-26 07:00:49 +03:00
|
|
|
|
|
|
|
case roles::DOCUMENT:
|
|
|
|
return [MOXWebAreaAccessible class];
|
2020-05-16 00:31:08 +03:00
|
|
|
|
2015-05-29 20:42:23 +03:00
|
|
|
case roles::PUSHBUTTON:
|
|
|
|
return [mozButtonAccessible class];
|
2015-06-08 17:59:19 +03:00
|
|
|
|
2015-05-29 20:42:23 +03:00
|
|
|
case roles::PAGETAB:
|
2020-03-13 01:16:39 +03:00
|
|
|
return [mozTabAccessible class];
|
2015-05-29 20:42:23 +03:00
|
|
|
|
|
|
|
case roles::CHECKBUTTON:
|
2020-03-14 08:39:59 +03:00
|
|
|
case roles::TOGGLE_BUTTON:
|
2020-05-29 07:05:21 +03:00
|
|
|
return [mozCheckboxAccessible class];
|
2020-05-28 18:53:01 +03:00
|
|
|
|
2020-05-29 20:37:46 +03:00
|
|
|
case roles::RADIOBUTTON:
|
|
|
|
return [mozRadioButtonAccessible class];
|
|
|
|
|
2020-04-28 20:20:16 +03:00
|
|
|
case roles::SPINBUTTON:
|
2020-03-17 20:32:33 +03:00
|
|
|
case roles::SLIDER:
|
2020-04-28 20:20:16 +03:00
|
|
|
return [mozIncrementableAccessible class];
|
2020-03-17 20:32:33 +03:00
|
|
|
|
2015-05-29 20:42:23 +03:00
|
|
|
case roles::HEADING:
|
|
|
|
return [mozHeadingAccessible class];
|
|
|
|
|
|
|
|
case roles::PAGETABLIST:
|
2020-03-13 01:16:39 +03:00
|
|
|
return [mozTabGroupAccessible class];
|
2015-05-29 20:42:23 +03:00
|
|
|
|
|
|
|
case roles::ENTRY:
|
|
|
|
case roles::CAPTION:
|
|
|
|
case roles::ACCEL_LABEL:
|
|
|
|
case roles::PASSWORD_TEXT:
|
|
|
|
// normal textfield (static or editable)
|
|
|
|
return [mozTextAccessible class];
|
|
|
|
|
|
|
|
case roles::TEXT_LEAF:
|
2020-04-27 21:19:50 +03:00
|
|
|
case roles::STATICTEXT:
|
2015-05-29 20:42:23 +03:00
|
|
|
return [mozTextLeafAccessible class];
|
|
|
|
|
|
|
|
case roles::LINK:
|
|
|
|
return [mozLinkAccessible class];
|
2015-06-08 17:59:19 +03:00
|
|
|
|
2020-05-13 02:28:34 +03:00
|
|
|
case roles::LISTBOX:
|
|
|
|
return [mozListboxAccessible class];
|
|
|
|
|
|
|
|
case roles::OPTION: {
|
|
|
|
return [mozOptionAccessible class];
|
|
|
|
}
|
|
|
|
|
2020-05-16 00:31:08 +03:00
|
|
|
case roles::COMBOBOX_LIST:
|
|
|
|
case roles::MENUBAR:
|
|
|
|
case roles::MENUPOPUP: {
|
|
|
|
return [mozMenuAccessible class];
|
|
|
|
}
|
|
|
|
|
|
|
|
case roles::COMBOBOX_OPTION:
|
|
|
|
case roles::PARENT_MENUITEM:
|
|
|
|
case roles::MENUITEM: {
|
|
|
|
return [mozMenuItemAccessible class];
|
|
|
|
}
|
|
|
|
|
2020-05-29 01:41:04 +03:00
|
|
|
case roles::MATHML_ROOT:
|
|
|
|
return [MOXMathRootAccessible class];
|
|
|
|
|
|
|
|
case roles::MATHML_SQUARE_ROOT:
|
|
|
|
return [MOXMathSquareRootAccessible class];
|
|
|
|
|
|
|
|
case roles::MATHML_FRACTION:
|
|
|
|
return [MOXMathFractionAccessible class];
|
|
|
|
|
|
|
|
case roles::MATHML_SUB:
|
|
|
|
case roles::MATHML_SUP:
|
|
|
|
case roles::MATHML_SUB_SUP:
|
|
|
|
return [MOXMathSubSupAccessible class];
|
|
|
|
|
|
|
|
case roles::MATHML_UNDER:
|
|
|
|
case roles::MATHML_OVER:
|
|
|
|
case roles::MATHML_UNDER_OVER:
|
|
|
|
return [MOXMathUnderOverAccessible class];
|
|
|
|
|
2020-05-29 01:41:06 +03:00
|
|
|
case roles::SUMMARY:
|
|
|
|
return [MOXSummaryAccessible class];
|
|
|
|
|
2015-05-29 20:42:23 +03:00
|
|
|
default:
|
|
|
|
return [mozAccessible class];
|
|
|
|
}
|
2015-06-08 17:59:19 +03:00
|
|
|
|
2015-05-29 20:42:23 +03:00
|
|
|
return nil;
|
|
|
|
|
|
|
|
NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
|
|
|
|
}
|