initial Pale Moon 26.5 Atom source import

This commit is contained in:
2017-12-25 15:08:46 +08:00
commit 8e117cd595
80808 changed files with 13910601 additions and 0 deletions
+181
View File
@@ -0,0 +1,181 @@
# .gdbinit file for debugging Mozilla
# You may need to put an 'add-auto-load-safe-path' command in your
# $HOME/.gdbinit file to get GDB to trust this file. If your builds are
# generally in $HOME/moz, then you can say:
#
# add-auto-load-safe-path ~/moz
# Don't stop for the SIG32/33/etc signals that Flash produces
handle SIG32 noprint nostop pass
handle SIG33 noprint nostop pass
handle SIGPIPE noprint nostop pass
# Show the concrete types behind nsIFoo
set print object on
# run when using the auto-solib-add trick
def prun
tbreak main
run
set auto-solib-add 0
cont
end
# run -mail, when using the auto-solib-add trick
def pmail
tbreak main
run -mail
set auto-solib-add 0
cont
end
# Define a "pu" command to display PRUnichar * strings (100 chars max)
# Also allows an optional argument for how many chars to print as long as
# it's less than 100.
def pu
set $uni = $arg0
if $argc == 2
set $limit = $arg1
if $limit > 100
set $limit = 100
end
else
set $limit = 100
end
# scratch array with space for 100 chars plus null terminator. Make
# sure to not use ' ' as the char so this copy/pastes well.
set $scratch = "____________________________________________________________________________________________________"
set $i = 0
set $scratch_idx = 0
while (*$uni && $i++ < $limit)
if (*$uni < 0x80)
set $scratch[$scratch_idx++] = *(char*)$uni++
else
if ($scratch_idx > 0)
set $scratch[$scratch_idx] = '\0'
print $scratch
set $scratch_idx = 0
end
print /x *(short*)$uni++
end
end
if ($scratch_idx > 0)
set $scratch[$scratch_idx] = '\0'
print $scratch
end
end
# Define a "ps" command to display subclasses of nsAC?String. Note that
# this assumes strings as of Gecko 1.9 (well, and probably a few
# releases before that as well); going back far enough will get you
# to string classes that this function doesn't work for.
def ps
set $str = $arg0
if (sizeof(*$str.mData) == 1 && ($str.mFlags & 1) != 0)
print $str.mData
else
pu $str.mData $str.mLength
end
end
# Define a "pa" command to display the string value for an nsIAtom
def pa
set $atom = $arg0
if (sizeof(*((&*$atom)->mString)) == 2)
pu (&*$atom)->mString
end
end
# define a "pxul" command to display the type of a XUL element from
# an nsXULElement* pointer.
def pxul
set $p = $arg0
print $p->mNodeInfo.mRawPtr->mInner.mName->mStaticAtom->mString
end
# define a "prefcnt" command to display the refcount of an XPCOM obj
def prefcnt
set $p = $arg0
print ((nsPurpleBufferEntry*)$p->mRefCnt.mTagged)->mRefCnt
end
# define a "ptag" command to display the tag name of a content node
def ptag
set $p = $arg0
pa $p->mNodeInfo.mRawPtr->mInner.mName
end
##
## nsTArray
##
define ptarray
if $argc == 0
help ptarray
else
set $size = $arg0.mHdr->mLength
set $capacity = $arg0.mHdr->mCapacity
set $size_max = $size - 1
set $elts = $arg0.Elements()
end
if $argc == 1
set $i = 0
while $i < $size
printf "elem[%u]: ", $i
p *($elts + $i)
set $i++
end
end
if $argc == 2
set $idx = $arg1
if $idx < 0 || $idx > $size_max
printf "idx1, idx2 are not in acceptable range: [0..%u].\n", $size_max
else
printf "elem[%u]: ", $idx
p *($elts + $idx)
end
end
if $argc == 3
set $start_idx = $arg1
set $stop_idx = $arg2
if $start_idx > $stop_idx
set $tmp_idx = $start_idx
set $start_idx = $stop_idx
set $stop_idx = $tmp_idx
end
if $start_idx < 0 || $stop_idx < 0 || $start_idx > $size_max || $stop_idx > $size_max
printf "idx1, idx2 are not in acceptable range: [0..%u].\n", $size_max
else
set $i = $start_idx
while $i <= $stop_idx
printf "elem[%u]: ", $i
p *($elts + $i)
set $i++
end
end
end
if $argc > 0
printf "nsTArray length = %u\n", $size
printf "nsTArray capacity = %u\n", $capacity
printf "Element "
whatis *$elts
end
end
document ptarray
Prints nsTArray information.
Syntax: ptarray
Note: idx, idx1 and idx2 must be in acceptable range [0...size()-1].
Examples:
ptarray a - Prints tarray content, size, capacity and T typedef
ptarray a 0 - Prints element[idx] from tarray
ptarray a 1 2 - Prints elements in range [idx1..idx2] from tarray
end
def js
call DumpJSStack()
end
def ft
call nsFrame::DumpFrameTree($arg0)
end
+1
View File
@@ -0,0 +1 @@
* -text
+66
View File
@@ -0,0 +1,66 @@
# .gitignore - List of filenames git should ignore
# Filenames that should be ignored wherever they appear
*~
*.rej
*.orig
*.pyc
*.pyo
TAGS
tags
ID
.DS_Store*
# Vim swap files.
.*.sw[a-z]
# User files that may appear at the root
/.mozconfig*
/mozconfig
/configure
/config.cache
/config.log
/.clang_complete
/mach.ini
# Empty marker file that's generated when we check out NSS
security/manager/.nss.checkout
# Build directories
/obj*/
/build-*/
# Build directories for js shell
*/_DBG.OBJ/
*/_OPT.OBJ/
# SpiderMonkey configury
js/src/configure
js/src/autom4te.cache
# SpiderMonkey test result logs
js/src/tests/results-*.html
js/src/tests/results-*.txt
# Java HTML5 parser classes
parser/html/java/htmlparser/
parser/html/java/javaparser/
# Ignore the files and directory that Eclipse IDE creates
.project
.cproject
.settings/
# Python virtualenv artifacts.
python/psutil/*.so
python/psutil/*.pyd
python/psutil/build/
# Ignore chrome.manifest files from the devtools loader
browser/devtools/chrome.manifest
toolkit/devtools/chrome.manifest
# Ignore misc files that need not be in the repo
other-licenses/7zstub/firefox/7zSD - Copy.sfx.exe
# Ignore official beta branding
browser/branding/officialbeta/
+1077
View File
File diff suppressed because it is too large Load Diff
+5
View File
@@ -0,0 +1,5 @@
# 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/.
# empty file to block B2G/Gonk from trying to build anything inside mozilla-central
+21
View File
@@ -0,0 +1,21 @@
# To Trigger a clobber replace ALL of the textual description below,
# giving a bug number and a one line description of why a clobber is
# required. Modifying this file will make configure check that a
# clobber has been performed before the build can continue.
#
# MERGE NOTE: When merging two branches that require a CLOBBER, you should
# merge both CLOBBER descriptions, to ensure that users on
# both branches correctly see the clobber warning.
#
# O <-- Users coming from both parents need to Clobber
# / \
# O O
# | |
# O <-- Clobber O <-- Clobber
#
# Note: The description below will be part of the error message shown to users.
#
# Modifying this file will now automatically clobber the buildbot machines \o/
#
Clobber required for addition of the URL API.
+14
View File
@@ -0,0 +1,14 @@
Please see the file toolkit/content/license.html for the copyright licensing
conditions attached to this codebase, including copies of the licenses
concerned.
For more information about source code licensing, see:
http://www.palemoon.org/licensing.shtml
You are not granted rights or licenses to the intellectual property or trademarks
of the Mozilla Foundation, Moonchild Productions, or any other party, including
without limitation the Pale Moon name or logo.
Binary versions of Pale Moon are subject to the Pale Moon redistribution license.
For more information, see: http://www.palemoon.org/redist.shtml
+167
View File
@@ -0,0 +1,167 @@
#
# 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/.
DEPTH = @DEPTH@
topsrcdir = @top_srcdir@
srcdir = @srcdir@
VPATH = @srcdir@
ifndef .PYMAKE
ifeq (,$(MAKE_VERSION))
$(error GNU Make is required)
endif
ifeq (,$(filter-out 3.78 3.79,$(MAKE_VERSION)))
$(error GNU Make 3.80 or higher is required)
endif
endif
export TOPLEVEL_BUILD := 1
include $(DEPTH)/config/autoconf.mk
default::
ifdef COMPILE_ENVIRONMENT
include $(topsrcdir)/$(MOZ_BUILD_APP)/build.mk
endif
include $(topsrcdir)/config/config.mk
GARBAGE_DIRS += dist _javagen _profile _tests staticlib
DIST_GARBAGE = config.cache config.log config.status* config-defs.h \
config/autoconf.mk \
unallmakefiles mozilla-config.h \
netwerk/necko-config.h xpcom/xpcom-config.h xpcom/xpcom-private.h \
$(topsrcdir)/.mozconfig.mk $(topsrcdir)/.mozconfig.out
ifndef MOZ_PROFILE_USE
# We need to explicitly put backend.RecursiveMakeBackend.built here
# otherwise the rule in rules.mk doesn't run early enough.
default alldep all:: CLOBBER $(topsrcdir)/configure config.status backend.RecursiveMakeBackend.built
$(RM) -r $(DIST)/sdk
$(RM) -r $(DIST)/include
$(RM) -r $(DIST)/private
$(RM) -r $(DIST)/public
$(RM) -r $(DIST)/bin
$(RM) -r _tests
endif
CLOBBER: $(topsrcdir)/CLOBBER
@echo "STOP! The CLOBBER file has changed."
@echo "Please run the build through a sanctioned build wrapper, such as"
@echo "'mach build' or client.mk."
@exit 1
$(topsrcdir)/configure: $(topsrcdir)/configure.in
@echo "STOP! configure.in has changed, and your configure is out of date."
@echo "Please rerun autoconf and re-configure your build directory."
@echo "To ignore this message, touch 'configure' in the source directory,"
@echo "but your build might not succeed."
@exit 1
config.status: $(topsrcdir)/configure
@echo "STOP! configure has changed and needs to be run in this build directory."
@echo "Please rerun configure."
@echo "To ignore this message, touch 'config.status' in the build directory,"
@echo "but your build might not succeed."
@exit 1
# Build pseudo-external modules first when export is explicitly called
export::
$(RM) -r $(DIST)/sdk
$(MAKE) -C config export
$(MAKE) tier_nspr
ifdef ENABLE_TESTS
# Additional makefile targets to call automated test suites
include $(topsrcdir)/testing/testsuite-targets.mk
endif
include $(topsrcdir)/config/rules.mk
distclean::
cat unallmakefiles | $(XARGS) rm -f
$(RM) unallmakefiles $(DIST_GARBAGE)
ifeq ($(OS_ARCH),WINNT)
# we want to copy PDB files on Windows
MAKE_SYM_STORE_ARGS := -c --vcs-info
ifdef PDBSTR_PATH
MAKE_SYM_STORE_ARGS += -i
endif
# PDB files don't get moved to dist, so we need to scan the whole objdir
MAKE_SYM_STORE_PATH := .
endif
ifeq ($(OS_ARCH),Darwin)
# need to pass arch flags for universal builds
ifdef UNIVERSAL_BINARY
MAKE_SYM_STORE_ARGS := -c -a "i386 x86_64" --vcs-info
MAKE_SYM_STORE_PATH := $(DIST)/universal
else
MAKE_SYM_STORE_ARGS := -c -a $(OS_TEST) --vcs-info
MAKE_SYM_STORE_PATH := $(DIST)/bin
endif
DUMP_SYMS_BIN ?= $(DIST)/host/bin/dump_syms
endif
ifeq (,$(filter-out Linux SunOS,$(OS_ARCH)))
MAKE_SYM_STORE_ARGS := -c --vcs-info
DUMP_SYMS_BIN ?= $(DIST)/host/bin/dump_syms
MAKE_SYM_STORE_PATH := $(DIST)/bin
endif
SYM_STORE_SOURCE_DIRS := $(topsrcdir)
include $(topsrcdir)/toolkit/mozapps/installer/package-name.mk
ifdef MOZ_SYMBOLS_EXTRA_BUILDID
EXTRA_BUILDID := -$(MOZ_SYMBOLS_EXTRA_BUILDID)
endif
SYMBOL_INDEX_NAME = \
$(MOZ_APP_NAME)-$(MOZ_APP_VERSION)-$(OS_TARGET)-$(BUILDID)-$(CPU_ARCH)$(EXTRA_BUILDID)-symbols.txt
buildsymbols:
uploadsymbols:
codesighs:
$(MAKE) -C $(MOZ_BUILD_APP)/installer codesighs
# defined in package-name.mk
export MOZ_SOURCE_STAMP
#XXX: this is a hack, since we don't want to clobber for MSVC
# PGO support, but we can't do this test in client.mk
ifneq ($(OS_ARCH)_$(GNU_CC), WINNT_)
# No point in clobbering if PGO has been explicitly disabled.
ifndef NO_PROFILE_GUIDED_OPTIMIZE
maybe_clobber_profiledbuild: clean
else
maybe_clobber_profiledbuild:
endif
else
maybe_clobber_profiledbuild:
$(RM) $(DIST)/bin/*.pgc
find $(DIST)/$(MOZ_APP_NAME) -name "*.pgc" -exec mv {} $(DIST)/bin \;
endif
.PHONY: maybe_clobber_profiledbuild
# Look for R_386_PC32 relocations in shared libs, these
# break x86_64 builds and SELinux users.
ifeq ($(OS_TARGET)_$(TARGET_XPCOM_ABI),Linux_x86-gcc3)
scheck::
@relcount=`find $(DIST)/bin -name "*.so" | xargs objdump -R | grep R_386_PC32 | wc -l` && if test $$relcount -gt 0; then echo "FAILED: R_386_PC32 relocations detected in a shared library. Did you use a system header without adding it to config/system-headers?"; exit 1; else echo "PASSED"; fi
endif
js/src/Makefile: subsrcdir := js/src
ifdef ENABLE_TESTS
# Incorporate static tier directories into tests. This should be incorporated
# into moz.build files someday.
check::
$(call SUBMAKE,$@,js/src)
endif
+15
View File
@@ -0,0 +1,15 @@
#Pale Moon web browser
This is the source code for the Pale Moon web browser, an independent
browser derived from Firefox/Mozilla community code. The source tree is
mostly laid out like other Mozilla-based products.
An explanation of the Mozilla Source Code Directory Structure and links to
project pages with documentation can be found at:
https://developer.mozilla.org/en/Mozilla_Source_Code_Directory_Structure
For information on how to build Pale Moon yourself from this source code, see:
http://forum.palemoon.org/viewtopic.php?f=19&t=4166
+11
View File
@@ -0,0 +1,11 @@
# -*- Mode: python; c-basic-offset: 4; 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/.
DIRS += ['public', 'src']
TEST_DIRS += ['tests']
MODULE = 'accessibility'
+10
View File
@@ -0,0 +1,10 @@
;+# 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/.
LIBRARY IA2Marshal.dll
EXPORTS DllGetClassObject PRIVATE
DllCanUnloadNow PRIVATE
DllRegisterServer PRIVATE
DllUnregisterServer PRIVATE
+95
View File
@@ -0,0 +1,95 @@
# 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/.
DEPTH = @DEPTH@
topsrcdir = @top_srcdir@
srcdir = @srcdir@
VPATH = @srcdir@
DEFFILE = $(win_srcdir)/IA2Marshal.def
IA2DIR = $(topsrcdir)/other-licenses/ia2
include $(DEPTH)/config/autoconf.mk
DEFINES += -DREGISTER_PROXY_DLL
GARBAGE += $(MIDL_GENERATED_FILES)
FORCE_SHARED_LIB = 1
# Please keep this list in sync with the moz.build file until the rest of this
# Makefile is ported over.
MIDL_INTERFACES = \
Accessible2.idl \
Accessible2_2.idl \
AccessibleAction.idl \
AccessibleApplication.idl \
AccessibleComponent.idl \
AccessibleDocument.idl \
AccessibleEditableText.idl \
AccessibleHyperlink.idl \
AccessibleHypertext.idl \
AccessibleHypertext2.idl \
AccessibleImage.idl \
AccessibleRelation.idl \
AccessibleTable.idl \
AccessibleTable2.idl \
AccessibleTableCell.idl \
AccessibleText.idl \
AccessibleText2.idl \
AccessibleValue.idl \
$(NULL)
# Please keep this list in sync with the moz.build file until the rest of this
# Makefile is ported over.
MIDL_ENUMS = \
AccessibleEventId.idl \
AccessibleRole.idl \
AccessibleStates.idl \
IA2CommonTypes.idl \
$(NULL)
CSRCS = \
dlldata.c \
$(MIDL_INTERFACES:%.idl=%_p.c) \
$(MIDL_INTERFACES:%.idl=%_i.c) \
$(NULL)
MIDL_GENERATED_FILES = \
dlldata.c \
$(MIDL_INTERFACES:%.idl=%_p.c) \
$(MIDL_INTERFACES:%.idl=%_i.c) \
$(MIDL_INTERFACES:%.idl=%.h) \
$(MIDL_ENUMS:%.idl=%.h) \
$(NULL)
EMBED_MANIFEST_AT = 2
include $(topsrcdir)/config/rules.mk
OS_LIBS = $(call EXPAND_LIBNAME,uuid kernel32 rpcns4 rpcrt4 ole32 oleaut32)
# generate list of to-be-generated files that are missing
# but ignore special file dlldata.c
missing:=$(strip $(foreach onefile,$(strip $(subst dlldata.c,,$(MIDL_GENERATED_FILES))),$(if $(wildcard $(onefile)),,$(onefile))))
missing_base:=$(sort $(basename $(subst _p.c,,$(subst _i.c,,$(missing)))))
$(MIDL_GENERATED_FILES) : midl_done
ifneq ("$(missing)","")
midl_done : FORCE
endif
midl_done : $(addprefix $(IA2DIR)/,$(MIDL_INTERFACES) $(MIDL_ENUMS))
for idl in $(sort $(subst FORCE,,$?) $(addsuffix .idl,$(addprefix $(IA2DIR)/,$(missing_base)))); do \
$(MIDL) $(MIDL_FLAGS) -app_config -I $(IA2DIR) -Oicf $$idl; \
done
touch $@
# This marshall dll is also registered in the installer
register::
regsvr32 -s $(DIST)/bin/$(SHARED_LIBRARY)
+53
View File
@@ -0,0 +1,53 @@
# -*- Mode: python; c-basic-offset: 4; 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/.
MODULE = 'accessibility'
# Please keep this list in sync with the Makefile.in until the rest of that file
# is ported over.
midl_interfaces = [
'Accessible2',
'Accessible2_2',
'AccessibleAction',
'AccessibleApplication',
'AccessibleComponent',
'AccessibleDocument',
'AccessibleEditableText',
'AccessibleHyperlink',
'AccessibleHypertext',
'AccessibleHypertext2',
'AccessibleImage',
'AccessibleRelation',
'AccessibleTable',
'AccessibleTable2',
'AccessibleTableCell',
'AccessibleText',
'AccessibleText2',
'AccessibleValue',
]
# Please keep this list in sync with the Makefile.in until the rest of that file
# is ported over.
midl_enums = [
'AccessibleEventId',
'AccessibleRole',
'AccessibleStates',
'IA2CommonTypes',
]
headers = ['%s.h' % x for x in midl_enums]
interfaces_h = ['%s.h' % x for x in midl_interfaces]
interfaces_c = ['%s_i.c' % x for x in midl_interfaces]
# The underscore throws off sorting and EXPORTS expects sorted lists.
interfaces_c.sort()
EXPORTS += headers
EXPORTS += interfaces_h
EXPORTS += interfaces_c
LIBRARY_NAME = 'IA2Marshal'
+44
View File
@@ -0,0 +1,44 @@
# -*- Mode: python; c-basic-offset: 4; 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/.
if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'windows':
DIRS += ['msaa', 'ia2']
XPIDL_SOURCES += [
'nsIAccessible.idl',
'nsIAccessibleApplication.idl',
'nsIAccessibleCaretMoveEvent.idl',
'nsIAccessibleDocument.idl',
'nsIAccessibleEditableText.idl',
'nsIAccessibleEvent.idl',
'nsIAccessibleHideEvent.idl',
'nsIAccessibleHyperLink.idl',
'nsIAccessibleHyperText.idl',
'nsIAccessibleImage.idl',
'nsIAccessiblePivot.idl',
'nsIAccessibleProvider.idl',
'nsIAccessibleRelation.idl',
'nsIAccessibleRetrieval.idl',
'nsIAccessibleRole.idl',
'nsIAccessibleSelectable.idl',
'nsIAccessibleStateChangeEvent.idl',
'nsIAccessibleStates.idl',
'nsIAccessibleTable.idl',
'nsIAccessibleTableChangeEvent.idl',
'nsIAccessibleText.idl',
'nsIAccessibleTextChangeEvent.idl',
'nsIAccessibleTypes.idl',
'nsIAccessibleValue.idl',
'nsIAccessibleVirtualCursorChangeEvent.idl',
'nsIXBLAccessible.idl',
]
MODULE = 'accessibility'
EXPORTS += [
'nsIAccessibilityService.h',
]
@@ -0,0 +1,11 @@
;+# 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/.
LIBRARY AccessibleMarshal.dll
EXPORTS DllGetClassObject PRIVATE
DllCanUnloadNow PRIVATE
DllRegisterServer PRIVATE
DllUnregisterServer PRIVATE
@@ -0,0 +1,83 @@
/* -*- 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/. */
cpp_quote("///////////////////////////////////////////////////////////////////////////////////////////////////////")
cpp_quote("//")
cpp_quote("// ISimpleDOMDocument")
cpp_quote("// ---------------------------------------------------------------------------------------------------=")
cpp_quote("//")
cpp_quote("// get_URL(out] BSTR *url)")
cpp_quote("// ---------------------------------------------------------------------------------------------------=")
cpp_quote("// Get the internet URL associated with this document.")
cpp_quote("//")
cpp_quote("// get_title([out BSTR *title")
cpp_quote("// ---------------------------------------------------------------------------------------------------=")
cpp_quote("// Get the document's title from the <TITLE> element")
cpp_quote("//")
cpp_quote("// get_mimeType([out BSTR *mimeType")
cpp_quote("// ---------------------------------------------------------------------------------------------------=")
cpp_quote("// Get the registered mime type, such as text/html")
cpp_quote("//")
cpp_quote("// get_docType([out] BSTR *docType")
cpp_quote("// ---------------------------------------------------------------------------------------------------=")
cpp_quote("// Get doctype associated with the <!DOCTYPE ..> element")
cpp_quote("//")
cpp_quote("// get_nameSpaceURIForID([in] short nameSpaceID, [out] BSTR *nameSpaceURI)")
cpp_quote("// ---------------------------------------------------------------------------------------------------=")
cpp_quote("// Some of the methods for ISimpleDOMNode return a nameSpaceID (-1,0,1,2,3,....)")
cpp_quote("// This method returns the associated namespace URI for each ID.")
cpp_quote("//")
cpp_quote("// set_alternateViewMediaTypes([in] BSTR *commaSeparatedMediaType)")
cpp_quote("// ---------------------------------------------------------------------------------------------------=")
cpp_quote("// For style property retrieval on nsISimpleDOMNode elements, ")
cpp_quote("// set the additional alternate media types that properties are available for.")
cpp_quote("// [in] BSTR *commaSeparatedMediaTypes is a comma separate list, for example \"aural, braille\".")
cpp_quote("// The alternate media properties are requested with nsISimpleDOMNode::get_computedStyle.")
cpp_quote("// Note: setting this value on a document will increase memory overhead, and may create a small delay.")
cpp_quote("//")
cpp_quote("// W3C media Types:")
cpp_quote("// * all: Suitable for all devices. ")
cpp_quote("// * aural: Intended for speech synthesizers. See the section on aural style sheets for details. ")
cpp_quote("// * braille: Intended for braille tactile feedback devices. ")
cpp_quote("// * embossed: Intended for paged braille printers. ")
cpp_quote("// * handheld: Intended for handheld devices - typically small screen, monochrome, limited bandwidth. ")
cpp_quote("// * print: Intended for paged, opaque material and for documents viewed on screen in print preview mode. Please consult the section on paged media for information about formatting issues that are specific to paged media. ")
cpp_quote("// * projection: Intended for projected presentations, for example projectors or print to transparencies. Please consult the section on paged media for information about formatting issues that are specific to paged media. ")
cpp_quote("// * screen: Intended primarily for color computer screens. ")
cpp_quote("// * tty: intended for media using a fixed-pitch character grid, such as teletypes, terminals, or portable devices with limited display capabilities. Authors should not use pixel units with the tty media type. ")
cpp_quote("// * tv: Intended for television-type devices - low resolution, color, limited-scrollability screens, sound")
cpp_quote("// * See latest W3C CSS specs for complete list of media types")
cpp_quote("//")
cpp_quote("//")
cpp_quote("///////////////////////////////////////////////////////////////////////////////////////////////////////")
cpp_quote("")
cpp_quote("")
import "objidl.idl";
import "oaidl.idl";
[object, uuid(0D68D6D0-D93D-4d08-A30D-F00DD1F45B24)]
interface ISimpleDOMDocument : IUnknown
{
[propget] HRESULT URL(
[out, retval] BSTR * url
);
[propget] HRESULT title(
[out, retval] BSTR * title
);
[propget] HRESULT mimeType(
[out, retval] BSTR * mimeType
);
[propget] HRESULT docType(
[out, retval] BSTR * docType
);
[propget] HRESULT nameSpaceURIForID(
[in] short nameSpaceID,
[out, retval] BSTR * nameSpaceURI
);
[propput] HRESULT alternateViewMediaTypes(
[in] BSTR * commaSeparatedMediaTypes
);
}
+188
View File
@@ -0,0 +1,188 @@
/* -*- 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/. */
cpp_quote("///////////////////////////////////////////////////////////////////////////////////////////////////////")
cpp_quote("//")
cpp_quote("// ISimpleDOMNode")
cpp_quote("// ---------------------------------------------------------------------------------------------------=")
cpp_quote("// An interface that extends MSAA's IAccessible to provide readonly DOM node information via cross-process COM.")
cpp_quote("//")
cpp_quote("// get_nodeInfo(")
cpp_quote("// /* [out] */ BSTR *nodeName, // For elements, this is the tag name")
cpp_quote("// /* [out] */ short *nameSpaceID,")
cpp_quote("// /* [out] */ BSTR *nodeValue, ")
cpp_quote("// /* [out] */ unsigned int *numChildren); ")
cpp_quote("// /* [out] */ unsigned int *uniqueID; // In Win32 accessible events we generate, the target's childID matches to this")
cpp_quote("// /* [out] */ unsigned short *nodeType,")
cpp_quote("// ---------------------------------------------------------------------------------------------------=")
cpp_quote("// Get the basic information about a node.")
cpp_quote("// The namespace ID can be mapped to an URI using nsISimpleDOMDocument::get_nameSpaceURIForID()")
cpp_quote("//")
cpp_quote("// get_attributes(")
cpp_quote("// /* [in] */ unsigned short maxAttribs,")
cpp_quote("// /* [out] */ unsigned short *numAttribs,")
cpp_quote("// /* [out] */ BSTR *attribNames,")
cpp_quote("// /* [out] */ short *nameSpaceID,")
cpp_quote("// /* [out] */ BSTR *attribValues);")
cpp_quote("// ---------------------------------------------------------------------------------------------------=")
cpp_quote("// Returns 3 arrays - the attribute names and values, and a namespace ID for each")
cpp_quote("// If the namespace ID is 0, it's the same namespace as the node's namespace")
cpp_quote("//")
cpp_quote("// get_attributesForNames(")
cpp_quote("// /* [in] */ unsigned short numAttribs,")
cpp_quote("// /* [in] */ BSTR *attribNames,")
cpp_quote("// /* [in] */ short *nameSpaceID,")
cpp_quote("// /* [out] */ BSTR *attribValues);")
cpp_quote("// ---------------------------------------------------------------------------------------------------=")
cpp_quote("// Takes 2 arrays - the attribute names and namespace IDs, and returns an array of corresponding values")
cpp_quote("// If the namespace ID is 0, it's the same namespace as the node's namespace")
cpp_quote("//")
cpp_quote("// computedStyle( ")
cpp_quote("// /* [in] */ unsigned short maxStyleProperties,")
cpp_quote("// /* [out] */ unsigned short *numStyleProperties, ")
cpp_quote("// /* [in] */ boolean useAlternateView, // If TRUE, returns properites for media as set in nsIDOMDocument::set_alternateViewMediaTypes")
cpp_quote("// /* [out] */ BSTR *styleProperties, ")
cpp_quote("// /* [out] */ BSTR *styleValues);")
cpp_quote("// ---------------------------------------------------------------------------------------------------=")
cpp_quote("// Returns 2 arrays -- the style properties and their values")
cpp_quote("// useAlternateView=FALSE: gets properties for the default media type (usually screen)")
cpp_quote("// useAlternateView=TRUE: properties for media types set w/ nsIDOMSimpleDocument::set_alternateViewMediaTypes()")
cpp_quote("//")
cpp_quote("// computedStyleForProperties( ")
cpp_quote("// /* [in] */ unsigned short numStyleProperties, ")
cpp_quote("// /* [in] */ boolean useAlternateView, // If TRUE, returns properites for media as set in nsIDOMDocument::set_alternateViewMediaTypes")
cpp_quote("// /* [in] */ BSTR *styleProperties, ")
cpp_quote("// /* [out] */ BSTR *styleValues);")
cpp_quote("// ---------------------------------------------------------------------------------------------------=")
cpp_quote("// Scroll the current view so that this dom node is visible.")
cpp_quote("// placeTopLeft=TRUE: scroll until the top left corner of the dom node is at the top left corner of the view.")
cpp_quote("// placeTopLeft=FALSE: scroll minimally to make the dom node visible. Don't scroll at all if already visible.")
cpp_quote("//")
cpp_quote("// scrollTo( ")
cpp_quote("// /* [in] */ boolean placeTopLeft); ")
cpp_quote("// ---------------------------------------------------------------------------------------------------=")
cpp_quote("// Returns style property values for those properties in the styleProperties [in] array")
cpp_quote("// Returns 2 arrays -- the style properties and their values")
cpp_quote("// useAlternateView=FALSE: gets properties for the default media type (usually screen)")
cpp_quote("// useAlternateView=TRUE: properties for media types set w/ nsIDOMSimpleDocument::set_alternateViewMediaTypes()")
cpp_quote("//")
cpp_quote("// get_parentNode (/* [out] */ ISimpleDOMNode **newNodePtr);")
cpp_quote("// get_firstChild (/* [out] */ ISimpleDOMNode **newNodePtr);")
cpp_quote("// get_lastChild (/* [out] */ ISimpleDOMNode **newNodePtr);")
cpp_quote("// get_previousSibling(/* [out] */ ISimpleDOMNode **newNodePtr);")
cpp_quote("// get_nextSibling (/* [out] */ ISimpleDOMNode **newNodePtr);")
cpp_quote("// get_childAt (/* [in] */ unsigned childIndex, /* [out] */ ISimpleDOMNode **newNodePtr);")
cpp_quote("// ---------------------------------------------------------------------------------------------------=")
cpp_quote("// DOM navigation - get a different node.")
cpp_quote("//")
cpp_quote("// get_innerHTML(/* [out] */ BSTR *htmlText);")
cpp_quote("// ---------------------------------------------------------------------------------------------------=")
cpp_quote("// Returns HTML of this DOM node's subtree. Does not include the start and end tag for this node/element.")
cpp_quote("//")
cpp_quote("//")
cpp_quote("// get_localInterface(/* [out] */ void **localInterface);")
cpp_quote("// ---------------------------------------------------------------------------------------------------=")
cpp_quote("// Only available in Goanna's process - casts to an XPCOM nsAccessNode object pointer")
cpp_quote("//")
cpp_quote("//")
cpp_quote("// get_language(/* [out] */ BSTR *htmlText);")
cpp_quote("// ---------------------------------------------------------------------------------------------------=")
cpp_quote("// Returns the computed language for this node, or empty string if unknown.")
cpp_quote("//")
cpp_quote("//")
cpp_quote("///////////////////////////////////////////////////////////////////////////////////////////////////////")
cpp_quote("")
cpp_quote("")
import "objidl.idl";
import "oaidl.idl";
import "ISimpleDOMText.idl";
import "ISimpleDOMDocument.idl";
[object, uuid(1814ceeb-49e2-407f-af99-fa755a7d2607)]
interface ISimpleDOMNode : IUnknown
{
const unsigned short NODETYPE_ELEMENT = 1;
const unsigned short NODETYPE_ATTRIBUTE = 2;
const unsigned short NODETYPE_TEXT = 3;
const unsigned short NODETYPE_CDATA_SECTION = 4;
const unsigned short NODETYPE_ENTITY_REFERENCE = 5;
const unsigned short NODETYPE_ENTITY = 6;
const unsigned short NODETYPE_PROCESSING_INSTRUCTION = 7;
const unsigned short NODETYPE_COMMENT = 8;
const unsigned short NODETYPE_DOCUMENT = 9;
const unsigned short NODETYPE_DOCUMENT_TYPE = 10;
const unsigned short NODETYPE_DOCUMENT_FRAGMENT = 11;
const unsigned short NODETYPE_NOTATION = 12;
[propget] HRESULT nodeInfo(
[out] BSTR *nodeName, // for performance returns NULL for text nodes (true nodeName would be "#text")
[out] short *nameSpaceID,
[out] BSTR *nodeValue,
[out] unsigned int *numChildren,
[out] unsigned int *uniqueID, // In Win32 accessible events we generate, the target's childID matches to this
[out, retval] unsigned short *nodeType
);
[propget] HRESULT attributes(
[in] unsigned short maxAttribs,
[out, size_is(maxAttribs), length_is(*numAttribs)] BSTR *attribNames,
[out, size_is(maxAttribs), length_is(*numAttribs)] short *nameSpaceID,
[out, size_is(maxAttribs), length_is(*numAttribs)] BSTR *attribValues,
[out, retval] unsigned short *numAttribs
);
[propget] HRESULT attributesForNames(
[in] unsigned short numAttribs,
[in, size_is(numAttribs), length_is(numAttribs)] BSTR *attribNames,
[in, size_is(numAttribs), length_is(numAttribs)] short *nameSpaceID,
[out, retval, size_is(numAttribs), length_is(numAttribs)] BSTR *attribValues
);
[propget] HRESULT computedStyle(
[in] unsigned short maxStyleProperties,
[in] boolean useAlternateView, // If TRUE, returns properites for media as set in nsIDOMDocument::set_alternateViewMediaTypes
[out, size_is(maxStyleProperties), length_is(*numStyleProperties)] BSTR *styleProperties,
[out, size_is(maxStyleProperties), length_is(*numStyleProperties)] BSTR *styleValues,
[out, retval] unsigned short *numStyleProperties
);
[propget] HRESULT computedStyleForProperties(
[in] unsigned short numStyleProperties,
[in] boolean useAlternateView, // If TRUE, returns properites for media as set in nsIDOMDocument::set_alternateViewMediaTypes
[in, size_is(numStyleProperties), length_is(numStyleProperties)] BSTR *styleProperties,
[out, retval, size_is(numStyleProperties), length_is(numStyleProperties)] BSTR *styleValues
);
HRESULT scrollTo([in] boolean placeTopLeft);
[propget] HRESULT parentNode([out, retval] ISimpleDOMNode **node);
[propget] HRESULT firstChild([out, retval] ISimpleDOMNode **node);
[propget] HRESULT lastChild([out, retval] ISimpleDOMNode **node);
[propget] HRESULT previousSibling([out, retval] ISimpleDOMNode **node);
[propget] HRESULT nextSibling([out, retval] ISimpleDOMNode **node);
[propget] HRESULT childAt([in] unsigned childIndex,
[out, retval] ISimpleDOMNode **node);
[propget] HRESULT innerHTML([out, retval] BSTR *innerHTML);
[propget, local] HRESULT localInterface([out][retval] void **localInterface);
[propget] HRESULT language([out, retval] BSTR *language);
}
[
uuid(a6245497-9c0b-4449-85a5-bd6ad07df8ea),
helpstring("ISimpleDOM Type Library")
]
library ISimpleDOM
{
interface ISimpleDOMNode;
interface ISimpleDOMText;
interface ISimpleDOMDocument;
};
+79
View File
@@ -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/. */
import "objidl.idl";
import "oaidl.idl";
cpp_quote("///////////////////////////////////////////////////////////////////////////////////////////////////////")
cpp_quote("//")
cpp_quote("// ISimpleDOMText")
cpp_quote("// ---------------------------------------------------------------------------------------------------=")
cpp_quote("// An interface that extends MSAA's IAccessible to provide important additional capabilities on text nodes")
cpp_quote("//")
cpp_quote("// [propget] domText(/* out,retval */ BSTR *domText")
cpp_quote("// ---------------------------------------------------------------------------------------------------=")
cpp_quote("// Similar to IAccessible::get_accName, but does not strip out whitespace characters.")
cpp_quote("// Important for retrieving the correct start/end substring indices to use with other")
cpp_quote("// methods in ISimpleDOMText.")
cpp_quote("//")
cpp_quote("//")
cpp_quote("// get_[un]clippedSubstringBounds(")
cpp_quote("// /* [in] */ unsigned int startIndex,")
cpp_quote("// /* [in] */ unsigned int endIndex,")
cpp_quote("// /* [out] */ int *x,")
cpp_quote("// /* [out] */ int *y,")
cpp_quote("// /* [out] */ int *width,")
cpp_quote("// /* [out] */ int *height);")
cpp_quote("// ---------------------------------------------------------------------------------------------------=")
cpp_quote("// Both methods get_clippedSubstringBounds and get_unclippedSubstringBounds return the screen pixel")
cpp_quote("// coordinates of the given text substring. The in parameters for start and end indices refer")
cpp_quote("// to the string returned by ISimpleDOMText::get_domText().")
cpp_quote("//")
cpp_quote("//")
cpp_quote("// scrollToSubstring(")
cpp_quote("// /* [in] */ unsigned int startIndex,")
cpp_quote("// /* [in] */ unsigned int endIndex);")
cpp_quote("// ---------------------------------------------------------------------------------------------------=")
cpp_quote("// In scrollable views, scrolls to ensure that the specified substring is visible onscreen.")
cpp_quote("// The in parameters for start and end indices refer to the string returned")
cpp_quote("// by ISimpleDOMText::get_domText().")
cpp_quote("//")
cpp_quote("//")
cpp_quote("// [propget] fontFamily(/* out,retval */ BSTR *fontFamily);")
cpp_quote("// ---------------------------------------------------------------------------------------------------=")
cpp_quote("// Return a single computed font family name, which is better than the comma delineated list")
cpp_quote("// that is returned by the ISimpleDOMNode computed style methods for font-family.")
cpp_quote("// In other words, return something like 'Arial' instead of 'Arial, Helvetica, Sans-serif'.")
cpp_quote("///////////////////////////////////////////////////////////////////////////////////////////////////////")
cpp_quote("")
cpp_quote("")
[object, uuid(4e747be5-2052-4265-8af0-8ecad7aad1c0)]
interface ISimpleDOMText: IUnknown
{
// Includes whitespace in DOM
[propget] HRESULT domText([out, retval] BSTR *domText);
HRESULT get_clippedSubstringBounds([in] unsigned int startIndex,
[in] unsigned int endIndex,
[out] int *x,
[out] int *y,
[out] int *width,
[out] int *height);
HRESULT get_unclippedSubstringBounds([in] unsigned int startIndex,
[in] unsigned int endIndex,
[out] int *x,
[out] int *y,
[out] int *width,
[out] int *height);
HRESULT scrollToSubstring([in] unsigned int startIndex,
[in] unsigned int endIndex);
[propget] HRESULT fontFamily([out, retval] BSTR *fontFamily);
};
+66
View File
@@ -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/.
DEPTH = @DEPTH@
topsrcdir = @top_srcdir@
srcdir = @srcdir@
VPATH = @srcdir@
DEFFILE = $(win_srcdir)/AccessibleMarshal.def
include $(DEPTH)/config/autoconf.mk
DEFINES += -DREGISTER_PROXY_DLL
GARBAGE += $(MIDL_GENERATED_FILES) done_gen dlldata.c
FORCE_SHARED_LIB = 1
CSRCS = \
dlldata.c \
ISimpleDOMNode_p.c \
ISimpleDOMNode_i.c \
ISimpleDOMDocument_p.c \
ISimpleDOMDocument_i.c \
ISimpleDOMText_p.c \
ISimpleDOMText_i.c \
$(NULL)
MIDL_GENERATED_FILES = \
ISimpleDOMNode.h \
ISimpleDOMNode_p.c \
ISimpleDOMNode_i.c \
ISimpleDOMDocument.h \
ISimpleDOMDocument_p.c \
ISimpleDOMDocument_i.c \
ISimpleDOMText.h \
ISimpleDOMText_p.c \
ISimpleDOMText_i.c \
$(NULL)
SRCDIR_CSRCS = $(addprefix $(srcdir)/,$(CSRCS))
OS_LIBS = $(call EXPAND_LIBNAME,kernel32 rpcns4 rpcrt4 oleaut32)
$(MIDL_GENERATED_FILES): done_gen
done_gen: ISimpleDOMNode.idl \
ISimpleDOMDocument.idl \
ISimpleDOMText.idl
$(MIDL) $(MIDL_FLAGS) -I $(srcdir) -Oicf $(srcdir)/ISimpleDOMNode.idl
$(MIDL) $(MIDL_FLAGS) -Oicf $(srcdir)/ISimpleDOMDocument.idl
$(MIDL) $(MIDL_FLAGS) -Oicf $(srcdir)/ISimpleDOMText.idl
touch $@
export:: done_gen
# This marshall dll is also registered in the installer
register::
regsvr32 -s $(DIST)/bin/$(SHARED_LIBRARY)
EMBED_MANIFEST_AT = 2
include $(topsrcdir)/config/rules.mk
+19
View File
@@ -0,0 +1,19 @@
# -*- Mode: python; c-basic-offset: 4; 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/.
MODULE = 'accessibility'
EXPORTS += [
'ISimpleDOMDocument.h',
'ISimpleDOMDocument_i.c',
'ISimpleDOMNode.h',
'ISimpleDOMNode_i.c',
'ISimpleDOMText.h',
'ISimpleDOMText_i.c',
]
LIBRARY_NAME = 'AccessibleMarshal'
@@ -0,0 +1,80 @@
/* -*- 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 _nsIAccessibilityService_h_
#define _nsIAccessibilityService_h_
#include "nsIAccessibleRetrieval.h"
#include "nsIAccessibleEvent.h"
#include "nsAutoPtr.h"
namespace mozilla {
namespace a11y {
class Accessible;
} // namespace a11y
} // namespace mozilla
class nsINode;
class nsIContent;
class nsIFrame;
class nsIPresShell;
class nsObjectFrame;
// 10ff6dca-b219-4b64-9a4c-67a62b86edce
#define NS_IACCESSIBILITYSERVICE_IID \
{ 0x84dd9182, 0x6639, 0x4377, \
{ 0xa4, 0x13, 0xad, 0xe1, 0xae, 0x4e, 0x52, 0xdd } }
class nsIAccessibilityService : public nsIAccessibleRetrieval
{
public:
NS_DECLARE_STATIC_IID_ACCESSOR(NS_IACCESSIBILITYSERVICE_IID)
/**
* Return root document accessible that is or contains a document accessible
* for the given presshell.
*
* @param aPresShell [in] the presshell
* @param aCanCreate [in] points whether the root document accessible
* should be returned from the cache or can be created
*/
virtual mozilla::a11y::Accessible*
GetRootDocumentAccessible(nsIPresShell* aPresShell, bool aCanCreate) = 0;
/**
* Adds/remove ATK root accessible for gtk+ native window to/from children
* of the application accessible.
*/
virtual mozilla::a11y::Accessible*
AddNativeRootAccessible(void* aAtkAccessible) = 0;
virtual void
RemoveNativeRootAccessible(mozilla::a11y::Accessible* aRootAccessible) = 0;
/**
* Fire accessible event of the given type for the given target.
*
* @param aEvent [in] accessible event type
* @param aTarget [in] target of accessible event
*/
virtual void FireAccessibleEvent(uint32_t aEvent,
mozilla::a11y::Accessible* aTarget) = 0;
};
NS_DEFINE_STATIC_IID_ACCESSOR(nsIAccessibilityService,
NS_IACCESSIBILITYSERVICE_IID)
// for component registration
// {DE401C37-9A7F-4278-A6F8-3DE2833989EF}
#define NS_ACCESSIBILITY_SERVICE_CID \
{ 0xde401c37, 0x9a7f, 0x4278, { 0xa6, 0xf8, 0x3d, 0xe2, 0x83, 0x39, 0x89, 0xef } }
extern nsresult
NS_GetAccessibilityService(nsIAccessibilityService** aResult);
#endif
+293
View File
@@ -0,0 +1,293 @@
/* -*- 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 "nsISupports.idl"
#include "nsIArray.idl"
interface nsIPersistentProperties;
interface nsIDOMCSSPrimitiveValue;
interface nsIDOMDOMStringList;
interface nsIDOMNode;
interface nsIAccessibleDocument;
interface nsIAccessibleRelation;
/**
* A cross-platform interface that supports platform-specific
* accessibility APIs like MSAA and ATK. Contains the sum of what's needed
* to support IAccessible as well as ATK's generic accessibility objects.
* Can also be used by in-process accessibility clients to get information
* about objects in the accessible tree. The accessible tree is a subset of
* nodes in the DOM tree -- such as documents, focusable elements and text.
* Mozilla creates the implementations of nsIAccessible on demand.
* See http://www.mozilla.org/projects/ui/accessibility for more information.
*/
[scriptable, uuid(45600c50-b06a-11e1-afa6-0800200c9a66)]
interface nsIAccessible : nsISupports
{
/**
* Parent node in accessible tree.
*/
readonly attribute nsIAccessible parent;
/**
* Next sibling in accessible tree
*/
readonly attribute nsIAccessible nextSibling;
/**
* Previous sibling in accessible tree
*/
readonly attribute nsIAccessible previousSibling;
/**
* First child in accessible tree
*/
readonly attribute nsIAccessible firstChild;
/**
* Last child in accessible tree
*/
readonly attribute nsIAccessible lastChild;
/**
* Array of all this element's children.
*/
readonly attribute nsIArray children;
/**
* Number of accessible children
*/
readonly attribute long childCount;
/**
* The 0-based index of this accessible in its parent's list of children,
* or -1 if this accessible does not have a parent.
*/
readonly attribute long indexInParent;
/**
* The DOM node this nsIAccessible is associated with.
*/
readonly attribute nsIDOMNode DOMNode;
/**
* The document accessible that this access node resides in.
*/
readonly attribute nsIAccessibleDocument document;
/**
* The root document accessible that this access node resides in.
*/
readonly attribute nsIAccessibleDocument rootDocument;
/**
* The language for the current DOM node, e.g. en, de, etc.
*/
readonly attribute DOMString language;
/**
* Accessible name -- the main text equivalent for this node. The name is
* specified by ARIA or by native markup. Example of ARIA markup is
* aria-labelledby attribute placed on element of this accessible. Example
* of native markup is HTML label linked with HTML element of this accessible.
*
* Value can be string or null. A null value indicates that AT may attempt to
* compute the name. Any string value, including the empty string, should be
* considered author-intentional, and respected.
*/
attribute AString name;
/**
* Accessible value -- a number or a secondary text equivalent for this node
* Widgets that use role attribute can force a value using the valuenow attribute
*/
readonly attribute AString value;
/**
* Accessible description -- long text associated with this node
*/
readonly attribute AString description;
/**
* Provides localized string of accesskey name, such as Alt+D.
* The modifier may be affected by user and platform preferences.
* Usually alt+letter, or just the letter alone for menu items.
*/
readonly attribute AString accessKey;
/**
* Provides localized string of global keyboard accelerator for default
* action, such as Ctrl+O for Open file
*/
readonly attribute AString keyboardShortcut;
/**
* Enumerated accessible role (see the constants defined in nsIAccessibleRole).
*
* @note The values might depend on platform because of variations. Widgets
* can use ARIA role attribute to force the final role.
*/
readonly attribute unsigned long role;
/**
* Accessible states -- bit fields which describe boolean properties of node.
* Many states are only valid given a certain role attribute that supports
* them.
*
* @param aState - the first bit field (see nsIAccessibleStates::STATE_*
* constants)
* @param aExtraState - the second bit field
* (see nsIAccessibleStates::EXT_STATE_* constants)
*/
void getState(out unsigned long aState, out unsigned long aExtraState);
/**
* Help text associated with node
*/
readonly attribute AString help;
/**
* Focused accessible child of node
*/
readonly attribute nsIAccessible focusedChild;
/**
* Attributes of accessible
*/
readonly attribute nsIPersistentProperties attributes;
/**
* Returns grouping information. Used for tree items, list items, tab panel
* labels, radio buttons, etc. Also used for collectons of non-text objects.
*
* @param groupLevel - 1-based, similar to ARIA 'level' property
* @param similarItemsInGroup - 1-based, similar to ARIA 'setsize' property,
* inclusive of the current item
* @param positionInGroup - 1-based, similar to ARIA 'posinset' property
*/
void groupPosition(out long aGroupLevel, out long aSimilarItemsInGroup,
out long aPositionInGroup);
/**
* Accessible child which contains the coordinate at (x, y) in screen pixels.
* If the point is in the current accessible but not in a child, the
* current accessible will be returned.
* If the point is in neither the current accessible or a child, then
* null will be returned.
*
* @param x screen's x coordinate
* @param y screen's y coordinate
* @return the deepest accessible child containing the given point
*/
nsIAccessible getChildAtPoint(in long x, in long y);
/**
* Deepest accessible child which contains the coordinate at (x, y) in screen
* pixels. If the point is in the current accessible but not in a child, the
* current accessible will be returned. If the point is in neither the current
* accessible or a child, then null will be returned.
*
* @param x screen's x coordinate
* @param y screen's y coordinate
* @return the deepest accessible child containing the given point
*/
nsIAccessible getDeepestChildAtPoint(in long x, in long y);
/**
* Nth accessible child using zero-based index or last child if index less than zero
*/
nsIAccessible getChildAt(in long aChildIndex);
/**
* Return accessible relation by the given relation type (see.
* constants defined in nsIAccessibleRelation).
*/
nsIAccessibleRelation getRelationByType(in unsigned long aRelationType);
/**
* Returns multiple accessible relations for this object.
*/
nsIArray getRelations();
/**
* Return accessible's x and y coordinates relative to the screen and
* accessible's width and height.
*/
void getBounds(out long x, out long y, out long width, out long height);
/**
* Add or remove this accessible to the current selection
*/
void setSelected(in boolean isSelected);
/**
* Extend the current selection from its current accessible anchor node
* to this accessible
*/
void extendSelection();
/**
* Select this accessible node only
*/
void takeSelection();
/**
* Focus this accessible node,
* The state STATE_FOCUSABLE indicates whether this node is normally focusable.
* It is the callers responsibility to determine whether this node is focusable.
* accTakeFocus on a node that is not normally focusable (such as a table),
* will still set focus on that node, although normally that will not be visually
* indicated in most style sheets.
*/
void takeFocus();
/**
* The number of accessible actions associated with this accessible
*/
readonly attribute uint8_t actionCount;
/**
* The name of the accessible action at the given zero-based index
*/
AString getActionName(in uint8_t index);
/**
* The description of the accessible action at the given zero-based index
*/
AString getActionDescription(in uint8_t aIndex);
/**
* Perform the accessible action at the given zero-based index
* Action number 0 is the default action
*/
void doAction(in uint8_t index);
/**
* Makes an object visible on screen.
*
* @param scrollType - defines where the object should be placed on
* the screen (see nsIAccessibleScrollType for
* available constants).
*/
void scrollTo(in unsigned long aScrollType);
/**
* Moves the top left of an object to a specified location.
*
* @param coordinateType [in] - specifies whether the coordinates are relative to
* the screen or the parent object (for available
* constants refer to nsIAccessibleCoordinateType)
* @param x [in] - defines the x coordinate
* @param y [in] - defines the y coordinate
*/
void scrollToPoint(in unsigned long coordinateType, in long x, in long y);
/**
* Get a pointer to accessibility interface for this node, which is specific
* to the OS/accessibility toolkit we're running on.
*/
[noscript] void getNativeInterface(out voidPtr aOutAccessible);
};
@@ -0,0 +1,34 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "nsISupports.idl"
/**
* This interface is implemented by top level accessible object in hierarchy and
* provides information about application.
*/
[scriptable, uuid(79251626-387c-4531-89f3-680d31d6cf05)]
interface nsIAccessibleApplication : nsISupports
{
/**
* Returns the application name.
*/
readonly attribute DOMString appName;
/**
* Returns the application version.
*/
readonly attribute DOMString appVersion;
/**
* Returns the platform name.
*/
readonly attribute DOMString platformName;
/**
* Returns the platform version.
*/
readonly attribute DOMString platformVersion;
};
@@ -0,0 +1,18 @@
/* -*- 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 "nsIAccessibleEvent.idl"
/**
* Fired when the caret changes position in text.
*/
[scriptable, builtinclass, uuid(5675c486-a230-4d85-a4bd-33670826d5ff)]
interface nsIAccessibleCaretMoveEvent: nsIAccessibleEvent
{
/**
* Return caret offset.
*/
readonly attribute long caretOffset;
};
@@ -0,0 +1,88 @@
/* -*- 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 "nsISupports.idl"
interface nsIAccessible;
interface nsIAccessiblePivot;
interface nsIDOMDocument;
interface nsIDOMNode;
interface nsIDOMWindow;
/**
* An interface for in-process accessibility clients
* that wish to retrieve information about a document.
* When accessibility is turned on in Goanna,
* there is an nsIAccessibleDocument for each document
* whether it is XUL, HTML or whatever.
* You can QueryInterface to nsIAccessibleDocument from the nsIAccessible for
* the root node of a document. You can also get one from
* nsIAccessible::GetAccessibleDocument() or
* nsIAccessibleEvent::GetAccessibleDocument()
*/
[scriptable, uuid(fe5b3886-2b6a-491a-80cd-a3e6342c451d)]
interface nsIAccessibleDocument : nsISupports
{
/**
* The URL of the document
*/
readonly attribute AString URL;
/**
* The title of the document, as specified in the document.
*/
readonly attribute AString title;
/**
* The mime type of the document
*/
readonly attribute AString mimeType;
/**
* The doc type of the document, as specified in the document.
*/
readonly attribute AString docType;
/**
* The nsIDOMDocument interface associated with this document.
*/
readonly attribute nsIDOMDocument DOMDocument;
/**
* The nsIDOMWindow that the document resides in.
*/
readonly attribute nsIDOMWindow window;
/**
* The namespace for each ID that is handed back.
*/
AString getNameSpaceURIForID(in short nameSpaceID);
/**
* The window handle for the OS window the document is being displayed in.
* For example, in Windows you can static cast it to an HWND.
*/
[noscript] readonly attribute voidPtr windowHandle;
/**
* Return the parent document accessible.
*/
readonly attribute nsIAccessibleDocument parentDocument;
/**
* Return the count of child document accessibles.
*/
readonly attribute unsigned long childDocumentCount;
/**
* The virtual cursor pivot this document manages.
*/
readonly attribute nsIAccessiblePivot virtualCursor;
/**
* Return the child document accessible at the given index.
*/
nsIAccessibleDocument getChildDocumentAt(in unsigned long index);
};
@@ -0,0 +1,71 @@
/* -*- 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 "nsISupports.idl"
interface nsIEditor;
[scriptable, uuid(e242d495-5cde-4b1c-8c84-2525b14939f5)]
interface nsIAccessibleEditableText : nsISupports
{
/**
* Sets the attributes for the text between the two given indices. The old
* attributes are replaced by the new list of attributes. For example,
* sets font styles, such as italic, bold...
*
* @param startPos - start index of the text whose attributes are modified.
* @param endPos - end index of the text whose attributes are modified.
* @param attributes - set of attributes that replaces the old list of
* attributes of the specified text portion.
*/
void setAttributes (in long startPos, in long endPos,
in nsISupports attributes);
/**
* Replaces the text represented by this object by the given text.
*/
void setTextContents (in AString text);
/**
* Inserts text at the specified position.
*
* @param text - text that is inserted.
* @param position - index at which to insert the text.
*/
void insertText (in AString text, in long position);
/**
* Copies the text range into the clipboard.
*
* @param startPos - start index of the text to moved into the clipboard.
* @param endPos - end index of the text to moved into the clipboard.
*/
void copyText (in long startPos, in long endPos);
/**
* Deletes a range of text and copies it to the clipboard.
*
* @param startPos - start index of the text to be deleted.
* @param endOffset - end index of the text to be deleted.
*/
void cutText (in long startPos, in long endPos);
/**
* Deletes a range of text.
*
* @param startPos - start index of the text to be deleted.
* @param endPos - end index of the text to be deleted.
*/
void deleteText (in long startPos, in long endPos);
/**
* Pastes text from the clipboard.
*
* @param position - index at which to insert the text from the system
* clipboard into the text represented by this object.
*/
void pasteText (in long position);
};
+450
View File
@@ -0,0 +1,450 @@
/* -*- 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 "nsISupports.idl"
interface nsIAccessible;
interface nsIAccessibleDocument;
interface nsIDOMNode;
%{C++
#define NS_ACCESSIBLE_EVENT_TOPIC "accessible-event"
%}
/**
* An interface for accessibility events listened to
* by in-process accessibility clients, which can be used
* to find out how to get accessibility and DOM interfaces for
* the event and its target. To listen to in-process accessibility invents,
* make your object an nsIObserver, and listen for accessible-event by
* using code something like this:
* nsCOMPtr<nsIObserverService> observerService =
* do_GetService("@mozilla.org/observer-service;1", &rv);
* if (NS_SUCCEEDED(rv))
* rv = observerService->AddObserver(this, "accessible-event", PR_TRUE);
*/
[scriptable, builtinclass, uuid(7f66a33a-9ed7-4fd4-87a8-e431b0f43368)]
interface nsIAccessibleEvent : nsISupports
{
/**
* An object has been created.
*/
const unsigned long EVENT_SHOW = 0x0001;
/**
* An object has been destroyed.
*/
const unsigned long EVENT_HIDE = 0x0002;
/**
* An object's children have changed
*/
const unsigned long EVENT_REORDER = 0x0003;
/**
* The active descendant of a component has changed. The active descendant
* is used in objects with transient children.
*/
const unsigned long EVENT_ACTIVE_DECENDENT_CHANGED = 0x0004;
/**
* An object has received the keyboard focus.
*/
const unsigned long EVENT_FOCUS = 0x0005;
/**
* An object's state has changed.
*/
const unsigned long EVENT_STATE_CHANGE = 0x0006;
/**
* An object has changed location, shape, or size.
*/
const unsigned long EVENT_LOCATION_CHANGE = 0x0007;
/**
* An object's Name property has changed.
*/
const unsigned long EVENT_NAME_CHANGE = 0x0008;
/**
* An object's Description property has changed.
*/
const unsigned long EVENT_DESCRIPTION_CHANGE = 0x0009;
/**
* An object's Value property has changed.
*/
const unsigned long EVENT_VALUE_CHANGE = 0x000A;
/**
* An object's help has changed.
*/
const unsigned long EVENT_HELP_CHANGE = 0x000B;
/**
* An object's default action has changed.
*/
const unsigned long EVENT_DEFACTION_CHANGE = 0x000C;
/**
* An object's action has changed.
*/
const unsigned long EVENT_ACTION_CHANGE = 0x000D;
/**
* An object's keyboard shortcut has changed.
*/
const unsigned long EVENT_ACCELERATOR_CHANGE = 0x000E;
/**
* The selection within a container object has changed.
*/
const unsigned long EVENT_SELECTION = 0x000F;
/**
* An item within a container object has been added to the selection.
*/
const unsigned long EVENT_SELECTION_ADD = 0x0010;
/**
* An item within a container object has been removed from the selection.
*/
const unsigned long EVENT_SELECTION_REMOVE = 0x0011;
/**
* Numerous selection changes have occurred within a container object.
*/
const unsigned long EVENT_SELECTION_WITHIN = 0x0012;
/**
* An alert has been generated. Server applications send this event when a
* user needs to know that a user interface element has changed.
*/
const unsigned long EVENT_ALERT = 0x0013;
/**
* The foreground window has changed.
*/
const unsigned long EVENT_FOREGROUND = 0x0014;
/**
* A menu item on the menu bar has been selected.
*/
const unsigned long EVENT_MENU_START = 0x0015;
/**
* A menu from the menu bar has been closed.
*/
const unsigned long EVENT_MENU_END = 0x0016;
/**
* A pop-up menu has been displayed.
*/
const unsigned long EVENT_MENUPOPUP_START = 0x0017;
/**
* A pop-up menu has been closed.
*/
const unsigned long EVENT_MENUPOPUP_END = 0x0018;
/**
* A window has received mouse capture.
*/
const unsigned long EVENT_CAPTURE_START = 0x0019;
/**
* A window has lost mouse capture.
*/
const unsigned long EVENT_CAPTURE_END = 0x001A;
/**
* A window is being moved or resized.
*/
const unsigned long EVENT_MOVESIZE_START = 0x001B;
/**
* The movement or resizing of a window has finished
*/
const unsigned long EVENT_MOVESIZE_END = 0x001C;
/**
* A window has entered context-sensitive Help mode
*/
const unsigned long EVENT_CONTEXTHELP_START = 0x001D;
/**
* A window has exited context-sensitive Help mode
*/
const unsigned long EVENT_CONTEXTHELP_END = 0x001E;
/**
* An application is about to enter drag-and-drop mode
*/
const unsigned long EVENT_DRAGDROP_START = 0x001F;
/**
* An application is about to exit drag-and-drop mode
*/
const unsigned long EVENT_DRAGDROP_END = 0x0020;
/**
* A dialog box has been displayed
*/
const unsigned long EVENT_DIALOG_START = 0x0021;
/**
* A dialog box has been closed
*/
const unsigned long EVENT_DIALOG_END = 0x0022;
/**
* Scrolling has started on a scroll bar
*/
const unsigned long EVENT_SCROLLING_START = 0x0023;
/**
* Scrolling has ended on a scroll bar
*/
const unsigned long EVENT_SCROLLING_END = 0x0024;
/**
* A window object is about to be minimized or maximized
*/
const unsigned long EVENT_MINIMIZE_START = 0x0025;
/**
* A window object has been minimized or maximized
*/
const unsigned long EVENT_MINIMIZE_END = 0x0026;
/**
* The loading of the document has completed.
*/
const unsigned long EVENT_DOCUMENT_LOAD_COMPLETE = 0x0027;
/**
* The document contents are being reloaded.
*/
const unsigned long EVENT_DOCUMENT_RELOAD = 0x0028;
/**
* The loading of the document was interrupted.
*/
const unsigned long EVENT_DOCUMENT_LOAD_STOPPED = 0x0029;
/**
* The document wide attributes of the document object have changed.
*/
const unsigned long EVENT_DOCUMENT_ATTRIBUTES_CHANGED = 0x002A;
/**
* The contents of the document have changed.
*/
const unsigned long EVENT_DOCUMENT_CONTENT_CHANGED = 0x002B;
const unsigned long EVENT_PROPERTY_CHANGED = 0x002C;
/**
* A slide changed in a presentation document or a page boundary was
* crossed in a word processing document.
*/
const unsigned long EVENT_PAGE_CHANGED = 0x002D;
/**
* A text object's attributes changed.
* Also see EVENT_OBJECT_ATTRIBUTE_CHANGED.
*/
const unsigned long EVENT_TEXT_ATTRIBUTE_CHANGED = 0x002E;
/**
* The caret has moved to a new position.
*/
const unsigned long EVENT_TEXT_CARET_MOVED = 0x002F;
/**
* This event indicates general text changes, i.e. changes to text that is
* exposed through the IAccessibleText and IAccessibleEditableText interfaces.
*/
const unsigned long EVENT_TEXT_CHANGED = 0x0030;
/**
* Text was inserted.
*/
const unsigned long EVENT_TEXT_INSERTED = 0x0031;
/**
* Text was removed.
*/
const unsigned long EVENT_TEXT_REMOVED = 0x0032;
/**
* Text was updated.
*/
const unsigned long EVENT_TEXT_UPDATED = 0x0033;
/**
* The text selection changed.
*/
const unsigned long EVENT_TEXT_SELECTION_CHANGED = 0x0034;
/**
* A visibile data event indicates the change of the visual appearance
* of an accessible object. This includes for example most of the
* attributes available via the IAccessibleComponent interface.
*/
const unsigned long EVENT_VISIBLE_DATA_CHANGED = 0x0035;
/**
* The caret moved from one column to the next.
*/
const unsigned long EVENT_TEXT_COLUMN_CHANGED = 0x0036;
/**
* The caret moved from one section to the next.
*/
const unsigned long EVENT_SECTION_CHANGED = 0x0037;
/**
* A table caption changed.
*/
const unsigned long EVENT_TABLE_CAPTION_CHANGED = 0x0038;
/**
* A table's data changed.
*/
const unsigned long EVENT_TABLE_MODEL_CHANGED = 0x0039;
/**
* A table's summary changed.
*/
const unsigned long EVENT_TABLE_SUMMARY_CHANGED = 0x003A;
/**
* A table's row description changed.
*/
const unsigned long EVENT_TABLE_ROW_DESCRIPTION_CHANGED = 0x003B;
/**
* A table's row header changed.
*/
const unsigned long EVENT_TABLE_ROW_HEADER_CHANGED = 0x003C;
const unsigned long EVENT_TABLE_ROW_INSERT = 0x003D;
const unsigned long EVENT_TABLE_ROW_DELETE = 0x003E;
const unsigned long EVENT_TABLE_ROW_REORDER = 0x003F;
/**
* A table's column description changed.
*/
const unsigned long EVENT_TABLE_COLUMN_DESCRIPTION_CHANGED = 0x0040;
/**
* A table's column header changed.
*/
const unsigned long EVENT_TABLE_COLUMN_HEADER_CHANGED = 0x0041;
const unsigned long EVENT_TABLE_COLUMN_INSERT = 0x0042;
const unsigned long EVENT_TABLE_COLUMN_DELETE = 0x0043;
const unsigned long EVENT_TABLE_COLUMN_REORDER = 0x0044;
const unsigned long EVENT_WINDOW_ACTIVATE = 0x0045;
const unsigned long EVENT_WINDOW_CREATE = 0x0046;
const unsigned long EVENT_WINDOW_DEACTIVATE = 0x0047;
const unsigned long EVENT_WINDOW_DESTROY = 0x0048;
const unsigned long EVENT_WINDOW_MAXIMIZE = 0x0049;
const unsigned long EVENT_WINDOW_MINIMIZE = 0x004A;
const unsigned long EVENT_WINDOW_RESIZE = 0x004B;
const unsigned long EVENT_WINDOW_RESTORE = 0x004C;
/**
* The ending index of this link within the containing string has changed.
*/
const unsigned long EVENT_HYPERLINK_END_INDEX_CHANGED = 0x004D;
/**
* The number of anchors assoicated with this hyperlink object has changed.
*/
const unsigned long EVENT_HYPERLINK_NUMBER_OF_ANCHORS_CHANGED = 0x004E;
/**
* The hyperlink selected state changed from selected to unselected or
* from unselected to selected.
*/
const unsigned long EVENT_HYPERLINK_SELECTED_LINK_CHANGED = 0x004F;
/**
* One of the links associated with the hypertext object has been activated.
*/
const unsigned long EVENT_HYPERTEXT_LINK_ACTIVATED = 0x0050;
/**
* One of the links associated with the hypertext object has been selected.
*/
const unsigned long EVENT_HYPERTEXT_LINK_SELECTED = 0x0051;
/**
* The starting index of this link within the containing string has changed.
*/
const unsigned long EVENT_HYPERLINK_START_INDEX_CHANGED = 0x0052;
/**
* Focus has changed from one hypertext object to another, or focus moved
* from a non-hypertext object to a hypertext object, or focus moved from a
* hypertext object to a non-hypertext object.
*/
const unsigned long EVENT_HYPERTEXT_CHANGED = 0x0053;
/**
* The number of hyperlinks associated with a hypertext object changed.
*/
const unsigned long EVENT_HYPERTEXT_NLINKS_CHANGED = 0x0054;
/**
* An object's attributes changed. Also see EVENT_TEXT_ATTRIBUTE_CHANGED.
*/
const unsigned long EVENT_OBJECT_ATTRIBUTE_CHANGED = 0x0055;
/**
* A cursorable's virtual cursor has changed.
*/
const unsigned long EVENT_VIRTUALCURSOR_CHANGED = 0x0056;
/**
* Help make sure event map does not get out-of-line.
*/
const unsigned long EVENT_LAST_ENTRY = 0x0057;
/**
* The type of event, based on the enumerated event values
* defined in this interface.
*/
readonly attribute unsigned long eventType;
/**
* The nsIAccessible associated with the event.
* May return null if no accessible is available
*/
readonly attribute nsIAccessible accessible;
/**
* The nsIAccessibleDocument that the event target nsIAccessible
* resides in. This can be used to get the DOM window,
* the DOM document and the window handler, among other things.
*/
readonly attribute nsIAccessibleDocument accessibleDocument;
/**
* The nsIDOMNode associated with the event
* May return null if accessible for event has been shut down
*/
readonly attribute nsIDOMNode DOMNode;
/**
* Returns true if the event was caused by explicit user input,
* as opposed to purely originating from a timer or mouse movement
*/
readonly attribute boolean isFromUserInput;
};
@@ -0,0 +1,28 @@
/* -*- 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 "nsIAccessibleEvent.idl"
/**
* Fired when a accessible and its subtree are removed from the tree.
*/
[scriptable, builtinclass, uuid(a2bd2eca-3afa-489b-afb2-f93ef32ad99c)]
interface nsIAccessibleHideEvent: nsIAccessibleEvent
{
/**
* Return an accessible that was a parent of the target.
*/
readonly attribute nsIAccessible targetParent;
/**
* Return an accessible that was a next sibling of the target
*/
readonly attribute nsIAccessible targetNextSibling;
/**
* Return an accessible that was a parent of the target
*/
readonly attribute nsIAccessible targetPrevSibling;
};
@@ -0,0 +1,96 @@
/* -*- 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 "nsISupports.idl"
interface nsIURI;
interface nsIAccessible;
/**
* A cross-platform interface that supports hyperlink-specific properties and
* methods. Anchors, image maps, xul:labels with class="text-link" implement this interface.
*/
[scriptable, uuid(38c60bfa-6040-4bfe-93f2-acd6a909bb60)]
interface nsIAccessibleHyperLink : nsISupports
{
/**
* Returns the offset of the link within the parent accessible.
*/
readonly attribute long startIndex;
/**
* Returns the end index of the link within the parent accessible.
*
* @note The link itself is represented by one embedded character within the
* parent text, so the endIndex should be startIndex + 1.
*/
readonly attribute long endIndex;
/**
* Determines whether the link is valid (e. g. points to a valid URL).
*
* @note XXX Currently only used with ARIA links, and the author has to
* specify that the link is invalid via the aria-invalid="true" attribute.
* In all other cases, TRUE is returned.
*/
readonly attribute boolean valid;
/**
* Determines whether the element currently has the focus, e. g. after
* returning from the destination page.
*
* @note ARIA links can only be focused if they have the tabindex
* attribute set. Also, state_focused should then be set on the accessible
* for this link.
*/
readonly attribute boolean selected;
/**
* The numbber of anchors within this Hyperlink. Is normally 1 for anchors.
* This anchor is, for example, the visible output of the html:a tag.
* With an Image Map, reflects the actual areas within the map.
*/
readonly attribute long anchorCount;
/**
* Returns the URI at the given index.
*
* @note ARIA hyperlinks do not have an URI to point to, since clicks are
* processed via JavaScript. Therefore this property does not work on ARIA
* links.
*
* @param index The 0-based index of the URI to be returned.
*
* @return the nsIURI object containing the specifications for the URI.
*/
nsIURI getURI (in long index);
/**
* Returns a reference to the object at the given index.
*
* @param index The 0-based index whose object is to be returned.
*
* @return the nsIAccessible object at the desired index.
*/
nsIAccessible getAnchor (in long index);
};
/*
Assumptions:
The object associated with object or anchor index
is an nsIAccessible.
A URI can be represented by the nsIURI interface
(or nsIURL interface).
Note that an object which supports nsIAccessibleHyperlink
does *not* generally implement nsIAccessible, unlike the
case of the other nsiAccessible* interfaces in this directory.
Aaron: would the nsISupports return from
getObject be queryable for nsIURI and nsIURL directly?
*/
@@ -0,0 +1,54 @@
/* -*- 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 "nsISupports.idl"
#include "nsIAccessibleHyperLink.idl"
/**
* A cross-platform interface that deals with text which contains hyperlinks.
* Each link is an embedded object representing exactly 1 character within
* the hypertext.
*
* Current implementation assumes every embedded object is a link.
*/
[scriptable, uuid(b33684e2-090c-4e1d-a3d9-f4b46f4237b9)]
interface nsIAccessibleHyperText : nsISupports
{
/**
* Return the number of links contained within this hypertext object.
*/
readonly attribute long linkCount;
/**
* Return link accessible at the given index.
*
* @param index [in] 0-based index of the link that is to be retrieved
*
* @return link accessible or null if there is no link at that index
*/
nsIAccessibleHyperLink getLinkAt(in long index);
/**
* Return index of the given link.
*
* @param link [in] link accessible the index is requested for
*
* @return index of the given link or null if there's no link within
* hypertext accessible
*/
long getLinkIndex(in nsIAccessibleHyperLink link);
/*
* Return link index at the given offset within hypertext accessible.
*
* @param offset [in] the 0-based character index
*
* @return 0-based link's index or -1 if no link is present at that
* offset
*/
long getLinkIndexAtOffset(in long offset);
};
+31
View File
@@ -0,0 +1,31 @@
/* -*- 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 "nsISupports.idl"
[scriptable, uuid(09086623-0f09-4310-ac56-c2cda7c29648)]
interface nsIAccessibleImage : nsISupports
{
/**
* Returns the coordinates of the image.
*
* @param coordType specifies coordinates origin (for available constants
* refer to nsIAccessibleCoordinateType)
* @param x the x coordinate
* @param y the y coordinate
*/
void getImagePosition(in unsigned long coordType,
out long x,
out long y);
/**
* Returns the size of the image.
*
* @param width the heigth
* @param height the width
*/
void getImageSize(out long width, out long height);
};
+231
View File
@@ -0,0 +1,231 @@
/* -*- 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 "nsISupports.idl"
typedef short TextBoundaryType;
typedef short PivotMoveReason;
interface nsIAccessible;
interface nsIAccessibleText;
interface nsIAccessibleTraversalRule;
interface nsIAccessiblePivotObserver;
/**
* The pivot interface encapsulates a reference to a single place in an accessible
* subtree. The pivot is a point or a range in the accessible tree. This interface
* provides traversal methods to move the pivot to next/prev state that complies
* to a given rule.
*/
[scriptable, uuid(c2938033-e240-4fe5-9cb6-e7ad649ccd10)]
interface nsIAccessiblePivot : nsISupports
{
const TextBoundaryType CHAR_BOUNDARY = 0;
const TextBoundaryType WORD_BOUNDARY = 1;
const TextBoundaryType LINE_BOUNDARY = 2;
const TextBoundaryType ATTRIBUTE_RANGE_BOUNDARY = 3;
const PivotMoveReason REASON_NONE = 0;
const PivotMoveReason REASON_NEXT = 1;
const PivotMoveReason REASON_PREV = 2;
const PivotMoveReason REASON_FIRST = 3;
const PivotMoveReason REASON_LAST = 4;
const PivotMoveReason REASON_TEXT = 5;
const PivotMoveReason REASON_POINT = 6;
/**
* The accessible the pivot is currently pointed at.
*/
attribute nsIAccessible position;
/**
* The root of the subtree in which the pivot traverses.
*/
readonly attribute nsIAccessible root;
/**
* The temporary modal root to which traversal is limited to.
*/
attribute nsIAccessible modalRoot;
/**
* The start offset of the text range the pivot points at, otherwise -1.
*/
readonly attribute long startOffset;
/**
* The end offset of the text range the pivot points at, otherwise -1.
*/
readonly attribute long endOffset;
/**
* Set the pivot's text range in a text accessible.
*
* @param aTextAccessible [in] the text accessible that contains the desired
* range.
* @param aStartOffset [in] the start offset to set.
* @param aEndOffset [in] the end offset to set.
* @throws NS_ERROR_INVALID_ARG when the offset exceeds the accessible's
* character count.
*/
void setTextRange(in nsIAccessibleText aTextAccessible,
in long aStartOffset, in long aEndOffset);
/**
* Move pivot to next object, from current position or given anchor,
* complying to given traversal rule.
*
* @param aRule [in] traversal rule to use.
* @param aAnchor [in] accessible to start search from, if not provided,
* current position will be used.
* @param aIncludeStart [in] include anchor accessible in search.
* @return true on success, false if there are no new nodes to traverse to.
*/
[optional_argc] boolean moveNext(in nsIAccessibleTraversalRule aRule,
[optional] in nsIAccessible aAnchor,
[optional] in boolean aIncludeStart);
/**
* Move pivot to previous object, from current position or given anchor,
* complying to given traversal rule.
*
* @param aRule [in] traversal rule to use.
* @param aAnchor [in] accessible to start search from, if not provided,
* current position will be used.
* @param aIncludeStart [in] include anchor accessible in search.
* @return true on success, false if there are no new nodes to traverse to.
*/
[optional_argc] boolean movePrevious(in nsIAccessibleTraversalRule aRule,
[optional] in nsIAccessible aAnchor,
[optional] in boolean aIncludeStart);
/**
* Move pivot to first object in subtree complying to given traversal rule.
*
* @param aRule [in] traversal rule to use.
* @return true on success, false if there are no new nodes to traverse to.
*/
boolean moveFirst(in nsIAccessibleTraversalRule aRule);
/**
* Move pivot to last object in subtree complying to given traversal rule.
*
* @param aRule [in] traversal rule to use.
* @return true on success, false if there are no new nodes to traverse to.
*/
boolean moveLast(in nsIAccessibleTraversalRule aRule);
/**
* Move pivot to next text range.
*
* @param aBoundary [in] type of boundary for next text range, character, word,
* etc.
* @return true on success, false if there are is no more text.
*/
boolean moveNextByText(in TextBoundaryType aBoundary);
/**
* Move pivot to previous text range.
*
* @param aBoundary [in] type of boundary for previous text range, character,
* word, etc.
* @return true on success, false if there are is no more text.
*/
boolean movePreviousByText(in TextBoundaryType aBoundary);
/**
* Move pivot to given coordinate in screen pixels.
*
* @param aRule [in] raversal rule to use.
* @param aX [in] screen's x coordinate
* @param aY [in] screen's y coordinate
* @param aIgnoreNoMatch [in] don't unset position if no object was found at
* point.
* @return true on success, false if the pivot has not been moved.
*/
boolean moveToPoint(in nsIAccessibleTraversalRule aRule,
in long aX, in long aY,
in boolean aIgnoreNoMatch);
/**
* Add an observer for pivot changes.
*
* @param aObserver [in] the observer object to be notified of pivot changes.
*/
void addObserver(in nsIAccessiblePivotObserver aObserver);
/**
* Remove an observer for pivot changes.
*
* @param aObserver [in] the observer object to remove from being notified.
*/
void removeObserver(in nsIAccessiblePivotObserver aObserver);
};
/**
* An observer interface for pivot changes.
*/
[scriptable, uuid(b6508c5e-c081-467d-835c-613eedf9ee9b)]
interface nsIAccessiblePivotObserver : nsISupports
{
/**
* Called when the pivot changes.
*
* @param aPivot [in] the pivot that has changed.
* @param aOldAccessible [in] the old pivot position before the change, or null.
* @param aOldStart [in] the old start offset, or -1.
* @param aOldEnd [in] the old end offset, or -1.
* @param aReason [in] the reason for the pivot change.
*/
void onPivotChanged(in nsIAccessiblePivot aPivot,
in nsIAccessible aOldAccessible,
in long aOldStart, in long aOldEnd,
in PivotMoveReason aReason);
};
[scriptable, uuid(366fe92b-44c9-4769-ae40-7c2a075d3b16)]
interface nsIAccessibleTraversalRule : nsISupports
{
/* Ignore this accessible object */
const unsigned short FILTER_IGNORE = 0x0;
/* Accept this accessible object */
const unsigned short FILTER_MATCH = 0x1;
/* Don't traverse accessibles children */
const unsigned short FILTER_IGNORE_SUBTREE = 0x2;
/* Pre-filters */
const unsigned long PREFILTER_INVISIBLE = 0x00000001;
const unsigned long PREFILTER_OFFSCREEN = 0x00000002;
const unsigned long PREFILTER_NOT_FOCUSABLE = 0x00000004;
const unsigned long PREFILTER_ARIA_HIDDEN = 0x00000008;
/**
* Pre-filter bitfield to filter out obviously ignorable nodes and lighten
* the load on match().
*/
readonly attribute unsigned long preFilter;
/**
* Retrieve a list of roles that the traversal rule should test for. Any node
* with a role not in this list will automatically be ignored. An empty list
* will match all roles. It should be assumed that this method is called once
* at the start of a traversal, so changing the method's return result after
* that would have no affect.
*
* @param aRoles [out] an array of the roles to match.
* @param aCount [out] the length of the array.
*/
void getMatchRoles([array, size_is(aCount)]out unsigned long aRoles,
[retval]out unsigned long aCount);
/**
* Determines if a given accessible is to be accepted in our traversal rule
*
* @param aAccessible [in] accessible to examine.
* @return a bitfield of FILTER_MATCH and FILTER_IGNORE_SUBTREE.
*/
unsigned short match(in nsIAccessible aAccessible);
};
@@ -0,0 +1,83 @@
/* -*- 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 "nsISupports.idl"
/**
* nsIAccessibleProvider interface is used to link element and accessible
object. For that XBL binding of element should implement the interface.
*/
[scriptable, uuid(f7e531b6-bc29-4d3d-8c91-60fc2b71eb40)]
interface nsIAccessibleProvider : nsISupports
{
/**
* Constants set of common use.
*/
/** Do not create an accessible for this object
* This is useful if an ancestor binding already implements nsIAccessibleProvider,
* but no accessible is desired for the inheriting binding
*/
const long NoAccessible = 0;
/** For elements that spawn a new document. For example now it is used by
<xul:iframe>, <xul:browser> and <xul:editor>. */
const long OuterDoc = 0x00000001;
/**
* Constants set is used by XUL controls.
*/
const long XULAlert = 0x00001001;
const long XULButton = 0x00001002;
const long XULCheckbox = 0x00001003;
const long XULColorPicker = 0x00001004;
const long XULColorPickerTile = 0x00001005;
const long XULCombobox = 0x00001006;
const long XULDropmarker = 0x00001007;
const long XULGroupbox = 0x00001008;
const long XULImage = 0x00001009;
const long XULLink = 0x0000100A;
const long XULListbox = 0x0000100B;
const long XULListCell = 0x00001026;
const long XULListHead = 0x00001024;
const long XULListHeader = 0x00001025;
const long XULListitem = 0x0000100C;
const long XULMenubar = 0x0000100D;
const long XULMenuitem = 0x0000100E;
const long XULMenupopup = 0x0000100F;
const long XULMenuSeparator = 0x00001010;
const long XULPane = 0x00001011;
const long XULProgressMeter = 0x00001012;
const long XULScale = 0x00001013;
const long XULStatusBar = 0x00001014;
const long XULRadioButton = 0x00001015;
const long XULRadioGroup = 0x00001016;
/** Used for XUL tab element */
const long XULTab = 0x00001017;
/** Used for XUL tabs element, a container for tab elements */
const long XULTabs = 0x00001018;
/** Used for XUL tabpanels element */
const long XULTabpanels = 0x00001019;
const long XULText = 0x0000101A;
const long XULTextBox = 0x0000101B;
const long XULThumb = 0x0000101C;
const long XULTree = 0x0000101D;
const long XULTreeColumns = 0x0000101E;
const long XULTreeColumnItem = 0x0000101F;
const long XULToolbar = 0x00001020;
const long XULToolbarSeparator = 0x00001021;
const long XULTooltip = 0x00001022;
const long XULToolbarButton = 0x00001023;
/**
* Return one of constants declared above.
*/
readonly attribute long accessibleType;
};
+132
View File
@@ -0,0 +1,132 @@
/* -*- 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 "nsISupports.idl"
#include "nsIArray.idl"
interface nsIAccessible;
/**
* This interface gives access to an accessible's set of relations.
*/
[scriptable, uuid(9f85fc0d-2969-48e6-b822-68140f7e5770)]
interface nsIAccessibleRelation : nsISupports
{
/**
* This object is labelled by a target object.
*/
const unsigned long RELATION_LABELLED_BY = 0x00;
/**
* This object is label for a target object.
*/
const unsigned long RELATION_LABEL_FOR = 0x01;
/**
* This object is described by the target object.
*/
const unsigned long RELATION_DESCRIBED_BY = 0x02;
/**
* This object is describes the target object.
*/
const unsigned long RELATION_DESCRIPTION_FOR = 0x3;
/**
* This object is a child of a target object.
*/
const unsigned long RELATION_NODE_CHILD_OF = 0x4;
/**
* This object is a parent of a target object. A dual relation to
* RELATION_NODE_CHILD_OF
*/
const unsigned long RELATION_NODE_PARENT_OF = 0x5;
/**
* Some attribute of this object is affected by a target object.
*/
const unsigned long RELATION_CONTROLLED_BY = 0x06;
/**
* This object is interactive and controls some attribute of a target object.
*/
const unsigned long RELATION_CONTROLLER_FOR = 0x07;
/**
* Content flows from this object to a target object, i.e. has content that
* flows logically to another object in a sequential way, e.g. text flow.
*/
const unsigned long RELATION_FLOWS_TO = 0x08;
/**
* Content flows to this object from a target object, i.e. has content that
* flows logically from another object in a sequential way, e.g. text flow.
*/
const unsigned long RELATION_FLOWS_FROM = 0x09;
/**
* This object is a member of a group of one or more objects. When there is
* more than one object in the group each member may have one and the same
* target, e.g. a grouping object. It is also possible that each member has
* multiple additional targets, e.g. one for every other member in the group.
*/
const unsigned long RELATION_MEMBER_OF = 0x0a;
/**
* This object is a sub window of a target object.
*/
const unsigned long RELATION_SUBWINDOW_OF = 0x0b;
/**
* This object embeds a target object. This relation can be used on the
* OBJID_CLIENT accessible for a top level window to show where the content
* areas are.
*/
const unsigned long RELATION_EMBEDS = 0x0c;
/**
* This object is embedded by a target object.
*/
const unsigned long RELATION_EMBEDDED_BY = 0x0d;
/**
* This object is a transient component related to the target object. When
* this object is activated the target object doesn't lose focus.
*/
const unsigned long RELATION_POPUP_FOR = 0x0e;
/**
* This object is a parent window of the target object.
*/
const unsigned long RELATION_PARENT_WINDOW_OF = 0x0f;
/**
* Part of a form/dialog with a related default button. It is used for
* MSAA/XPCOM, it isn't for IA2 or ATK.
*/
const unsigned long RELATION_DEFAULT_BUTTON = 0x10;
/**
* Returns the type of the relation.
*/
readonly attribute unsigned long relationType;
/**
* Returns the number of targets for this relation.
*/
readonly attribute unsigned long targetsCount;
/**
* Returns one accessible relation target.
* @param index - 0 based index of relation target.
*/
nsIAccessible getTarget(in unsigned long index);
/**
* Returns multiple accessible relation targets.
*/
nsIArray getTargets();
};
@@ -0,0 +1,112 @@
/* -*- 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 "nsISupports.idl"
interface nsIDOMNode;
interface nsIAccessible;
interface nsIWeakReference;
interface nsIPresShell;
interface nsIDOMWindow;
interface nsIDOMDOMStringList;
interface nsIAccessiblePivot;
/**
* An interface for in-process accessibility clients wishing to get an
* nsIAccessible for a given DOM node. More documentation at:
* http://www.mozilla.org/projects/ui/accessibility
*/
[scriptable, uuid(17f86615-1a3d-4021-b227-3a2ef5cbffd8)]
interface nsIAccessibleRetrieval : nsISupports
{
/**
* Return application accessible.
*/
nsIAccessible getApplicationAccessible();
/**
* Return an nsIAccessible for a DOM node in pres shell 0.
* Create a new accessible of the appropriate type if necessary,
* or use one from the accessibility cache if it already exists.
* @param aNode The DOM node to get an accessible for.
* @return The nsIAccessible for the given DOM node.
*/
nsIAccessible getAccessibleFor(in nsIDOMNode aNode);
/**
* Returns accessible role as a string.
*
* @param aRole - the accessible role constants.
*/
AString getStringRole(in unsigned long aRole);
/**
* Returns list which contains accessible states as a strings.
*
* @param aStates - accessible states.
* @param aExtraStates - accessible extra states.
*/
nsIDOMDOMStringList getStringStates(in unsigned long aStates,
in unsigned long aExtraStates);
/**
* Get the type of accessible event as a string.
*
* @param aEventType - the accessible event type constant
* @return - accessible event type presented as human readable string
*/
AString getStringEventType(in unsigned long aEventType);
/**
* Get the type of accessible relation as a string.
*
* @param aRelationType - the accessible relation type constant
* @return - accessible relation type presented as human readable string
*/
AString getStringRelationType(in unsigned long aRelationType);
/**
* Return an accessible for the given DOM node from the cache.
* @note the method is intended for testing purposes
*
* @param aNode [in] the DOM node to get an accessible for
*
* @return cached accessible for the given DOM node if any
*/
nsIAccessible getAccessibleFromCache(in nsIDOMNode aNode);
/**
* Create a new pivot for tracking a position and traversing a subtree.
*
* @param aRoot [in] the accessible root for the pivot
* @return a new pivot
*/
nsIAccessiblePivot createAccessiblePivot(in nsIAccessible aRoot);
/**
* Enable logging for the given modules, all other modules aren't logged.
*
* @param aModules [in] list of modules, format is comma separated list
* like 'docload,doccreate'.
* @note Works on debug build only.
* @see Logging.cpp for list of possible values.
*/
void setLogging(in ACString aModules);
/**
* Return true if the given module is logged.
*/
boolean isLogged(in AString aModule);
};
%{ C++
// for component registration
// {663CA4A8-D219-4000-925D-D8F66406B626}
#define NS_ACCESSIBLE_RETRIEVAL_CID \
{ 0x663ca4a8, 0xd219, 0x4000, { 0x92, 0x5d, 0xd8, 0xf6, 0x64, 0x6, 0xb6, 0x26 } }
%}
+781
View File
@@ -0,0 +1,781 @@
/* -*- 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 "nsISupports.idl"
/**
* Defines cross platform (Goanna) roles.
*/
[scriptable, uuid(50db5e86-9a45-4637-a5c3-4ff148c33270)]
interface nsIAccessibleRole : nsISupports
{
/**
* Used when accessible hans't strong defined role.
*/
const unsigned long ROLE_NOTHING = 0;
/**
* Represents a title or caption bar for a window. It is used by MSAA only,
* supported automatically by MS Windows.
*/
const unsigned long ROLE_TITLEBAR = 1;
/**
* Represents the menu bar (positioned beneath the title bar of a window)
* from which menus are selected by the user. The role is used by
* xul:menubar or role="menubar".
*/
const unsigned long ROLE_MENUBAR = 2;
/**
* Represents a vertical or horizontal scroll bar, which is part of the client
* area or used in a control.
*/
const unsigned long ROLE_SCROLLBAR = 3;
/**
* Represents a special mouse pointer, which allows a user to manipulate user
* interface elements such as windows. For example, a user clicks and drags
* a sizing grip in the lower-right corner of a window to resize it.
*/
const unsigned long ROLE_GRIP = 4;
/**
* Represents a system sound, which is associated with various system events.
*/
const unsigned long ROLE_SOUND = 5;
/**
* Represents the system mouse pointer.
*/
const unsigned long ROLE_CURSOR = 6;
/**
* Represents the system caret. The role is supported for caret.
*/
const unsigned long ROLE_CARET = 7;
/**
* Represents an alert or a condition that a user should be notified about.
* Assistive Technologies typically respond to the role by reading the entire
* onscreen contents of containers advertising this role. Should be used for
* warning dialogs, etc. The role is used by xul:browsermessage,
* role="alert".
*/
const unsigned long ROLE_ALERT = 8;
/**
* Represents the window frame, which contains child objects such as
* a title bar, client, and other objects contained in a window. The role
* is supported automatically by MS Windows.
*/
const unsigned long ROLE_WINDOW = 9;
/**
* A sub-document (<frame> or <iframe>)
*/
const unsigned long ROLE_INTERNAL_FRAME = 10;
/**
* Represents a menu, which presents a list of options from which the user can
* make a selection to perform an action. It is used for role="menu".
*/
const unsigned long ROLE_MENUPOPUP = 11;
/**
* Represents a menu item, which is an entry in a menu that a user can choose
* to carry out a command, select an option. It is used for xul:menuitem,
* role="menuitem".
*/
const unsigned long ROLE_MENUITEM = 12;
/**
* Represents a ToolTip that provides helpful hints.
*/
const unsigned long ROLE_TOOLTIP = 13;
/**
* Represents a main window for an application. It is used for
* role="application". Also refer to ROLE_APP_ROOT
*/
const unsigned long ROLE_APPLICATION = 14;
/**
* Represents a document window. A document window is always contained within
* an application window. It is used for role="document".
*/
const unsigned long ROLE_DOCUMENT = 15;
/**
* Represents a pane within a frame or document window. Users can navigate
* between panes and within the contents of the current pane, but cannot
* navigate between items in different panes. Thus, panes represent a level
* of grouping lower than frame windows or documents, but above individual
* controls. It is used for the first child of a <frame> or <iframe>.
*/
const unsigned long ROLE_PANE = 16;
/**
* Represents a graphical image used to represent data.
*/
const unsigned long ROLE_CHART = 17;
/**
* Represents a dialog box or message box. It is used for xul:dialog,
* role="dialog".
*/
const unsigned long ROLE_DIALOG = 18;
/**
* Represents a window border.
*/
const unsigned long ROLE_BORDER = 19;
/**
* Logically groups other objects. There is not always a parent-child
* relationship between the grouping object and the objects it contains. It
* is used for html:textfield, xul:groupbox, role="group".
*/
const unsigned long ROLE_GROUPING = 20;
/**
* Used to visually divide a space into two regions, such as a separator menu
* item or a bar that divides split panes within a window. It is used for
* xul:separator, html:hr, role="separator".
*/
const unsigned long ROLE_SEPARATOR = 21;
/**
* Represents a toolbar, which is a grouping of controls (push buttons or
* toggle buttons) that provides easy access to frequently used features. It
* is used for xul:toolbar, role="toolbar".
*/
const unsigned long ROLE_TOOLBAR = 22;
/**
* Represents a status bar, which is an area at the bottom of a window that
* displays information about the current operation, state of the application,
* or selected object. The status bar has multiple fields, which display
* different kinds of information. It is used for xul:statusbar.
*/
const unsigned long ROLE_STATUSBAR = 23;
/**
* Represents a table that contains rows and columns of cells, and optionally,
* row headers and column headers. It is used for html:table,
* role="grid". Also refer to the following roles: ROLE_COLUMNHEADER,
* ROLE_ROWHEADER, ROLE_COLUMN, ROLE_ROW, ROLE_CELL.
*/
const unsigned long ROLE_TABLE = 24;
/**
* Represents a column header, providing a visual label for a column in
* a table. It is used for XUL tree column headers, html:th,
* role="colheader". Also refer to ROLE_TABLE.
*/
const unsigned long ROLE_COLUMNHEADER = 25;
/**
* Represents a row header, which provides a visual label for a table row.
* It is used for role="rowheader". Also, see ROLE_TABLE.
*/
const unsigned long ROLE_ROWHEADER = 26;
/**
* Represents a column of cells within a table. Also, see ROLE_TABLE.
*/
const unsigned long ROLE_COLUMN = 27;
/**
* Represents a row of cells within a table. Also, see ROLE_TABLE.
*/
const unsigned long ROLE_ROW = 28;
/**
* Represents a cell within a table. It is used for html:td,
* xul:tree cell and xul:listcell. Also, see ROLE_TABLE.
*/
const unsigned long ROLE_CELL = 29;
/**
* Represents a link to something else. This object might look like text or
* a graphic, but it acts like a button. It is used for
* xul:label@class="text-link", html:a, html:area.
*/
const unsigned long ROLE_LINK = 30;
/**
* Displays a Help topic in the form of a ToolTip or Help balloon.
*/
const unsigned long ROLE_HELPBALLOON = 31;
/**
* Represents a cartoon-like graphic object, such as Microsoft Office
* Assistant, which is displayed to provide help to users of an application.
*/
const unsigned long ROLE_CHARACTER = 32;
/**
* Represents a list box, allowing the user to select one or more items. It
* is used for xul:listbox, html:select@size, role="list". See also
* ROLE_LIST_ITEM.
*/
const unsigned long ROLE_LIST = 33;
/**
* Represents an item in a list. See also ROLE_LIST.
*/
const unsigned long ROLE_LISTITEM = 34;
/**
* Represents an outline or tree structure, such as a tree view control,
* that displays a hierarchical list and allows the user to expand and
* collapse branches. Is is used for role="tree".
*/
const unsigned long ROLE_OUTLINE = 35;
/**
* Represents an item in an outline or tree structure. It is used for
* role="treeitem".
*/
const unsigned long ROLE_OUTLINEITEM = 36;
/**
* Represents a page tab, it is a child of a page tab list. It is used for
* xul:tab, role="treeitem". Also refer to ROLE_PAGETABLIST.
*/
const unsigned long ROLE_PAGETAB = 37;
/**
* Represents a property sheet. It is used for xul:tabpanel,
* role="tabpanel".
*/
const unsigned long ROLE_PROPERTYPAGE = 38;
/**
* Represents an indicator, such as a pointer graphic, that points to the
* current item.
*/
const unsigned long ROLE_INDICATOR = 39;
/**
* Represents a picture. Is is used for xul:image, html:img.
*/
const unsigned long ROLE_GRAPHIC = 40;
/**
* Represents read-only text, such as labels for other controls or
* instructions in a dialog box. Static text cannot be modified or selected.
* Is is used for xul:label, xul:description, html:label, role="label".
*/
const unsigned long ROLE_STATICTEXT = 41;
/**
* Represents selectable text that allows edits or is designated read-only.
*/
const unsigned long ROLE_TEXT_LEAF = 42;
/**
* Represents a push button control. It is used for xul:button, html:button,
* role="button".
*/
const unsigned long ROLE_PUSHBUTTON = 43;
/**
* Represents a check box control. It is used for xul:checkbox,
* html:input@type="checkbox", role="checkbox".
*/
const unsigned long ROLE_CHECKBUTTON = 44;
/**
* Represents an option button, also called a radio button. It is one of a
* group of mutually exclusive options. All objects sharing a single parent
* that have this attribute are assumed to be part of single mutually
* exclusive group. It is used for xul:radio, html:input@type="radio",
* role="radio".
*/
const unsigned long ROLE_RADIOBUTTON = 45;
/**
* Represents a combo box; an edit control with an associated list box that
* provides a set of predefined choices. It is used for html:select,
* xul:menulist, role="combobox".
*/
const unsigned long ROLE_COMBOBOX = 46;
/**
* Represents the calendar control.
*/
const unsigned long ROLE_DROPLIST = 47;
/**
* Represents a progress bar, dynamically showing the user the percent
* complete of an operation in progress. It is used for xul:progressmeter,
* role="progressbar".
*/
const unsigned long ROLE_PROGRESSBAR = 48;
/**
* Represents a dial or knob whose purpose is to allow a user to set a value.
*/
const unsigned long ROLE_DIAL = 49;
/**
* Represents a hot-key field that allows the user to enter a combination or
* sequence of keystrokes.
*/
const unsigned long ROLE_HOTKEYFIELD = 50;
/**
* Represents a slider, which allows the user to adjust a setting in given
* increments between minimum and maximum values. It is used by xul:scale,
* role="slider".
*/
const unsigned long ROLE_SLIDER = 51;
/**
* Represents a spin box, which is a control that allows the user to increment
* or decrement the value displayed in a separate "buddy" control associated
* with the spin box. It is used for xul:spinbuttons.
*/
const unsigned long ROLE_SPINBUTTON = 52;
/**
* Represents a graphical image used to diagram data. It is used for svg:svg.
*/
const unsigned long ROLE_DIAGRAM = 53;
/**
* Represents an animation control, which contains content that changes over
* time, such as a control that displays a series of bitmap frames.
*/
const unsigned long ROLE_ANIMATION = 54;
/**
* Represents a mathematical equation. It is used by MATHML, where there is a
* rich DOM subtree for an equation. Use ROLE_FLAT_EQUATION for <img role="math" alt="[TeX]"/>
*/
const unsigned long ROLE_EQUATION = 55;
/**
* Represents a button that drops down a list of items.
*/
const unsigned long ROLE_BUTTONDROPDOWN = 56;
/**
* Represents a button that drops down a menu.
*/
const unsigned long ROLE_BUTTONMENU = 57;
/**
* Represents a button that drops down a grid. It is used for xul:colorpicker.
*/
const unsigned long ROLE_BUTTONDROPDOWNGRID = 58;
/**
* Represents blank space between other objects.
*/
const unsigned long ROLE_WHITESPACE = 59;
/**
* Represents a container of page tab controls. Is it used for xul:tabs,
* DHTML: role="tabs". Also refer to ROLE_PAGETAB.
*/
const unsigned long ROLE_PAGETABLIST = 60;
/**
* Represents a control that displays time.
*/
const unsigned long ROLE_CLOCK = 61;
/**
* Represents a button on a toolbar that has a drop-down list icon directly
* adjacent to the button.
*/
const unsigned long ROLE_SPLITBUTTON = 62;
/**
* Represents an edit control designed for an Internet Protocol (IP) address.
* The edit control is divided into sections for the different parts of the
* IP address.
*/
const unsigned long ROLE_IPADDRESS = 63;
/**
* Represents a label control that has an accelerator.
*/
const unsigned long ROLE_ACCEL_LABEL = 64;
/**
* Represents an arrow in one of the four cardinal directions.
*/
const unsigned long ROLE_ARROW = 65;
/**
* Represents a control that can be drawn into and is used to trap events.
* It is used for html:canvas.
*/
const unsigned long ROLE_CANVAS = 66;
/**
* Represents a menu item with a check box.
*/
const unsigned long ROLE_CHECK_MENU_ITEM = 67;
/**
* Represents a specialized dialog that lets the user choose a color.
*/
const unsigned long ROLE_COLOR_CHOOSER = 68;
/**
* Represents control whose purpose is to allow a user to edit a date.
*/
const unsigned long ROLE_DATE_EDITOR = 69;
/**
* An iconified internal frame in an ROLE_DESKTOP_PANE. Also refer to
* ROLE_INTERNAL_FRAME.
*/
const unsigned long ROLE_DESKTOP_ICON = 70;
/**
* A desktop pane. A pane that supports internal frames and iconified
* versions of those internal frames.
*/
const unsigned long ROLE_DESKTOP_FRAME = 71;
/**
* A directory pane. A pane that allows the user to navigate through
* and select the contents of a directory. May be used by a file chooser.
* Also refer to ROLE_FILE_CHOOSER.
*/
const unsigned long ROLE_DIRECTORY_PANE = 72;
/**
* A file chooser. A specialized dialog that displays the files in the
* directory and lets the user select a file, browse a different directory,
* or specify a filename. May use the directory pane to show the contents of
* a directory. Also refer to ROLE_DIRECTORY_PANE.
*/
const unsigned long ROLE_FILE_CHOOSER = 73;
/**
* A font chooser. A font chooser is a component that lets the user pick
* various attributes for fonts.
*/
const unsigned long ROLE_FONT_CHOOSER = 74;
/**
* Frame role. A top level window with a title bar, border, menu bar, etc.
* It is often used as the primary window for an application.
*/
const unsigned long ROLE_CHROME_WINDOW = 75;
/**
* A glass pane. A pane that is guaranteed to be painted on top of all
* panes beneath it. Also refer to ROLE_ROOT_PANE.
*/
const unsigned long ROLE_GLASS_PANE = 76;
/**
* A document container for HTML, whose children represent the document
* content.
*/
const unsigned long ROLE_HTML_CONTAINER = 77;
/**
* A small fixed size picture, typically used to decorate components.
*/
const unsigned long ROLE_ICON = 78;
/**
* Presents an icon or short string in an interface.
*/
const unsigned long ROLE_LABEL = 79;
/**
* A layered pane. A specialized pane that allows its children to be drawn
* in layers, providing a form of stacking order. This is usually the pane
* that holds the menu bar as well as the pane that contains most of the
* visual components in a window. Also refer to ROLE_GLASS_PANE and
* ROLE_ROOT_PANE.
*/
const unsigned long ROLE_LAYERED_PANE = 80;
/**
* A specialized pane whose primary use is inside a dialog.
*/
const unsigned long ROLE_OPTION_PANE = 81;
/**
* A text object uses for passwords, or other places where the text content
* is not shown visibly to the user.
*/
const unsigned long ROLE_PASSWORD_TEXT = 82;
/**
* A temporary window that is usually used to offer the user a list of
* choices, and then hides when the user selects one of those choices.
*/
const unsigned long ROLE_POPUP_MENU = 83;
/**
* A radio button that is a menu item.
*/
const unsigned long ROLE_RADIO_MENU_ITEM = 84;
/**
* A root pane. A specialized pane that has a glass pane and a layered pane
* as its children. Also refer to ROLE_GLASS_PANE and ROLE_LAYERED_PANE.
*/
const unsigned long ROLE_ROOT_PANE = 85;
/**
* A scroll pane. An object that allows a user to incrementally view a large
* amount of information. Its children can include scroll bars and a
* viewport. Also refer to ROLE_VIEW_PORT.
*/
const unsigned long ROLE_SCROLL_PANE = 86;
/**
* A split pane. A specialized panel that presents two other panels at the
* same time. Between the two panels is a divider the user can manipulate to
* make one panel larger and the other panel smaller.
*/
const unsigned long ROLE_SPLIT_PANE = 87;
/**
* The header for a column of a table.
* XXX: it looks this role is dupe of ROLE_COLUMNHEADER.
*/
const unsigned long ROLE_TABLE_COLUMN_HEADER = 88;
/**
* The header for a row of a table.
* XXX: it looks this role is dupe of ROLE_ROWHEADER
*/
const unsigned long ROLE_TABLE_ROW_HEADER = 89;
/**
* A menu item used to tear off and reattach its menu.
*/
const unsigned long ROLE_TEAR_OFF_MENU_ITEM = 90;
/**
* Represents an accessible terminal.
*/
const unsigned long ROLE_TERMINAL = 91;
/**
* Collection of objects that constitute a logical text entity.
*/
const unsigned long ROLE_TEXT_CONTAINER = 92;
/**
* A toggle button. A specialized push button that can be checked or
* unchecked, but does not provide a separate indicator for the current state.
*/
const unsigned long ROLE_TOGGLE_BUTTON = 93;
/**
* Representas a control that is capable of expanding and collapsing rows as
* well as showing multiple columns of data.
* XXX: it looks like this role is dupe of ROLE_OUTLINE.
*/
const unsigned long ROLE_TREE_TABLE = 94;
/**
* A viewport. An object usually used in a scroll pane. It represents the
* portion of the entire data that the user can see. As the user manipulates
* the scroll bars, the contents of the viewport can change. Also refer to
* ROLE_SCROLL_PANE.
*/
const unsigned long ROLE_VIEWPORT = 95;
/**
* Header of a document page. Also refer to ROLE_FOOTER.
*/
const unsigned long ROLE_HEADER = 96;
/**
* Footer of a document page. Also refer to ROLE_HEADER.
*/
const unsigned long ROLE_FOOTER = 97;
/**
* A paragraph of text.
*/
const unsigned long ROLE_PARAGRAPH = 98;
/**
* A ruler such as those used in word processors.
*/
const unsigned long ROLE_RULER = 99;
/**
* A text entry having dialog or list containing items for insertion into
* an entry widget, for instance a list of words for completion of a
* text entry. It is used for xul:textbox@autocomplete
*/
const unsigned long ROLE_AUTOCOMPLETE = 100;
/**
* An editable text object in a toolbar.
*/
const unsigned long ROLE_EDITBAR = 101;
/**
* An control whose textual content may be entered or modified by the user.
*/
const unsigned long ROLE_ENTRY = 102;
/**
* A caption describing another object.
*/
const unsigned long ROLE_CAPTION = 103;
/**
* A visual frame or container which contains a view of document content.
* Document frames may occur within another Document instance, in which case
* the second document may be said to be embedded in the containing instance.
* HTML frames are often ROLE_DOCUMENT_FRAME. Either this object, or a
* singleton descendant, should implement the Document interface.
*/
const unsigned long ROLE_DOCUMENT_FRAME = 104;
/**
* Heading.
*/
const unsigned long ROLE_HEADING = 105;
/**
* An object representing a page of document content. It is used in documents
* which are accessed by the user on a page by page basis.
*/
const unsigned long ROLE_PAGE = 106;
/**
* A container of document content. An example of the use of this role is to
* represent an html:div.
*/
const unsigned long ROLE_SECTION = 107;
/**
* An object which is redundant with another object in the accessible
* hierarchy. ATs typically ignore objects with this role.
*/
const unsigned long ROLE_REDUNDANT_OBJECT = 108;
/**
* A container of form controls. An example of the use of this role is to
* represent an html:form.
*/
const unsigned long ROLE_FORM = 109;
/**
* An object which is used to allow input of characters not found on a
* keyboard, such as the input of Chinese characters on a Western keyboard.
*/
const unsigned long ROLE_IME = 110;
/**
* XXX: document this.
*/
const unsigned long ROLE_APP_ROOT = 111;
/**
* Represents a menu item, which is an entry in a menu that a user can choose
* to display another menu.
*/
const unsigned long ROLE_PARENT_MENUITEM = 112;
/**
* A calendar that allows the user to select a date.
*/
const unsigned long ROLE_CALENDAR = 113;
/**
* A list of items that is shown by combobox.
*/
const unsigned long ROLE_COMBOBOX_LIST = 114;
/**
* A item of list that is shown by combobox;
*/
const unsigned long ROLE_COMBOBOX_OPTION = 115;
/**
* An image map -- has child links representing the areas
*/
const unsigned long ROLE_IMAGE_MAP = 116;
/**
* An option in a listbox
*/
const unsigned long ROLE_OPTION = 117;
/**
* A rich option in a listbox, it can have other widgets as children
*/
const unsigned long ROLE_RICH_OPTION = 118;
/**
* A list of options
*/
const unsigned long ROLE_LISTBOX = 119;
/**
* Represents a mathematical equation in the accessible name
*/
const unsigned long ROLE_FLAT_EQUATION = 120;
/**
* Represents a cell within a grid. It is used for role="gridcell". Unlike
* ROLE_CELL, it allows the calculation of the accessible name from subtree.
* Also, see ROLE_TABLE.
*/
const unsigned long ROLE_GRID_CELL = 121;
/**
* Represents an embedded object. It is used for html:object or html:embed.
*/
const unsigned long ROLE_EMBEDDED_OBJECT = 122;
/**
* A note. Originally intended to be hidden until activated, but now also used
* for things like html 'aside'.
*/
const unsigned long ROLE_NOTE = 123;
/**
* A figure. Used for things like HTML5 figure element.
*/
const unsigned long ROLE_FIGURE = 124;
/**
* Represents a rich item with a check box.
*/
const unsigned long ROLE_CHECK_RICH_OPTION = 125;
/**
* An HTML definition list <dl>
*/
const unsigned long ROLE_DEFINITION_LIST = 126;
/**
* An HTML definition term <dt>
*/
const unsigned long ROLE_TERM = 127;
/**
* An HTML definition <dd>
*/
const unsigned long ROLE_DEFINITION = 128;
/**
* A keyboard or keypad key.
*/
const unsigned long ROLE_KEY = 129;
};
@@ -0,0 +1,72 @@
/* -*- 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 "nsISupports.idl"
#include "nsIAccessible.idl"
#include "nsIArray.idl"
/**
* An interface for the accessibility module and in-process accessibility clients
* for dealing with getting and changing the selection of accessible nodes.
*/
[scriptable, uuid(34d268d6-1dd2-11b2-9d63-83a5e0ada290)]
interface nsIAccessibleSelectable : nsISupports
{
const unsigned long eSelection_Add = 0;
const unsigned long eSelection_Remove = 1;
const unsigned long eSelection_GetState = 2;
/**
* Return an nsIArray of selected nsIAccessible children
*/
nsIArray GetSelectedChildren();
/**
* Returns the number of accessible children currently selected.
*/
readonly attribute long selectionCount;
/**
* Adds the specified accessible child of the object to the
* object's selection.
* If the specified object is already selected, then it does nothing.
* @throws NS_ERROR_FAILURE if the specified object is not selectable.
*/
void addChildToSelection(in long index);
/**
* Removes the specified child of the object from the object's selection.
* If the specified object was not selected, then it does nothing.
* @throws NS_ERROR_FAILURE if the specified object is not selectable.
*/
void removeChildFromSelection(in long index);
/**
* Clears the selection in the object so that no children in the object
* are selected.
*/
void clearSelection();
/**
* Returns a reference to the accessible object representing the specified
* selected child of the object.
* @param index Zero-based selected accessible child index
* @return The nth selected accessible child
*/
nsIAccessible refSelection(in long index);
/**
* Determines if the current child of this object is selected
* @param The zero-based accessible child index
* @return Returns true if the child is selected, false if not.
*/
boolean isChildSelected(in long index);
/**
* Select all children
* @return If the object does not accept multiple selection, return false.
* Otherwise, returns true.
*/
boolean selectAllSelection();
};
@@ -0,0 +1,29 @@
/* -*- 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 "nsIAccessibleEvent.idl"
/**
* Fired when a state of an accessible changes.
*/
[scriptable, builtinclass, uuid(0d2d77c5-7b16-4a15-8b20-c484ceb5ac0d)]
interface nsIAccessibleStateChangeEvent : nsIAccessibleEvent
{
/**
* Returns the state of accessible (see constants declared
* in nsIAccessibleStates).
*/
readonly attribute unsigned long state;
/**
* Returns true if the state is extra state.
*/
readonly attribute boolean isExtraState;
/**
* Returns true if the state is turned on.
*/
readonly attribute boolean isEnabled;
};
+76
View File
@@ -0,0 +1,76 @@
/* -*- 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 "nsISupports.idl"
[scriptable, uuid(f1e0fbb7-fde4-4519-9383-2bcbee428513)]
interface nsIAccessibleStates : nsISupports
{
/**
* MSAA State flags - used for bitfield. More than 1 allowed.
*/
const unsigned long STATE_UNAVAILABLE = 0x00000001; // Disabled, maps to opposite of Java ENABLED, Gnome/ATK SENSITIVE?
const unsigned long STATE_SELECTED = 0x00000002;
const unsigned long STATE_FOCUSED = 0x00000004;
const unsigned long STATE_PRESSED = 0x00000008;
const unsigned long STATE_CHECKED = 0x00000010;
const unsigned long STATE_MIXED = 0x00000020; // 3-state checkbox or toolbar button
const unsigned long STATE_READONLY = 0x00000040; // Maps to opposite of Java/Gnome/ATK EDITABLE state
const unsigned long STATE_HOTTRACKED = 0x00000080;
const unsigned long STATE_DEFAULT = 0x00000100;
const unsigned long STATE_EXPANDED = 0x00000200;
const unsigned long STATE_COLLAPSED = 0x00000400;
const unsigned long STATE_BUSY = 0x00000800;
const unsigned long STATE_FLOATING = 0x00001000; // Children "owned" not "contained" by parent
const unsigned long STATE_MARQUEED = 0x00002000;
const unsigned long STATE_ANIMATED = 0x00004000;
const unsigned long STATE_INVISIBLE = 0x00008000; // Programatically hidden
const unsigned long STATE_OFFSCREEN = 0x00010000; // Scrolled off
const unsigned long STATE_SIZEABLE = 0x00020000;
const unsigned long STATE_MOVEABLE = 0x00040000;
const unsigned long STATE_SELFVOICING = 0x00080000;
const unsigned long STATE_FOCUSABLE = 0x00100000;
const unsigned long STATE_SELECTABLE = 0x00200000;
const unsigned long STATE_LINKED = 0x00400000;
const unsigned long STATE_TRAVERSED = 0x00800000;
const unsigned long STATE_MULTISELECTABLE = 0x01000000; // Supports multiple selection
const unsigned long STATE_EXTSELECTABLE = 0x02000000; // Supports extended selection
const unsigned long STATE_ALERT_LOW = 0x04000000; // This information is of low priority
const unsigned long STATE_ALERT_MEDIUM = 0x08000000; // This information is of medium priority
const unsigned long STATE_ALERT_HIGH = 0x10000000; // This information is of high priority
const unsigned long STATE_PROTECTED = 0x20000000; // Maps to Gnome's *Role* ATK_ROLE_PASSWD_TEXT, nothing for Java?
const unsigned long STATE_HASPOPUP = 0x40000000; // New in MSAA 2.0
// Mapping important states that we don't have to unused alert states on MSAA
// as per discussions with AT vendors. On ATK there will be legitimate states for
// STATE_REQUIRED AND STATE_INVALID
const unsigned long STATE_REQUIRED = STATE_ALERT_LOW;
const unsigned long STATE_IMPORTANT = STATE_ALERT_MEDIUM; // Not currently used
const unsigned long STATE_INVALID = STATE_ALERT_HIGH;
const unsigned long STATE_CHECKABLE = STATE_MARQUEED;
/**
* Extended state flags (for now non-MSAA, for Java and Gnome/ATK support)
* "Extended state flags" has separate value space from "MSAA State flags".
*/
const unsigned long EXT_STATE_SUPPORTS_AUTOCOMPLETION = 0x00000001; // For editable areas that have any kind of autocompletion
const unsigned long EXT_STATE_DEFUNCT = 0x00000002; // Object no longer exists
const unsigned long EXT_STATE_SELECTABLE_TEXT = 0x00000004; // For text which is selectable, object must implement nsIAccessibleText
const unsigned long EXT_STATE_EDITABLE = 0x00000008; // Implements nsIAccessibleEditableText
const unsigned long EXT_STATE_ACTIVE = 0x00000010; // This window is currently the active window
const unsigned long EXT_STATE_MODAL = 0x00000020; // Must do something with control before leaving it
const unsigned long EXT_STATE_MULTI_LINE = 0x00000040; // Edit control that can take multiple lines
const unsigned long EXT_STATE_HORIZONTAL = 0x00000080; // Uses horizontal layout
const unsigned long EXT_STATE_OPAQUE = 0x00000100; // Indicates this object paints every pixel within its rectangular region.
const unsigned long EXT_STATE_SINGLE_LINE = 0x00000200; // This text object can only contain 1 line of text
const unsigned long EXT_STATE_TRANSIENT = 0x00000400; //
const unsigned long EXT_STATE_VERTICAL = 0x00000800; // Especially used for sliders and scrollbars
const unsigned long EXT_STATE_STALE = 0x00001000; // Object not dead, but not up-to-date either
const unsigned long EXT_STATE_ENABLED = 0x00002000; // A widget that is not unavailable
const unsigned long EXT_STATE_SENSITIVE = 0x00004000; // Same as ENABLED for now
const unsigned long EXT_STATE_EXPANDABLE = 0x00008000; // If COLLAPSED or EXPANDED
const unsigned long EXT_STATE_PINNED = 0x00010000; // Indicates object is pinned.
};
+268
View File
@@ -0,0 +1,268 @@
/* -*- 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 "nsISupports.idl"
interface nsIAccessible;
interface nsIArray;
[scriptable, uuid(cb0bf7b9-117e-40e2-9e46-189c3d43ce4a)]
interface nsIAccessibleTable : nsISupports
{
/**
* Return the caption accessible for the table. For example, html:caption
* element of html:table element.
*/
readonly attribute nsIAccessible caption;
/**
* Return summary description for the table. For example, @summary attribute
* on html:table element.
*/
readonly attribute AString summary;
/**
* Return columns count in the table.
*/
readonly attribute long columnCount;
/**
* Return rows count in the table.
*/
readonly attribute long rowCount;
/**
* Return the accessible object at the specified row and column in the table.
* If both row and column index are valid then the corresponding accessible
* object is returned that represents the requested cell regardless of whether
* the cell is currently visible (on the screen).
*
* @param rowIndex [in] the row index to retrieve the cell at
* @param columnIndex [in] the column index to retrieve the cell at
*/
nsIAccessible getCellAt(in long rowIndex, in long columnIndex);
/**
* Translate the given row and column indices into the corresponding cell
* index.
*
* @param rowIndex [in] the row index to return cell index at
* @param columnIndex [in] the column index to return cell index at
*/
long getCellIndexAt(in long rowIndex, in long columnIndex);
/**
* Translate the given cell index into the corresponding column index.
*
* @param cellIndex [in] index of the table cell to return column index for
*/
long getColumnIndexAt(in long cellIndex);
/**
* Translate the given cell index into the corresponding row index.
*
* @param cellIndex [in] index of the table cell to return row index for
*/
long getRowIndexAt(in long cellIndex);
/**
* Translate the given cell index into the corresponding row and column
* indices.
*
* @param cellIndex [in] cell index to return row and column indices for
* @param rowIndex [out] row index at the given cell index
* @param columnIndex [out] column index at the given cell index
*/
void getRowAndColumnIndicesAt(in long cellIndex,
out long rowIndex, out long columnIndex);
/**
* Return the number of columns occupied by the accessible cell at
* the specified row and column in the table. The result differs from 1 if
* the specified cell spans multiple columns.
*
* @param row [in] row index of the cell to return the column extent for
* @param column [in] column index of the cell to return the column extent
* for
*/
long getColumnExtentAt(in long row, in long column);
/**
* Return the number of rows occupied by the accessible cell at the specified
* row and column in the table. The result differs from 1 if the specified
* cell spans multiple rows.
*
* @param row [in] row index of the cell to return the column extent for
* @param column [in] column index of the cell to return the column extent
* for
*/
long getRowExtentAt(in long row, in long column);
/**
* Return the description text of the specified column in the table.
*
* @param columnIndex [in] the column index to retrieve description for
*/
AString getColumnDescription(in long columnIndex);
/**
* Return the description text of the specified row in the table.
*
* @param rowIndex [in] the row index to retrieve description for
*/
AString getRowDescription(in long rowIndex);
/**
* Return a boolean value indicating whether the specified column is
* selected, i.e. all cells within the column are selected.
*
* @param columnIndex [in] the column index to determine if it's selected
*/
boolean isColumnSelected(in long columnIndex);
/**
* Return a boolean value indicating whether the specified row is selected,
* i.e. all cells within the row are selected.
*
* @param rowIndex [in] the row index to determine whether it's selected
*/
boolean isRowSelected(in long rowIndex);
/**
* Return a boolean value indicating whether the specified cell is selected.
*
* @param rowIndex [in] the row index of the cell
* @param columnIndex [in] the column index of the cell
*/
boolean isCellSelected(in long rowIndex, in long columnIndex);
/**
* Return the total number of selected cells.
*/
readonly attribute unsigned long selectedCellCount;
/**
* Return the total number of selected columns.
*/
readonly attribute unsigned long selectedColumnCount;
/**
* Return the total number of selected rows.
*/
readonly attribute unsigned long selectedRowCount;
/**
* Return an array of selected cells.
*/
readonly attribute nsIArray selectedCells;
/**
* Return an array of cell indices currently selected.
*
* @param cellsArraySize [in] length of array
* @param cellsArray [in] array of indexes of selected cells
*/
void getSelectedCellIndices(out unsigned long cellsArraySize,
[retval, array, size_is(cellsArraySize)] out long cellsArray);
/**
* Return an array of column indices currently selected.
*
* @param columnsArraySize [in] length of array
* @param columnsArray [in] array of indices of selected columns
*/
void getSelectedColumnIndices(out unsigned long columnsArraySize,
[retval, array, size_is(columnsArraySize)] out long columnsArray);
/**
* Return an array of row indices currently selected.
*
* @param rowsArraySize [in] Length of array
* @param rowsArray [in] array of indices of selected rows
*/
void getSelectedRowIndices(out unsigned long rowsArraySize,
[retval, array, size_is(rowsArraySize)] out long rowsArray);
/**
* Select a row and unselects all previously selected rows.
*
* @param rowIndex [in] the row index to select
*/
void selectRow(in long rowIndex);
/**
* Select a column and unselects all previously selected columns.
*
* @param columnIndex [in] the column index to select
*/
void selectColumn(in long columnIndex);
/**
* Unselect the given row, leaving other selected rows selected (if any).
*
* @param rowIndex [in] the row index to select
*/
void unselectRow(in long rowIndex);
/**
* Unselect the given column, leaving other selected columns selected (if any).
*
* @param columnIndex [in] the column index to select
*/
void unselectColumn(in long columnIndex);
/**
* Use heuristics to determine if table is most likely used for layout.
*/
boolean isProbablyForLayout();
};
[scriptable, uuid(654e296d-fae6-452b-987d-746b20b9514b)]
interface nsIAccessibleTableCell : nsISupports
{
/**
* Return host table accessible.
*/
readonly attribute nsIAccessibleTable table;
/**
* Return column index of this cell.
*/
readonly attribute long columnIndex;
/**
* Return row index of this cell.
*/
readonly attribute long rowIndex;
/**
* Return the number of columns occupied by this cell. The result differs
* from 1 if the specified cell spans multiple columns.
*/
readonly attribute long columnExtent;
/**
* Return the number of rows occupied by this accessible cell. The result
* differs from 1 if the specified cell spans multiple rows.
*/
readonly attribute long rowExtent;
/**
* Return an array of column header cells for this cell.
*/
readonly attribute nsIArray columnHeaderCells;
/**
* Return an array of row header cells for this cell.
*/
readonly attribute nsIArray rowHeaderCells;
/**
* Return a boolean value indicating whether this cell is selected.
*/
boolean isSelected();
};
@@ -0,0 +1,20 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "nsIAccessibleEvent.idl"
[scriptable, builtinclass, uuid(df517997-ed52-4ea2-b310-2f8e0fe64572)]
interface nsIAccessibleTableChangeEvent: nsIAccessibleEvent
{
/**
* Return the row or column index.
*/
readonly attribute long rowOrColIndex;
/**
* Return the number of rows or cols
*/
readonly attribute long RowsOrColsCount;
};
+208
View File
@@ -0,0 +1,208 @@
/* -*- 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 "nsISupports.idl"
typedef long AccessibleTextBoundary;
interface nsIAccessible;
interface nsIPersistentProperties;
[scriptable, uuid(0f4633b1-550c-4b50-8c04-0eb1005eef2f)]
interface nsIAccessibleText : nsISupports
{
// In parameters for character offsets:
// -1 will be treated as the equal to the end of the text
// -2 will be treated as the caret position
const int32_t TEXT_OFFSET_END_OF_TEXT = -1;
const int32_t TEXT_OFFSET_CARET = -2;
const AccessibleTextBoundary BOUNDARY_CHAR = 0;
const AccessibleTextBoundary BOUNDARY_WORD_START = 1;
const AccessibleTextBoundary BOUNDARY_WORD_END = 2;
const AccessibleTextBoundary BOUNDARY_SENTENCE_START = 3; // don't use, deprecated
const AccessibleTextBoundary BOUNDARY_SENTENCE_END = 4; // don't use, deprecated
const AccessibleTextBoundary BOUNDARY_LINE_START = 5;
const AccessibleTextBoundary BOUNDARY_LINE_END = 6;
const AccessibleTextBoundary BOUNDARY_ATTRIBUTE_RANGE = 7;
/**
* The current current caret offset.
* If set < 0 then caret will be placed at the end of the text
*/
attribute long caretOffset;
readonly attribute long characterCount;
readonly attribute long selectionCount;
/**
* String methods may need to return multibyte-encoded strings,
* since some locales can't be encoded using 16-bit chars.
* So the methods below might return UTF-16 strings, or they could
* return "string" values which are UTF-8.
*/
AString getText (in long startOffset, in long endOffset);
AString getTextAfterOffset (in long offset,
in AccessibleTextBoundary boundaryType,
out long startOffset,
out long endOffset);
AString getTextAtOffset (in long offset,
in AccessibleTextBoundary boundaryType,
out long startOffset,
out long endOffset);
AString getTextBeforeOffset (in long offset,
in AccessibleTextBoundary boundaryType,
out long startOffset,
out long endOffset);
/**
* It would be better to return an unsigned long here,
* to allow unicode chars > 16 bits
*/
wchar getCharacterAtOffset (in long offset);
/**
* Get the accessible start/end offsets around the given offset,
* return the text attributes for this range of text.
*
* @param includeDefAttrs [in] points whether text attributes applied to
* the entire accessible should be included or not.
* @param offset [in] text offset
* @param rangeStartOffset [out] start offset of the range of text
* @param rangeEndOffset [out] end offset of the range of text
*/
nsIPersistentProperties getTextAttributes(in boolean includeDefAttrs,
in long offset,
out long rangeStartOffset,
out long rangeEndOffset);
/**
* Return the text attributes that apply to the entire accessible.
*/
readonly attribute nsIPersistentProperties defaultTextAttributes;
/**
* Returns the bounding box of the specified position.
*
* The virtual character after the last character of the represented text,
* i.e. the one at position length is a special case. It represents the
* current input position and will therefore typically be queried by AT more
* often than other positions. Because it does not represent an existing
* character its bounding box is defined in relation to preceding characters.
* It should be roughly equivalent to the bounding box of some character when
* inserted at the end of the text. Its height typically being the maximal
* height of all the characters in the text or the height of the preceding
* character, its width being at least one pixel so that the bounding box is
* not degenerate.
*
* @param offset - Index of the character for which to return its bounding
* box. The valid range is 0..length.
* @param x - X coordinate of the bounding box of the referenced character.
* @param y - Y coordinate of the bounding box of the referenced character.
* @param width - Width of the bounding box of the referenced character.
* @param height - Height of the bounding box of the referenced character.
* @param coordType - Specifies if the coordinates are relative to the screen
* or to the parent window (see constants declared in
* nsIAccessibleCoordinateType).
*/
void getCharacterExtents (in long offset,
out long x,
out long y,
out long width,
out long height,
in unsigned long coordType);
void getRangeExtents (in long startOffset,
in long endOffset,
out long x,
out long y,
out long width,
out long height,
in unsigned long coordType);
/**
* Get the text offset at the given point, or return -1
* if no character exists at that point
*
* @param x - The position's x value for which to look up the index of the
* character that is rendered on to the display at that point.
* @param y - The position's y value for which to look up the index of the
* character that is rendered on to the display at that point.
* @param coordType - Screen coordinates or window coordinates (see constants
* declared in nsIAccessibleCoordinateType).
* @return offset - Index of the character under the given point or -1 if
* the point is invalid or there is no character under
* the point.
*/
long getOffsetAtPoint (in long x, in long y,
in unsigned long coordType);
void getSelectionBounds (in long selectionNum,
out long startOffset,
out long endOffset);
/**
* Set the bounds for the given selection range
*/
void setSelectionBounds (in long selectionNum,
in long startOffset,
in long endOffset);
void addSelection (in long startOffset, in long endOffset);
void removeSelection (in long selectionNum);
/**
* Makes a specific part of string visible on screen.
*
* @param startIndex 0-based character offset
* @param endIndex 0-based character offset - the offset of the
* character just past the last character of the
* string
* @param scrollType defines how to scroll (see nsIAccessibleScrollType for
* available constants)
*/
void scrollSubstringTo(in long startIndex, in long endIndex,
in unsigned long scrollType);
/**
* Moves the top left of a substring to a specified location.
*
* @param startIndex 0-based character offset
* @param endIndex 0-based character offset - the offset of the
* character just past the last character of
* the string
* @param coordinateType specifies the coordinates origin (for available
* constants refer to nsIAccessibleCoordinateType)
* @param x defines the x coordinate
* @param y defines the y coordinate
*/
void scrollSubstringToPoint(in long startIndex, in long endIndex,
in unsigned long coordinateType,
in long x, in long y);
};
/*
Assumptions:
Using wstring (UCS2) instead of string encoded in UTF-8.
Multibyte encodings (or at least potentially multi-byte
encodings) would be preferred for the reasons cited above.
The following methods will throw an exception on failure
(since not every text component will allow every operation):
setSelectionBounds, addSelection, removeSelection, setCaretOffset.
we assume that all text components support the idea of
a caret offset, whether visible or "virtual". If this
isn't the case, caretOffset can be made readonly and
a setCaretOffset method provided which throws an exception
on failure (as with *selection methods above).
*/
@@ -0,0 +1,33 @@
/* -*- 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 "nsIAccessibleEvent.idl"
/**
* Fired when an accessible's text changes.
*/
[scriptable, builtinclass, uuid(21e0f8bd-5638-4964-870b-3c8e944ac4c4)]
interface nsIAccessibleTextChangeEvent : nsIAccessibleEvent
{
/**
* Returns offset of changed text in accessible.
*/
readonly attribute long start;
/**
* Returns length of changed text.
*/
readonly attribute unsigned long length;
/**
* Returns true if text was inserted, otherwise false.
*/
readonly attribute boolean isInserted;
/**
* The inserted or removed text
*/
readonly attribute DOMString modifiedText;
};
+81
View File
@@ -0,0 +1,81 @@
/* -*- 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 "nsISupports.idl"
/**
* These constants control the scrolling of an object or substring into a
* window. Note, keep them synchronized with IA2ScrollType.
*/
[scriptable, uuid(05cd38b1-94b3-4cdf-8371-3935a9611405)]
interface nsIAccessibleScrollType : nsISupports
{
/**
* Scroll the top left of the object or substring to the top left of the
* window (or as close as possible).
*/
const unsigned long SCROLL_TYPE_TOP_LEFT =0x00;
/**
* Scroll the bottom right of the object or substring to the bottom right of
* the window (or as close as possible).
*/
const unsigned long SCROLL_TYPE_BOTTOM_RIGHT = 0x01;
/**
* Scroll the top edge of the object or substring to the top edge of the
* window (or as close as possible).
*/
const unsigned long SCROLL_TYPE_TOP_EDGE = 0x02;
/**
* Scroll the bottom edge of the object or substring to the bottom edge of
* the window (or as close as possible).
*/
const unsigned long SCROLL_TYPE_BOTTOM_EDGE = 0x03;
/**
* Scroll the left edge of the object or substring to the left edge of the
* window (or as close as possible).
*/
const unsigned long SCROLL_TYPE_LEFT_EDGE =0x04;
/**
* Scroll the right edge of the object or substring to the right edge of the
* window (or as close as possible).
*/
const unsigned long SCROLL_TYPE_RIGHT_EDGE = 0x05;
/**
* Scroll an object the minimum amount necessary in order for the entire
* frame to be visible (if possible).
*/
const unsigned long SCROLL_TYPE_ANYWHERE = 0x06;
};
/**
* These constants define which coordinate system a point is located in.
*/
[scriptable, uuid(c9fbdf10-619e-436f-bf4b-8566686f1577)]
interface nsIAccessibleCoordinateType : nsISupports
{
/**
* The coordinates are relative to the screen.
*/
const unsigned long COORDTYPE_SCREEN_RELATIVE = 0x00;
/**
* The coordinates are relative to the window.
*/
const unsigned long COORDTYPE_WINDOW_RELATIVE = 0x01;
/**
* The coordinates are relative to the upper left corner of the bounding box
* of the immediate parent.
*/
const unsigned long COORDTYPE_PARENT_RELATIVE = 0x02;
};
+35
View File
@@ -0,0 +1,35 @@
/* -*- 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 "nsISupports.idl"
[scriptable, uuid(42a1e1dc-58cf-419d-bff0-ed3314c70016)]
interface nsIAccessibleValue : nsISupports
{
readonly attribute double maximumValue;
readonly attribute double minimumValue;
attribute double currentValue;
readonly attribute double minimumIncrement;
};
/*
Assumptions:
The attribute currentValue will throw an exception
if it cannot be set i.e. if the value is not a
member of the interval.
This may not be the 'desired' behaviour given gObject
equivalent. Thus it could be changed to be:
readonly attribute double currentValue;
boolean setCurrentValue (double long value);
GValue can represent many basic types.
Since this interface is designed to represent
an interval and a member of double should
cover the cases of char int and float.
*/
@@ -0,0 +1,34 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "nsIAccessibleEvent.idl"
/*
* An interface for virtual cursor changed events.
* Passes previous cursor position and text offsets.
*/
[scriptable, builtinclass, uuid(370e8b9b-2bbc-4bff-a9c7-16ddc54aea21)]
interface nsIAccessibleVirtualCursorChangeEvent : nsIAccessibleEvent
{
/**
* Previous object pointed at by virtual cursor. null if none.
*/
readonly attribute nsIAccessible oldAccessible;
/**
* Previous start offset of pivot. -1 if none.
*/
readonly attribute long oldStartOffset;
/**
* Previous end offset of pivot. -1 if none.
*/
readonly attribute long oldEndOffset;
/**
* Reason for virtual cursor move.
*/
readonly attribute short reason;
};
+20
View File
@@ -0,0 +1,20 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "nsISupports.idl"
/**
* XBL controls can implement this interface to provide own implementation of
* accessible properties.
*/
[scriptable, uuid(3716eb86-166b-445b-a94a-9b522fee96e6)]
interface nsIXBLAccessible : nsISupports
{
/**
* Return accessible name.
*/
readonly attribute DOMString accessibleName;
};
+21
View File
@@ -0,0 +1,21 @@
# 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/.
DEPTH = @DEPTH@
topsrcdir = @top_srcdir@
srcdir = @srcdir@
VPATH = @srcdir@
include $(DEPTH)/config/autoconf.mk
A11Y_LOG = 0
ifdef MOZ_DEBUG
A11Y_LOG = 1
endif
ifeq (,$(filter aurora beta release esr,$(MOZ_UPDATE_CHANNEL)))
A11Y_LOG = 1
endif
export A11Y_LOG
include $(topsrcdir)/config/rules.mk
@@ -0,0 +1,21 @@
/* -*- 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_ARIAGRIDACCESSIBLEWRAP_H
#define MOZILLA_A11Y_ARIAGRIDACCESSIBLEWRAP_H
#include "ARIAGridAccessible.h"
namespace mozilla {
namespace a11y {
typedef class ARIAGridAccessible ARIAGridAccessibleWrap;
typedef class ARIAGridCellAccessible ARIAGridCellAccessibleWrap;
} // namespace a11y
} // namespace mozilla
#endif
File diff suppressed because it is too large Load Diff
+107
View File
@@ -0,0 +1,107 @@
/* -*- 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 __NS_ACCESSIBLE_WRAP_H__
#define __NS_ACCESSIBLE_WRAP_H__
#include "nsCOMPtr.h"
#include "Accessible.h"
struct _AtkObject;
typedef struct _AtkObject AtkObject;
enum AtkProperty {
PROP_0, // gobject convention
PROP_NAME,
PROP_DESCRIPTION,
PROP_PARENT, // ancestry has changed
PROP_ROLE,
PROP_LAYER,
PROP_MDI_ZORDER,
PROP_TABLE_CAPTION,
PROP_TABLE_COLUMN_DESCRIPTION,
PROP_TABLE_COLUMN_HEADER,
PROP_TABLE_ROW_DESCRIPTION,
PROP_TABLE_ROW_HEADER,
PROP_TABLE_SUMMARY,
PROP_LAST // gobject convention
};
struct AtkPropertyChange {
int32_t type; // property type as listed above
void *oldvalue;
void *newvalue;
};
namespace mozilla {
namespace a11y {
class MaiHyperlink;
/**
* AccessibleWrap, and its descendents in atk directory provide the
* implementation of AtkObject.
*/
class AccessibleWrap : public Accessible
{
public:
AccessibleWrap(nsIContent* aContent, DocAccessible* aDoc);
virtual ~AccessibleWrap();
void ShutdownAtkObject();
// nsAccessNode
virtual void Shutdown();
// return the atk object for this AccessibleWrap
NS_IMETHOD GetNativeInterface(void **aOutAccessible);
virtual nsresult HandleAccEvent(AccEvent* aEvent);
AtkObject * GetAtkObject(void);
static AtkObject * GetAtkObject(nsIAccessible * acc);
bool IsValidObject();
// get/set the MaiHyperlink object for this AccessibleWrap
MaiHyperlink* GetMaiHyperlink(bool aCreate = true);
void SetMaiHyperlink(MaiHyperlink* aMaiHyperlink);
static const char * ReturnString(nsAString &aString) {
static nsCString returnedString;
returnedString = NS_ConvertUTF16toUTF8(aString);
return returnedString.get();
}
protected:
nsresult FireAtkStateChangeEvent(AccEvent* aEvent, AtkObject *aObject);
nsresult FireAtkTextChangedEvent(AccEvent* aEvent, AtkObject *aObject);
nsresult FireAtkShowHideEvent(AccEvent* aEvent, AtkObject *aObject,
bool aIsAdded);
AtkObject *mAtkObject;
private:
/*
* do we have text-remove and text-insert signals if not we need to use
* text-changed see AccessibleWrap::FireAtkTextChangedEvent() and
* bug 619002
*/
enum EAvailableAtkSignals {
eUnknown,
eHaveNewAtkTextSignals,
eNoNewAtkSignals
};
static EAvailableAtkSignals gAvailableAtkSignals;
uint16_t CreateMaiInterfaces(void);
};
} // namespace a11y
} // namespace mozilla
#endif /* __NS_ACCESSIBLE_WRAP_H__ */
@@ -0,0 +1,169 @@
/* -*- 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 "ApplicationAccessibleWrap.h"
#include "nsCOMPtr.h"
#include "nsMai.h"
#include "nsAutoPtr.h"
#include "nsAccessibilityService.h"
#include <gtk/gtk.h>
#include <atk/atk.h>
using namespace mozilla;
using namespace mozilla::a11y;
// ApplicationAccessibleWrap
ApplicationAccessibleWrap::ApplicationAccessibleWrap():
ApplicationAccessible()
{
}
ApplicationAccessibleWrap::~ApplicationAccessibleWrap()
{
AccessibleWrap::ShutdownAtkObject();
}
gboolean
toplevel_event_watcher(GSignalInvocationHint* ihint,
guint n_param_values,
const GValue* param_values,
gpointer data)
{
static GQuark sQuark_goanna_acc_obj = 0;
if (!sQuark_goanna_acc_obj)
sQuark_goanna_acc_obj = g_quark_from_static_string("GoannaAccObj");
if (nsAccessibilityService::IsShutdown())
return TRUE;
GObject* object = reinterpret_cast<GObject*>(g_value_get_object(param_values));
if (!GTK_IS_WINDOW(object))
return TRUE;
AtkObject* child = gtk_widget_get_accessible(GTK_WIDGET(object));
// GTK native dialog
if (!IS_MAI_OBJECT(child) &&
(atk_object_get_role(child) == ATK_ROLE_DIALOG)) {
if (data == reinterpret_cast<gpointer>(nsIAccessibleEvent::EVENT_SHOW)) {
// Attach the dialog accessible to app accessible tree
Accessible* windowAcc = GetAccService()->AddNativeRootAccessible(child);
g_object_set_qdata(G_OBJECT(child), sQuark_goanna_acc_obj,
reinterpret_cast<gpointer>(windowAcc));
} else {
// Deattach the dialog accessible
Accessible* windowAcc =
reinterpret_cast<Accessible*>
(g_object_get_qdata(G_OBJECT(child), sQuark_goanna_acc_obj));
if (windowAcc) {
GetAccService()->RemoveNativeRootAccessible(windowAcc);
g_object_set_qdata(G_OBJECT(child), sQuark_goanna_acc_obj, nullptr);
}
}
}
return TRUE;
}
ENameValueFlag
ApplicationAccessibleWrap::Name(nsString& aName)
{
// ATK doesn't provide a way to obtain an application name (for example,
// Firefox or Thunderbird) like IA2 does. Thus let's return an application
// name as accessible name that was used to get a branding name (for example,
// Minefield aka nightly Firefox or Daily aka nightly Thunderbird).
GetAppName(aName);
return eNameOK;
}
NS_IMETHODIMP
ApplicationAccessibleWrap::GetNativeInterface(void** aOutAccessible)
{
*aOutAccessible = nullptr;
if (!mAtkObject) {
mAtkObject =
reinterpret_cast<AtkObject *>
(g_object_new(MAI_TYPE_ATK_OBJECT, nullptr));
NS_ENSURE_TRUE(mAtkObject, NS_ERROR_OUT_OF_MEMORY);
atk_object_initialize(mAtkObject, this);
mAtkObject->role = ATK_ROLE_INVALID;
mAtkObject->layer = ATK_LAYER_INVALID;
}
*aOutAccessible = mAtkObject;
return NS_OK;
}
struct AtkRootAccessibleAddedEvent {
AtkObject *app_accessible;
AtkObject *root_accessible;
uint32_t index;
};
gboolean fireRootAccessibleAddedCB(gpointer data)
{
AtkRootAccessibleAddedEvent* eventData = (AtkRootAccessibleAddedEvent*)data;
g_signal_emit_by_name(eventData->app_accessible, "children_changed::add",
eventData->index, eventData->root_accessible, nullptr);
g_object_unref(eventData->app_accessible);
g_object_unref(eventData->root_accessible);
free(data);
return FALSE;
}
bool
ApplicationAccessibleWrap::InsertChildAt(uint32_t aIdx, Accessible* aChild)
{
if (!ApplicationAccessible::InsertChildAt(aIdx, aChild))
return false;
AtkObject* atkAccessible = AccessibleWrap::GetAtkObject(aChild);
atk_object_set_parent(atkAccessible, mAtkObject);
uint32_t count = mChildren.Length();
// Emit children_changed::add in a timeout
// to make sure aRootAccWrap is fully initialized.
AtkRootAccessibleAddedEvent* eventData = (AtkRootAccessibleAddedEvent*)
malloc(sizeof(AtkRootAccessibleAddedEvent));
if (eventData) {
eventData->app_accessible = mAtkObject;
eventData->root_accessible = atkAccessible;
eventData->index = count -1;
g_object_ref(mAtkObject);
g_object_ref(atkAccessible);
g_timeout_add(0, fireRootAccessibleAddedCB, eventData);
}
return true;
}
bool
ApplicationAccessibleWrap::RemoveChild(Accessible* aChild)
{
int32_t index = aChild->IndexInParent();
AtkObject* atkAccessible = AccessibleWrap::GetAtkObject(aChild);
atk_object_set_parent(atkAccessible, nullptr);
g_signal_emit_by_name(mAtkObject, "children_changed::remove", index,
atkAccessible, nullptr);
return ApplicationAccessible::RemoveChild(aChild);
}
@@ -0,0 +1,35 @@
/* -*- 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_ApplicationAccessibleWrap_h__
#define mozilla_a11y_ApplicationAccessibleWrap_h__
#include "ApplicationAccessible.h"
namespace mozilla {
namespace a11y {
class ApplicationAccessibleWrap: public ApplicationAccessible
{
public:
ApplicationAccessibleWrap();
virtual ~ApplicationAccessibleWrap();
// Accessible
virtual mozilla::a11y::ENameValueFlag Name(nsString& aName);
virtual bool InsertChildAt(uint32_t aIdx, Accessible* aChild) MOZ_OVERRIDE;
virtual bool RemoveChild(Accessible* aChild);
/**
* Return the atk object for app root accessible.
*/
NS_IMETHOD GetNativeInterface(void** aOutAccessible);
};
} // namespace a11y
} // namespace mozilla
#endif /* __NS_APP_ROOT_ACCESSIBLE_H__ */
+156
View File
@@ -0,0 +1,156 @@
/* -*- 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 <atk/atk.h>
#include "AtkSocketAccessible.h"
#include "InterfaceInitFuncs.h"
#include "nsMai.h"
#include "mozilla/Likely.h"
using namespace mozilla::a11y;
AtkSocketEmbedType AtkSocketAccessible::g_atk_socket_embed = nullptr;
GType AtkSocketAccessible::g_atk_socket_type = G_TYPE_INVALID;
const char* AtkSocketAccessible::sATKSocketEmbedSymbol = "atk_socket_embed";
const char* AtkSocketAccessible::sATKSocketGetTypeSymbol = "atk_socket_get_type";
bool AtkSocketAccessible::gCanEmbed = FALSE;
extern "C" void mai_atk_component_iface_init(AtkComponentIface* aIface);
extern "C" GType mai_atk_socket_get_type(void);
/* MaiAtkSocket */
#define MAI_TYPE_ATK_SOCKET (mai_atk_socket_get_type ())
#define MAI_ATK_SOCKET(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj),\
MAI_TYPE_ATK_SOCKET, MaiAtkSocket))
#define MAI_IS_ATK_SOCKET(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj),\
MAI_TYPE_ATK_SOCKET))
#define MAI_ATK_SOCKET_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass),\
MAI_TYPE_ATK_SOCKET,\
MaiAtkSocketClass))
#define MAI_IS_ATK_SOCKET_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass),\
MAI_TYPE_ATK_SOCKET))
#define MAI_ATK_SOCKET_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj),\
MAI_TYPE_ATK_SOCKET,\
MaiAtkSocketClass))
typedef struct _MaiAtkSocket
{
AtkSocket parent;
AccessibleWrap* accWrap;
} MaiAtkSocket;
typedef struct _MaiAtkSocketClass
{
AtkSocketClass parent_class;
} MaiAtkSocketClass;
G_DEFINE_TYPE_EXTENDED(MaiAtkSocket, mai_atk_socket,
AtkSocketAccessible::g_atk_socket_type, 0,
G_IMPLEMENT_INTERFACE(ATK_TYPE_COMPONENT,
mai_atk_component_iface_init))
void
mai_atk_socket_class_init(MaiAtkSocketClass* aAcc)
{
}
void
mai_atk_socket_init(MaiAtkSocket* aAcc)
{
}
static AtkObject*
mai_atk_socket_new(AccessibleWrap* aAccWrap)
{
NS_ENSURE_TRUE(aAccWrap, nullptr);
MaiAtkSocket* acc = nullptr;
acc = static_cast<MaiAtkSocket*>(g_object_new(MAI_TYPE_ATK_SOCKET, nullptr));
NS_ENSURE_TRUE(acc, nullptr);
acc->accWrap = aAccWrap;
return ATK_OBJECT(acc);
}
extern "C" {
static AtkObject*
RefAccessibleAtPoint(AtkComponent* aComponent, gint aX, gint aY,
AtkCoordType aCoordType)
{
NS_ENSURE_TRUE(MAI_IS_ATK_SOCKET(aComponent), nullptr);
return refAccessibleAtPointHelper(MAI_ATK_SOCKET(aComponent)->accWrap,
aX, aY, aCoordType);
}
static void
GetExtents(AtkComponent* aComponent, gint* aX, gint* aY, gint* aWidth,
gint* aHeight, AtkCoordType aCoordType)
{
*aX = *aY = *aWidth = *aHeight = 0;
if (!MAI_IS_ATK_SOCKET(aComponent))
return;
getExtentsHelper(MAI_ATK_SOCKET(aComponent)->accWrap,
aX, aY, aWidth, aHeight, aCoordType);
}
}
void
mai_atk_component_iface_init(AtkComponentIface* aIface)
{
NS_ASSERTION(aIface, "Invalid Interface");
if (MOZ_UNLIKELY(!aIface))
return;
aIface->ref_accessible_at_point = RefAccessibleAtPoint;
aIface->get_extents = GetExtents;
}
AtkSocketAccessible::AtkSocketAccessible(nsIContent* aContent,
DocAccessible* aDoc,
const nsCString& aPlugId) :
AccessibleWrap(aContent, aDoc)
{
mAtkObject = mai_atk_socket_new(this);
if (!mAtkObject)
return;
// Embeds the children of an AtkPlug, specified by plugId, as the children of
// this socket.
// Using G_TYPE macros instead of ATK_SOCKET macros to avoid undefined
// symbols.
if (gCanEmbed && G_TYPE_CHECK_INSTANCE_TYPE(mAtkObject, g_atk_socket_type) &&
!aPlugId.IsVoid()) {
AtkSocket* accSocket =
G_TYPE_CHECK_INSTANCE_CAST(mAtkObject, g_atk_socket_type, AtkSocket);
g_atk_socket_embed(accSocket, (gchar*)aPlugId.get());
}
}
NS_IMETHODIMP
AtkSocketAccessible::GetNativeInterface(void** aOutAccessible)
{
*aOutAccessible = mAtkObject;
return NS_OK;
}
void
AtkSocketAccessible::Shutdown()
{
if (mAtkObject) {
if (MAI_IS_ATK_SOCKET(mAtkObject))
MAI_ATK_SOCKET(mAtkObject)->accWrap = nullptr;
g_object_unref(mAtkObject);
mAtkObject = nullptr;
}
AccessibleWrap::Shutdown();
}
+58
View File
@@ -0,0 +1,58 @@
/* -*- 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 _AtkSocketAccessible_H_
#define _AtkSocketAccessible_H_
#include "AccessibleWrap.h"
// This file gets included by nsAccessibilityService.cpp, which can't include
// atk.h (or glib.h), so we can't rely on it being included.
#ifdef __ATK_H__
extern "C" typedef void (*AtkSocketEmbedType) (AtkSocket*, gchar*);
#else
extern "C" typedef void (*AtkSocketEmbedType) (void*, void*);
#endif
namespace mozilla {
namespace a11y {
/**
* Provides a AccessibleWrap wrapper around AtkSocket for out-of-process
* accessibles.
*/
class AtkSocketAccessible : public AccessibleWrap
{
public:
// Soft references to AtkSocket
static AtkSocketEmbedType g_atk_socket_embed;
#ifdef __ATK_H__
static GType g_atk_socket_type;
#endif
static const char* sATKSocketEmbedSymbol;
static const char* sATKSocketGetTypeSymbol;
/*
* True if the current Atk version supports AtkSocket and it was correctly
* loaded.
*/
static bool gCanEmbed;
AtkSocketAccessible(nsIContent* aContent, DocAccessible* aDoc,
const nsCString& aPlugId);
// nsAccessNode
virtual void Shutdown();
// nsIAccessible
NS_IMETHODIMP GetNativeInterface(void** aOutAccessible);
};
} // namespace a11y
} // namespace mozilla
#endif
+26
View File
@@ -0,0 +1,26 @@
/* -*- 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 "nsMai.h"
#include "DocAccessibleWrap.h"
using namespace mozilla::a11y;
////////////////////////////////////////////////////////////////////////////////
// DocAccessibleWrap
////////////////////////////////////////////////////////////////////////////////
DocAccessibleWrap::
DocAccessibleWrap(nsIDocument* aDocument, nsIContent* aRootContent,
nsIPresShell* aPresShell) :
DocAccessible(aDocument, aRootContent, aPresShell), mActivated(false)
{
}
DocAccessibleWrap::~DocAccessibleWrap()
{
}
+32
View File
@@ -0,0 +1,32 @@
/* -*- 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/. */
/* For documentation of the accessibility architecture,
* see http://lxr.mozilla.org/seamonkey/source/accessible/accessible-docs.html
*/
#ifndef mozilla_a11y_DocAccessibleWrap_h__
#define mozilla_a11y_DocAccessibleWrap_h__
#include "DocAccessible.h"
namespace mozilla {
namespace a11y {
class DocAccessibleWrap : public DocAccessible
{
public:
DocAccessibleWrap(nsIDocument* aDocument, nsIContent* aRootContent,
nsIPresShell* aPresShell);
virtual ~DocAccessibleWrap();
bool mActivated;
};
} // namespace a11y
} // namespace mozilla
#endif
@@ -0,0 +1,23 @@
/* -*- 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_HTMLTableAccessibleWrap_h__
#define mozilla_a11y_HTMLTableAccessibleWrap_h__
#include "HTMLTableAccessible.h"
namespace mozilla {
namespace a11y {
typedef class HTMLTableAccessible HTMLTableAccessibleWrap;
typedef class HTMLTableCellAccessible HTMLTableCellAccessibleWrap;
typedef class HTMLTableHeaderCellAccessible HTMLTableHeaderCellAccessibleWrap;
} // namespace a11y
} // namespace mozilla
#endif
@@ -0,0 +1,21 @@
/* -*- 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_HyperTextAccessibleWrap_h__
#define mozilla_a11y_HyperTextAccessibleWrap_h__
#include "HyperTextAccessible.h"
namespace mozilla {
namespace a11y {
typedef class HyperTextAccessible HyperTextAccessibleWrap;
} // namespace a11y
} // namespace mozilla
#endif
+21
View File
@@ -0,0 +1,21 @@
/* -*- 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_ImageAccessibleWrap_h__
#define mozilla_a11y_ImageAccessibleWrap_h__
#include "ImageAccessible.h"
namespace mozilla {
namespace a11y {
typedef class ImageAccessible ImageAccessibleWrap;
} // namespace a11y
} // namespace mozilla
#endif
+45
View File
@@ -0,0 +1,45 @@
/* -*- 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 ATK_INTERFACE_INIT_FUNCS_H_
#define ATK_INTERFACE_INIT_FUNCS_H_
#include <atk/atk.h>
namespace mozilla {
namespace a11y {
class AccessibleWrap;
} // namespace a11y
} // namespace mozilla
struct MaiUtilClass;
extern "C" {
void actionInterfaceInitCB(AtkActionIface* aIface);
void componentInterfaceInitCB(AtkComponentIface* aIface);
void documentInterfaceInitCB(AtkDocumentIface *aIface);
void editableTextInterfaceInitCB(AtkEditableTextIface* aIface);
void hyperlinkImplInterfaceInitCB(AtkHyperlinkImplIface *aIface);
void hypertextInterfaceInitCB(AtkHypertextIface* aIface);
void imageInterfaceInitCB(AtkImageIface* aIface);
void selectionInterfaceInitCB(AtkSelectionIface* aIface);
void tableInterfaceInitCB(AtkTableIface *aIface);
void textInterfaceInitCB(AtkTextIface* aIface);
void valueInterfaceInitCB(AtkValueIface *aIface);
}
/**
* XXX these should live in a file of utils for atk.
*/
AtkObject* refAccessibleAtPointHelper(mozilla::a11y::AccessibleWrap* aAccWrap,
gint aX, gint aY, AtkCoordType aCoordType);
void getExtentsHelper(mozilla::a11y::AccessibleWrap* aAccWrap,
gint* aX, gint* aY, gint* aWidth, gint* aHeight,
AtkCoordType aCoordType);
#endif // ATK_INTERFACE_INIT_FUNCS_H_
+41
View File
@@ -0,0 +1,41 @@
# 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/.
DEPTH = @DEPTH@
topsrcdir = @top_srcdir@
srcdir = @srcdir@
VPATH = @srcdir@
include $(DEPTH)/config/autoconf.mk
EXPORT_LIBRARY = ..
LIBXUL_LIBRARY = 1
# we want to force the creation of a static lib.
FORCE_STATIC_LIB = 1
include $(topsrcdir)/config/rules.mk
ifdef MOZ_ENABLE_GTK
CFLAGS += $(TK_CFLAGS)
CXXFLAGS += $(TK_CFLAGS)
endif
ifdef MOZ_ENABLE_DBUS
CXXFLAGS += $(MOZ_DBUS_CFLAGS)
endif
LOCAL_INCLUDES += \
-I$(srcdir) \
-I$(srcdir)/../base \
-I$(srcdir)/../generic \
-I$(srcdir)/../html \
-I$(srcdir)/../xpcom \
-I$(srcdir)/../xul \
-I$(topsrcdir)/other-licenses/atk-1.0 \
$(NULL)
ifneq ($(A11Y_LOG),0)
DEFINES += -DA11Y_LOG
endif
+339
View File
@@ -0,0 +1,339 @@
/* -*- 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 "Platform.h"
#include "nsIAccessibleEvent.h"
#include "nsIGConfService.h"
#include "nsIServiceManager.h"
#include "nsMai.h"
#include "AtkSocketAccessible.h"
#include "prenv.h"
#include "prlink.h"
#ifdef MOZ_ENABLE_DBUS
#include <dbus/dbus.h>
#endif
#include <gtk/gtk.h>
using namespace mozilla;
using namespace mozilla::a11y;
extern "C" {
typedef GType (* AtkGetTypeType) (void);
typedef void (*GnomeAccessibilityInit) (void);
typedef void (*GnomeAccessibilityShutdown) (void);
}
static PRLibrary* sATKLib = nullptr;
static const char sATKLibName[] = "libatk-1.0.so.0";
static const char sATKHyperlinkImplGetTypeSymbol[] =
"atk_hyperlink_impl_get_type";
gboolean toplevel_event_watcher(GSignalInvocationHint*, guint, const GValue*,
gpointer);
static bool sToplevel_event_hook_added = false;
static gulong sToplevel_show_hook = 0;
static gulong sToplevel_hide_hook = 0;
GType g_atk_hyperlink_impl_type = G_TYPE_INVALID;
struct GnomeAccessibilityModule
{
const char *libName;
PRLibrary *lib;
const char *initName;
GnomeAccessibilityInit init;
const char *shutdownName;
GnomeAccessibilityShutdown shutdown;
};
static GnomeAccessibilityModule sAtkBridge = {
#ifdef AIX
"libatk-bridge.a(libatk-bridge.so.0)", nullptr,
#else
"libatk-bridge.so", nullptr,
#endif
"gnome_accessibility_module_init", nullptr,
"gnome_accessibility_module_shutdown", nullptr
};
static GnomeAccessibilityModule sGail = {
"libgail.so", nullptr,
"gnome_accessibility_module_init", nullptr,
"gnome_accessibility_module_shutdown", nullptr
};
static nsresult
LoadGtkModule(GnomeAccessibilityModule& aModule)
{
NS_ENSURE_ARG(aModule.libName);
if (!(aModule.lib = PR_LoadLibrary(aModule.libName))) {
//try to load the module with "gtk-2.0/modules" appended
char *curLibPath = PR_GetLibraryPath();
nsAutoCString libPath(curLibPath);
#if defined(LINUX) && defined(__x86_64__)
libPath.Append(":/usr/lib64:/usr/lib");
#else
libPath.Append(":/usr/lib");
#endif
PR_FreeLibraryName(curLibPath);
int16_t loc1 = 0, loc2 = 0;
int16_t subLen = 0;
while (loc2 >= 0) {
loc2 = libPath.FindChar(':', loc1);
if (loc2 < 0)
subLen = libPath.Length() - loc1;
else
subLen = loc2 - loc1;
nsAutoCString sub(Substring(libPath, loc1, subLen));
sub.Append("/gtk-2.0/modules/");
sub.Append(aModule.libName);
aModule.lib = PR_LoadLibrary(sub.get());
if (aModule.lib)
break;
loc1 = loc2+1;
}
if (!aModule.lib)
return NS_ERROR_FAILURE;
}
//we have loaded the library, try to get the function ptrs
if (!(aModule.init = PR_FindFunctionSymbol(aModule.lib,
aModule.initName)) ||
!(aModule.shutdown = PR_FindFunctionSymbol(aModule.lib,
aModule.shutdownName))) {
//fail, :(
PR_UnloadLibrary(aModule.lib);
aModule.lib = nullptr;
return NS_ERROR_FAILURE;
}
return NS_OK;
}
void
a11y::PlatformInit()
{
if (!ShouldA11yBeEnabled())
return;
sATKLib = PR_LoadLibrary(sATKLibName);
if (!sATKLib)
return;
AtkGetTypeType pfn_atk_hyperlink_impl_get_type =
(AtkGetTypeType) PR_FindFunctionSymbol(sATKLib, sATKHyperlinkImplGetTypeSymbol);
if (pfn_atk_hyperlink_impl_get_type)
g_atk_hyperlink_impl_type = pfn_atk_hyperlink_impl_get_type();
AtkGetTypeType pfn_atk_socket_get_type = (AtkGetTypeType)
PR_FindFunctionSymbol(sATKLib, AtkSocketAccessible::sATKSocketGetTypeSymbol);
if (pfn_atk_socket_get_type) {
AtkSocketAccessible::g_atk_socket_type = pfn_atk_socket_get_type();
AtkSocketAccessible::g_atk_socket_embed = (AtkSocketEmbedType)
PR_FindFunctionSymbol(sATKLib, AtkSocketAccessible ::sATKSocketEmbedSymbol);
AtkSocketAccessible::gCanEmbed =
AtkSocketAccessible::g_atk_socket_type != G_TYPE_INVALID &&
AtkSocketAccessible::g_atk_socket_embed;
}
// Load and initialize gail library.
nsresult rv = LoadGtkModule(sGail);
if (NS_SUCCEEDED(rv))
(*sGail.init)();
// Initialize the MAI Utility class, it will overwrite gail_util.
g_type_class_unref(g_type_class_ref(mai_util_get_type()));
// Init atk-bridge now
PR_SetEnv("NO_AT_BRIDGE=0");
rv = LoadGtkModule(sAtkBridge);
if (NS_SUCCEEDED(rv)) {
(*sAtkBridge.init)();
}
if (!sToplevel_event_hook_added) {
sToplevel_event_hook_added = true;
sToplevel_show_hook =
g_signal_add_emission_hook(g_signal_lookup("show", GTK_TYPE_WINDOW),
0, toplevel_event_watcher,
reinterpret_cast<gpointer>(nsIAccessibleEvent::EVENT_SHOW),
nullptr);
sToplevel_hide_hook =
g_signal_add_emission_hook(g_signal_lookup("hide", GTK_TYPE_WINDOW), 0,
toplevel_event_watcher,
reinterpret_cast<gpointer>(nsIAccessibleEvent::EVENT_HIDE),
nullptr);
}
}
void
a11y::PlatformShutdown()
{
if (sToplevel_event_hook_added) {
sToplevel_event_hook_added = false;
g_signal_remove_emission_hook(g_signal_lookup("show", GTK_TYPE_WINDOW),
sToplevel_show_hook);
g_signal_remove_emission_hook(g_signal_lookup("hide", GTK_TYPE_WINDOW),
sToplevel_hide_hook);
}
if (sAtkBridge.lib) {
// Do not shutdown/unload atk-bridge,
// an exit function registered will take care of it
// if (sAtkBridge.shutdown)
// (*sAtkBridge.shutdown)();
// PR_UnloadLibrary(sAtkBridge.lib);
sAtkBridge.lib = nullptr;
sAtkBridge.init = nullptr;
sAtkBridge.shutdown = nullptr;
}
if (sGail.lib) {
// Do not shutdown gail because
// 1) Maybe it's not init-ed by us. e.g. GtkEmbed
// 2) We need it to avoid assert in spi_atk_tidy_windows
// if (sGail.shutdown)
// (*sGail.shutdown)();
// PR_UnloadLibrary(sGail.lib);
sGail.lib = nullptr;
sGail.init = nullptr;
sGail.shutdown = nullptr;
}
// if (sATKLib) {
// PR_UnloadLibrary(sATKLib);
// sATKLib = nullptr;
// }
}
static const char sAccEnv [] = "GNOME_ACCESSIBILITY";
#ifdef MOZ_ENABLE_DBUS
static DBusPendingCall *sPendingCall = nullptr;
#endif
void
a11y::PreInit()
{
#ifdef MOZ_ENABLE_DBUS
static bool sChecked = FALSE;
if (sChecked)
return;
sChecked = TRUE;
// dbus is only checked if GNOME_ACCESSIBILITY is unset
// also make sure that a session bus address is available to prevent dbus from
// starting a new one. Dbus confuses the test harness when it creates a new
// process (see bug 693343)
if (PR_GetEnv(sAccEnv) || !PR_GetEnv("DBUS_SESSION_BUS_ADDRESS"))
return;
DBusConnection* bus = dbus_bus_get(DBUS_BUS_SESSION, nullptr);
if (!bus)
return;
dbus_connection_set_exit_on_disconnect(bus, FALSE);
static const char* iface = "org.a11y.Status";
static const char* member = "IsEnabled";
DBusMessage *message;
message = dbus_message_new_method_call("org.a11y.Bus", "/org/a11y/bus",
"org.freedesktop.DBus.Properties",
"Get");
if (!message)
goto dbus_done;
dbus_message_append_args(message, DBUS_TYPE_STRING, &iface,
DBUS_TYPE_STRING, &member, DBUS_TYPE_INVALID);
dbus_connection_send_with_reply(bus, message, &sPendingCall, 1000);
dbus_message_unref(message);
dbus_done:
dbus_connection_unref(bus);
#endif
}
bool
a11y::ShouldA11yBeEnabled()
{
static bool sChecked = false, sShouldEnable = false;
if (sChecked)
return sShouldEnable;
sChecked = true;
EPlatformDisabledState disabledState = PlatformDisabledState();
if (disabledState == ePlatformIsDisabled)
return sShouldEnable = false;
// check if accessibility enabled/disabled by environment variable
const char* envValue = PR_GetEnv(sAccEnv);
if (envValue)
return sShouldEnable = !!atoi(envValue);
#ifdef MOZ_ENABLE_DBUS
PreInit();
bool dbusSuccess = false;
DBusMessage *reply = nullptr;
if (!sPendingCall)
goto dbus_done;
dbus_pending_call_block(sPendingCall);
reply = dbus_pending_call_steal_reply(sPendingCall);
dbus_pending_call_unref(sPendingCall);
sPendingCall = nullptr;
if (!reply ||
dbus_message_get_type(reply) != DBUS_MESSAGE_TYPE_METHOD_RETURN ||
strcmp(dbus_message_get_signature (reply), DBUS_TYPE_VARIANT_AS_STRING))
goto dbus_done;
DBusMessageIter iter, iter_variant, iter_struct;
dbus_bool_t dResult;
dbus_message_iter_init(reply, &iter);
dbus_message_iter_recurse (&iter, &iter_variant);
switch (dbus_message_iter_get_arg_type(&iter_variant)) {
case DBUS_TYPE_STRUCT:
// at-spi2-core 2.2.0-2.2.1 had a bug where it returned a struct
dbus_message_iter_recurse(&iter_variant, &iter_struct);
if (dbus_message_iter_get_arg_type(&iter_struct) == DBUS_TYPE_BOOLEAN) {
dbus_message_iter_get_basic(&iter_struct, &dResult);
sShouldEnable = dResult;
dbusSuccess = true;
}
break;
case DBUS_TYPE_BOOLEAN:
dbus_message_iter_get_basic(&iter_variant, &dResult);
sShouldEnable = dResult;
dbusSuccess = true;
break;
default:
break;
}
dbus_done:
if (reply)
dbus_message_unref(reply);
if (dbusSuccess)
return sShouldEnable;
#endif
//check gconf-2 setting
static const char sGconfAccessibilityKey[] =
"/desktop/gnome/interface/accessibility";
nsresult rv = NS_OK;
nsCOMPtr<nsIGConfService> gconf =
do_GetService(NS_GCONFSERVICE_CONTRACTID, &rv);
if (NS_SUCCEEDED(rv) && gconf)
gconf->GetBool(NS_LITERAL_CSTRING(sGconfAccessibilityKey), &sShouldEnable);
return sShouldEnable;
}
+24
View File
@@ -0,0 +1,24 @@
/* -*- 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 "RootAccessibleWrap.h"
#include "nsMai.h"
using namespace mozilla::a11y;
GtkWindowAccessible::GtkWindowAccessible(AtkObject* aAccessible) :
DummyAccessible()
{
g_object_ref(aAccessible);
mAtkObject = aAccessible;
}
GtkWindowAccessible::~GtkWindowAccessible()
{
g_object_unref(mAtkObject);
mAtkObject = nullptr;
}
+34
View File
@@ -0,0 +1,34 @@
/* -*- 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_RootAccessibleWrap_h__
#define mozilla_a11y_RootAccessibleWrap_h__
#include "BaseAccessibles.h"
#include "RootAccessible.h"
namespace mozilla {
namespace a11y {
typedef RootAccessible RootAccessibleWrap;
/* GtkWindowAccessible is the accessible class for gtk+ native window.
* The instance of GtkWindowAccessible is a child of MaiAppRoot instance.
* It is added into root when the toplevel window is created, and removed
* from root when the toplevel window is destroyed.
*/
class GtkWindowAccessible MOZ_FINAL : public DummyAccessible
{
public:
GtkWindowAccessible(AtkObject* aAccessible);
virtual ~GtkWindowAccessible();
};
} // namespace a11y
} // namespace mozilla
#endif /* mozilla_a11y_Root_Accessible_Wrap_h__ */
@@ -0,0 +1,20 @@
/* -*- 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_TextLeafAccessibleWrap_h__
#define mozilla_a11y_TextLeafAccessibleWrap_h__
#include "TextLeafAccessible.h"
namespace mozilla {
namespace a11y {
typedef class TextLeafAccessible TextLeafAccessibleWrap;
} // namespace a11y
} // namespace mozilla
#endif
+404
View File
@@ -0,0 +1,404 @@
/* -*- 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 "ApplicationAccessibleWrap.h"
#include "mozilla/Likely.h"
#include "nsAccessibilityService.h"
#include "nsMai.h"
#include <atk/atk.h>
#include <gtk/gtk.h>
#include <string.h>
using namespace mozilla;
using namespace mozilla::a11y;
typedef AtkUtil MaiUtil;
typedef AtkUtilClass MaiUtilClass;
#define MAI_VERSION MOZILLA_VERSION
#define MAI_NAME "Goanna"
extern "C" {
static guint (*gail_add_global_event_listener)(GSignalEmissionHook listener,
const gchar* event_type);
static void (*gail_remove_global_event_listener) (guint remove_listener);
static void (*gail_remove_key_event_listener) (guint remove_listener);
static AtkObject* (*gail_get_root)();
}
struct MaiUtilListenerInfo
{
gint key;
guint signal_id;
gulong hook_id;
// For window create/destory/minimize/maximize/restore/activate/deactivate
// events, we'll chain gail_util's add/remove_global_event_listener.
// So we store the listenerid returned by gail's add_global_event_listener
// in this structure to call gail's remove_global_event_listener later.
guint gail_listenerid;
};
static GHashTable* sListener_list = nullptr;
static gint sListener_idx = 1;
extern "C" {
static guint
add_listener (GSignalEmissionHook listener,
const gchar *object_type,
const gchar *signal,
const gchar *hook_data,
guint gail_listenerid = 0)
{
GType type;
guint signal_id;
gint rc = 0;
type = g_type_from_name(object_type);
if (type) {
signal_id = g_signal_lookup(signal, type);
if (signal_id > 0) {
MaiUtilListenerInfo *listener_info;
rc = sListener_idx;
listener_info = (MaiUtilListenerInfo *)
g_malloc(sizeof(MaiUtilListenerInfo));
listener_info->key = sListener_idx;
listener_info->hook_id =
g_signal_add_emission_hook(signal_id, 0, listener,
g_strdup(hook_data),
(GDestroyNotify)g_free);
listener_info->signal_id = signal_id;
listener_info->gail_listenerid = gail_listenerid;
g_hash_table_insert(sListener_list, &(listener_info->key),
listener_info);
sListener_idx++;
}
else {
g_warning("Invalid signal type %s\n", signal);
}
}
else {
g_warning("Invalid object type %s\n", object_type);
}
return rc;
}
static guint
mai_util_add_global_event_listener(GSignalEmissionHook listener,
const gchar *event_type)
{
guint rc = 0;
gchar **split_string;
split_string = g_strsplit (event_type, ":", 3);
if (split_string) {
if (!strcmp ("window", split_string[0])) {
guint gail_listenerid = 0;
if (gail_add_global_event_listener) {
// call gail's function to track gtk native window events
gail_listenerid =
gail_add_global_event_listener(listener, event_type);
}
rc = add_listener (listener, "MaiAtkObject", split_string[1],
event_type, gail_listenerid);
}
else {
rc = add_listener (listener, split_string[1], split_string[2],
event_type);
}
g_strfreev(split_string);
}
return rc;
}
static void
mai_util_remove_global_event_listener(guint remove_listener)
{
if (remove_listener > 0) {
MaiUtilListenerInfo *listener_info;
gint tmp_idx = remove_listener;
listener_info = (MaiUtilListenerInfo *)
g_hash_table_lookup(sListener_list, &tmp_idx);
if (listener_info != nullptr) {
if (gail_remove_global_event_listener &&
listener_info->gail_listenerid) {
gail_remove_global_event_listener(listener_info->gail_listenerid);
}
/* Hook id of 0 and signal id of 0 are invalid */
if (listener_info->hook_id != 0 && listener_info->signal_id != 0) {
/* Remove the emission hook */
g_signal_remove_emission_hook(listener_info->signal_id,
listener_info->hook_id);
/* Remove the element from the hash */
g_hash_table_remove(sListener_list, &tmp_idx);
}
else {
g_warning("Invalid listener hook_id %ld or signal_id %d\n",
listener_info->hook_id, listener_info->signal_id);
}
}
else {
// atk-bridge is initialized with gail (e.g. yelp)
// try gail_remove_global_event_listener
if (gail_remove_global_event_listener) {
return gail_remove_global_event_listener(remove_listener);
}
g_warning("No listener with the specified listener id %d",
remove_listener);
}
}
else {
g_warning("Invalid listener_id %d", remove_listener);
}
}
static AtkKeyEventStruct *
atk_key_event_from_gdk_event_key (GdkEventKey *key)
{
AtkKeyEventStruct *event = g_new0(AtkKeyEventStruct, 1);
switch (key->type) {
case GDK_KEY_PRESS:
event->type = ATK_KEY_EVENT_PRESS;
break;
case GDK_KEY_RELEASE:
event->type = ATK_KEY_EVENT_RELEASE;
break;
default:
g_assert_not_reached ();
return nullptr;
}
event->state = key->state;
event->keyval = key->keyval;
event->length = key->length;
if (key->string && key->string [0] &&
(key->state & GDK_CONTROL_MASK ||
g_unichar_isgraph (g_utf8_get_char (key->string)))) {
event->string = key->string;
}
else if (key->type == GDK_KEY_PRESS ||
key->type == GDK_KEY_RELEASE) {
event->string = gdk_keyval_name (key->keyval);
}
event->keycode = key->hardware_keycode;
event->timestamp = key->time;
return event;
}
struct MaiKeyEventInfo
{
AtkKeyEventStruct *key_event;
gpointer func_data;
};
union AtkKeySnoopFuncPointer
{
AtkKeySnoopFunc func_ptr;
gpointer data;
};
static gboolean
notify_hf(gpointer key, gpointer value, gpointer data)
{
MaiKeyEventInfo *info = (MaiKeyEventInfo *)data;
AtkKeySnoopFuncPointer atkKeySnoop;
atkKeySnoop.data = value;
return (atkKeySnoop.func_ptr)(info->key_event, info->func_data) ? TRUE : FALSE;
}
static void
insert_hf(gpointer key, gpointer value, gpointer data)
{
GHashTable *new_table = (GHashTable *) data;
g_hash_table_insert (new_table, key, value);
}
static GHashTable* sKey_listener_list = nullptr;
static gint
mai_key_snooper(GtkWidget *the_widget, GdkEventKey *event, gpointer func_data)
{
/* notify each AtkKeySnoopFunc in turn... */
MaiKeyEventInfo *info = g_new0(MaiKeyEventInfo, 1);
gint consumed = 0;
if (sKey_listener_list) {
GHashTable *new_hash = g_hash_table_new(nullptr, nullptr);
g_hash_table_foreach (sKey_listener_list, insert_hf, new_hash);
info->key_event = atk_key_event_from_gdk_event_key (event);
info->func_data = func_data;
consumed = g_hash_table_foreach_steal (new_hash, notify_hf, info);
g_hash_table_destroy (new_hash);
g_free(info->key_event);
}
g_free(info);
return (consumed ? 1 : 0);
}
static guint sKey_snooper_id = 0;
static guint
mai_util_add_key_event_listener (AtkKeySnoopFunc listener,
gpointer data)
{
if (MOZ_UNLIKELY(!listener))
return 0;
static guint key=0;
if (!sKey_listener_list) {
sKey_listener_list = g_hash_table_new(nullptr, nullptr);
sKey_snooper_id = gtk_key_snooper_install(mai_key_snooper, data);
}
AtkKeySnoopFuncPointer atkKeySnoop;
atkKeySnoop.func_ptr = listener;
g_hash_table_insert(sKey_listener_list, GUINT_TO_POINTER (key++),
atkKeySnoop.data);
return key;
}
static void
mai_util_remove_key_event_listener (guint remove_listener)
{
if (!sKey_listener_list) {
// atk-bridge is initialized with gail (e.g. yelp)
// try gail_remove_key_event_listener
return gail_remove_key_event_listener(remove_listener);
}
g_hash_table_remove(sKey_listener_list, GUINT_TO_POINTER (remove_listener));
if (g_hash_table_size(sKey_listener_list) == 0) {
gtk_key_snooper_remove(sKey_snooper_id);
}
}
static AtkObject*
mai_util_get_root()
{
ApplicationAccessible* app = ApplicationAcc();
if (app)
return app->GetAtkObject();
// We've shutdown, try to use gail instead
// (to avoid assert in spi_atk_tidy_windows())
// XXX tbsaunde then why didn't we replace the gail atk_util impl?
if (gail_get_root)
return gail_get_root();
return nullptr;
}
static const gchar*
mai_util_get_toolkit_name()
{
return MAI_NAME;
}
static const gchar*
mai_util_get_toolkit_version()
{
return MAI_VERSION;
}
static void
_listener_info_destroy(gpointer data)
{
g_free(data);
}
static void
window_added (AtkObject *atk_obj,
guint index,
AtkObject *child)
{
if (!IS_MAI_OBJECT(child))
return;
static guint id = g_signal_lookup ("create", MAI_TYPE_ATK_OBJECT);
g_signal_emit (child, id, 0);
}
static void
window_removed (AtkObject *atk_obj,
guint index,
AtkObject *child)
{
if (!IS_MAI_OBJECT(child))
return;
static guint id = g_signal_lookup ("destroy", MAI_TYPE_ATK_OBJECT);
g_signal_emit (child, id, 0);
}
static void
UtilInterfaceInit(MaiUtilClass* klass)
{
AtkUtilClass *atk_class;
gpointer data;
data = g_type_class_peek(ATK_TYPE_UTIL);
atk_class = ATK_UTIL_CLASS(data);
// save gail function pointer
gail_add_global_event_listener = atk_class->add_global_event_listener;
gail_remove_global_event_listener = atk_class->remove_global_event_listener;
gail_remove_key_event_listener = atk_class->remove_key_event_listener;
gail_get_root = atk_class->get_root;
atk_class->add_global_event_listener =
mai_util_add_global_event_listener;
atk_class->remove_global_event_listener =
mai_util_remove_global_event_listener;
atk_class->add_key_event_listener = mai_util_add_key_event_listener;
atk_class->remove_key_event_listener = mai_util_remove_key_event_listener;
atk_class->get_root = mai_util_get_root;
atk_class->get_toolkit_name = mai_util_get_toolkit_name;
atk_class->get_toolkit_version = mai_util_get_toolkit_version;
sListener_list = g_hash_table_new_full(g_int_hash, g_int_equal, nullptr,
_listener_info_destroy);
// Keep track of added/removed windows.
AtkObject *root = atk_get_root ();
g_signal_connect (root, "children-changed::add", (GCallback) window_added, nullptr);
g_signal_connect (root, "children-changed::remove", (GCallback) window_removed, nullptr);
}
}
GType
mai_util_get_type()
{
static GType type = 0;
if (!type) {
static const GTypeInfo tinfo = {
sizeof(MaiUtilClass),
(GBaseInitFunc) nullptr, /* base init */
(GBaseFinalizeFunc) nullptr, /* base finalize */
(GClassInitFunc) UtilInterfaceInit, /* class init */
(GClassFinalizeFunc) nullptr, /* class finalize */
nullptr, /* class data */
sizeof(MaiUtil), /* instance size */
0, /* nb preallocs */
(GInstanceInitFunc) nullptr, /* instance init */
nullptr /* value table */
};
type = g_type_register_static(ATK_TYPE_UTIL,
"MaiUtil", &tinfo, GTypeFlags(0));
}
return type;
}
@@ -0,0 +1,21 @@
/* -*- 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_XULListboxAccessibleWrap_h__
#define mozilla_a11y_XULListboxAccessibleWrap_h__
#include "XULListboxAccessible.h"
namespace mozilla {
namespace a11y {
typedef class XULListboxAccessible XULListboxAccessibleWrap;
typedef class XULListCellAccessible XULListCellAccessibleWrap;
} // namespace a11y
} // namespace mozilla
#endif
@@ -0,0 +1,20 @@
/* -*- 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_XULMenuAccessibleWrap_h__
#define mozilla_a11y_XULMenuAccessibleWrap_h__
#include "XULMenuAccessible.h"
namespace mozilla {
namespace a11y {
typedef class XULMenuitemAccessible XULMenuitemAccessibleWrap;
} // namespace a11y
} // namespace mozilla
#endif
@@ -0,0 +1,22 @@
/* -*- 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_XULTreeGridAccessibleWrap_h__
#define mozilla_a11y_XULTreeGridAccessibleWrap_h__
#include "XULTreeGridAccessible.h"
namespace mozilla {
namespace a11y {
typedef class XULTreeGridAccessible XULTreeGridAccessibleWrap;
typedef class XULTreeGridCellAccessible XULTreeGridCellAccessibleWrap;
} // namespace a11y
} // namespace mozilla
#endif
+37
View File
@@ -0,0 +1,37 @@
# -*- Mode: python; c-basic-offset: 4; 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/.
MODULE = 'accessibility'
EXPORTS.mozilla.a11y += [
'AccessibleWrap.h',
'HyperTextAccessibleWrap.h',
]
CPP_SOURCES += [
'AccessibleWrap.cpp',
'ApplicationAccessibleWrap.cpp',
'AtkSocketAccessible.cpp',
'DocAccessibleWrap.cpp',
'Platform.cpp',
'RootAccessibleWrap.cpp',
'UtilInterface.cpp',
'nsMaiHyperlink.cpp',
'nsMaiInterfaceAction.cpp',
'nsMaiInterfaceComponent.cpp',
'nsMaiInterfaceDocument.cpp',
'nsMaiInterfaceEditableText.cpp',
'nsMaiInterfaceHyperlinkImpl.cpp',
'nsMaiInterfaceHypertext.cpp',
'nsMaiInterfaceImage.cpp',
'nsMaiInterfaceSelection.cpp',
'nsMaiInterfaceTable.cpp',
'nsMaiInterfaceText.cpp',
'nsMaiInterfaceValue.cpp',
]
LIBRARY_NAME = 'accessibility_toolkit_s'
+33
View File
@@ -0,0 +1,33 @@
/* -*- 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 __NS_MAI_H__
#define __NS_MAI_H__
#include <atk/atk.h>
#include <glib.h>
#include <glib-object.h>
#include "AccessibleWrap.h"
#define MAI_TYPE_ATK_OBJECT (mai_atk_object_get_type ())
#define MAI_ATK_OBJECT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), \
MAI_TYPE_ATK_OBJECT, MaiAtkObject))
#define MAI_ATK_OBJECT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), \
MAI_TYPE_ATK_OBJECT, \
MaiAtkObjectClass))
#define IS_MAI_OBJECT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), \
MAI_TYPE_ATK_OBJECT))
#define IS_MAI_OBJECT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), \
MAI_TYPE_ATK_OBJECT))
#define MAI_ATK_OBJECT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), \
MAI_TYPE_ATK_OBJECT, \
MaiAtkObjectClass))
GType mai_atk_object_get_type(void);
GType mai_util_get_type();
mozilla::a11y::AccessibleWrap* GetAccessibleWrap(AtkObject* aAtkObj);
#endif /* __NS_MAI_H__ */
+259
View File
@@ -0,0 +1,259 @@
/* -*- 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 "nsIURI.h"
#include "nsMaiHyperlink.h"
using namespace mozilla::a11y;
/* MaiAtkHyperlink */
#define MAI_TYPE_ATK_HYPERLINK (mai_atk_hyperlink_get_type ())
#define MAI_ATK_HYPERLINK(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj),\
MAI_TYPE_ATK_HYPERLINK, MaiAtkHyperlink))
#define MAI_ATK_HYPERLINK_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass),\
MAI_TYPE_ATK_HYPERLINK, MaiAtkHyperlinkClass))
#define MAI_IS_ATK_HYPERLINK(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj),\
MAI_TYPE_ATK_HYPERLINK))
#define MAI_IS_ATK_HYPERLINK_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass),\
MAI_TYPE_ATK_HYPERLINK))
#define MAI_ATK_HYPERLINK_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj),\
MAI_TYPE_ATK_HYPERLINK, MaiAtkHyperlinkClass))
/**
* This MaiAtkHyperlink is a thin wrapper, in the MAI namespace,
* for AtkHyperlink
*/
struct MaiAtkHyperlink
{
AtkHyperlink parent;
/*
* The MaiHyperlink whose properties and features are exported via this
* hyperlink instance.
*/
MaiHyperlink *maiHyperlink;
};
struct MaiAtkHyperlinkClass
{
AtkHyperlinkClass parent_class;
};
GType mai_atk_hyperlink_get_type(void);
G_BEGIN_DECLS
/* callbacks for AtkHyperlink */
static void classInitCB(AtkHyperlinkClass *aClass);
static void finalizeCB(GObject *aObj);
/* callbacks for AtkHyperlink virtual functions */
static gchar *getUriCB(AtkHyperlink *aLink, gint aLinkIndex);
static AtkObject *getObjectCB(AtkHyperlink *aLink, gint aLinkIndex);
static gint getEndIndexCB(AtkHyperlink *aLink);
static gint getStartIndexCB(AtkHyperlink *aLink);
static gboolean isValidCB(AtkHyperlink *aLink);
static gint getAnchorCountCB(AtkHyperlink *aLink);
G_END_DECLS
static gpointer parent_class = nullptr;
static Accessible*
get_accessible_hyperlink(AtkHyperlink *aHyperlink);
GType
mai_atk_hyperlink_get_type(void)
{
static GType type = 0;
if (!type) {
static const GTypeInfo tinfo = {
sizeof(MaiAtkHyperlinkClass),
(GBaseInitFunc)nullptr,
(GBaseFinalizeFunc)nullptr,
(GClassInitFunc)classInitCB,
(GClassFinalizeFunc)nullptr,
nullptr, /* class data */
sizeof(MaiAtkHyperlink), /* instance size */
0, /* nb preallocs */
(GInstanceInitFunc)nullptr,
nullptr /* value table */
};
type = g_type_register_static(ATK_TYPE_HYPERLINK,
"MaiAtkHyperlink",
&tinfo, GTypeFlags(0));
}
return type;
}
MaiHyperlink::MaiHyperlink(Accessible* aHyperLink) :
mHyperlink(aHyperLink),
mMaiAtkHyperlink(nullptr)
{
}
MaiHyperlink::~MaiHyperlink()
{
if (mMaiAtkHyperlink) {
MAI_ATK_HYPERLINK(mMaiAtkHyperlink)->maiHyperlink = nullptr;
g_object_unref(mMaiAtkHyperlink);
}
}
AtkHyperlink*
MaiHyperlink::GetAtkHyperlink(void)
{
NS_ENSURE_TRUE(mHyperlink, nullptr);
if (mMaiAtkHyperlink)
return mMaiAtkHyperlink;
if (!mHyperlink->IsLink())
return nullptr;
mMaiAtkHyperlink =
reinterpret_cast<AtkHyperlink *>
(g_object_new(mai_atk_hyperlink_get_type(), nullptr));
NS_ASSERTION(mMaiAtkHyperlink, "OUT OF MEMORY");
NS_ENSURE_TRUE(mMaiAtkHyperlink, nullptr);
/* be sure to initialize it with "this" */
MaiHyperlink::Initialize(mMaiAtkHyperlink, this);
return mMaiAtkHyperlink;
}
/* static */
/* remember to call this static function when a MaiAtkHyperlink
* is created
*/
nsresult
MaiHyperlink::Initialize(AtkHyperlink *aObj, MaiHyperlink *aHyperlink)
{
NS_ENSURE_ARG(MAI_IS_ATK_HYPERLINK(aObj));
NS_ENSURE_ARG(aHyperlink);
/* initialize hyperlink */
MAI_ATK_HYPERLINK(aObj)->maiHyperlink = aHyperlink;
return NS_OK;
}
/* static functions for ATK callbacks */
void
classInitCB(AtkHyperlinkClass *aClass)
{
GObjectClass *gobject_class = G_OBJECT_CLASS(aClass);
parent_class = g_type_class_peek_parent(aClass);
aClass->get_uri = getUriCB;
aClass->get_object = getObjectCB;
aClass->get_end_index = getEndIndexCB;
aClass->get_start_index = getStartIndexCB;
aClass->is_valid = isValidCB;
aClass->get_n_anchors = getAnchorCountCB;
gobject_class->finalize = finalizeCB;
}
void
finalizeCB(GObject *aObj)
{
NS_ASSERTION(MAI_IS_ATK_HYPERLINK(aObj), "Invalid MaiAtkHyperlink");
if (!MAI_IS_ATK_HYPERLINK(aObj))
return;
MaiAtkHyperlink *maiAtkHyperlink = MAI_ATK_HYPERLINK(aObj);
maiAtkHyperlink->maiHyperlink = nullptr;
/* call parent finalize function */
if (G_OBJECT_CLASS (parent_class)->finalize)
G_OBJECT_CLASS (parent_class)->finalize(aObj);
}
gchar *
getUriCB(AtkHyperlink *aLink, gint aLinkIndex)
{
Accessible* hyperlink = get_accessible_hyperlink(aLink);
NS_ENSURE_TRUE(hyperlink, nullptr);
nsCOMPtr<nsIURI> uri = hyperlink->AnchorURIAt(aLinkIndex);
if (!uri)
return nullptr;
nsAutoCString cautoStr;
nsresult rv = uri->GetSpec(cautoStr);
NS_ENSURE_SUCCESS(rv, nullptr);
return g_strdup(cautoStr.get());
}
AtkObject *
getObjectCB(AtkHyperlink *aLink, gint aLinkIndex)
{
Accessible* hyperlink = get_accessible_hyperlink(aLink);
NS_ENSURE_TRUE(hyperlink, nullptr);
Accessible* anchor = hyperlink->AnchorAt(aLinkIndex);
NS_ENSURE_TRUE(anchor, nullptr);
AtkObject* atkObj = AccessibleWrap::GetAtkObject(anchor);
//no need to add ref it, because it is "get" not "ref"
return atkObj;
}
gint
getEndIndexCB(AtkHyperlink *aLink)
{
Accessible* hyperlink = get_accessible_hyperlink(aLink);
NS_ENSURE_TRUE(hyperlink, -1);
return static_cast<gint>(hyperlink->EndOffset());
}
gint
getStartIndexCB(AtkHyperlink *aLink)
{
Accessible* hyperlink = get_accessible_hyperlink(aLink);
NS_ENSURE_TRUE(hyperlink, -1);
return static_cast<gint>(hyperlink->StartOffset());
}
gboolean
isValidCB(AtkHyperlink *aLink)
{
Accessible* hyperlink = get_accessible_hyperlink(aLink);
NS_ENSURE_TRUE(hyperlink, FALSE);
return static_cast<gboolean>(hyperlink->IsLinkValid());
}
gint
getAnchorCountCB(AtkHyperlink *aLink)
{
Accessible* hyperlink = get_accessible_hyperlink(aLink);
NS_ENSURE_TRUE(hyperlink, -1);
return static_cast<gint>(hyperlink->AnchorCount());
}
// Check if aHyperlink is a valid MaiHyperlink, and return the
// HyperLinkAccessible related.
Accessible*
get_accessible_hyperlink(AtkHyperlink *aHyperlink)
{
NS_ENSURE_TRUE(MAI_IS_ATK_HYPERLINK(aHyperlink), nullptr);
MaiHyperlink * maiHyperlink =
MAI_ATK_HYPERLINK(aHyperlink)->maiHyperlink;
NS_ENSURE_TRUE(maiHyperlink != nullptr, nullptr);
NS_ENSURE_TRUE(maiHyperlink->GetAtkHyperlink() == aHyperlink, nullptr);
return maiHyperlink->GetAccHyperlink();
}
+44
View File
@@ -0,0 +1,44 @@
/* -*- 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 __MAI_HYPERLINK_H__
#define __MAI_HYPERLINK_H__
#include "nsMai.h"
#include "Accessible.h"
struct _AtkHyperlink;
typedef struct _AtkHyperlink AtkHyperlink;
namespace mozilla {
namespace a11y {
/*
* MaiHyperlink is a auxiliary class for MaiInterfaceHyperText.
*/
class MaiHyperlink
{
public:
MaiHyperlink(Accessible* aHyperLink);
~MaiHyperlink();
public:
AtkHyperlink *GetAtkHyperlink(void);
Accessible* GetAccHyperlink()
{ return mHyperlink && mHyperlink->IsLink() ? mHyperlink : nullptr; }
protected:
Accessible* mHyperlink;
AtkHyperlink* mMaiAtkHyperlink;
public:
static nsresult Initialize(AtkHyperlink *aObj, MaiHyperlink *aClass);
};
} // namespace a11y
} // namespace mozilla
#endif /* __MAI_HYPERLINK_H__ */
+128
View File
@@ -0,0 +1,128 @@
/* -*- 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 "InterfaceInitFuncs.h"
#include "Accessible-inl.h"
#include "nsMai.h"
#include "Role.h"
#include "mozilla/Likely.h"
#include "nsString.h"
using namespace mozilla::a11y;
extern "C" {
static gboolean
doActionCB(AtkAction *aAction, gint aActionIndex)
{
AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aAction));
if (!accWrap)
return FALSE;
nsresult rv = accWrap->DoAction(aActionIndex);
return (NS_FAILED(rv)) ? FALSE : TRUE;
}
static gint
getActionCountCB(AtkAction *aAction)
{
AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aAction));
return accWrap ? accWrap->ActionCount() : 0;
}
static const gchar*
getActionDescriptionCB(AtkAction *aAction, gint aActionIndex)
{
AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aAction));
if (!accWrap)
return nullptr;
nsAutoString description;
nsresult rv = accWrap->GetActionDescription(aActionIndex, description);
NS_ENSURE_SUCCESS(rv, nullptr);
return AccessibleWrap::ReturnString(description);
}
static const gchar*
getActionNameCB(AtkAction *aAction, gint aActionIndex)
{
AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aAction));
if (!accWrap)
return nullptr;
nsAutoString autoStr;
nsresult rv = accWrap->GetActionName(aActionIndex, autoStr);
NS_ENSURE_SUCCESS(rv, nullptr);
return AccessibleWrap::ReturnString(autoStr);
}
static const gchar*
getKeyBindingCB(AtkAction *aAction, gint aActionIndex)
{
AccessibleWrap* acc = GetAccessibleWrap(ATK_OBJECT(aAction));
if (!acc)
return nullptr;
// Return all key bindings including access key and keyboard shortcut.
nsAutoString keyBindingsStr;
// Get access key.
KeyBinding keyBinding = acc->AccessKey();
if (!keyBinding.IsEmpty()) {
keyBinding.AppendToString(keyBindingsStr, KeyBinding::eAtkFormat);
Accessible* parent = acc->Parent();
roles::Role role = parent ? parent->Role() : roles::NOTHING;
if (role == roles::PARENT_MENUITEM || role == roles::MENUITEM ||
role == roles::RADIO_MENU_ITEM || role == roles::CHECK_MENU_ITEM) {
// It is submenu, expose keyboard shortcuts from menu hierarchy like
// "s;<Alt>f:s"
nsAutoString keysInHierarchyStr = keyBindingsStr;
do {
KeyBinding parentKeyBinding = parent->AccessKey();
if (!parentKeyBinding.IsEmpty()) {
nsAutoString str;
parentKeyBinding.ToString(str, KeyBinding::eAtkFormat);
str.Append(':');
keysInHierarchyStr.Insert(str, 0);
}
} while ((parent = parent->Parent()) && parent->Role() != roles::MENUBAR);
keyBindingsStr.Append(';');
keyBindingsStr.Append(keysInHierarchyStr);
}
} else {
// No access key, add ';' to point this.
keyBindingsStr.Append(';');
}
// Get keyboard shortcut.
keyBindingsStr.Append(';');
keyBinding = acc->KeyboardShortcut();
if (!keyBinding.IsEmpty()) {
keyBinding.AppendToString(keyBindingsStr, KeyBinding::eAtkFormat);
}
return AccessibleWrap::ReturnString(keyBindingsStr);
}
}
void
actionInterfaceInitCB(AtkActionIface* aIface)
{
NS_ASSERTION(aIface, "Invalid aIface");
if (MOZ_UNLIKELY(!aIface))
return;
aIface->do_action = doActionCB;
aIface->get_n_actions = getActionCountCB;
aIface->get_description = getActionDescriptionCB;
aIface->get_keybinding = getKeyBindingCB;
aIface->get_name = getActionNameCB;
}
@@ -0,0 +1,116 @@
/* -*- 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 "InterfaceInitFuncs.h"
#include "AccessibleWrap.h"
#include "nsAccUtils.h"
#include "nsCoreUtils.h"
#include "nsMai.h"
#include "mozilla/Likely.h"
using namespace mozilla::a11y;
extern "C" {
static AtkObject*
refAccessibleAtPointCB(AtkComponent* aComponent, gint aAccX, gint aAccY,
AtkCoordType aCoordType)
{
return refAccessibleAtPointHelper(GetAccessibleWrap(ATK_OBJECT(aComponent)),
aAccX, aAccY, aCoordType);
}
static void
getExtentsCB(AtkComponent* aComponent, gint* aX, gint* aY,
gint* aWidth, gint* aHeight, AtkCoordType aCoordType)
{
getExtentsHelper(GetAccessibleWrap(ATK_OBJECT(aComponent)),
aX, aY, aWidth, aHeight, aCoordType);
}
static gboolean
grabFocusCB(AtkComponent* aComponent)
{
AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aComponent));
if (!accWrap)
return FALSE;
nsresult rv = accWrap->TakeFocus();
return (NS_FAILED(rv)) ? FALSE : TRUE;
}
}
AtkObject*
refAccessibleAtPointHelper(AccessibleWrap* aAccWrap, gint aX, gint aY,
AtkCoordType aCoordType)
{
if (!aAccWrap || aAccWrap->IsDefunct() || nsAccUtils::MustPrune(aAccWrap))
return nullptr;
// Accessible::ChildAtPoint(x,y) is in screen pixels.
if (aCoordType == ATK_XY_WINDOW) {
nsIntPoint winCoords =
nsCoreUtils::GetScreenCoordsForWindow(aAccWrap->GetNode());
aX += winCoords.x;
aY += winCoords.y;
}
Accessible* accAtPoint = aAccWrap->ChildAtPoint(aX, aY,
Accessible::eDirectChild);
if (!accAtPoint)
return nullptr;
AtkObject* atkObj = AccessibleWrap::GetAtkObject(accAtPoint);
if (atkObj)
g_object_ref(atkObj);
return atkObj;
}
void
getExtentsHelper(AccessibleWrap* aAccWrap,
gint* aX, gint* aY, gint* aWidth, gint* aHeight,
AtkCoordType aCoordType)
{
*aX = *aY = *aWidth = *aHeight = 0;
if (!aAccWrap || aAccWrap->IsDefunct())
return;
int32_t x = 0, y = 0, width = 0, height = 0;
// Returned in screen coordinates
nsresult rv = aAccWrap->GetBounds(&x, &y, &width, &height);
if (NS_FAILED(rv))
return;
if (aCoordType == ATK_XY_WINDOW) {
nsIntPoint winCoords =
nsCoreUtils::GetScreenCoordsForWindow(aAccWrap->GetNode());
x -= winCoords.x;
y -= winCoords.y;
}
*aX = x;
*aY = y;
*aWidth = width;
*aHeight = height;
}
void
componentInterfaceInitCB(AtkComponentIface* aIface)
{
NS_ASSERTION(aIface, "Invalid Interface");
if(MOZ_UNLIKELY(!aIface))
return;
/*
* Use default implementation in atk for contains, get_position,
* and get_size
*/
aIface->ref_accessible_at_point = refAccessibleAtPointCB;
aIface->get_extents = getExtentsCB;
aIface->grab_focus = grabFocusCB;
}
@@ -0,0 +1,122 @@
/* -*- 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 "InterfaceInitFuncs.h"
#include "Accessible-inl.h"
#include "AccessibleWrap.h"
#include "DocAccessible.h"
#include "nsMai.h"
#include "mozilla/Likely.h"
using namespace mozilla::a11y;
static const char* const kDocTypeName = "W3C-doctype";
static const char* const kDocUrlName = "DocURL";
static const char* const kMimeTypeName = "MimeType";
// below functions are vfuncs on an ATK interface so they need to be C call
extern "C" {
static const gchar* getDocumentLocaleCB(AtkDocument* aDocument);
static AtkAttributeSet* getDocumentAttributesCB(AtkDocument* aDocument);
static const gchar* getDocumentAttributeValueCB(AtkDocument* aDocument,
const gchar* aAttrName);
void
documentInterfaceInitCB(AtkDocumentIface *aIface)
{
NS_ASSERTION(aIface, "Invalid Interface");
if(MOZ_UNLIKELY(!aIface))
return;
/*
* We don't support get_document or set_attribute right now.
* get_document_type is deprecated, we return DocType in
* get_document_attribute_value and get_document_attributes instead.
*/
aIface->get_document_attributes = getDocumentAttributesCB;
aIface->get_document_attribute_value = getDocumentAttributeValueCB;
aIface->get_document_locale = getDocumentLocaleCB;
}
const gchar *
getDocumentLocaleCB(AtkDocument *aDocument)
{
AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aDocument));
if (!accWrap)
return nullptr;
nsAutoString locale;
accWrap->Language(locale);
return locale.IsEmpty() ? nullptr : AccessibleWrap::ReturnString(locale);
}
static inline GSList *
prependToList(GSList *aList, const char *const aName, const nsAutoString &aValue)
{
if (aValue.IsEmpty())
return aList;
// libspi will free these
AtkAttribute *atkAttr = (AtkAttribute *)g_malloc(sizeof(AtkAttribute));
atkAttr->name = g_strdup(aName);
atkAttr->value = g_strdup(NS_ConvertUTF16toUTF8(aValue).get());
return g_slist_prepend(aList, atkAttr);
}
AtkAttributeSet *
getDocumentAttributesCB(AtkDocument *aDocument)
{
AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aDocument));
if (!accWrap || !accWrap->IsDoc())
return nullptr;
// according to atkobject.h, AtkAttributeSet is a GSList
GSList* attributes = nullptr;
DocAccessible* document = accWrap->AsDoc();
nsAutoString aURL;
nsresult rv = document->GetURL(aURL);
if (NS_SUCCEEDED(rv))
attributes = prependToList(attributes, kDocUrlName, aURL);
nsAutoString aW3CDocType;
rv = document->GetDocType(aW3CDocType);
if (NS_SUCCEEDED(rv))
attributes = prependToList(attributes, kDocTypeName, aW3CDocType);
nsAutoString aMimeType;
rv = document->GetMimeType(aMimeType);
if (NS_SUCCEEDED(rv))
attributes = prependToList(attributes, kMimeTypeName, aMimeType);
return attributes;
}
const gchar *
getDocumentAttributeValueCB(AtkDocument *aDocument,
const gchar *aAttrName)
{
AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aDocument));
if (!accWrap || !accWrap->IsDoc())
return nullptr;
DocAccessible* document = accWrap->AsDoc();
nsresult rv;
nsAutoString attrValue;
if (!strcasecmp(aAttrName, kDocTypeName))
rv = document->GetDocType(attrValue);
else if (!strcasecmp(aAttrName, kDocUrlName))
rv = document->GetURL(attrValue);
else if (!strcasecmp(aAttrName, kMimeTypeName))
rv = document->GetMimeType(attrValue);
else
return nullptr;
NS_ENSURE_SUCCESS(rv, nullptr);
return attrValue.IsEmpty() ? nullptr : AccessibleWrap::ReturnString(attrValue);
}
}
@@ -0,0 +1,120 @@
/* -*- 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 "InterfaceInitFuncs.h"
#include "Accessible-inl.h"
#include "HyperTextAccessible.h"
#include "nsMai.h"
#include "nsString.h"
#include "mozilla/Likely.h"
using namespace mozilla::a11y;
extern "C" {
static void
setTextContentsCB(AtkEditableText *aText, const gchar *aString)
{
AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aText));
if (!accWrap)
return;
HyperTextAccessible* text = accWrap->AsHyperText();
if (!text || !text->IsTextRole())
return;
NS_ConvertUTF8toUTF16 strContent(aString);
text->SetTextContents(strContent);
}
static void
insertTextCB(AtkEditableText *aText,
const gchar *aString, gint aLength, gint *aPosition)
{
AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aText));
if (!accWrap)
return;
HyperTextAccessible* text = accWrap->AsHyperText();
if (!text || !text->IsTextRole())
return;
NS_ConvertUTF8toUTF16 strContent(aString, aLength);
text->InsertText(strContent, *aPosition);
}
static void
copyTextCB(AtkEditableText *aText, gint aStartPos, gint aEndPos)
{
AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aText));
if (!accWrap)
return;
HyperTextAccessible* text = accWrap->AsHyperText();
if (!text || !text->IsTextRole())
return;
text->CopyText(aStartPos, aEndPos);
}
static void
cutTextCB(AtkEditableText *aText, gint aStartPos, gint aEndPos)
{
AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aText));
if (!accWrap)
return;
HyperTextAccessible* text = accWrap->AsHyperText();
if (!text || !text->IsTextRole())
return;
text->CutText(aStartPos, aEndPos);
}
static void
deleteTextCB(AtkEditableText *aText, gint aStartPos, gint aEndPos)
{
AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aText));
if (!accWrap)
return;
HyperTextAccessible* text = accWrap->AsHyperText();
if (!text || !text->IsTextRole())
return;
text->DeleteText(aStartPos, aEndPos);
}
static void
pasteTextCB(AtkEditableText *aText, gint aPosition)
{
AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aText));
if (!accWrap)
return;
HyperTextAccessible* text = accWrap->AsHyperText();
if (!text || !text->IsTextRole())
return;
text->PasteText(aPosition);
}
}
void
editableTextInterfaceInitCB(AtkEditableTextIface* aIface)
{
NS_ASSERTION(aIface, "Invalid aIface");
if (MOZ_UNLIKELY(!aIface))
return;
aIface->set_text_contents = setTextContentsCB;
aIface->insert_text = insertTextCB;
aIface->copy_text = copyTextCB;
aIface->cut_text = cutTextCB;
aIface->delete_text = deleteTextCB;
aIface->paste_text = pasteTextCB;
}
@@ -0,0 +1,38 @@
/* -*- 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 "InterfaceInitFuncs.h"
#include "nsMaiHyperlink.h"
#include "mozilla/Likely.h"
using namespace mozilla::a11y;
extern "C" {
static AtkHyperlink*
getHyperlinkCB(AtkHyperlinkImpl* aImpl)
{
AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aImpl));
if (!accWrap)
return nullptr;
NS_ENSURE_TRUE(accWrap->IsLink(), nullptr);
MaiHyperlink* maiHyperlink = accWrap->GetMaiHyperlink();
NS_ENSURE_TRUE(maiHyperlink, nullptr);
return maiHyperlink->GetAtkHyperlink();
}
}
void
hyperlinkImplInterfaceInitCB(AtkHyperlinkImplIface *aIface)
{
NS_ASSERTION(aIface, "no interface!");
if (MOZ_UNLIKELY(!aIface))
return;
aIface->get_hyperlink = getHyperlinkCB;
}
@@ -0,0 +1,83 @@
/* -*- 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 "InterfaceInitFuncs.h"
#include "Accessible-inl.h"
#include "HyperTextAccessible.h"
#include "nsMai.h"
#include "nsMaiHyperlink.h"
#include "mozilla/Likely.h"
using namespace mozilla::a11y;
extern "C" {
static AtkHyperlink*
getLinkCB(AtkHypertext *aText, gint aLinkIndex)
{
AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aText));
if (!accWrap)
return nullptr;
HyperTextAccessible* hyperText = accWrap->AsHyperText();
NS_ENSURE_TRUE(hyperText, nullptr);
Accessible* hyperLink = hyperText->GetLinkAt(aLinkIndex);
if (!hyperLink)
return nullptr;
AtkObject* hyperLinkAtkObj = AccessibleWrap::GetAtkObject(hyperLink);
AccessibleWrap* accChild = GetAccessibleWrap(hyperLinkAtkObj);
NS_ENSURE_TRUE(accChild, nullptr);
MaiHyperlink *maiHyperlink = accChild->GetMaiHyperlink();
NS_ENSURE_TRUE(maiHyperlink, nullptr);
return maiHyperlink->GetAtkHyperlink();
}
static gint
getLinkCountCB(AtkHypertext *aText)
{
AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aText));
if (!accWrap)
return -1;
HyperTextAccessible* hyperText = accWrap->AsHyperText();
NS_ENSURE_TRUE(hyperText, -1);
return hyperText->GetLinkCount();
}
static gint
getLinkIndexCB(AtkHypertext *aText, gint aCharIndex)
{
AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aText));
if (!accWrap)
return -1;
HyperTextAccessible* hyperText = accWrap->AsHyperText();
NS_ENSURE_TRUE(hyperText, -1);
int32_t index = -1;
nsresult rv = hyperText->GetLinkIndexAtOffset(aCharIndex, &index);
NS_ENSURE_SUCCESS(rv, -1);
return index;
}
}
void
hypertextInterfaceInitCB(AtkHypertextIface* aIface)
{
NS_ASSERTION(aIface, "no interface!");
if (MOZ_UNLIKELY(!aIface))
return;
aIface->get_link = getLinkCB;
aIface->get_n_links = getLinkCountCB;
aIface->get_link_index = getLinkIndexCB;
}
@@ -0,0 +1,63 @@
/* -*- 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 "InterfaceInitFuncs.h"
#include "AccessibleWrap.h"
#include "ImageAccessible.h"
#include "mozilla/Likely.h"
#include "nsMai.h"
using namespace mozilla;
using namespace mozilla::a11y;
extern "C" {
const gchar* getDescriptionCB(AtkObject* aAtkObj);
static void
getImagePositionCB(AtkImage* aImage, gint* aAccX, gint* aAccY,
AtkCoordType aCoordType)
{
AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aImage));
if (!accWrap || !accWrap->IsImage())
return;
ImageAccessible* image = accWrap->AsImage();
uint32_t goannaCoordType = (aCoordType == ATK_XY_WINDOW) ?
nsIAccessibleCoordinateType::COORDTYPE_WINDOW_RELATIVE :
nsIAccessibleCoordinateType::COORDTYPE_SCREEN_RELATIVE;
// Returned in screen coordinates
image->GetImagePosition(goannaCoordType, aAccX, aAccY);
}
static const gchar*
getImageDescriptionCB(AtkImage* aImage)
{
return getDescriptionCB(ATK_OBJECT(aImage));
}
static void
getImageSizeCB(AtkImage* aImage, gint* aAccWidth, gint* aAccHeight)
{
AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aImage));
if (!accWrap || !accWrap->IsImage())
return;
accWrap->AsImage()->GetImageSize(aAccWidth, aAccHeight);
}
}
void
imageInterfaceInitCB(AtkImageIface* aIface)
{
NS_ASSERTION(aIface, "no interface!");
if (MOZ_UNLIKELY(!aIface))
return;
aIface->get_image_position = getImagePositionCB;
aIface->get_image_description = getImageDescriptionCB;
aIface->get_image_size = getImageSizeCB;
}
@@ -0,0 +1,113 @@
/* -*- 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 "InterfaceInitFuncs.h"
#include "Accessible-inl.h"
#include "AccessibleWrap.h"
#include "nsMai.h"
#include "mozilla/Likely.h"
#include <atk/atk.h>
using namespace mozilla::a11y;
extern "C" {
static gboolean
addSelectionCB(AtkSelection *aSelection, gint i)
{
AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aSelection));
if (!accWrap || !accWrap->IsSelect())
return FALSE;
return accWrap->AddItemToSelection(i);
}
static gboolean
clearSelectionCB(AtkSelection *aSelection)
{
AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aSelection));
if (!accWrap || !accWrap->IsSelect())
return FALSE;
return accWrap->UnselectAll();
}
static AtkObject*
refSelectionCB(AtkSelection *aSelection, gint i)
{
AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aSelection));
if (!accWrap || !accWrap->IsSelect())
return nullptr;
Accessible* selectedItem = accWrap->GetSelectedItem(i);
if (!selectedItem)
return nullptr;
AtkObject* atkObj = AccessibleWrap::GetAtkObject(selectedItem);
if (atkObj)
g_object_ref(atkObj);
return atkObj;
}
static gint
getSelectionCountCB(AtkSelection *aSelection)
{
AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aSelection));
if (!accWrap || !accWrap->IsSelect())
return -1;
return accWrap->SelectedItemCount();
}
static gboolean
isChildSelectedCB(AtkSelection *aSelection, gint i)
{
AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aSelection));
if (!accWrap || !accWrap->IsSelect())
return FALSE;
return accWrap->IsItemSelected(i);
}
static gboolean
removeSelectionCB(AtkSelection *aSelection, gint i)
{
AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aSelection));
if (!accWrap || !accWrap->IsSelect())
return FALSE;
return accWrap->RemoveItemFromSelection(i);
}
static gboolean
selectAllSelectionCB(AtkSelection *aSelection)
{
AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aSelection));
if (!accWrap || !accWrap->IsSelect())
return FALSE;
return accWrap->SelectAll();
}
}
void
selectionInterfaceInitCB(AtkSelectionIface* aIface)
{
NS_ASSERTION(aIface, "Invalid aIface");
if (MOZ_UNLIKELY(!aIface))
return;
aIface->add_selection = addSelectionCB;
aIface->clear_selection = clearSelectionCB;
aIface->ref_selection = refSelectionCB;
aIface->get_selection_count = getSelectionCountCB;
aIface->is_child_selected = isChildSelectedCB;
aIface->remove_selection = removeSelectionCB;
aIface->select_all_selection = selectAllSelectionCB;
}
+320
View File
@@ -0,0 +1,320 @@
/* -*- 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 "InterfaceInitFuncs.h"
#include "Accessible-inl.h"
#include "AccessibleWrap.h"
#include "nsAccUtils.h"
#include "TableAccessible.h"
#include "TableCellAccessible.h"
#include "nsMai.h"
#include "nsArrayUtils.h"
#include "mozilla/Likely.h"
using namespace mozilla::a11y;
extern "C" {
static AtkObject*
refAtCB(AtkTable* aTable, gint aRowIdx, gint aColIdx)
{
AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aTable));
if (!accWrap || aRowIdx < 0 || aColIdx < 0)
return nullptr;
Accessible* cell = accWrap->AsTable()->CellAt(aRowIdx, aColIdx);
if (!cell)
return nullptr;
AtkObject* cellAtkObj = AccessibleWrap::GetAtkObject(cell);
if (cellAtkObj)
g_object_ref(cellAtkObj);
return cellAtkObj;
}
static gint
getIndexAtCB(AtkTable* aTable, gint aRowIdx, gint aColIdx)
{
AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aTable));
if (!accWrap || aRowIdx < 0 || aColIdx < 0)
return -1;
return static_cast<gint>(accWrap->AsTable()->CellIndexAt(aRowIdx, aColIdx));
}
static gint
getColumnAtIndexCB(AtkTable *aTable, gint aIdx)
{
AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aTable));
if (!accWrap || aIdx < 0)
return -1;
return static_cast<gint>(accWrap->AsTable()->ColIndexAt(aIdx));
}
static gint
getRowAtIndexCB(AtkTable *aTable, gint aIdx)
{
AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aTable));
if (!accWrap || aIdx < 0)
return -1;
return static_cast<gint>(accWrap->AsTable()->RowIndexAt(aIdx));
}
static gint
getColumnCountCB(AtkTable *aTable)
{
AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aTable));
if (!accWrap)
return -1;
return static_cast<gint>(accWrap->AsTable()->ColCount());
}
static gint
getRowCountCB(AtkTable *aTable)
{
AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aTable));
if (!accWrap)
return -1;
return static_cast<gint>(accWrap->AsTable()->RowCount());
}
static gint
getColumnExtentAtCB(AtkTable *aTable, gint aRowIdx, gint aColIdx)
{
AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aTable));
if (!accWrap || aRowIdx < 0 || aColIdx < 0)
return -1;
return static_cast<gint>(accWrap->AsTable()->ColExtentAt(aRowIdx, aColIdx));
}
static gint
getRowExtentAtCB(AtkTable *aTable, gint aRowIdx, gint aColIdx)
{
AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aTable));
if (!accWrap)
return -1;
return static_cast<gint>(accWrap->AsTable()->RowExtentAt(aRowIdx, aColIdx));
}
static AtkObject*
getCaptionCB(AtkTable* aTable)
{
AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aTable));
if (!accWrap)
return nullptr;
Accessible* caption = accWrap->AsTable()->Caption();
return caption ? AccessibleWrap::GetAtkObject(caption) : nullptr;
}
static const gchar*
getColumnDescriptionCB(AtkTable *aTable, gint aColumn)
{
AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aTable));
if (!accWrap)
return nullptr;
nsAutoString autoStr;
accWrap->AsTable()->ColDescription(aColumn, autoStr);
return AccessibleWrap::ReturnString(autoStr);
}
static AtkObject*
getColumnHeaderCB(AtkTable *aTable, gint aColIdx)
{
AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aTable));
if (!accWrap)
return nullptr;
Accessible* cell = accWrap->AsTable()->CellAt(0, aColIdx);
if (!cell)
return nullptr;
// If the cell at the first row is column header then assume it is column
// header for all rows,
if (cell->Role() == roles::COLUMNHEADER)
return AccessibleWrap::GetAtkObject(cell);
// otherwise get column header for the data cell at the first row.
TableCellAccessible* tableCell = cell->AsTableCell();
if (!tableCell)
return nullptr;
nsAutoTArray<Accessible*, 10> headerCells;
tableCell->ColHeaderCells(&headerCells);
if (headerCells.IsEmpty())
return nullptr;
return AccessibleWrap::GetAtkObject(headerCells[0]);
}
static const gchar*
getRowDescriptionCB(AtkTable *aTable, gint aRow)
{
AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aTable));
if (!accWrap)
return nullptr;
nsAutoString autoStr;
accWrap->AsTable()->RowDescription(aRow, autoStr);
return AccessibleWrap::ReturnString(autoStr);
}
static AtkObject*
getRowHeaderCB(AtkTable *aTable, gint aRowIdx)
{
AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aTable));
if (!accWrap)
return nullptr;
Accessible* cell = accWrap->AsTable()->CellAt(aRowIdx, 0);
if (!cell)
return nullptr;
// If the cell at the first column is row header then assume it is row
// header for all columns,
if (cell->Role() == roles::ROWHEADER)
return AccessibleWrap::GetAtkObject(cell);
// otherwise get row header for the data cell at the first column.
TableCellAccessible* tableCell = cell->AsTableCell();
if (!tableCell)
return nullptr;
nsAutoTArray<Accessible*, 10> headerCells;
tableCell->RowHeaderCells(&headerCells);
if (headerCells.IsEmpty())
return nullptr;
return AccessibleWrap::GetAtkObject(headerCells[0]);
}
static AtkObject*
getSummaryCB(AtkTable *aTable)
{
// Neither html:table nor xul:tree nor ARIA grid/tree have an ability to
// link an accessible object to specify a summary. There is closes method
// in TableAccessible::summary to get a summary as a string which is not
// mapped directly to ATK.
return nullptr;
}
static gint
getSelectedColumnsCB(AtkTable *aTable, gint** aSelected)
{
*aSelected = nullptr;
AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aTable));
if (!accWrap)
return 0;
nsAutoTArray<uint32_t, 10> cols;
accWrap->AsTable()->SelectedColIndices(&cols);
if (cols.IsEmpty())
return 0;
gint* atkColumns = g_new(gint, cols.Length());
if (!atkColumns) {
NS_WARNING("OUT OF MEMORY");
return 0;
}
memcpy(atkColumns, cols.Elements(), cols.Length() * sizeof(uint32_t));
*aSelected = atkColumns;
return cols.Length();
}
static gint
getSelectedRowsCB(AtkTable *aTable, gint **aSelected)
{
AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aTable));
if (!accWrap)
return 0;
nsAutoTArray<uint32_t, 10> rows;
accWrap->AsTable()->SelectedRowIndices(&rows);
gint* atkRows = g_new(gint, rows.Length());
if (!atkRows) {
NS_WARNING("OUT OF MEMORY");
return 0;
}
memcpy(atkRows, rows.Elements(), rows.Length() * sizeof(uint32_t));
*aSelected = atkRows;
return rows.Length();
}
static gboolean
isColumnSelectedCB(AtkTable *aTable, gint aColIdx)
{
AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aTable));
if (!accWrap)
return FALSE;
return static_cast<gboolean>(accWrap->AsTable()->IsColSelected(aColIdx));
}
static gboolean
isRowSelectedCB(AtkTable *aTable, gint aRowIdx)
{
AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aTable));
if (!accWrap)
return FALSE;
return static_cast<gboolean>(accWrap->AsTable()->IsRowSelected(aRowIdx));
}
static gboolean
isCellSelectedCB(AtkTable *aTable, gint aRowIdx, gint aColIdx)
{
AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aTable));
if (!accWrap)
return FALSE;
return static_cast<gboolean>(accWrap->AsTable()->
IsCellSelected(aRowIdx, aColIdx));
}
}
void
tableInterfaceInitCB(AtkTableIface* aIface)
{
NS_ASSERTION(aIface, "no interface!");
if (MOZ_UNLIKELY(!aIface))
return;
aIface->ref_at = refAtCB;
aIface->get_index_at = getIndexAtCB;
aIface->get_column_at_index = getColumnAtIndexCB;
aIface->get_row_at_index = getRowAtIndexCB;
aIface->get_n_columns = getColumnCountCB;
aIface->get_n_rows = getRowCountCB;
aIface->get_column_extent_at = getColumnExtentAtCB;
aIface->get_row_extent_at = getRowExtentAtCB;
aIface->get_caption = getCaptionCB;
aIface->get_column_description = getColumnDescriptionCB;
aIface->get_column_header = getColumnHeaderCB;
aIface->get_row_description = getRowDescriptionCB;
aIface->get_row_header = getRowHeaderCB;
aIface->get_summary = getSummaryCB;
aIface->get_selected_columns = getSelectedColumnsCB;
aIface->get_selected_rows = getSelectedRowsCB;
aIface->is_column_selected = isColumnSelectedCB;
aIface->is_row_selected = isRowSelectedCB;
aIface->is_selected = isCellSelectedCB;
}
+475
View File
@@ -0,0 +1,475 @@
/* -*- 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 "InterfaceInitFuncs.h"
#include "Accessible-inl.h"
#include "HyperTextAccessible.h"
#include "nsMai.h"
#include "nsIPersistentProperties2.h"
#include "mozilla/Likely.h"
using namespace mozilla::a11y;
AtkAttributeSet* ConvertToAtkAttributeSet(nsIPersistentProperties* aAttributes);
static void
ConvertTexttoAsterisks(AccessibleWrap* accWrap, nsAString& aString)
{
// convert each char to "*" when it's "password text"
if (accWrap->NativeRole() == roles::PASSWORD_TEXT) {
for (uint32_t i = 0; i < aString.Length(); i++)
aString.Replace(i, 1, NS_LITERAL_STRING("*"));
}
}
extern "C" {
static gchar*
getTextCB(AtkText *aText, gint aStartOffset, gint aEndOffset)
{
AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aText));
if (!accWrap)
return nullptr;
HyperTextAccessible* text = accWrap->AsHyperText();
if (!text || !text->IsTextRole())
return nullptr;
nsAutoString autoStr;
nsresult rv = text->GetText(aStartOffset, aEndOffset, autoStr);
NS_ENSURE_SUCCESS(rv, nullptr);
ConvertTexttoAsterisks(accWrap, autoStr);
NS_ConvertUTF16toUTF8 cautoStr(autoStr);
//copy and return, libspi will free it.
return (cautoStr.get()) ? g_strdup(cautoStr.get()) : nullptr;
}
static gchar*
getTextAfterOffsetCB(AtkText *aText, gint aOffset,
AtkTextBoundary aBoundaryType,
gint *aStartOffset, gint *aEndOffset)
{
AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aText));
if (!accWrap)
return nullptr;
HyperTextAccessible* text = accWrap->AsHyperText();
if (!text || !text->IsTextRole())
return nullptr;
nsAutoString autoStr;
int32_t startOffset = 0, endOffset = 0;
nsresult rv =
text->GetTextAfterOffset(aOffset, aBoundaryType,
&startOffset, &endOffset, autoStr);
*aStartOffset = startOffset;
*aEndOffset = endOffset;
NS_ENSURE_SUCCESS(rv, nullptr);
ConvertTexttoAsterisks(accWrap, autoStr);
NS_ConvertUTF16toUTF8 cautoStr(autoStr);
return (cautoStr.get()) ? g_strdup(cautoStr.get()) : nullptr;
}
static gchar*
getTextAtOffsetCB(AtkText *aText, gint aOffset,
AtkTextBoundary aBoundaryType,
gint *aStartOffset, gint *aEndOffset)
{
AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aText));
if (!accWrap)
return nullptr;
HyperTextAccessible* text = accWrap->AsHyperText();
if (!text || !text->IsTextRole())
return nullptr;
nsAutoString autoStr;
int32_t startOffset = 0, endOffset = 0;
nsresult rv =
text->GetTextAtOffset(aOffset, aBoundaryType,
&startOffset, &endOffset, autoStr);
*aStartOffset = startOffset;
*aEndOffset = endOffset;
NS_ENSURE_SUCCESS(rv, nullptr);
ConvertTexttoAsterisks(accWrap, autoStr);
NS_ConvertUTF16toUTF8 cautoStr(autoStr);
return (cautoStr.get()) ? g_strdup(cautoStr.get()) : nullptr;
}
static gunichar
getCharacterAtOffsetCB(AtkText* aText, gint aOffset)
{
AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aText));
if (!accWrap)
return 0;
HyperTextAccessible* text = accWrap->AsHyperText();
if (!text || !text->IsTextRole())
return 0;
// PRUnichar is unsigned short in Mozilla
// gnuichar is guint32 in glib
PRUnichar uniChar = 0;
nsresult rv = text->GetCharacterAtOffset(aOffset, &uniChar);
if (NS_FAILED(rv))
return 0;
// Convert char to "*" when it's "password text".
if (accWrap->NativeRole() == roles::PASSWORD_TEXT)
uniChar = '*';
return static_cast<gunichar>(uniChar);
}
static gchar*
getTextBeforeOffsetCB(AtkText *aText, gint aOffset,
AtkTextBoundary aBoundaryType,
gint *aStartOffset, gint *aEndOffset)
{
AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aText));
if (!accWrap)
return nullptr;
HyperTextAccessible* text = accWrap->AsHyperText();
if (!text || !text->IsTextRole())
return nullptr;
nsAutoString autoStr;
int32_t startOffset = 0, endOffset = 0;
nsresult rv =
text->GetTextBeforeOffset(aOffset, aBoundaryType,
&startOffset, &endOffset, autoStr);
*aStartOffset = startOffset;
*aEndOffset = endOffset;
NS_ENSURE_SUCCESS(rv, nullptr);
ConvertTexttoAsterisks(accWrap, autoStr);
NS_ConvertUTF16toUTF8 cautoStr(autoStr);
return (cautoStr.get()) ? g_strdup(cautoStr.get()) : nullptr;
}
static gint
getCaretOffsetCB(AtkText *aText)
{
AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aText));
if (!accWrap)
return 0;
HyperTextAccessible* text = accWrap->AsHyperText();
if (!text || !text->IsTextRole())
return 0;
int32_t offset;
nsresult rv = text->GetCaretOffset(&offset);
return (NS_FAILED(rv)) ? 0 : static_cast<gint>(offset);
}
static AtkAttributeSet*
getRunAttributesCB(AtkText *aText, gint aOffset,
gint *aStartOffset,
gint *aEndOffset)
{
*aStartOffset = -1;
*aEndOffset = -1;
AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aText));
if (!accWrap)
return nullptr;
HyperTextAccessible* text = accWrap->AsHyperText();
if (!text || !text->IsTextRole())
return nullptr;
nsCOMPtr<nsIPersistentProperties> attributes;
int32_t startOffset = 0, endOffset = 0;
nsresult rv = text->GetTextAttributes(false, aOffset,
&startOffset, &endOffset,
getter_AddRefs(attributes));
NS_ENSURE_SUCCESS(rv, nullptr);
*aStartOffset = startOffset;
*aEndOffset = endOffset;
return ConvertToAtkAttributeSet(attributes);
}
static AtkAttributeSet*
getDefaultAttributesCB(AtkText *aText)
{
AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aText));
if (!accWrap)
return nullptr;
HyperTextAccessible* text = accWrap->AsHyperText();
if (!text || !text->IsTextRole())
return nullptr;
nsCOMPtr<nsIPersistentProperties> attributes;
nsresult rv = text->GetDefaultTextAttributes(getter_AddRefs(attributes));
if (NS_FAILED(rv))
return nullptr;
return ConvertToAtkAttributeSet(attributes);
}
static void
getCharacterExtentsCB(AtkText *aText, gint aOffset,
gint *aX, gint *aY,
gint *aWidth, gint *aHeight,
AtkCoordType aCoords)
{
AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aText));
if(!accWrap || !aX || !aY || !aWidth || !aHeight)
return;
HyperTextAccessible* text = accWrap->AsHyperText();
if (!text || !text->IsTextRole())
return;
int32_t extY = 0, extX = 0;
int32_t extWidth = 0, extHeight = 0;
uint32_t goannaCoordType;
if (aCoords == ATK_XY_SCREEN)
goannaCoordType = nsIAccessibleCoordinateType::COORDTYPE_SCREEN_RELATIVE;
else
goannaCoordType = nsIAccessibleCoordinateType::COORDTYPE_WINDOW_RELATIVE;
#ifdef DEBUG
nsresult rv =
#endif
text->GetCharacterExtents(aOffset, &extX, &extY,
&extWidth, &extHeight,
goannaCoordType);
*aX = extX;
*aY = extY;
*aWidth = extWidth;
*aHeight = extHeight;
NS_ASSERTION(NS_SUCCEEDED(rv),
"MaiInterfaceText::GetCharacterExtents, failed\n");
}
static void
getRangeExtentsCB(AtkText *aText, gint aStartOffset, gint aEndOffset,
AtkCoordType aCoords, AtkTextRectangle *aRect)
{
AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aText));
if(!accWrap || !aRect)
return;
HyperTextAccessible* text = accWrap->AsHyperText();
if (!text || !text->IsTextRole())
return;
int32_t extY = 0, extX = 0;
int32_t extWidth = 0, extHeight = 0;
uint32_t goannaCoordType;
if (aCoords == ATK_XY_SCREEN)
goannaCoordType = nsIAccessibleCoordinateType::COORDTYPE_SCREEN_RELATIVE;
else
goannaCoordType = nsIAccessibleCoordinateType::COORDTYPE_WINDOW_RELATIVE;
#ifdef DEBUG
nsresult rv =
#endif
text->GetRangeExtents(aStartOffset, aEndOffset,
&extX, &extY,
&extWidth, &extHeight,
goannaCoordType);
aRect->x = extX;
aRect->y = extY;
aRect->width = extWidth;
aRect->height = extHeight;
NS_ASSERTION(NS_SUCCEEDED(rv),
"MaiInterfaceText::GetRangeExtents, failed\n");
}
static gint
getCharacterCountCB(AtkText *aText)
{
AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aText));
if (!accWrap)
return 0;
HyperTextAccessible* textAcc = accWrap->AsHyperText();
return textAcc->IsDefunct() ?
0 : static_cast<gint>(textAcc->CharacterCount());
}
static gint
getOffsetAtPointCB(AtkText *aText,
gint aX, gint aY,
AtkCoordType aCoords)
{
AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aText));
if (!accWrap)
return -1;
HyperTextAccessible* text = accWrap->AsHyperText();
if (!text || !text->IsTextRole())
return -1;
int32_t offset = 0;
uint32_t goannaCoordType;
if (aCoords == ATK_XY_SCREEN)
goannaCoordType = nsIAccessibleCoordinateType::COORDTYPE_SCREEN_RELATIVE;
else
goannaCoordType = nsIAccessibleCoordinateType::COORDTYPE_WINDOW_RELATIVE;
text->GetOffsetAtPoint(aX, aY, goannaCoordType, &offset);
return static_cast<gint>(offset);
}
static gint
getTextSelectionCountCB(AtkText *aText)
{
AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aText));
if (!accWrap)
return 0;
HyperTextAccessible* text = accWrap->AsHyperText();
if (!text || !text->IsTextRole())
return 0;
int32_t selectionCount;
nsresult rv = text->GetSelectionCount(&selectionCount);
return NS_FAILED(rv) ? 0 : selectionCount;
}
static gchar*
getTextSelectionCB(AtkText *aText, gint aSelectionNum,
gint *aStartOffset, gint *aEndOffset)
{
AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aText));
if (!accWrap)
return nullptr;
HyperTextAccessible* text = accWrap->AsHyperText();
if (!text || !text->IsTextRole())
return nullptr;
int32_t startOffset = 0, endOffset = 0;
nsresult rv = text->GetSelectionBounds(aSelectionNum,
&startOffset, &endOffset);
*aStartOffset = startOffset;
*aEndOffset = endOffset;
NS_ENSURE_SUCCESS(rv, nullptr);
return getTextCB(aText, *aStartOffset, *aEndOffset);
}
// set methods
static gboolean
addTextSelectionCB(AtkText *aText,
gint aStartOffset,
gint aEndOffset)
{
AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aText));
if (!accWrap)
return FALSE;
HyperTextAccessible* text = accWrap->AsHyperText();
if (!text || !text->IsTextRole())
return false;
nsresult rv = text->AddSelection(aStartOffset, aEndOffset);
return NS_SUCCEEDED(rv) ? TRUE : FALSE;
}
static gboolean
removeTextSelectionCB(AtkText *aText,
gint aSelectionNum)
{
AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aText));
if (!accWrap)
return FALSE;
HyperTextAccessible* text = accWrap->AsHyperText();
if (!text || !text->IsTextRole())
return false;
nsresult rv = text->RemoveSelection(aSelectionNum);
return NS_SUCCEEDED(rv) ? TRUE : FALSE;
}
static gboolean
setTextSelectionCB(AtkText *aText, gint aSelectionNum,
gint aStartOffset, gint aEndOffset)
{
AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aText));
if (!accWrap)
return FALSE;
HyperTextAccessible* text = accWrap->AsHyperText();
if (!text || !text->IsTextRole())
return false;
nsresult rv = text->SetSelectionBounds(aSelectionNum,
aStartOffset, aEndOffset);
return NS_SUCCEEDED(rv) ? TRUE : FALSE;
}
static gboolean
setCaretOffsetCB(AtkText *aText, gint aOffset)
{
AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aText));
if (!accWrap)
return FALSE;
HyperTextAccessible* text = accWrap->AsHyperText();
if (!text || !text->IsTextRole())
return false;
nsresult rv = text->SetCaretOffset(aOffset);
return NS_SUCCEEDED(rv) ? TRUE : FALSE;
}
}
void
textInterfaceInitCB(AtkTextIface* aIface)
{
NS_ASSERTION(aIface, "Invalid aIface");
if (MOZ_UNLIKELY(!aIface))
return;
aIface->get_text = getTextCB;
aIface->get_text_after_offset = getTextAfterOffsetCB;
aIface->get_text_at_offset = getTextAtOffsetCB;
aIface->get_character_at_offset = getCharacterAtOffsetCB;
aIface->get_text_before_offset = getTextBeforeOffsetCB;
aIface->get_caret_offset = getCaretOffsetCB;
aIface->get_run_attributes = getRunAttributesCB;
aIface->get_default_attributes = getDefaultAttributesCB;
aIface->get_character_extents = getCharacterExtentsCB;
aIface->get_range_extents = getRangeExtentsCB;
aIface->get_character_count = getCharacterCountCB;
aIface->get_offset_at_point = getOffsetAtPointCB;
aIface->get_n_selections = getTextSelectionCountCB;
aIface->get_selection = getTextSelectionCB;
// set methods
aIface->add_selection = addTextSelectionCB;
aIface->remove_selection = removeTextSelectionCB;
aIface->set_selection = setTextSelectionCB;
aIface->set_caret_offset = setCaretOffsetCB;
}
+130
View File
@@ -0,0 +1,130 @@
/* -*- 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 "InterfaceInitFuncs.h"
#include "mozilla/Likely.h"
#include "AccessibleWrap.h"
#include "nsMai.h"
using namespace mozilla::a11y;
extern "C" {
static void
getCurrentValueCB(AtkValue *obj, GValue *value)
{
AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(obj));
if (!accWrap)
return;
nsCOMPtr<nsIAccessibleValue> accValue;
accWrap->QueryInterface(NS_GET_IID(nsIAccessibleValue),
getter_AddRefs(accValue));
if (!accValue)
return;
memset (value, 0, sizeof (GValue));
double accDouble;
if (NS_FAILED(accValue->GetCurrentValue(&accDouble)))
return;
g_value_init (value, G_TYPE_DOUBLE);
g_value_set_double (value, accDouble);
}
static void
getMaximumValueCB(AtkValue *obj, GValue *value)
{
AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(obj));
if (!accWrap)
return;
nsCOMPtr<nsIAccessibleValue> accValue;
accWrap->QueryInterface(NS_GET_IID(nsIAccessibleValue),
getter_AddRefs(accValue));
if (!accValue)
return;
memset (value, 0, sizeof (GValue));
double accDouble;
if (NS_FAILED(accValue->GetMaximumValue(&accDouble)))
return;
g_value_init (value, G_TYPE_DOUBLE);
g_value_set_double (value, accDouble);
}
static void
getMinimumValueCB(AtkValue *obj, GValue *value)
{
AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(obj));
if (!accWrap)
return;
nsCOMPtr<nsIAccessibleValue> accValue;
accWrap->QueryInterface(NS_GET_IID(nsIAccessibleValue),
getter_AddRefs(accValue));
if (!accValue)
return;
memset (value, 0, sizeof (GValue));
double accDouble;
if (NS_FAILED(accValue->GetMinimumValue(&accDouble)))
return;
g_value_init (value, G_TYPE_DOUBLE);
g_value_set_double (value, accDouble);
}
static void
getMinimumIncrementCB(AtkValue *obj, GValue *minimumIncrement)
{
AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(obj));
if (!accWrap)
return;
nsCOMPtr<nsIAccessibleValue> accValue;
accWrap->QueryInterface(NS_GET_IID(nsIAccessibleValue),
getter_AddRefs(accValue));
if (!accValue)
return;
memset (minimumIncrement, 0, sizeof (GValue));
double accDouble;
if (NS_FAILED(accValue->GetMinimumIncrement(&accDouble)))
return;
g_value_init (minimumIncrement, G_TYPE_DOUBLE);
g_value_set_double (minimumIncrement, accDouble);
}
static gboolean
setCurrentValueCB(AtkValue *obj, const GValue *value)
{
AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(obj));
if (!accWrap)
return FALSE;
nsCOMPtr<nsIAccessibleValue> accValue;
accWrap->QueryInterface(NS_GET_IID(nsIAccessibleValue),
getter_AddRefs(accValue));
NS_ENSURE_TRUE(accValue, FALSE);
double accDouble =g_value_get_double (value);
return !NS_FAILED(accValue->SetCurrentValue(accDouble));
}
}
void
valueInterfaceInitCB(AtkValueIface* aIface)
{
NS_ASSERTION(aIface, "Invalid aIface");
if (MOZ_UNLIKELY(!aIface))
return;
aIface->get_current_value = getCurrentValueCB;
aIface->get_maximum_value = getMaximumValueCB;
aIface->get_minimum_value = getMinimumValueCB;
aIface->get_minimum_increment = getMinimumIncrementCB;
aIface->set_current_value = setCurrentValueCB;
}
+115
View File
@@ -0,0 +1,115 @@
/* -*- 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 <atk/atk.h>
#include "AccessibleWrap.h"
/******************************************************************************
The following nsIAccessible states aren't translated, just ignored:
STATE_READONLY: Supported indirectly via EXT_STATE_EDITABLE
STATE_HOTTRACKED: No ATK equivalent. No known use case.
The nsIAccessible state is not currently supported.
STATE_FLOATING: No ATK equivalent. No known use case.
The nsIAccessible state is not currently supported.
STATE_MOVEABLE: No ATK equivalent. No known use case.
The nsIAccessible state is not currently supported.
STATE_SELFVOICING: No ATK equivalent -- the object has self-TTS.
The nsIAccessible state is not currently supported.
STATE_LINKED: The object is formatted as a hyperlink. Supported via ATK_ROLE_LINK.
STATE_EXTSELECTABLE: Indicates that an object extends its selection.
This is supported via STATE_MULTISELECTABLE.
STATE_PROTECTED: The object is a password-protected edit control.
Supported via ATK_ROLE_PASSWORD_TEXT
STATE_HASPOPUP: Object displays a pop-up menu or window when invoked.
No ATK equivalent. The nsIAccessible state is not currently supported.
STATE_PINNED: The object is pinned, usually indicating it is fixed in place and has permanence.
No ATK equivalent. The nsIAccessible state is not currently supported.
The following ATK states are not supported:
ATK_STATE_ARMED: No clear use case, used briefly when button is activated
ATK_STATE_HAS_TOOLTIP: No clear use case, no IA2 equivalent
ATK_STATE_ICONIFIED: Mozilla does not have elements which are collapsable into icons
ATK_STATE_TRUNCATED: No clear use case. Indicates that an object's onscreen content is truncated,
e.g. a text value in a spreadsheet cell. No IA2 state.
******************************************************************************/
enum EStateMapEntryType {
kMapDirectly,
kMapOpposite, // For example, UNAVAILABLE is the opposite of ENABLED
kNoStateChange, // Don't fire state change event
kNoSuchState
};
const AtkStateType kNone = ATK_STATE_INVALID;
struct AtkStateMap {
AtkStateType atkState;
EStateMapEntryType stateMapEntryType;
static int32_t GetStateIndexFor(uint64_t aState)
{
int32_t stateIndex = -1;
while (aState > 0) {
++ stateIndex;
aState >>= 1;
}
return stateIndex; // Returns -1 if not mapped
}
};
// Map array from cross platform states to ATK states
static const AtkStateMap gAtkStateMap[] = { // Cross Platform States
{ kNone, kMapOpposite }, // states::UNAVAILABLE = 1 << 0
{ ATK_STATE_SELECTED, kMapDirectly }, // states::SELECTED = 1 << 1
{ ATK_STATE_FOCUSED, kMapDirectly }, // states::FOCUSED = 1 << 2
{ ATK_STATE_PRESSED, kMapDirectly }, // states::PRESSED = 1 << 3
{ ATK_STATE_CHECKED, kMapDirectly }, // states::CHECKED = 1 << 4
{ ATK_STATE_INDETERMINATE, kMapDirectly }, // states::MIXED = 1 << 5
{ kNone, kMapDirectly }, // states::READONLY = 1 << 6
{ kNone, kMapDirectly }, // states::HOTTRACKED = 1 << 7
{ ATK_STATE_DEFAULT, kMapDirectly }, // states::DEFAULT = 1 << 8
{ ATK_STATE_EXPANDED, kMapDirectly }, // states::EXPANDED = 1 << 9
{ kNone, kNoStateChange }, // states::COLLAPSED = 1 << 10
{ ATK_STATE_BUSY, kMapDirectly }, // states::BUSY = 1 << 11
{ kNone, kMapDirectly }, // states::FLOATING = 1 << 12
{ kNone, kMapDirectly }, // states::CHECKABLE = 1 << 13
{ ATK_STATE_ANIMATED, kMapDirectly }, // states::ANIMATED = 1 << 14
{ ATK_STATE_VISIBLE, kMapOpposite }, // states::INVISIBLE = 1 << 15
{ ATK_STATE_SHOWING, kMapOpposite }, // states::OFFSCREEN = 1 << 16
{ ATK_STATE_RESIZABLE, kMapDirectly }, // states::SIZEABLE = 1 << 17
{ kNone, kMapDirectly }, // states::MOVEABLE = 1 << 18
{ kNone, kMapDirectly }, // states::SELFVOICING = 1 << 19
{ ATK_STATE_FOCUSABLE, kMapDirectly }, // states::FOCUSABLE = 1 << 20
{ ATK_STATE_SELECTABLE, kMapDirectly }, // states::SELECTABLE = 1 << 21
{ kNone, kMapDirectly }, // states::LINKED = 1 << 22
{ ATK_STATE_VISITED, kMapDirectly }, // states::TRAVERSED = 1 << 23
{ ATK_STATE_MULTISELECTABLE, kMapDirectly }, // states::MULTISELECTABLE = 1 << 24
{ kNone, kMapDirectly }, // states::EXTSELECTABLE = 1 << 25
{ ATK_STATE_REQUIRED, kMapDirectly }, // states::STATE_REQUIRED = 1 << 26
{ kNone, kMapDirectly }, // states::ALERT_MEDIUM = 1 << 27
{ ATK_STATE_INVALID_ENTRY, kMapDirectly }, // states::INVALID = 1 << 28
{ kNone, kMapDirectly }, // states::PROTECTED = 1 << 29
{ kNone, kMapDirectly }, // states::HASPOPUP = 1 << 30
{ ATK_STATE_SUPPORTS_AUTOCOMPLETION, kMapDirectly }, // states::SUPPORTS_AUTOCOMPLETION = 1 << 31
{ ATK_STATE_DEFUNCT, kMapDirectly }, // states::DEFUNCT = 1 << 32
{ ATK_STATE_SELECTABLE_TEXT, kMapDirectly }, // states::SELECTABLE_TEXT = 1 << 33
{ ATK_STATE_EDITABLE, kMapDirectly }, // states::EDITABLE = 1 << 34
{ ATK_STATE_ACTIVE, kMapDirectly }, // states::ACTIVE = 1 << 35
{ ATK_STATE_MODAL, kMapDirectly }, // states::MODAL = 1 << 36
{ ATK_STATE_MULTI_LINE, kMapDirectly }, // states::MULTI_LINE = 1 << 37
{ ATK_STATE_HORIZONTAL, kMapDirectly }, // states::HORIZONTAL = 1 << 38
{ ATK_STATE_OPAQUE, kMapDirectly }, // states::OPAQUE = 1 << 39
{ ATK_STATE_SINGLE_LINE, kMapDirectly }, // states::SINGLE_LINE = 1 << 40
{ ATK_STATE_TRANSIENT, kMapDirectly }, // states::TRANSIENT = 1 << 41
{ ATK_STATE_VERTICAL, kMapDirectly }, // states::VERTICAL = 1 << 42
{ ATK_STATE_STALE, kMapDirectly }, // states::STALE = 1 << 43
{ ATK_STATE_ENABLED, kMapDirectly }, // states::ENABLED = 1 << 44
{ ATK_STATE_SENSITIVE, kMapDirectly }, // states::SENSITIVE = 1 << 45
{ ATK_STATE_EXPANDABLE, kMapDirectly }, // states::EXPANDABLE = 1 << 46
{ kNone, kMapDirectly }, // states::PINNED = 1 << 47
{ kNone, kNoSuchState }, // = 1 << 48
};
+820
View File
@@ -0,0 +1,820 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim:expandtab:shiftwidth=2:tabstop=2:
*/
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "ARIAMap.h"
#include "Accessible.h"
#include "nsAccUtils.h"
#include "nsCoreUtils.h"
#include "Role.h"
#include "States.h"
#include "nsAttrName.h"
#include "nsWhitespaceTokenizer.h"
using namespace mozilla;
using namespace mozilla::a11y;
using namespace mozilla::a11y::aria;
static const uint32_t kGenericAccType = 0;
/**
* This list of WAI-defined roles are currently hardcoded.
* Eventually we will most likely be loading an RDF resource that contains this information
* Using RDF will also allow for role extensibility. See bug 280138.
*
* Definition of nsRoleMapEntry contains comments explaining this table.
*
* When no nsIAccessibleRole enum mapping exists for an ARIA role, the
* role will be exposed via the object attribute "xml-roles".
* In addition, in MSAA, the unmapped role will also be exposed as a BSTR string role.
*
* There are no nsIAccessibleRole enums for the following landmark roles:
* banner, contentinfo, main, navigation, note, search, secondary, seealso, breadcrumbs
*/
static nsRoleMapEntry sWAIRoleMaps[] =
{
{ // alert
&nsGkAtoms::alert,
roles::ALERT,
kUseMapRole,
eNoValue,
eNoAction,
eNoLiveAttr,
kGenericAccType,
kNoReqStates
},
{ // alertdialog
&nsGkAtoms::alertdialog,
roles::DIALOG,
kUseMapRole,
eNoValue,
eNoAction,
eNoLiveAttr,
kGenericAccType,
kNoReqStates
},
{ // application
&nsGkAtoms::application,
roles::APPLICATION,
kUseMapRole,
eNoValue,
eNoAction,
eNoLiveAttr,
kGenericAccType,
kNoReqStates
},
{ // article
&nsGkAtoms::article,
roles::DOCUMENT,
kUseMapRole,
eNoValue,
eNoAction,
eNoLiveAttr,
kGenericAccType,
kNoReqStates,
eReadonlyUntilEditable
},
{ // button
&nsGkAtoms::button,
roles::PUSHBUTTON,
kUseMapRole,
eNoValue,
ePressAction,
eNoLiveAttr,
kGenericAccType,
kNoReqStates,
eARIAPressed
},
{ // checkbox
&nsGkAtoms::checkbox,
roles::CHECKBUTTON,
kUseMapRole,
eNoValue,
eCheckUncheckAction,
eNoLiveAttr,
kGenericAccType,
kNoReqStates,
eARIACheckableMixed,
eARIAReadonly
},
{ // columnheader
&nsGkAtoms::columnheader,
roles::COLUMNHEADER,
kUseMapRole,
eNoValue,
eSortAction,
eNoLiveAttr,
eTableCell,
kNoReqStates,
eARIASelectable,
eARIAReadonlyOrEditableIfDefined
},
{ // combobox
&nsGkAtoms::combobox,
roles::COMBOBOX,
kUseMapRole,
eNoValue,
eOpenCloseAction,
eNoLiveAttr,
kGenericAccType,
states::COLLAPSED | states::HASPOPUP,
eARIAAutoComplete,
eARIAReadonly
},
{ // dialog
&nsGkAtoms::dialog,
roles::DIALOG,
kUseMapRole,
eNoValue,
eNoAction,
eNoLiveAttr,
kGenericAccType,
kNoReqStates
},
{ // directory
&nsGkAtoms::directory,
roles::LIST,
kUseMapRole,
eNoValue,
eNoAction,
eNoLiveAttr,
eList,
kNoReqStates
},
{ // document
&nsGkAtoms::document,
roles::DOCUMENT,
kUseMapRole,
eNoValue,
eNoAction,
eNoLiveAttr,
kGenericAccType,
kNoReqStates,
eReadonlyUntilEditable
},
{ // form
&nsGkAtoms::form,
roles::FORM,
kUseMapRole,
eNoValue,
eNoAction,
eNoLiveAttr,
kGenericAccType,
kNoReqStates
},
{ // grid
&nsGkAtoms::grid,
roles::TABLE,
kUseMapRole,
eNoValue,
eNoAction,
eNoLiveAttr,
eSelect | eTable,
states::FOCUSABLE,
eARIAMultiSelectable,
eARIAReadonlyOrEditable
},
{ // gridcell
&nsGkAtoms::gridcell,
roles::GRID_CELL,
kUseMapRole,
eNoValue,
eNoAction,
eNoLiveAttr,
eTableCell,
kNoReqStates,
eARIASelectable,
eARIAReadonlyOrEditableIfDefined
},
{ // group
&nsGkAtoms::group,
roles::GROUPING,
kUseMapRole,
eNoValue,
eNoAction,
eNoLiveAttr,
kGenericAccType,
kNoReqStates
},
{ // heading
&nsGkAtoms::heading,
roles::HEADING,
kUseMapRole,
eNoValue,
eNoAction,
eNoLiveAttr,
kGenericAccType,
kNoReqStates
},
{ // img
&nsGkAtoms::img,
roles::GRAPHIC,
kUseMapRole,
eNoValue,
eNoAction,
eNoLiveAttr,
kGenericAccType,
kNoReqStates
},
{ // key
&nsGkAtoms::key,
roles::KEY,
kUseMapRole,
eNoValue,
ePressAction,
eNoLiveAttr,
kGenericAccType,
kNoReqStates,
eARIAPressed
},
{ // link
&nsGkAtoms::link,
roles::LINK,
kUseMapRole,
eNoValue,
eJumpAction,
eNoLiveAttr,
kGenericAccType,
states::LINKED
},
{ // list
&nsGkAtoms::list,
roles::LIST,
kUseMapRole,
eNoValue,
eNoAction,
eNoLiveAttr,
eList,
states::READONLY
},
{ // listbox
&nsGkAtoms::listbox,
roles::LISTBOX,
kUseMapRole,
eNoValue,
eNoAction,
eNoLiveAttr,
eListControl | eSelect,
kNoReqStates,
eARIAMultiSelectable,
eARIAReadonly
},
{ // listitem
&nsGkAtoms::listitem,
roles::LISTITEM,
kUseMapRole,
eNoValue,
eNoAction, // XXX: should depend on state, parent accessible
eNoLiveAttr,
kGenericAccType,
states::READONLY
},
{ // log
&nsGkAtoms::log_,
roles::NOTHING,
kUseNativeRole,
eNoValue,
eNoAction,
ePoliteLiveAttr,
kGenericAccType,
kNoReqStates
},
{ // marquee
&nsGkAtoms::marquee,
roles::ANIMATION,
kUseMapRole,
eNoValue,
eNoAction,
eOffLiveAttr,
kGenericAccType,
kNoReqStates
},
{ // math
&nsGkAtoms::math,
roles::FLAT_EQUATION,
kUseMapRole,
eNoValue,
eNoAction,
eNoLiveAttr,
kGenericAccType,
kNoReqStates
},
{ // menu
&nsGkAtoms::menu,
roles::MENUPOPUP,
kUseMapRole,
eNoValue,
eNoAction, // XXX: technically accessibles of menupopup role haven't
// any action, but menu can be open or close.
eNoLiveAttr,
kGenericAccType,
kNoReqStates
},
{ // menubar
&nsGkAtoms::menubar,
roles::MENUBAR,
kUseMapRole,
eNoValue,
eNoAction,
eNoLiveAttr,
kGenericAccType,
kNoReqStates
},
{ // menuitem
&nsGkAtoms::menuitem,
roles::MENUITEM,
kUseMapRole,
eNoValue,
eClickAction,
eNoLiveAttr,
kGenericAccType,
kNoReqStates,
eARIACheckedMixed
},
{ // menuitemcheckbox
&nsGkAtoms::menuitemcheckbox,
roles::CHECK_MENU_ITEM,
kUseMapRole,
eNoValue,
eClickAction,
eNoLiveAttr,
kGenericAccType,
kNoReqStates,
eARIACheckableMixed
},
{ // menuitemradio
&nsGkAtoms::menuitemradio,
roles::RADIO_MENU_ITEM,
kUseMapRole,
eNoValue,
eClickAction,
eNoLiveAttr,
kGenericAccType,
kNoReqStates,
eARIACheckableBool
},
{ // note
&nsGkAtoms::note_,
roles::NOTE,
kUseMapRole,
eNoValue,
eNoAction,
eNoLiveAttr,
kGenericAccType,
kNoReqStates
},
{ // option
&nsGkAtoms::option,
roles::OPTION,
kUseMapRole,
eNoValue,
eSelectAction,
eNoLiveAttr,
kGenericAccType,
kNoReqStates,
eARIASelectable,
eARIACheckedMixed
},
{ // presentation
&nsGkAtoms::presentation,
roles::NOTHING,
kUseMapRole,
eNoValue,
eNoAction,
eNoLiveAttr,
kGenericAccType,
kNoReqStates
},
{ // progressbar
&nsGkAtoms::progressbar,
roles::PROGRESSBAR,
kUseMapRole,
eHasValueMinMax,
eNoAction,
eNoLiveAttr,
kGenericAccType,
states::READONLY,
eIndeterminateIfNoValue
},
{ // radio
&nsGkAtoms::radio,
roles::RADIOBUTTON,
kUseMapRole,
eNoValue,
eSelectAction,
eNoLiveAttr,
kGenericAccType,
kNoReqStates,
eARIACheckableBool
},
{ // radiogroup
&nsGkAtoms::radiogroup,
roles::GROUPING,
kUseMapRole,
eNoValue,
eNoAction,
eNoLiveAttr,
kGenericAccType,
kNoReqStates
},
{ // region
&nsGkAtoms::region,
roles::PANE,
kUseMapRole,
eNoValue,
eNoAction,
eNoLiveAttr,
kGenericAccType,
kNoReqStates
},
{ // row
&nsGkAtoms::row,
roles::ROW,
kUseMapRole,
eNoValue,
eNoAction,
eNoLiveAttr,
eTableRow,
kNoReqStates,
eARIASelectable
},
{ // rowgroup
&nsGkAtoms::rowgroup,
roles::GROUPING,
kUseMapRole,
eNoValue,
eNoAction,
eNoLiveAttr,
kGenericAccType,
kNoReqStates
},
{ // rowheader
&nsGkAtoms::rowheader,
roles::ROWHEADER,
kUseMapRole,
eNoValue,
eSortAction,
eNoLiveAttr,
eTableCell,
kNoReqStates,
eARIASelectable,
eARIAReadonlyOrEditableIfDefined
},
{ // scrollbar
&nsGkAtoms::scrollbar,
roles::SCROLLBAR,
kUseMapRole,
eHasValueMinMax,
eNoAction,
eNoLiveAttr,
kGenericAccType,
kNoReqStates,
eARIAOrientation,
eARIAReadonly
},
{ // separator
&nsGkAtoms::separator_,
roles::SEPARATOR,
kUseMapRole,
eNoValue,
eNoAction,
eNoLiveAttr,
kGenericAccType,
kNoReqStates,
eARIAOrientation
},
{ // slider
&nsGkAtoms::slider,
roles::SLIDER,
kUseMapRole,
eHasValueMinMax,
eNoAction,
eNoLiveAttr,
kGenericAccType,
kNoReqStates,
eARIAOrientation,
eARIAReadonly
},
{ // spinbutton
&nsGkAtoms::spinbutton,
roles::SPINBUTTON,
kUseMapRole,
eHasValueMinMax,
eNoAction,
eNoLiveAttr,
kGenericAccType,
kNoReqStates,
eARIAReadonly
},
{ // status
&nsGkAtoms::status,
roles::STATUSBAR,
kUseMapRole,
eNoValue,
eNoAction,
ePoliteLiveAttr,
kGenericAccType,
kNoReqStates
},
{ // tab
&nsGkAtoms::tab,
roles::PAGETAB,
kUseMapRole,
eNoValue,
eSwitchAction,
eNoLiveAttr,
kGenericAccType,
kNoReqStates,
eARIASelectable
},
{ // tablist
&nsGkAtoms::tablist,
roles::PAGETABLIST,
kUseMapRole,
eNoValue,
eNoAction,
ePoliteLiveAttr,
eSelect,
kNoReqStates
},
{ // tabpanel
&nsGkAtoms::tabpanel,
roles::PROPERTYPAGE,
kUseMapRole,
eNoValue,
eNoAction,
eNoLiveAttr,
kGenericAccType,
kNoReqStates
},
{ // textbox
&nsGkAtoms::textbox,
roles::ENTRY,
kUseMapRole,
eNoValue,
eActivateAction,
eNoLiveAttr,
kGenericAccType,
kNoReqStates,
eARIAAutoComplete,
eARIAMultiline,
eARIAReadonlyOrEditable
},
{ // timer
&nsGkAtoms::timer,
roles::NOTHING,
kUseNativeRole,
eNoValue,
eNoAction,
eOffLiveAttr,
kNoReqStates
},
{ // toolbar
&nsGkAtoms::toolbar,
roles::TOOLBAR,
kUseMapRole,
eNoValue,
eNoAction,
eNoLiveAttr,
kGenericAccType,
kNoReqStates
},
{ // tooltip
&nsGkAtoms::tooltip,
roles::TOOLTIP,
kUseMapRole,
eNoValue,
eNoAction,
eNoLiveAttr,
kGenericAccType,
kNoReqStates
},
{ // tree
&nsGkAtoms::tree,
roles::OUTLINE,
kUseMapRole,
eNoValue,
eNoAction,
eNoLiveAttr,
eSelect,
kNoReqStates,
eARIAReadonly,
eARIAMultiSelectable
},
{ // treegrid
&nsGkAtoms::treegrid,
roles::TREE_TABLE,
kUseMapRole,
eNoValue,
eNoAction,
eNoLiveAttr,
eSelect | eTable,
kNoReqStates,
eARIAReadonly,
eARIAMultiSelectable
},
{ // treeitem
&nsGkAtoms::treeitem,
roles::OUTLINEITEM,
kUseMapRole,
eNoValue,
eActivateAction, // XXX: should expose second 'expand/collapse' action based
// on states
eNoLiveAttr,
kGenericAccType,
kNoReqStates,
eARIASelectable,
eARIACheckedMixed
}
};
static nsRoleMapEntry sLandmarkRoleMap = {
&nsGkAtoms::_empty,
roles::NOTHING,
kUseNativeRole,
eNoValue,
eNoAction,
eNoLiveAttr,
kGenericAccType,
kNoReqStates
};
nsRoleMapEntry aria::gEmptyRoleMap = {
&nsGkAtoms::_empty,
roles::NOTHING,
kUseMapRole,
eNoValue,
eNoAction,
eNoLiveAttr,
kGenericAccType,
kNoReqStates
};
/**
* Universal (Global) states:
* The following state rules are applied to any accessible element,
* whether there is an ARIA role or not:
*/
static const EStateRule sWAIUnivStateMap[] = {
eARIABusy,
eARIADisabled,
eARIAExpanded, // Currently under spec review but precedent exists
eARIAHasPopup, // Note this is technically a "property"
eARIAInvalid,
eARIARequired, // XXX not global, Bug 553117
eARIANone
};
/**
* ARIA attribute map for attribute characteristics.
* @note ARIA attributes that don't have any flags are not included here.
*/
struct AttrCharacteristics
{
nsIAtom** attributeName;
const uint8_t characteristics;
};
static const AttrCharacteristics gWAIUnivAttrMap[] = {
{&nsGkAtoms::aria_activedescendant, ATTR_BYPASSOBJ },
{&nsGkAtoms::aria_atomic, ATTR_VALTOKEN | ATTR_GLOBAL },
{&nsGkAtoms::aria_busy, ATTR_VALTOKEN | ATTR_GLOBAL },
{&nsGkAtoms::aria_checked, ATTR_BYPASSOBJ | ATTR_VALTOKEN }, /* exposes checkable obj attr */
{&nsGkAtoms::aria_controls, ATTR_BYPASSOBJ | ATTR_GLOBAL },
{&nsGkAtoms::aria_describedby, ATTR_BYPASSOBJ | ATTR_GLOBAL },
{&nsGkAtoms::aria_disabled, ATTR_BYPASSOBJ | ATTR_VALTOKEN | ATTR_GLOBAL },
{&nsGkAtoms::aria_dropeffect, ATTR_VALTOKEN | ATTR_GLOBAL },
{&nsGkAtoms::aria_expanded, ATTR_BYPASSOBJ | ATTR_VALTOKEN },
{&nsGkAtoms::aria_flowto, ATTR_BYPASSOBJ | ATTR_GLOBAL },
{&nsGkAtoms::aria_grabbed, ATTR_VALTOKEN | ATTR_GLOBAL },
{&nsGkAtoms::aria_haspopup, ATTR_BYPASSOBJ | ATTR_VALTOKEN | ATTR_GLOBAL },
{&nsGkAtoms::aria_hidden, ATTR_BYPASSOBJ_IF_FALSE | ATTR_VALTOKEN | ATTR_GLOBAL },
{&nsGkAtoms::aria_invalid, ATTR_BYPASSOBJ | ATTR_VALTOKEN | ATTR_GLOBAL },
{&nsGkAtoms::aria_label, ATTR_BYPASSOBJ | ATTR_GLOBAL },
{&nsGkAtoms::aria_labelledby, ATTR_BYPASSOBJ | ATTR_GLOBAL },
{&nsGkAtoms::aria_level, ATTR_BYPASSOBJ }, /* handled via groupPosition */
{&nsGkAtoms::aria_live, ATTR_VALTOKEN | ATTR_GLOBAL },
{&nsGkAtoms::aria_multiline, ATTR_BYPASSOBJ | ATTR_VALTOKEN },
{&nsGkAtoms::aria_multiselectable, ATTR_BYPASSOBJ | ATTR_VALTOKEN },
{&nsGkAtoms::aria_owns, ATTR_BYPASSOBJ | ATTR_GLOBAL },
{&nsGkAtoms::aria_orientation, ATTR_VALTOKEN },
{&nsGkAtoms::aria_posinset, ATTR_BYPASSOBJ }, /* handled via groupPosition */
{&nsGkAtoms::aria_pressed, ATTR_BYPASSOBJ | ATTR_VALTOKEN },
{&nsGkAtoms::aria_readonly, ATTR_BYPASSOBJ | ATTR_VALTOKEN },
{&nsGkAtoms::aria_relevant, ATTR_BYPASSOBJ | ATTR_GLOBAL },
{&nsGkAtoms::aria_required, ATTR_BYPASSOBJ | ATTR_VALTOKEN },
{&nsGkAtoms::aria_selected, ATTR_BYPASSOBJ | ATTR_VALTOKEN },
{&nsGkAtoms::aria_setsize, ATTR_BYPASSOBJ }, /* handled via groupPosition */
{&nsGkAtoms::aria_sort, ATTR_VALTOKEN },
{&nsGkAtoms::aria_valuenow, ATTR_BYPASSOBJ },
{&nsGkAtoms::aria_valuemin, ATTR_BYPASSOBJ },
{&nsGkAtoms::aria_valuemax, ATTR_BYPASSOBJ },
{&nsGkAtoms::aria_valuetext, ATTR_BYPASSOBJ }
};
nsRoleMapEntry*
aria::GetRoleMap(nsINode* aNode)
{
nsIContent* content = nsCoreUtils::GetRoleContent(aNode);
nsAutoString roles;
if (!content ||
!content->GetAttr(kNameSpaceID_None, nsGkAtoms::role, roles) ||
roles.IsEmpty()) {
// We treat role="" as if the role attribute is absent (per aria spec:8.1.1)
return nullptr;
}
nsWhitespaceTokenizer tokenizer(roles);
while (tokenizer.hasMoreTokens()) {
// Do a binary search through table for the next role in role list
const nsDependentSubstring role = tokenizer.nextToken();
uint32_t low = 0;
uint32_t high = ArrayLength(sWAIRoleMaps);
while (low < high) {
uint32_t idx = (low + high) / 2;
int32_t compare = Compare(role, sWAIRoleMaps[idx].ARIARoleString());
if (compare == 0)
return sWAIRoleMaps + idx;
if (compare < 0)
high = idx;
else
low = idx + 1;
}
}
// Always use some entry if there is a non-empty role string
// To ensure an accessible object is created
return &sLandmarkRoleMap;
}
uint64_t
aria::UniversalStatesFor(mozilla::dom::Element* aElement)
{
uint64_t state = 0;
uint32_t index = 0;
while (MapToState(sWAIUnivStateMap[index], aElement, &state))
index++;
return state;
}
uint8_t
aria::AttrCharacteristicsFor(nsIAtom* aAtom)
{
for (uint32_t i = 0; i < ArrayLength(gWAIUnivAttrMap); i++)
if (*gWAIUnivAttrMap[i].attributeName == aAtom)
return gWAIUnivAttrMap[i].characteristics;
return 0;
}
////////////////////////////////////////////////////////////////////////////////
// AttrIterator class
bool
AttrIterator::Next(nsAString& aAttrName, nsAString& aAttrValue)
{
while (mAttrIdx < mAttrCount) {
const nsAttrName* attr = mContent->GetAttrNameAt(mAttrIdx);
mAttrIdx++;
if (attr->NamespaceEquals(kNameSpaceID_None)) {
nsIAtom* attrAtom = attr->Atom();
nsDependentAtomString attrStr(attrAtom);
if (!StringBeginsWith(attrStr, NS_LITERAL_STRING("aria-")))
continue; // Not ARIA
uint8_t attrFlags = aria::AttrCharacteristicsFor(attrAtom);
if (attrFlags & ATTR_BYPASSOBJ)
continue; // No need to handle exposing as obj attribute here
if ((attrFlags & ATTR_VALTOKEN) &&
!nsAccUtils::HasDefinedARIAToken(mContent, attrAtom))
continue; // only expose token based attributes if they are defined
if ((attrFlags & ATTR_BYPASSOBJ_IF_FALSE) &&
mContent->AttrValueIs(kNameSpaceID_None, attrAtom,
nsGkAtoms::_false, eCaseMatters)) {
continue; // only expose token based attribute if value is not 'false'.
}
nsAutoString value;
if (mContent->GetAttr(kNameSpaceID_None, attrAtom, value)) {
aAttrName.Assign(Substring(attrStr, 5));
aAttrValue.Assign(value);
return true;
}
}
}
return false;
}
+258
View File
@@ -0,0 +1,258 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim:expandtab:shiftwidth=2:tabstop=2:
*/
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef mozilla_a11y_aria_ARIAMap_h_
#define mozilla_a11y_aria_ARIAMap_h_
#include "ARIAStateMap.h"
#include "mozilla/a11y/AccTypes.h"
#include "mozilla/a11y/Role.h"
#include "nsIAtom.h"
#include "nsIContent.h"
class nsINode;
////////////////////////////////////////////////////////////////////////////////
// Value constants
/**
* Used to define if role requires to expose nsIAccessibleValue.
*/
enum EValueRule
{
/**
* nsIAccessibleValue isn't exposed.
*/
eNoValue,
/**
* nsIAccessibleValue is implemented, supports value, min and max from
* aria-valuenow, aria-valuemin and aria-valuemax.
*/
eHasValueMinMax
};
////////////////////////////////////////////////////////////////////////////////
// Action constants
/**
* Used to define if the role requires to expose action.
*/
enum EActionRule
{
eNoAction,
eActivateAction,
eClickAction,
ePressAction,
eCheckUncheckAction,
eExpandAction,
eJumpAction,
eOpenCloseAction,
eSelectAction,
eSortAction,
eSwitchAction
};
////////////////////////////////////////////////////////////////////////////////
// Live region constants
/**
* Used to define if role exposes default value of aria-live attribute.
*/
enum ELiveAttrRule
{
eNoLiveAttr,
eOffLiveAttr,
ePoliteLiveAttr
};
////////////////////////////////////////////////////////////////////////////////
// Role constants
/**
* ARIA role overrides role from native markup.
*/
const bool kUseMapRole = true;
/**
* ARIA role doesn't override the role from native markup.
*/
const bool kUseNativeRole = false;
////////////////////////////////////////////////////////////////////////////////
// ARIA attribute characteristic masks
/**
* This mask indicates the attribute should not be exposed as an object
* attribute via the catch-all logic in Accessible::Attributes().
* This means it either isn't mean't to be exposed as an object attribute, or
* that it should, but is already handled in other code.
*/
const uint8_t ATTR_BYPASSOBJ = 0x1 << 0;
const uint8_t ATTR_BYPASSOBJ_IF_FALSE = 0x1 << 1;
/**
* This mask indicates the attribute is expected to have an NMTOKEN or bool value.
* (See for example usage in Accessible::Attributes())
*/
const uint8_t ATTR_VALTOKEN = 0x1 << 2;
/**
* Indicate the attribute is global state or property (refer to
* http://www.w3.org/TR/wai-aria/states_and_properties#global_states).
*/
const uint8_t ATTR_GLOBAL = 0x1 << 3;
////////////////////////////////////////////////////////////////////////////////
// State map entry
/**
* Used in nsRoleMapEntry.state if no nsIAccessibleStates are automatic for
* a given role.
*/
#define kNoReqStates 0
////////////////////////////////////////////////////////////////////////////////
// Role map entry
/**
* For each ARIA role, this maps the nsIAccessible information.
*/
struct nsRoleMapEntry
{
/**
* Return true if matches to the given ARIA role.
*/
bool Is(nsIAtom* aARIARole) const
{ return *roleAtom == aARIARole; }
/**
* Return true if ARIA role has the given accessible type.
*/
bool IsOfType(mozilla::a11y::AccGenericType aType) const
{ return accTypes & aType; }
/**
* Return ARIA role.
*/
const nsDependentAtomString ARIARoleString() const
{ return nsDependentAtomString(*roleAtom); }
// ARIA role: string representation such as "button"
nsIAtom** roleAtom;
// Role mapping rule: maps to this nsIAccessibleRole
mozilla::a11y::role role;
// Role rule: whether to use mapped role or native semantics
bool roleRule;
// Value mapping rule: how to compute nsIAccessible value
EValueRule valueRule;
// Action mapping rule, how to expose nsIAccessible action
EActionRule actionRule;
// 'live' and 'container-live' object attributes mapping rule: how to expose
// these object attributes if ARIA 'live' attribute is missed.
ELiveAttrRule liveAttRule;
// Accessible types this role belongs to.
uint32_t accTypes;
// Automatic state mapping rule: always include in nsIAccessibleStates
uint64_t state; // or kNoReqStates if no nsIAccessibleStates are automatic for this role.
// ARIA properties supported for this role
// (in other words, the aria-foo attribute to nsIAccessibleStates mapping rules)
// Currently you cannot have unlimited mappings, because
// a variable sized array would not allow the use of
// C++'s struct initialization feature.
mozilla::a11y::aria::EStateRule attributeMap1;
mozilla::a11y::aria::EStateRule attributeMap2;
mozilla::a11y::aria::EStateRule attributeMap3;
};
////////////////////////////////////////////////////////////////////////////////
// ARIA map
/**
* These provide the mappings for WAI-ARIA roles, states and properties using
* the structs defined in this file and ARIAStateMap files.
*/
namespace mozilla {
namespace a11y {
namespace aria {
/**
* Empty role map entry. Used by accessibility service to create an accessible
* if the accessible can't use role of used accessible class. For example,
* it is used for table cells that aren't contained by table.
*/
extern nsRoleMapEntry gEmptyRoleMap;
/**
* Get the role map entry for a given DOM node. This will use the first
* ARIA role if the role attribute provides a space delimited list of roles.
*
* @param aNode [in] the DOM node to get the role map entry for
* @return a pointer to the role map entry for the ARIA role, or nullptr
* if none
*/
nsRoleMapEntry* GetRoleMap(nsINode* aNode);
/**
* Return accessible state from ARIA universal states applied to the given
* element.
*/
uint64_t UniversalStatesFor(mozilla::dom::Element* aElement);
/**
* Get the ARIA attribute characteristics for a given ARIA attribute.
*
* @param aAtom ARIA attribute
* @return A bitflag representing the attribute characteristics
* (see above for possible bit masks, prefixed "ATTR_")
*/
uint8_t AttrCharacteristicsFor(nsIAtom* aAtom);
/**
* Represents a simple enumerator for iterating through ARIA attributes
* exposed as object attributes on a given accessible.
*/
class AttrIterator
{
public:
AttrIterator(nsIContent* aContent) :
mContent(aContent), mAttrIdx(0)
{
mAttrCount = mContent->GetAttrCount();
}
bool Next(nsAString& aAttrName, nsAString& aAttrValue);
private:
AttrIterator() MOZ_DELETE;
AttrIterator(const AttrIterator&) MOZ_DELETE;
AttrIterator& operator= (const AttrIterator&) MOZ_DELETE;
nsIContent* mContent;
uint32_t mAttrIdx;
uint32_t mAttrCount;
};
} // namespace aria
} // namespace a11y
} // namespace mozilla
#endif
+373
View File
@@ -0,0 +1,373 @@
/* -*- 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 "ARIAMap.h"
#include "States.h"
#include "mozilla/dom/Element.h"
using namespace mozilla;
using namespace mozilla::a11y;
using namespace mozilla::a11y::aria;
/**
* Used to store state map rule data for ARIA attribute of enum type.
*/
struct EnumTypeData
{
EnumTypeData(nsIAtom* aAttrName,
nsIAtom** aValue1, uint64_t aState1,
nsIAtom** aValue2, uint64_t aState2,
nsIAtom** aValue3 = 0, uint64_t aState3 = 0) :
mState1(aState1), mState2(aState2), mState3(aState3), mDefaultState(0),
mAttrName(aAttrName), mValue1(aValue1), mValue2(aValue2), mValue3(aValue3),
mNullValue(nullptr)
{ }
EnumTypeData(nsIAtom* aAttrName, uint64_t aDefaultState,
nsIAtom** aValue1, uint64_t aState1) :
mState1(aState1), mState2(0), mState3(0), mDefaultState(aDefaultState),
mAttrName(aAttrName), mValue1(aValue1), mValue2(nullptr), mValue3(nullptr),
mNullValue(nullptr)
{ }
// States applied if corresponding enum values are matched.
const uint64_t mState1;
const uint64_t mState2;
const uint64_t mState3;
// Default state if no one enum value is matched.
const uint64_t mDefaultState;
// ARIA attribute name.
nsIAtom* const mAttrName;
// States if the attribute value is matched to the enum value. Used as
// nsIContent::AttrValuesArray.
nsIAtom* const* const mValue1;
nsIAtom* const* const mValue2;
nsIAtom* const* const mValue3;
nsIAtom* const* const mNullValue;
};
enum ETokenType
{
eBoolType = 0,
eMixedType = 1, // can take 'mixed' value
eDefinedIfAbsent = 2 // permanent and false state are applied if absent
};
/**
* Used to store state map rule data for ARIA attribute of token type (including
* mixed value).
*/
struct TokenTypeData
{
TokenTypeData(nsIAtom* aAttrName, uint32_t aType,
uint64_t aPermanentState,
uint64_t aTrueState,
uint64_t aFalseState = 0) :
mAttrName(aAttrName), mType(aType), mPermanentState(aPermanentState),
mTrueState(aTrueState), mFalseState(aFalseState)
{ }
// ARIA attribute name.
nsIAtom* const mAttrName;
// Type.
const uint32_t mType;
// State applied if the attribute is defined or mType doesn't have
// eDefinedIfAbsent flag set.
const uint64_t mPermanentState;
// States applied if the attribute value is true/false.
const uint64_t mTrueState;
const uint64_t mFalseState;
};
/**
* Map enum type attribute value to accessible state.
*/
static void MapEnumType(dom::Element* aElement, uint64_t* aState,
const EnumTypeData& aData);
/**
* Map token type attribute value to states.
*/
static void MapTokenType(dom::Element* aContent, uint64_t* aState,
const TokenTypeData& aData);
bool
aria::MapToState(EStateRule aRule, dom::Element* aElement, uint64_t* aState)
{
switch (aRule) {
case eARIAAutoComplete:
{
static const EnumTypeData data(
nsGkAtoms::aria_autocomplete,
&nsGkAtoms::inlinevalue, states::SUPPORTS_AUTOCOMPLETION,
&nsGkAtoms::list, states::HASPOPUP | states::SUPPORTS_AUTOCOMPLETION,
&nsGkAtoms::both, states::HASPOPUP | states::SUPPORTS_AUTOCOMPLETION);
MapEnumType(aElement, aState, data);
return true;
}
case eARIABusy:
{
static const EnumTypeData data(
nsGkAtoms::aria_busy,
&nsGkAtoms::_true, states::BUSY,
&nsGkAtoms::error, states::INVALID);
MapEnumType(aElement, aState, data);
return true;
}
case eARIACheckableBool:
{
static const TokenTypeData data(
nsGkAtoms::aria_checked, eBoolType | eDefinedIfAbsent,
states::CHECKABLE, states::CHECKED);
MapTokenType(aElement, aState, data);
return true;
}
case eARIACheckableMixed:
{
static const TokenTypeData data(
nsGkAtoms::aria_checked, eMixedType | eDefinedIfAbsent,
states::CHECKABLE, states::CHECKED);
MapTokenType(aElement, aState, data);
return true;
}
case eARIACheckedMixed:
{
static const TokenTypeData data(
nsGkAtoms::aria_checked, eMixedType,
states::CHECKABLE, states::CHECKED);
MapTokenType(aElement, aState, data);
return true;
}
case eARIADisabled:
{
static const TokenTypeData data(
nsGkAtoms::aria_disabled, eBoolType,
0, states::UNAVAILABLE);
MapTokenType(aElement, aState, data);
return true;
}
case eARIAExpanded:
{
static const TokenTypeData data(
nsGkAtoms::aria_expanded, eBoolType,
0, states::EXPANDED, states::COLLAPSED);
MapTokenType(aElement, aState, data);
return true;
}
case eARIAHasPopup:
{
static const TokenTypeData data(
nsGkAtoms::aria_haspopup, eBoolType,
0, states::HASPOPUP);
MapTokenType(aElement, aState, data);
return true;
}
case eARIAInvalid:
{
static const TokenTypeData data(
nsGkAtoms::aria_invalid, eBoolType,
0, states::INVALID);
MapTokenType(aElement, aState, data);
return true;
}
case eARIAMultiline:
{
static const TokenTypeData data(
nsGkAtoms::aria_multiline, eBoolType | eDefinedIfAbsent,
0, states::MULTI_LINE, states::SINGLE_LINE);
MapTokenType(aElement, aState, data);
return true;
}
case eARIAMultiSelectable:
{
static const TokenTypeData data(
nsGkAtoms::aria_multiselectable, eBoolType,
0, states::MULTISELECTABLE | states::EXTSELECTABLE);
MapTokenType(aElement, aState, data);
return true;
}
case eARIAOrientation:
{
if (aElement->AttrValueIs(kNameSpaceID_None, nsGkAtoms::aria_orientation,
NS_LITERAL_STRING("horizontal"), eCaseMatters)) {
*aState &= ~states::VERTICAL;
*aState |= states::HORIZONTAL;
} else if (aElement->AttrValueIs(kNameSpaceID_None,
nsGkAtoms::aria_orientation,
NS_LITERAL_STRING("vertical"),
eCaseMatters)) {
*aState &= ~states::HORIZONTAL;
*aState |= states::VERTICAL;
} else {
NS_ASSERTION(!(*aState & (states::HORIZONTAL | states::VERTICAL)),
"orientation state on role with default aria-orientation!");
*aState |= GetRoleMap(aElement)->Is(nsGkAtoms::scrollbar) ?
states::VERTICAL : states::HORIZONTAL;
}
return true;
}
case eARIAPressed:
{
static const TokenTypeData data(
nsGkAtoms::aria_pressed, eMixedType,
states::CHECKABLE, states::PRESSED);
MapTokenType(aElement, aState, data);
return true;
}
case eARIAReadonly:
{
static const TokenTypeData data(
nsGkAtoms::aria_readonly, eBoolType,
0, states::READONLY);
MapTokenType(aElement, aState, data);
return true;
}
case eARIAReadonlyOrEditable:
{
static const TokenTypeData data(
nsGkAtoms::aria_readonly, eBoolType | eDefinedIfAbsent,
0, states::READONLY, states::EDITABLE);
MapTokenType(aElement, aState, data);
return true;
}
case eARIAReadonlyOrEditableIfDefined:
{
static const TokenTypeData data(
nsGkAtoms::aria_readonly, eBoolType,
0, states::READONLY, states::EDITABLE);
MapTokenType(aElement, aState, data);
return true;
}
case eARIARequired:
{
static const TokenTypeData data(
nsGkAtoms::aria_required, eBoolType,
0, states::REQUIRED);
MapTokenType(aElement, aState, data);
return true;
}
case eARIASelectable:
{
static const TokenTypeData data(
nsGkAtoms::aria_selected, eBoolType | eDefinedIfAbsent,
states::SELECTABLE, states::SELECTED);
MapTokenType(aElement, aState, data);
return true;
}
case eReadonlyUntilEditable:
{
if (!(*aState & states::EDITABLE))
*aState |= states::READONLY;
return true;
}
case eIndeterminateIfNoValue:
{
if (!aElement->HasAttr(kNameSpaceID_None, nsGkAtoms::aria_valuenow) &&
!aElement->HasAttr(kNameSpaceID_None, nsGkAtoms::aria_valuetext))
*aState |= states::MIXED;
return true;
}
default:
return false;
}
}
static void
MapEnumType(dom::Element* aElement, uint64_t* aState, const EnumTypeData& aData)
{
switch (aElement->FindAttrValueIn(kNameSpaceID_None, aData.mAttrName,
&aData.mValue1, eCaseMatters)) {
case 0:
*aState |= aData.mState1;
return;
case 1:
*aState |= aData.mState2;
return;
case 2:
*aState |= aData.mState3;
return;
}
*aState |= aData.mDefaultState;
}
static void
MapTokenType(dom::Element* aElement, uint64_t* aState,
const TokenTypeData& aData)
{
if (aElement->HasAttr(kNameSpaceID_None, aData.mAttrName)) {
if ((aData.mType & eMixedType) &&
aElement->AttrValueIs(kNameSpaceID_None, aData.mAttrName,
nsGkAtoms::mixed, eCaseMatters)) {
*aState |= aData.mPermanentState | states::MIXED;
return;
}
if (aElement->AttrValueIs(kNameSpaceID_None, aData.mAttrName,
nsGkAtoms::_false, eCaseMatters)) {
*aState |= aData.mPermanentState | aData.mFalseState;
return;
}
if (!aElement->AttrValueIs(kNameSpaceID_None, aData.mAttrName,
nsGkAtoms::_undefined, eCaseMatters) &&
!aElement->AttrValueIs(kNameSpaceID_None, aData.mAttrName,
nsGkAtoms::_empty, eCaseMatters)) {
*aState |= aData.mPermanentState | aData.mTrueState;
}
return;
}
if (aData.mType & eDefinedIfAbsent)
*aState |= aData.mPermanentState | aData.mFalseState;
}
+64
View File
@@ -0,0 +1,64 @@
/* -*- 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_aria_ARIAStateMap_h_
#define _mozilla_a11y_aria_ARIAStateMap_h_
#include "mozilla/StandardInteger.h"
namespace mozilla {
namespace dom {
class Element;
}
namespace a11y {
namespace aria {
/**
* List of the ARIA state mapping rules.
*/
enum EStateRule
{
eARIANone,
eARIAAutoComplete,
eARIABusy,
eARIACheckableBool,
eARIACheckableMixed,
eARIACheckedMixed,
eARIADisabled,
eARIAExpanded,
eARIAHasPopup,
eARIAInvalid,
eARIAMultiline,
eARIAMultiSelectable,
eARIAOrientation,
eARIAPressed,
eARIAReadonly,
eARIAReadonlyOrEditable,
eARIAReadonlyOrEditableIfDefined,
eARIARequired,
eARIASelectable,
eReadonlyUntilEditable,
eIndeterminateIfNoValue
};
/**
* Expose the accessible states for the given element accordingly to state
* mapping rule.
*
* @param aRule [in] state mapping rule ID
* @param aElement [in] node of the accessible
* @param aState [in/out] accessible states
* @return true if state map rule ID is valid
*/
bool MapToState(EStateRule aRule, dom::Element* aElement, uint64_t* aState);
} // namespace aria
} // namespace a11y
} // namespace mozilla
#endif
+117
View File
@@ -0,0 +1,117 @@
/* 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 "AccCollector.h"
#include "Accessible.h"
using namespace mozilla::a11y;
////////////////////////////////////////////////////////////////////////////////
// nsAccCollector
////////////////////////////////////////////////////////////////////////////////
AccCollector::
AccCollector(Accessible* aRoot, filters::FilterFuncPtr aFilterFunc) :
mFilterFunc(aFilterFunc), mRoot(aRoot), mRootChildIdx(0)
{
}
AccCollector::~AccCollector()
{
}
uint32_t
AccCollector::Count()
{
EnsureNGetIndex(nullptr);
return mObjects.Length();
}
Accessible*
AccCollector::GetAccessibleAt(uint32_t aIndex)
{
Accessible* accessible = mObjects.SafeElementAt(aIndex, nullptr);
if (accessible)
return accessible;
return EnsureNGetObject(aIndex);
}
int32_t
AccCollector::GetIndexAt(Accessible* aAccessible)
{
int32_t index = mObjects.IndexOf(aAccessible);
if (index != -1)
return index;
return EnsureNGetIndex(aAccessible);
}
////////////////////////////////////////////////////////////////////////////////
// nsAccCollector protected
Accessible*
AccCollector::EnsureNGetObject(uint32_t aIndex)
{
uint32_t childCount = mRoot->ChildCount();
while (mRootChildIdx < childCount) {
Accessible* child = mRoot->GetChildAt(mRootChildIdx++);
if (!(mFilterFunc(child) & filters::eMatch))
continue;
AppendObject(child);
if (mObjects.Length() - 1 == aIndex)
return mObjects[aIndex];
}
return nullptr;
}
int32_t
AccCollector::EnsureNGetIndex(Accessible* aAccessible)
{
uint32_t childCount = mRoot->ChildCount();
while (mRootChildIdx < childCount) {
Accessible* child = mRoot->GetChildAt(mRootChildIdx++);
if (!(mFilterFunc(child) & filters::eMatch))
continue;
AppendObject(child);
if (child == aAccessible)
return mObjects.Length() - 1;
}
return -1;
}
void
AccCollector::AppendObject(Accessible* aAccessible)
{
mObjects.AppendElement(aAccessible);
}
////////////////////////////////////////////////////////////////////////////////
// EmbeddedObjCollector
////////////////////////////////////////////////////////////////////////////////
int32_t
EmbeddedObjCollector::GetIndexAt(Accessible* aAccessible)
{
if (aAccessible->mParent != mRoot)
return -1;
if (aAccessible->mIndexOfEmbeddedChild != -1)
return aAccessible->mIndexOfEmbeddedChild;
return mFilterFunc(aAccessible) & filters::eMatch ?
EnsureNGetIndex(aAccessible) : -1;
}
void
EmbeddedObjCollector::AppendObject(Accessible* aAccessible)
{
aAccessible->mIndexOfEmbeddedChild = mObjects.Length();
mObjects.AppendElement(aAccessible);
}
+95
View File
@@ -0,0 +1,95 @@
/* 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_AccCollector_h__
#define mozilla_a11y_AccCollector_h__
#include "Filters.h"
#include "nsTArray.h"
namespace mozilla {
namespace a11y {
class Accessible;
/**
* Collect accessible children complying with filter function. Provides quick
* access to accessible by index.
*/
class AccCollector
{
public:
AccCollector(Accessible* aRoot, filters::FilterFuncPtr aFilterFunc);
virtual ~AccCollector();
/**
* Return accessible count within the collection.
*/
uint32_t Count();
/**
* Return an accessible from the collection at the given index.
*/
Accessible* GetAccessibleAt(uint32_t aIndex);
/**
* Return index of the given accessible within the collection.
*/
virtual int32_t GetIndexAt(Accessible* aAccessible);
protected:
/**
* Ensure accessible at the given index is stored and return it.
*/
Accessible* EnsureNGetObject(uint32_t aIndex);
/**
* Ensure index for the given accessible is stored and return it.
*/
int32_t EnsureNGetIndex(Accessible* aAccessible);
/**
* Append the object to collection.
*/
virtual void AppendObject(Accessible* aAccessible);
filters::FilterFuncPtr mFilterFunc;
Accessible* mRoot;
uint32_t mRootChildIdx;
nsTArray<Accessible*> mObjects;
private:
AccCollector();
AccCollector(const AccCollector&);
AccCollector& operator =(const AccCollector&);
};
/**
* Collect embedded objects. Provide quick access to accessible by index and
* vice versa.
*/
class EmbeddedObjCollector : public AccCollector
{
public:
virtual ~EmbeddedObjCollector() { }
public:
virtual int32_t GetIndexAt(Accessible* aAccessible);
protected:
// Make sure it's used by Accessible class only.
EmbeddedObjCollector(Accessible* aRoot) :
AccCollector(aRoot, filters::GetEmbeddedObject) { }
virtual void AppendObject(Accessible* aAccessible);
friend class Accessible;
};
} // namespace a11y
} // namespace mozilla
#endif
+236
View File
@@ -0,0 +1,236 @@
/* -*- 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 "AccEvent.h"
#include "ApplicationAccessibleWrap.h"
#include "nsAccessibilityService.h"
#include "nsAccUtils.h"
#include "DocAccessible.h"
#include "nsIAccessibleText.h"
#include "xpcAccEvents.h"
#include "States.h"
#include "nsEventStateManager.h"
#include "nsIServiceManager.h"
#ifdef MOZ_XUL
#include "nsIDOMXULMultSelectCntrlEl.h"
#endif
using namespace mozilla;
using namespace mozilla::a11y;
////////////////////////////////////////////////////////////////////////////////
// AccEvent
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
// AccEvent constructors
AccEvent::AccEvent(uint32_t aEventType, Accessible* aAccessible,
EIsFromUserInput aIsFromUserInput, EEventRule aEventRule) :
mEventType(aEventType), mEventRule(aEventRule), mAccessible(aAccessible)
{
if (aIsFromUserInput == eAutoDetect)
mIsFromUserInput = nsEventStateManager::IsHandlingUserInput();
else
mIsFromUserInput = aIsFromUserInput == eFromUserInput ? true : false;
}
////////////////////////////////////////////////////////////////////////////////
// AccEvent cycle collection
NS_IMPL_CYCLE_COLLECTION_1(AccEvent, mAccessible)
NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(AccEvent, AddRef)
NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(AccEvent, Release)
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
// AccTextChangeEvent
////////////////////////////////////////////////////////////////////////////////
// Note: we pass in eAllowDupes to the base class because we don't support text
// events coalescence. We fire delayed text change events in DocAccessible but
// we continue to base the event off the accessible object rather than just the
// node. This means we won't try to create an accessible based on the node when
// we are ready to fire the event and so we will no longer assert at that point
// if the node was removed from the document. Either way, the AT won't work with
// a defunct accessible so the behaviour should be equivalent.
AccTextChangeEvent::
AccTextChangeEvent(Accessible* aAccessible, int32_t aStart,
const nsAString& aModifiedText, bool aIsInserted,
EIsFromUserInput aIsFromUserInput)
: AccEvent(aIsInserted ?
static_cast<uint32_t>(nsIAccessibleEvent::EVENT_TEXT_INSERTED) :
static_cast<uint32_t>(nsIAccessibleEvent::EVENT_TEXT_REMOVED),
aAccessible, aIsFromUserInput, eAllowDupes)
, mStart(aStart)
, mIsInserted(aIsInserted)
, mModifiedText(aModifiedText)
{
// XXX We should use IsFromUserInput here, but that isn't always correct
// when the text change isn't related to content insertion or removal.
mIsFromUserInput = mAccessible->State() &
(states::FOCUSED | states::EDITABLE);
}
////////////////////////////////////////////////////////////////////////////////
// AccReorderEvent
////////////////////////////////////////////////////////////////////////////////
uint32_t
AccReorderEvent::IsShowHideEventTarget(const Accessible* aTarget) const
{
uint32_t count = mDependentEvents.Length();
for (uint32_t index = count - 1; index < count; index--) {
if (mDependentEvents[index]->mAccessible == aTarget) {
uint32_t eventType = mDependentEvents[index]->mEventType;
if (eventType == nsIAccessibleEvent::EVENT_SHOW ||
eventType == nsIAccessibleEvent::EVENT_HIDE) {
return mDependentEvents[index]->mEventType;
}
}
}
return 0;
}
////////////////////////////////////////////////////////////////////////////////
// AccHideEvent
////////////////////////////////////////////////////////////////////////////////
AccHideEvent::
AccHideEvent(Accessible* aTarget, nsINode* aTargetNode) :
AccMutationEvent(::nsIAccessibleEvent::EVENT_HIDE, aTarget, aTargetNode)
{
mNextSibling = mAccessible->NextSibling();
mPrevSibling = mAccessible->PrevSibling();
}
////////////////////////////////////////////////////////////////////////////////
// AccShowEvent
////////////////////////////////////////////////////////////////////////////////
AccShowEvent::
AccShowEvent(Accessible* aTarget, nsINode* aTargetNode) :
AccMutationEvent(::nsIAccessibleEvent::EVENT_SHOW, aTarget, aTargetNode)
{
}
////////////////////////////////////////////////////////////////////////////////
// AccSelChangeEvent
////////////////////////////////////////////////////////////////////////////////
AccSelChangeEvent::
AccSelChangeEvent(Accessible* aWidget, Accessible* aItem,
SelChangeType aSelChangeType) :
AccEvent(0, aItem, eAutoDetect, eCoalesceSelectionChange),
mWidget(aWidget), mItem(aItem), mSelChangeType(aSelChangeType),
mPreceedingCount(0), mPackedEvent(nullptr)
{
if (aSelChangeType == eSelectionAdd) {
if (mWidget->GetSelectedItem(1))
mEventType = nsIAccessibleEvent::EVENT_SELECTION_ADD;
else
mEventType = nsIAccessibleEvent::EVENT_SELECTION;
} else {
mEventType = nsIAccessibleEvent::EVENT_SELECTION_REMOVE;
}
}
////////////////////////////////////////////////////////////////////////////////
// AccTableChangeEvent
////////////////////////////////////////////////////////////////////////////////
AccTableChangeEvent::
AccTableChangeEvent(Accessible* aAccessible, uint32_t aEventType,
int32_t aRowOrColIndex, int32_t aNumRowsOrCols) :
AccEvent(aEventType, aAccessible),
mRowOrColIndex(aRowOrColIndex), mNumRowsOrCols(aNumRowsOrCols)
{
}
////////////////////////////////////////////////////////////////////////////////
// AccVCChangeEvent
////////////////////////////////////////////////////////////////////////////////
AccVCChangeEvent::
AccVCChangeEvent(Accessible* aAccessible,
nsIAccessible* aOldAccessible,
int32_t aOldStart, int32_t aOldEnd,
int16_t aReason) :
AccEvent(::nsIAccessibleEvent::EVENT_VIRTUALCURSOR_CHANGED, aAccessible),
mOldAccessible(aOldAccessible), mOldStart(aOldStart), mOldEnd(aOldEnd),
mReason(aReason)
{
}
already_AddRefed<nsIAccessibleEvent>
a11y::MakeXPCEvent(AccEvent* aEvent)
{
DocAccessible* doc = aEvent->GetDocAccessible();
Accessible* acc = aEvent->GetAccessible();
nsINode* node = acc->GetNode();
nsIDOMNode* domNode = node ? node->AsDOMNode() : nullptr;
bool fromUser = aEvent->IsFromUserInput();
uint32_t type = aEvent->GetEventType();
uint32_t eventGroup = aEvent->GetEventGroups();
nsCOMPtr<nsIAccessibleEvent> xpEvent;
if (eventGroup & (1 << AccEvent::eStateChangeEvent)) {
AccStateChangeEvent* sc = downcast_accEvent(aEvent);
bool extra = false;
uint32_t state = nsAccUtils::To32States(sc->GetState(), &extra);
xpEvent = new xpcAccStateChangeEvent(type, acc, doc, domNode, fromUser,
state, extra, sc->IsStateEnabled());
return xpEvent.forget();
}
if (eventGroup & (1 << AccEvent::eTextChangeEvent)) {
AccTextChangeEvent* tc = downcast_accEvent(aEvent);
nsString text;
tc->GetModifiedText(text);
xpEvent = new xpcAccTextChangeEvent(type, acc, doc, domNode, fromUser,
tc->GetStartOffset(), tc->GetLength(),
tc->IsTextInserted(), text);
return xpEvent.forget();
}
if (eventGroup & (1 << AccEvent::eHideEvent)) {
AccHideEvent* hideEvent = downcast_accEvent(aEvent);
xpEvent = new xpcAccHideEvent(type, acc, doc, domNode, fromUser,
hideEvent->TargetParent(),
hideEvent->TargetNextSibling(),
hideEvent->TargetPrevSibling());
return xpEvent.forget();
}
if (eventGroup & (1 << AccEvent::eCaretMoveEvent)) {
AccCaretMoveEvent* cm = downcast_accEvent(aEvent);
xpEvent = new xpcAccCaretMoveEvent(type, acc, doc, domNode, fromUser,
cm->GetCaretOffset());
return xpEvent.forget();
}
if (eventGroup & (1 << AccEvent::eVirtualCursorChangeEvent)) {
AccVCChangeEvent* vcc = downcast_accEvent(aEvent);
xpEvent = new xpcAccVirtualCursorChangeEvent(type, acc, doc, domNode, fromUser,
vcc->OldAccessible(),
vcc->OldStartOffset(),
vcc->OldEndOffset(),
vcc->Reason());
return xpEvent.forget();
}
xpEvent = new xpcAccEvent(type, acc, doc, domNode, fromUser);
return xpEvent.forget();
}
+481
View File
@@ -0,0 +1,481 @@
/* -*- 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 _AccEvent_H_
#define _AccEvent_H_
#include "nsIAccessibleEvent.h"
#include "mozilla/a11y/Accessible.h"
namespace mozilla {
namespace a11y {
class DocAccessible;
// Constants used to point whether the event is from user input.
enum EIsFromUserInput
{
// eNoUserInput: event is not from user input
eNoUserInput = 0,
// eFromUserInput: event is from user input
eFromUserInput = 1,
// eAutoDetect: the value should be obtained from event state manager
eAutoDetect = -1
};
/**
* Generic accessible event.
*/
class AccEvent
{
public:
// Rule for accessible events.
// The rule will be applied when flushing pending events.
enum EEventRule {
// eAllowDupes : More than one event of the same type is allowed.
// This event will always be emitted. This flag is used for events that
// don't support coalescence.
eAllowDupes,
// eCoalesceReorder : For reorder events from the same subtree or the same
// node, only the umbrella event on the ancestor will be emitted.
eCoalesceReorder,
// eCoalesceMutationTextChange : coalesce text change events caused by
// tree mutations of the same tree level.
eCoalesceMutationTextChange,
// eCoalesceOfSameType : For events of the same type, only the newest event
// will be processed.
eCoalesceOfSameType,
// eCoalesceSelectionChange: coalescence of selection change events.
eCoalesceSelectionChange,
// eCoalesceStateChange: coalesce state change events.
eCoalesceStateChange,
// eRemoveDupes : For repeat events, only the newest event in queue
// will be emitted.
eRemoveDupes,
// eDoNotEmit : This event is confirmed as a duplicate, do not emit it.
eDoNotEmit
};
// Initialize with an nsIAccessible
AccEvent(uint32_t aEventType, Accessible* aAccessible,
EIsFromUserInput aIsFromUserInput = eAutoDetect,
EEventRule aEventRule = eRemoveDupes);
virtual ~AccEvent() {}
// AccEvent
uint32_t GetEventType() const { return mEventType; }
EEventRule GetEventRule() const { return mEventRule; }
bool IsFromUserInput() const { return mIsFromUserInput; }
Accessible* GetAccessible() const { return mAccessible; }
DocAccessible* GetDocAccessible() const { return mAccessible->Document(); }
/**
* Down casting.
*/
enum EventGroup {
eGenericEvent,
eStateChangeEvent,
eTextChangeEvent,
eMutationEvent,
eReorderEvent,
eHideEvent,
eShowEvent,
eCaretMoveEvent,
eSelectionChangeEvent,
eTableChangeEvent,
eVirtualCursorChangeEvent
};
static const EventGroup kEventGroup = eGenericEvent;
virtual unsigned int GetEventGroups() const
{
return 1U << eGenericEvent;
}
/**
* Reference counting and cycle collection.
*/
NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(AccEvent)
NS_DECL_CYCLE_COLLECTION_NATIVE_CLASS(AccEvent)
protected:
bool mIsFromUserInput;
uint32_t mEventType;
EEventRule mEventRule;
nsRefPtr<Accessible> mAccessible;
friend class EventQueue;
friend class AccReorderEvent;
};
/**
* Accessible state change event.
*/
class AccStateChangeEvent: public AccEvent
{
public:
AccStateChangeEvent(Accessible* aAccessible, uint64_t aState,
bool aIsEnabled,
EIsFromUserInput aIsFromUserInput = eAutoDetect) :
AccEvent(nsIAccessibleEvent::EVENT_STATE_CHANGE, aAccessible,
aIsFromUserInput, eCoalesceStateChange),
mState(aState), mIsEnabled(aIsEnabled) { }
AccStateChangeEvent(Accessible* aAccessible, uint64_t aState) :
AccEvent(::nsIAccessibleEvent::EVENT_STATE_CHANGE, aAccessible,
eAutoDetect, eCoalesceStateChange), mState(aState)
{ mIsEnabled = (mAccessible->State() & mState) != 0; }
// AccEvent
static const EventGroup kEventGroup = eStateChangeEvent;
virtual unsigned int GetEventGroups() const
{
return AccEvent::GetEventGroups() | (1U << eStateChangeEvent);
}
// AccStateChangeEvent
uint64_t GetState() const { return mState; }
bool IsStateEnabled() const { return mIsEnabled; }
private:
uint64_t mState;
bool mIsEnabled;
friend class EventQueue;
};
/**
* Accessible text change event.
*/
class AccTextChangeEvent: public AccEvent
{
public:
AccTextChangeEvent(Accessible* aAccessible, int32_t aStart,
const nsAString& aModifiedText, bool aIsInserted,
EIsFromUserInput aIsFromUserInput = eAutoDetect);
// AccEvent
static const EventGroup kEventGroup = eTextChangeEvent;
virtual unsigned int GetEventGroups() const
{
return AccEvent::GetEventGroups() | (1U << eTextChangeEvent);
}
// AccTextChangeEvent
int32_t GetStartOffset() const { return mStart; }
uint32_t GetLength() const { return mModifiedText.Length(); }
bool IsTextInserted() const { return mIsInserted; }
void GetModifiedText(nsAString& aModifiedText)
{ aModifiedText = mModifiedText; }
private:
int32_t mStart;
bool mIsInserted;
nsString mModifiedText;
friend class EventQueue;
friend class AccReorderEvent;
};
/**
* Base class for show and hide accessible events.
*/
class AccMutationEvent: public AccEvent
{
public:
AccMutationEvent(uint32_t aEventType, Accessible* aTarget,
nsINode* aTargetNode) :
AccEvent(aEventType, aTarget, eAutoDetect, eCoalesceMutationTextChange)
{
// Don't coalesce these since they are coalesced by reorder event. Coalesce
// contained text change events.
mParent = mAccessible->Parent();
}
virtual ~AccMutationEvent() { }
// Event
static const EventGroup kEventGroup = eMutationEvent;
virtual unsigned int GetEventGroups() const
{
return AccEvent::GetEventGroups() | (1U << eMutationEvent);
}
// MutationEvent
bool IsShow() const { return mEventType == nsIAccessibleEvent::EVENT_SHOW; }
bool IsHide() const { return mEventType == nsIAccessibleEvent::EVENT_HIDE; }
protected:
nsCOMPtr<nsINode> mNode;
nsRefPtr<Accessible> mParent;
nsRefPtr<AccTextChangeEvent> mTextChangeEvent;
friend class EventQueue;
};
/**
* Accessible hide event.
*/
class AccHideEvent: public AccMutationEvent
{
public:
AccHideEvent(Accessible* aTarget, nsINode* aTargetNode);
// Event
static const EventGroup kEventGroup = eHideEvent;
virtual unsigned int GetEventGroups() const
{
return AccMutationEvent::GetEventGroups() | (1U << eHideEvent);
}
// AccHideEvent
Accessible* TargetParent() const { return mParent; }
Accessible* TargetNextSibling() const { return mNextSibling; }
Accessible* TargetPrevSibling() const { return mPrevSibling; }
protected:
nsRefPtr<Accessible> mNextSibling;
nsRefPtr<Accessible> mPrevSibling;
friend class EventQueue;
};
/**
* Accessible show event.
*/
class AccShowEvent: public AccMutationEvent
{
public:
AccShowEvent(Accessible* aTarget, nsINode* aTargetNode);
// Event
static const EventGroup kEventGroup = eShowEvent;
virtual unsigned int GetEventGroups() const
{
return AccMutationEvent::GetEventGroups() | (1U << eShowEvent);
}
};
/**
* Class for reorder accessible event. Takes care about
*/
class AccReorderEvent : public AccEvent
{
public:
AccReorderEvent(Accessible* aTarget) :
AccEvent(::nsIAccessibleEvent::EVENT_REORDER, aTarget,
eAutoDetect, eCoalesceReorder) { }
virtual ~AccReorderEvent() { }
// Event
static const EventGroup kEventGroup = eReorderEvent;
virtual unsigned int GetEventGroups() const
{
return AccEvent::GetEventGroups() | (1U << eReorderEvent);
}
/**
* Get connected with mutation event.
*/
void AddSubMutationEvent(AccMutationEvent* aEvent)
{ mDependentEvents.AppendElement(aEvent); }
/**
* Do not emit the reorder event and its connected mutation events.
*/
void DoNotEmitAll()
{
mEventRule = AccEvent::eDoNotEmit;
uint32_t eventsCount = mDependentEvents.Length();
for (uint32_t idx = 0; idx < eventsCount; idx++)
mDependentEvents[idx]->mEventRule = AccEvent::eDoNotEmit;
}
/**
* Return true if the given accessible is a target of connected mutation
* event.
*/
uint32_t IsShowHideEventTarget(const Accessible* aTarget) const;
protected:
/**
* Show and hide events causing this reorder event.
*/
nsTArray<AccMutationEvent*> mDependentEvents;
friend class EventQueue;
};
/**
* Accessible caret move event.
*/
class AccCaretMoveEvent: public AccEvent
{
public:
AccCaretMoveEvent(Accessible* aAccessible) :
AccEvent(::nsIAccessibleEvent::EVENT_TEXT_CARET_MOVED, aAccessible),
mCaretOffset(-1) { }
virtual ~AccCaretMoveEvent() { }
// AccEvent
static const EventGroup kEventGroup = eCaretMoveEvent;
virtual unsigned int GetEventGroups() const
{
return AccEvent::GetEventGroups() | (1U << eCaretMoveEvent);
}
// AccCaretMoveEvent
int32_t GetCaretOffset() const { return mCaretOffset; }
private:
int32_t mCaretOffset;
friend class EventQueue;
};
/**
* Accessible widget selection change event.
*/
class AccSelChangeEvent : public AccEvent
{
public:
enum SelChangeType {
eSelectionAdd,
eSelectionRemove
};
AccSelChangeEvent(Accessible* aWidget, Accessible* aItem,
SelChangeType aSelChangeType);
virtual ~AccSelChangeEvent() { }
// AccEvent
static const EventGroup kEventGroup = eSelectionChangeEvent;
virtual unsigned int GetEventGroups() const
{
return AccEvent::GetEventGroups() | (1U << eSelectionChangeEvent);
}
// AccSelChangeEvent
Accessible* Widget() const { return mWidget; }
private:
nsRefPtr<Accessible> mWidget;
nsRefPtr<Accessible> mItem;
SelChangeType mSelChangeType;
uint32_t mPreceedingCount;
AccSelChangeEvent* mPackedEvent;
friend class EventQueue;
};
/**
* Accessible table change event.
*/
class AccTableChangeEvent : public AccEvent
{
public:
AccTableChangeEvent(Accessible* aAccessible, uint32_t aEventType,
int32_t aRowOrColIndex, int32_t aNumRowsOrCols);
// AccEvent
static const EventGroup kEventGroup = eTableChangeEvent;
virtual unsigned int GetEventGroups() const
{
return AccEvent::GetEventGroups() | (1U << eTableChangeEvent);
}
// AccTableChangeEvent
uint32_t GetIndex() const { return mRowOrColIndex; }
uint32_t GetCount() const { return mNumRowsOrCols; }
private:
uint32_t mRowOrColIndex; // the start row/column after which the rows are inserted/deleted.
uint32_t mNumRowsOrCols; // the number of inserted/deleted rows/columns
};
/**
* Accessible virtual cursor change event.
*/
class AccVCChangeEvent : public AccEvent
{
public:
AccVCChangeEvent(Accessible* aAccessible,
nsIAccessible* aOldAccessible,
int32_t aOldStart, int32_t aOldEnd,
int16_t aReason);
virtual ~AccVCChangeEvent() { }
// AccEvent
static const EventGroup kEventGroup = eVirtualCursorChangeEvent;
virtual unsigned int GetEventGroups() const
{
return AccEvent::GetEventGroups() | (1U << eVirtualCursorChangeEvent);
}
// AccTableChangeEvent
nsIAccessible* OldAccessible() const { return mOldAccessible; }
int32_t OldStartOffset() const { return mOldStart; }
int32_t OldEndOffset() const { return mOldEnd; }
int32_t Reason() const { return mReason; }
private:
nsRefPtr<nsIAccessible> mOldAccessible;
int32_t mOldStart;
int32_t mOldEnd;
int16_t mReason;
};
/**
* Downcast the generic accessible event object to derived type.
*/
class downcast_accEvent
{
public:
downcast_accEvent(AccEvent* e) : mRawPtr(e) { }
template<class Destination>
operator Destination*() {
if (!mRawPtr)
return nullptr;
return mRawPtr->GetEventGroups() & (1U << Destination::kEventGroup) ?
static_cast<Destination*>(mRawPtr) : nullptr;
}
private:
AccEvent* mRawPtr;
};
/**
* Return a new xpcom accessible event for the given internal one.
*/
already_AddRefed<nsIAccessibleEvent>
MakeXPCEvent(AccEvent* aEvent);
} // namespace a11y
} // namespace mozilla
#endif
+231
View File
@@ -0,0 +1,231 @@
/* 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 "AccGroupInfo.h"
#include "Role.h"
#include "States.h"
using namespace mozilla::a11y;
AccGroupInfo::AccGroupInfo(Accessible* aItem, role aRole) :
mPosInSet(0), mSetSize(0), mParent(nullptr)
{
MOZ_COUNT_CTOR(AccGroupInfo);
Accessible* parent = aItem->Parent();
if (!parent)
return;
int32_t indexInParent = aItem->IndexInParent();
uint32_t siblingCount = parent->ChildCount();
if (indexInParent == -1 ||
indexInParent >= static_cast<int32_t>(siblingCount)) {
NS_ERROR("Wrong index in parent! Tree invalidation problem.");
return;
}
int32_t level = nsAccUtils::GetARIAOrDefaultLevel(aItem);
// Compute position in set.
mPosInSet = 1;
for (int32_t idx = indexInParent - 1; idx >= 0 ; idx--) {
Accessible* sibling = parent->GetChildAt(idx);
roles::Role siblingRole = sibling->Role();
// If the sibling is separator then the group is ended.
if (siblingRole == roles::SEPARATOR)
break;
// If sibling is not visible and hasn't the same base role.
if (BaseRole(siblingRole) != aRole || sibling->State() & states::INVISIBLE)
continue;
// Check if it's hierarchical flatten structure, i.e. if the sibling
// level is lesser than this one then group is ended, if the sibling level
// is greater than this one then the group is split by some child elements
// (group will be continued).
int32_t siblingLevel = nsAccUtils::GetARIAOrDefaultLevel(sibling);
if (siblingLevel < level) {
mParent = sibling;
break;
}
// Skip subset.
if (siblingLevel > level)
continue;
// If the previous item in the group has calculated group information then
// build group information for this item based on found one.
if (sibling->mGroupInfo) {
mPosInSet += sibling->mGroupInfo->mPosInSet;
mParent = sibling->mGroupInfo->mParent;
mSetSize = sibling->mGroupInfo->mSetSize;
return;
}
mPosInSet++;
}
// Compute set size.
mSetSize = mPosInSet;
for (uint32_t idx = indexInParent + 1; idx < siblingCount; idx++) {
Accessible* sibling = parent->GetChildAt(idx);
roles::Role siblingRole = sibling->Role();
// If the sibling is separator then the group is ended.
if (siblingRole == roles::SEPARATOR)
break;
// If sibling is visible and has the same base role
if (BaseRole(siblingRole) != aRole || sibling->State() & states::INVISIBLE)
continue;
// and check if it's hierarchical flatten structure.
int32_t siblingLevel = nsAccUtils::GetARIAOrDefaultLevel(sibling);
if (siblingLevel < level)
break;
// Skip subset.
if (siblingLevel > level)
continue;
// If the next item in the group has calculated group information then
// build group information for this item based on found one.
if (sibling->mGroupInfo) {
mParent = sibling->mGroupInfo->mParent;
mSetSize = sibling->mGroupInfo->mSetSize;
return;
}
mSetSize++;
}
if (mParent)
return;
roles::Role parentRole = parent->Role();
if (IsConceptualParent(aRole, parentRole))
mParent = parent;
// ARIA tree and list can be arranged by using ARIA groups to organize levels.
if (parentRole != roles::GROUPING)
return;
// Way #1 for ARIA tree (not ARIA treegrid): previous sibling of a group is a
// parent. In other words the parent of the tree item will be a group and
// the previous tree item of the group is a conceptual parent of the tree
// item.
if (aRole == roles::OUTLINEITEM) {
Accessible* parentPrevSibling = parent->PrevSibling();
if (parentPrevSibling && parentPrevSibling->Role() == aRole) {
mParent = parentPrevSibling;
return;
}
}
// Way #2 for ARIA list and tree: group is a child of an item. In other words
// the parent of the item will be a group and containing item of the group is
// a conceptual parent of the item.
if (aRole == roles::LISTITEM || aRole == roles::OUTLINEITEM) {
Accessible* grandParent = parent->Parent();
if (grandParent && grandParent->Role() == aRole)
mParent = grandParent;
}
}
Accessible*
AccGroupInfo::FirstItemOf(Accessible* aContainer)
{
// ARIA tree can be arranged by ARIA groups case #1 (previous sibling of a
// group is a parent) or by aria-level.
a11y::role containerRole = aContainer->Role();
Accessible* item = aContainer->NextSibling();
if (item) {
if (containerRole == roles::OUTLINEITEM && item->Role() == roles::GROUPING)
item = item->FirstChild();
if (item) {
AccGroupInfo* itemGroupInfo = item->GetGroupInfo();
if (itemGroupInfo && itemGroupInfo->ConceptualParent() == aContainer)
return item;
}
}
// ARIA list and tree can be arranged by ARIA groups case #2 (group is
// a child of an item).
item = aContainer->LastChild();
if (!item)
return nullptr;
if (item->Role() == roles::GROUPING &&
(containerRole == roles::LISTITEM || containerRole == roles::OUTLINEITEM)) {
item = item->FirstChild();
if (item) {
AccGroupInfo* itemGroupInfo = item->GetGroupInfo();
if (itemGroupInfo && itemGroupInfo->ConceptualParent() == aContainer)
return item;
}
}
// Otherwise it can be a direct child.
item = aContainer->FirstChild();
if (IsConceptualParent(BaseRole(item->Role()), containerRole))
return item;
return nullptr;
}
Accessible*
AccGroupInfo::NextItemTo(Accessible* aItem)
{
AccGroupInfo* groupInfo = aItem->GetGroupInfo();
if (!groupInfo)
return nullptr;
// If the item in middle of the group then search next item in siblings.
if (groupInfo->PosInSet() >= groupInfo->SetSize())
return nullptr;
Accessible* parent = aItem->Parent();
uint32_t childCount = parent->ChildCount();
for (int32_t idx = aItem->IndexInParent() + 1; idx < childCount; idx++) {
Accessible* nextItem = parent->GetChildAt(idx);
AccGroupInfo* nextGroupInfo = nextItem->GetGroupInfo();
if (nextGroupInfo &&
nextGroupInfo->ConceptualParent() == groupInfo->ConceptualParent()) {
return nextItem;
}
}
NS_NOTREACHED("Item in the midle of the group but there's no next item!");
return nullptr;
}
bool
AccGroupInfo::IsConceptualParent(role aRole, role aParentRole)
{
if (aParentRole == roles::OUTLINE && aRole == roles::OUTLINEITEM)
return true;
if ((aParentRole == roles::TABLE || aParentRole == roles::TREE_TABLE) &&
aRole == roles::ROW)
return true;
if (aParentRole == roles::ROW &&
(aRole == roles::CELL || aRole == roles::GRID_CELL))
return true;
if (aParentRole == roles::LIST && aRole == roles::LISTITEM)
return true;
if (aParentRole == roles::COMBOBOX_LIST && aRole == roles::COMBOBOX_OPTION)
return true;
if (aParentRole == roles::LISTBOX && aRole == roles::OPTION)
return true;
if (aParentRole == roles::PAGETABLIST && aRole == roles::PAGETAB)
return true;
if ((aParentRole == roles::POPUP_MENU || aParentRole == roles::MENUPOPUP) &&
aRole == roles::MENUITEM)
return true;
return false;
}
+109
View File
@@ -0,0 +1,109 @@
/* 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 AccGroupInfo_h_
#define AccGroupInfo_h_
#include "Accessible-inl.h"
#include "nsAccUtils.h"
namespace mozilla {
namespace a11y {
/**
* Calculate and store group information.
*/
class AccGroupInfo
{
public:
~AccGroupInfo() { MOZ_COUNT_DTOR(AccGroupInfo); }
/**
* Return 1-based position in the group.
*/
uint32_t PosInSet() const { return mPosInSet; }
/**
* Return a number of items in the group.
*/
uint32_t SetSize() const { return mSetSize; }
/**
* Return a direct or logical parent of the accessible that this group info is
* created for.
*/
Accessible* ConceptualParent() const { return mParent; }
/**
* Create group info.
*/
static AccGroupInfo* CreateGroupInfo(Accessible* aAccessible)
{
mozilla::a11y::role role = aAccessible->Role();
if (role != mozilla::a11y::roles::ROW &&
role != mozilla::a11y::roles::GRID_CELL &&
role != mozilla::a11y::roles::OUTLINEITEM &&
role != mozilla::a11y::roles::OPTION &&
role != mozilla::a11y::roles::LISTITEM &&
role != mozilla::a11y::roles::MENUITEM &&
role != mozilla::a11y::roles::COMBOBOX_OPTION &&
role != mozilla::a11y::roles::RICH_OPTION &&
role != mozilla::a11y::roles::CHECK_RICH_OPTION &&
role != mozilla::a11y::roles::PARENT_MENUITEM &&
role != mozilla::a11y::roles::CHECK_MENU_ITEM &&
role != mozilla::a11y::roles::RADIO_MENU_ITEM &&
role != mozilla::a11y::roles::RADIOBUTTON &&
role != mozilla::a11y::roles::PAGETAB)
return nullptr;
AccGroupInfo* info = new AccGroupInfo(aAccessible, BaseRole(role));
return info;
}
/**
* Return a first item for the given container.
*/
static Accessible* FirstItemOf(Accessible* aContainer);
/**
* Return next item of the same group to the given item.
*/
static Accessible* NextItemTo(Accessible* aItem);
protected:
AccGroupInfo(Accessible* aItem, a11y::role aRole);
private:
AccGroupInfo() MOZ_DELETE;
AccGroupInfo(const AccGroupInfo&) MOZ_DELETE;
AccGroupInfo& operator =(const AccGroupInfo&) MOZ_DELETE;
static mozilla::a11y::role BaseRole(mozilla::a11y::role aRole)
{
if (aRole == mozilla::a11y::roles::CHECK_MENU_ITEM ||
aRole == mozilla::a11y::roles::PARENT_MENUITEM ||
aRole == mozilla::a11y::roles::RADIO_MENU_ITEM)
return mozilla::a11y::roles::MENUITEM;
if (aRole == mozilla::a11y::roles::CHECK_RICH_OPTION)
return mozilla::a11y::roles::RICH_OPTION;
return aRole;
}
/**
* Return true if the given parent role is conceptual parent of the given
* role.
*/
static bool IsConceptualParent(a11y::role aRole, a11y::role aParentRole);
uint32_t mPosInSet;
uint32_t mSetSize;
Accessible* mParent;
};
} // namespace mozilla
} // namespace a11y
#endif
+401
View File
@@ -0,0 +1,401 @@
/* 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 "AccIterator.h"
#include "nsAccessibilityService.h"
#include "AccGroupInfo.h"
#include "Accessible-inl.h"
#ifdef MOZ_XUL
#include "XULTreeAccessible.h"
#endif
#include "mozilla/dom/Element.h"
#include "nsBindingManager.h"
using namespace mozilla;
using namespace mozilla::a11y;
////////////////////////////////////////////////////////////////////////////////
// AccIterator
////////////////////////////////////////////////////////////////////////////////
AccIterator::AccIterator(Accessible* aAccessible,
filters::FilterFuncPtr aFilterFunc) :
mFilterFunc(aFilterFunc)
{
mState = new IteratorState(aAccessible);
}
AccIterator::~AccIterator()
{
while (mState) {
IteratorState *tmp = mState;
mState = tmp->mParentState;
delete tmp;
}
}
Accessible*
AccIterator::Next()
{
while (mState) {
Accessible* child = mState->mParent->GetChildAt(mState->mIndex++);
if (!child) {
IteratorState* tmp = mState;
mState = mState->mParentState;
delete tmp;
continue;
}
uint32_t result = mFilterFunc(child);
if (result & filters::eMatch)
return child;
if (!(result & filters::eSkipSubtree)) {
IteratorState* childState = new IteratorState(child, mState);
mState = childState;
}
}
return nullptr;
}
////////////////////////////////////////////////////////////////////////////////
// nsAccIterator::IteratorState
AccIterator::IteratorState::IteratorState(Accessible* aParent,
IteratorState *mParentState) :
mParent(aParent), mIndex(0), mParentState(mParentState)
{
}
////////////////////////////////////////////////////////////////////////////////
// RelatedAccIterator
////////////////////////////////////////////////////////////////////////////////
RelatedAccIterator::
RelatedAccIterator(DocAccessible* aDocument, nsIContent* aDependentContent,
nsIAtom* aRelAttr) :
mDocument(aDocument), mRelAttr(aRelAttr), mProviders(nullptr),
mBindingParent(nullptr), mIndex(0)
{
mBindingParent = aDependentContent->GetBindingParent();
nsIAtom* IDAttr = mBindingParent ?
nsGkAtoms::anonid : aDependentContent->GetIDAttributeName();
nsAutoString id;
if (aDependentContent->GetAttr(kNameSpaceID_None, IDAttr, id))
mProviders = mDocument->mDependentIDsHash.Get(id);
}
Accessible*
RelatedAccIterator::Next()
{
if (!mProviders)
return nullptr;
while (mIndex < mProviders->Length()) {
DocAccessible::AttrRelProvider* provider = (*mProviders)[mIndex++];
// Return related accessible for the given attribute and if the provider
// content is in the same binding in the case of XBL usage.
if (provider->mRelAttr == mRelAttr) {
nsIContent* bindingParent = provider->mContent->GetBindingParent();
bool inScope = mBindingParent == bindingParent ||
mBindingParent == provider->mContent;
if (inScope) {
Accessible* related = mDocument->GetAccessible(provider->mContent);
if (related)
return related;
// If the document content is pointed by relation then return the document
// itself.
if (provider->mContent == mDocument->GetContent())
return mDocument;
}
}
}
return nullptr;
}
////////////////////////////////////////////////////////////////////////////////
// HTMLLabelIterator
////////////////////////////////////////////////////////////////////////////////
HTMLLabelIterator::
HTMLLabelIterator(DocAccessible* aDocument, const Accessible* aAccessible,
LabelFilter aFilter) :
mRelIter(aDocument, aAccessible->GetContent(), nsGkAtoms::_for),
mAcc(aAccessible), mLabelFilter(aFilter)
{
}
Accessible*
HTMLLabelIterator::Next()
{
// Get either <label for="[id]"> element which explicitly points to given
// element, or <label> ancestor which implicitly point to it.
Accessible* label = nullptr;
while ((label = mRelIter.Next())) {
if (label->GetContent()->Tag() == nsGkAtoms::label)
return label;
}
// Ignore ancestor label on not widget accessible.
if (mLabelFilter == eSkipAncestorLabel || !mAcc->IsWidget())
return nullptr;
// Go up tree to get a name of ancestor label if there is one (an ancestor
// <label> implicitly points to us). Don't go up farther than form or
// document.
Accessible* walkUp = mAcc->Parent();
while (walkUp && !walkUp->IsDoc()) {
nsIContent* walkUpElm = walkUp->GetContent();
if (walkUpElm->IsHTML()) {
if (walkUpElm->Tag() == nsGkAtoms::label &&
!walkUpElm->HasAttr(kNameSpaceID_None, nsGkAtoms::_for)) {
mLabelFilter = eSkipAncestorLabel; // prevent infinite loop
return walkUp;
}
if (walkUpElm->Tag() == nsGkAtoms::form)
break;
}
walkUp = walkUp->Parent();
}
return nullptr;
}
////////////////////////////////////////////////////////////////////////////////
// HTMLOutputIterator
////////////////////////////////////////////////////////////////////////////////
HTMLOutputIterator::
HTMLOutputIterator(DocAccessible* aDocument, nsIContent* aElement) :
mRelIter(aDocument, aElement, nsGkAtoms::_for)
{
}
Accessible*
HTMLOutputIterator::Next()
{
Accessible* output = nullptr;
while ((output = mRelIter.Next())) {
if (output->GetContent()->Tag() == nsGkAtoms::output)
return output;
}
return nullptr;
}
////////////////////////////////////////////////////////////////////////////////
// XULLabelIterator
////////////////////////////////////////////////////////////////////////////////
XULLabelIterator::
XULLabelIterator(DocAccessible* aDocument, nsIContent* aElement) :
mRelIter(aDocument, aElement, nsGkAtoms::control)
{
}
Accessible*
XULLabelIterator::Next()
{
Accessible* label = nullptr;
while ((label = mRelIter.Next())) {
if (label->GetContent()->Tag() == nsGkAtoms::label)
return label;
}
return nullptr;
}
////////////////////////////////////////////////////////////////////////////////
// XULDescriptionIterator
////////////////////////////////////////////////////////////////////////////////
XULDescriptionIterator::
XULDescriptionIterator(DocAccessible* aDocument, nsIContent* aElement) :
mRelIter(aDocument, aElement, nsGkAtoms::control)
{
}
Accessible*
XULDescriptionIterator::Next()
{
Accessible* descr = nullptr;
while ((descr = mRelIter.Next())) {
if (descr->GetContent()->Tag() == nsGkAtoms::description)
return descr;
}
return nullptr;
}
////////////////////////////////////////////////////////////////////////////////
// IDRefsIterator
////////////////////////////////////////////////////////////////////////////////
IDRefsIterator::
IDRefsIterator(DocAccessible* aDoc, nsIContent* aContent,
nsIAtom* aIDRefsAttr) :
mContent(aContent), mDoc(aDoc), mCurrIdx(0)
{
if (mContent->IsInDoc())
mContent->GetAttr(kNameSpaceID_None, aIDRefsAttr, mIDs);
}
const nsDependentSubstring
IDRefsIterator::NextID()
{
for (; mCurrIdx < mIDs.Length(); mCurrIdx++) {
if (!NS_IsAsciiWhitespace(mIDs[mCurrIdx]))
break;
}
if (mCurrIdx >= mIDs.Length())
return nsDependentSubstring();
nsAString::index_type idStartIdx = mCurrIdx;
while (++mCurrIdx < mIDs.Length()) {
if (NS_IsAsciiWhitespace(mIDs[mCurrIdx]))
break;
}
return Substring(mIDs, idStartIdx, mCurrIdx++ - idStartIdx);
}
nsIContent*
IDRefsIterator::NextElem()
{
while (true) {
const nsDependentSubstring id = NextID();
if (id.IsEmpty())
break;
nsIContent* refContent = GetElem(id);
if (refContent)
return refContent;
}
return nullptr;
}
nsIContent*
IDRefsIterator::GetElem(const nsDependentSubstring& aID)
{
// Get elements in DOM tree by ID attribute if this is an explicit content.
// In case of bound element check its anonymous subtree.
if (!mContent->IsInAnonymousSubtree()) {
dom::Element* refElm = mContent->OwnerDoc()->GetElementById(aID);
if (refElm || !mContent->OwnerDoc()->BindingManager()->GetBinding(mContent))
return refElm;
}
// If content is in anonymous subtree or an element having anonymous subtree
// then use "anonid" attribute to get elements in anonymous subtree.
// Check inside the binding the element is contained in.
nsIContent* bindingParent = mContent->GetBindingParent();
if (bindingParent) {
nsIContent* refElm = bindingParent->OwnerDoc()->
GetAnonymousElementByAttribute(bindingParent, nsGkAtoms::anonid, aID);
if (refElm)
return refElm;
}
// Check inside the binding of the element.
if (mContent->OwnerDoc()->BindingManager()->GetBinding(mContent)) {
return mContent->OwnerDoc()->
GetAnonymousElementByAttribute(mContent, nsGkAtoms::anonid, aID);
}
return nullptr;
}
Accessible*
IDRefsIterator::Next()
{
nsIContent* nextElm = NextElem();
return nextElm ? mDoc->GetAccessible(nextElm) : nullptr;
}
////////////////////////////////////////////////////////////////////////////////
// SingleAccIterator
////////////////////////////////////////////////////////////////////////////////
Accessible*
SingleAccIterator::Next()
{
nsRefPtr<Accessible> nextAcc;
mAcc.swap(nextAcc);
return (nextAcc && !nextAcc->IsDefunct()) ? nextAcc : nullptr;
}
////////////////////////////////////////////////////////////////////////////////
// ItemIterator
////////////////////////////////////////////////////////////////////////////////
Accessible*
ItemIterator::Next()
{
if (mContainer) {
mAnchor = AccGroupInfo::FirstItemOf(mContainer);
mContainer = nullptr;
return mAnchor;
}
return mAnchor ? (mAnchor = AccGroupInfo::NextItemTo(mAnchor)) : nullptr;
}
////////////////////////////////////////////////////////////////////////////////
// XULTreeItemIterator
////////////////////////////////////////////////////////////////////////////////
XULTreeItemIterator::XULTreeItemIterator(XULTreeAccessible* aXULTree,
nsITreeView* aTreeView,
int32_t aRowIdx) :
mXULTree(aXULTree), mTreeView(aTreeView), mRowCount(-1),
mContainerLevel(-1), mCurrRowIdx(aRowIdx + 1)
{
mTreeView->GetRowCount(&mRowCount);
if (aRowIdx != -1)
mTreeView->GetLevel(aRowIdx, &mContainerLevel);
}
Accessible*
XULTreeItemIterator::Next()
{
while (mCurrRowIdx < mRowCount) {
int32_t level = 0;
mTreeView->GetLevel(mCurrRowIdx, &level);
if (level == mContainerLevel + 1)
return mXULTree->GetTreeItemAccessible(mCurrRowIdx++);
if (level <= mContainerLevel) { // got level up
mCurrRowIdx = mRowCount;
break;
}
mCurrRowIdx++;
}
return nullptr;
}
+319
View File
@@ -0,0 +1,319 @@
/* -*- 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_AccIterator_h__
#define mozilla_a11y_AccIterator_h__
#include "DocAccessible.h"
#include "Filters.h"
#include "nsAccessibilityService.h"
namespace mozilla {
namespace a11y {
/**
* AccIterable is a basic interface for iterators over accessibles.
*/
class AccIterable
{
public:
virtual ~AccIterable() { }
virtual Accessible* Next() = 0;
private:
friend class Relation;
nsAutoPtr<AccIterable> mNextIter;
};
/**
* Allows to iterate through accessible children or subtree complying with
* filter function.
*/
class AccIterator : public AccIterable
{
public:
AccIterator(Accessible* aRoot, filters::FilterFuncPtr aFilterFunc);
virtual ~AccIterator();
/**
* Return next accessible complying with filter function. Return the first
* accessible for the first time.
*/
virtual Accessible* Next();
private:
AccIterator();
AccIterator(const AccIterator&);
AccIterator& operator =(const AccIterator&);
struct IteratorState
{
IteratorState(Accessible* aParent, IteratorState* mParentState = nullptr);
Accessible* mParent;
int32_t mIndex;
IteratorState* mParentState;
};
filters::FilterFuncPtr mFilterFunc;
IteratorState* mState;
};
/**
* Allows to traverse through related accessibles that are pointing to the given
* dependent accessible by relation attribute.
*/
class RelatedAccIterator : public AccIterable
{
public:
/**
* Constructor.
*
* @param aDocument [in] the document accessible the related
* & accessibles belong to.
* @param aDependentContent [in] the content of dependent accessible that
* relations were requested for
* @param aRelAttr [in] relation attribute that relations are
* pointed by
*/
RelatedAccIterator(DocAccessible* aDocument, nsIContent* aDependentContent,
nsIAtom* aRelAttr);
virtual ~RelatedAccIterator() { }
/**
* Return next related accessible for the given dependent accessible.
*/
virtual Accessible* Next();
private:
RelatedAccIterator();
RelatedAccIterator(const RelatedAccIterator&);
RelatedAccIterator& operator = (const RelatedAccIterator&);
DocAccessible* mDocument;
nsIAtom* mRelAttr;
DocAccessible::AttrRelProviderArray* mProviders;
nsIContent* mBindingParent;
uint32_t mIndex;
};
/**
* Used to iterate through HTML labels associated with the given accessible.
*/
class HTMLLabelIterator : public AccIterable
{
public:
enum LabelFilter {
eAllLabels,
eSkipAncestorLabel
};
HTMLLabelIterator(DocAccessible* aDocument, const Accessible* aAccessible,
LabelFilter aFilter = eAllLabels);
virtual ~HTMLLabelIterator() { }
/**
* Return next label accessible associated with the given element.
*/
virtual Accessible* Next();
private:
HTMLLabelIterator();
HTMLLabelIterator(const HTMLLabelIterator&);
HTMLLabelIterator& operator = (const HTMLLabelIterator&);
RelatedAccIterator mRelIter;
// XXX: replace it on weak reference (bug 678429), it's safe to use raw
// pointer now because iterators life cycle is short.
const Accessible* mAcc;
LabelFilter mLabelFilter;
};
/**
* Used to iterate through HTML outputs associated with the given element.
*/
class HTMLOutputIterator : public AccIterable
{
public:
HTMLOutputIterator(DocAccessible* aDocument, nsIContent* aElement);
virtual ~HTMLOutputIterator() { }
/**
* Return next output accessible associated with the given element.
*/
virtual Accessible* Next();
private:
HTMLOutputIterator();
HTMLOutputIterator(const HTMLOutputIterator&);
HTMLOutputIterator& operator = (const HTMLOutputIterator&);
RelatedAccIterator mRelIter;
};
/**
* Used to iterate through XUL labels associated with the given element.
*/
class XULLabelIterator : public AccIterable
{
public:
XULLabelIterator(DocAccessible* aDocument, nsIContent* aElement);
virtual ~XULLabelIterator() { }
/**
* Return next label accessible associated with the given element.
*/
virtual Accessible* Next();
private:
XULLabelIterator();
XULLabelIterator(const XULLabelIterator&);
XULLabelIterator& operator = (const XULLabelIterator&);
RelatedAccIterator mRelIter;
};
/**
* Used to iterate through XUL descriptions associated with the given element.
*/
class XULDescriptionIterator : public AccIterable
{
public:
XULDescriptionIterator(DocAccessible* aDocument, nsIContent* aElement);
virtual ~XULDescriptionIterator() { }
/**
* Return next description accessible associated with the given element.
*/
virtual Accessible* Next();
private:
XULDescriptionIterator();
XULDescriptionIterator(const XULDescriptionIterator&);
XULDescriptionIterator& operator = (const XULDescriptionIterator&);
RelatedAccIterator mRelIter;
};
/**
* Used to iterate through IDs, elements or accessibles pointed by IDRefs
* attribute. Note, any method used to iterate through IDs, elements, or
* accessibles moves iterator to next position.
*/
class IDRefsIterator : public AccIterable
{
public:
IDRefsIterator(DocAccessible* aDoc, nsIContent* aContent,
nsIAtom* aIDRefsAttr);
virtual ~IDRefsIterator() { }
/**
* Return next ID.
*/
const nsDependentSubstring NextID();
/**
* Return next element.
*/
nsIContent* NextElem();
/**
* Return the element with the given ID.
*/
nsIContent* GetElem(const nsDependentSubstring& aID);
// AccIterable
virtual Accessible* Next();
private:
IDRefsIterator();
IDRefsIterator(const IDRefsIterator&);
IDRefsIterator operator = (const IDRefsIterator&);
nsString mIDs;
nsIContent* mContent;
DocAccessible* mDoc;
nsAString::index_type mCurrIdx;
};
/**
* Iterator that points to a single accessible returning it on the first call
* to Next().
*/
class SingleAccIterator : public AccIterable
{
public:
SingleAccIterator(Accessible* aTarget): mAcc(aTarget) { }
virtual ~SingleAccIterator() { }
virtual Accessible* Next();
private:
SingleAccIterator();
SingleAccIterator(const SingleAccIterator&);
SingleAccIterator& operator = (const SingleAccIterator&);
nsRefPtr<Accessible> mAcc;
};
/**
* Used to iterate items of the given item container.
*/
class ItemIterator : public AccIterable
{
public:
ItemIterator(Accessible* aItemContainer) :
mContainer(aItemContainer), mAnchor(nullptr) { }
virtual ~ItemIterator() { }
virtual Accessible* Next();
private:
ItemIterator() MOZ_DELETE;
ItemIterator(const ItemIterator&) MOZ_DELETE;
ItemIterator& operator = (const ItemIterator&) MOZ_DELETE;
Accessible* mContainer;
Accessible* mAnchor;
};
/**
* Used to iterate through XUL tree items of the same level.
*/
class XULTreeItemIterator : public AccIterable
{
public:
XULTreeItemIterator(XULTreeAccessible* aXULTree, nsITreeView* aTreeView,
int32_t aRowIdx);
virtual ~XULTreeItemIterator() { }
virtual Accessible* Next();
private:
XULTreeItemIterator() MOZ_DELETE;
XULTreeItemIterator(const XULTreeItemIterator&) MOZ_DELETE;
XULTreeItemIterator& operator = (const XULTreeItemIterator&) MOZ_DELETE;
XULTreeAccessible* mXULTree;
nsITreeView* mTreeView;
int32_t mRowCount;
int32_t mContainerLevel;
int32_t mCurrRowIdx;
};
} // namespace a11y
} // namespace mozilla
#endif
+88
View File
@@ -0,0 +1,88 @@
/* -*- 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_AccTypes_h
#define mozilla_a11y_AccTypes_h
namespace mozilla {
namespace a11y {
/**
* Accessible object types. Each accessible class can have own type.
*/
enum AccType {
/**
* This set of types is used for accessible creation, keep them together in
* alphabetical order since they are used in switch statement.
*/
eNoType,
eHTMLBRType,
eHTMLButtonType,
eHTMLCanvasType,
eHTMLCaptionType,
eHTMLCheckboxType,
eHTMLComboboxType,
eHTMLFileInputType,
eHTMLGroupboxType,
eHTMLHRType,
eHTMLImageMapType,
eHTMLLabelType,
eHTMLLiType,
eHTMLSelectListType,
eHTMLMediaType,
eHTMLRadioButtonType,
eHTMLRangeType,
eHTMLTableType,
eHTMLTableCellType,
eHTMLTableRowType,
eHTMLTextFieldType,
eHyperTextType,
eImageType,
eOuterDocType,
ePluginType,
eTextLeafType,
/**
* Other accessible types.
*/
eApplicationType,
eHTMLOptGroupType,
eImageMapType,
eMenuPopupType,
eProgressType,
eRootType,
eXULLabelType,
eXULTabpanelsType,
eXULTreeType,
eLastAccType = eXULTreeType
};
/**
* Generic accessible type, different accessible classes can share the same
* type, the same accessible class can have several types.
*/
enum AccGenericType {
eAutoComplete = 1 << 0,
eAutoCompletePopup = 1 << 1,
eCombobox = 1 << 2,
eDocument = 1 << 3,
eHyperText = 1 << 4,
eList = 1 << 5,
eListControl = 1 << 6,
eMenuButton = 1 << 7,
eSelect = 1 << 8,
eTable = 1 << 9,
eTableCell = 1 << 10,
eTableRow = 1 << 11,
eLastAccGenericType = eTableRow
};
} // namespace a11y
} // namespace mozilla
#endif // mozilla_a11y_AccTypes_h
+500
View File
@@ -0,0 +1,500 @@
/* -*- 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 "DocManager.h"
#include "Accessible-inl.h"
#include "ApplicationAccessible.h"
#include "ARIAMap.h"
#include "DocAccessible-inl.h"
#include "nsAccessibilityService.h"
#include "nsAccUtils.h"
#include "RootAccessibleWrap.h"
#include "States.h"
#ifdef A11Y_LOG
#include "Logging.h"
#endif
#include "nsCURILoader.h"
#include "nsDocShellLoadTypes.h"
#include "nsDOMEvent.h"
#include "nsIChannel.h"
#include "nsIContentViewer.h"
#include "nsIDOMDocument.h"
#include "nsEventListenerManager.h"
#include "nsIDOMWindow.h"
#include "nsIInterfaceRequestorUtils.h"
#include "nsIWebNavigation.h"
#include "nsServiceManagerUtils.h"
using namespace mozilla;
using namespace mozilla::a11y;
using namespace mozilla::dom;
////////////////////////////////////////////////////////////////////////////////
// DocManager
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
// DocManager public
DocAccessible*
DocManager::GetDocAccessible(nsIDocument* aDocument)
{
if (!aDocument)
return nullptr;
// Ensure CacheChildren is called before we query cache.
ApplicationAcc()->EnsureChildren();
DocAccessible* docAcc = GetExistingDocAccessible(aDocument);
if (docAcc)
return docAcc;
return CreateDocOrRootAccessible(aDocument);
}
Accessible*
DocManager::FindAccessibleInCache(nsINode* aNode) const
{
nsSearchAccessibleInCacheArg arg;
arg.mNode = aNode;
mDocAccessibleCache.EnumerateRead(SearchAccessibleInDocCache,
static_cast<void*>(&arg));
return arg.mAccessible;
}
#ifdef DEBUG
bool
DocManager::IsProcessingRefreshDriverNotification() const
{
bool isDocRefreshing = false;
mDocAccessibleCache.EnumerateRead(SearchIfDocIsRefreshing,
static_cast<void*>(&isDocRefreshing));
return isDocRefreshing;
}
#endif
////////////////////////////////////////////////////////////////////////////////
// DocManager protected
bool
DocManager::Init()
{
mDocAccessibleCache.Init(4);
nsCOMPtr<nsIWebProgress> progress =
do_GetService(NS_DOCUMENTLOADER_SERVICE_CONTRACTID);
if (!progress)
return false;
progress->AddProgressListener(static_cast<nsIWebProgressListener*>(this),
nsIWebProgress::NOTIFY_STATE_DOCUMENT);
return true;
}
void
DocManager::Shutdown()
{
nsCOMPtr<nsIWebProgress> progress =
do_GetService(NS_DOCUMENTLOADER_SERVICE_CONTRACTID);
if (progress)
progress->RemoveProgressListener(static_cast<nsIWebProgressListener*>(this));
ClearDocCache();
}
////////////////////////////////////////////////////////////////////////////////
// nsISupports
NS_IMPL_THREADSAFE_ISUPPORTS3(DocManager,
nsIWebProgressListener,
nsIDOMEventListener,
nsISupportsWeakReference)
////////////////////////////////////////////////////////////////////////////////
// nsIWebProgressListener
NS_IMETHODIMP
DocManager::OnStateChange(nsIWebProgress* aWebProgress,
nsIRequest* aRequest, uint32_t aStateFlags,
nsresult aStatus)
{
NS_ASSERTION(aStateFlags & STATE_IS_DOCUMENT, "Other notifications excluded");
if (nsAccessibilityService::IsShutdown() || !aWebProgress ||
(aStateFlags & (STATE_START | STATE_STOP)) == 0)
return NS_OK;
nsCOMPtr<nsIDOMWindow> DOMWindow;
aWebProgress->GetDOMWindow(getter_AddRefs(DOMWindow));
NS_ENSURE_STATE(DOMWindow);
nsCOMPtr<nsIDOMDocument> DOMDocument;
DOMWindow->GetDocument(getter_AddRefs(DOMDocument));
NS_ENSURE_STATE(DOMDocument);
nsCOMPtr<nsIDocument> document(do_QueryInterface(DOMDocument));
// Document was loaded.
if (aStateFlags & STATE_STOP) {
#ifdef A11Y_LOG
if (logging::IsEnabled(logging::eDocLoad))
logging::DocLoad("document loaded", aWebProgress, aRequest, aStateFlags);
#endif
// Figure out an event type to notify the document has been loaded.
uint32_t eventType = nsIAccessibleEvent::EVENT_DOCUMENT_LOAD_STOPPED;
// Some XUL documents get start state and then stop state with failure
// status when everything is ok. Fire document load complete event in this
// case.
if (NS_SUCCEEDED(aStatus) || !nsCoreUtils::IsContentDocument(document))
eventType = nsIAccessibleEvent::EVENT_DOCUMENT_LOAD_COMPLETE;
// If end consumer has been retargeted for loaded content then do not fire
// any event because it means no new document has been loaded, for example,
// it happens when user clicks on file link.
if (aRequest) {
uint32_t loadFlags = 0;
aRequest->GetLoadFlags(&loadFlags);
if (loadFlags & nsIChannel::LOAD_RETARGETED_DOCUMENT_URI)
eventType = 0;
}
HandleDOMDocumentLoad(document, eventType);
return NS_OK;
}
// Document loading was started.
#ifdef A11Y_LOG
if (logging::IsEnabled(logging::eDocLoad))
logging::DocLoad("start document loading", aWebProgress, aRequest, aStateFlags);
#endif
DocAccessible* docAcc = GetExistingDocAccessible(document);
if (!docAcc)
return NS_OK;
nsCOMPtr<nsIWebNavigation> webNav(do_GetInterface(DOMWindow));
nsCOMPtr<nsIDocShell> docShell(do_QueryInterface(webNav));
NS_ENSURE_STATE(docShell);
bool isReloading = false;
uint32_t loadType;
docShell->GetLoadType(&loadType);
if (loadType == LOAD_RELOAD_NORMAL ||
loadType == LOAD_RELOAD_BYPASS_CACHE ||
loadType == LOAD_RELOAD_BYPASS_PROXY ||
loadType == LOAD_RELOAD_BYPASS_PROXY_AND_CACHE ||
loadType == LOAD_RELOAD_ALLOW_MIXED_CONTENT) {
isReloading = true;
}
docAcc->NotifyOfLoading(isReloading);
return NS_OK;
}
NS_IMETHODIMP
DocManager::OnProgressChange(nsIWebProgress* aWebProgress,
nsIRequest* aRequest,
int32_t aCurSelfProgress,
int32_t aMaxSelfProgress,
int32_t aCurTotalProgress,
int32_t aMaxTotalProgress)
{
NS_NOTREACHED("notification excluded in AddProgressListener(...)");
return NS_OK;
}
NS_IMETHODIMP
DocManager::OnLocationChange(nsIWebProgress* aWebProgress,
nsIRequest* aRequest, nsIURI* aLocation,
uint32_t aFlags)
{
NS_NOTREACHED("notification excluded in AddProgressListener(...)");
return NS_OK;
}
NS_IMETHODIMP
DocManager::OnStatusChange(nsIWebProgress* aWebProgress,
nsIRequest* aRequest, nsresult aStatus,
const PRUnichar* aMessage)
{
NS_NOTREACHED("notification excluded in AddProgressListener(...)");
return NS_OK;
}
NS_IMETHODIMP
DocManager::OnSecurityChange(nsIWebProgress* aWebProgress,
nsIRequest* aRequest,
uint32_t aState)
{
NS_NOTREACHED("notification excluded in AddProgressListener(...)");
return NS_OK;
}
////////////////////////////////////////////////////////////////////////////////
// nsIDOMEventListener
NS_IMETHODIMP
DocManager::HandleEvent(nsIDOMEvent* aEvent)
{
nsAutoString type;
aEvent->GetType(type);
nsCOMPtr<nsIDocument> document =
do_QueryInterface(aEvent->InternalDOMEvent()->GetTarget());
NS_ASSERTION(document, "pagehide or DOMContentLoaded for non document!");
if (!document)
return NS_OK;
if (type.EqualsLiteral("pagehide")) {
// 'pagehide' event is registered on every DOM document we create an
// accessible for, process the event for the target. This document
// accessible and all its sub document accessible are shutdown as result of
// processing.
#ifdef A11Y_LOG
if (logging::IsEnabled(logging::eDocDestroy))
logging::DocDestroy("received 'pagehide' event", document);
#endif
// Ignore 'pagehide' on temporary documents since we ignore them entirely in
// accessibility.
if (document->IsInitialDocument())
return NS_OK;
// Shutdown this one and sub document accessibles.
// We're allowed to not remove listeners when accessible document is
// shutdown since we don't keep strong reference on chrome event target and
// listeners are removed automatically when chrome event target goes away.
DocAccessible* docAccessible = GetExistingDocAccessible(document);
if (docAccessible)
docAccessible->Shutdown();
return NS_OK;
}
// XXX: handle error pages loading separately since they get neither
// webprogress notifications nor 'pageshow' event.
if (type.EqualsLiteral("DOMContentLoaded") &&
nsCoreUtils::IsErrorPage(document)) {
#ifdef A11Y_LOG
if (logging::IsEnabled(logging::eDocLoad))
logging::DocLoad("handled 'DOMContentLoaded' event", document);
#endif
HandleDOMDocumentLoad(document,
nsIAccessibleEvent::EVENT_DOCUMENT_LOAD_COMPLETE);
}
return NS_OK;
}
////////////////////////////////////////////////////////////////////////////////
// DocManager private
void
DocManager::HandleDOMDocumentLoad(nsIDocument* aDocument,
uint32_t aLoadEventType)
{
// Document accessible can be created before we were notified the DOM document
// was loaded completely. However if it's not created yet then create it.
DocAccessible* docAcc = GetExistingDocAccessible(aDocument);
if (!docAcc) {
docAcc = CreateDocOrRootAccessible(aDocument);
if (!docAcc)
return;
}
docAcc->NotifyOfLoad(aLoadEventType);
}
void
DocManager::AddListeners(nsIDocument* aDocument,
bool aAddDOMContentLoadedListener)
{
nsPIDOMWindow* window = aDocument->GetWindow();
EventTarget* target = window->GetChromeEventHandler();
nsEventListenerManager* elm = target->GetListenerManager(true);
elm->AddEventListenerByType(this, NS_LITERAL_STRING("pagehide"),
dom::TrustedEventsAtCapture());
#ifdef A11Y_LOG
if (logging::IsEnabled(logging::eDocCreate))
logging::Text("added 'pagehide' listener");
#endif
if (aAddDOMContentLoadedListener) {
elm->AddEventListenerByType(this, NS_LITERAL_STRING("DOMContentLoaded"),
dom::TrustedEventsAtCapture());
#ifdef A11Y_LOG
if (logging::IsEnabled(logging::eDocCreate))
logging::Text("added 'DOMContentLoaded' listener");
#endif
}
}
void
DocManager::RemoveListeners(nsIDocument* aDocument)
{
nsPIDOMWindow* window = aDocument->GetWindow();
if (!window)
return;
EventTarget* target = window->GetChromeEventHandler();
nsEventListenerManager* elm = target->GetListenerManager(true);
elm->RemoveEventListenerByType(this, NS_LITERAL_STRING("pagehide"),
dom::TrustedEventsAtCapture());
elm->RemoveEventListenerByType(this, NS_LITERAL_STRING("DOMContentLoaded"),
dom::TrustedEventsAtCapture());
}
DocAccessible*
DocManager::CreateDocOrRootAccessible(nsIDocument* aDocument)
{
// Ignore temporary, hiding, resource documents and documents without
// docshell.
if (aDocument->IsInitialDocument() ||
!aDocument->IsVisibleConsideringAncestors() ||
aDocument->IsResourceDoc() || !aDocument->IsActive())
return nullptr;
// Ignore documents without presshell and not having root frame.
nsIPresShell* presShell = aDocument->GetShell();
if (!presShell || presShell->IsDestroying())
return nullptr;
bool isRootDoc = nsCoreUtils::IsRootDocument(aDocument);
DocAccessible* parentDocAcc = nullptr;
if (!isRootDoc) {
// XXXaaronl: ideally we would traverse the presshell chain. Since there's
// no easy way to do that, we cheat and use the document hierarchy.
parentDocAcc = GetDocAccessible(aDocument->GetParentDocument());
NS_ASSERTION(parentDocAcc,
"Can't create an accessible for the document!");
if (!parentDocAcc)
return nullptr;
}
// We only create root accessibles for the true root, otherwise create a
// doc accessible.
nsIContent *rootElm = nsCoreUtils::GetRoleContent(aDocument);
nsRefPtr<DocAccessible> docAcc = isRootDoc ?
new RootAccessibleWrap(aDocument, rootElm, presShell) :
new DocAccessibleWrap(aDocument, rootElm, presShell);
// Cache the document accessible into document cache.
mDocAccessibleCache.Put(aDocument, docAcc);
// Initialize the document accessible.
docAcc->Init();
docAcc->SetRoleMapEntry(aria::GetRoleMap(aDocument));
// Bind the document to the tree.
if (isRootDoc) {
if (!ApplicationAcc()->AppendChild(docAcc)) {
docAcc->Shutdown();
return nullptr;
}
// Fire reorder event to notify new accessible document has been attached to
// the tree. The reorder event is delivered after the document tree is
// constructed because event processing and tree construction are done by
// the same document.
// Note: don't use AccReorderEvent to avoid coalsecense and special reorder
// events processing.
docAcc->FireDelayedEvent(nsIAccessibleEvent::EVENT_REORDER,
ApplicationAcc());
} else {
parentDocAcc->BindChildDocument(docAcc);
}
#ifdef A11Y_LOG
if (logging::IsEnabled(logging::eDocCreate)) {
logging::DocCreate("document creation finished", aDocument);
logging::Stack();
}
#endif
AddListeners(aDocument, isRootDoc);
return docAcc;
}
////////////////////////////////////////////////////////////////////////////////
// DocManager static
PLDHashOperator
DocManager::GetFirstEntryInDocCache(const nsIDocument* aKey,
DocAccessible* aDocAccessible,
void* aUserArg)
{
NS_ASSERTION(aDocAccessible,
"No doc accessible for the object in doc accessible cache!");
*reinterpret_cast<DocAccessible**>(aUserArg) = aDocAccessible;
return PL_DHASH_STOP;
}
void
DocManager::ClearDocCache()
{
DocAccessible* docAcc = nullptr;
while (mDocAccessibleCache.EnumerateRead(GetFirstEntryInDocCache, static_cast<void*>(&docAcc))) {
if (docAcc)
docAcc->Shutdown();
}
}
PLDHashOperator
DocManager::SearchAccessibleInDocCache(const nsIDocument* aKey,
DocAccessible* aDocAccessible,
void* aUserArg)
{
NS_ASSERTION(aDocAccessible,
"No doc accessible for the object in doc accessible cache!");
if (aDocAccessible) {
nsSearchAccessibleInCacheArg* arg =
static_cast<nsSearchAccessibleInCacheArg*>(aUserArg);
arg->mAccessible = aDocAccessible->GetAccessible(arg->mNode);
if (arg->mAccessible)
return PL_DHASH_STOP;
}
return PL_DHASH_NEXT;
}
#ifdef DEBUG
PLDHashOperator
DocManager::SearchIfDocIsRefreshing(const nsIDocument* aKey,
DocAccessible* aDocAccessible,
void* aUserArg)
{
NS_ASSERTION(aDocAccessible,
"No doc accessible for the object in doc accessible cache!");
if (aDocAccessible && aDocAccessible->mNotificationController &&
aDocAccessible->mNotificationController->IsUpdating()) {
*(static_cast<bool*>(aUserArg)) = true;
return PL_DHASH_STOP;
}
return PL_DHASH_NEXT;
}
#endif

Some files were not shown because too many files have changed in this diff Show More