2001-09-26 02:32:32 +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/. */
|
2001-02-14 23:51:33 +03:00
|
|
|
|
2012-04-09 14:18:03 +04:00
|
|
|
#include "nsAccessibilityService.h"
|
2011-10-11 09:50:08 +04:00
|
|
|
|
2001-12-17 04:21:29 +03:00
|
|
|
// NOTE: alphabetically ordered
|
2012-04-25 15:29:40 +04:00
|
|
|
#include "ApplicationAccessibleWrap.h"
|
2012-04-09 14:18:03 +04:00
|
|
|
#include "ARIAGridAccessibleWrap.h"
|
2013-04-25 07:48:26 +04:00
|
|
|
#include "ARIAMap.h"
|
2012-06-01 22:39:47 +04:00
|
|
|
#include "DocAccessible-inl.h"
|
2012-04-09 14:18:03 +04:00
|
|
|
#include "FocusManager.h"
|
2012-06-06 14:27:51 +04:00
|
|
|
#include "HTMLCanvasAccessible.h"
|
2012-06-02 15:30:29 +04:00
|
|
|
#include "HTMLElementAccessibles.h"
|
2012-06-04 16:32:34 +04:00
|
|
|
#include "HTMLImageMapAccessible.h"
|
2012-06-04 16:32:38 +04:00
|
|
|
#include "HTMLLinkAccessible.h"
|
2012-05-08 09:16:40 +04:00
|
|
|
#include "HTMLListAccessible.h"
|
2012-06-06 14:27:46 +04:00
|
|
|
#include "HTMLSelectAccessible.h"
|
2012-06-11 03:44:50 +04:00
|
|
|
#include "HTMLTableAccessibleWrap.h"
|
2012-05-31 12:04:41 +04:00
|
|
|
#include "HyperTextAccessibleWrap.h"
|
2013-09-11 02:18:59 +04:00
|
|
|
#include "RootAccessible.h"
|
2019-01-29 07:17:20 +03:00
|
|
|
#include "StyleInfo.h"
|
2008-10-16 13:12:05 +04:00
|
|
|
#include "nsAccUtils.h"
|
2015-08-05 06:35:54 +03:00
|
|
|
#include "nsArrayUtils.h"
|
2013-09-11 02:18:59 +04:00
|
|
|
#include "nsAttrName.h"
|
2018-02-22 21:24:25 +03:00
|
|
|
#include "nsDOMTokenList.h"
|
2012-07-28 08:21:40 +04:00
|
|
|
#include "nsEventShell.h"
|
2013-09-11 02:18:59 +04:00
|
|
|
#include "nsIURI.h"
|
2017-11-08 07:07:24 +03:00
|
|
|
#include "nsTextFormatter.h"
|
2012-04-09 14:18:03 +04:00
|
|
|
#include "OuterDocAccessible.h"
|
2012-01-12 07:07:35 +04:00
|
|
|
#include "Role.h"
|
2013-09-11 02:18:59 +04:00
|
|
|
#ifdef MOZ_ACCESSIBILITY_ATK
|
2012-05-04 10:09:22 +04:00
|
|
|
# include "RootAccessibleWrap.h"
|
2013-09-11 02:18:59 +04:00
|
|
|
#endif
|
2011-04-10 03:38:06 +04:00
|
|
|
#include "States.h"
|
2011-08-11 15:01:27 +04:00
|
|
|
#include "Statistics.h"
|
2012-10-13 10:34:21 +04:00
|
|
|
#include "TextLeafAccessibleWrap.h"
|
2014-09-20 04:02:30 +04:00
|
|
|
#include "TreeWalker.h"
|
2014-10-22 04:49:28 +04:00
|
|
|
#include "xpcAccessibleApplication.h"
|
|
|
|
#include "xpcAccessibleDocument.h"
|
2012-10-13 10:34:21 +04:00
|
|
|
|
|
|
|
#ifdef MOZ_ACCESSIBILITY_ATK
|
|
|
|
# include "AtkSocketAccessible.h"
|
|
|
|
#endif
|
|
|
|
|
2012-04-09 14:18:03 +04:00
|
|
|
#ifdef XP_WIN
|
2013-02-27 02:07:24 +04:00
|
|
|
# include "mozilla/a11y/Compatibility.h"
|
2016-10-27 21:40:50 +03:00
|
|
|
# include "mozilla/dom/ContentChild.h"
|
2012-10-13 10:34:21 +04:00
|
|
|
# include "HTMLWin32ObjectAccessible.h"
|
2013-09-11 02:18:59 +04:00
|
|
|
# include "mozilla/StaticPtr.h"
|
2012-04-09 14:18:03 +04:00
|
|
|
#endif
|
2010-04-06 04:41:28 +04:00
|
|
|
|
2012-10-04 13:57:09 +04:00
|
|
|
#ifdef A11Y_LOG
|
2012-05-23 13:21:40 +04:00
|
|
|
# include "Logging.h"
|
|
|
|
#endif
|
|
|
|
|
2012-07-20 22:43:49 +04:00
|
|
|
#include "nsExceptionHandler.h"
|
2011-04-26 10:52:19 +04:00
|
|
|
#include "nsImageFrame.h"
|
2017-07-26 21:18:20 +03:00
|
|
|
#include "nsINamed.h"
|
2003-04-22 11:38:18 +04:00
|
|
|
#include "nsIObserverService.h"
|
2011-10-05 10:24:44 +04:00
|
|
|
#include "nsLayoutUtils.h"
|
2014-09-24 08:33:00 +04:00
|
|
|
#include "nsPluginFrame.h"
|
2016-12-18 14:11:47 +03:00
|
|
|
#include "SVGGeometryFrame.h"
|
2012-11-20 00:36:05 +04:00
|
|
|
#include "nsTreeBodyFrame.h"
|
|
|
|
#include "nsTreeColumns.h"
|
|
|
|
#include "nsTreeUtils.h"
|
2013-07-19 08:13:35 +04:00
|
|
|
#include "nsXBLPrototypeBinding.h"
|
|
|
|
#include "nsXBLBinding.h"
|
2013-12-09 06:52:54 +04:00
|
|
|
#include "mozilla/ArrayUtils.h"
|
2013-07-09 21:54:21 +04:00
|
|
|
#include "mozilla/dom/DOMStringList.h"
|
2018-04-20 07:49:30 +03:00
|
|
|
#include "mozilla/dom/EventTarget.h"
|
2018-11-26 02:39:52 +03:00
|
|
|
#include "mozilla/dom/HTMLTableElement.h"
|
2012-06-20 03:19:13 +04:00
|
|
|
#include "mozilla/Preferences.h"
|
2019-03-29 18:12:47 +03:00
|
|
|
#include "mozilla/PresShell.h"
|
Bug 560095 - Use mozilla::services::GetObserverService(). r=biesi,dveditz,gavin,josh,jst,mrbkap,roc,sdwilsh,shaver,sicking,smontagu,surkov
2010-04-29 20:59:13 +04:00
|
|
|
#include "mozilla/Services.h"
|
2012-12-28 12:15:02 +04:00
|
|
|
#include "nsDeckFrame.h"
|
2003-04-22 11:38:18 +04:00
|
|
|
|
2003-04-11 04:56:27 +04:00
|
|
|
#ifdef MOZ_XUL
|
2012-06-11 03:44:50 +04:00
|
|
|
# include "XULAlertAccessible.h"
|
|
|
|
# include "XULComboboxAccessible.h"
|
|
|
|
# include "XULElementAccessibles.h"
|
2012-06-09 12:21:07 +04:00
|
|
|
# include "XULFormControlAccessible.h"
|
2012-06-11 03:44:50 +04:00
|
|
|
# include "XULListboxAccessibleWrap.h"
|
|
|
|
# include "XULMenuAccessibleWrap.h"
|
|
|
|
# include "XULTabAccessible.h"
|
|
|
|
# include "XULTreeGridAccessibleWrap.h"
|
2003-04-11 04:56:27 +04:00
|
|
|
#endif
|
2001-05-12 01:11:38 +04:00
|
|
|
|
2013-09-11 02:18:59 +04:00
|
|
|
#if defined(XP_WIN) || defined(MOZ_ACCESSIBILITY_ATK)
|
|
|
|
# include "nsNPAPIPluginInstance.h"
|
|
|
|
#endif
|
|
|
|
|
2011-10-11 09:50:08 +04:00
|
|
|
using namespace mozilla;
|
2011-07-27 16:43:01 +04:00
|
|
|
using namespace mozilla::a11y;
|
2013-07-09 21:54:21 +04:00
|
|
|
using namespace mozilla::dom;
|
2011-07-27 16:43:01 +04:00
|
|
|
|
2017-09-25 20:02:57 +03:00
|
|
|
/**
|
|
|
|
* Accessibility service force enable/disable preference.
|
|
|
|
* Supported values:
|
|
|
|
* Accessibility is force enabled (accessibility should always be enabled): -1
|
|
|
|
* Accessibility is enabled (will be started upon a request, default value): 0
|
|
|
|
* Accessibility is force disabled (never enable accessibility): 1
|
|
|
|
*/
|
|
|
|
#define PREF_ACCESSIBILITY_FORCE_DISABLED "accessibility.force_disabled"
|
|
|
|
|
2012-11-10 14:26:58 +04:00
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
// Statics
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Return true if the element must be accessible.
|
|
|
|
*/
|
|
|
|
static bool MustBeAccessible(nsIContent* aContent, DocAccessible* aDocument) {
|
|
|
|
if (aContent->GetPrimaryFrame()->IsFocusable()) return true;
|
|
|
|
|
2017-12-05 20:05:51 +03:00
|
|
|
if (aContent->IsElement()) {
|
|
|
|
uint32_t attrCount = aContent->AsElement()->GetAttrCount();
|
|
|
|
for (uint32_t attrIdx = 0; attrIdx < attrCount; attrIdx++) {
|
|
|
|
const nsAttrName* attr = aContent->AsElement()->GetAttrNameAt(attrIdx);
|
|
|
|
if (attr->NamespaceEquals(kNameSpaceID_None)) {
|
|
|
|
nsAtom* attrAtom = attr->Atom();
|
2019-01-23 04:31:54 +03:00
|
|
|
if (attrAtom == nsGkAtoms::title && aContent->IsHTMLElement()) {
|
|
|
|
// If the author provided a title on an element that would not
|
|
|
|
// be accessible normally, assume an intent and make it accessible.
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2017-12-05 20:05:51 +03:00
|
|
|
nsDependentAtomString attrStr(attrAtom);
|
|
|
|
if (!StringBeginsWith(attrStr, NS_LITERAL_STRING("aria-")))
|
|
|
|
continue; // not ARIA
|
|
|
|
|
|
|
|
// A global state or a property and in case of token defined.
|
|
|
|
uint8_t attrFlags = aria::AttrCharacteristicsFor(attrAtom);
|
|
|
|
if ((attrFlags & ATTR_GLOBAL) &&
|
|
|
|
(!(attrFlags & ATTR_VALTOKEN) ||
|
|
|
|
nsAccUtils::HasDefinedARIAToken(aContent, attrAtom))) {
|
|
|
|
return true;
|
|
|
|
}
|
2012-11-10 14:26:58 +04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-10-30 03:17:04 +03:00
|
|
|
// If the given ID is referred by relation attribute then create an
|
|
|
|
// accessible for it.
|
|
|
|
nsAutoString id;
|
|
|
|
if (nsCoreUtils::GetID(aContent, id) && !id.IsEmpty()) {
|
|
|
|
return aDocument->IsDependentID(aContent->AsElement(), id);
|
|
|
|
}
|
|
|
|
}
|
2012-11-10 14:26:58 +04:00
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2018-02-28 22:26:51 +03:00
|
|
|
/**
|
|
|
|
* Used by XULMap.h to map both menupopup and popup elements
|
|
|
|
*/
|
|
|
|
#ifdef MOZ_XUL
|
2018-03-07 00:47:43 +03:00
|
|
|
Accessible* CreateMenupopupAccessible(Element* aElement, Accessible* aContext) {
|
2018-02-28 22:26:51 +03:00
|
|
|
# ifdef MOZ_ACCESSIBILITY_ATK
|
|
|
|
// ATK considers this node to be redundant when within menubars, and it makes
|
|
|
|
// menu navigation with assistive technologies more difficult
|
|
|
|
// XXX In the future we will should this for consistency across the
|
|
|
|
// nsIAccessible implementations on each platform for a consistent scripting
|
|
|
|
// environment, but then strip out redundant accessibles in the AccessibleWrap
|
|
|
|
// class for each platform.
|
2018-03-07 00:47:43 +03:00
|
|
|
nsIContent* parent = aElement->GetParent();
|
2018-02-28 22:26:51 +03:00
|
|
|
if (parent && parent->IsXULElement(nsGkAtoms::menu)) return nullptr;
|
|
|
|
# endif
|
|
|
|
|
2018-03-07 00:47:43 +03:00
|
|
|
return new XULMenupopupAccessible(aElement, aContext->Document());
|
2018-02-28 22:26:51 +03:00
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2015-03-05 06:56:57 +03:00
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
// Accessible constructors
|
|
|
|
|
2018-03-07 00:47:43 +03:00
|
|
|
static Accessible* New_HyperText(Element* aElement, Accessible* aContext) {
|
|
|
|
return new HyperTextAccessibleWrap(aElement, aContext->Document());
|
|
|
|
}
|
2015-03-05 06:56:57 +03:00
|
|
|
|
2018-07-18 13:13:01 +03:00
|
|
|
template <typename AccClass>
|
|
|
|
static Accessible* New_HTMLDtOrDd(Element* aElement, Accessible* aContext) {
|
|
|
|
nsIContent* parent = aContext->GetContent();
|
|
|
|
if (parent->IsHTMLElement(nsGkAtoms::div)) {
|
|
|
|
// It is conforming in HTML to use a div to group dt/dd elements.
|
|
|
|
parent = parent->GetParent();
|
|
|
|
}
|
|
|
|
|
|
|
|
if (parent && parent->IsHTMLElement(nsGkAtoms::dl)) {
|
|
|
|
return new AccClass(aElement, aContext->Document());
|
|
|
|
}
|
|
|
|
|
2015-03-05 06:56:57 +03:00
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
|
2017-09-25 20:02:57 +03:00
|
|
|
/**
|
|
|
|
* Cached value of the PREF_ACCESSIBILITY_FORCE_DISABLED preference.
|
|
|
|
*/
|
|
|
|
static int32_t sPlatformDisabledState = 0;
|
|
|
|
|
2015-03-05 06:56:57 +03:00
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
// Markup maps array.
|
|
|
|
|
2015-03-08 04:20:17 +03:00
|
|
|
#define Attr(name, value) \
|
2018-04-03 04:20:13 +03:00
|
|
|
{ nsGkAtoms::name, nsGkAtoms::value }
|
2015-03-08 04:20:17 +03:00
|
|
|
|
|
|
|
#define AttrFromDOM(name, DOMAttrName) \
|
2018-04-03 04:20:13 +03:00
|
|
|
{ nsGkAtoms::name, nullptr, nsGkAtoms::DOMAttrName }
|
2015-03-08 04:20:17 +03:00
|
|
|
|
|
|
|
#define AttrFromDOMIf(name, DOMAttrName, DOMAttrValue) \
|
2018-04-03 04:20:13 +03:00
|
|
|
{ nsGkAtoms::name, nullptr, nsGkAtoms::DOMAttrName, nsGkAtoms::DOMAttrValue }
|
2015-03-08 04:20:17 +03:00
|
|
|
|
|
|
|
#define MARKUPMAP(atom, new_func, r, ...) \
|
2018-04-03 04:20:13 +03:00
|
|
|
{nsGkAtoms::atom, new_func, static_cast<a11y::role>(r), {__VA_ARGS__}},
|
2015-03-05 06:56:57 +03:00
|
|
|
|
2018-02-05 17:26:59 +03:00
|
|
|
static const HTMLMarkupMapInfo sHTMLMarkupMapList[] = {
|
2015-03-05 06:56:57 +03:00
|
|
|
#include "MarkupMap.h"
|
|
|
|
};
|
|
|
|
|
2018-02-06 16:26:14 +03:00
|
|
|
#undef MARKUPMAP
|
|
|
|
|
2017-11-03 14:15:44 +03:00
|
|
|
#ifdef MOZ_XUL
|
2018-04-03 04:20:13 +03:00
|
|
|
# define XULMAP(atom, ...) {nsGkAtoms::atom, __VA_ARGS__},
|
2017-11-03 14:15:44 +03:00
|
|
|
|
2018-02-06 16:26:14 +03:00
|
|
|
# define XULMAP_TYPE(atom, new_type) \
|
2018-03-07 00:47:43 +03:00
|
|
|
XULMAP(atom, [](Element* aElement, Accessible* aContext) -> Accessible* { \
|
|
|
|
return new new_type(aElement, aContext->Document()); \
|
2018-02-06 16:26:14 +03:00
|
|
|
})
|
|
|
|
|
2018-02-05 17:26:59 +03:00
|
|
|
static const XULMarkupMapInfo sXULMarkupMapList[] = {
|
2017-11-03 14:15:44 +03:00
|
|
|
# include "XULMap.h"
|
|
|
|
};
|
2018-02-06 16:26:14 +03:00
|
|
|
|
|
|
|
# undef XULMAP_TYPE
|
|
|
|
# undef XULMAP
|
2017-11-03 14:15:44 +03:00
|
|
|
#endif
|
|
|
|
|
2015-03-08 04:20:17 +03:00
|
|
|
#undef Attr
|
|
|
|
#undef AttrFromDOM
|
|
|
|
#undef AttrFromDOMIf
|
2015-03-05 06:56:57 +03:00
|
|
|
|
2010-02-21 03:56:35 +03:00
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
// nsAccessibilityService
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
2012-07-30 18:20:58 +04:00
|
|
|
nsAccessibilityService* nsAccessibilityService::gAccessibilityService = nullptr;
|
2012-09-10 17:20:26 +04:00
|
|
|
ApplicationAccessible* nsAccessibilityService::gApplicationAccessible = nullptr;
|
2014-10-22 04:49:28 +04:00
|
|
|
xpcAccessibleApplication* nsAccessibilityService::gXPCApplicationAccessible =
|
|
|
|
nullptr;
|
2016-08-29 18:06:48 +03:00
|
|
|
uint32_t nsAccessibilityService::gConsumers = 0;
|
2003-07-09 11:01:46 +04:00
|
|
|
|
2011-09-28 05:46:11 +04:00
|
|
|
nsAccessibilityService::nsAccessibilityService()
|
2018-02-05 17:26:59 +03:00
|
|
|
: DocManager(),
|
|
|
|
FocusManager(),
|
|
|
|
mHTMLMarkupMap(ArrayLength(sHTMLMarkupMapList))
|
2017-11-03 14:15:44 +03:00
|
|
|
#ifdef MOZ_XUL
|
2018-02-05 17:26:59 +03:00
|
|
|
,
|
|
|
|
mXULMarkupMap(ArrayLength(sXULMarkupMapList))
|
2017-11-03 14:15:44 +03:00
|
|
|
#endif
|
2001-03-05 23:21:39 +03:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
nsAccessibilityService::~nsAccessibilityService() {
|
2016-08-29 18:06:48 +03:00
|
|
|
NS_ASSERTION(IsShutdown(), "Accessibility wasn't shutdown!");
|
2012-07-30 18:20:58 +04:00
|
|
|
gAccessibilityService = nullptr;
|
2001-03-05 23:21:39 +03:00
|
|
|
}
|
|
|
|
|
2015-08-05 06:35:54 +03:00
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
// nsIListenerChangeListener
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
nsAccessibilityService::ListenersChanged(nsIArray* aEventChanges) {
|
|
|
|
uint32_t targetCount;
|
|
|
|
nsresult rv = aEventChanges->GetLength(&targetCount);
|
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
|
|
|
|
for (uint32_t i = 0; i < targetCount; i++) {
|
|
|
|
nsCOMPtr<nsIEventListenerChange> change =
|
|
|
|
do_QueryElementAt(aEventChanges, i);
|
|
|
|
|
2018-04-20 07:49:30 +03:00
|
|
|
RefPtr<EventTarget> target;
|
2015-08-05 06:35:54 +03:00
|
|
|
change->GetTarget(getter_AddRefs(target));
|
|
|
|
nsCOMPtr<nsIContent> node(do_QueryInterface(target));
|
|
|
|
if (!node || !node->IsHTMLElement()) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
uint32_t changeCount;
|
2017-09-25 09:38:04 +03:00
|
|
|
change->GetCountOfEventListenerChangesAffectingAccessibility(&changeCount);
|
2015-08-05 06:35:54 +03:00
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
|
|
|
|
for (uint32_t i = 0; i < changeCount; i++) {
|
2019-01-02 16:05:23 +03:00
|
|
|
Document* ownerDoc = node->OwnerDoc();
|
2015-08-05 06:35:54 +03:00
|
|
|
DocAccessible* document = GetExistingDocAccessible(ownerDoc);
|
|
|
|
|
2017-03-15 22:19:26 +03:00
|
|
|
// Create an accessible for a inaccessible element having click event
|
|
|
|
// handler.
|
|
|
|
if (document && !document->HasAccessible(node) &&
|
|
|
|
nsCoreUtils::HasClickListener(node)) {
|
2018-10-18 11:02:51 +03:00
|
|
|
document->ContentInserted(node, node->GetNextSibling());
|
2015-08-05 06:35:54 +03:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2010-06-08 20:39:58 +04:00
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
// nsISupports
|
2003-04-15 12:45:55 +04:00
|
|
|
|
2014-04-27 11:06:00 +04:00
|
|
|
NS_IMPL_ISUPPORTS_INHERITED(nsAccessibilityService, DocManager, nsIObserver,
|
2015-08-05 06:35:54 +03:00
|
|
|
nsIListenerChangeListener,
|
2014-04-27 11:06:00 +04:00
|
|
|
nsISelectionListener) // from SelectionManager
|
2010-02-21 03:56:35 +03:00
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
2003-04-15 12:45:55 +04:00
|
|
|
// nsIObserver
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
nsAccessibilityService::Observe(nsISupports* aSubject, const char* aTopic,
|
2014-01-04 19:02:17 +04:00
|
|
|
const char16_t* aData) {
|
2018-05-28 20:40:41 +03:00
|
|
|
if (!nsCRT::strcmp(aTopic, NS_XPCOM_SHUTDOWN_OBSERVER_ID)) {
|
2010-06-08 20:39:58 +04:00
|
|
|
Shutdown();
|
2018-05-28 20:40:41 +03:00
|
|
|
}
|
2010-01-25 18:08:08 +03:00
|
|
|
|
2008-02-26 11:51:10 +03:00
|
|
|
return NS_OK;
|
|
|
|
}
|
2003-06-26 12:45:39 +04:00
|
|
|
|
2011-01-25 06:33:37 +03:00
|
|
|
void nsAccessibilityService::NotifyOfAnchorJumpTo(nsIContent* aTargetNode) {
|
2019-01-02 16:05:23 +03:00
|
|
|
Document* documentNode = aTargetNode->GetUncomposedDoc();
|
2011-01-25 06:33:37 +03:00
|
|
|
if (documentNode) {
|
2012-05-27 13:01:40 +04:00
|
|
|
DocAccessible* document = GetDocAccessible(documentNode);
|
2011-10-08 09:16:37 +04:00
|
|
|
if (document) document->SetAnchorJump(aTargetNode);
|
2011-01-25 06:33:37 +03:00
|
|
|
}
|
2009-11-02 04:02:09 +03:00
|
|
|
}
|
|
|
|
|
2012-08-22 19:56:38 +04:00
|
|
|
void nsAccessibilityService::FireAccessibleEvent(uint32_t aEvent,
|
2012-05-29 05:18:45 +04:00
|
|
|
Accessible* aTarget) {
|
2010-09-23 07:35:39 +04:00
|
|
|
nsEventShell::FireEvent(aEvent, aTarget);
|
2008-11-04 06:36:36 +03:00
|
|
|
}
|
|
|
|
|
2010-09-23 07:35:39 +04:00
|
|
|
Accessible* nsAccessibilityService::GetRootDocumentAccessible(
|
2019-04-13 04:03:13 +03:00
|
|
|
PresShell* aPresShell, bool aCanCreate) {
|
|
|
|
PresShell* presShell = aPresShell;
|
2019-01-02 16:05:23 +03:00
|
|
|
Document* documentNode = aPresShell->GetDocument();
|
2010-09-23 07:35:39 +04:00
|
|
|
if (documentNode) {
|
2013-11-15 20:32:12 +04:00
|
|
|
nsCOMPtr<nsIDocShellTreeItem> treeItem(documentNode->GetDocShell());
|
2010-09-23 07:35:39 +04:00
|
|
|
if (treeItem) {
|
|
|
|
nsCOMPtr<nsIDocShellTreeItem> rootTreeItem;
|
|
|
|
treeItem->GetRootTreeItem(getter_AddRefs(rootTreeItem));
|
|
|
|
if (treeItem != rootTreeItem) {
|
|
|
|
nsCOMPtr<nsIDocShell> docShell(do_QueryInterface(rootTreeItem));
|
2019-04-13 04:03:13 +03:00
|
|
|
presShell = docShell->GetPresShell();
|
2010-09-23 07:35:39 +04:00
|
|
|
}
|
|
|
|
|
2019-04-13 04:03:13 +03:00
|
|
|
return aCanCreate ? GetDocAccessible(presShell)
|
|
|
|
: presShell->GetDocAccessible();
|
2010-09-23 07:35:39 +04:00
|
|
|
}
|
|
|
|
}
|
2012-07-30 18:20:58 +04:00
|
|
|
return nullptr;
|
2010-09-23 07:35:39 +04:00
|
|
|
}
|
2012-06-04 16:32:34 +04:00
|
|
|
|
2013-02-27 02:07:24 +04:00
|
|
|
#ifdef XP_WIN
|
|
|
|
static StaticAutoPtr<nsTArray<nsCOMPtr<nsIContent> > > sPendingPlugins;
|
|
|
|
static StaticAutoPtr<nsTArray<nsCOMPtr<nsITimer> > > sPluginTimers;
|
|
|
|
|
2015-03-21 19:28:04 +03:00
|
|
|
class PluginTimerCallBack final : public nsITimerCallback, public nsINamed {
|
2014-07-15 22:57:48 +04:00
|
|
|
~PluginTimerCallBack() {}
|
|
|
|
|
2013-02-27 02:07:24 +04:00
|
|
|
public:
|
2016-12-16 10:43:21 +03:00
|
|
|
explicit PluginTimerCallBack(nsIContent* aContent) : mContent(aContent) {}
|
2013-02-27 02:07:24 +04:00
|
|
|
|
|
|
|
NS_DECL_ISUPPORTS
|
|
|
|
|
2018-02-06 09:46:57 +03:00
|
|
|
NS_IMETHOD Notify(nsITimer* aTimer) final {
|
2016-03-31 13:58:25 +03:00
|
|
|
if (!mContent->IsInUncomposedDoc()) return NS_OK;
|
2013-09-27 01:17:13 +04:00
|
|
|
|
2019-03-29 18:12:47 +03:00
|
|
|
PresShell* presShell = mContent->OwnerDoc()->GetPresShell();
|
|
|
|
if (presShell) {
|
|
|
|
DocAccessible* doc = presShell->GetDocAccessible();
|
2013-02-27 02:07:24 +04:00
|
|
|
if (doc) {
|
|
|
|
// Make sure that if we created an accessible for the plugin that wasn't
|
|
|
|
// a plugin accessible we remove it before creating the right
|
|
|
|
// accessible.
|
|
|
|
doc->RecreateAccessible(mContent);
|
|
|
|
sPluginTimers->RemoveElement(aTimer);
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// We couldn't get a doc accessible so presumably the document went away.
|
|
|
|
// In this case don't leak our ref to the content or timer.
|
|
|
|
sPendingPlugins->RemoveElement(mContent);
|
|
|
|
sPluginTimers->RemoveElement(aTimer);
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2018-02-06 09:46:57 +03:00
|
|
|
NS_IMETHOD GetName(nsACString& aName) final {
|
2017-07-26 21:18:20 +03:00
|
|
|
aName.AssignLiteral("PluginTimerCallBack");
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2013-02-27 02:07:24 +04:00
|
|
|
private:
|
|
|
|
nsCOMPtr<nsIContent> mContent;
|
|
|
|
};
|
|
|
|
|
2017-07-26 21:18:20 +03:00
|
|
|
NS_IMPL_ISUPPORTS(PluginTimerCallBack, nsITimerCallback, nsINamed)
|
2013-02-27 02:07:24 +04:00
|
|
|
#endif
|
|
|
|
|
2014-09-24 08:34:00 +04:00
|
|
|
already_AddRefed<Accessible> nsAccessibilityService::CreatePluginAccessible(
|
2012-12-12 14:04:12 +04:00
|
|
|
nsPluginFrame* aFrame, nsIContent* aContent, Accessible* aContext) {
|
2014-09-24 08:34:00 +04:00
|
|
|
// nsPluginFrame means a plugin, so we need to use the accessibility support
|
2012-11-30 05:33:52 +04:00
|
|
|
// of the plugin.
|
2010-06-28 16:02:03 +04:00
|
|
|
if (aFrame->GetRect().IsEmpty()) return nullptr;
|
2010-06-11 12:23:18 +04:00
|
|
|
|
2011-04-27 17:42:18 +04:00
|
|
|
#if defined(XP_WIN) || defined(MOZ_ACCESSIBILITY_ATK)
|
2018-11-20 04:20:17 +03:00
|
|
|
RefPtr<nsNPAPIPluginInstance> pluginInstance = aFrame->GetPluginInstance();
|
|
|
|
if (pluginInstance) {
|
2011-04-27 17:42:18 +04:00
|
|
|
# ifdef XP_WIN
|
2013-02-27 02:07:24 +04:00
|
|
|
if (!sPendingPlugins->Contains(aContent) &&
|
|
|
|
(Preferences::GetBool("accessibility.delay_plugins") ||
|
|
|
|
Compatibility::IsJAWS() || Compatibility::IsWE())) {
|
2015-10-18 08:24:48 +03:00
|
|
|
RefPtr<PluginTimerCallBack> cb = new PluginTimerCallBack(aContent);
|
2017-09-25 05:57:48 +03:00
|
|
|
nsCOMPtr<nsITimer> timer;
|
|
|
|
NS_NewTimerWithCallback(
|
|
|
|
getter_AddRefs(timer), cb,
|
|
|
|
Preferences::GetUint("accessibility.delay_plugin_time"),
|
2013-02-27 02:07:24 +04:00
|
|
|
nsITimer::TYPE_ONE_SHOT);
|
|
|
|
sPluginTimers->AppendElement(timer);
|
|
|
|
sPendingPlugins->AppendElement(aContent);
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
// We need to remove aContent from the pending plugins here to avoid
|
|
|
|
// reentrancy. When the timer fires it calls
|
|
|
|
// DocAccessible::ContentInserted() which does the work async.
|
|
|
|
sPendingPlugins->RemoveElement(aContent);
|
|
|
|
|
2009-10-15 07:53:08 +04:00
|
|
|
// Note: pluginPort will be null if windowless.
|
2012-07-30 18:20:58 +04:00
|
|
|
HWND pluginPort = nullptr;
|
2003-04-15 12:45:55 +04:00
|
|
|
aFrame->GetPluginPort(&pluginPort);
|
2009-10-15 07:53:08 +04:00
|
|
|
|
2012-11-30 11:33:01 +04:00
|
|
|
RefPtr<Accessible> accessible = new HTMLWin32ObjectOwnerAccessible(
|
|
|
|
aContent, aContext->Document(), pluginPort);
|
2013-04-28 15:52:10 +04:00
|
|
|
return accessible.forget();
|
2011-04-27 17:42:18 +04:00
|
|
|
|
|
|
|
# elif MOZ_ACCESSIBILITY_ATK
|
|
|
|
if (!AtkSocketAccessible::gCanEmbed) return nullptr;
|
|
|
|
|
2012-11-30 05:33:52 +04:00
|
|
|
// Note this calls into the plugin, so crazy things may happen and aFrame
|
|
|
|
// may go away.
|
2011-04-27 17:42:18 +04:00
|
|
|
nsCString plugId;
|
|
|
|
nsresult rv = pluginInstance->GetValueFromPlugin(
|
|
|
|
NPPVpluginNativeAccessibleAtkPlugId, &plugId);
|
2012-01-26 23:58:29 +04:00
|
|
|
if (NS_SUCCEEDED(rv) && !plugId.IsEmpty()) {
|
2015-10-18 08:24:48 +03:00
|
|
|
RefPtr<AtkSocketAccessible> socketAccessible =
|
2012-11-30 11:33:01 +04:00
|
|
|
new AtkSocketAccessible(aContent, aContext->Document(), plugId);
|
2011-04-27 17:42:18 +04:00
|
|
|
|
2013-04-22 15:15:59 +04:00
|
|
|
return socketAccessible.forget();
|
2011-04-27 17:42:18 +04:00
|
|
|
}
|
|
|
|
# endif
|
2003-04-15 12:45:55 +04:00
|
|
|
}
|
2002-05-11 02:34:53 +04:00
|
|
|
#endif
|
2003-04-15 12:45:55 +04:00
|
|
|
|
2012-11-30 05:33:52 +04:00
|
|
|
return nullptr;
|
2007-07-05 19:39:29 +04:00
|
|
|
}
|
|
|
|
|
2019-04-13 15:13:15 +03:00
|
|
|
void nsAccessibilityService::DeckPanelSwitched(PresShell* aPresShell,
|
2012-12-28 12:15:02 +04:00
|
|
|
nsIContent* aDeckNode,
|
|
|
|
nsIFrame* aPrevBoxFrame,
|
|
|
|
nsIFrame* aCurrentBoxFrame) {
|
|
|
|
// Ignore tabpanels elements (a deck having an accessible) since their
|
|
|
|
// children are accessible not depending on selected tab.
|
|
|
|
DocAccessible* document = GetDocAccessible(aPresShell);
|
|
|
|
if (!document || document->HasAccessible(aDeckNode)) return;
|
|
|
|
|
|
|
|
if (aPrevBoxFrame) {
|
|
|
|
nsIContent* panelNode = aPrevBoxFrame->GetContent();
|
|
|
|
#ifdef A11Y_LOG
|
|
|
|
if (logging::IsEnabled(logging::eTree)) {
|
|
|
|
logging::MsgBegin("TREE", "deck panel unselected");
|
|
|
|
logging::Node("container", panelNode);
|
|
|
|
logging::Node("content", aDeckNode);
|
|
|
|
logging::MsgEnd();
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2017-04-25 21:02:41 +03:00
|
|
|
document->ContentRemoved(panelNode);
|
2012-12-28 12:15:02 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
if (aCurrentBoxFrame) {
|
|
|
|
nsIContent* panelNode = aCurrentBoxFrame->GetContent();
|
|
|
|
#ifdef A11Y_LOG
|
|
|
|
if (logging::IsEnabled(logging::eTree)) {
|
|
|
|
logging::MsgBegin("TREE", "deck panel selected");
|
|
|
|
logging::Node("container", panelNode);
|
|
|
|
logging::Node("content", aDeckNode);
|
|
|
|
logging::MsgEnd();
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2018-10-18 11:02:51 +03:00
|
|
|
document->ContentInserted(panelNode, panelNode->GetNextSibling());
|
2012-12-28 12:15:02 +04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-04-13 15:13:15 +03:00
|
|
|
void nsAccessibilityService::ContentRangeInserted(PresShell* aPresShell,
|
2010-10-21 08:16:10 +04:00
|
|
|
nsIContent* aStartChild,
|
|
|
|
nsIContent* aEndChild) {
|
2016-06-08 20:45:22 +03:00
|
|
|
DocAccessible* document = GetDocAccessible(aPresShell);
|
2012-10-04 13:57:09 +04:00
|
|
|
#ifdef A11Y_LOG
|
2012-06-01 08:27:25 +04:00
|
|
|
if (logging::IsEnabled(logging::eTree)) {
|
2016-06-08 20:45:22 +03:00
|
|
|
logging::MsgBegin("TREE", "content inserted; doc: %p", document);
|
2018-04-02 06:30:51 +03:00
|
|
|
logging::Node("container", aStartChild->GetParent());
|
2012-06-01 08:27:25 +04:00
|
|
|
for (nsIContent* child = aStartChild; child != aEndChild;
|
|
|
|
child = child->GetNextSibling()) {
|
|
|
|
logging::Node("content", child);
|
|
|
|
}
|
|
|
|
logging::MsgEnd();
|
2012-11-04 06:19:56 +04:00
|
|
|
logging::Stack();
|
2010-11-06 07:11:08 +03:00
|
|
|
}
|
2010-10-21 08:16:10 +04:00
|
|
|
#endif
|
|
|
|
|
2016-06-08 20:45:22 +03:00
|
|
|
if (document) {
|
2018-10-18 11:02:51 +03:00
|
|
|
document->ContentInserted(aStartChild, aEndChild);
|
2016-06-08 20:45:22 +03:00
|
|
|
}
|
2010-10-21 08:16:10 +04:00
|
|
|
}
|
|
|
|
|
2019-04-13 15:13:15 +03:00
|
|
|
void nsAccessibilityService::ContentRemoved(PresShell* aPresShell,
|
2014-09-20 04:02:30 +04:00
|
|
|
nsIContent* aChildNode) {
|
2016-06-08 20:45:22 +03:00
|
|
|
DocAccessible* document = GetDocAccessible(aPresShell);
|
2012-10-04 13:57:09 +04:00
|
|
|
#ifdef A11Y_LOG
|
2012-06-01 08:27:25 +04:00
|
|
|
if (logging::IsEnabled(logging::eTree)) {
|
2016-06-08 20:45:22 +03:00
|
|
|
logging::MsgBegin("TREE", "content removed; doc: %p", document);
|
2016-04-07 16:30:22 +03:00
|
|
|
logging::Node("container node", aChildNode->GetFlattenedTreeParent());
|
|
|
|
logging::Node("content node", aChildNode);
|
|
|
|
logging::MsgEnd();
|
2014-09-20 04:02:30 +04:00
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
if (document) {
|
2017-04-25 21:02:41 +03:00
|
|
|
document->ContentRemoved(aChildNode);
|
2014-09-20 04:02:30 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
#ifdef A11Y_LOG
|
|
|
|
if (logging::IsEnabled(logging::eTree)) {
|
2012-06-01 08:27:25 +04:00
|
|
|
logging::MsgEnd();
|
2012-11-04 06:19:56 +04:00
|
|
|
logging::Stack();
|
2010-10-21 08:16:10 +04:00
|
|
|
}
|
2010-11-06 07:11:08 +03:00
|
|
|
#endif
|
2010-10-21 08:16:10 +04:00
|
|
|
}
|
|
|
|
|
2019-04-13 15:13:15 +03:00
|
|
|
void nsAccessibilityService::UpdateText(PresShell* aPresShell,
|
2011-01-28 11:42:22 +03:00
|
|
|
nsIContent* aContent) {
|
2012-05-27 13:01:40 +04:00
|
|
|
DocAccessible* document = GetDocAccessible(aPresShell);
|
2011-01-28 11:42:22 +03:00
|
|
|
if (document) document->UpdateText(aContent);
|
|
|
|
}
|
|
|
|
|
2019-04-13 15:13:15 +03:00
|
|
|
void nsAccessibilityService::TreeViewChanged(PresShell* aPresShell,
|
2012-04-02 15:31:10 +04:00
|
|
|
nsIContent* aContent,
|
|
|
|
nsITreeView* aView) {
|
2012-05-27 13:01:40 +04:00
|
|
|
DocAccessible* document = GetDocAccessible(aPresShell);
|
2012-04-02 15:31:10 +04:00
|
|
|
if (document) {
|
2012-05-29 05:18:45 +04:00
|
|
|
Accessible* accessible = document->GetAccessible(aContent);
|
2012-04-02 15:31:10 +04:00
|
|
|
if (accessible) {
|
2012-06-11 03:44:50 +04:00
|
|
|
XULTreeAccessible* treeAcc = accessible->AsXULTree();
|
2012-04-02 15:31:10 +04:00
|
|
|
if (treeAcc) treeAcc->TreeViewChanged(aView);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-04-13 15:13:15 +03:00
|
|
|
void nsAccessibilityService::RangeValueChanged(PresShell* aPresShell,
|
2013-04-28 04:54:54 +04:00
|
|
|
nsIContent* aContent) {
|
|
|
|
DocAccessible* document = GetDocAccessible(aPresShell);
|
|
|
|
if (document) {
|
|
|
|
Accessible* accessible = document->GetAccessible(aContent);
|
|
|
|
if (accessible) {
|
|
|
|
document->FireDelayedEvent(nsIAccessibleEvent::EVENT_VALUE_CHANGE,
|
|
|
|
accessible);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-04-13 15:13:15 +03:00
|
|
|
void nsAccessibilityService::UpdateListBullet(PresShell* aPresShell,
|
2011-03-28 17:59:54 +04:00
|
|
|
nsIContent* aHTMLListItemContent,
|
|
|
|
bool aHasBullet) {
|
2012-05-27 13:01:40 +04:00
|
|
|
DocAccessible* document = GetDocAccessible(aPresShell);
|
2011-03-28 17:59:54 +04:00
|
|
|
if (document) {
|
2012-05-29 05:18:45 +04:00
|
|
|
Accessible* accessible = document->GetAccessible(aHTMLListItemContent);
|
2011-03-28 17:59:54 +04:00
|
|
|
if (accessible) {
|
2012-05-08 09:16:40 +04:00
|
|
|
HTMLLIAccessible* listItem = accessible->AsHTMLListItem();
|
2011-03-28 17:59:54 +04:00
|
|
|
if (listItem) listItem->UpdateBullet(aHasBullet);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-03-16 00:16:02 +04:00
|
|
|
void nsAccessibilityService::UpdateImageMap(nsImageFrame* aImageFrame) {
|
2019-04-06 09:02:28 +03:00
|
|
|
PresShell* presShell = aImageFrame->PresShell();
|
2012-05-27 13:01:40 +04:00
|
|
|
DocAccessible* document = GetDocAccessible(presShell);
|
2012-03-16 00:16:02 +04:00
|
|
|
if (document) {
|
|
|
|
Accessible* accessible = document->GetAccessible(aImageFrame->GetContent());
|
|
|
|
if (accessible) {
|
2012-06-04 16:32:34 +04:00
|
|
|
HTMLImageMapAccessible* imageMap = accessible->AsImageMap();
|
2012-03-16 00:16:02 +04:00
|
|
|
if (imageMap) {
|
|
|
|
imageMap->UpdateChildAreas();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// If image map was initialized after we created an accessible (that'll
|
|
|
|
// be an image accessible) then recreate it.
|
|
|
|
RecreateAccessible(presShell, aImageFrame->GetContent());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-04-13 15:13:15 +03:00
|
|
|
void nsAccessibilityService::UpdateLabelValue(PresShell* aPresShell,
|
2013-03-01 08:06:16 +04:00
|
|
|
nsIContent* aLabelElm,
|
|
|
|
const nsString& aNewValue) {
|
|
|
|
DocAccessible* document = GetDocAccessible(aPresShell);
|
|
|
|
if (document) {
|
|
|
|
Accessible* accessible = document->GetAccessible(aLabelElm);
|
|
|
|
if (accessible) {
|
|
|
|
XULLabelAccessible* xulLabel = accessible->AsXULLabel();
|
|
|
|
NS_ASSERTION(xulLabel,
|
|
|
|
"UpdateLabelValue was called for wrong accessible!");
|
|
|
|
if (xulLabel) xulLabel->UpdateLabelValue(aNewValue);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-04-13 15:13:15 +03:00
|
|
|
void nsAccessibilityService::PresShellActivated(PresShell* aPresShell) {
|
2012-11-03 03:57:58 +04:00
|
|
|
DocAccessible* document = aPresShell->GetDocAccessible();
|
|
|
|
if (document) {
|
|
|
|
RootAccessible* rootDocument = document->RootAccessible();
|
|
|
|
NS_ASSERTION(rootDocument, "Entirely broken tree: no root document!");
|
|
|
|
if (rootDocument) rootDocument->DocumentActivated(document);
|
2011-03-02 17:41:42 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-04-13 15:13:15 +03:00
|
|
|
void nsAccessibilityService::RecreateAccessible(PresShell* aPresShell,
|
2010-10-21 08:16:10 +04:00
|
|
|
nsIContent* aContent) {
|
2012-05-27 13:01:40 +04:00
|
|
|
DocAccessible* document = GetDocAccessible(aPresShell);
|
2012-03-23 05:49:55 +04:00
|
|
|
if (document) document->RecreateAccessible(aContent);
|
2010-10-21 08:16:10 +04:00
|
|
|
}
|
|
|
|
|
2012-08-22 19:56:38 +04:00
|
|
|
void nsAccessibilityService::GetStringRole(uint32_t aRole, nsAString& aString) {
|
2012-07-21 22:32:25 +04:00
|
|
|
#define ROLE(geckoRole, stringRole, atkRole, macRole, msaaRole, ia2Role, \
|
2018-08-09 14:43:00 +03:00
|
|
|
androidClass, nameRule) \
|
2012-04-26 22:25:33 +04:00
|
|
|
case roles::geckoRole: \
|
2018-03-24 21:06:05 +03:00
|
|
|
aString.AssignLiteral(stringRole); \
|
2016-08-08 18:35:56 +03:00
|
|
|
return;
|
2012-04-26 22:25:33 +04:00
|
|
|
|
|
|
|
switch (aRole) {
|
|
|
|
#include "RoleMap.h"
|
|
|
|
default:
|
|
|
|
aString.AssignLiteral("unknown");
|
2016-08-08 18:35:56 +03:00
|
|
|
return;
|
2007-06-02 07:23:58 +04:00
|
|
|
}
|
|
|
|
|
2012-04-26 22:25:33 +04:00
|
|
|
#undef ROLE
|
2007-06-02 07:23:58 +04:00
|
|
|
}
|
|
|
|
|
2012-08-22 19:56:38 +04:00
|
|
|
void nsAccessibilityService::GetStringStates(uint32_t aState,
|
|
|
|
uint32_t aExtraState,
|
2016-12-13 22:00:16 +03:00
|
|
|
nsISupports** aStringStates) {
|
2017-07-06 15:00:35 +03:00
|
|
|
RefPtr<DOMStringList> stringStates =
|
2016-12-13 22:00:16 +03:00
|
|
|
GetStringStates(nsAccUtils::To64State(aState, aExtraState));
|
|
|
|
|
|
|
|
// unknown state
|
|
|
|
if (!stringStates->Length()) {
|
|
|
|
stringStates->Add(NS_LITERAL_STRING("unknown"));
|
|
|
|
}
|
|
|
|
|
|
|
|
stringStates.forget(aStringStates);
|
|
|
|
}
|
2007-06-02 07:23:58 +04:00
|
|
|
|
2016-12-13 22:00:16 +03:00
|
|
|
already_AddRefed<DOMStringList> nsAccessibilityService::GetStringStates(
|
|
|
|
uint64_t aStates) const {
|
|
|
|
RefPtr<DOMStringList> stringStates = new DOMStringList();
|
2011-04-10 03:38:06 +04:00
|
|
|
|
2016-12-13 22:00:16 +03:00
|
|
|
if (aStates & states::UNAVAILABLE) {
|
2007-06-02 07:23:58 +04:00
|
|
|
stringStates->Add(NS_LITERAL_STRING("unavailable"));
|
2016-08-08 18:35:56 +03:00
|
|
|
}
|
2016-12-13 22:00:16 +03:00
|
|
|
if (aStates & states::SELECTED) {
|
2007-06-02 07:23:58 +04:00
|
|
|
stringStates->Add(NS_LITERAL_STRING("selected"));
|
2016-08-08 18:35:56 +03:00
|
|
|
}
|
2016-12-13 22:00:16 +03:00
|
|
|
if (aStates & states::FOCUSED) {
|
2007-06-02 07:23:58 +04:00
|
|
|
stringStates->Add(NS_LITERAL_STRING("focused"));
|
2016-08-08 18:35:56 +03:00
|
|
|
}
|
2016-12-13 22:00:16 +03:00
|
|
|
if (aStates & states::PRESSED) {
|
2007-06-02 07:23:58 +04:00
|
|
|
stringStates->Add(NS_LITERAL_STRING("pressed"));
|
2016-08-08 18:35:56 +03:00
|
|
|
}
|
2016-12-13 22:00:16 +03:00
|
|
|
if (aStates & states::CHECKED) {
|
2007-06-02 07:23:58 +04:00
|
|
|
stringStates->Add(NS_LITERAL_STRING("checked"));
|
2016-08-08 18:35:56 +03:00
|
|
|
}
|
2016-12-13 22:00:16 +03:00
|
|
|
if (aStates & states::MIXED) {
|
2007-06-02 07:23:58 +04:00
|
|
|
stringStates->Add(NS_LITERAL_STRING("mixed"));
|
2016-08-08 18:35:56 +03:00
|
|
|
}
|
2016-12-13 22:00:16 +03:00
|
|
|
if (aStates & states::READONLY) {
|
2007-06-02 07:23:58 +04:00
|
|
|
stringStates->Add(NS_LITERAL_STRING("readonly"));
|
2016-08-08 18:35:56 +03:00
|
|
|
}
|
2016-12-13 22:00:16 +03:00
|
|
|
if (aStates & states::HOTTRACKED) {
|
2007-06-02 07:23:58 +04:00
|
|
|
stringStates->Add(NS_LITERAL_STRING("hottracked"));
|
2016-08-08 18:35:56 +03:00
|
|
|
}
|
2016-12-13 22:00:16 +03:00
|
|
|
if (aStates & states::DEFAULT) {
|
2007-06-02 07:23:58 +04:00
|
|
|
stringStates->Add(NS_LITERAL_STRING("default"));
|
2016-08-08 18:35:56 +03:00
|
|
|
}
|
2016-12-13 22:00:16 +03:00
|
|
|
if (aStates & states::EXPANDED) {
|
2007-06-02 07:23:58 +04:00
|
|
|
stringStates->Add(NS_LITERAL_STRING("expanded"));
|
2016-08-08 18:35:56 +03:00
|
|
|
}
|
2016-12-13 22:00:16 +03:00
|
|
|
if (aStates & states::COLLAPSED) {
|
2007-06-02 07:23:58 +04:00
|
|
|
stringStates->Add(NS_LITERAL_STRING("collapsed"));
|
2016-08-08 18:35:56 +03:00
|
|
|
}
|
2016-12-13 22:00:16 +03:00
|
|
|
if (aStates & states::BUSY) {
|
2007-06-02 07:23:58 +04:00
|
|
|
stringStates->Add(NS_LITERAL_STRING("busy"));
|
2016-08-08 18:35:56 +03:00
|
|
|
}
|
2016-12-13 22:00:16 +03:00
|
|
|
if (aStates & states::FLOATING) {
|
2007-06-02 07:23:58 +04:00
|
|
|
stringStates->Add(NS_LITERAL_STRING("floating"));
|
2016-08-08 18:35:56 +03:00
|
|
|
}
|
2016-12-13 22:00:16 +03:00
|
|
|
if (aStates & states::ANIMATED) {
|
2007-06-02 07:23:58 +04:00
|
|
|
stringStates->Add(NS_LITERAL_STRING("animated"));
|
2016-08-08 18:35:56 +03:00
|
|
|
}
|
2016-12-13 22:00:16 +03:00
|
|
|
if (aStates & states::INVISIBLE) {
|
2007-06-02 07:23:58 +04:00
|
|
|
stringStates->Add(NS_LITERAL_STRING("invisible"));
|
2016-08-08 18:35:56 +03:00
|
|
|
}
|
2016-12-13 22:00:16 +03:00
|
|
|
if (aStates & states::OFFSCREEN) {
|
2007-06-02 07:23:58 +04:00
|
|
|
stringStates->Add(NS_LITERAL_STRING("offscreen"));
|
2016-08-08 18:35:56 +03:00
|
|
|
}
|
2016-12-13 22:00:16 +03:00
|
|
|
if (aStates & states::SIZEABLE) {
|
2007-06-02 07:23:58 +04:00
|
|
|
stringStates->Add(NS_LITERAL_STRING("sizeable"));
|
2016-08-08 18:35:56 +03:00
|
|
|
}
|
2016-12-13 22:00:16 +03:00
|
|
|
if (aStates & states::MOVEABLE) {
|
2007-06-02 07:23:58 +04:00
|
|
|
stringStates->Add(NS_LITERAL_STRING("moveable"));
|
2016-08-08 18:35:56 +03:00
|
|
|
}
|
2016-12-13 22:00:16 +03:00
|
|
|
if (aStates & states::SELFVOICING) {
|
2007-06-02 07:23:58 +04:00
|
|
|
stringStates->Add(NS_LITERAL_STRING("selfvoicing"));
|
2016-08-08 18:35:56 +03:00
|
|
|
}
|
2016-12-13 22:00:16 +03:00
|
|
|
if (aStates & states::FOCUSABLE) {
|
2007-06-02 07:23:58 +04:00
|
|
|
stringStates->Add(NS_LITERAL_STRING("focusable"));
|
2016-08-08 18:35:56 +03:00
|
|
|
}
|
2016-12-13 22:00:16 +03:00
|
|
|
if (aStates & states::SELECTABLE) {
|
2007-06-02 07:23:58 +04:00
|
|
|
stringStates->Add(NS_LITERAL_STRING("selectable"));
|
2016-08-08 18:35:56 +03:00
|
|
|
}
|
2016-12-13 22:00:16 +03:00
|
|
|
if (aStates & states::LINKED) {
|
2007-06-02 07:23:58 +04:00
|
|
|
stringStates->Add(NS_LITERAL_STRING("linked"));
|
2016-08-08 18:35:56 +03:00
|
|
|
}
|
2016-12-13 22:00:16 +03:00
|
|
|
if (aStates & states::TRAVERSED) {
|
2007-06-02 07:23:58 +04:00
|
|
|
stringStates->Add(NS_LITERAL_STRING("traversed"));
|
2016-08-08 18:35:56 +03:00
|
|
|
}
|
2016-12-13 22:00:16 +03:00
|
|
|
if (aStates & states::MULTISELECTABLE) {
|
2007-06-02 07:23:58 +04:00
|
|
|
stringStates->Add(NS_LITERAL_STRING("multiselectable"));
|
2016-08-08 18:35:56 +03:00
|
|
|
}
|
2016-12-13 22:00:16 +03:00
|
|
|
if (aStates & states::EXTSELECTABLE) {
|
2007-06-02 07:23:58 +04:00
|
|
|
stringStates->Add(NS_LITERAL_STRING("extselectable"));
|
2016-08-08 18:35:56 +03:00
|
|
|
}
|
2016-12-13 22:00:16 +03:00
|
|
|
if (aStates & states::PROTECTED) {
|
2007-06-02 07:23:58 +04:00
|
|
|
stringStates->Add(NS_LITERAL_STRING("protected"));
|
2016-08-08 18:35:56 +03:00
|
|
|
}
|
2016-12-13 22:00:16 +03:00
|
|
|
if (aStates & states::HASPOPUP) {
|
2007-06-02 07:23:58 +04:00
|
|
|
stringStates->Add(NS_LITERAL_STRING("haspopup"));
|
2016-08-08 18:35:56 +03:00
|
|
|
}
|
2016-12-13 22:00:16 +03:00
|
|
|
if (aStates & states::REQUIRED) {
|
2007-06-02 07:23:58 +04:00
|
|
|
stringStates->Add(NS_LITERAL_STRING("required"));
|
2016-08-08 18:35:56 +03:00
|
|
|
}
|
2016-12-13 22:00:16 +03:00
|
|
|
if (aStates & states::ALERT) {
|
2011-04-10 03:38:06 +04:00
|
|
|
stringStates->Add(NS_LITERAL_STRING("alert"));
|
2016-08-08 18:35:56 +03:00
|
|
|
}
|
2016-12-13 22:00:16 +03:00
|
|
|
if (aStates & states::INVALID) {
|
2007-06-02 07:23:58 +04:00
|
|
|
stringStates->Add(NS_LITERAL_STRING("invalid"));
|
2016-08-08 18:35:56 +03:00
|
|
|
}
|
2016-12-13 22:00:16 +03:00
|
|
|
if (aStates & states::CHECKABLE) {
|
2007-06-02 07:23:58 +04:00
|
|
|
stringStates->Add(NS_LITERAL_STRING("checkable"));
|
2016-08-08 18:35:56 +03:00
|
|
|
}
|
2016-12-13 22:00:16 +03:00
|
|
|
if (aStates & states::SUPPORTS_AUTOCOMPLETION) {
|
2007-07-16 11:57:46 +04:00
|
|
|
stringStates->Add(NS_LITERAL_STRING("autocompletion"));
|
2016-08-08 18:35:56 +03:00
|
|
|
}
|
2016-12-13 22:00:16 +03:00
|
|
|
if (aStates & states::DEFUNCT) {
|
2007-07-16 11:57:46 +04:00
|
|
|
stringStates->Add(NS_LITERAL_STRING("defunct"));
|
2016-08-08 18:35:56 +03:00
|
|
|
}
|
2016-12-13 22:00:16 +03:00
|
|
|
if (aStates & states::SELECTABLE_TEXT) {
|
2007-06-02 07:23:58 +04:00
|
|
|
stringStates->Add(NS_LITERAL_STRING("selectable text"));
|
2016-08-08 18:35:56 +03:00
|
|
|
}
|
2016-12-13 22:00:16 +03:00
|
|
|
if (aStates & states::EDITABLE) {
|
2007-06-02 07:23:58 +04:00
|
|
|
stringStates->Add(NS_LITERAL_STRING("editable"));
|
2016-08-08 18:35:56 +03:00
|
|
|
}
|
2016-12-13 22:00:16 +03:00
|
|
|
if (aStates & states::ACTIVE) {
|
2007-06-02 07:23:58 +04:00
|
|
|
stringStates->Add(NS_LITERAL_STRING("active"));
|
2016-08-08 18:35:56 +03:00
|
|
|
}
|
2016-12-13 22:00:16 +03:00
|
|
|
if (aStates & states::MODAL) {
|
2007-06-02 07:23:58 +04:00
|
|
|
stringStates->Add(NS_LITERAL_STRING("modal"));
|
2016-08-08 18:35:56 +03:00
|
|
|
}
|
2016-12-13 22:00:16 +03:00
|
|
|
if (aStates & states::MULTI_LINE) {
|
2007-06-02 07:23:58 +04:00
|
|
|
stringStates->Add(NS_LITERAL_STRING("multi line"));
|
2016-08-08 18:35:56 +03:00
|
|
|
}
|
2016-12-13 22:00:16 +03:00
|
|
|
if (aStates & states::HORIZONTAL) {
|
2007-07-16 11:57:46 +04:00
|
|
|
stringStates->Add(NS_LITERAL_STRING("horizontal"));
|
2016-08-08 18:35:56 +03:00
|
|
|
}
|
2016-12-13 22:00:16 +03:00
|
|
|
if (aStates & states::OPAQUE1) {
|
2007-07-16 11:57:46 +04:00
|
|
|
stringStates->Add(NS_LITERAL_STRING("opaque"));
|
2016-08-08 18:35:56 +03:00
|
|
|
}
|
2016-12-13 22:00:16 +03:00
|
|
|
if (aStates & states::SINGLE_LINE) {
|
2007-06-02 07:23:58 +04:00
|
|
|
stringStates->Add(NS_LITERAL_STRING("single line"));
|
2016-08-08 18:35:56 +03:00
|
|
|
}
|
2016-12-13 22:00:16 +03:00
|
|
|
if (aStates & states::TRANSIENT) {
|
2007-06-02 07:23:58 +04:00
|
|
|
stringStates->Add(NS_LITERAL_STRING("transient"));
|
2016-08-08 18:35:56 +03:00
|
|
|
}
|
2016-12-13 22:00:16 +03:00
|
|
|
if (aStates & states::VERTICAL) {
|
2007-06-02 07:23:58 +04:00
|
|
|
stringStates->Add(NS_LITERAL_STRING("vertical"));
|
2016-08-08 18:35:56 +03:00
|
|
|
}
|
2016-12-13 22:00:16 +03:00
|
|
|
if (aStates & states::STALE) {
|
2007-07-16 11:57:46 +04:00
|
|
|
stringStates->Add(NS_LITERAL_STRING("stale"));
|
2016-08-08 18:35:56 +03:00
|
|
|
}
|
2016-12-13 22:00:16 +03:00
|
|
|
if (aStates & states::ENABLED) {
|
2007-07-16 11:57:46 +04:00
|
|
|
stringStates->Add(NS_LITERAL_STRING("enabled"));
|
2016-08-08 18:35:56 +03:00
|
|
|
}
|
2016-12-13 22:00:16 +03:00
|
|
|
if (aStates & states::SENSITIVE) {
|
2007-07-16 11:57:46 +04:00
|
|
|
stringStates->Add(NS_LITERAL_STRING("sensitive"));
|
2016-08-08 18:35:56 +03:00
|
|
|
}
|
2016-12-13 22:00:16 +03:00
|
|
|
if (aStates & states::EXPANDABLE) {
|
2007-07-16 11:57:46 +04:00
|
|
|
stringStates->Add(NS_LITERAL_STRING("expandable"));
|
2016-08-08 18:35:56 +03:00
|
|
|
}
|
2007-06-02 07:23:58 +04:00
|
|
|
|
2016-12-13 22:00:16 +03:00
|
|
|
return stringStates.forget();
|
2007-06-02 07:23:58 +04:00
|
|
|
}
|
|
|
|
|
2012-08-22 19:56:38 +04:00
|
|
|
void nsAccessibilityService::GetStringEventType(uint32_t aEventType,
|
2007-08-23 07:26:38 +04:00
|
|
|
nsAString& aString) {
|
2011-10-11 09:50:08 +04:00
|
|
|
NS_ASSERTION(
|
|
|
|
nsIAccessibleEvent::EVENT_LAST_ENTRY == ArrayLength(kEventTypeNames),
|
2007-09-25 07:36:51 +04:00
|
|
|
"nsIAccessibleEvent constants are out of sync to kEventTypeNames");
|
|
|
|
|
2011-10-11 09:50:08 +04:00
|
|
|
if (aEventType >= ArrayLength(kEventTypeNames)) {
|
2007-08-23 07:26:38 +04:00
|
|
|
aString.AssignLiteral("unknown");
|
2016-08-08 18:35:56 +03:00
|
|
|
return;
|
2007-08-23 07:26:38 +04:00
|
|
|
}
|
|
|
|
|
2018-03-24 21:06:05 +03:00
|
|
|
aString.AssignASCII(kEventTypeNames[aEventType]);
|
2007-08-23 07:26:38 +04:00
|
|
|
}
|
|
|
|
|
2017-08-03 00:39:51 +03:00
|
|
|
void nsAccessibilityService::GetStringEventType(uint32_t aEventType,
|
|
|
|
nsACString& aString) {
|
|
|
|
MOZ_ASSERT(
|
|
|
|
nsIAccessibleEvent::EVENT_LAST_ENTRY == ArrayLength(kEventTypeNames),
|
|
|
|
"nsIAccessibleEvent constants are out of sync to kEventTypeNames");
|
|
|
|
|
|
|
|
if (aEventType >= ArrayLength(kEventTypeNames)) {
|
|
|
|
aString.AssignLiteral("unknown");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
aString = nsDependentCString(kEventTypeNames[aEventType]);
|
|
|
|
}
|
|
|
|
|
2012-08-22 19:56:38 +04:00
|
|
|
void nsAccessibilityService::GetStringRelationType(uint32_t aRelationType,
|
2007-10-11 06:02:09 +04:00
|
|
|
nsAString& aString) {
|
2016-08-08 18:35:56 +03:00
|
|
|
NS_ENSURE_TRUE_VOID(aRelationType <=
|
|
|
|
static_cast<uint32_t>(RelationType::LAST));
|
2013-10-23 03:55:27 +04:00
|
|
|
|
|
|
|
#define RELATIONTYPE(geckoType, geckoTypeName, atkType, msaaType, ia2Type) \
|
|
|
|
case RelationType::geckoType: \
|
|
|
|
aString.AssignLiteral(geckoTypeName); \
|
2016-08-08 18:35:56 +03:00
|
|
|
return;
|
2013-10-23 03:55:27 +04:00
|
|
|
|
|
|
|
RelationType relationType = static_cast<RelationType>(aRelationType);
|
|
|
|
switch (relationType) {
|
|
|
|
#include "RelationTypeMap.h"
|
|
|
|
default:
|
|
|
|
aString.AssignLiteral("unknown");
|
2016-08-08 18:35:56 +03:00
|
|
|
return;
|
2007-10-11 06:02:09 +04:00
|
|
|
}
|
|
|
|
|
2013-10-23 03:55:27 +04:00
|
|
|
#undef RELATIONTYPE
|
2010-06-18 06:43:58 +04:00
|
|
|
}
|
|
|
|
|
2010-02-21 03:56:35 +03:00
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
// nsAccessibilityService public
|
|
|
|
|
2016-04-06 14:23:41 +03:00
|
|
|
Accessible* nsAccessibilityService::CreateAccessible(nsINode* aNode,
|
|
|
|
Accessible* aContext,
|
|
|
|
bool* aIsSubtreeHidden) {
|
|
|
|
MOZ_ASSERT(aContext, "No context provided");
|
|
|
|
MOZ_ASSERT(aNode, "No node to create an accessible for");
|
2016-08-29 18:06:48 +03:00
|
|
|
MOZ_ASSERT(gConsumers, "No creation after shutdown");
|
2001-10-31 09:10:44 +03:00
|
|
|
|
2010-11-13 20:49:26 +03:00
|
|
|
if (aIsSubtreeHidden) *aIsSubtreeHidden = false;
|
2009-11-16 17:03:53 +03:00
|
|
|
|
2012-11-30 11:33:01 +04:00
|
|
|
DocAccessible* document = aContext->Document();
|
2016-04-06 14:23:41 +03:00
|
|
|
MOZ_ASSERT(!document->GetAccessible(aNode),
|
|
|
|
"We already have an accessible for this node.");
|
2008-06-11 10:27:22 +04:00
|
|
|
|
2018-04-15 12:43:15 +03:00
|
|
|
if (aNode->IsDocument()) {
|
2010-06-08 20:39:58 +04:00
|
|
|
// If it's document node then ask accessible document loader for
|
|
|
|
// document accessible, otherwise return null.
|
2018-04-15 12:43:15 +03:00
|
|
|
return GetDocAccessible(aNode->AsDocument());
|
2001-06-30 04:25:09 +04:00
|
|
|
}
|
2001-08-03 12:15:20 +04:00
|
|
|
|
2010-02-21 03:56:35 +03:00
|
|
|
// We have a content node.
|
2016-03-31 15:20:14 +03:00
|
|
|
if (!aNode->GetComposedDoc()) {
|
2010-06-08 20:39:58 +04:00
|
|
|
NS_WARNING("Creating accessible for node with no document");
|
2012-07-30 18:20:58 +04:00
|
|
|
return nullptr;
|
2005-09-09 06:30:16 +04:00
|
|
|
}
|
2010-02-21 03:56:35 +03:00
|
|
|
|
2012-11-30 11:33:01 +04:00
|
|
|
if (aNode->OwnerDoc() != document->DocumentNode()) {
|
2012-02-09 20:49:17 +04:00
|
|
|
NS_ERROR("Creating accessible for wrong document");
|
2012-07-30 18:20:58 +04:00
|
|
|
return nullptr;
|
2005-09-09 06:30:16 +04:00
|
|
|
}
|
|
|
|
|
2012-09-06 01:41:10 +04:00
|
|
|
if (!aNode->IsContent()) return nullptr;
|
2010-06-11 12:23:18 +04:00
|
|
|
|
2012-09-06 01:41:10 +04:00
|
|
|
nsIContent* content = aNode->AsContent();
|
2018-07-04 17:18:43 +03:00
|
|
|
if (aria::HasDefinedARIAHidden(content)) {
|
|
|
|
if (aIsSubtreeHidden) {
|
|
|
|
*aIsSubtreeHidden = true;
|
|
|
|
}
|
|
|
|
return nullptr;
|
|
|
|
}
|
2009-11-16 17:03:53 +03:00
|
|
|
|
2010-11-13 20:49:26 +03:00
|
|
|
// Check frame and its visibility. Note, hidden frame allows visible
|
|
|
|
// elements in subtree.
|
2018-07-04 17:18:43 +03:00
|
|
|
nsIFrame* frame = content->GetPrimaryFrame();
|
2013-02-17 01:51:02 +04:00
|
|
|
if (!frame || !frame->StyleVisibility()->IsVisible()) {
|
2018-05-15 16:44:21 +03:00
|
|
|
// display:contents element doesn't have a frame, but retains the semantics.
|
|
|
|
// All its children are unaffected.
|
|
|
|
if (content->IsElement() && content->AsElement()->IsDisplayContents()) {
|
|
|
|
const HTMLMarkupMapInfo* markupMap =
|
|
|
|
mHTMLMarkupMap.Get(content->NodeInfo()->NameAtom());
|
|
|
|
if (markupMap && markupMap->new_func) {
|
|
|
|
RefPtr<Accessible> newAcc =
|
|
|
|
markupMap->new_func(content->AsElement(), aContext);
|
2018-09-26 07:06:57 +03:00
|
|
|
if (newAcc) {
|
|
|
|
document->BindToDocument(newAcc,
|
|
|
|
aria::GetRoleMap(content->AsElement()));
|
|
|
|
}
|
2018-05-15 16:44:21 +03:00
|
|
|
return newAcc;
|
|
|
|
}
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
|
2012-09-06 01:41:10 +04:00
|
|
|
if (aIsSubtreeHidden && !frame) *aIsSubtreeHidden = true;
|
2006-05-01 19:52:56 +04:00
|
|
|
|
2012-07-30 18:20:58 +04:00
|
|
|
return nullptr;
|
2010-02-21 03:56:35 +03:00
|
|
|
}
|
|
|
|
|
2012-09-06 01:41:10 +04:00
|
|
|
if (frame->GetContent() != content) {
|
2010-04-08 10:43:08 +04:00
|
|
|
// Not the main content for this frame. This happens because <area>
|
|
|
|
// elements return the image frame as their primary frame. The main content
|
|
|
|
// for the image frame is the image content. If the frame is not an image
|
|
|
|
// frame or the node is not an area element then null is returned.
|
2011-10-04 17:05:17 +04:00
|
|
|
// This setup will change when bug 135040 is fixed. Make sure we don't
|
|
|
|
// create area accessible here. Hopefully assertion below will handle that.
|
|
|
|
|
|
|
|
#ifdef DEBUG
|
2012-09-06 01:41:10 +04:00
|
|
|
nsImageFrame* imageFrame = do_QueryFrame(frame);
|
2015-03-03 14:08:59 +03:00
|
|
|
NS_ASSERTION(imageFrame && content->IsHTMLElement(nsGkAtoms::area),
|
2011-10-04 17:05:17 +04:00
|
|
|
"Unknown case of not main content for the frame!");
|
|
|
|
#endif
|
2012-07-30 18:20:58 +04:00
|
|
|
return nullptr;
|
2004-05-26 17:01:13 +04:00
|
|
|
}
|
2001-06-30 04:25:09 +04:00
|
|
|
|
2011-10-04 17:05:17 +04:00
|
|
|
#ifdef DEBUG
|
2012-09-06 01:41:10 +04:00
|
|
|
nsImageFrame* imageFrame = do_QueryFrame(frame);
|
2015-03-03 14:08:59 +03:00
|
|
|
NS_ASSERTION(!imageFrame || !content->IsHTMLElement(nsGkAtoms::area),
|
2011-10-04 17:05:17 +04:00
|
|
|
"Image map manages the area accessible creation!");
|
|
|
|
#endif
|
|
|
|
|
2010-02-21 03:56:35 +03:00
|
|
|
// Attempt to create an accessible based on what we know.
|
2015-10-18 08:24:48 +03:00
|
|
|
RefPtr<Accessible> newAcc;
|
2011-01-31 18:53:09 +03:00
|
|
|
|
|
|
|
// Create accessible for visible text frames.
|
2018-04-13 01:41:00 +03:00
|
|
|
if (content->IsText()) {
|
2015-11-30 16:21:25 +03:00
|
|
|
nsIFrame::RenderedText text = frame->GetRenderedText(
|
2019-04-26 02:03:04 +03:00
|
|
|
0, UINT32_MAX, nsIFrame::TextOffsetType::OffsetsInContentText,
|
|
|
|
nsIFrame::TrailingWhitespace::DontTrim);
|
2013-07-18 19:09:45 +04:00
|
|
|
// Ignore not rendered text nodes and whitespace text nodes between table
|
|
|
|
// cells.
|
2015-10-30 09:23:10 +03:00
|
|
|
if (text.mString.IsEmpty() ||
|
|
|
|
(aContext->IsTableRow() &&
|
|
|
|
nsCoreUtils::IsWhitespaceString(text.mString))) {
|
2011-01-31 18:53:09 +03:00
|
|
|
if (aIsSubtreeHidden) *aIsSubtreeHidden = true;
|
|
|
|
|
2012-07-30 18:20:58 +04:00
|
|
|
return nullptr;
|
2009-11-16 17:03:53 +03:00
|
|
|
}
|
2009-11-19 02:42:18 +03:00
|
|
|
|
2012-11-30 11:33:01 +04:00
|
|
|
newAcc = CreateAccessibleByFrameType(frame, content, aContext);
|
2013-09-06 23:27:07 +04:00
|
|
|
document->BindToDocument(newAcc, nullptr);
|
2015-10-30 09:23:10 +03:00
|
|
|
newAcc->AsTextLeaf()->SetText(text.mString);
|
2013-09-06 23:27:07 +04:00
|
|
|
return newAcc;
|
2004-05-26 17:01:13 +04:00
|
|
|
}
|
2006-07-13 16:55:15 +04:00
|
|
|
|
2015-03-03 14:08:59 +03:00
|
|
|
if (content->IsHTMLElement(nsGkAtoms::map)) {
|
2008-06-11 10:27:22 +04:00
|
|
|
// Create hyper text accessible for HTML map if it is used to group links
|
|
|
|
// (see http://www.w3.org/TR/WCAG10-HTML-TECHS/#group-bypass). If the HTML
|
2011-10-05 10:24:44 +04:00
|
|
|
// map rect is empty then it is used for links grouping. Otherwise it should
|
|
|
|
// be used in conjunction with HTML image element and in this case we don't
|
|
|
|
// create any accessible for it and don't walk into it. The accessibles for
|
2012-06-04 16:32:34 +04:00
|
|
|
// HTML area (HTMLAreaAccessible) the map contains are attached as
|
2011-10-05 10:24:44 +04:00
|
|
|
// children of the appropriate accessible for HTML image
|
2012-06-02 15:30:34 +04:00
|
|
|
// (ImageAccessible).
|
2012-09-06 01:41:10 +04:00
|
|
|
if (nsLayoutUtils::GetAllInFlowRectsUnion(frame, frame->GetParent())
|
|
|
|
.IsEmpty()) {
|
2010-11-13 20:49:26 +03:00
|
|
|
if (aIsSubtreeHidden) *aIsSubtreeHidden = true;
|
2010-02-21 03:56:35 +03:00
|
|
|
|
2012-07-30 18:20:58 +04:00
|
|
|
return nullptr;
|
2008-06-11 10:27:22 +04:00
|
|
|
}
|
2010-02-21 03:56:35 +03:00
|
|
|
|
2012-11-30 11:33:01 +04:00
|
|
|
newAcc = new HyperTextAccessibleWrap(content, document);
|
2016-03-03 15:45:47 +03:00
|
|
|
document->BindToDocument(newAcc, aria::GetRoleMap(content->AsElement()));
|
2013-09-06 23:27:07 +04:00
|
|
|
return newAcc;
|
2008-06-11 10:27:22 +04:00
|
|
|
}
|
|
|
|
|
2016-03-11 05:13:01 +03:00
|
|
|
const nsRoleMapEntry* roleMapEntry = aria::GetRoleMap(content->AsElement());
|
2012-09-18 06:51:39 +04:00
|
|
|
|
|
|
|
// If the element is focusable or global ARIA attribute is applied to it or
|
|
|
|
// it is referenced by ARIA relationship then treat role="presentation" on
|
|
|
|
// the element as the role is not there.
|
2015-02-19 20:50:34 +03:00
|
|
|
if (roleMapEntry && (roleMapEntry->Is(nsGkAtoms::presentation) ||
|
|
|
|
roleMapEntry->Is(nsGkAtoms::none))) {
|
2012-11-30 11:33:01 +04:00
|
|
|
if (!MustBeAccessible(content, document)) return nullptr;
|
2012-09-18 06:51:39 +04:00
|
|
|
|
|
|
|
roleMapEntry = nullptr;
|
2006-07-13 16:55:15 +04:00
|
|
|
}
|
|
|
|
|
2015-03-03 14:08:59 +03:00
|
|
|
if (!newAcc && content->IsHTMLElement()) { // HTML accessibles
|
2015-06-27 00:41:22 +03:00
|
|
|
bool isARIATablePart = roleMapEntry && (roleMapEntry->accTypes &
|
|
|
|
(eTableCell | eTableRow | eTable));
|
2015-02-14 04:09:51 +03:00
|
|
|
|
|
|
|
if (!isARIATablePart || frame->AccessibleType() == eHTMLTableCellType ||
|
2015-06-27 00:41:22 +03:00
|
|
|
frame->AccessibleType() == eHTMLTableRowType ||
|
2015-02-14 04:09:51 +03:00
|
|
|
frame->AccessibleType() == eHTMLTableType) {
|
2015-03-05 06:56:57 +03:00
|
|
|
// Prefer to use markup to decide if and what kind of accessible to
|
|
|
|
// create,
|
2018-02-05 17:26:59 +03:00
|
|
|
const HTMLMarkupMapInfo* markupMap =
|
|
|
|
mHTMLMarkupMap.Get(content->NodeInfo()->NameAtom());
|
2015-03-05 21:16:12 +03:00
|
|
|
if (markupMap && markupMap->new_func)
|
2018-03-07 00:47:43 +03:00
|
|
|
newAcc = markupMap->new_func(content->AsElement(), aContext);
|
2015-03-05 06:56:57 +03:00
|
|
|
|
2015-02-14 04:09:51 +03:00
|
|
|
if (!newAcc) // try by frame accessible type.
|
|
|
|
newAcc = CreateAccessibleByFrameType(frame, content, aContext);
|
|
|
|
}
|
|
|
|
|
2015-06-27 00:41:22 +03:00
|
|
|
// In case of ARIA grid or table use table-specific classes if it's not
|
|
|
|
// native table based.
|
|
|
|
if (isARIATablePart && (!newAcc || newAcc->IsGenericHyperText())) {
|
2012-12-18 09:22:26 +04:00
|
|
|
if ((roleMapEntry->accTypes & eTableCell)) {
|
2015-02-14 04:09:51 +03:00
|
|
|
if (aContext->IsTableRow())
|
2012-11-30 11:33:01 +04:00
|
|
|
newAcc = new ARIAGridCellAccessibleWrap(content, document);
|
|
|
|
|
2015-06-27 00:41:22 +03:00
|
|
|
} else if (roleMapEntry->IsOfType(eTableRow)) {
|
2019-02-04 09:17:33 +03:00
|
|
|
if (aContext->IsTable() ||
|
|
|
|
(aContext->Parent() && aContext->Parent()->IsTable())) {
|
2015-06-27 00:41:22 +03:00
|
|
|
newAcc = new ARIARowAccessible(content, document);
|
2019-02-04 09:17:33 +03:00
|
|
|
}
|
2015-06-27 00:41:22 +03:00
|
|
|
|
2015-02-14 04:09:51 +03:00
|
|
|
} else if (roleMapEntry->IsOfType(eTable)) {
|
2012-11-30 11:33:01 +04:00
|
|
|
newAcc = new ARIAGridAccessibleWrap(content, document);
|
2009-05-18 12:35:21 +04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-02-14 04:09:51 +03:00
|
|
|
// If table has strong ARIA role then all table descendants shouldn't
|
|
|
|
// expose their native roles.
|
|
|
|
if (!roleMapEntry && newAcc && aContext->HasStrongARIARole()) {
|
|
|
|
if (frame->AccessibleType() == eHTMLTableRowType) {
|
2016-03-11 05:13:01 +03:00
|
|
|
const nsRoleMapEntry* contextRoleMap = aContext->ARIARoleMap();
|
2015-02-14 04:09:51 +03:00
|
|
|
if (!contextRoleMap->IsOfType(eTable))
|
|
|
|
roleMapEntry = &aria::gEmptyRoleMap;
|
2012-11-30 11:33:01 +04:00
|
|
|
|
2015-02-14 04:09:51 +03:00
|
|
|
} else if (frame->AccessibleType() == eHTMLTableCellType &&
|
|
|
|
aContext->ARIARoleMap() == &aria::gEmptyRoleMap) {
|
|
|
|
roleMapEntry = &aria::gEmptyRoleMap;
|
2012-11-30 11:33:01 +04:00
|
|
|
|
2015-03-03 14:08:59 +03:00
|
|
|
} else if (content->IsAnyOfHTMLElements(nsGkAtoms::dt, nsGkAtoms::li,
|
|
|
|
nsGkAtoms::dd) ||
|
2015-02-14 04:09:51 +03:00
|
|
|
frame->AccessibleType() == eHTMLLiType) {
|
2016-03-11 05:13:01 +03:00
|
|
|
const nsRoleMapEntry* contextRoleMap = aContext->ARIARoleMap();
|
2015-02-14 04:09:51 +03:00
|
|
|
if (!contextRoleMap->IsOfType(eList))
|
2013-04-25 07:48:26 +04:00
|
|
|
roleMapEntry = &aria::gEmptyRoleMap;
|
2012-11-30 11:33:01 +04:00
|
|
|
}
|
2006-07-13 16:55:15 +04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-12-28 12:15:02 +04:00
|
|
|
// Accessible XBL types and deck stuff are used in XUL only currently.
|
2015-03-03 14:08:59 +03:00
|
|
|
if (!newAcc && content->IsXULElement()) {
|
2012-12-28 12:15:02 +04:00
|
|
|
// No accessible for not selected deck panel and its children.
|
|
|
|
if (!aContext->IsXULTabpanels()) {
|
|
|
|
nsDeckFrame* deckFrame = do_QueryFrame(frame->GetParent());
|
|
|
|
if (deckFrame && deckFrame->GetSelectedBox() != frame) {
|
|
|
|
if (aIsSubtreeHidden) *aIsSubtreeHidden = true;
|
|
|
|
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-11-03 14:15:44 +03:00
|
|
|
#ifdef MOZ_XUL
|
|
|
|
// Prefer to use XUL to decide if and what kind of accessible to create.
|
|
|
|
const XULMarkupMapInfo* xulMap =
|
2018-02-05 17:26:59 +03:00
|
|
|
mXULMarkupMap.Get(content->NodeInfo()->NameAtom());
|
2017-11-03 14:15:44 +03:00
|
|
|
if (xulMap && xulMap->new_func) {
|
2018-03-07 00:47:43 +03:00
|
|
|
newAcc = xulMap->new_func(content->AsElement(), aContext);
|
2017-11-03 14:15:44 +03:00
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2012-12-28 12:15:02 +04:00
|
|
|
// Any XUL box can be used as tabpanel, make sure we create a proper
|
|
|
|
// accessible for it.
|
|
|
|
if (!newAcc && aContext->IsXULTabpanels() &&
|
|
|
|
content->GetParent() == aContext->GetContent()) {
|
2017-05-01 20:32:52 +03:00
|
|
|
LayoutFrameType frameType = frame->Type();
|
|
|
|
if (frameType == LayoutFrameType::Box ||
|
|
|
|
frameType == LayoutFrameType::Scroll) {
|
2012-12-28 12:15:02 +04:00
|
|
|
newAcc = new XULTabpanelAccessible(content, document);
|
|
|
|
}
|
|
|
|
}
|
2009-05-18 12:35:21 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
if (!newAcc) {
|
2015-03-03 14:08:59 +03:00
|
|
|
if (content->IsSVGElement()) {
|
2016-12-18 14:11:47 +03:00
|
|
|
SVGGeometryFrame* geometryFrame = do_QueryFrame(frame);
|
|
|
|
if (geometryFrame) {
|
2013-01-04 08:26:00 +04:00
|
|
|
// A graphic elements: rect, circle, ellipse, line, path, polygon,
|
|
|
|
// polyline and image. A 'use' and 'text' graphic elements require
|
|
|
|
// special support.
|
2015-03-05 03:04:46 +03:00
|
|
|
newAcc = new EnumRoleAccessible<roles::GRAPHIC>(content, document);
|
2015-03-03 14:08:59 +03:00
|
|
|
} else if (content->IsSVGElement(nsGkAtoms::svg)) {
|
2015-03-05 03:04:46 +03:00
|
|
|
newAcc = new EnumRoleAccessible<roles::DIAGRAM>(content, document);
|
2013-01-04 08:26:00 +04:00
|
|
|
}
|
2015-03-09 15:16:12 +03:00
|
|
|
|
2015-03-03 14:08:59 +03:00
|
|
|
} else if (content->IsMathMLElement()) {
|
2018-02-05 17:26:59 +03:00
|
|
|
const HTMLMarkupMapInfo* markupMap =
|
|
|
|
mHTMLMarkupMap.Get(content->NodeInfo()->NameAtom());
|
2015-03-09 15:16:12 +03:00
|
|
|
if (markupMap && markupMap->new_func)
|
2018-03-07 00:47:43 +03:00
|
|
|
newAcc = markupMap->new_func(content->AsElement(), aContext);
|
2015-03-09 15:16:12 +03:00
|
|
|
|
|
|
|
// Fall back to text when encountering Content MathML.
|
2015-06-16 17:15:00 +03:00
|
|
|
if (!newAcc && !content->IsAnyOfMathMLElements(
|
|
|
|
nsGkAtoms::annotation_, nsGkAtoms::annotation_xml_,
|
2015-03-09 15:16:12 +03:00
|
|
|
nsGkAtoms::mpadded_, nsGkAtoms::mphantom_,
|
|
|
|
nsGkAtoms::maligngroup_, nsGkAtoms::malignmark_,
|
2015-06-16 17:15:00 +03:00
|
|
|
nsGkAtoms::mspace_, nsGkAtoms::semantics_)) {
|
|
|
|
newAcc = new HyperTextAccessible(content, document);
|
2015-03-09 15:16:12 +03:00
|
|
|
}
|
2009-05-18 12:35:21 +04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2006-07-13 16:55:15 +04:00
|
|
|
// If no accessible, see if we need to create a generic accessible because
|
|
|
|
// of some property that makes this object interesting
|
2012-06-04 16:32:38 +04:00
|
|
|
// We don't do this for <body>, <html>, <window>, <dialog> etc. which
|
2006-08-17 17:21:41 +04:00
|
|
|
// correspond to the doc accessible and will be created in any case
|
2015-03-03 14:08:59 +03:00
|
|
|
if (!newAcc && !content->IsHTMLElement(nsGkAtoms::body) &&
|
|
|
|
content->GetParent() &&
|
2012-11-30 11:33:01 +04:00
|
|
|
(roleMapEntry || MustBeAccessible(content, document) ||
|
2015-03-03 14:08:59 +03:00
|
|
|
(content->IsHTMLElement() && nsCoreUtils::HasClickListener(content)))) {
|
2006-07-13 16:55:15 +04:00
|
|
|
// This content is focusable or has an interesting dynamic content
|
|
|
|
// accessibility property. If it's interesting we need it in the
|
|
|
|
// accessibility hierarchy so that events or other accessibles can point to
|
|
|
|
// it, or so that it can hold a state, etc.
|
2015-03-03 14:08:59 +03:00
|
|
|
if (content->IsHTMLElement()) {
|
2006-07-13 16:55:15 +04:00
|
|
|
// Interesting HTML container which may have selectable text and/or
|
|
|
|
// embedded objects
|
2012-11-30 11:33:01 +04:00
|
|
|
newAcc = new HyperTextAccessibleWrap(content, document);
|
2012-09-06 01:41:10 +04:00
|
|
|
} else { // XUL, SVG, MathML etc.
|
2006-07-13 16:55:15 +04:00
|
|
|
// Interesting generic non-HTML container
|
2012-11-30 11:33:01 +04:00
|
|
|
newAcc = new AccessibleWrap(content, document);
|
2001-08-14 10:01:48 +04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-02-24 16:01:21 +03:00
|
|
|
if (newAcc) {
|
|
|
|
document->BindToDocument(newAcc, roleMapEntry);
|
|
|
|
}
|
2013-09-06 23:27:07 +04:00
|
|
|
return newAcc;
|
2001-06-30 04:25:09 +04:00
|
|
|
}
|
|
|
|
|
2010-06-08 20:39:58 +04:00
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
// nsAccessibilityService private
|
|
|
|
|
|
|
|
bool nsAccessibilityService::Init() {
|
|
|
|
// Initialize accessible document manager.
|
2012-11-20 18:15:32 +04:00
|
|
|
if (!DocManager::Init()) return false;
|
2010-06-08 20:39:58 +04:00
|
|
|
|
|
|
|
// Add observers.
|
|
|
|
nsCOMPtr<nsIObserverService> observerService =
|
|
|
|
mozilla::services::GetObserverService();
|
|
|
|
if (!observerService) return false;
|
|
|
|
|
2011-10-17 18:59:28 +04:00
|
|
|
observerService->AddObserver(this, NS_XPCOM_SHUTDOWN_OBSERVER_ID, false);
|
2010-06-08 20:39:58 +04:00
|
|
|
|
2017-09-09 00:05:06 +03:00
|
|
|
#if defined(XP_WIN)
|
|
|
|
// This information needs to be initialized before the observer fires.
|
|
|
|
if (XRE_IsParentProcess()) {
|
|
|
|
Compatibility::Init();
|
|
|
|
}
|
|
|
|
#endif // defined(XP_WIN)
|
|
|
|
|
2015-08-05 06:35:54 +03:00
|
|
|
// Subscribe to EventListenerService.
|
|
|
|
nsCOMPtr<nsIEventListenerService> eventListenerService =
|
|
|
|
do_GetService("@mozilla.org/eventlistenerservice;1");
|
|
|
|
if (!eventListenerService) return false;
|
|
|
|
|
|
|
|
eventListenerService->AddListenerChangeListener(this);
|
|
|
|
|
2018-02-05 17:26:59 +03:00
|
|
|
for (uint32_t i = 0; i < ArrayLength(sHTMLMarkupMapList); i++)
|
2018-04-03 04:20:13 +03:00
|
|
|
mHTMLMarkupMap.Put(sHTMLMarkupMapList[i].tag, &sHTMLMarkupMapList[i]);
|
2015-03-05 06:56:57 +03:00
|
|
|
|
2017-11-03 14:15:44 +03:00
|
|
|
#ifdef MOZ_XUL
|
2018-02-05 17:26:59 +03:00
|
|
|
for (uint32_t i = 0; i < ArrayLength(sXULMarkupMapList); i++)
|
2018-04-03 04:20:13 +03:00
|
|
|
mXULMarkupMap.Put(sXULMarkupMapList[i].tag, &sXULMarkupMapList[i]);
|
2017-11-03 14:15:44 +03:00
|
|
|
#endif
|
|
|
|
|
2012-10-04 13:57:09 +04:00
|
|
|
#ifdef A11Y_LOG
|
2012-05-23 13:21:40 +04:00
|
|
|
logging::CheckEnv();
|
|
|
|
#endif
|
|
|
|
|
2016-04-01 17:57:06 +03:00
|
|
|
gAccessibilityService = this;
|
2016-08-08 18:35:56 +03:00
|
|
|
NS_ADDREF(gAccessibilityService); // will release in Shutdown()
|
2016-04-01 17:57:06 +03:00
|
|
|
|
2016-10-27 21:40:50 +03:00
|
|
|
if (XRE_IsParentProcess()) {
|
2014-06-10 23:54:06 +04:00
|
|
|
gApplicationAccessible = new ApplicationAccessibleWrap();
|
2016-10-27 21:40:50 +03:00
|
|
|
} else {
|
|
|
|
#if defined(XP_WIN)
|
|
|
|
dom::ContentChild* contentChild = dom::ContentChild::GetSingleton();
|
|
|
|
MOZ_ASSERT(contentChild);
|
|
|
|
// If we were instantiated by the chrome process, GetMsaaID() will return
|
|
|
|
// a non-zero value and we may safely continue with initialization.
|
|
|
|
if (!contentChild->GetMsaaID()) {
|
|
|
|
// Since we were not instantiated by chrome, we need to synchronously
|
|
|
|
// obtain a MSAA content process id.
|
|
|
|
contentChild->SendGetA11yContentId();
|
|
|
|
}
|
|
|
|
|
2017-09-20 01:55:34 +03:00
|
|
|
gApplicationAccessible = new ApplicationAccessibleWrap();
|
|
|
|
#else
|
2014-06-10 23:54:06 +04:00
|
|
|
gApplicationAccessible = new ApplicationAccessible();
|
2017-09-20 01:55:34 +03:00
|
|
|
#endif // defined(XP_WIN)
|
2016-10-27 21:40:50 +03:00
|
|
|
}
|
2014-06-10 23:54:06 +04:00
|
|
|
|
2012-09-10 17:20:26 +04:00
|
|
|
NS_ADDREF(gApplicationAccessible); // will release in Shutdown()
|
2016-04-01 17:57:06 +03:00
|
|
|
gApplicationAccessible->Init();
|
2012-09-10 17:20:26 +04:00
|
|
|
|
Bug 1348273 - Convert crash annotations into a machine-readable list of constants; r=ted.mielczarek,njn,dholbert,mak,cpearce,mcmanus,froydnj,Dexter,jrmuizel,jchen,jimm,bz,surkov
This introduces the machinery needed to generate crash annotations from a YAML
file. The relevant C++ functions are updated to take a typed enum. JavaScript
calls are unaffected but they will throw if the string argument does not
correspond to one of the known entries in the C++ enum. The existing whitelists
and blacklists of annotations are also generated from the YAML file and all
duplicate code related to them has been consolidated. Once written out to the
.extra file the annotations are converted in string form and are no different
than the existing ones.
All existing annotations have been included in the list (and some obsolete ones
have been removed) and all call sites have been updated including tests where
appropriate.
--HG--
extra : source : 4f6c43f2830701ec5552e08e3f1b06fe6d045860
2018-07-05 16:42:11 +03:00
|
|
|
CrashReporter::AnnotateCrashReport(CrashReporter::Annotation::Accessibility,
|
2012-07-20 22:43:49 +04:00
|
|
|
NS_LITERAL_CSTRING("Active"));
|
|
|
|
|
2013-02-27 02:07:24 +04:00
|
|
|
#ifdef XP_WIN
|
|
|
|
sPendingPlugins = new nsTArray<nsCOMPtr<nsIContent> >;
|
|
|
|
sPluginTimers = new nsTArray<nsCOMPtr<nsITimer> >;
|
|
|
|
#endif
|
|
|
|
|
2012-12-02 04:58:25 +04:00
|
|
|
// Now its safe to start platform accessibility.
|
2015-07-04 04:29:00 +03:00
|
|
|
if (XRE_IsParentProcess()) PlatformInit();
|
2012-12-02 04:58:25 +04:00
|
|
|
|
2016-08-16 20:25:29 +03:00
|
|
|
statistics::A11yInitialized();
|
|
|
|
|
2018-01-16 05:59:19 +03:00
|
|
|
static const char16_t kInitIndicator[] = {'1', 0};
|
|
|
|
observerService->NotifyObservers(nullptr, "a11y-init-or-shutdown",
|
|
|
|
kInitIndicator);
|
|
|
|
|
2011-10-17 18:59:28 +04:00
|
|
|
return true;
|
2010-06-08 20:39:58 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
void nsAccessibilityService::Shutdown() {
|
2016-08-08 18:35:56 +03:00
|
|
|
// Application is going to be closed, shutdown accessibility and mark
|
|
|
|
// accessibility service as shutdown to prevent calls of its methods.
|
|
|
|
// Don't null accessibility service static member at this point to be safe
|
|
|
|
// if someone will try to operate with it.
|
|
|
|
|
2016-08-29 18:06:48 +03:00
|
|
|
MOZ_ASSERT(gConsumers, "Accessibility was shutdown already");
|
2017-11-08 07:07:24 +03:00
|
|
|
UnsetConsumers(eXPCOM | eMainProcess | ePlatformAPI);
|
2016-08-08 18:35:56 +03:00
|
|
|
|
2010-06-08 20:39:58 +04:00
|
|
|
// Remove observers.
|
|
|
|
nsCOMPtr<nsIObserverService> observerService =
|
|
|
|
mozilla::services::GetObserverService();
|
2012-05-07 13:14:27 +04:00
|
|
|
if (observerService) {
|
2010-06-08 20:39:58 +04:00
|
|
|
observerService->RemoveObserver(this, NS_XPCOM_SHUTDOWN_OBSERVER_ID);
|
2012-05-07 13:14:27 +04:00
|
|
|
}
|
|
|
|
|
2010-06-08 20:39:58 +04:00
|
|
|
// Stop accessible document loader.
|
2012-11-20 18:15:32 +04:00
|
|
|
DocManager::Shutdown();
|
2010-06-08 20:39:58 +04:00
|
|
|
|
2013-03-07 16:16:10 +04:00
|
|
|
SelectionManager::Shutdown();
|
|
|
|
|
2013-02-27 02:07:24 +04:00
|
|
|
#ifdef XP_WIN
|
|
|
|
sPendingPlugins = nullptr;
|
|
|
|
|
|
|
|
uint32_t timerCount = sPluginTimers->Length();
|
|
|
|
for (uint32_t i = 0; i < timerCount; i++)
|
|
|
|
sPluginTimers->ElementAt(i)->Cancel();
|
|
|
|
|
|
|
|
sPluginTimers = nullptr;
|
|
|
|
#endif
|
|
|
|
|
2015-07-04 04:29:00 +03:00
|
|
|
if (XRE_IsParentProcess()) PlatformShutdown();
|
2014-06-10 23:54:06 +04:00
|
|
|
|
2012-09-10 17:20:26 +04:00
|
|
|
gApplicationAccessible->Shutdown();
|
|
|
|
NS_RELEASE(gApplicationAccessible);
|
|
|
|
gApplicationAccessible = nullptr;
|
2014-10-22 04:49:28 +04:00
|
|
|
|
|
|
|
NS_IF_RELEASE(gXPCApplicationAccessible);
|
|
|
|
gXPCApplicationAccessible = nullptr;
|
2016-08-08 18:35:56 +03:00
|
|
|
|
|
|
|
NS_RELEASE(gAccessibilityService);
|
|
|
|
gAccessibilityService = nullptr;
|
2018-01-16 05:59:19 +03:00
|
|
|
|
|
|
|
if (observerService) {
|
|
|
|
static const char16_t kShutdownIndicator[] = {'0', 0};
|
|
|
|
observerService->NotifyObservers(nullptr, "a11y-init-or-shutdown",
|
|
|
|
kShutdownIndicator);
|
|
|
|
}
|
2010-06-08 20:39:58 +04:00
|
|
|
}
|
|
|
|
|
2012-09-29 01:53:44 +04:00
|
|
|
already_AddRefed<Accessible>
|
|
|
|
nsAccessibilityService::CreateAccessibleByFrameType(nsIFrame* aFrame,
|
|
|
|
nsIContent* aContent,
|
2012-11-30 11:33:01 +04:00
|
|
|
Accessible* aContext) {
|
|
|
|
DocAccessible* document = aContext->Document();
|
|
|
|
|
2015-10-18 08:24:48 +03:00
|
|
|
RefPtr<Accessible> newAcc;
|
2012-09-29 01:53:44 +04:00
|
|
|
switch (aFrame->AccessibleType()) {
|
2012-12-12 14:04:12 +04:00
|
|
|
case eNoType:
|
2012-09-29 01:53:44 +04:00
|
|
|
return nullptr;
|
2012-12-18 05:25:52 +04:00
|
|
|
case eHTMLBRType:
|
2012-11-30 11:33:01 +04:00
|
|
|
newAcc = new HTMLBRAccessible(aContent, document);
|
2012-09-29 01:53:44 +04:00
|
|
|
break;
|
2012-12-18 05:25:52 +04:00
|
|
|
case eHTMLButtonType:
|
2012-11-30 11:33:01 +04:00
|
|
|
newAcc = new HTMLButtonAccessible(aContent, document);
|
2012-09-29 01:53:44 +04:00
|
|
|
break;
|
2012-12-18 05:25:52 +04:00
|
|
|
case eHTMLCanvasType:
|
2012-11-30 11:33:01 +04:00
|
|
|
newAcc = new HTMLCanvasAccessible(aContent, document);
|
2012-09-29 01:53:44 +04:00
|
|
|
break;
|
2012-12-18 05:25:52 +04:00
|
|
|
case eHTMLCaptionType:
|
2012-12-18 09:22:26 +04:00
|
|
|
if (aContext->IsTable() &&
|
2012-11-30 11:33:01 +04:00
|
|
|
aContext->GetContent() == aContent->GetParent()) {
|
|
|
|
newAcc = new HTMLCaptionAccessible(aContent, document);
|
|
|
|
}
|
2012-09-29 01:53:44 +04:00
|
|
|
break;
|
2012-12-18 05:25:52 +04:00
|
|
|
case eHTMLCheckboxType:
|
2018-08-29 10:42:31 +03:00
|
|
|
newAcc = new CheckboxAccessible(aContent, document);
|
2012-09-29 01:53:44 +04:00
|
|
|
break;
|
2012-12-18 05:25:52 +04:00
|
|
|
case eHTMLComboboxType:
|
2012-11-30 11:33:01 +04:00
|
|
|
newAcc = new HTMLComboboxAccessible(aContent, document);
|
2012-09-29 01:53:44 +04:00
|
|
|
break;
|
2012-12-18 05:25:52 +04:00
|
|
|
case eHTMLFileInputType:
|
2012-11-30 11:33:01 +04:00
|
|
|
newAcc = new HTMLFileInputAccessible(aContent, document);
|
2012-09-29 01:53:44 +04:00
|
|
|
break;
|
2012-12-18 05:25:52 +04:00
|
|
|
case eHTMLGroupboxType:
|
2012-11-30 11:33:01 +04:00
|
|
|
newAcc = new HTMLGroupboxAccessible(aContent, document);
|
2012-09-29 01:53:44 +04:00
|
|
|
break;
|
2012-12-18 05:25:52 +04:00
|
|
|
case eHTMLHRType:
|
2012-11-30 11:33:01 +04:00
|
|
|
newAcc = new HTMLHRAccessible(aContent, document);
|
2012-09-29 01:53:44 +04:00
|
|
|
break;
|
2012-12-18 05:25:52 +04:00
|
|
|
case eHTMLImageMapType:
|
2012-11-30 11:33:01 +04:00
|
|
|
newAcc = new HTMLImageMapAccessible(aContent, document);
|
2012-09-29 01:53:44 +04:00
|
|
|
break;
|
2012-12-18 05:25:52 +04:00
|
|
|
case eHTMLLiType:
|
2012-12-18 09:22:26 +04:00
|
|
|
if (aContext->IsList() &&
|
2012-12-02 15:35:41 +04:00
|
|
|
aContext->GetContent() == aContent->GetParent()) {
|
|
|
|
newAcc = new HTMLLIAccessible(aContent, document);
|
2014-11-21 17:13:32 +03:00
|
|
|
} else {
|
|
|
|
// Otherwise create a generic text accessible to avoid text jamming.
|
|
|
|
newAcc = new HyperTextAccessibleWrap(aContent, document);
|
2012-12-02 15:35:41 +04:00
|
|
|
}
|
2012-09-29 01:53:44 +04:00
|
|
|
break;
|
2012-12-18 05:25:52 +04:00
|
|
|
case eHTMLSelectListType:
|
2012-11-30 11:33:01 +04:00
|
|
|
newAcc = new HTMLSelectListAccessible(aContent, document);
|
2012-09-29 01:53:44 +04:00
|
|
|
break;
|
2012-12-18 05:25:52 +04:00
|
|
|
case eHTMLMediaType:
|
2015-03-05 03:04:46 +03:00
|
|
|
newAcc = new EnumRoleAccessible<roles::GROUPING>(aContent, document);
|
2012-09-29 01:53:44 +04:00
|
|
|
break;
|
2012-12-18 05:25:52 +04:00
|
|
|
case eHTMLRadioButtonType:
|
2012-11-30 11:33:01 +04:00
|
|
|
newAcc = new HTMLRadioButtonAccessible(aContent, document);
|
2012-09-29 01:53:44 +04:00
|
|
|
break;
|
2013-04-28 04:54:54 +04:00
|
|
|
case eHTMLRangeType:
|
|
|
|
newAcc = new HTMLRangeAccessible(aContent, document);
|
|
|
|
break;
|
2013-12-11 07:19:26 +04:00
|
|
|
case eHTMLSpinnerType:
|
|
|
|
newAcc = new HTMLSpinnerAccessible(aContent, document);
|
|
|
|
break;
|
2012-12-18 05:25:52 +04:00
|
|
|
case eHTMLTableType:
|
2015-10-19 15:46:54 +03:00
|
|
|
if (aContent->IsHTMLElement(nsGkAtoms::table))
|
|
|
|
newAcc = new HTMLTableAccessibleWrap(aContent, document);
|
|
|
|
else
|
|
|
|
newAcc = new HyperTextAccessibleWrap(aContent, document);
|
2012-09-29 01:53:44 +04:00
|
|
|
break;
|
2012-12-18 05:25:52 +04:00
|
|
|
case eHTMLTableCellType:
|
2013-02-16 09:42:00 +04:00
|
|
|
// Accessible HTML table cell should be a child of accessible HTML table
|
|
|
|
// or its row (CSS HTML tables are polite to the used markup at
|
|
|
|
// certain degree).
|
2013-12-18 21:25:07 +04:00
|
|
|
// Otherwise create a generic text accessible to avoid text jamming
|
|
|
|
// when reading by AT.
|
2013-02-16 09:42:00 +04:00
|
|
|
if (aContext->IsHTMLTableRow() || aContext->IsHTMLTable())
|
2012-11-30 11:33:01 +04:00
|
|
|
newAcc = new HTMLTableCellAccessibleWrap(aContent, document);
|
2013-12-18 21:25:07 +04:00
|
|
|
else
|
|
|
|
newAcc = new HyperTextAccessibleWrap(aContent, document);
|
2012-09-29 01:53:44 +04:00
|
|
|
break;
|
2012-11-30 11:33:01 +04:00
|
|
|
|
2012-12-18 05:25:52 +04:00
|
|
|
case eHTMLTableRowType: {
|
2014-06-06 21:22:46 +04:00
|
|
|
// Accessible HTML table row may be a child of tbody/tfoot/thead of
|
|
|
|
// accessible HTML table or a direct child of accessible of HTML table.
|
2014-07-15 18:17:16 +04:00
|
|
|
Accessible* table = aContext->IsTable() ? aContext : nullptr;
|
|
|
|
if (!table && aContext->Parent() && aContext->Parent()->IsTable())
|
|
|
|
table = aContext->Parent();
|
2014-06-06 21:22:46 +04:00
|
|
|
|
|
|
|
if (table) {
|
2019-04-19 01:52:06 +03:00
|
|
|
nsIContent* parentContent =
|
|
|
|
aContent->GetParentOrHostNode()->AsContent();
|
|
|
|
nsIFrame* parentFrame = nullptr;
|
|
|
|
if (parentContent) {
|
2012-11-30 11:33:01 +04:00
|
|
|
parentFrame = parentContent->GetPrimaryFrame();
|
2019-04-19 01:52:06 +03:00
|
|
|
if (!parentFrame || !parentFrame->IsTableWrapperFrame()) {
|
|
|
|
parentContent = parentContent->GetParentOrHostNode()->AsContent();
|
|
|
|
if (parentContent) {
|
|
|
|
parentFrame = parentContent->GetPrimaryFrame();
|
|
|
|
}
|
|
|
|
}
|
2012-11-30 11:33:01 +04:00
|
|
|
}
|
|
|
|
|
2019-04-19 01:52:06 +03:00
|
|
|
if (parentFrame && parentFrame->IsTableWrapperFrame() &&
|
2014-06-06 21:22:46 +04:00
|
|
|
table->GetContent() == parentContent) {
|
2012-11-30 11:33:01 +04:00
|
|
|
newAcc = new HTMLTableRowAccessible(aContent, document);
|
|
|
|
}
|
|
|
|
}
|
2012-09-29 01:53:44 +04:00
|
|
|
break;
|
2012-11-30 11:33:01 +04:00
|
|
|
}
|
2012-12-18 05:25:52 +04:00
|
|
|
case eHTMLTextFieldType:
|
2012-11-30 11:33:01 +04:00
|
|
|
newAcc = new HTMLTextFieldAccessible(aContent, document);
|
2012-09-29 01:53:44 +04:00
|
|
|
break;
|
2012-12-18 05:25:52 +04:00
|
|
|
case eHyperTextType:
|
2019-01-29 07:17:20 +03:00
|
|
|
if (!aContent->IsAnyOfHTMLElements(nsGkAtoms::dt, nsGkAtoms::dd,
|
|
|
|
nsGkAtoms::div)) {
|
2012-12-02 15:35:41 +04:00
|
|
|
newAcc = new HyperTextAccessibleWrap(aContent, document);
|
2019-01-29 07:17:20 +03:00
|
|
|
}
|
2012-09-29 01:53:44 +04:00
|
|
|
break;
|
2012-12-02 15:35:41 +04:00
|
|
|
|
2012-12-18 05:25:52 +04:00
|
|
|
case eImageType:
|
2012-11-30 11:33:01 +04:00
|
|
|
newAcc = new ImageAccessibleWrap(aContent, document);
|
2012-09-29 01:53:44 +04:00
|
|
|
break;
|
2012-12-18 05:25:52 +04:00
|
|
|
case eOuterDocType:
|
2012-11-30 11:33:01 +04:00
|
|
|
newAcc = new OuterDocAccessible(aContent, document);
|
2012-09-29 01:53:44 +04:00
|
|
|
break;
|
2012-12-18 09:22:26 +04:00
|
|
|
case ePluginType: {
|
2014-09-24 08:35:00 +04:00
|
|
|
nsPluginFrame* pluginFrame = do_QueryFrame(aFrame);
|
|
|
|
newAcc = CreatePluginAccessible(pluginFrame, aContent, aContext);
|
2012-12-12 14:04:12 +04:00
|
|
|
break;
|
|
|
|
}
|
2012-12-18 05:25:52 +04:00
|
|
|
case eTextLeafType:
|
2012-11-30 11:33:01 +04:00
|
|
|
newAcc = new TextLeafAccessibleWrap(aContent, document);
|
2012-09-29 01:53:44 +04:00
|
|
|
break;
|
2013-01-02 04:49:19 +04:00
|
|
|
default:
|
|
|
|
MOZ_ASSERT(false);
|
|
|
|
break;
|
2012-09-29 01:53:44 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
return newAcc.forget();
|
|
|
|
}
|
|
|
|
|
2015-03-08 04:20:17 +03:00
|
|
|
void nsAccessibilityService::MarkupAttributes(
|
|
|
|
const nsIContent* aContent, nsIPersistentProperties* aAttributes) const {
|
2018-02-05 17:26:59 +03:00
|
|
|
const mozilla::a11y::HTMLMarkupMapInfo* markupMap =
|
|
|
|
mHTMLMarkupMap.Get(aContent->NodeInfo()->NameAtom());
|
2015-03-08 04:20:17 +03:00
|
|
|
if (!markupMap) return;
|
|
|
|
|
|
|
|
for (uint32_t i = 0; i < ArrayLength(markupMap->attrs); i++) {
|
|
|
|
const MarkupAttrInfo* info = markupMap->attrs + i;
|
|
|
|
if (!info->name) break;
|
|
|
|
|
|
|
|
if (info->DOMAttrName) {
|
|
|
|
if (info->DOMAttrValue) {
|
2017-12-07 21:13:50 +03:00
|
|
|
if (aContent->IsElement() && aContent->AsElement()->AttrValueIs(
|
2018-04-03 04:20:13 +03:00
|
|
|
kNameSpaceID_None, info->DOMAttrName,
|
|
|
|
info->DOMAttrValue, eCaseMatters)) {
|
|
|
|
nsAccUtils::SetAccAttr(aAttributes, info->name, info->DOMAttrValue);
|
2015-03-08 04:20:17 +03:00
|
|
|
}
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
nsAutoString value;
|
2017-12-07 21:13:50 +03:00
|
|
|
|
|
|
|
if (aContent->IsElement()) {
|
2018-04-03 04:20:13 +03:00
|
|
|
aContent->AsElement()->GetAttr(kNameSpaceID_None, info->DOMAttrName,
|
|
|
|
value);
|
2017-12-07 21:13:50 +03:00
|
|
|
}
|
|
|
|
|
2015-03-08 04:20:17 +03:00
|
|
|
if (!value.IsEmpty())
|
2018-04-03 04:20:13 +03:00
|
|
|
nsAccUtils::SetAccAttr(aAttributes, info->name, value);
|
2015-03-08 04:20:17 +03:00
|
|
|
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2018-04-03 04:20:13 +03:00
|
|
|
nsAccUtils::SetAccAttr(aAttributes, info->name, info->value);
|
2015-03-08 04:20:17 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-06-25 13:50:23 +04:00
|
|
|
Accessible* nsAccessibilityService::AddNativeRootAccessible(
|
|
|
|
void* aAtkAccessible) {
|
2006-08-30 09:19:06 +04:00
|
|
|
#ifdef MOZ_ACCESSIBILITY_ATK
|
2012-09-10 17:20:26 +04:00
|
|
|
ApplicationAccessible* applicationAcc = ApplicationAcc();
|
2010-06-25 13:50:23 +04:00
|
|
|
if (!applicationAcc) return nullptr;
|
2007-06-02 07:01:38 +04:00
|
|
|
|
2012-10-13 10:34:21 +04:00
|
|
|
GtkWindowAccessible* nativeWnd =
|
|
|
|
new GtkWindowAccessible(static_cast<AtkObject*>(aAtkAccessible));
|
2006-08-30 09:19:06 +04:00
|
|
|
|
2012-10-13 10:34:21 +04:00
|
|
|
if (applicationAcc->AppendChild(nativeWnd)) return nativeWnd;
|
2006-08-30 09:19:06 +04:00
|
|
|
#endif
|
|
|
|
|
2012-07-30 18:20:58 +04:00
|
|
|
return nullptr;
|
2012-05-04 10:09:22 +04:00
|
|
|
}
|
2010-06-25 13:50:23 +04:00
|
|
|
|
2012-05-29 05:18:45 +04:00
|
|
|
void nsAccessibilityService::RemoveNativeRootAccessible(
|
|
|
|
Accessible* aAccessible) {
|
2006-08-30 09:19:06 +04:00
|
|
|
#ifdef MOZ_ACCESSIBILITY_ATK
|
2012-09-10 17:20:26 +04:00
|
|
|
ApplicationAccessible* applicationAcc = ApplicationAcc();
|
2007-06-02 07:01:38 +04:00
|
|
|
|
2010-06-25 13:50:23 +04:00
|
|
|
if (applicationAcc) applicationAcc->RemoveChild(aAccessible);
|
2006-08-30 09:19:06 +04:00
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
2018-05-30 05:58:47 +03:00
|
|
|
bool nsAccessibilityService::HasAccessible(nsINode* aDOMNode) {
|
|
|
|
if (!aDOMNode) return false;
|
2014-10-22 04:49:28 +04:00
|
|
|
|
2018-05-30 05:58:47 +03:00
|
|
|
DocAccessible* document = GetDocAccessible(aDOMNode->OwnerDoc());
|
2014-10-22 04:49:28 +04:00
|
|
|
if (!document) return false;
|
|
|
|
|
2018-05-30 05:58:47 +03:00
|
|
|
return document->HasAccessible(aDOMNode);
|
2014-10-22 04:49:28 +04:00
|
|
|
}
|
|
|
|
|
2010-02-21 03:56:35 +03:00
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
// nsAccessibilityService private (DON'T put methods here)
|
|
|
|
|
2018-03-08 20:22:22 +03:00
|
|
|
void nsAccessibilityService::SetConsumers(uint32_t aConsumers, bool aNotify) {
|
2017-11-08 07:07:24 +03:00
|
|
|
if (gConsumers & aConsumers) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
gConsumers |= aConsumers;
|
2018-03-08 20:22:22 +03:00
|
|
|
if (aNotify) {
|
|
|
|
NotifyOfConsumersChange();
|
|
|
|
}
|
2017-11-08 07:07:24 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
void nsAccessibilityService::UnsetConsumers(uint32_t aConsumers) {
|
|
|
|
if (!(gConsumers & aConsumers)) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
gConsumers &= ~aConsumers;
|
|
|
|
NotifyOfConsumersChange();
|
|
|
|
}
|
|
|
|
|
2017-11-14 00:36:37 +03:00
|
|
|
void nsAccessibilityService::GetConsumers(nsAString& aString) {
|
|
|
|
const char16_t* kJSONFmt =
|
|
|
|
u"{ \"XPCOM\": %s, \"MainProcess\": %s, \"PlatformAPI\": %s }";
|
|
|
|
nsString json;
|
|
|
|
nsTextFormatter::ssprintf(json, kJSONFmt,
|
|
|
|
gConsumers & eXPCOM ? "true" : "false",
|
|
|
|
gConsumers & eMainProcess ? "true" : "false",
|
|
|
|
gConsumers & ePlatformAPI ? "true" : "false");
|
|
|
|
aString.Assign(json);
|
|
|
|
}
|
|
|
|
|
2017-11-08 07:07:24 +03:00
|
|
|
void nsAccessibilityService::NotifyOfConsumersChange() {
|
|
|
|
nsCOMPtr<nsIObserverService> observerService =
|
|
|
|
mozilla::services::GetObserverService();
|
|
|
|
|
|
|
|
if (!observerService) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2017-11-14 00:36:37 +03:00
|
|
|
nsAutoString consumers;
|
|
|
|
GetConsumers(consumers);
|
|
|
|
observerService->NotifyObservers(nullptr, "a11y-consumers-changed",
|
|
|
|
consumers.get());
|
2017-11-08 07:07:24 +03:00
|
|
|
}
|
|
|
|
|
2016-08-29 18:06:48 +03:00
|
|
|
nsAccessibilityService* GetOrCreateAccService(uint32_t aNewConsumer) {
|
2017-11-29 00:02:04 +03:00
|
|
|
// Do not initialize accessibility if it is force disabled.
|
|
|
|
if (PlatformDisabledState() == ePlatformIsDisabled) {
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
|
2016-08-08 18:35:56 +03:00
|
|
|
if (!nsAccessibilityService::gAccessibilityService) {
|
|
|
|
RefPtr<nsAccessibilityService> service = new nsAccessibilityService();
|
|
|
|
if (!service->Init()) {
|
|
|
|
service->Shutdown();
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
MOZ_ASSERT(nsAccessibilityService::gAccessibilityService,
|
|
|
|
"Accessible service is not initialized.");
|
2017-11-08 07:07:24 +03:00
|
|
|
nsAccessibilityService::gAccessibilityService->SetConsumers(aNewConsumer);
|
2016-08-08 18:35:56 +03:00
|
|
|
return nsAccessibilityService::gAccessibilityService;
|
|
|
|
}
|
|
|
|
|
2016-08-29 18:06:48 +03:00
|
|
|
void MaybeShutdownAccService(uint32_t aFormerConsumer) {
|
|
|
|
nsAccessibilityService* accService =
|
|
|
|
nsAccessibilityService::gAccessibilityService;
|
|
|
|
|
2018-03-16 16:29:15 +03:00
|
|
|
if (!accService || nsAccessibilityService::IsShutdown()) {
|
2016-08-29 18:06:48 +03:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2018-03-08 20:22:22 +03:00
|
|
|
// Still used by XPCOM
|
2016-08-29 18:06:48 +03:00
|
|
|
if (nsCoreUtils::AccEventObserversExist() ||
|
2016-11-19 07:29:10 +03:00
|
|
|
xpcAccessibilityService::IsInUse() || accService->HasXPCDocuments()) {
|
2018-03-08 20:22:22 +03:00
|
|
|
// In case the XPCOM flag was unset (possibly because of the shutdown
|
|
|
|
// timer in the xpcAccessibilityService) ensure it is still present. Note:
|
|
|
|
// this should be fixed when all the consumer logic is taken out as a
|
|
|
|
// separate class.
|
|
|
|
accService->SetConsumers(nsAccessibilityService::eXPCOM, false);
|
|
|
|
|
2017-11-08 07:07:24 +03:00
|
|
|
if (aFormerConsumer != nsAccessibilityService::eXPCOM) {
|
|
|
|
// Only unset non-XPCOM consumers.
|
|
|
|
accService->UnsetConsumers(aFormerConsumer);
|
|
|
|
}
|
2016-08-29 18:06:48 +03:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (nsAccessibilityService::gConsumers & ~aFormerConsumer) {
|
2017-11-08 07:07:24 +03:00
|
|
|
accService->UnsetConsumers(aFormerConsumer);
|
2016-08-29 18:06:48 +03:00
|
|
|
} else {
|
|
|
|
accService
|
|
|
|
->Shutdown(); // Will unset all nsAccessibilityService::gConsumers
|
2016-08-08 18:35:56 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-09-28 05:46:11 +04:00
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
// Services
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
2012-06-20 03:19:13 +04:00
|
|
|
namespace mozilla {
|
|
|
|
namespace a11y {
|
|
|
|
|
|
|
|
FocusManager* FocusMgr() {
|
2011-09-28 05:46:11 +04:00
|
|
|
return nsAccessibilityService::gAccessibilityService;
|
|
|
|
}
|
2012-06-20 03:19:13 +04:00
|
|
|
|
2013-03-07 16:16:10 +04:00
|
|
|
SelectionManager* SelectionMgr() {
|
|
|
|
return nsAccessibilityService::gAccessibilityService;
|
|
|
|
}
|
|
|
|
|
2012-09-10 17:20:26 +04:00
|
|
|
ApplicationAccessible* ApplicationAcc() {
|
|
|
|
return nsAccessibilityService::gApplicationAccessible;
|
|
|
|
}
|
|
|
|
|
2014-10-22 04:49:28 +04:00
|
|
|
xpcAccessibleApplication* XPCApplicationAcc() {
|
|
|
|
if (!nsAccessibilityService::gXPCApplicationAccessible &&
|
|
|
|
nsAccessibilityService::gApplicationAccessible) {
|
|
|
|
nsAccessibilityService::gXPCApplicationAccessible =
|
|
|
|
new xpcAccessibleApplication(
|
|
|
|
nsAccessibilityService::gApplicationAccessible);
|
|
|
|
NS_ADDREF(nsAccessibilityService::gXPCApplicationAccessible);
|
|
|
|
}
|
|
|
|
|
|
|
|
return nsAccessibilityService::gXPCApplicationAccessible;
|
|
|
|
}
|
|
|
|
|
2012-06-20 03:19:13 +04:00
|
|
|
EPlatformDisabledState PlatformDisabledState() {
|
2017-09-25 20:02:57 +03:00
|
|
|
static bool platformDisabledStateCached = false;
|
|
|
|
if (platformDisabledStateCached) {
|
|
|
|
return static_cast<EPlatformDisabledState>(sPlatformDisabledState);
|
|
|
|
}
|
|
|
|
|
|
|
|
platformDisabledStateCached = true;
|
|
|
|
Preferences::RegisterCallback(PrefChanged, PREF_ACCESSIBILITY_FORCE_DISABLED);
|
|
|
|
return ReadPlatformDisabledState();
|
|
|
|
}
|
2012-06-20 03:19:13 +04:00
|
|
|
|
2017-09-25 20:02:57 +03:00
|
|
|
EPlatformDisabledState ReadPlatformDisabledState() {
|
|
|
|
sPlatformDisabledState =
|
|
|
|
Preferences::GetInt(PREF_ACCESSIBILITY_FORCE_DISABLED, 0);
|
|
|
|
if (sPlatformDisabledState < ePlatformIsForceEnabled) {
|
|
|
|
sPlatformDisabledState = ePlatformIsForceEnabled;
|
|
|
|
} else if (sPlatformDisabledState > ePlatformIsDisabled) {
|
|
|
|
sPlatformDisabledState = ePlatformIsDisabled;
|
2012-06-20 03:19:13 +04:00
|
|
|
}
|
|
|
|
|
2017-09-25 20:02:57 +03:00
|
|
|
return static_cast<EPlatformDisabledState>(sPlatformDisabledState);
|
|
|
|
}
|
|
|
|
|
|
|
|
void PrefChanged(const char* aPref, void* aClosure) {
|
|
|
|
if (ReadPlatformDisabledState() == ePlatformIsDisabled) {
|
|
|
|
// Force shut down accessibility.
|
|
|
|
nsAccessibilityService* accService =
|
|
|
|
nsAccessibilityService::gAccessibilityService;
|
2018-03-16 16:29:15 +03:00
|
|
|
if (accService && !nsAccessibilityService::IsShutdown()) {
|
2017-09-25 20:02:57 +03:00
|
|
|
accService->Shutdown();
|
|
|
|
}
|
|
|
|
}
|
2012-06-20 03:19:13 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
} // namespace a11y
|
|
|
|
} // namespace mozilla
|