summaryrefslogtreecommitdiff
path: root/accessible/xpcom
diff options
context:
space:
mode:
Diffstat (limited to 'accessible/xpcom')
-rwxr-xr-xaccessible/xpcom/AccEventGen.py228
-rw-r--r--accessible/xpcom/AccEvents.conf18
-rw-r--r--accessible/xpcom/moz.build66
-rw-r--r--accessible/xpcom/nsAccessibleRelation.cpp79
-rw-r--r--accessible/xpcom/nsAccessibleRelation.h50
-rw-r--r--accessible/xpcom/xpcAccessibilityService.cpp246
-rw-r--r--accessible/xpcom/xpcAccessibilityService.h66
-rw-r--r--accessible/xpcom/xpcAccessible.cpp826
-rw-r--r--accessible/xpcom/xpcAccessible.h106
-rw-r--r--accessible/xpcom/xpcAccessibleApplication.cpp69
-rw-r--r--accessible/xpcom/xpcAccessibleApplication.h48
-rw-r--r--accessible/xpcom/xpcAccessibleDocument.cpp262
-rw-r--r--accessible/xpcom/xpcAccessibleDocument.h150
-rw-r--r--accessible/xpcom/xpcAccessibleGeneric.cpp46
-rw-r--r--accessible/xpcom/xpcAccessibleGeneric.h110
-rw-r--r--accessible/xpcom/xpcAccessibleHyperLink.cpp180
-rw-r--r--accessible/xpcom/xpcAccessibleHyperLink.h48
-rw-r--r--accessible/xpcom/xpcAccessibleHyperText.cpp822
-rw-r--r--accessible/xpcom/xpcAccessibleHyperText.h62
-rw-r--r--accessible/xpcom/xpcAccessibleImage.cpp55
-rw-r--r--accessible/xpcom/xpcAccessibleImage.h47
-rw-r--r--accessible/xpcom/xpcAccessibleSelectable.cpp134
-rw-r--r--accessible/xpcom/xpcAccessibleSelectable.h54
-rw-r--r--accessible/xpcom/xpcAccessibleTable.cpp493
-rw-r--r--accessible/xpcom/xpcAccessibleTable.h96
-rw-r--r--accessible/xpcom/xpcAccessibleTableCell.cpp161
-rw-r--r--accessible/xpcom/xpcAccessibleTableCell.h62
-rw-r--r--accessible/xpcom/xpcAccessibleTextRange.cpp221
-rw-r--r--accessible/xpcom/xpcAccessibleTextRange.h85
-rw-r--r--accessible/xpcom/xpcAccessibleValue.cpp133
-rw-r--r--accessible/xpcom/xpcAccessibleValue.h43
31 files changed, 5066 insertions, 0 deletions
diff --git a/accessible/xpcom/AccEventGen.py b/accessible/xpcom/AccEventGen.py
new file mode 100755
index 0000000000..6af54c34db
--- /dev/null
+++ b/accessible/xpcom/AccEventGen.py
@@ -0,0 +1,228 @@
+#!/usr/bin/env python
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+import sys
+import os
+
+import buildconfig
+import mozpack.path as mozpath
+
+# The xpidl parser is not incorporated in the in-tree virtualenv.
+xpidl_dir = mozpath.join(buildconfig.topsrcdir, 'xpcom', 'idl-parser',
+ 'xpidl')
+xpidl_cachedir = mozpath.join(buildconfig.topobjdir, 'xpcom', 'idl-parser',
+ 'xpidl')
+sys.path.extend([xpidl_dir, xpidl_cachedir])
+import xpidl
+
+# Instantiate the parser.
+p = xpidl.IDLParser()
+
+def findIDL(includePath, interfaceFileName):
+ for d in includePath:
+ path = mozpath.join(d, interfaceFileName)
+ if os.path.exists(path):
+ return path
+ raise BaseException("No IDL file found for interface %s "
+ "in include path %r"
+ % (interfaceFileName, includePath))
+
+def loadEventIDL(parser, includePath, eventname):
+ eventidl = ("nsIAccessible%s.idl" % eventname)
+ idlFile = findIDL(includePath, eventidl)
+ idl = p.parse(open(idlFile).read(), idlFile)
+ idl.resolve(includePath, p)
+ return idl, idlFile
+
+class Configuration:
+ def __init__(self, filename):
+ config = {}
+ execfile(filename, config)
+ self.simple_events = config.get('simple_events', [])
+
+def firstCap(str):
+ return str[0].upper() + str[1:]
+
+def writeAttributeParams(a):
+ return ("%s a%s" % (a.realtype.nativeType('in'), firstCap(a.name)))
+
+def print_header_file(fd, conf, incdirs):
+ idl_paths = set()
+
+ fd.write("/* THIS FILE IS AUTOGENERATED - DO NOT EDIT */\n")
+ fd.write("#ifndef _mozilla_a11y_generated_AccEvents_h_\n"
+ "#define _mozilla_a11y_generated_AccEvents_h_\n\n")
+ fd.write("#include \"nscore.h\"\n")
+ fd.write("#include \"nsCOMPtr.h\"\n")
+ fd.write("#include \"nsCycleCollectionParticipant.h\"\n")
+ fd.write("#include \"nsString.h\"\n")
+ for e in conf.simple_events:
+ fd.write("#include \"nsIAccessible%s.h\"\n" % e)
+ for e in conf.simple_events:
+ idl, idl_path = loadEventIDL(p, incdirs, e)
+ idl_paths.add(idl_path)
+ for iface in filter(lambda p: p.kind == "interface", idl.productions):
+ classname = ("xpcAcc%s" % e)
+ baseinterfaces = interfaces(iface)
+
+ fd.write("\nclass %s final : public %s\n" % (classname, iface.name))
+ fd.write("{\n")
+ fd.write("public:\n")
+
+ attributes = allAttributes(iface)
+ args = map(writeAttributeParams, attributes)
+ fd.write(" %s(%s) :\n" % (classname, ", ".join(args)))
+
+ initializers = []
+ for a in attributes:
+ initializers.append("m%s(a%s)" % (firstCap(a.name), firstCap(a.name)))
+ fd.write(" %s\n {}\n\n" % ", ".join(initializers))
+ fd.write(" NS_DECL_CYCLE_COLLECTING_ISUPPORTS\n")
+ fd.write(" NS_DECL_CYCLE_COLLECTION_CLASS(%s)\n" % (classname))
+
+ for iface in filter(lambda i: i.name != "nsISupports", baseinterfaces):
+ fd.write(" NS_DECL_%s\n" % iface.name.upper())
+
+ fd.write("\nprivate:\n")
+ fd.write(" ~%s() {}\n\n" % classname)
+ for a in attributes:
+ fd.write(" %s\n" % attributeVariableTypeAndName(a))
+ fd.write("};\n\n")
+
+ fd.write("#endif\n")
+
+ return idl_paths
+
+def interfaceAttributeTypes(idl):
+ ifaces = filter(lambda p: p.kind == "interface", idl.productions)
+ attributes = []
+ for i in ifaces:
+ ifaceAttributes = allAttributes(i)
+ attributes.extend(ifaceAttributes)
+ ifaceAttrs = filter(lambda a: a.realtype.nativeType("in").endswith("*"), attributes)
+ return map(lambda a: a.realtype.nativeType("in").strip(" *"), ifaceAttrs)
+
+def print_cpp(idl, fd, conf, eventname):
+ for p in idl.productions:
+ if p.kind == 'interface':
+ write_cpp(eventname, p, fd)
+
+def print_cpp_file(fd, conf, incdirs):
+ idl_paths = set()
+ fd.write("/* THIS FILE IS AUTOGENERATED - DO NOT EDIT */\n\n")
+ fd.write('#include "xpcAccEvents.h"\n')
+
+ includes = []
+ for e in conf.simple_events:
+ if not e in includes:
+ includes.append(("nsIAccessible%s" % e))
+
+ types = []
+ for e in conf.simple_events:
+ idl, idl_path = loadEventIDL(p, incdirs, e)
+ idl_paths.add(idl_path)
+ types.extend(interfaceAttributeTypes(idl))
+
+ for c in types:
+ fd.write("#include \"%s.h\"\n" % c)
+
+ fd.write("\n")
+ for e in conf.simple_events:
+ idl, idl_path = loadEventIDL(p, incdirs, e)
+ idl_paths.add(idl_path)
+ print_cpp(idl, fd, conf, e)
+
+ return idl_paths
+
+def attributeVariableTypeAndName(a):
+ if a.realtype.nativeType('in').endswith('*'):
+ l = ["nsCOMPtr<%s> m%s;" % (a.realtype.nativeType('in').strip('* '),
+ firstCap(a.name))]
+ elif a.realtype.nativeType('in').count("nsAString"):
+ l = ["nsString m%s;" % firstCap(a.name)]
+ elif a.realtype.nativeType('in').count("nsACString"):
+ l = ["nsCString m%s;" % firstCap(a.name)]
+ else:
+ l = ["%sm%s;" % (a.realtype.nativeType('in'),
+ firstCap(a.name))]
+ return ", ".join(l)
+
+def writeAttributeGetter(fd, classname, a):
+ fd.write("NS_IMETHODIMP\n")
+ fd.write("%s::Get%s(" % (classname, firstCap(a.name)))
+ if a.realtype.nativeType('in').endswith('*'):
+ fd.write("%s** a%s" % (a.realtype.nativeType('in').strip('* '), firstCap(a.name)))
+ elif a.realtype.nativeType('in').count("nsAString"):
+ fd.write("nsAString& a%s" % firstCap(a.name))
+ elif a.realtype.nativeType('in').count("nsACString"):
+ fd.write("nsACString& a%s" % firstCap(a.name))
+ else:
+ fd.write("%s*a%s" % (a.realtype.nativeType('in'), firstCap(a.name)))
+ fd.write(")\n");
+ fd.write("{\n");
+ if a.realtype.nativeType('in').endswith('*'):
+ fd.write(" NS_IF_ADDREF(*a%s = m%s);\n" % (firstCap(a.name), firstCap(a.name)))
+ elif a.realtype.nativeType('in').count("nsAString"):
+ fd.write(" a%s = m%s;\n" % (firstCap(a.name), firstCap(a.name)))
+ elif a.realtype.nativeType('in').count("nsACString"):
+ fd.write(" a%s = m%s;\n" % (firstCap(a.name), firstCap(a.name)))
+ else:
+ fd.write(" *a%s = m%s;\n" % (firstCap(a.name), firstCap(a.name)))
+ fd.write(" return NS_OK;\n");
+ fd.write("}\n\n");
+
+def interfaces(iface):
+ interfaces = []
+ while iface.base:
+ interfaces.append(iface)
+ iface = iface.idl.getName(iface.base, iface.location)
+ interfaces.append(iface)
+ interfaces.reverse()
+ return interfaces
+
+def allAttributes(iface):
+ attributes = []
+ for i in interfaces(iface):
+ attrs = filter(lambda m: isinstance(m, xpidl.Attribute), i.members)
+ attributes.extend(attrs)
+
+ return attributes
+
+def write_cpp(eventname, iface, fd):
+ classname = "xpcAcc%s" % eventname
+ attributes = allAttributes(iface)
+ ccattributes = filter(lambda m: m.realtype.nativeType('in').endswith('*'), attributes)
+ fd.write("NS_IMPL_CYCLE_COLLECTION(%s" % classname)
+ for c in ccattributes:
+ fd.write(", m%s" % firstCap(c.name))
+ fd.write(")\n\n");
+
+ fd.write("NS_IMPL_CYCLE_COLLECTING_ADDREF(%s)\n" % classname)
+ fd.write("NS_IMPL_CYCLE_COLLECTING_RELEASE(%s)\n\n" % classname)
+
+ fd.write("NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(%s)\n" % classname)
+ for baseiface in interfaces(iface):
+ fd.write(" NS_INTERFACE_MAP_ENTRY(%s)\n" % baseiface.name)
+ fd.write("NS_INTERFACE_MAP_END\n\n")
+
+ for a in attributes:
+ writeAttributeGetter(fd, classname, a)
+
+def get_conf(conf_file):
+ conf = Configuration(conf_file)
+ inc_dir = [
+ mozpath.join(buildconfig.topsrcdir, 'accessible', 'interfaces'),
+ mozpath.join(buildconfig.topsrcdir, 'xpcom', 'base'),
+ ]
+ return conf, inc_dir
+
+def gen_files(fd, conf_file, xpidllex, xpidlyacc):
+ deps = set()
+ conf, inc_dir = get_conf(conf_file)
+ deps.update(print_header_file(fd, conf, inc_dir))
+ with open('xpcAccEvents.cpp', 'w') as cpp_fd:
+ deps.update(print_cpp_file(cpp_fd, conf, inc_dir))
+ return deps
diff --git a/accessible/xpcom/AccEvents.conf b/accessible/xpcom/AccEvents.conf
new file mode 100644
index 0000000000..0824bb78a0
--- /dev/null
+++ b/accessible/xpcom/AccEvents.conf
@@ -0,0 +1,18 @@
+""" -*- Mode: Python -*-
+ 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/.
+
+ The name of the event which real interface should have nsIAccessible-prefix,
+ and should be in nsIAccessible<name>.idl file"""
+
+simple_events = [
+ 'Event',
+ 'StateChangeEvent',
+ 'TextChangeEvent',
+ 'HideEvent',
+ 'CaretMoveEvent',
+ 'ObjectAttributeChangedEvent',
+ 'TableChangeEvent',
+ 'VirtualCursorChangeEvent'
+ ]
diff --git a/accessible/xpcom/moz.build b/accessible/xpcom/moz.build
new file mode 100644
index 0000000000..ec54a197a4
--- /dev/null
+++ b/accessible/xpcom/moz.build
@@ -0,0 +1,66 @@
+# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
+# vim: set filetype=python:
+# 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/.
+
+UNIFIED_SOURCES += [
+ 'nsAccessibleRelation.cpp',
+ 'xpcAccessibilityService.cpp',
+ 'xpcAccessible.cpp',
+ 'xpcAccessibleApplication.cpp',
+ 'xpcAccessibleDocument.cpp',
+ 'xpcAccessibleGeneric.cpp',
+ 'xpcAccessibleHyperLink.cpp',
+ 'xpcAccessibleHyperText.cpp',
+ 'xpcAccessibleImage.cpp',
+ 'xpcAccessibleSelectable.cpp',
+ 'xpcAccessibleTable.cpp',
+ 'xpcAccessibleTableCell.cpp',
+ 'xpcAccessibleTextRange.cpp',
+ 'xpcAccessibleValue.cpp',
+]
+
+SOURCES += [
+ '!xpcAccEvents.cpp',
+]
+
+EXPORTS += [
+ '!xpcAccEvents.h',
+ 'xpcAccessibilityService.h',
+]
+
+LOCAL_INCLUDES += [
+ '/accessible/base',
+ '/accessible/generic',
+]
+
+if 'gtk' in CONFIG['MOZ_WIDGET_TOOLKIT']:
+ LOCAL_INCLUDES += [
+ '/accessible/atk',
+ ]
+elif CONFIG['MOZ_WIDGET_TOOLKIT'] == 'windows':
+ LOCAL_INCLUDES += [
+ '/accessible/windows/msaa',
+ ]
+elif CONFIG['MOZ_WIDGET_TOOLKIT'] == 'cocoa':
+ LOCAL_INCLUDES += [
+ '/accessible/mac',
+ ]
+else:
+ LOCAL_INCLUDES += [
+ '/accessible/other',
+ ]
+
+GENERATED_FILES += [('xpcAccEvents.h', 'xpcAccEvents.cpp')]
+
+xpc_acc = GENERATED_FILES[('xpcAccEvents.h', 'xpcAccEvents.cpp')]
+xpc_acc.script = 'AccEventGen.py:gen_files'
+xpc_acc.inputs += ['AccEvents.conf', '!/xpcom/idl-parser/xpidl/xpidllex.py', '!/xpcom/idl-parser/xpidl/xpidlyacc.py']
+
+FINAL_LIBRARY = 'xul'
+
+include('/ipc/chromium/chromium-config.mozbuild')
+
+if CONFIG['GNU_CXX']:
+ CXXFLAGS += ['-Wno-error=shadow']
diff --git a/accessible/xpcom/nsAccessibleRelation.cpp b/accessible/xpcom/nsAccessibleRelation.cpp
new file mode 100644
index 0000000000..c22cb22020
--- /dev/null
+++ b/accessible/xpcom/nsAccessibleRelation.cpp
@@ -0,0 +1,79 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "nsAccessibleRelation.h"
+
+#include "Relation.h"
+#include "Accessible.h"
+#include "xpcAccessibleDocument.h"
+
+#include "nsArrayUtils.h"
+#include "nsComponentManagerUtils.h"
+
+using namespace mozilla::a11y;
+
+nsAccessibleRelation::nsAccessibleRelation(uint32_t aType,
+ Relation* aRel) :
+ mType(aType)
+{
+ mTargets = do_CreateInstance(NS_ARRAY_CONTRACTID);
+ Accessible* targetAcc = nullptr;
+ while ((targetAcc = aRel->Next()))
+ mTargets->AppendElement(static_cast<nsIAccessible*>(ToXPC(targetAcc)), false);
+}
+
+nsAccessibleRelation::nsAccessibleRelation(uint32_t aType,
+ const nsTArray<ProxyAccessible*>* aTargets) :
+ mType(aType)
+{
+ mTargets = do_CreateInstance(NS_ARRAY_CONTRACTID);
+ for (uint32_t idx = 0; idx < aTargets->Length(); ++idx) {
+ mTargets->AppendElement(
+ static_cast<nsIAccessible*>(ToXPC(aTargets->ElementAt(idx))),
+ false);
+ }
+}
+
+nsAccessibleRelation::~nsAccessibleRelation()
+{
+}
+
+// nsISupports
+NS_IMPL_ISUPPORTS(nsAccessibleRelation, nsIAccessibleRelation)
+
+// nsIAccessibleRelation
+NS_IMETHODIMP
+nsAccessibleRelation::GetRelationType(uint32_t *aType)
+{
+ NS_ENSURE_ARG_POINTER(aType);
+ *aType = mType;
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsAccessibleRelation::GetTargetsCount(uint32_t *aCount)
+{
+ NS_ENSURE_ARG_POINTER(aCount);
+ *aCount = 0;
+ return mTargets->GetLength(aCount);
+}
+
+NS_IMETHODIMP
+nsAccessibleRelation::GetTarget(uint32_t aIndex, nsIAccessible **aTarget)
+{
+ NS_ENSURE_ARG_POINTER(aTarget);
+ nsresult rv = NS_OK;
+ nsCOMPtr<nsIAccessible> target = do_QueryElementAt(mTargets, aIndex, &rv);
+ target.forget(aTarget);
+ return rv;
+}
+
+NS_IMETHODIMP
+nsAccessibleRelation::GetTargets(nsIArray **aTargets)
+{
+ NS_ENSURE_ARG_POINTER(aTargets);
+ NS_ADDREF(*aTargets = mTargets);
+ return NS_OK;
+}
diff --git a/accessible/xpcom/nsAccessibleRelation.h b/accessible/xpcom/nsAccessibleRelation.h
new file mode 100644
index 0000000000..1f201d6cca
--- /dev/null
+++ b/accessible/xpcom/nsAccessibleRelation.h
@@ -0,0 +1,50 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef _nsAccessibleRelation_H_
+#define _nsAccessibleRelation_H_
+
+#include "nsIAccessibleRelation.h"
+
+#include "nsCOMPtr.h"
+#include "nsTArray.h"
+#include "nsIMutableArray.h"
+#include "mozilla/Attributes.h"
+#include "mozilla/a11y/ProxyAccessible.h"
+
+namespace mozilla {
+namespace a11y {
+
+class Relation;
+
+/**
+ * Class represents an accessible relation.
+ */
+class nsAccessibleRelation final : public nsIAccessibleRelation
+{
+public:
+ nsAccessibleRelation(uint32_t aType, Relation* aRel);
+
+ nsAccessibleRelation(uint32_t aType,
+ const nsTArray<ProxyAccessible*>* aTargets);
+
+ NS_DECL_ISUPPORTS
+ NS_DECL_NSIACCESSIBLERELATION
+
+private:
+ nsAccessibleRelation();
+ ~nsAccessibleRelation();
+
+ nsAccessibleRelation(const nsAccessibleRelation&);
+ nsAccessibleRelation& operator = (const nsAccessibleRelation&);
+
+ uint32_t mType;
+ nsCOMPtr<nsIMutableArray> mTargets;
+};
+
+} // namespace a11y
+} // namespace mozilla
+
+#endif
diff --git a/accessible/xpcom/xpcAccessibilityService.cpp b/accessible/xpcom/xpcAccessibilityService.cpp
new file mode 100644
index 0000000000..97c0d0e721
--- /dev/null
+++ b/accessible/xpcom/xpcAccessibilityService.cpp
@@ -0,0 +1,246 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "xpcAccessibilityService.h"
+
+#include "nsAccessiblePivot.h"
+#include "nsAccessibilityService.h"
+
+#ifdef A11Y_LOG
+#include "Logging.h"
+#endif
+
+using namespace mozilla;
+using namespace mozilla::a11y;
+using namespace mozilla::dom;
+
+xpcAccessibilityService *xpcAccessibilityService::gXPCAccessibilityService = nullptr;
+
+////////////////////////////////////////////////////////////////////////////////
+// nsISupports
+
+void
+xpcAccessibilityService::ShutdownCallback(nsITimer* aTimer, void* aClosure)
+{
+ MaybeShutdownAccService(nsAccessibilityService::eXPCOM);
+ xpcAccessibilityService* xpcAccService =
+ reinterpret_cast<xpcAccessibilityService*>(aClosure);
+
+ if (xpcAccService->mShutdownTimer) {
+ xpcAccService->mShutdownTimer->Cancel();
+ xpcAccService->mShutdownTimer = nullptr;
+ }
+}
+
+NS_IMETHODIMP_(MozExternalRefCountType)
+xpcAccessibilityService::AddRef(void)
+{
+ MOZ_ASSERT_TYPE_OK_FOR_REFCOUNTING(xpcAccessibilityService)
+ MOZ_ASSERT(int32_t(mRefCnt) >= 0, "illegal refcnt");
+ if (!mRefCnt.isThreadSafe)
+ NS_ASSERT_OWNINGTHREAD(xpcAccessibilityService);
+ nsrefcnt count = ++mRefCnt;
+ NS_LOG_ADDREF(this, count, "xpcAccessibilityService", sizeof(*this));
+
+ if (mRefCnt > 1) {
+ GetOrCreateAccService(nsAccessibilityService::eXPCOM);
+ }
+
+ return count;
+}
+
+NS_IMETHODIMP_(MozExternalRefCountType)
+xpcAccessibilityService::Release(void)
+{
+ MOZ_ASSERT(int32_t(mRefCnt) > 0, "dup release");
+
+ if (!mRefCnt.isThreadSafe) {
+ NS_ASSERT_OWNINGTHREAD(xpcAccessibilityService);
+ }
+
+ nsrefcnt count = --mRefCnt;
+ NS_LOG_RELEASE(this, count, "xpcAccessibilityService");
+
+ if (count == 0) {
+ if (!mRefCnt.isThreadSafe) {
+ NS_ASSERT_OWNINGTHREAD(xpcAccessibilityService);
+ }
+
+ mRefCnt = 1; /* stabilize */
+ delete (this);
+ return 0;
+ }
+
+ // When ref count goes down to 1 (held internally as a static reference),
+ // it means that there are no more external references to the
+ // xpcAccessibilityService and we can attempt to shut down acceessiblity
+ // service.
+ if (count == 1 && !mShutdownTimer) {
+ mShutdownTimer = do_CreateInstance(NS_TIMER_CONTRACTID);
+ if (mShutdownTimer) {
+ mShutdownTimer->InitWithFuncCallback(ShutdownCallback, this, 100,
+ nsITimer::TYPE_ONE_SHOT);
+ }
+ }
+
+ return count;
+}
+
+NS_IMPL_QUERY_INTERFACE(xpcAccessibilityService, nsIAccessibilityService,
+ nsIAccessibleRetrieval)
+
+NS_IMETHODIMP
+xpcAccessibilityService::GetApplicationAccessible(nsIAccessible** aAccessibleApplication)
+{
+ NS_ENSURE_ARG_POINTER(aAccessibleApplication);
+
+ NS_IF_ADDREF(*aAccessibleApplication = XPCApplicationAcc());
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+xpcAccessibilityService::GetAccessibleFor(nsIDOMNode *aNode,
+ nsIAccessible **aAccessible)
+{
+ NS_ENSURE_ARG_POINTER(aAccessible);
+ *aAccessible = nullptr;
+ if (!aNode) {
+ return NS_OK;
+ }
+
+ nsCOMPtr<nsINode> node(do_QueryInterface(aNode));
+ if (!node) {
+ return NS_ERROR_INVALID_ARG;
+ }
+
+ DocAccessible* document = GetAccService()->GetDocAccessible(node->OwnerDoc());
+ if (document) {
+ NS_IF_ADDREF(*aAccessible = ToXPC(document->GetAccessible(node)));
+ }
+
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+xpcAccessibilityService::GetStringRole(uint32_t aRole, nsAString& aString)
+{
+ GetAccService()->GetStringRole(aRole, aString);
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+xpcAccessibilityService::GetStringStates(uint32_t aState, uint32_t aExtraState,
+ nsISupports **aStringStates)
+{
+ GetAccService()->GetStringStates(aState, aExtraState, aStringStates);
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+xpcAccessibilityService::GetStringEventType(uint32_t aEventType,
+ nsAString& aString)
+{
+ GetAccService()->GetStringEventType(aEventType, aString);
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+xpcAccessibilityService::GetStringRelationType(uint32_t aRelationType,
+ nsAString& aString)
+{
+ GetAccService()->GetStringRelationType(aRelationType, aString);
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+xpcAccessibilityService::GetAccessibleFromCache(nsIDOMNode* aNode,
+ nsIAccessible** aAccessible)
+{
+ NS_ENSURE_ARG_POINTER(aAccessible);
+ *aAccessible = nullptr;
+ if (!aNode) {
+ return NS_OK;
+ }
+
+ nsCOMPtr<nsINode> node(do_QueryInterface(aNode));
+ if (!node) {
+ return NS_ERROR_INVALID_ARG;
+ }
+
+ // Search for an accessible in each of our per document accessible object
+ // caches. If we don't find it, and the given node is itself a document, check
+ // our cache of document accessibles (document cache). Note usually shutdown
+ // document accessibles are not stored in the document cache, however an
+ // "unofficially" shutdown document (i.e. not from DocManager) can still
+ // exist in the document cache.
+ Accessible* accessible = GetAccService()->FindAccessibleInCache(node);
+ if (!accessible) {
+ nsCOMPtr<nsIDocument> document(do_QueryInterface(node));
+ if (document) {
+ accessible = mozilla::a11y::GetExistingDocAccessible(document);
+ }
+ }
+
+ NS_IF_ADDREF(*aAccessible = ToXPC(accessible));
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+xpcAccessibilityService::CreateAccessiblePivot(nsIAccessible* aRoot,
+ nsIAccessiblePivot** aPivot)
+{
+ NS_ENSURE_ARG_POINTER(aPivot);
+ NS_ENSURE_ARG(aRoot);
+ *aPivot = nullptr;
+
+ Accessible* accessibleRoot = aRoot->ToInternalAccessible();
+ NS_ENSURE_TRUE(accessibleRoot, NS_ERROR_INVALID_ARG);
+
+ nsAccessiblePivot* pivot = new nsAccessiblePivot(accessibleRoot);
+ NS_ADDREF(*aPivot = pivot);
+
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+xpcAccessibilityService::SetLogging(const nsACString& aModules)
+{
+#ifdef A11Y_LOG
+ logging::Enable(PromiseFlatCString(aModules));
+#endif
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+xpcAccessibilityService::IsLogged(const nsAString& aModule, bool* aIsLogged)
+{
+ NS_ENSURE_ARG_POINTER(aIsLogged);
+ *aIsLogged = false;
+
+#ifdef A11Y_LOG
+ *aIsLogged = logging::IsEnabled(aModule);
+#endif
+
+ return NS_OK;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// NS_GetAccessibilityService
+////////////////////////////////////////////////////////////////////////////////
+
+nsresult
+NS_GetAccessibilityService(nsIAccessibilityService** aResult)
+{
+ NS_ENSURE_TRUE(aResult, NS_ERROR_NULL_POINTER);
+ *aResult = nullptr;
+
+ GetOrCreateAccService(nsAccessibilityService::eXPCOM);
+
+ xpcAccessibilityService* service = new xpcAccessibilityService();
+ NS_ENSURE_TRUE(service, NS_ERROR_OUT_OF_MEMORY);
+ xpcAccessibilityService::gXPCAccessibilityService = service;
+ NS_ADDREF(*aResult = service);
+
+ return NS_OK;
+}
diff --git a/accessible/xpcom/xpcAccessibilityService.h b/accessible/xpcom/xpcAccessibilityService.h
new file mode 100644
index 0000000000..76389a8a5d
--- /dev/null
+++ b/accessible/xpcom/xpcAccessibilityService.h
@@ -0,0 +1,66 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef mozilla_a11y_xpcAccessibilityService_h_
+#define mozilla_a11y_xpcAccessibilityService_h_
+
+#include "nsIAccessibilityService.h"
+
+class xpcAccessibilityService : public nsIAccessibleRetrieval
+{
+
+public:
+ NS_DECL_ISUPPORTS
+ NS_DECL_NSIACCESSIBILITYSERVICE
+ NS_DECL_NSIACCESSIBLERETRIEVAL
+
+ /**
+ * Return true if xpc accessibility service is in use.
+ */
+ static bool IsInUse() {
+ // When ref count goes down to 1 (held internally as a static reference),
+ // it means that there are no more external references and thus it is not in
+ // use.
+ return gXPCAccessibilityService ? gXPCAccessibilityService->mRefCnt > 1 : false;
+ }
+
+protected:
+ virtual ~xpcAccessibilityService() {
+ if (mShutdownTimer) {
+ mShutdownTimer->Cancel();
+ mShutdownTimer = nullptr;
+ }
+ gXPCAccessibilityService = nullptr;
+ }
+
+private:
+ // xpcAccessibilityService creation is controlled by friend
+ // NS_GetAccessibilityService, keep constructor private.
+ xpcAccessibilityService() { };
+
+ nsCOMPtr<nsITimer> mShutdownTimer;
+
+ /**
+ * Reference for xpc accessibility service instance.
+ */
+ static xpcAccessibilityService* gXPCAccessibilityService;
+
+ /**
+ * Used to shutdown nsAccessibilityService if xpcom accessible service is not
+ * in use any more.
+ */
+ static void ShutdownCallback(nsITimer* aTimer, void* aClosure);
+
+ friend nsresult NS_GetAccessibilityService(nsIAccessibilityService** aResult);
+};
+
+// for component registration
+// {3b265b69-f813-48ff-880d-d88d101af404}
+#define NS_ACCESSIBILITY_SERVICE_CID \
+{ 0x3b265b69, 0xf813, 0x48ff, { 0x88, 0x0d, 0xd8, 0x8d, 0x10, 0x1a, 0xf4, 0x04 } }
+
+extern nsresult
+NS_GetAccessibilityService(nsIAccessibilityService** aResult);
+
+#endif
diff --git a/accessible/xpcom/xpcAccessible.cpp b/accessible/xpcom/xpcAccessible.cpp
new file mode 100644
index 0000000000..843b21cd2c
--- /dev/null
+++ b/accessible/xpcom/xpcAccessible.cpp
@@ -0,0 +1,826 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=2 et sw=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "Accessible-inl.h"
+#include "mozilla/a11y/DocAccessibleParent.h"
+#include "nsAccUtils.h"
+#include "nsIAccessibleRelation.h"
+#include "nsIAccessibleRole.h"
+#include "nsAccessibleRelation.h"
+#include "Relation.h"
+#include "Role.h"
+#include "RootAccessible.h"
+#include "xpcAccessibleDocument.h"
+
+#include "nsIMutableArray.h"
+#include "nsIPersistentProperties2.h"
+
+using namespace mozilla::a11y;
+
+NS_IMETHODIMP
+xpcAccessible::GetParent(nsIAccessible** aParent)
+{
+ NS_ENSURE_ARG_POINTER(aParent);
+ *aParent = nullptr;
+ if (IntlGeneric().IsNull())
+ return NS_ERROR_FAILURE;
+
+ AccessibleOrProxy parent = IntlGeneric().Parent();
+ NS_IF_ADDREF(*aParent = ToXPC(parent));
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+xpcAccessible::GetNextSibling(nsIAccessible** aNextSibling)
+{
+ NS_ENSURE_ARG_POINTER(aNextSibling);
+ *aNextSibling = nullptr;
+ if (IntlGeneric().IsNull())
+ return NS_ERROR_FAILURE;
+
+ if (IntlGeneric().IsAccessible()) {
+ nsresult rv = NS_OK;
+ NS_IF_ADDREF(*aNextSibling = ToXPC(Intl()->GetSiblingAtOffset(1, &rv)));
+ return rv;
+ }
+
+ ProxyAccessible* proxy = IntlGeneric().AsProxy();
+ NS_ENSURE_STATE(proxy);
+
+ NS_IF_ADDREF(*aNextSibling = ToXPC(proxy->NextSibling()));
+ return *aNextSibling ? NS_OK : NS_ERROR_FAILURE;
+}
+
+NS_IMETHODIMP
+xpcAccessible::GetPreviousSibling(nsIAccessible** aPreviousSibling)
+{
+ NS_ENSURE_ARG_POINTER(aPreviousSibling);
+ *aPreviousSibling = nullptr;
+ if (IntlGeneric().IsNull())
+ return NS_ERROR_FAILURE;
+
+ if (IntlGeneric().IsAccessible()) {
+ nsresult rv = NS_OK;
+ NS_IF_ADDREF(*aPreviousSibling = ToXPC(Intl()->GetSiblingAtOffset(-1, &rv)));
+ return rv;
+ }
+
+ ProxyAccessible* proxy = IntlGeneric().AsProxy();
+ NS_ENSURE_STATE(proxy);
+
+ NS_IF_ADDREF(*aPreviousSibling = ToXPC(proxy->PrevSibling()));
+ return *aPreviousSibling ? NS_OK : NS_ERROR_FAILURE;
+}
+
+NS_IMETHODIMP
+xpcAccessible::GetFirstChild(nsIAccessible** aFirstChild)
+{
+ NS_ENSURE_ARG_POINTER(aFirstChild);
+ *aFirstChild = nullptr;
+
+ if (IntlGeneric().IsNull())
+ return NS_ERROR_FAILURE;
+
+ NS_IF_ADDREF(*aFirstChild = ToXPC(IntlGeneric().FirstChild()));
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+xpcAccessible::GetLastChild(nsIAccessible** aLastChild)
+{
+ NS_ENSURE_ARG_POINTER(aLastChild);
+ *aLastChild = nullptr;
+
+ if (IntlGeneric().IsNull())
+ return NS_ERROR_FAILURE;
+
+ NS_IF_ADDREF(*aLastChild = ToXPC(IntlGeneric().LastChild()));
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+xpcAccessible::GetChildCount(int32_t* aChildCount)
+{
+ NS_ENSURE_ARG_POINTER(aChildCount);
+
+ if (IntlGeneric().IsNull())
+ return NS_ERROR_FAILURE;
+
+ *aChildCount = IntlGeneric().ChildCount();
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+xpcAccessible::GetChildAt(int32_t aChildIndex, nsIAccessible** aChild)
+{
+ NS_ENSURE_ARG_POINTER(aChild);
+ *aChild = nullptr;
+
+ if (IntlGeneric().IsNull())
+ return NS_ERROR_FAILURE;
+
+ // If child index is negative, then return last child.
+ // XXX: do we really need this?
+ if (aChildIndex < 0)
+ aChildIndex = IntlGeneric().ChildCount() - 1;
+
+ AccessibleOrProxy child = IntlGeneric().ChildAt(aChildIndex);
+ if (child.IsNull())
+ return NS_ERROR_INVALID_ARG;
+
+ NS_ADDREF(*aChild = ToXPC(child));
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+xpcAccessible::GetChildren(nsIArray** aChildren)
+{
+ NS_ENSURE_ARG_POINTER(aChildren);
+ *aChildren = nullptr;
+
+ if (IntlGeneric().IsNull())
+ return NS_ERROR_FAILURE;
+
+ nsresult rv = NS_OK;
+ nsCOMPtr<nsIMutableArray> children =
+ do_CreateInstance(NS_ARRAY_CONTRACTID, &rv);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ uint32_t childCount = IntlGeneric().ChildCount();
+ for (uint32_t childIdx = 0; childIdx < childCount; childIdx++) {
+ AccessibleOrProxy child = IntlGeneric().ChildAt(childIdx);
+ children->AppendElement(static_cast<nsIAccessible*>(ToXPC(child)), false);
+ }
+
+ children.forget(aChildren);
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+xpcAccessible::GetIndexInParent(int32_t* aIndexInParent)
+{
+ NS_ENSURE_ARG_POINTER(aIndexInParent);
+ *aIndexInParent = -1;
+ if (IntlGeneric().IsNull())
+ return NS_ERROR_FAILURE;
+
+ if (IntlGeneric().IsAccessible()) {
+ *aIndexInParent = Intl()->IndexInParent();
+ } else if (IntlGeneric().IsProxy()) {
+ *aIndexInParent = IntlGeneric().AsProxy()->IndexInParent();
+ }
+
+ return *aIndexInParent != -1 ? NS_OK : NS_ERROR_FAILURE;
+}
+
+NS_IMETHODIMP
+xpcAccessible::GetDOMNode(nsIDOMNode** aDOMNode)
+{
+ NS_ENSURE_ARG_POINTER(aDOMNode);
+ *aDOMNode = nullptr;
+
+ if (!Intl())
+ return NS_ERROR_FAILURE;
+
+ nsINode* node = Intl()->GetNode();
+ if (node)
+ CallQueryInterface(node, aDOMNode);
+
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+xpcAccessible::GetId(nsAString& aID)
+{
+#if defined(XP_WIN)
+ return NS_ERROR_NOT_IMPLEMENTED;
+#else
+ ProxyAccessible* proxy = IntlGeneric().AsProxy();
+ if (!proxy) {
+ return NS_ERROR_FAILURE;
+ }
+
+ nsString id;
+ proxy->DOMNodeID(id);
+ aID.Assign(id);
+
+ return NS_OK;
+#endif
+}
+
+NS_IMETHODIMP
+xpcAccessible::GetDocument(nsIAccessibleDocument** aDocument)
+{
+ NS_ENSURE_ARG_POINTER(aDocument);
+ *aDocument = nullptr;
+
+ if (!Intl())
+ return NS_ERROR_FAILURE;
+
+ NS_IF_ADDREF(*aDocument = ToXPCDocument(Intl()->Document()));
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+xpcAccessible::GetRootDocument(nsIAccessibleDocument** aRootDocument)
+{
+ NS_ENSURE_ARG_POINTER(aRootDocument);
+ *aRootDocument = nullptr;
+
+ if (!Intl())
+ return NS_ERROR_FAILURE;
+
+ NS_IF_ADDREF(*aRootDocument = ToXPCDocument(Intl()->RootAccessible()));
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+xpcAccessible::GetRole(uint32_t* aRole)
+{
+ NS_ENSURE_ARG_POINTER(aRole);
+ *aRole = nsIAccessibleRole::ROLE_NOTHING;
+
+ if (IntlGeneric().IsNull())
+ return NS_ERROR_FAILURE;
+
+ *aRole = IntlGeneric().Role();
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+xpcAccessible::GetState(uint32_t* aState, uint32_t* aExtraState)
+{
+ NS_ENSURE_ARG_POINTER(aState);
+
+ if (IntlGeneric().IsNull())
+ nsAccUtils::To32States(states::DEFUNCT, aState, aExtraState);
+ else if (Intl())
+ nsAccUtils::To32States(Intl()->State(), aState, aExtraState);
+ else
+ nsAccUtils::To32States(IntlGeneric().AsProxy()->State(), aState,
+ aExtraState);
+
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+xpcAccessible::GetName(nsAString& aName)
+{
+ aName.Truncate();
+
+ if (IntlGeneric().IsNull())
+ return NS_ERROR_FAILURE;
+
+ nsAutoString name;
+ if (ProxyAccessible* proxy = IntlGeneric().AsProxy()) {
+ proxy->Name(name);
+ } else {
+ Intl()->Name(name);
+ }
+
+ aName.Assign(name);
+
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+xpcAccessible::GetDescription(nsAString& aDescription)
+{
+ if (IntlGeneric().IsNull())
+ return NS_ERROR_FAILURE;
+
+ nsAutoString desc;
+ if (ProxyAccessible* proxy = IntlGeneric().AsProxy()) {
+ proxy->Description(desc);
+ } else {
+ Intl()->Description(desc);
+ }
+
+ aDescription.Assign(desc);
+
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+xpcAccessible::GetLanguage(nsAString& aLanguage)
+{
+ if (IntlGeneric().IsNull())
+ return NS_ERROR_FAILURE;
+
+ nsAutoString lang;
+ if (ProxyAccessible* proxy = IntlGeneric().AsProxy()) {
+ proxy->Language(lang);
+ } else {
+ Intl()->Language(lang);
+ }
+
+ aLanguage.Assign(lang);
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+xpcAccessible::GetValue(nsAString& aValue)
+{
+ if (IntlGeneric().IsNull())
+ return NS_ERROR_FAILURE;
+
+ nsAutoString value;
+ if (ProxyAccessible* proxy = IntlGeneric().AsProxy()) {
+ proxy->Value(value);
+ } else {
+ Intl()->Value(value);
+ }
+
+ aValue.Assign(value);
+
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+xpcAccessible::GetHelp(nsAString& aHelp)
+{
+ if (IntlGeneric().IsNull())
+ return NS_ERROR_FAILURE;
+
+ nsAutoString help;
+ if (ProxyAccessible* proxy = IntlGeneric().AsProxy()) {
+#if defined(XP_WIN)
+ return NS_ERROR_NOT_IMPLEMENTED;
+#else
+ proxy->Help(help);
+#endif
+ } else {
+ Intl()->Help(help);
+ }
+
+ aHelp.Assign(help);
+
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+xpcAccessible::GetAccessKey(nsAString& aAccessKey)
+{
+ aAccessKey.Truncate();
+
+ if (IntlGeneric().IsNull())
+ return NS_ERROR_FAILURE;
+
+ if (ProxyAccessible* proxy = IntlGeneric().AsProxy()) {
+#if defined(XP_WIN)
+ return NS_ERROR_NOT_IMPLEMENTED;
+#else
+ proxy->AccessKey().ToString(aAccessKey);
+#endif
+ } else {
+ Intl()->AccessKey().ToString(aAccessKey);
+ }
+
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+xpcAccessible::GetKeyboardShortcut(nsAString& aKeyBinding)
+{
+ aKeyBinding.Truncate();
+ if (IntlGeneric().IsNull())
+ return NS_ERROR_FAILURE;
+
+ if (ProxyAccessible* proxy = IntlGeneric().AsProxy()) {
+#if defined(XP_WIN)
+ return NS_ERROR_NOT_IMPLEMENTED;
+#else
+ proxy->KeyboardShortcut().ToString(aKeyBinding);
+#endif
+ } else {
+ Intl()->KeyboardShortcut().ToString(aKeyBinding);
+ }
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+xpcAccessible::GetAttributes(nsIPersistentProperties** aAttributes)
+{
+ NS_ENSURE_ARG_POINTER(aAttributes);
+ *aAttributes = nullptr;
+
+ if (IntlGeneric().IsNull()) {
+ return NS_ERROR_FAILURE;
+ }
+
+ if (Accessible* acc = Intl()) {
+ nsCOMPtr<nsIPersistentProperties> attributes = acc->Attributes();
+ attributes.swap(*aAttributes);
+ return NS_OK;
+ }
+
+ ProxyAccessible* proxy = IntlGeneric().AsProxy();
+ AutoTArray<Attribute, 10> attrs;
+ proxy->Attributes(&attrs);
+
+ nsCOMPtr<nsIPersistentProperties> props =
+ do_CreateInstance(NS_PERSISTENTPROPERTIES_CONTRACTID);
+ uint32_t attrCount = attrs.Length();
+ nsAutoString unused;
+ for (uint32_t i = 0; i < attrCount; i++) {
+ props->SetStringProperty(attrs[i].Name(), attrs[i].Value(), unused);
+ }
+
+ props.forget(aAttributes);
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+xpcAccessible::GetBounds(int32_t* aX, int32_t* aY,
+ int32_t* aWidth, int32_t* aHeight)
+{
+ NS_ENSURE_ARG_POINTER(aX);
+ *aX = 0;
+ NS_ENSURE_ARG_POINTER(aY);
+ *aY = 0;
+ NS_ENSURE_ARG_POINTER(aWidth);
+ *aWidth = 0;
+ NS_ENSURE_ARG_POINTER(aHeight);
+ *aHeight = 0;
+
+ if (IntlGeneric().IsNull())
+ return NS_ERROR_FAILURE;
+
+ nsIntRect rect;
+ if (Accessible* acc = IntlGeneric().AsAccessible()) {
+ rect = acc->Bounds();
+ } else {
+ rect = IntlGeneric().AsProxy()->Bounds();
+ }
+
+ *aX = rect.x;
+ *aY = rect.y;
+ *aWidth = rect.width;
+ *aHeight = rect.height;
+
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+xpcAccessible::GroupPosition(int32_t* aGroupLevel,
+ int32_t* aSimilarItemsInGroup,
+ int32_t* aPositionInGroup)
+{
+ NS_ENSURE_ARG_POINTER(aGroupLevel);
+ *aGroupLevel = 0;
+
+ NS_ENSURE_ARG_POINTER(aSimilarItemsInGroup);
+ *aSimilarItemsInGroup = 0;
+
+ NS_ENSURE_ARG_POINTER(aPositionInGroup);
+ *aPositionInGroup = 0;
+
+ if (!Intl())
+ return NS_ERROR_FAILURE;
+
+ GroupPos groupPos = Intl()->GroupPosition();
+
+ *aGroupLevel = groupPos.level;
+ *aSimilarItemsInGroup = groupPos.setSize;
+ *aPositionInGroup = groupPos.posInSet;
+
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+xpcAccessible::GetRelationByType(uint32_t aType,
+ nsIAccessibleRelation** aRelation)
+{
+ NS_ENSURE_ARG_POINTER(aRelation);
+ *aRelation = nullptr;
+
+ NS_ENSURE_ARG(aType <= static_cast<uint32_t>(RelationType::LAST));
+
+ if (IntlGeneric().IsNull())
+ return NS_ERROR_FAILURE;
+
+ if (IntlGeneric().IsAccessible()) {
+ Relation rel = Intl()->RelationByType(static_cast<RelationType>(aType));
+ NS_ADDREF(*aRelation = new nsAccessibleRelation(aType, &rel));
+ return NS_OK;
+ }
+
+#if defined(XP_WIN)
+ return NS_ERROR_NOT_IMPLEMENTED;
+#else
+ ProxyAccessible* proxy = IntlGeneric().AsProxy();
+ nsTArray<ProxyAccessible*> targets =
+ proxy->RelationByType(static_cast<RelationType>(aType));
+ NS_ADDREF(*aRelation = new nsAccessibleRelation(aType, &targets));
+
+ return NS_OK;
+#endif
+}
+
+NS_IMETHODIMP
+xpcAccessible::GetRelations(nsIArray** aRelations)
+{
+ NS_ENSURE_ARG_POINTER(aRelations);
+ *aRelations = nullptr;
+
+ if (IntlGeneric().IsNull())
+ return NS_ERROR_FAILURE;
+
+ nsCOMPtr<nsIMutableArray> relations = do_CreateInstance(NS_ARRAY_CONTRACTID);
+ NS_ENSURE_TRUE(relations, NS_ERROR_OUT_OF_MEMORY);
+
+ static const uint32_t relationTypes[] = {
+ nsIAccessibleRelation::RELATION_LABELLED_BY,
+ nsIAccessibleRelation::RELATION_LABEL_FOR,
+ nsIAccessibleRelation::RELATION_DESCRIBED_BY,
+ nsIAccessibleRelation::RELATION_DESCRIPTION_FOR,
+ nsIAccessibleRelation::RELATION_NODE_CHILD_OF,
+ nsIAccessibleRelation::RELATION_NODE_PARENT_OF,
+ nsIAccessibleRelation::RELATION_CONTROLLED_BY,
+ nsIAccessibleRelation::RELATION_CONTROLLER_FOR,
+ nsIAccessibleRelation::RELATION_FLOWS_TO,
+ nsIAccessibleRelation::RELATION_FLOWS_FROM,
+ nsIAccessibleRelation::RELATION_MEMBER_OF,
+ nsIAccessibleRelation::RELATION_SUBWINDOW_OF,
+ nsIAccessibleRelation::RELATION_EMBEDS,
+ nsIAccessibleRelation::RELATION_EMBEDDED_BY,
+ nsIAccessibleRelation::RELATION_POPUP_FOR,
+ nsIAccessibleRelation::RELATION_PARENT_WINDOW_OF,
+ nsIAccessibleRelation::RELATION_DEFAULT_BUTTON,
+ nsIAccessibleRelation::RELATION_CONTAINING_DOCUMENT,
+ nsIAccessibleRelation::RELATION_CONTAINING_TAB_PANE,
+ nsIAccessibleRelation::RELATION_CONTAINING_APPLICATION
+ };
+
+ for (uint32_t idx = 0; idx < ArrayLength(relationTypes); idx++) {
+ nsCOMPtr<nsIAccessibleRelation> relation;
+ nsresult rv = GetRelationByType(relationTypes[idx], getter_AddRefs(relation));
+
+ if (NS_SUCCEEDED(rv) && relation) {
+ uint32_t targets = 0;
+ relation->GetTargetsCount(&targets);
+ if (targets)
+ relations->AppendElement(relation, false);
+ }
+ }
+
+ NS_ADDREF(*aRelations = relations);
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+xpcAccessible::GetFocusedChild(nsIAccessible** aChild)
+{
+ NS_ENSURE_ARG_POINTER(aChild);
+ *aChild = nullptr;
+
+ if (IntlGeneric().IsNull())
+ return NS_ERROR_FAILURE;
+
+ if (ProxyAccessible* proxy = IntlGeneric().AsProxy()) {
+#if defined(XP_WIN)
+ return NS_ERROR_NOT_IMPLEMENTED;
+#else
+ NS_IF_ADDREF(*aChild = ToXPC(proxy->FocusedChild()));
+#endif
+ } else {
+ NS_IF_ADDREF(*aChild = ToXPC(Intl()->FocusedChild()));
+ }
+
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+xpcAccessible::GetChildAtPoint(int32_t aX, int32_t aY,
+ nsIAccessible** aAccessible)
+{
+ NS_ENSURE_ARG_POINTER(aAccessible);
+ *aAccessible = nullptr;
+
+ if (IntlGeneric().IsNull())
+ return NS_ERROR_FAILURE;
+
+ if (ProxyAccessible* proxy = IntlGeneric().AsProxy()) {
+#if defined(XP_WIN)
+ return NS_ERROR_NOT_IMPLEMENTED;
+#else
+ NS_IF_ADDREF(*aAccessible =
+ ToXPC(proxy->ChildAtPoint(aX, aY, Accessible::eDirectChild)));
+#endif
+ } else {
+ NS_IF_ADDREF(*aAccessible =
+ ToXPC(Intl()->ChildAtPoint(aX, aY, Accessible::eDirectChild)));
+ }
+
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+xpcAccessible::GetDeepestChildAtPoint(int32_t aX, int32_t aY,
+ nsIAccessible** aAccessible)
+{
+ NS_ENSURE_ARG_POINTER(aAccessible);
+ *aAccessible = nullptr;
+
+ if (IntlGeneric().IsNull())
+ return NS_ERROR_FAILURE;
+
+ if (ProxyAccessible* proxy = IntlGeneric().AsProxy()) {
+#if defined(XP_WIN)
+ return NS_ERROR_NOT_IMPLEMENTED;
+#else
+ NS_IF_ADDREF(*aAccessible =
+ ToXPC(proxy->ChildAtPoint(aX, aY, Accessible::eDeepestChild)));
+#endif
+ } else {
+ NS_IF_ADDREF(*aAccessible =
+ ToXPC(Intl()->ChildAtPoint(aX, aY, Accessible::eDeepestChild)));
+ }
+
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+xpcAccessible::SetSelected(bool aSelect)
+{
+ if (IntlGeneric().IsNull())
+ return NS_ERROR_FAILURE;
+
+ if (ProxyAccessible* proxy = IntlGeneric().AsProxy()) {
+#if defined(XP_WIN)
+ return NS_ERROR_NOT_IMPLEMENTED;
+#else
+ proxy->SetSelected(aSelect);
+#endif
+ } else {
+ Intl()->SetSelected(aSelect);
+ }
+
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+xpcAccessible::TakeSelection()
+{
+ if (IntlGeneric().IsNull())
+ return NS_ERROR_FAILURE;
+
+ if (ProxyAccessible* proxy = IntlGeneric().AsProxy()) {
+#if defined(XP_WIN)
+ return NS_ERROR_NOT_IMPLEMENTED;
+#else
+ proxy->TakeSelection();
+#endif
+ } else {
+ Intl()->TakeSelection();
+ }
+
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+xpcAccessible::TakeFocus()
+{
+ if (IntlGeneric().IsNull())
+ return NS_ERROR_FAILURE;
+
+ if (ProxyAccessible* proxy = IntlGeneric().AsProxy()) {
+#if defined(XP_WIN)
+ return NS_ERROR_NOT_IMPLEMENTED;
+#else
+ proxy->TakeFocus();
+#endif
+ } else {
+ Intl()->TakeFocus();
+ }
+
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+xpcAccessible::GetActionCount(uint8_t* aActionCount)
+{
+ NS_ENSURE_ARG_POINTER(aActionCount);
+ *aActionCount = 0;
+ if (IntlGeneric().IsNull())
+ return NS_ERROR_FAILURE;
+
+ if (ProxyAccessible* proxy = IntlGeneric().AsProxy()) {
+#if defined(XP_WIN)
+ return NS_ERROR_NOT_IMPLEMENTED;
+#else
+ *aActionCount = proxy->ActionCount();
+#endif
+ } else {
+ *aActionCount = Intl()->ActionCount();
+ }
+
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+xpcAccessible::GetActionName(uint8_t aIndex, nsAString& aName)
+{
+ if (IntlGeneric().IsNull())
+ return NS_ERROR_FAILURE;
+
+ if (ProxyAccessible* proxy = IntlGeneric().AsProxy()) {
+#if defined(XP_WIN)
+ return NS_ERROR_NOT_IMPLEMENTED;
+#else
+ nsString name;
+ proxy->ActionNameAt(aIndex, name);
+ aName.Assign(name);
+#endif
+ } else {
+ if (aIndex >= Intl()->ActionCount())
+ return NS_ERROR_INVALID_ARG;
+
+ Intl()->ActionNameAt(aIndex, aName);
+ }
+
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+xpcAccessible::GetActionDescription(uint8_t aIndex, nsAString& aDescription)
+{
+ if (IntlGeneric().IsNull())
+ return NS_ERROR_FAILURE;
+
+ if (ProxyAccessible* proxy = IntlGeneric().AsProxy()) {
+#if defined(XP_WIN)
+ return NS_ERROR_NOT_IMPLEMENTED;
+#else
+ nsString description;
+ proxy->ActionDescriptionAt(aIndex, description);
+ aDescription.Assign(description);
+#endif
+ } else {
+ if (aIndex >= Intl()->ActionCount())
+ return NS_ERROR_INVALID_ARG;
+
+ Intl()->ActionDescriptionAt(aIndex, aDescription);
+ }
+
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+xpcAccessible::DoAction(uint8_t aIndex)
+{
+ if (IntlGeneric().IsNull())
+ return NS_ERROR_FAILURE;
+
+ if (ProxyAccessible* proxy = IntlGeneric().AsProxy()) {
+#if defined(XP_WIN)
+ return NS_ERROR_NOT_IMPLEMENTED;
+#else
+ return proxy->DoAction(aIndex) ? NS_OK : NS_ERROR_INVALID_ARG;
+#endif
+ } else {
+ return Intl()->DoAction(aIndex) ?
+ NS_OK : NS_ERROR_INVALID_ARG;
+ }
+}
+
+NS_IMETHODIMP
+xpcAccessible::ScrollTo(uint32_t aHow)
+{
+ if (IntlGeneric().IsNull())
+ return NS_ERROR_FAILURE;
+
+ if (ProxyAccessible* proxy = IntlGeneric().AsProxy()) {
+#if defined(XP_WIN)
+ return NS_ERROR_NOT_IMPLEMENTED;
+#else
+ proxy->ScrollTo(aHow);
+#endif
+ } else {
+ Intl()->ScrollTo(aHow);
+ }
+
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+xpcAccessible::ScrollToPoint(uint32_t aCoordinateType, int32_t aX, int32_t aY)
+{
+ if (IntlGeneric().IsNull())
+ return NS_ERROR_FAILURE;
+
+ if (ProxyAccessible* proxy = IntlGeneric().AsProxy()) {
+#if defined(XP_WIN)
+ return NS_ERROR_NOT_IMPLEMENTED;
+#else
+ proxy->ScrollToPoint(aCoordinateType, aX, aY);
+#endif
+ } else {
+ Intl()->ScrollToPoint(aCoordinateType, aX, aY);
+ }
+
+ return NS_OK;
+}
diff --git a/accessible/xpcom/xpcAccessible.h b/accessible/xpcom/xpcAccessible.h
new file mode 100644
index 0000000000..cecc727203
--- /dev/null
+++ b/accessible/xpcom/xpcAccessible.h
@@ -0,0 +1,106 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=2 et sw=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef mozilla_a11y_xpcAccessible_h_
+#define mozilla_a11y_xpcAccessible_h_
+
+#include "nsIAccessible.h"
+
+class nsIAccessible;
+
+namespace mozilla {
+namespace a11y {
+
+class Accessible;
+class AccessibleOrProxy;
+
+/**
+ * XPCOM nsIAccessible interface implementation, used by xpcAccessibleGeneric
+ * class.
+ */
+class xpcAccessible : public nsIAccessible
+{
+public:
+ // nsIAccessible
+ NS_IMETHOD GetParent(nsIAccessible** aParent) final override;
+ NS_IMETHOD GetNextSibling(nsIAccessible** aNextSibling) final override;
+ NS_IMETHOD GetPreviousSibling(nsIAccessible** aPreviousSibling)
+ final override;
+ NS_IMETHOD GetFirstChild(nsIAccessible** aFirstChild) final override;
+ NS_IMETHOD GetLastChild(nsIAccessible** aLastChild) final override;
+ NS_IMETHOD GetChildCount(int32_t* aChildCount) final override;
+ NS_IMETHOD GetChildAt(int32_t aChildIndex, nsIAccessible** aChild)
+ final override;
+ NS_IMETHOD GetChildren(nsIArray** aChildren) final override;
+ NS_IMETHOD GetIndexInParent(int32_t* aIndexInParent) final override;
+
+ NS_IMETHOD GetDOMNode(nsIDOMNode** aDOMNode) final override;
+ NS_IMETHOD GetId(nsAString& aID) final override;
+ NS_IMETHOD GetDocument(nsIAccessibleDocument** aDocument) final override;
+ NS_IMETHOD GetRootDocument(nsIAccessibleDocument** aRootDocument)
+ final override;
+
+ NS_IMETHOD GetRole(uint32_t* aRole) final override;
+ NS_IMETHOD GetState(uint32_t* aState, uint32_t* aExtraState)
+ final override;
+
+ NS_IMETHOD GetDescription(nsAString& aDescription) final override;
+ NS_IMETHOD GetName(nsAString& aName) final override;
+ NS_IMETHOD GetLanguage(nsAString& aLanguage) final override;
+ NS_IMETHOD GetValue(nsAString& aValue) final override;
+ NS_IMETHOD GetHelp(nsAString& aHelp) final override;
+
+ NS_IMETHOD GetAccessKey(nsAString& aAccessKey) final override;
+ NS_IMETHOD GetKeyboardShortcut(nsAString& aKeyBinding) final override;
+
+ NS_IMETHOD GetAttributes(nsIPersistentProperties** aAttributes)
+ final override;
+ NS_IMETHOD GetBounds(int32_t* aX, int32_t* aY,
+ int32_t* aWidth, int32_t* aHeight) final override;
+ NS_IMETHOD GroupPosition(int32_t* aGroupLevel, int32_t* aSimilarItemsInGroup,
+ int32_t* aPositionInGroup) final override;
+ NS_IMETHOD GetRelationByType(uint32_t aType,
+ nsIAccessibleRelation** aRelation)
+ final override;
+ NS_IMETHOD GetRelations(nsIArray** aRelations) final override;
+
+ NS_IMETHOD GetFocusedChild(nsIAccessible** aChild) final override;
+ NS_IMETHOD GetChildAtPoint(int32_t aX, int32_t aY,
+ nsIAccessible** aAccessible) final override;
+ NS_IMETHOD GetDeepestChildAtPoint(int32_t aX, int32_t aY,
+ nsIAccessible** aAccessible)
+ final override;
+
+ NS_IMETHOD SetSelected(bool aSelect) final override;
+ NS_IMETHOD TakeSelection() final override;
+ NS_IMETHOD TakeFocus() final override;
+
+ NS_IMETHOD GetActionCount(uint8_t* aActionCount) final override;
+ NS_IMETHOD GetActionName(uint8_t aIndex, nsAString& aName) final override;
+ NS_IMETHOD GetActionDescription(uint8_t aIndex, nsAString& aDescription)
+ final override;
+ NS_IMETHOD DoAction(uint8_t aIndex) final override;
+
+ NS_IMETHOD ScrollTo(uint32_t aHow) final override;
+ NS_IMETHOD ScrollToPoint(uint32_t aCoordinateType,
+ int32_t aX, int32_t aY) final override;
+
+protected:
+ xpcAccessible() { }
+ virtual ~xpcAccessible() {}
+
+private:
+ Accessible* Intl();
+ AccessibleOrProxy IntlGeneric();
+
+ xpcAccessible(const xpcAccessible&) = delete;
+ xpcAccessible& operator =(const xpcAccessible&) = delete;
+};
+
+} // namespace a11y
+} // namespace mozilla
+
+#endif
diff --git a/accessible/xpcom/xpcAccessibleApplication.cpp b/accessible/xpcom/xpcAccessibleApplication.cpp
new file mode 100644
index 0000000000..af2bde466f
--- /dev/null
+++ b/accessible/xpcom/xpcAccessibleApplication.cpp
@@ -0,0 +1,69 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=2 et sw=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "xpcAccessibleApplication.h"
+
+#include "ApplicationAccessible.h"
+
+using namespace mozilla::a11y;
+
+////////////////////////////////////////////////////////////////////////////////
+// nsISupports
+
+NS_IMPL_ISUPPORTS_INHERITED(xpcAccessibleApplication,
+ xpcAccessibleGeneric,
+ nsIAccessibleApplication)
+
+////////////////////////////////////////////////////////////////////////////////
+// nsIAccessibleApplication
+
+NS_IMETHODIMP
+xpcAccessibleApplication::GetAppName(nsAString& aName)
+{
+ aName.Truncate();
+
+ if (!Intl())
+ return NS_ERROR_FAILURE;
+
+ Intl()->AppName(aName);
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+xpcAccessibleApplication::GetAppVersion(nsAString& aVersion)
+{
+ aVersion.Truncate();
+
+ if (!Intl())
+ return NS_ERROR_FAILURE;
+
+ Intl()->AppVersion(aVersion);
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+xpcAccessibleApplication::GetPlatformName(nsAString& aName)
+{
+ aName.Truncate();
+
+ if (!Intl())
+ return NS_ERROR_FAILURE;
+
+ Intl()->PlatformName(aName);
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+xpcAccessibleApplication::GetPlatformVersion(nsAString& aVersion)
+{
+ aVersion.Truncate();
+
+ if (!Intl())
+ return NS_ERROR_FAILURE;
+
+ Intl()->PlatformVersion(aVersion);
+ return NS_OK;
+}
diff --git a/accessible/xpcom/xpcAccessibleApplication.h b/accessible/xpcom/xpcAccessibleApplication.h
new file mode 100644
index 0000000000..24edbcbdbc
--- /dev/null
+++ b/accessible/xpcom/xpcAccessibleApplication.h
@@ -0,0 +1,48 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=2 et sw=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef mozilla_a11y_xpcAccessibleApplication_h_
+#define mozilla_a11y_xpcAccessibleApplication_h_
+
+#include "nsIAccessibleApplication.h"
+#include "ApplicationAccessible.h"
+#include "xpcAccessibleGeneric.h"
+
+namespace mozilla {
+namespace a11y {
+
+/**
+ * XPCOM wrapper around ApplicationAccessible class.
+ */
+class xpcAccessibleApplication : public xpcAccessibleGeneric,
+ public nsIAccessibleApplication
+{
+public:
+ explicit xpcAccessibleApplication(Accessible* aIntl) :
+ xpcAccessibleGeneric(aIntl) { }
+
+ NS_DECL_ISUPPORTS_INHERITED
+
+ // nsIAccessibleApplication
+ NS_IMETHOD GetAppName(nsAString& aName) final override;
+ NS_IMETHOD GetAppVersion(nsAString& aVersion) final override;
+ NS_IMETHOD GetPlatformName(nsAString& aName) final override;
+ NS_IMETHOD GetPlatformVersion(nsAString& aVersion) final override;
+
+protected:
+ virtual ~xpcAccessibleApplication() {}
+
+private:
+ ApplicationAccessible* Intl() { return mIntl.AsAccessible()->AsApplication(); }
+
+ xpcAccessibleApplication(const xpcAccessibleApplication&) = delete;
+ xpcAccessibleApplication& operator =(const xpcAccessibleApplication&) = delete;
+};
+
+} // namespace a11y
+} // namespace mozilla
+
+#endif
diff --git a/accessible/xpcom/xpcAccessibleDocument.cpp b/accessible/xpcom/xpcAccessibleDocument.cpp
new file mode 100644
index 0000000000..055cb8a860
--- /dev/null
+++ b/accessible/xpcom/xpcAccessibleDocument.cpp
@@ -0,0 +1,262 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=2 et sw=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "xpcAccessibleDocument.h"
+#include "xpcAccessibleImage.h"
+#include "xpcAccessibleTable.h"
+#include "xpcAccessibleTableCell.h"
+
+#include "mozilla/a11y/DocAccessibleParent.h"
+#include "DocAccessible-inl.h"
+#include "nsIDOMDocument.h"
+
+using namespace mozilla;
+using namespace mozilla::a11y;
+
+////////////////////////////////////////////////////////////////////////////////
+// nsISupports and cycle collection
+
+NS_IMPL_CYCLE_COLLECTION_CLASS(xpcAccessibleDocument)
+
+NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(xpcAccessibleDocument,
+ xpcAccessibleGeneric)
+ NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mCache)
+NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
+
+NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(xpcAccessibleDocument,
+ xpcAccessibleGeneric)
+ tmp->mCache.Clear();
+NS_IMPL_CYCLE_COLLECTION_UNLINK_END
+
+NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(xpcAccessibleDocument)
+ NS_INTERFACE_MAP_ENTRY(nsIAccessibleDocument)
+NS_INTERFACE_MAP_END_INHERITING(xpcAccessibleHyperText)
+
+NS_IMPL_ADDREF_INHERITED(xpcAccessibleDocument, xpcAccessibleHyperText)
+NS_IMPL_RELEASE_INHERITED(xpcAccessibleDocument, xpcAccessibleHyperText)
+
+////////////////////////////////////////////////////////////////////////////////
+// nsIAccessibleDocument
+
+NS_IMETHODIMP
+xpcAccessibleDocument::GetURL(nsAString& aURL)
+{
+ if (!Intl())
+ return NS_ERROR_FAILURE;
+
+ Intl()->URL(aURL);
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+xpcAccessibleDocument::GetTitle(nsAString& aTitle)
+{
+ if (!Intl())
+ return NS_ERROR_FAILURE;
+
+ nsAutoString title;
+ Intl()->Title(title);
+ aTitle = title;
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+xpcAccessibleDocument::GetMimeType(nsAString& aType)
+{
+ if (!Intl())
+ return NS_ERROR_FAILURE;
+
+ Intl()->MimeType(aType);
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+xpcAccessibleDocument::GetDocType(nsAString& aType)
+{
+ if (!Intl())
+ return NS_ERROR_FAILURE;
+
+ Intl()->DocType(aType);
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+xpcAccessibleDocument::GetDOMDocument(nsIDOMDocument** aDOMDocument)
+{
+ NS_ENSURE_ARG_POINTER(aDOMDocument);
+ *aDOMDocument = nullptr;
+
+ if (!Intl())
+ return NS_ERROR_FAILURE;
+
+ if (Intl()->DocumentNode())
+ CallQueryInterface(Intl()->DocumentNode(), aDOMDocument);
+
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+xpcAccessibleDocument::GetWindow(mozIDOMWindowProxy** aDOMWindow)
+{
+ NS_ENSURE_ARG_POINTER(aDOMWindow);
+ *aDOMWindow = nullptr;
+
+ if (!Intl())
+ return NS_ERROR_FAILURE;
+
+ NS_IF_ADDREF(*aDOMWindow = Intl()->DocumentNode()->GetWindow());
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+xpcAccessibleDocument::GetParentDocument(nsIAccessibleDocument** aDocument)
+{
+ NS_ENSURE_ARG_POINTER(aDocument);
+ *aDocument = nullptr;
+
+ if (!Intl())
+ return NS_ERROR_FAILURE;
+
+ NS_IF_ADDREF(*aDocument = ToXPCDocument(Intl()->ParentDocument()));
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+xpcAccessibleDocument::GetChildDocumentCount(uint32_t* aCount)
+{
+ NS_ENSURE_ARG_POINTER(aCount);
+ *aCount = 0;
+
+ if (!Intl())
+ return NS_ERROR_FAILURE;
+
+ *aCount = Intl()->ChildDocumentCount();
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+xpcAccessibleDocument::GetChildDocumentAt(uint32_t aIndex,
+ nsIAccessibleDocument** aDocument)
+{
+ NS_ENSURE_ARG_POINTER(aDocument);
+ *aDocument = nullptr;
+
+ if (!Intl())
+ return NS_ERROR_FAILURE;
+
+ NS_IF_ADDREF(*aDocument = ToXPCDocument(Intl()->GetChildDocumentAt(aIndex)));
+ return *aDocument ? NS_OK : NS_ERROR_INVALID_ARG;
+}
+
+NS_IMETHODIMP
+xpcAccessibleDocument::GetVirtualCursor(nsIAccessiblePivot** aVirtualCursor)
+{
+ NS_ENSURE_ARG_POINTER(aVirtualCursor);
+ *aVirtualCursor = nullptr;
+
+ if (!Intl())
+ return NS_ERROR_FAILURE;
+
+ NS_ADDREF(*aVirtualCursor = Intl()->VirtualCursor());
+ return NS_OK;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// xpcAccessibleDocument
+
+xpcAccessibleGeneric*
+xpcAccessibleDocument::GetAccessible(Accessible* aAccessible)
+{
+ MOZ_ASSERT(!mRemote);
+ if (ToXPCDocument(aAccessible->Document()) != this) {
+ NS_ERROR("This XPCOM document is not related with given internal accessible!");
+ return nullptr;
+ }
+
+ if (aAccessible->IsDoc())
+ return this;
+
+ xpcAccessibleGeneric* xpcAcc = mCache.GetWeak(aAccessible);
+ if (xpcAcc)
+ return xpcAcc;
+
+ if (aAccessible->IsImage())
+ xpcAcc = new xpcAccessibleImage(aAccessible);
+ else if (aAccessible->IsTable())
+ xpcAcc = new xpcAccessibleTable(aAccessible);
+ else if (aAccessible->IsTableCell())
+ xpcAcc = new xpcAccessibleTableCell(aAccessible);
+ else if (aAccessible->IsHyperText())
+ xpcAcc = new xpcAccessibleHyperText(aAccessible);
+ else
+ xpcAcc = new xpcAccessibleGeneric(aAccessible);
+
+ mCache.Put(aAccessible, xpcAcc);
+ return xpcAcc;
+}
+
+xpcAccessibleGeneric*
+xpcAccessibleDocument::GetXPCAccessible(ProxyAccessible* aProxy)
+{
+ MOZ_ASSERT(mRemote);
+ MOZ_ASSERT(aProxy->Document() == mIntl.AsProxy());
+ if (aProxy->IsDoc()) {
+ return this;
+ }
+
+ xpcAccessibleGeneric* acc = mCache.GetWeak(aProxy);
+ if (acc) {
+ return acc;
+ }
+
+ // XXX support exposing optional interfaces.
+ uint8_t interfaces = 0;
+ if (aProxy->mHasValue) {
+ interfaces |= eValue;
+ }
+
+ if (aProxy->mIsHyperLink) {
+ interfaces |= eHyperLink;
+ }
+
+ if (aProxy->mIsHyperText) {
+ interfaces |= eText;
+ acc = new xpcAccessibleHyperText(aProxy, interfaces);
+ mCache.Put(aProxy, acc);
+
+ return acc;
+ }
+
+ acc = new xpcAccessibleGeneric(aProxy, interfaces);
+ mCache.Put(aProxy, acc);
+
+ return acc;
+}
+
+void
+xpcAccessibleDocument::Shutdown()
+{
+ for (auto iter = mCache.Iter(); !iter.Done(); iter.Next()) {
+ iter.Data()->Shutdown();
+ iter.Remove();
+ }
+ xpcAccessibleGeneric::Shutdown();
+}
+
+xpcAccessibleGeneric*
+a11y::ToXPC(AccessibleOrProxy aAcc)
+{
+ if (aAcc.IsNull()) {
+ return nullptr;
+ }
+
+ if (aAcc.IsAccessible()) {
+ return ToXPC(aAcc.AsAccessible());
+ }
+
+ xpcAccessibleDocument* doc = ToXPCDocument(aAcc.AsProxy()->Document());
+ return doc->GetXPCAccessible(aAcc.AsProxy());
+}
diff --git a/accessible/xpcom/xpcAccessibleDocument.h b/accessible/xpcom/xpcAccessibleDocument.h
new file mode 100644
index 0000000000..651fe22552
--- /dev/null
+++ b/accessible/xpcom/xpcAccessibleDocument.h
@@ -0,0 +1,150 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=2 et sw=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef mozilla_a11y_xpcAccessibleDocument_h_
+#define mozilla_a11y_xpcAccessibleDocument_h_
+
+#include "nsIAccessibleDocument.h"
+
+#include "DocAccessible.h"
+#include "nsAccessibilityService.h"
+#include "xpcAccessibleApplication.h"
+#include "xpcAccessibleHyperText.h"
+
+namespace mozilla {
+namespace a11y {
+
+/**
+ * XPCOM wrapper around DocAccessible class.
+ */
+class xpcAccessibleDocument : public xpcAccessibleHyperText,
+ public nsIAccessibleDocument
+{
+public:
+ explicit xpcAccessibleDocument(DocAccessible* aIntl) :
+ xpcAccessibleHyperText(aIntl), mCache(kDefaultCacheLength), mRemote(false) { }
+
+ xpcAccessibleDocument(ProxyAccessible* aProxy, uint32_t aInterfaces) :
+ xpcAccessibleHyperText(aProxy, aInterfaces), mCache(kDefaultCacheLength),
+ mRemote(true) {}
+
+ NS_DECL_ISUPPORTS_INHERITED
+ NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(xpcAccessibleDocument,
+ xpcAccessibleGeneric)
+
+ // nsIAccessibleDocument
+ NS_IMETHOD GetURL(nsAString& aURL) final override;
+ NS_IMETHOD GetTitle(nsAString& aTitle) final override;
+ NS_IMETHOD GetMimeType(nsAString& aType) final override;
+ NS_IMETHOD GetDocType(nsAString& aType) final override;
+ NS_IMETHOD GetDOMDocument(nsIDOMDocument** aDOMDocument) final override;
+ NS_IMETHOD GetWindow(mozIDOMWindowProxy** aDOMWindow) final override;
+ NS_IMETHOD GetParentDocument(nsIAccessibleDocument** aDocument)
+ final override;
+ NS_IMETHOD GetChildDocumentCount(uint32_t* aCount) final override;
+ NS_IMETHOD GetChildDocumentAt(uint32_t aIndex,
+ nsIAccessibleDocument** aDocument)
+ final override;
+ NS_IMETHOD GetVirtualCursor(nsIAccessiblePivot** aVirtualCursor)
+ final override;
+
+ /**
+ * Return XPCOM wrapper for the internal accessible.
+ */
+ xpcAccessibleGeneric* GetAccessible(Accessible* aAccessible);
+ xpcAccessibleGeneric* GetXPCAccessible(ProxyAccessible* aProxy);
+
+ virtual void Shutdown() override;
+
+protected:
+ virtual ~xpcAccessibleDocument() {}
+
+private:
+ DocAccessible* Intl()
+ {
+ if (Accessible* acc = mIntl.AsAccessible()) {
+ return acc->AsDoc();
+ }
+
+ return nullptr;
+ }
+
+ void NotifyOfShutdown(Accessible* aAccessible)
+ {
+ MOZ_ASSERT(!mRemote);
+ xpcAccessibleGeneric* xpcAcc = mCache.GetWeak(aAccessible);
+ if (xpcAcc)
+ xpcAcc->Shutdown();
+
+ mCache.Remove(aAccessible);
+ }
+
+ void NotifyOfShutdown(ProxyAccessible* aProxy)
+ {
+ MOZ_ASSERT(mRemote);
+ xpcAccessibleGeneric* acc = mCache.GetWeak(aProxy);
+ if (acc) {
+ acc->Shutdown();
+ }
+
+ mCache.Remove(aProxy);
+ }
+
+ friend class DocManager;
+ friend class DocAccessible;
+ friend class ProxyAccessible;
+ friend class ProxyAccessibleBase<ProxyAccessible>;
+
+ xpcAccessibleDocument(const xpcAccessibleDocument&) = delete;
+ xpcAccessibleDocument& operator =(const xpcAccessibleDocument&) = delete;
+
+ nsRefPtrHashtable<nsPtrHashKey<const void>, xpcAccessibleGeneric> mCache;
+ bool mRemote;
+};
+
+inline xpcAccessibleGeneric*
+ToXPC(Accessible* aAccessible)
+{
+ if (!aAccessible)
+ return nullptr;
+
+ if (aAccessible->IsApplication())
+ return XPCApplicationAcc();
+
+ xpcAccessibleDocument* xpcDoc =
+ GetAccService()->GetXPCDocument(aAccessible->Document());
+ return xpcDoc ? xpcDoc->GetAccessible(aAccessible) : nullptr;
+}
+
+xpcAccessibleGeneric* ToXPC(AccessibleOrProxy aAcc);
+
+inline xpcAccessibleHyperText*
+ToXPCText(HyperTextAccessible* aAccessible)
+{
+ if (!aAccessible)
+ return nullptr;
+
+ xpcAccessibleDocument* xpcDoc =
+ GetAccService()->GetXPCDocument(aAccessible->Document());
+ return static_cast<xpcAccessibleHyperText*>(xpcDoc->GetAccessible(aAccessible));
+}
+
+inline xpcAccessibleDocument*
+ToXPCDocument(DocAccessible* aAccessible)
+{
+ return GetAccService()->GetXPCDocument(aAccessible);
+}
+
+inline xpcAccessibleDocument*
+ToXPCDocument(DocAccessibleParent* aAccessible)
+{
+ return GetAccService()->GetXPCDocument(aAccessible);
+}
+
+} // namespace a11y
+} // namespace mozilla
+
+#endif
diff --git a/accessible/xpcom/xpcAccessibleGeneric.cpp b/accessible/xpcom/xpcAccessibleGeneric.cpp
new file mode 100644
index 0000000000..5793b8a2ef
--- /dev/null
+++ b/accessible/xpcom/xpcAccessibleGeneric.cpp
@@ -0,0 +1,46 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=2 et sw=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "xpcAccessibleGeneric.h"
+
+using namespace mozilla::a11y;
+
+////////////////////////////////////////////////////////////////////////////////
+// nsISupports and cycle collection
+
+NS_IMPL_CYCLE_COLLECTION_0(xpcAccessibleGeneric)
+
+NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(xpcAccessibleGeneric)
+ NS_INTERFACE_MAP_ENTRY(nsIAccessible)
+ NS_INTERFACE_MAP_ENTRY_CONDITIONAL(nsIAccessibleSelectable,
+ mSupportedIfaces & eSelectable)
+ NS_INTERFACE_MAP_ENTRY_CONDITIONAL(nsIAccessibleValue,
+ mSupportedIfaces & eValue)
+ NS_INTERFACE_MAP_ENTRY_CONDITIONAL(nsIAccessibleHyperLink,
+ mSupportedIfaces & eHyperLink)
+ NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIAccessible)
+NS_INTERFACE_MAP_END
+
+NS_IMPL_CYCLE_COLLECTING_ADDREF(xpcAccessibleGeneric)
+NS_IMPL_CYCLE_COLLECTING_RELEASE(xpcAccessibleGeneric)
+
+////////////////////////////////////////////////////////////////////////////////
+// nsIAccessible
+
+Accessible*
+xpcAccessibleGeneric::ToInternalAccessible() const
+{
+ return mIntl.AsAccessible();
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// xpcAccessibleGeneric
+
+void
+xpcAccessibleGeneric::Shutdown()
+{
+ mIntl = nullptr;
+}
diff --git a/accessible/xpcom/xpcAccessibleGeneric.h b/accessible/xpcom/xpcAccessibleGeneric.h
new file mode 100644
index 0000000000..da51d27285
--- /dev/null
+++ b/accessible/xpcom/xpcAccessibleGeneric.h
@@ -0,0 +1,110 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=2 et sw=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef mozilla_a11y_xpcAccessibleGeneric_h_
+#define mozilla_a11y_xpcAccessibleGeneric_h_
+
+#include "xpcAccessible.h"
+#include "xpcAccessibleHyperLink.h"
+#include "xpcAccessibleSelectable.h"
+#include "xpcAccessibleValue.h"
+
+#include "Accessible.h"
+#include "AccessibleOrProxy.h"
+
+namespace mozilla {
+namespace a11y {
+
+/**
+ * XPCOM wrapper around Accessible class.
+ */
+class xpcAccessibleGeneric : public xpcAccessible,
+ public xpcAccessibleHyperLink,
+ public xpcAccessibleSelectable,
+ public xpcAccessibleValue
+{
+public:
+ explicit xpcAccessibleGeneric(Accessible* aInternal) :
+ mIntl(aInternal), mSupportedIfaces(0)
+ {
+ if (aInternal->IsSelect())
+ mSupportedIfaces |= eSelectable;
+ if (aInternal->HasNumericValue())
+ mSupportedIfaces |= eValue;
+ if (aInternal->IsLink())
+ mSupportedIfaces |= eHyperLink;
+ }
+
+ xpcAccessibleGeneric(ProxyAccessible* aProxy, uint8_t aInterfaces) :
+ mIntl(aProxy), mSupportedIfaces(aInterfaces) {}
+
+ NS_DECL_CYCLE_COLLECTING_ISUPPORTS
+ NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(xpcAccessibleGeneric, nsIAccessible)
+
+ // nsIAccessible
+ virtual Accessible* ToInternalAccessible() const final override;
+
+ // xpcAccessibleGeneric
+ virtual void Shutdown();
+
+protected:
+ virtual ~xpcAccessibleGeneric() {}
+
+ AccessibleOrProxy mIntl;
+
+ enum {
+ eSelectable = 1 << 0,
+ eValue = 1 << 1,
+ eHyperLink = 1 << 2,
+ eText = 1 << 3
+ };
+ uint8_t mSupportedIfaces;
+
+private:
+ friend class Accessible;
+ friend class xpcAccessible;
+ friend class xpcAccessibleHyperLink;
+ friend class xpcAccessibleSelectable;
+ friend class xpcAccessibleValue;
+
+ xpcAccessibleGeneric(const xpcAccessibleGeneric&) = delete;
+ xpcAccessibleGeneric& operator =(const xpcAccessibleGeneric&) = delete;
+};
+
+inline Accessible*
+xpcAccessible::Intl()
+{
+ return static_cast<xpcAccessibleGeneric*>(this)->mIntl.AsAccessible();
+}
+
+inline AccessibleOrProxy
+xpcAccessible::IntlGeneric()
+{
+ return static_cast<xpcAccessibleGeneric*>(this)->mIntl;
+}
+
+inline AccessibleOrProxy
+xpcAccessibleHyperLink::Intl()
+{
+ return static_cast<xpcAccessibleGeneric*>(this)->mIntl;
+}
+
+inline Accessible*
+xpcAccessibleSelectable::Intl()
+{
+ return static_cast<xpcAccessibleGeneric*>(this)->mIntl.AsAccessible();
+}
+
+inline AccessibleOrProxy
+xpcAccessibleValue::Intl()
+{
+ return static_cast<xpcAccessibleGeneric*>(this)->mIntl;
+}
+
+} // namespace a11y
+} // namespace mozilla
+
+#endif
diff --git a/accessible/xpcom/xpcAccessibleHyperLink.cpp b/accessible/xpcom/xpcAccessibleHyperLink.cpp
new file mode 100644
index 0000000000..644f355f07
--- /dev/null
+++ b/accessible/xpcom/xpcAccessibleHyperLink.cpp
@@ -0,0 +1,180 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=2 et sw=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "Accessible-inl.h"
+#include "xpcAccessibleDocument.h"
+#include "nsNetUtil.h"
+
+using namespace mozilla::a11y;
+
+NS_IMETHODIMP
+xpcAccessibleHyperLink::GetStartIndex(int32_t* aStartIndex)
+{
+ NS_ENSURE_ARG_POINTER(aStartIndex);
+ *aStartIndex = 0;
+
+ if (Intl().IsNull())
+ return NS_ERROR_FAILURE;
+
+ if (Intl().IsAccessible()) {
+ *aStartIndex = Intl().AsAccessible()->StartOffset();
+ } else {
+#if defined(XP_WIN)
+ return NS_ERROR_NOT_IMPLEMENTED;
+#else
+ bool isIndexValid = false;
+ uint32_t startOffset = Intl().AsProxy()->StartOffset(&isIndexValid);
+ if (!isIndexValid)
+ return NS_ERROR_FAILURE;
+
+ *aStartIndex = startOffset;
+#endif
+ }
+
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+xpcAccessibleHyperLink::GetEndIndex(int32_t* aEndIndex)
+{
+ NS_ENSURE_ARG_POINTER(aEndIndex);
+ *aEndIndex = 0;
+
+ if (Intl().IsNull())
+ return NS_ERROR_FAILURE;
+
+ if (Intl().IsAccessible()) {
+ *aEndIndex = Intl().AsAccessible()->EndOffset();
+ } else {
+#if defined(XP_WIN)
+ return NS_ERROR_NOT_IMPLEMENTED;
+#else
+ bool isIndexValid = false;
+ uint32_t endOffset = Intl().AsProxy()->EndOffset(&isIndexValid);
+ if (!isIndexValid)
+ return NS_ERROR_FAILURE;
+
+ *aEndIndex = endOffset;
+#endif
+ }
+
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+xpcAccessibleHyperLink::GetAnchorCount(int32_t* aAnchorCount)
+{
+ NS_ENSURE_ARG_POINTER(aAnchorCount);
+ *aAnchorCount = 0;
+
+ if (Intl().IsNull())
+ return NS_ERROR_FAILURE;
+
+ if (Intl().IsAccessible()) {
+ *aAnchorCount = Intl().AsAccessible()->AnchorCount();
+ } else {
+#if defined(XP_WIN)
+ return NS_ERROR_NOT_IMPLEMENTED;
+#else
+ bool isCountValid = false;
+ uint32_t anchorCount = Intl().AsProxy()->AnchorCount(&isCountValid);
+ if (!isCountValid)
+ return NS_ERROR_FAILURE;
+
+ *aAnchorCount = anchorCount;
+#endif
+ }
+
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+xpcAccessibleHyperLink::GetURI(int32_t aIndex, nsIURI** aURI)
+{
+ NS_ENSURE_ARG_POINTER(aURI);
+
+ if (Intl().IsNull())
+ return NS_ERROR_FAILURE;
+
+ if (aIndex < 0)
+ return NS_ERROR_INVALID_ARG;
+
+ if (Intl().IsAccessible()) {
+ if (aIndex >= static_cast<int32_t>(Intl().AsAccessible()->AnchorCount()))
+ return NS_ERROR_INVALID_ARG;
+
+ RefPtr<nsIURI>(Intl().AsAccessible()->AnchorURIAt(aIndex)).forget(aURI);
+ } else {
+#if defined(XP_WIN)
+ return NS_ERROR_NOT_IMPLEMENTED;
+#else
+ nsCString spec;
+ bool isURIValid = false;
+ Intl().AsProxy()->AnchorURIAt(aIndex, spec, &isURIValid);
+ if (!isURIValid)
+ return NS_ERROR_FAILURE;
+
+ nsCOMPtr<nsIURI> uri;
+ nsresult rv = NS_NewURI(getter_AddRefs(uri), spec);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ uri.forget(aURI);
+#endif
+ }
+
+ return NS_OK;
+}
+
+
+NS_IMETHODIMP
+xpcAccessibleHyperLink::GetAnchor(int32_t aIndex, nsIAccessible** aAccessible)
+{
+ NS_ENSURE_ARG_POINTER(aAccessible);
+ *aAccessible = nullptr;
+
+ if (Intl().IsNull())
+ return NS_ERROR_FAILURE;
+
+ if (aIndex < 0)
+ return NS_ERROR_INVALID_ARG;
+
+ if (Intl().IsAccessible()) {
+ if (aIndex >= static_cast<int32_t>(Intl().AsAccessible()->AnchorCount()))
+ return NS_ERROR_INVALID_ARG;
+
+ NS_IF_ADDREF(*aAccessible = ToXPC(Intl().AsAccessible()->AnchorAt(aIndex)));
+ } else {
+#if defined(XP_WIN)
+ return NS_ERROR_NOT_IMPLEMENTED;
+#else
+ NS_IF_ADDREF(*aAccessible = ToXPC(Intl().AsProxy()->AnchorAt(aIndex)));
+#endif
+ }
+
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+xpcAccessibleHyperLink::GetValid(bool* aValid)
+{
+ NS_ENSURE_ARG_POINTER(aValid);
+ *aValid = false;
+
+ if (Intl().IsNull())
+ return NS_ERROR_FAILURE;
+
+ if (Intl().IsAccessible()) {
+ *aValid = Intl().AsAccessible()->IsLinkValid();
+ } else {
+#if defined(XP_WIN)
+ return NS_ERROR_NOT_IMPLEMENTED;
+#else
+ *aValid = Intl().AsProxy()->IsLinkValid();
+#endif
+ }
+
+ return NS_OK;
+}
diff --git a/accessible/xpcom/xpcAccessibleHyperLink.h b/accessible/xpcom/xpcAccessibleHyperLink.h
new file mode 100644
index 0000000000..0f986cfd47
--- /dev/null
+++ b/accessible/xpcom/xpcAccessibleHyperLink.h
@@ -0,0 +1,48 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=2 et sw=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef mozilla_a11y_xpcAccessibleHyperLink_h_
+#define mozilla_a11y_xpcAccessibleHyperLink_h_
+
+#include "nsIAccessibleHyperLink.h"
+
+class nsIAccessible;
+
+namespace mozilla {
+namespace a11y {
+
+class Accessible;
+
+/**
+ * XPCOM nsIAccessibleHyperLink implementation, used by xpcAccessibleGeneric
+ * class.
+ */
+class xpcAccessibleHyperLink : public nsIAccessibleHyperLink
+{
+public:
+ NS_IMETHOD GetAnchorCount(int32_t* aAnchorCount) final override;
+ NS_IMETHOD GetStartIndex(int32_t* aStartIndex) final override;
+ NS_IMETHOD GetEndIndex(int32_t* aEndIndex) final override;
+ NS_IMETHOD GetURI(int32_t aIndex, nsIURI** aURI) final override;
+ NS_IMETHOD GetAnchor(int32_t aIndex, nsIAccessible** aAccessible)
+ final override;
+ NS_IMETHOD GetValid(bool* aValid) final override;
+
+protected:
+ xpcAccessibleHyperLink() { }
+ virtual ~xpcAccessibleHyperLink() {}
+
+private:
+ xpcAccessibleHyperLink(const xpcAccessibleHyperLink&) = delete;
+ xpcAccessibleHyperLink& operator =(const xpcAccessibleHyperLink&) = delete;
+
+ AccessibleOrProxy Intl();
+};
+
+} // namespace a11y
+} // namespace mozilla
+
+#endif
diff --git a/accessible/xpcom/xpcAccessibleHyperText.cpp b/accessible/xpcom/xpcAccessibleHyperText.cpp
new file mode 100644
index 0000000000..b31544ac7f
--- /dev/null
+++ b/accessible/xpcom/xpcAccessibleHyperText.cpp
@@ -0,0 +1,822 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=2 et sw=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "xpcAccessibleHyperText.h"
+
+#include "Accessible-inl.h"
+#include "HyperTextAccessible-inl.h"
+#include "TextRange.h"
+#include "xpcAccessibleDocument.h"
+#include "xpcAccessibleTextRange.h"
+
+#include "nsIPersistentProperties2.h"
+#include "nsIMutableArray.h"
+
+using namespace mozilla::a11y;
+
+////////////////////////////////////////////////////////////////////////////////
+// nsISupports
+
+NS_INTERFACE_MAP_BEGIN(xpcAccessibleHyperText)
+ NS_INTERFACE_MAP_ENTRY_CONDITIONAL(nsIAccessibleText,
+ mSupportedIfaces & eText)
+ NS_INTERFACE_MAP_ENTRY_CONDITIONAL(nsIAccessibleEditableText,
+ mSupportedIfaces & eText)
+ NS_INTERFACE_MAP_ENTRY_CONDITIONAL(nsIAccessibleHyperText,
+ mSupportedIfaces & eText)
+NS_INTERFACE_MAP_END_INHERITING(xpcAccessibleGeneric)
+
+NS_IMPL_ADDREF_INHERITED(xpcAccessibleHyperText, xpcAccessibleGeneric)
+NS_IMPL_RELEASE_INHERITED(xpcAccessibleHyperText, xpcAccessibleGeneric)
+
+////////////////////////////////////////////////////////////////////////////////
+// nsIAccessibleText
+
+NS_IMETHODIMP
+xpcAccessibleHyperText::GetCharacterCount(int32_t* aCharacterCount)
+{
+ NS_ENSURE_ARG_POINTER(aCharacterCount);
+ *aCharacterCount = 0;
+
+ if (mIntl.IsNull())
+ return NS_ERROR_FAILURE;
+
+ if (mIntl.IsAccessible()) {
+ *aCharacterCount = Intl()->CharacterCount();
+ } else {
+#if defined(XP_WIN)
+ return NS_ERROR_NOT_IMPLEMENTED;
+#else
+ *aCharacterCount = mIntl.AsProxy()->CharacterCount();
+#endif
+ }
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+xpcAccessibleHyperText::GetText(int32_t aStartOffset, int32_t aEndOffset,
+ nsAString& aText)
+{
+ aText.Truncate();
+
+ if (mIntl.IsNull())
+ return NS_ERROR_FAILURE;
+
+ if (mIntl.IsAccessible()) {
+ Intl()->TextSubstring(aStartOffset, aEndOffset, aText);
+ } else {
+ nsString text;
+ mIntl.AsProxy()->TextSubstring(aStartOffset, aEndOffset, text);
+ aText = text;
+ }
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+xpcAccessibleHyperText::GetTextBeforeOffset(int32_t aOffset,
+ AccessibleTextBoundary aBoundaryType,
+ int32_t* aStartOffset,
+ int32_t* aEndOffset,
+ nsAString& aText)
+{
+ NS_ENSURE_ARG_POINTER(aStartOffset);
+ NS_ENSURE_ARG_POINTER(aEndOffset);
+ *aStartOffset = *aEndOffset = 0;
+ aText.Truncate();
+
+ if (mIntl.IsNull())
+ return NS_ERROR_FAILURE;
+
+ if (mIntl.IsAccessible()) {
+ Intl()->TextBeforeOffset(aOffset, aBoundaryType, aStartOffset, aEndOffset,
+ aText);
+ } else {
+ nsString text;
+ mIntl.AsProxy()->GetTextBeforeOffset(aOffset, aBoundaryType, text,
+ aStartOffset, aEndOffset);
+ aText = text;
+ }
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+xpcAccessibleHyperText::GetTextAtOffset(int32_t aOffset,
+ AccessibleTextBoundary aBoundaryType,
+ int32_t* aStartOffset,
+ int32_t* aEndOffset, nsAString& aText)
+{
+ NS_ENSURE_ARG_POINTER(aStartOffset);
+ NS_ENSURE_ARG_POINTER(aEndOffset);
+ *aStartOffset = *aEndOffset = 0;
+ aText.Truncate();
+
+ if (mIntl.IsNull())
+ return NS_ERROR_FAILURE;
+
+ if (mIntl.IsAccessible()) {
+ Intl()->TextAtOffset(aOffset, aBoundaryType, aStartOffset, aEndOffset,
+ aText);
+ } else {
+ nsString text;
+ mIntl.AsProxy()->GetTextAtOffset(aOffset, aBoundaryType, text,
+ aStartOffset, aEndOffset);
+ aText = text;
+ }
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+xpcAccessibleHyperText::GetTextAfterOffset(int32_t aOffset,
+ AccessibleTextBoundary aBoundaryType,
+ int32_t* aStartOffset,
+ int32_t* aEndOffset, nsAString& aText)
+{
+ NS_ENSURE_ARG_POINTER(aStartOffset);
+ NS_ENSURE_ARG_POINTER(aEndOffset);
+ *aStartOffset = *aEndOffset = 0;
+ aText.Truncate();
+
+ if (mIntl.IsNull())
+ return NS_ERROR_FAILURE;
+
+ if (mIntl.IsAccessible()) {
+ Intl()->TextAfterOffset(aOffset, aBoundaryType, aStartOffset, aEndOffset,
+ aText);
+ } else {
+ nsString text;
+ mIntl.AsProxy()->GetTextAfterOffset(aOffset, aBoundaryType, text,
+ aStartOffset, aEndOffset);
+ aText = text;
+ }
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+xpcAccessibleHyperText::GetCharacterAtOffset(int32_t aOffset,
+ char16_t* aCharacter)
+{
+ NS_ENSURE_ARG_POINTER(aCharacter);
+ *aCharacter = L'\0';
+
+ if (mIntl.IsNull())
+ return NS_ERROR_FAILURE;
+
+ if (mIntl.IsAccessible()) {
+ *aCharacter = Intl()->CharAt(aOffset);
+ } else {
+#if defined(XP_WIN)
+ return NS_ERROR_NOT_IMPLEMENTED;
+#else
+ *aCharacter = mIntl.AsProxy()->CharAt(aOffset);
+#endif
+ }
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+xpcAccessibleHyperText::GetTextAttributes(bool aIncludeDefAttrs,
+ int32_t aOffset,
+ int32_t* aStartOffset,
+ int32_t* aEndOffset,
+ nsIPersistentProperties** aAttributes)
+{
+ NS_ENSURE_ARG_POINTER(aStartOffset);
+ NS_ENSURE_ARG_POINTER(aEndOffset);
+ NS_ENSURE_ARG_POINTER(aAttributes);
+ *aStartOffset = *aEndOffset = 0;
+ *aAttributes = nullptr;
+
+ if (mIntl.IsNull())
+ return NS_ERROR_FAILURE;
+
+ nsCOMPtr<nsIPersistentProperties> props;
+ if (mIntl.IsAccessible()) {
+ props = Intl()->TextAttributes(aIncludeDefAttrs, aOffset, aStartOffset,
+ aEndOffset);
+ } else {
+#if defined(XP_WIN)
+ return NS_ERROR_NOT_IMPLEMENTED;
+#else
+ AutoTArray<Attribute, 10> attrs;
+ mIntl.AsProxy()->TextAttributes(aIncludeDefAttrs, aOffset, &attrs,
+ aStartOffset, aEndOffset);
+ uint32_t attrCount = attrs.Length();
+ nsAutoString unused;
+ for (uint32_t i = 0; i < attrCount; i++) {
+ props->SetStringProperty(attrs[i].Name(), attrs[i].Value(), unused);
+ }
+#endif
+ }
+ props.forget(aAttributes);
+
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+xpcAccessibleHyperText::GetDefaultTextAttributes(nsIPersistentProperties** aAttributes)
+{
+ NS_ENSURE_ARG_POINTER(aAttributes);
+ *aAttributes = nullptr;
+
+ if (mIntl.IsNull())
+ return NS_ERROR_FAILURE;
+
+ nsCOMPtr<nsIPersistentProperties> props;
+ if (mIntl.IsAccessible()) {
+ props = Intl()->DefaultTextAttributes();
+ } else {
+#if defined(XP_WIN)
+ return NS_ERROR_NOT_IMPLEMENTED;
+#else
+ AutoTArray<Attribute, 10> attrs;
+ mIntl.AsProxy()->DefaultTextAttributes(&attrs);
+ uint32_t attrCount = attrs.Length();
+ nsAutoString unused;
+ for (uint32_t i = 0; i < attrCount; i++) {
+ props->SetStringProperty(attrs[i].Name(), attrs[i].Value(), unused);
+ }
+#endif
+ }
+ props.forget(aAttributes);
+
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+xpcAccessibleHyperText::GetCharacterExtents(int32_t aOffset,
+ int32_t* aX, int32_t* aY,
+ int32_t* aWidth, int32_t* aHeight,
+ uint32_t aCoordType)
+{
+ NS_ENSURE_ARG_POINTER(aX);
+ NS_ENSURE_ARG_POINTER(aY);
+ NS_ENSURE_ARG_POINTER(aWidth);
+ NS_ENSURE_ARG_POINTER(aHeight);
+ *aX = *aY = *aWidth = *aHeight;
+
+ if (mIntl.IsNull())
+ return NS_ERROR_FAILURE;
+
+ nsIntRect rect;
+ if (mIntl.IsAccessible()) {
+ rect = Intl()->CharBounds(aOffset, aCoordType);
+ } else {
+#if defined(XP_WIN)
+ return NS_ERROR_NOT_IMPLEMENTED;
+#else
+ rect = mIntl.AsProxy()->CharBounds(aOffset, aCoordType);
+#endif
+ }
+ *aX = rect.x; *aY = rect.y;
+ *aWidth = rect.width; *aHeight = rect.height;
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+xpcAccessibleHyperText::GetRangeExtents(int32_t aStartOffset, int32_t aEndOffset,
+ int32_t* aX, int32_t* aY,
+ int32_t* aWidth, int32_t* aHeight,
+ uint32_t aCoordType)
+{
+ NS_ENSURE_ARG_POINTER(aX);
+ NS_ENSURE_ARG_POINTER(aY);
+ NS_ENSURE_ARG_POINTER(aWidth);
+ NS_ENSURE_ARG_POINTER(aHeight);
+ *aX = *aY = *aWidth = *aHeight = 0;
+
+ if (mIntl.IsNull())
+ return NS_ERROR_FAILURE;
+
+ nsIntRect rect;
+ if (mIntl.IsAccessible()) {
+ rect = Intl()->TextBounds(aStartOffset, aEndOffset, aCoordType);
+ } else {
+#if defined(XP_WIN)
+ return NS_ERROR_NOT_IMPLEMENTED;
+#else
+ rect = mIntl.AsProxy()->TextBounds(aStartOffset, aEndOffset, aCoordType);
+#endif
+ }
+ *aX = rect.x; *aY = rect.y;
+ *aWidth = rect.width; *aHeight = rect.height;
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+xpcAccessibleHyperText::GetOffsetAtPoint(int32_t aX, int32_t aY,
+ uint32_t aCoordType, int32_t* aOffset)
+{
+ NS_ENSURE_ARG_POINTER(aOffset);
+ *aOffset = -1;
+
+ if (mIntl.IsNull())
+ return NS_ERROR_FAILURE;
+
+ if (mIntl.IsAccessible()) {
+ *aOffset = Intl()->OffsetAtPoint(aX, aY, aCoordType);
+ } else {
+#if defined(XP_WIN)
+ return NS_ERROR_NOT_IMPLEMENTED;
+#else
+ *aOffset = mIntl.AsProxy()->OffsetAtPoint(aX, aY, aCoordType);
+#endif
+ }
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+xpcAccessibleHyperText::GetCaretOffset(int32_t* aCaretOffset)
+{
+ NS_ENSURE_ARG_POINTER(aCaretOffset);
+ *aCaretOffset = -1;
+
+ if (mIntl.IsNull())
+ return NS_ERROR_FAILURE;
+
+ if (mIntl.IsAccessible()) {
+ *aCaretOffset = Intl()->CaretOffset();
+ } else {
+ *aCaretOffset = mIntl.AsProxy()->CaretOffset();
+ }
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+xpcAccessibleHyperText::SetCaretOffset(int32_t aCaretOffset)
+{
+ if (mIntl.IsNull())
+ return NS_ERROR_FAILURE;
+
+ if (mIntl.IsAccessible()) {
+ Intl()->SetCaretOffset(aCaretOffset);
+ } else {
+ mIntl.AsProxy()->SetCaretOffset(aCaretOffset);
+ }
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+xpcAccessibleHyperText::GetSelectionCount(int32_t* aSelectionCount)
+{
+ NS_ENSURE_ARG_POINTER(aSelectionCount);
+ *aSelectionCount = 0;
+
+ if (mIntl.IsNull())
+ return NS_ERROR_FAILURE;
+
+ if (mIntl.IsAccessible()) {
+ *aSelectionCount = Intl()->SelectionCount();
+ } else {
+#if defined(XP_WIN)
+ return NS_ERROR_NOT_IMPLEMENTED;
+#else
+ *aSelectionCount = mIntl.AsProxy()->SelectionCount();
+#endif
+ }
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+xpcAccessibleHyperText::GetSelectionBounds(int32_t aSelectionNum,
+ int32_t* aStartOffset,
+ int32_t* aEndOffset)
+{
+ NS_ENSURE_ARG_POINTER(aStartOffset);
+ NS_ENSURE_ARG_POINTER(aEndOffset);
+ *aStartOffset = *aEndOffset = 0;
+
+ if (mIntl.IsNull())
+ return NS_ERROR_FAILURE;
+
+ if (aSelectionNum < 0)
+ return NS_ERROR_INVALID_ARG;
+
+ if (mIntl.IsAccessible()) {
+ if (aSelectionNum >= Intl()->SelectionCount())
+ return NS_ERROR_INVALID_ARG;
+
+ Intl()->SelectionBoundsAt(aSelectionNum, aStartOffset, aEndOffset);
+ } else {
+#if defined(XP_WIN)
+ return NS_ERROR_NOT_IMPLEMENTED;
+#else
+ nsString unused;
+ mIntl.AsProxy()->SelectionBoundsAt(aSelectionNum, unused, aStartOffset,
+ aEndOffset);
+#endif
+ }
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+xpcAccessibleHyperText::SetSelectionBounds(int32_t aSelectionNum,
+ int32_t aStartOffset,
+ int32_t aEndOffset)
+{
+ if (mIntl.IsNull())
+ return NS_ERROR_FAILURE;
+
+ if (aSelectionNum < 0)
+ return NS_ERROR_INVALID_ARG;
+
+ if (mIntl.IsAccessible()) {
+ if (!Intl()->SetSelectionBoundsAt(aSelectionNum, aStartOffset,
+ aEndOffset)) {
+ return NS_ERROR_INVALID_ARG;
+ }
+ } else {
+#if defined(XP_WIN)
+ return NS_ERROR_NOT_IMPLEMENTED;
+#else
+ if (!mIntl.AsProxy()->SetSelectionBoundsAt(aSelectionNum, aStartOffset,
+ aEndOffset)) {
+ return NS_ERROR_INVALID_ARG;
+ }
+#endif
+ }
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+xpcAccessibleHyperText::AddSelection(int32_t aStartOffset, int32_t aEndOffset)
+{
+ if (mIntl.IsNull())
+ return NS_ERROR_FAILURE;
+
+ if (mIntl.IsAccessible()) {
+ Intl()->AddToSelection(aStartOffset, aEndOffset);
+ } else {
+ mIntl.AsProxy()->AddToSelection(aStartOffset, aEndOffset);
+ }
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+xpcAccessibleHyperText::RemoveSelection(int32_t aSelectionNum)
+{
+ if (mIntl.IsNull())
+ return NS_ERROR_FAILURE;
+
+ if (mIntl.IsAccessible()) {
+ Intl()->RemoveFromSelection(aSelectionNum);
+ } else {
+ mIntl.AsProxy()->RemoveFromSelection(aSelectionNum);
+ }
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+xpcAccessibleHyperText::ScrollSubstringTo(int32_t aStartOffset,
+ int32_t aEndOffset,
+ uint32_t aScrollType)
+{
+ if (mIntl.IsNull())
+ return NS_ERROR_FAILURE;
+
+ if (mIntl.IsAccessible()) {
+ Intl()->ScrollSubstringTo(aStartOffset, aEndOffset, aScrollType);
+ } else {
+ mIntl.AsProxy()->ScrollSubstringTo(aStartOffset, aEndOffset, aScrollType);
+ }
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+xpcAccessibleHyperText::ScrollSubstringToPoint(int32_t aStartOffset,
+ int32_t aEndOffset,
+ uint32_t aCoordinateType,
+ int32_t aX, int32_t aY)
+{
+ if (mIntl.IsNull())
+ return NS_ERROR_FAILURE;
+
+ if (mIntl.IsAccessible()) {
+ Intl()->ScrollSubstringToPoint(aStartOffset, aEndOffset, aCoordinateType,
+ aX, aY);
+ } else {
+ mIntl.AsProxy()->ScrollSubstringToPoint(aStartOffset, aEndOffset,
+ aCoordinateType, aX, aY);
+ }
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+xpcAccessibleHyperText::GetEnclosingRange(nsIAccessibleTextRange** aRange)
+{
+ NS_ENSURE_ARG_POINTER(aRange);
+ *aRange = nullptr;
+
+ if (!Intl())
+ return NS_ERROR_FAILURE;
+
+ RefPtr<xpcAccessibleTextRange> range = new xpcAccessibleTextRange;
+ Intl()->EnclosingRange(range->mRange);
+ NS_ASSERTION(range->mRange.IsValid(),
+ "Should always have an enclosing range!");
+
+ range.forget(aRange);
+
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+xpcAccessibleHyperText::GetSelectionRanges(nsIArray** aRanges)
+{
+ NS_ENSURE_ARG_POINTER(aRanges);
+ *aRanges = nullptr;
+
+ if (!Intl())
+ return NS_ERROR_FAILURE;
+
+ nsresult rv = NS_OK;
+ nsCOMPtr<nsIMutableArray> xpcRanges =
+ do_CreateInstance(NS_ARRAY_CONTRACTID, &rv);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ AutoTArray<TextRange, 1> ranges;
+ Intl()->SelectionRanges(&ranges);
+ uint32_t len = ranges.Length();
+ for (uint32_t idx = 0; idx < len; idx++)
+ xpcRanges->AppendElement(new xpcAccessibleTextRange(Move(ranges[idx])),
+ false);
+
+ xpcRanges.forget(aRanges);
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+xpcAccessibleHyperText::GetVisibleRanges(nsIArray** aRanges)
+{
+ NS_ENSURE_ARG_POINTER(aRanges);
+ *aRanges = nullptr;
+
+ if (!Intl())
+ return NS_ERROR_FAILURE;
+
+ nsresult rv = NS_OK;
+ nsCOMPtr<nsIMutableArray> xpcRanges =
+ do_CreateInstance(NS_ARRAY_CONTRACTID, &rv);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ nsTArray<TextRange> ranges;
+ Intl()->VisibleRanges(&ranges);
+ uint32_t len = ranges.Length();
+ for (uint32_t idx = 0; idx < len; idx++)
+ xpcRanges->AppendElement(new xpcAccessibleTextRange(Move(ranges[idx])),
+ false);
+
+ xpcRanges.forget(aRanges);
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+xpcAccessibleHyperText::GetRangeByChild(nsIAccessible* aChild,
+ nsIAccessibleTextRange** aRange)
+{
+ NS_ENSURE_ARG_POINTER(aRange);
+ *aRange = nullptr;
+
+ if (!Intl())
+ return NS_ERROR_FAILURE;
+
+ Accessible* child = aChild->ToInternalAccessible();
+ if (child) {
+ RefPtr<xpcAccessibleTextRange> range = new xpcAccessibleTextRange;
+ Intl()->RangeByChild(child, range->mRange);
+ if (range->mRange.IsValid())
+ range.forget(aRange);
+ }
+
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+xpcAccessibleHyperText::GetRangeAtPoint(int32_t aX, int32_t aY,
+ nsIAccessibleTextRange** aRange)
+{
+ NS_ENSURE_ARG_POINTER(aRange);
+ *aRange = nullptr;
+
+ if (!Intl())
+ return NS_ERROR_FAILURE;
+
+ RefPtr<xpcAccessibleTextRange> range = new xpcAccessibleTextRange;
+ Intl()->RangeAtPoint(aX, aY, range->mRange);
+ if (range->mRange.IsValid())
+ range.forget(aRange);
+
+ return NS_OK;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// nsIAccessibleEditableText
+
+NS_IMETHODIMP
+xpcAccessibleHyperText::SetTextContents(const nsAString& aText)
+{
+ if (mIntl.IsNull())
+ return NS_ERROR_FAILURE;
+
+ if (mIntl.IsAccessible()) {
+ Intl()->ReplaceText(aText);
+ } else {
+#if defined(XP_WIN)
+ return NS_ERROR_NOT_IMPLEMENTED;
+#else
+ nsString text(aText);
+ mIntl.AsProxy()->ReplaceText(text);
+#endif
+ }
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+xpcAccessibleHyperText::InsertText(const nsAString& aText, int32_t aOffset)
+{
+ if (mIntl.IsNull())
+ return NS_ERROR_FAILURE;
+
+ if (mIntl.IsAccessible()) {
+ Intl()->InsertText(aText, aOffset);
+ } else {
+#if defined(XP_WIN)
+ return NS_ERROR_NOT_IMPLEMENTED;
+#else
+ nsString text(aText);
+ mIntl.AsProxy()->InsertText(text, aOffset);
+#endif
+ }
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+xpcAccessibleHyperText::CopyText(int32_t aStartOffset, int32_t aEndOffset)
+{
+ if (mIntl.IsNull())
+ return NS_ERROR_FAILURE;
+
+ if (mIntl.IsAccessible()) {
+ Intl()->CopyText(aStartOffset, aEndOffset);
+ } else {
+#if defined(XP_WIN)
+ return NS_ERROR_NOT_IMPLEMENTED;
+#else
+ mIntl.AsProxy()->CopyText(aStartOffset, aEndOffset);
+#endif
+ }
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+xpcAccessibleHyperText::CutText(int32_t aStartOffset, int32_t aEndOffset)
+{
+ if (mIntl.IsNull())
+ return NS_ERROR_FAILURE;
+
+ if (mIntl.IsAccessible()) {
+ Intl()->CutText(aStartOffset, aEndOffset);
+ } else {
+#if defined(XP_WIN)
+ return NS_ERROR_NOT_IMPLEMENTED;
+#else
+ mIntl.AsProxy()->CutText(aStartOffset, aEndOffset);
+#endif
+ }
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+xpcAccessibleHyperText::DeleteText(int32_t aStartOffset, int32_t aEndOffset)
+{
+ if (mIntl.IsNull())
+ return NS_ERROR_FAILURE;
+
+ if (mIntl.IsAccessible()) {
+ Intl()->DeleteText(aStartOffset, aEndOffset);
+ } else {
+#if defined(XP_WIN)
+ return NS_ERROR_NOT_IMPLEMENTED;
+#else
+ mIntl.AsProxy()->DeleteText(aStartOffset, aEndOffset);
+#endif
+ }
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+xpcAccessibleHyperText::PasteText(int32_t aOffset)
+{
+ if (mIntl.IsNull())
+ return NS_ERROR_FAILURE;
+
+ if (mIntl.IsAccessible()) {
+ Intl()->PasteText(aOffset);
+ } else {
+#if defined(XP_WIN)
+ return NS_ERROR_NOT_IMPLEMENTED;
+#else
+ mIntl.AsProxy()->PasteText(aOffset);
+#endif
+ }
+ return NS_OK;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// nsIAccessibleHyperText
+
+NS_IMETHODIMP
+xpcAccessibleHyperText::GetLinkCount(int32_t* aLinkCount)
+{
+ NS_ENSURE_ARG_POINTER(aLinkCount);
+ *aLinkCount = 0;
+
+ if (mIntl.IsNull())
+ return NS_ERROR_FAILURE;
+
+ if (mIntl.IsAccessible()) {
+ *aLinkCount = Intl()->LinkCount();
+ } else {
+#if defined(XP_WIN)
+ return NS_ERROR_NOT_IMPLEMENTED;
+#else
+ *aLinkCount = mIntl.AsProxy()->LinkCount();
+#endif
+ }
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+xpcAccessibleHyperText::GetLinkAt(int32_t aIndex, nsIAccessibleHyperLink** aLink)
+{
+ NS_ENSURE_ARG_POINTER(aLink);
+ *aLink = nullptr;
+
+ if (mIntl.IsNull())
+ return NS_ERROR_FAILURE;
+
+ if (mIntl.IsAccessible()) {
+ NS_IF_ADDREF(*aLink = ToXPC(Intl()->LinkAt(aIndex)));
+ } else {
+#if defined(XP_WIN)
+ return NS_ERROR_NOT_IMPLEMENTED;
+#else
+ NS_IF_ADDREF(*aLink = ToXPC(mIntl.AsProxy()->LinkAt(aIndex)));
+#endif
+ }
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+xpcAccessibleHyperText::GetLinkIndex(nsIAccessibleHyperLink* aLink,
+ int32_t* aIndex)
+{
+ NS_ENSURE_ARG_POINTER(aLink);
+ NS_ENSURE_ARG_POINTER(aIndex);
+ *aIndex = -1;
+
+ if (mIntl.IsNull())
+ return NS_ERROR_FAILURE;
+
+ nsCOMPtr<nsIAccessible> xpcLink(do_QueryInterface(aLink));
+ if (Accessible* accLink = xpcLink->ToInternalAccessible()) {
+ *aIndex = Intl()->LinkIndexOf(accLink);
+ } else {
+#if defined(XP_WIN)
+ return NS_ERROR_NOT_IMPLEMENTED;
+#else
+ xpcAccessibleHyperText* linkHyperText =
+ static_cast<xpcAccessibleHyperText*>(xpcLink.get());
+ ProxyAccessible* proxyLink = linkHyperText->mIntl.AsProxy();
+ if (proxyLink) {
+ *aIndex = mIntl.AsProxy()->LinkIndexOf(proxyLink);
+ }
+#endif
+ }
+
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+xpcAccessibleHyperText::GetLinkIndexAtOffset(int32_t aOffset,
+ int32_t* aLinkIndex)
+{
+ NS_ENSURE_ARG_POINTER(aLinkIndex);
+ *aLinkIndex = -1; // API says this magic value means 'not found'
+
+ if (mIntl.IsNull())
+ return NS_ERROR_FAILURE;
+
+ if (mIntl.IsAccessible()) {
+ *aLinkIndex = Intl()->LinkIndexAtOffset(aOffset);
+ } else {
+#if defined(XP_WIN)
+ return NS_ERROR_NOT_IMPLEMENTED;
+#else
+ *aLinkIndex = mIntl.AsProxy()->LinkIndexAtOffset(aOffset);
+#endif
+ }
+ return NS_OK;
+}
diff --git a/accessible/xpcom/xpcAccessibleHyperText.h b/accessible/xpcom/xpcAccessibleHyperText.h
new file mode 100644
index 0000000000..fbdac95cf8
--- /dev/null
+++ b/accessible/xpcom/xpcAccessibleHyperText.h
@@ -0,0 +1,62 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=2 et sw=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef mozilla_a11y_xpcAccessibleHyperText_h_
+#define mozilla_a11y_xpcAccessibleHyperText_h_
+
+#include "nsIAccessibleText.h"
+#include "nsIAccessibleHyperText.h"
+#include "nsIAccessibleEditableText.h"
+
+#include "HyperTextAccessible.h"
+#include "xpcAccessibleGeneric.h"
+
+namespace mozilla {
+namespace a11y {
+
+class xpcAccessibleHyperText : public xpcAccessibleGeneric,
+ public nsIAccessibleText,
+ public nsIAccessibleEditableText,
+ public nsIAccessibleHyperText
+{
+public:
+ explicit xpcAccessibleHyperText(Accessible* aIntl) :
+ xpcAccessibleGeneric(aIntl)
+ {
+ if (aIntl->IsHyperText() && aIntl->AsHyperText()->IsTextRole())
+ mSupportedIfaces |= eText;
+ }
+
+ xpcAccessibleHyperText(ProxyAccessible* aProxy, uint32_t aInterfaces) :
+ xpcAccessibleGeneric(aProxy, aInterfaces) { mSupportedIfaces |= eText; }
+
+ NS_DECL_ISUPPORTS_INHERITED
+
+ NS_DECL_NSIACCESSIBLETEXT
+ NS_DECL_NSIACCESSIBLEHYPERTEXT
+ NS_DECL_NSIACCESSIBLEEDITABLETEXT
+
+protected:
+ virtual ~xpcAccessibleHyperText() {}
+
+private:
+ HyperTextAccessible* Intl()
+ {
+ if (Accessible* acc = mIntl.AsAccessible()) {
+ return acc->AsHyperText();
+ }
+
+ return nullptr;
+ }
+
+ xpcAccessibleHyperText(const xpcAccessibleHyperText&) = delete;
+ xpcAccessibleHyperText& operator =(const xpcAccessibleHyperText&) = delete;
+};
+
+} // namespace a11y
+} // namespace mozilla
+
+#endif // mozilla_a11y_xpcAccessibleHyperText_h_
diff --git a/accessible/xpcom/xpcAccessibleImage.cpp b/accessible/xpcom/xpcAccessibleImage.cpp
new file mode 100644
index 0000000000..c0ef317215
--- /dev/null
+++ b/accessible/xpcom/xpcAccessibleImage.cpp
@@ -0,0 +1,55 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=2 et sw=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "xpcAccessibleImage.h"
+
+#include "ImageAccessible.h"
+
+using namespace mozilla::a11y;
+
+////////////////////////////////////////////////////////////////////////////////
+// nsISupports
+
+NS_IMPL_ISUPPORTS_INHERITED(xpcAccessibleImage,
+ xpcAccessibleGeneric,
+ nsIAccessibleImage)
+
+////////////////////////////////////////////////////////////////////////////////
+// nsIAccessibleImage
+
+NS_IMETHODIMP
+xpcAccessibleImage::GetImagePosition(uint32_t aCoordType,
+ int32_t* aX, int32_t* aY)
+{
+ NS_ENSURE_ARG_POINTER(aX);
+ *aX = 0;
+ NS_ENSURE_ARG_POINTER(aY);
+ *aY = 0;
+
+ if (!Intl())
+ return NS_ERROR_FAILURE;
+
+ nsIntPoint point = Intl()->Position(aCoordType);
+ *aX = point.x; *aY = point.y;
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+xpcAccessibleImage::GetImageSize(int32_t* aWidth, int32_t* aHeight)
+{
+ NS_ENSURE_ARG_POINTER(aWidth);
+ *aWidth = 0;
+ NS_ENSURE_ARG_POINTER(aHeight);
+ *aHeight = 0;
+
+ if (!Intl())
+ return NS_ERROR_FAILURE;
+
+ nsIntSize size = Intl()->Size();
+ *aWidth = size.width;
+ *aHeight = size.height;
+ return NS_OK;
+}
diff --git a/accessible/xpcom/xpcAccessibleImage.h b/accessible/xpcom/xpcAccessibleImage.h
new file mode 100644
index 0000000000..1c0bc805fd
--- /dev/null
+++ b/accessible/xpcom/xpcAccessibleImage.h
@@ -0,0 +1,47 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=2 et sw=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef mozilla_a11y_xpcAccessibleImage_h_
+#define mozilla_a11y_xpcAccessibleImage_h_
+
+#include "nsIAccessibleImage.h"
+
+#include "xpcAccessibleGeneric.h"
+
+namespace mozilla {
+namespace a11y {
+
+class xpcAccessibleImage : public xpcAccessibleGeneric,
+ public nsIAccessibleImage
+{
+public:
+ explicit xpcAccessibleImage(Accessible* aIntl) :
+ xpcAccessibleGeneric(aIntl) { }
+
+ xpcAccessibleImage(ProxyAccessible* aProxy, uint32_t aInterfaces) :
+ xpcAccessibleGeneric(aProxy, aInterfaces) {}
+
+ NS_DECL_ISUPPORTS_INHERITED
+
+ NS_IMETHOD GetImagePosition(uint32_t aCoordType,
+ int32_t* aX, int32_t* aY) final override;
+ NS_IMETHOD GetImageSize(int32_t* aWidth, int32_t* aHeight) final override;
+
+protected:
+ virtual ~xpcAccessibleImage() {}
+
+private:
+ ImageAccessible* Intl()
+ { return mIntl.IsAccessible() ? mIntl.AsAccessible()->AsImage() : nullptr; }
+
+ xpcAccessibleImage(const xpcAccessibleImage&) = delete;
+ xpcAccessibleImage& operator =(const xpcAccessibleImage&) = delete;
+};
+
+} // namespace a11y
+} // namespace mozilla
+
+#endif
diff --git a/accessible/xpcom/xpcAccessibleSelectable.cpp b/accessible/xpcom/xpcAccessibleSelectable.cpp
new file mode 100644
index 0000000000..df63e116c8
--- /dev/null
+++ b/accessible/xpcom/xpcAccessibleSelectable.cpp
@@ -0,0 +1,134 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=2 et sw=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "Accessible-inl.h"
+#include "xpcAccessibleDocument.h"
+
+#include "nsIMutableArray.h"
+
+using namespace mozilla::a11y;
+
+NS_IMETHODIMP
+xpcAccessibleSelectable::GetSelectedItems(nsIArray** aSelectedItems)
+{
+ NS_ENSURE_ARG_POINTER(aSelectedItems);
+ *aSelectedItems = nullptr;
+
+ if (!Intl())
+ return NS_ERROR_FAILURE;
+ NS_PRECONDITION(Intl()->IsSelect(), "Called on non selectable widget!");
+
+ AutoTArray<Accessible*, 10> items;
+ Intl()->SelectedItems(&items);
+
+ uint32_t itemCount = items.Length();
+ if (itemCount == 0)
+ return NS_OK;
+
+ nsresult rv = NS_OK;
+ nsCOMPtr<nsIMutableArray> xpcItems =
+ do_CreateInstance(NS_ARRAY_CONTRACTID, &rv);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ for (uint32_t idx = 0; idx < itemCount; idx++)
+ xpcItems->AppendElement(static_cast<nsIAccessible*>(ToXPC(items[idx])), false);
+
+ NS_ADDREF(*aSelectedItems = xpcItems);
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+xpcAccessibleSelectable::GetSelectedItemCount(uint32_t* aSelectionCount)
+{
+ NS_ENSURE_ARG_POINTER(aSelectionCount);
+ *aSelectionCount = 0;
+
+ if (!Intl())
+ return NS_ERROR_FAILURE;
+ NS_PRECONDITION(Intl()->IsSelect(), "Called on non selectable widget!");
+
+ *aSelectionCount = Intl()->SelectedItemCount();
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+xpcAccessibleSelectable::GetSelectedItemAt(uint32_t aIndex,
+ nsIAccessible** aSelected)
+{
+ NS_ENSURE_ARG_POINTER(aSelected);
+ *aSelected = nullptr;
+
+ if (!Intl())
+ return NS_ERROR_FAILURE;
+ NS_PRECONDITION(Intl()->IsSelect(), "Called on non selectable widget!");
+
+ *aSelected = ToXPC(Intl()->GetSelectedItem(aIndex));
+ if (*aSelected) {
+ NS_ADDREF(*aSelected);
+ return NS_OK;
+ }
+
+ return NS_ERROR_INVALID_ARG;
+}
+
+NS_IMETHODIMP
+xpcAccessibleSelectable::IsItemSelected(uint32_t aIndex, bool* aIsSelected)
+{
+ NS_ENSURE_ARG_POINTER(aIsSelected);
+ *aIsSelected = false;
+
+ if (!Intl())
+ return NS_ERROR_FAILURE;
+ NS_PRECONDITION(Intl()->IsSelect(), "Called on non selectable widget!");
+
+ *aIsSelected = Intl()->IsItemSelected(aIndex);
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+xpcAccessibleSelectable::AddItemToSelection(uint32_t aIndex)
+{
+ if (!Intl())
+ return NS_ERROR_FAILURE;
+ NS_PRECONDITION(Intl()->IsSelect(), "Called on non selectable widget!");
+
+ return Intl()->AddItemToSelection(aIndex) ? NS_OK : NS_ERROR_INVALID_ARG;
+}
+
+NS_IMETHODIMP
+xpcAccessibleSelectable::RemoveItemFromSelection(uint32_t aIndex)
+{
+ if (!Intl())
+ return NS_ERROR_FAILURE;
+ NS_PRECONDITION(Intl()->IsSelect(), "Called on non selectable widget!");
+
+ return Intl()->RemoveItemFromSelection(aIndex) ? NS_OK : NS_ERROR_INVALID_ARG;
+}
+
+NS_IMETHODIMP
+xpcAccessibleSelectable::SelectAll(bool* aIsMultiSelect)
+{
+ NS_ENSURE_ARG_POINTER(aIsMultiSelect);
+ *aIsMultiSelect = false;
+
+ if (!Intl())
+ return NS_ERROR_FAILURE;
+ NS_PRECONDITION(Intl()->IsSelect(), "Called on non selectable widget!");
+
+ *aIsMultiSelect = Intl()->SelectAll();
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+xpcAccessibleSelectable::UnselectAll()
+{
+ if (!Intl())
+ return NS_ERROR_FAILURE;
+ NS_PRECONDITION(Intl()->IsSelect(), "Called on non selectable widget!");
+
+ Intl()->UnselectAll();
+ return NS_OK;
+}
diff --git a/accessible/xpcom/xpcAccessibleSelectable.h b/accessible/xpcom/xpcAccessibleSelectable.h
new file mode 100644
index 0000000000..7b2f8a8276
--- /dev/null
+++ b/accessible/xpcom/xpcAccessibleSelectable.h
@@ -0,0 +1,54 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=2 et sw=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef mozilla_a11y_xpcAccessibleSelectable_h_
+#define mozilla_a11y_xpcAccessibleSelectable_h_
+
+#include "nsIAccessibleSelectable.h"
+
+class nsIAccessible;
+class nsIArray;
+
+namespace mozilla {
+namespace a11y {
+
+class Accessible;
+
+/**
+ * XPCOM nsIAccessibleSelectable inteface implementation, used by
+ * xpcAccessibleGeneric class.
+ */
+class xpcAccessibleSelectable : public nsIAccessibleSelectable
+{
+public:
+ // nsIAccessibleSelectable
+ NS_IMETHOD GetSelectedItems(nsIArray** aSelectedItems) final override;
+ NS_IMETHOD GetSelectedItemCount(uint32_t* aSelectedItemCount)
+ final override;
+ NS_IMETHOD GetSelectedItemAt(uint32_t aIndex, nsIAccessible** aItem)
+ final override;
+ NS_IMETHOD IsItemSelected(uint32_t aIndex, bool* aIsSelected)
+ final override;
+ NS_IMETHOD AddItemToSelection(uint32_t aIndex) final override;
+ NS_IMETHOD RemoveItemFromSelection(uint32_t aIndex) final override;
+ NS_IMETHOD SelectAll(bool* aIsMultiSelect) final override;
+ NS_IMETHOD UnselectAll() final override;
+
+protected:
+ xpcAccessibleSelectable() { }
+ virtual ~xpcAccessibleSelectable() {}
+
+private:
+ xpcAccessibleSelectable(const xpcAccessibleSelectable&) = delete;
+ xpcAccessibleSelectable& operator =(const xpcAccessibleSelectable&) = delete;
+
+ Accessible* Intl();
+};
+
+} // namespace a11y
+} // namespace mozilla
+
+#endif
diff --git a/accessible/xpcom/xpcAccessibleTable.cpp b/accessible/xpcom/xpcAccessibleTable.cpp
new file mode 100644
index 0000000000..0787bf73fd
--- /dev/null
+++ b/accessible/xpcom/xpcAccessibleTable.cpp
@@ -0,0 +1,493 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=2 et sw=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "xpcAccessibleTable.h"
+
+#include "Accessible.h"
+#include "TableAccessible.h"
+#include "xpcAccessibleDocument.h"
+
+#include "nsIMutableArray.h"
+#include "nsComponentManagerUtils.h"
+
+using namespace mozilla::a11y;
+
+static const uint32_t XPC_TABLE_DEFAULT_SIZE = 40;
+
+////////////////////////////////////////////////////////////////////////////////
+// nsISupports
+
+NS_IMPL_ISUPPORTS_INHERITED(xpcAccessibleTable,
+ xpcAccessibleGeneric,
+ nsIAccessibleTable)
+
+////////////////////////////////////////////////////////////////////////////////
+// nsIAccessibleTable
+
+NS_IMETHODIMP
+xpcAccessibleTable::GetCaption(nsIAccessible** aCaption)
+{
+ NS_ENSURE_ARG_POINTER(aCaption);
+ *aCaption = nullptr;
+ if (!Intl())
+ return NS_ERROR_FAILURE;
+
+ NS_IF_ADDREF(*aCaption = ToXPC(Intl()->Caption()));
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+xpcAccessibleTable::GetColumnCount(int32_t* aColumnCount)
+{
+ NS_ENSURE_ARG_POINTER(aColumnCount);
+ *aColumnCount = 0;
+
+ if (!Intl())
+ return NS_ERROR_FAILURE;
+
+ *aColumnCount = Intl()->ColCount();
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+xpcAccessibleTable::GetRowCount(int32_t* aRowCount)
+{
+ NS_ENSURE_ARG_POINTER(aRowCount);
+ *aRowCount = 0;
+
+ if (!Intl())
+ return NS_ERROR_FAILURE;
+
+ *aRowCount = Intl()->RowCount();
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+xpcAccessibleTable::GetCellAt(int32_t aRowIdx, int32_t aColIdx,
+ nsIAccessible** aCell)
+{
+ NS_ENSURE_ARG_POINTER(aCell);
+ *aCell = nullptr;
+
+ if (!Intl())
+ return NS_ERROR_FAILURE;
+
+ if (aRowIdx < 0 || static_cast<uint32_t>(aRowIdx) >= Intl()->RowCount() ||
+ aColIdx < 0 || static_cast<uint32_t>(aColIdx) >= Intl()->ColCount())
+ return NS_ERROR_INVALID_ARG;
+
+ NS_IF_ADDREF(*aCell = ToXPC(Intl()->CellAt(aRowIdx, aColIdx)));
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+xpcAccessibleTable::GetCellIndexAt(int32_t aRowIdx, int32_t aColIdx,
+ int32_t* aCellIdx)
+{
+ NS_ENSURE_ARG_POINTER(aCellIdx);
+ *aCellIdx = -1;
+
+ if (!Intl())
+ return NS_ERROR_FAILURE;
+
+ if (aRowIdx < 0 || static_cast<uint32_t>(aRowIdx) >= Intl()->RowCount() ||
+ aColIdx < 0 || static_cast<uint32_t>(aColIdx) >= Intl()->ColCount())
+ return NS_ERROR_INVALID_ARG;
+
+ *aCellIdx = Intl()->CellIndexAt(aRowIdx, aColIdx);
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+xpcAccessibleTable::GetColumnExtentAt(int32_t aRowIdx, int32_t aColIdx,
+ int32_t* aColumnExtent)
+{
+ NS_ENSURE_ARG_POINTER(aColumnExtent);
+ *aColumnExtent = -1;
+
+ if (!Intl())
+ return NS_ERROR_FAILURE;
+
+ if (aRowIdx < 0 || static_cast<uint32_t>(aRowIdx) >= Intl()->RowCount() ||
+ aColIdx < 0 || static_cast<uint32_t>(aColIdx) >= Intl()->ColCount())
+ return NS_ERROR_INVALID_ARG;
+
+ *aColumnExtent = Intl()->ColExtentAt(aRowIdx, aColIdx);
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+xpcAccessibleTable::GetRowExtentAt(int32_t aRowIdx, int32_t aColIdx,
+ int32_t* aRowExtent)
+{
+ NS_ENSURE_ARG_POINTER(aRowExtent);
+ *aRowExtent = -1;
+
+ if (!Intl())
+ return NS_ERROR_FAILURE;
+
+ if (aRowIdx < 0 || static_cast<uint32_t>(aRowIdx) >= Intl()->RowCount() ||
+ aColIdx < 0 || static_cast<uint32_t>(aColIdx) >= Intl()->ColCount())
+ return NS_ERROR_INVALID_ARG;
+
+ *aRowExtent = Intl()->RowExtentAt(aRowIdx, aColIdx);
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+xpcAccessibleTable::GetColumnDescription(int32_t aColIdx,
+ nsAString& aDescription)
+{
+ if (!Intl())
+ return NS_ERROR_FAILURE;
+
+ if (aColIdx < 0 || static_cast<uint32_t>(aColIdx) >= Intl()->ColCount())
+ return NS_ERROR_INVALID_ARG;
+
+ nsAutoString description;
+ Intl()->ColDescription(aColIdx, description);
+ aDescription.Assign(description);
+
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+xpcAccessibleTable::GetRowDescription(int32_t aRowIdx, nsAString& aDescription)
+{
+ if (!Intl())
+ return NS_ERROR_FAILURE;
+
+ if (aRowIdx < 0 || static_cast<uint32_t>(aRowIdx) >= Intl()->ColCount())
+ return NS_ERROR_INVALID_ARG;
+
+ nsAutoString description;
+ Intl()->RowDescription(aRowIdx, description);
+ aDescription.Assign(description);
+
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+xpcAccessibleTable::IsColumnSelected(int32_t aColIdx, bool* aIsSelected)
+{
+ NS_ENSURE_ARG_POINTER(aIsSelected);
+ *aIsSelected = false;
+
+ if (!Intl())
+ return NS_ERROR_FAILURE;
+
+ if (aColIdx < 0 || static_cast<uint32_t>(aColIdx) >= Intl()->ColCount())
+ return NS_ERROR_INVALID_ARG;
+
+ *aIsSelected = Intl()->IsColSelected(aColIdx);
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+xpcAccessibleTable::IsRowSelected(int32_t aRowIdx, bool* aIsSelected)
+{
+ NS_ENSURE_ARG_POINTER(aIsSelected);
+ *aIsSelected = false;
+
+ if (!Intl())
+ return NS_ERROR_FAILURE;
+
+ if (aRowIdx < 0 || static_cast<uint32_t>(aRowIdx) >= Intl()->RowCount())
+ return NS_ERROR_INVALID_ARG;
+
+ *aIsSelected = Intl()->IsRowSelected(aRowIdx);
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+xpcAccessibleTable::IsCellSelected(int32_t aRowIdx, int32_t aColIdx,
+ bool* aIsSelected)
+{
+ NS_ENSURE_ARG_POINTER(aIsSelected);
+ *aIsSelected = false;
+
+ if (!Intl())
+ return NS_ERROR_FAILURE;
+
+ if (aRowIdx < 0 || static_cast<uint32_t>(aRowIdx) >= Intl()->RowCount() ||
+ aColIdx < 0 || static_cast<uint32_t>(aColIdx) >= Intl()->ColCount())
+ return NS_ERROR_INVALID_ARG;
+
+ *aIsSelected = Intl()->IsCellSelected(aRowIdx, aColIdx);
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+xpcAccessibleTable::GetSelectedCellCount(uint32_t* aSelectedCellCount)
+{
+ NS_ENSURE_ARG_POINTER(aSelectedCellCount);
+ *aSelectedCellCount = 0;
+
+ if (!Intl())
+ return NS_ERROR_FAILURE;
+
+ *aSelectedCellCount = Intl()->SelectedCellCount();
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+xpcAccessibleTable::GetSelectedColumnCount(uint32_t* aSelectedColumnCount)
+{
+ NS_ENSURE_ARG_POINTER(aSelectedColumnCount);
+ *aSelectedColumnCount = 0;
+
+ if (!Intl())
+ return NS_ERROR_FAILURE;
+
+ *aSelectedColumnCount = Intl()->SelectedColCount();
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+xpcAccessibleTable::GetSelectedRowCount(uint32_t* aSelectedRowCount)
+{
+ NS_ENSURE_ARG_POINTER(aSelectedRowCount);
+ *aSelectedRowCount = 0;
+
+ if (!Intl())
+ return NS_ERROR_FAILURE;
+
+ *aSelectedRowCount = Intl()->SelectedRowCount();
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+xpcAccessibleTable::GetSelectedCells(nsIArray** aSelectedCells)
+{
+ NS_ENSURE_ARG_POINTER(aSelectedCells);
+ *aSelectedCells = nullptr;
+
+ if (!Intl())
+ return NS_ERROR_FAILURE;
+
+ nsresult rv = NS_OK;
+ nsCOMPtr<nsIMutableArray> selCells =
+ do_CreateInstance(NS_ARRAY_CONTRACTID, &rv);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ AutoTArray<Accessible*, XPC_TABLE_DEFAULT_SIZE> cellsArray;
+ Intl()->SelectedCells(&cellsArray);
+
+ uint32_t totalCount = cellsArray.Length();
+ for (uint32_t idx = 0; idx < totalCount; idx++) {
+ Accessible* cell = cellsArray.ElementAt(idx);
+ selCells->AppendElement(static_cast<nsIAccessible*>(ToXPC(cell)), false);
+ }
+
+ NS_ADDREF(*aSelectedCells = selCells);
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+xpcAccessibleTable::GetSelectedCellIndices(uint32_t* aCellsArraySize,
+ int32_t** aCellsArray)
+{
+ NS_ENSURE_ARG_POINTER(aCellsArraySize);
+ *aCellsArraySize = 0;
+
+ NS_ENSURE_ARG_POINTER(aCellsArray);
+ *aCellsArray = 0;
+
+ if (!Intl())
+ return NS_ERROR_FAILURE;
+
+ AutoTArray<uint32_t, XPC_TABLE_DEFAULT_SIZE> cellsArray;
+ Intl()->SelectedCellIndices(&cellsArray);
+
+ *aCellsArraySize = cellsArray.Length();
+ *aCellsArray = static_cast<int32_t*>
+ (moz_xmalloc(*aCellsArraySize * sizeof(int32_t)));
+ memcpy(*aCellsArray, cellsArray.Elements(),
+ *aCellsArraySize * sizeof(int32_t));
+
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+xpcAccessibleTable::GetSelectedColumnIndices(uint32_t* aColsArraySize,
+ int32_t** aColsArray)
+{
+ NS_ENSURE_ARG_POINTER(aColsArraySize);
+ *aColsArraySize = 0;
+
+ NS_ENSURE_ARG_POINTER(aColsArray);
+ *aColsArray = 0;
+
+ if (!Intl())
+ return NS_ERROR_FAILURE;
+
+ AutoTArray<uint32_t, XPC_TABLE_DEFAULT_SIZE> colsArray;
+ Intl()->SelectedColIndices(&colsArray);
+
+ *aColsArraySize = colsArray.Length();
+ *aColsArray = static_cast<int32_t*>
+ (moz_xmalloc(*aColsArraySize * sizeof(int32_t)));
+ memcpy(*aColsArray, colsArray.Elements(),
+ *aColsArraySize * sizeof(int32_t));
+
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+xpcAccessibleTable::GetSelectedRowIndices(uint32_t* aRowsArraySize,
+ int32_t** aRowsArray)
+{
+ NS_ENSURE_ARG_POINTER(aRowsArraySize);
+ *aRowsArraySize = 0;
+
+ NS_ENSURE_ARG_POINTER(aRowsArray);
+ *aRowsArray = 0;
+
+ if (!Intl())
+ return NS_ERROR_FAILURE;
+
+ AutoTArray<uint32_t, XPC_TABLE_DEFAULT_SIZE> rowsArray;
+ Intl()->SelectedRowIndices(&rowsArray);
+
+ *aRowsArraySize = rowsArray.Length();
+ *aRowsArray = static_cast<int32_t*>
+ (moz_xmalloc(*aRowsArraySize * sizeof(int32_t)));
+ memcpy(*aRowsArray, rowsArray.Elements(),
+ *aRowsArraySize * sizeof(int32_t));
+
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+xpcAccessibleTable::GetColumnIndexAt(int32_t aCellIdx, int32_t* aColIdx)
+{
+ NS_ENSURE_ARG_POINTER(aColIdx);
+ *aColIdx = -1;
+
+ if (!Intl())
+ return NS_ERROR_FAILURE;
+
+ if (aCellIdx < 0 ||
+ static_cast<uint32_t>(aCellIdx) >= Intl()->RowCount() * Intl()->ColCount())
+ return NS_ERROR_INVALID_ARG;
+
+ *aColIdx = Intl()->ColIndexAt(aCellIdx);
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+xpcAccessibleTable::GetRowIndexAt(int32_t aCellIdx, int32_t* aRowIdx)
+{
+ NS_ENSURE_ARG_POINTER(aRowIdx);
+ *aRowIdx = -1;
+
+ if (!Intl())
+ return NS_ERROR_FAILURE;
+
+ if (aCellIdx < 0 ||
+ static_cast<uint32_t>(aCellIdx) >= Intl()->RowCount() * Intl()->ColCount())
+ return NS_ERROR_INVALID_ARG;
+
+ *aRowIdx = Intl()->RowIndexAt(aCellIdx);
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+xpcAccessibleTable::GetRowAndColumnIndicesAt(int32_t aCellIdx, int32_t* aRowIdx,
+ int32_t* aColIdx)
+{
+ NS_ENSURE_ARG_POINTER(aRowIdx);
+ *aRowIdx = -1;
+ NS_ENSURE_ARG_POINTER(aColIdx);
+ *aColIdx = -1;
+
+ if (!Intl())
+ return NS_ERROR_FAILURE;
+
+ if (aCellIdx < 0 ||
+ static_cast<uint32_t>(aCellIdx) >= Intl()->RowCount() * Intl()->ColCount())
+ return NS_ERROR_INVALID_ARG;
+
+ Intl()->RowAndColIndicesAt(aCellIdx, aRowIdx, aColIdx);
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+xpcAccessibleTable::GetSummary(nsAString& aSummary)
+{
+ if (!Intl())
+ return NS_ERROR_FAILURE;
+
+ nsAutoString summary;
+ Intl()->Summary(summary);
+ aSummary.Assign(summary);
+
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+xpcAccessibleTable::IsProbablyForLayout(bool* aResult)
+{
+ NS_ENSURE_ARG_POINTER(aResult);
+ *aResult = false;
+ if (!Intl())
+ return NS_ERROR_FAILURE;
+
+ *aResult = Intl()->IsProbablyLayoutTable();
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+xpcAccessibleTable::SelectColumn(int32_t aColIdx)
+{
+ if (!Intl())
+ return NS_ERROR_FAILURE;
+
+ if (aColIdx < 0 || static_cast<uint32_t>(aColIdx) >= Intl()->ColCount())
+ return NS_ERROR_INVALID_ARG;
+
+ Intl()->SelectCol(aColIdx);
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+xpcAccessibleTable::SelectRow(int32_t aRowIdx)
+{
+ if (!Intl())
+ return NS_ERROR_FAILURE;
+
+ if (aRowIdx < 0 || static_cast<uint32_t>(aRowIdx) >= Intl()->RowCount())
+ return NS_ERROR_INVALID_ARG;
+
+ Intl()->SelectRow(aRowIdx);
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+xpcAccessibleTable::UnselectColumn(int32_t aColIdx)
+{
+ if (!Intl())
+ return NS_ERROR_FAILURE;
+
+ if (aColIdx < 0 || static_cast<uint32_t>(aColIdx) >= Intl()->ColCount())
+ return NS_ERROR_INVALID_ARG;
+
+ Intl()->UnselectCol(aColIdx);
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+xpcAccessibleTable::UnselectRow(int32_t aRowIdx)
+{
+ if (!Intl())
+ return NS_ERROR_FAILURE;
+
+ if (aRowIdx < 0 || static_cast<uint32_t>(aRowIdx) >= Intl()->RowCount())
+ return NS_ERROR_INVALID_ARG;
+
+ Intl()->UnselectRow(aRowIdx);
+ return NS_OK;
+}
diff --git a/accessible/xpcom/xpcAccessibleTable.h b/accessible/xpcom/xpcAccessibleTable.h
new file mode 100644
index 0000000000..36dd77e0a4
--- /dev/null
+++ b/accessible/xpcom/xpcAccessibleTable.h
@@ -0,0 +1,96 @@
+/* -*- Mode: C++ final; tab-width: 2 final; indent-tabs-mode: nil final; c-basic-offset: 2 -*- */
+/* vim: set ts=2 et sw=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef mozilla_a11y_xpcAccessibleTable_h_
+#define mozilla_a11y_xpcAccessibleTable_h_
+
+#include "nsIAccessibleTable.h"
+#include "xpcAccessibleGeneric.h"
+
+namespace mozilla {
+namespace a11y {
+
+/**
+ * XPCOM wrapper around TableAccessible class.
+ */
+class xpcAccessibleTable : public xpcAccessibleGeneric,
+ public nsIAccessibleTable
+{
+public:
+ explicit xpcAccessibleTable(Accessible* aIntl) :
+ xpcAccessibleGeneric(aIntl) { }
+
+ xpcAccessibleTable(ProxyAccessible* aProxy, uint32_t aInterfaces) :
+ xpcAccessibleGeneric(aProxy, aInterfaces) {}
+
+ NS_DECL_ISUPPORTS_INHERITED
+
+ // nsIAccessibleTable
+ NS_IMETHOD GetCaption(nsIAccessible** aCaption) final override;
+ NS_IMETHOD GetSummary(nsAString& aSummary) final override;
+ NS_IMETHOD GetColumnCount(int32_t* aColumnCount) final override;
+ NS_IMETHOD GetRowCount(int32_t* aRowCount) final override;
+ NS_IMETHOD GetCellAt(int32_t aRowIndex, int32_t aColumnIndex,
+ nsIAccessible** aCell) final override;
+ NS_IMETHOD GetCellIndexAt(int32_t aRowIndex, int32_t aColumnIndex,
+ int32_t* aCellIndex) final override;
+ NS_IMETHOD GetColumnIndexAt(int32_t aCellIndex, int32_t* aColumnIndex)
+ final override;
+ NS_IMETHOD GetRowIndexAt(int32_t aCellIndex, int32_t* aRowIndex)
+ final override;
+ NS_IMETHOD GetRowAndColumnIndicesAt(int32_t aCellIndex, int32_t* aRowIndex,
+ int32_t* aColumnIndex)
+ final override;
+ NS_IMETHOD GetColumnExtentAt(int32_t row, int32_t column,
+ int32_t* aColumnExtent) final override;
+ NS_IMETHOD GetRowExtentAt(int32_t row, int32_t column,
+ int32_t* aRowExtent) final override;
+ NS_IMETHOD GetColumnDescription(int32_t aColIdx, nsAString& aDescription)
+ final override;
+ NS_IMETHOD GetRowDescription(int32_t aRowIdx, nsAString& aDescription)
+ final override;
+ NS_IMETHOD IsColumnSelected(int32_t aColIdx, bool* _retval)
+ final override;
+ NS_IMETHOD IsRowSelected(int32_t aRowIdx, bool* _retval)
+ final override;
+ NS_IMETHOD IsCellSelected(int32_t aRowIdx, int32_t aColIdx, bool* _retval)
+ final override;
+ NS_IMETHOD GetSelectedCellCount(uint32_t* aSelectedCellCount)
+ final override;
+ NS_IMETHOD GetSelectedColumnCount(uint32_t* aSelectedColumnCount)
+ final override;
+ NS_IMETHOD GetSelectedRowCount(uint32_t* aSelectedRowCount)
+ final override;
+ NS_IMETHOD GetSelectedCells(nsIArray** aSelectedCell) final override;
+ NS_IMETHOD GetSelectedCellIndices(uint32_t* aCellsArraySize,
+ int32_t** aCellsArray)
+ final override;
+ NS_IMETHOD GetSelectedColumnIndices(uint32_t* aColsArraySize,
+ int32_t** aColsArray)
+ final override;
+ NS_IMETHOD GetSelectedRowIndices(uint32_t* aRowsArraySize,
+ int32_t** aRowsArray) final override;
+ NS_IMETHOD SelectColumn(int32_t aColIdx) final override;
+ NS_IMETHOD SelectRow(int32_t aRowIdx) final override;
+ NS_IMETHOD UnselectColumn(int32_t aColIdx) final override;
+ NS_IMETHOD UnselectRow(int32_t aRowIdx) final override;
+ NS_IMETHOD IsProbablyForLayout(bool* aIsForLayout) final override;
+
+protected:
+ virtual ~xpcAccessibleTable() {}
+
+private:
+ TableAccessible* Intl()
+ { return mIntl.IsAccessible() ? mIntl.AsAccessible()->AsTable() : nullptr; }
+
+ xpcAccessibleTable(const xpcAccessibleTable&) = delete;
+ xpcAccessibleTable& operator =(const xpcAccessibleTable&) = delete;
+};
+
+} // namespace a11y
+} // namespace mozilla
+
+#endif // mozilla_a11y_xpcAccessibleTable_h_
diff --git a/accessible/xpcom/xpcAccessibleTableCell.cpp b/accessible/xpcom/xpcAccessibleTableCell.cpp
new file mode 100644
index 0000000000..e507a88162
--- /dev/null
+++ b/accessible/xpcom/xpcAccessibleTableCell.cpp
@@ -0,0 +1,161 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=2 et sw=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "xpcAccessibleTableCell.h"
+
+#include "Accessible.h"
+#include "nsIAccessibleTable.h"
+#include "TableAccessible.h"
+#include "TableCellAccessible.h"
+#include "xpcAccessibleDocument.h"
+
+#include "nsComponentManagerUtils.h"
+#include "nsIMutableArray.h"
+
+using namespace mozilla;
+using namespace mozilla::a11y;
+
+////////////////////////////////////////////////////////////////////////////////
+// nsISupports
+
+NS_IMPL_ISUPPORTS_INHERITED(xpcAccessibleTableCell,
+ xpcAccessibleHyperText,
+ nsIAccessibleTableCell)
+
+////////////////////////////////////////////////////////////////////////////////
+// nsIAccessibleTableCell
+
+NS_IMETHODIMP
+xpcAccessibleTableCell::GetTable(nsIAccessibleTable** aTable)
+{
+ NS_ENSURE_ARG_POINTER(aTable);
+ *aTable = nullptr;
+
+ if (!Intl())
+ return NS_ERROR_FAILURE;
+
+ TableAccessible* table = Intl()->Table();
+ if (!table)
+ return NS_ERROR_FAILURE;
+
+ nsCOMPtr<nsIAccessibleTable> xpcTable =
+ do_QueryInterface(static_cast<nsIAccessible*>(ToXPC(table->AsAccessible())));
+ xpcTable.forget(aTable);
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+xpcAccessibleTableCell::GetColumnIndex(int32_t* aColIdx)
+{
+ NS_ENSURE_ARG_POINTER(aColIdx);
+ *aColIdx = -1;
+
+ if (!Intl())
+ return NS_ERROR_FAILURE;
+
+ *aColIdx = Intl()->ColIdx();
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+xpcAccessibleTableCell::GetRowIndex(int32_t* aRowIdx)
+{
+ NS_ENSURE_ARG_POINTER(aRowIdx);
+ *aRowIdx = -1;
+
+ if (!Intl())
+ return NS_ERROR_FAILURE;
+
+ *aRowIdx = Intl()->RowIdx();
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+xpcAccessibleTableCell::GetColumnExtent(int32_t* aExtent)
+{
+ NS_ENSURE_ARG_POINTER(aExtent);
+ *aExtent = -1;
+
+ if (!Intl())
+ return NS_ERROR_FAILURE;
+
+ *aExtent = Intl()->ColExtent();
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+xpcAccessibleTableCell::GetRowExtent(int32_t* aExtent)
+{
+ NS_ENSURE_ARG_POINTER(aExtent);
+ *aExtent = -1;
+
+ if (!Intl())
+ return NS_ERROR_FAILURE;
+
+ *aExtent = Intl()->RowExtent();
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+xpcAccessibleTableCell::GetColumnHeaderCells(nsIArray** aHeaderCells)
+{
+ NS_ENSURE_ARG_POINTER(aHeaderCells);
+ *aHeaderCells = nullptr;
+
+ if (!Intl())
+ return NS_ERROR_FAILURE;
+
+ AutoTArray<Accessible*, 10> headerCells;
+ Intl()->ColHeaderCells(&headerCells);
+
+ nsCOMPtr<nsIMutableArray> cells = do_CreateInstance(NS_ARRAY_CONTRACTID);
+ NS_ENSURE_TRUE(cells, NS_ERROR_FAILURE);
+
+ for (uint32_t idx = 0; idx < headerCells.Length(); idx++) {
+ cells->AppendElement(static_cast<nsIAccessible*>(ToXPC(headerCells[idx])),
+ false);
+ }
+
+ NS_ADDREF(*aHeaderCells = cells);
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+xpcAccessibleTableCell::GetRowHeaderCells(nsIArray** aHeaderCells)
+{
+ NS_ENSURE_ARG_POINTER(aHeaderCells);
+ *aHeaderCells = nullptr;
+
+ if (!Intl())
+ return NS_ERROR_FAILURE;
+
+ AutoTArray<Accessible*, 10> headerCells;
+ Intl()->RowHeaderCells(&headerCells);
+
+ nsCOMPtr<nsIMutableArray> cells = do_CreateInstance(NS_ARRAY_CONTRACTID);
+ NS_ENSURE_TRUE(cells, NS_ERROR_FAILURE);
+
+ for (uint32_t idx = 0; idx < headerCells.Length(); idx++) {
+ cells->AppendElement(static_cast<nsIAccessible*>(ToXPC(headerCells[idx])),
+ false);
+ }
+
+ NS_ADDREF(*aHeaderCells = cells);
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+xpcAccessibleTableCell::IsSelected(bool* aSelected)
+{
+ NS_ENSURE_ARG_POINTER(aSelected);
+ *aSelected = false;
+
+ if (!Intl())
+ return NS_ERROR_FAILURE;
+
+ *aSelected = Intl()->Selected();
+ return NS_OK;
+}
diff --git a/accessible/xpcom/xpcAccessibleTableCell.h b/accessible/xpcom/xpcAccessibleTableCell.h
new file mode 100644
index 0000000000..9a40f8e1a5
--- /dev/null
+++ b/accessible/xpcom/xpcAccessibleTableCell.h
@@ -0,0 +1,62 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=2 et sw=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef mozilla_a11y_xpcom_xpcAccessibletableCell_h_
+#define mozilla_a11y_xpcom_xpcAccessibletableCell_h_
+
+#include "nsIAccessibleTable.h"
+
+#include "xpcAccessibleHyperText.h"
+
+namespace mozilla {
+namespace a11y {
+
+/**
+ * XPCOM wrapper around TableAccessibleCell class.
+ */
+class xpcAccessibleTableCell : public xpcAccessibleHyperText,
+ public nsIAccessibleTableCell
+{
+public:
+ explicit xpcAccessibleTableCell(Accessible* aIntl) :
+ xpcAccessibleHyperText(aIntl) { }
+
+ xpcAccessibleTableCell(ProxyAccessible* aProxy, uint32_t aInterfaces) :
+ xpcAccessibleHyperText(aProxy, aInterfaces) {}
+
+ NS_DECL_ISUPPORTS_INHERITED
+
+ // nsIAccessibleTableCell
+ NS_IMETHOD GetTable(nsIAccessibleTable** aTable) final override;
+ NS_IMETHOD GetColumnIndex(int32_t* aColIdx) final override;
+ NS_IMETHOD GetRowIndex(int32_t* aRowIdx) final override;
+ NS_IMETHOD GetColumnExtent(int32_t* aExtent) final override;
+ NS_IMETHOD GetRowExtent(int32_t* aExtent) final override;
+ NS_IMETHOD GetColumnHeaderCells(nsIArray** aHeaderCells) final override;
+ NS_IMETHOD GetRowHeaderCells(nsIArray** aHeaderCells) final override;
+ NS_IMETHOD IsSelected(bool* aSelected) final override;
+
+protected:
+ virtual ~xpcAccessibleTableCell() {}
+
+private:
+ TableCellAccessible* Intl()
+ {
+ if (Accessible* acc = mIntl.AsAccessible()) {
+ return acc->AsTableCell();
+ }
+
+ return nullptr;
+}
+
+ xpcAccessibleTableCell(const xpcAccessibleTableCell&) = delete;
+ xpcAccessibleTableCell& operator =(const xpcAccessibleTableCell&) = delete;
+};
+
+} // namespace a11y
+} // namespace mozilla
+
+#endif // mozilla_a11y_xpcom_xpcAccessibletableCell_h_
diff --git a/accessible/xpcom/xpcAccessibleTextRange.cpp b/accessible/xpcom/xpcAccessibleTextRange.cpp
new file mode 100644
index 0000000000..07a6ec6d36
--- /dev/null
+++ b/accessible/xpcom/xpcAccessibleTextRange.cpp
@@ -0,0 +1,221 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=2 et sw=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "xpcAccessibleTextRange.h"
+
+#include "TextRange-inl.h"
+#include "xpcAccessibleDocument.h"
+
+#include "nsIMutableArray.h"
+#include "nsComponentManagerUtils.h"
+#include "nsQueryObject.h"
+
+using namespace mozilla;
+using namespace mozilla::a11y;
+
+// nsISupports and cycle collection
+
+NS_IMPL_CYCLE_COLLECTION(xpcAccessibleTextRange,
+ mRange.mRoot,
+ mRange.mStartContainer,
+ mRange.mEndContainer)
+
+NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(xpcAccessibleTextRange)
+ NS_INTERFACE_MAP_ENTRY(nsIAccessibleTextRange)
+ NS_INTERFACE_MAP_ENTRY(xpcAccessibleTextRange)
+ NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIAccessibleTextRange)
+NS_INTERFACE_MAP_END
+
+NS_IMPL_CYCLE_COLLECTING_ADDREF(xpcAccessibleTextRange)
+NS_IMPL_CYCLE_COLLECTING_RELEASE(xpcAccessibleTextRange)
+
+// nsIAccessibleTextRange
+
+NS_IMETHODIMP
+xpcAccessibleTextRange::GetStartContainer(nsIAccessibleText** aAnchor)
+{
+ NS_ENSURE_ARG_POINTER(aAnchor);
+ NS_IF_ADDREF(*aAnchor = ToXPCText(mRange.StartContainer()));
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+xpcAccessibleTextRange::GetStartOffset(int32_t* aOffset)
+{
+ NS_ENSURE_ARG_POINTER(aOffset);
+ *aOffset = mRange.StartOffset();
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+xpcAccessibleTextRange::GetEndContainer(nsIAccessibleText** aAnchor)
+{
+ NS_ENSURE_ARG_POINTER(aAnchor);
+ NS_IF_ADDREF(*aAnchor = ToXPCText(mRange.EndContainer()));
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+xpcAccessibleTextRange::GetEndOffset(int32_t* aOffset)
+{
+ NS_ENSURE_ARG_POINTER(aOffset);
+ *aOffset = mRange.EndOffset();
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+xpcAccessibleTextRange::GetContainer(nsIAccessible** aContainer)
+{
+ NS_ENSURE_ARG_POINTER(aContainer);
+ NS_IF_ADDREF(*aContainer = ToXPC(mRange.Container()));
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+xpcAccessibleTextRange::GetEmbeddedChildren(nsIArray** aList)
+{
+ nsresult rv = NS_OK;
+ nsCOMPtr<nsIMutableArray> xpcList =
+ do_CreateInstance(NS_ARRAY_CONTRACTID, &rv);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ nsTArray<Accessible*> objects;
+ mRange.EmbeddedChildren(&objects);
+
+ uint32_t len = objects.Length();
+ for (uint32_t idx = 0; idx < len; idx++)
+ xpcList->AppendElement(static_cast<nsIAccessible*>(ToXPC(objects[idx])), false);
+
+ xpcList.forget(aList);
+
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+xpcAccessibleTextRange::Compare(nsIAccessibleTextRange* aOtherRange,
+ bool* aResult)
+{
+
+ RefPtr<xpcAccessibleTextRange> xpcRange(do_QueryObject(aOtherRange));
+ if (!xpcRange || !aResult)
+ return NS_ERROR_INVALID_ARG;
+
+ *aResult = (mRange == xpcRange->mRange);
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+xpcAccessibleTextRange::CompareEndPoints(uint32_t aEndPoint,
+ nsIAccessibleTextRange* aOtherRange,
+ uint32_t aOtherRangeEndPoint,
+ int32_t* aResult)
+{
+ RefPtr<xpcAccessibleTextRange> xpcRange(do_QueryObject(aOtherRange));
+ if (!xpcRange || !aResult)
+ return NS_ERROR_INVALID_ARG;
+
+ TextPoint p = (aEndPoint == EndPoint_Start) ?
+ mRange.StartPoint() : mRange.EndPoint();
+ TextPoint otherPoint = (aOtherRangeEndPoint == EndPoint_Start) ?
+ xpcRange->mRange.StartPoint() : xpcRange->mRange.EndPoint();
+
+ if (p == otherPoint)
+ *aResult = 0;
+ else
+ *aResult = p < otherPoint ? -1 : 1;
+
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+xpcAccessibleTextRange::GetText(nsAString& aText)
+{
+ nsAutoString text;
+ mRange.Text(text);
+ aText.Assign(text);
+
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+xpcAccessibleTextRange::GetBounds(nsIArray** aRectList)
+{
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+xpcAccessibleTextRange::Move(uint32_t aUnit, int32_t aCount)
+{
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+xpcAccessibleTextRange::MoveStart(uint32_t aUnit, int32_t aCount)
+{
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+xpcAccessibleTextRange::MoveEnd(uint32_t aUnit, int32_t aCount)
+{
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+xpcAccessibleTextRange::Normalize(uint32_t aUnit)
+{
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+xpcAccessibleTextRange::Crop(nsIAccessible* aContainer, bool* aSuccess)
+{
+ Accessible* container = aContainer->ToInternalAccessible();
+ NS_ENSURE_TRUE(container, NS_ERROR_INVALID_ARG);
+
+ *aSuccess = mRange.Crop(container);
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+xpcAccessibleTextRange::FindText(const nsAString& aText, bool aIsBackward,
+ bool aIsIgnoreCase,
+ nsIAccessibleTextRange** aRange)
+{
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+xpcAccessibleTextRange::FindAttr(uint32_t aAttr, nsIVariant* aVal,
+ bool aIsBackward,
+ nsIAccessibleTextRange** aRange)
+{
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+xpcAccessibleTextRange::AddToSelection()
+{
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+xpcAccessibleTextRange::RemoveFromSelection()
+{
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+xpcAccessibleTextRange::Select()
+{
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+xpcAccessibleTextRange::ScrollIntoView(uint32_t aHow)
+{
+ return NS_OK;
+}
diff --git a/accessible/xpcom/xpcAccessibleTextRange.h b/accessible/xpcom/xpcAccessibleTextRange.h
new file mode 100644
index 0000000000..3157077033
--- /dev/null
+++ b/accessible/xpcom/xpcAccessibleTextRange.h
@@ -0,0 +1,85 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=2 et sw=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef mozilla_a11y_xpcAccessibleTextRange_h_
+#define mozilla_a11y_xpcAccessibleTextRange_h_
+
+#include "nsIAccessibleTextRange.h"
+#include "TextRange.h"
+
+#include "mozilla/Move.h"
+#include "nsCycleCollectionParticipant.h"
+
+namespace mozilla {
+namespace a11y {
+
+class TextRange;
+
+#define NS_ACCESSIBLETEXTRANGE_IMPL_IID \
+{ /* 133c8bf4-4913-4355-bd50-426bd1d6e1ad */ \
+ 0xb17652d9, \
+ 0x4f54, \
+ 0x4c56, \
+ { 0xbb, 0x62, 0x6d, 0x5b, 0xf1, 0xef, 0x91, 0x0c } \
+}
+
+class xpcAccessibleTextRange final : public nsIAccessibleTextRange
+{
+public:
+ NS_DECL_CYCLE_COLLECTING_ISUPPORTS
+ NS_DECL_CYCLE_COLLECTION_CLASS(xpcAccessibleTextRange)
+
+ NS_IMETHOD GetStartContainer(nsIAccessibleText** aAnchor) final override;
+ NS_IMETHOD GetStartOffset(int32_t* aOffset) final override;
+ NS_IMETHOD GetEndContainer(nsIAccessibleText** aAnchor) final override;
+ NS_IMETHOD GetEndOffset(int32_t* aOffset) final override;
+ NS_IMETHOD GetContainer(nsIAccessible** aContainer) final override;
+ NS_IMETHOD GetEmbeddedChildren(nsIArray** aList) final override;
+ NS_IMETHOD Compare(nsIAccessibleTextRange* aOtherRange, bool* aResult) final override;
+ NS_IMETHOD CompareEndPoints(uint32_t aEndPoint,
+ nsIAccessibleTextRange* aOtherRange,
+ uint32_t aOtherRangeEndPoint,
+ int32_t* aResult) final override;
+ NS_IMETHOD GetText(nsAString& aText) final override;
+ NS_IMETHOD GetBounds(nsIArray** aRectList) final override;
+ NS_IMETHOD Move(uint32_t aUnit, int32_t aCount) final override;
+ NS_IMETHOD MoveStart(uint32_t aUnit, int32_t aCount) final override;
+ NS_IMETHOD MoveEnd(uint32_t aUnit, int32_t aCount) final override;
+ NS_IMETHOD Normalize(uint32_t aUnit) final override;
+ NS_IMETHOD Crop(nsIAccessible* aContainer, bool* aSuccess) final override;
+ NS_IMETHOD FindText(const nsAString& aText, bool aIsBackward, bool aIsIgnoreCase,
+ nsIAccessibleTextRange** aRange) final override;
+ NS_IMETHOD FindAttr(uint32_t aAttr, nsIVariant* aVal, bool aIsBackward,
+ nsIAccessibleTextRange** aRange) final override;
+ NS_IMETHOD AddToSelection() final override;
+ NS_IMETHOD RemoveFromSelection() final override;
+ NS_IMETHOD Select() final override;
+ NS_IMETHOD ScrollIntoView(uint32_t aHow) final override;
+
+ NS_DECLARE_STATIC_IID_ACCESSOR(NS_ACCESSIBLETEXTRANGE_IMPL_IID)
+
+private:
+ explicit xpcAccessibleTextRange(TextRange&& aRange) :
+ mRange(Forward<TextRange>(aRange)) {}
+ xpcAccessibleTextRange() {}
+
+ ~xpcAccessibleTextRange() {}
+
+ friend class xpcAccessibleHyperText;
+
+ xpcAccessibleTextRange(const xpcAccessibleTextRange&) = delete;
+ xpcAccessibleTextRange& operator =(const xpcAccessibleTextRange&) = delete;
+
+ TextRange mRange;
+};
+
+NS_DEFINE_STATIC_IID_ACCESSOR(xpcAccessibleTextRange,
+ NS_ACCESSIBLETEXTRANGE_IMPL_IID)
+
+} // namespace a11y
+} // namespace mozilla
+
+#endif
diff --git a/accessible/xpcom/xpcAccessibleValue.cpp b/accessible/xpcom/xpcAccessibleValue.cpp
new file mode 100644
index 0000000000..f3628ff037
--- /dev/null
+++ b/accessible/xpcom/xpcAccessibleValue.cpp
@@ -0,0 +1,133 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=2 et sw=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "xpcAccessibleGeneric.h"
+#include "Accessible.h"
+
+using namespace mozilla;
+using namespace mozilla::a11y;
+
+NS_IMETHODIMP
+xpcAccessibleValue::GetMaximumValue(double* aValue)
+{
+ NS_ENSURE_ARG_POINTER(aValue);
+ *aValue = 0;
+
+ if (Intl().IsNull())
+ return NS_ERROR_FAILURE;
+
+ if (Intl().IsAccessible() && Intl().AsAccessible()->IsDefunct())
+ return NS_ERROR_FAILURE;
+
+ double value;
+ if (Intl().IsAccessible()) {
+ value = Intl().AsAccessible()->MaxValue();
+ } else {
+ value = Intl().AsProxy()->MaxValue();
+ }
+
+ if (!IsNaN(value))
+ *aValue = value;
+
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+xpcAccessibleValue::GetMinimumValue(double* aValue)
+{
+ NS_ENSURE_ARG_POINTER(aValue);
+ *aValue = 0;
+
+ if (Intl().IsNull())
+ return NS_ERROR_FAILURE;
+
+ if (Intl().IsAccessible() && Intl().AsAccessible()->IsDefunct())
+ return NS_ERROR_FAILURE;
+
+ double value;
+ if (Intl().IsAccessible()) {
+ value = Intl().AsAccessible()->MinValue();
+ } else {
+ value = Intl().AsProxy()->MinValue();
+ }
+
+ if (!IsNaN(value))
+ *aValue = value;
+
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+xpcAccessibleValue::GetCurrentValue(double* aValue)
+{
+ NS_ENSURE_ARG_POINTER(aValue);
+ *aValue = 0;
+
+ if (Intl().IsNull())
+ return NS_ERROR_FAILURE;
+
+ if (Intl().IsAccessible() && Intl().AsAccessible()->IsDefunct())
+ return NS_ERROR_FAILURE;
+
+ double value;
+ if (Intl().IsAccessible()) {
+ value = Intl().AsAccessible()->CurValue();
+ } else {
+ value = Intl().AsProxy()->CurValue();
+ }
+
+ if (!IsNaN(value))
+ *aValue = value;
+
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+xpcAccessibleValue::SetCurrentValue(double aValue)
+{
+ if (Intl().IsNull())
+ return NS_ERROR_FAILURE;
+
+ if (Intl().IsAccessible() && Intl().AsAccessible()->IsDefunct())
+ return NS_ERROR_FAILURE;
+
+ if (Intl().IsAccessible()) {
+ Intl().AsAccessible()->SetCurValue(aValue);
+ } else {
+ Intl().AsProxy()->SetCurValue(aValue);
+ }
+
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+xpcAccessibleValue::GetMinimumIncrement(double* aValue)
+{
+ NS_ENSURE_ARG_POINTER(aValue);
+ *aValue = 0;
+
+ if (Intl().IsNull())
+ return NS_ERROR_FAILURE;
+
+ if (Intl().IsAccessible() && Intl().AsAccessible()->IsDefunct())
+ return NS_ERROR_FAILURE;
+
+ double value;
+ if (Intl().IsAccessible()) {
+ value = Intl().AsAccessible()->Step();
+ } else {
+#if defined(XP_WIN)
+ return NS_ERROR_NOT_IMPLEMENTED;
+#else
+ value = Intl().AsProxy()->Step();
+#endif
+ }
+
+ if (!IsNaN(value))
+ *aValue = value;
+
+ return NS_OK;
+}
diff --git a/accessible/xpcom/xpcAccessibleValue.h b/accessible/xpcom/xpcAccessibleValue.h
new file mode 100644
index 0000000000..740b512b89
--- /dev/null
+++ b/accessible/xpcom/xpcAccessibleValue.h
@@ -0,0 +1,43 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=2 et sw=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef mozilla_a11y_xpcAccessibleValue_h_
+#define mozilla_a11y_xpcAccessibleValue_h_
+
+#include "nsIAccessibleValue.h"
+
+namespace mozilla {
+namespace a11y {
+
+class Accessible;
+
+/**
+ * XPCOM nsIAccessibleValue interface implementation, used by
+ * xpcAccessibleGeneric class.
+ */
+class xpcAccessibleValue : public nsIAccessibleValue
+{
+public:
+ NS_IMETHOD GetMaximumValue(double* aValue) final override;
+ NS_IMETHOD GetMinimumValue(double* aValue) final override;
+ NS_IMETHOD GetCurrentValue(double* aValue) final override;
+ NS_IMETHOD SetCurrentValue(double aValue) final override;
+ NS_IMETHOD GetMinimumIncrement(double* aMinIncrement) final override;
+
+protected:
+ xpcAccessibleValue() { }
+ virtual ~xpcAccessibleValue() {}
+
+private:
+ AccessibleOrProxy Intl();
+
+ xpcAccessibleValue(const xpcAccessibleValue&) = delete;
+ xpcAccessibleValue& operator =(const xpcAccessibleValue&) = delete;
+};
+
+} // namespace a11y
+} // namespace mozilla
+#endif