зеркало из https://github.com/mozilla/gecko-dev.git
Back out JS-as-C++, because it's a suspect in the Linux performance regression.
--HG-- rename : js/src/js.cpp => js/src/js.c rename : js/src/jsapi.cpp => js/src/jsapi.c rename : js/src/jsarena.cpp => js/src/jsarena.c rename : js/src/jsarray.cpp => js/src/jsarray.c rename : js/src/jsatom.cpp => js/src/jsatom.c rename : js/src/jsbool.cpp => js/src/jsbool.c rename : js/src/jscntxt.cpp => js/src/jscntxt.c rename : js/src/jscpucfg.cpp => js/src/jscpucfg.c rename : js/src/jsdate.cpp => js/src/jsdate.c rename : js/src/jsdbgapi.cpp => js/src/jsdbgapi.c rename : js/src/jsdhash.cpp => js/src/jsdhash.c rename : js/src/jsdtoa.cpp => js/src/jsdtoa.c rename : js/src/jsemit.cpp => js/src/jsemit.c rename : js/src/jsexn.cpp => js/src/jsexn.c rename : js/src/jsfile.cpp => js/src/jsfile.c rename : js/src/jsfun.cpp => js/src/jsfun.c rename : js/src/jsgc.cpp => js/src/jsgc.c rename : js/src/jshash.cpp => js/src/jshash.c rename : js/src/jsinterp.cpp => js/src/jsinterp.c rename : js/src/jsinvoke.cpp => js/src/jsinvoke.c rename : js/src/jsiter.cpp => js/src/jsiter.c rename : js/src/jskwgen.cpp => js/src/jskwgen.c rename : js/src/jslock.cpp => js/src/jslock.c rename : js/src/jslog2.cpp => js/src/jslog2.c rename : js/src/jslong.cpp => js/src/jslong.c rename : js/src/jsmath.cpp => js/src/jsmath.c rename : js/src/jsnum.cpp => js/src/jsnum.c rename : js/src/jsobj.cpp => js/src/jsobj.c rename : js/src/jsopcode.cpp => js/src/jsopcode.c rename : js/src/jsparse.cpp => js/src/jsparse.c rename : js/src/jsprf.cpp => js/src/jsprf.c rename : js/src/jsregexp.cpp => js/src/jsregexp.c rename : js/src/jsscan.cpp => js/src/jsscan.c rename : js/src/jsscope.cpp => js/src/jsscope.c rename : js/src/jsscript.cpp => js/src/jsscript.c rename : js/src/jsstr.cpp => js/src/jsstr.c rename : js/src/jsutil.cpp => js/src/jsutil.c rename : js/src/jsxdrapi.cpp => js/src/jsxdrapi.c rename : js/src/jsxml.cpp => js/src/jsxml.c rename : js/src/prmjtime.cpp => js/src/prmjtime.c
This commit is contained in:
Коммит
5068d70767
35
.hgignore
35
.hgignore
|
@ -1,2 +1,33 @@
|
|||
CVS\/.*
|
||||
\.cvsignore$
|
||||
# .hgignore - List of filenames hg should ignore
|
||||
|
||||
# Filenames that should be ignored wherever they appear
|
||||
~$
|
||||
\.pyc$
|
||||
|
||||
# User files that may appear at the root
|
||||
^\.mozconfig$
|
||||
^mozconfig$
|
||||
^\.mozconfig\.mk$
|
||||
^\.mozconfig\.out$
|
||||
^configure$
|
||||
^config\.cache$
|
||||
^config\.log$
|
||||
|
||||
# Empty marker file that's generated when we check out NSS
|
||||
^security/manager/\.nss\.checkout$
|
||||
|
||||
# subtrees from other repositories
|
||||
^nsprpub/
|
||||
^dbm/
|
||||
^security/nss/
|
||||
^security/coreconf/
|
||||
^security/dbm/
|
||||
|
||||
# Build directories
|
||||
^obj-
|
||||
^objdir-
|
||||
|
||||
# Build directories for js shell
|
||||
_DBG\.OBJ/
|
||||
_OPT\.OBJ/
|
||||
|
||||
|
|
1
.hgtags
1
.hgtags
|
@ -1,2 +1,3 @@
|
|||
df7a3c8ffeeaba229067efee5a20e21dae0dd877 MOZILLA_1_9_a4_BASE
|
||||
4209e16b58411750ac73f761023e46b76b793e2c MOZILLA_1_9_a6_BASE
|
||||
66a5c7bce7ee86a820d3c0d54fa07cb719be751c MOZILLA_1_9_a7_BASE
|
||||
|
|
70
Makefile.in
70
Makefile.in
|
@ -47,8 +47,9 @@ include $(topsrcdir)/config/config.mk
|
|||
default alldep all::
|
||||
$(RM) -rf $(DIST)/sdk
|
||||
$(RM) -rf $(DIST)/include
|
||||
$(RM) -rf $(DIST)/private
|
||||
$(RM) -rf $(DIST)/public
|
||||
$(RM) -rf _tests
|
||||
$(MAKE) -C config export
|
||||
|
||||
TIERS += base
|
||||
|
||||
|
@ -58,8 +59,13 @@ TIERS += base
|
|||
tier_base_dirs = \
|
||||
config \
|
||||
build \
|
||||
probes \
|
||||
$(NULL)
|
||||
|
||||
ifdef MOZ_MEMORY
|
||||
tier_base_dirs += memory/jemalloc
|
||||
endif
|
||||
|
||||
include $(topsrcdir)/$(MOZ_BUILD_APP)/build.mk
|
||||
|
||||
TIERS += testharness
|
||||
|
@ -69,11 +75,11 @@ ifdef ENABLE_TESTS
|
|||
tier_testharness_dirs += tools/test-harness
|
||||
endif
|
||||
|
||||
GARBAGE_DIRS += dist
|
||||
GARBAGE_DIRS += dist _javagen _profile _tests staticlib
|
||||
DIST_GARBAGE = config.cache config.log config.status config-defs.h \
|
||||
dependencies.beos config/autoconf.mk config/myrules.mk config/myconfig.mk \
|
||||
unallmakefiles mozilla-config.h \
|
||||
gfx/gfx-config.h netwerk/necko-config.h xpcom/xpcom-config.h xpcom/xpcom-private.h \
|
||||
netwerk/necko-config.h xpcom/xpcom-config.h xpcom/xpcom-private.h \
|
||||
$(topsrcdir)/.mozconfig.mk $(topsrcdir)/.mozconfig.out
|
||||
|
||||
# Build pseudo-external modules first when export is explicitly called
|
||||
|
@ -82,11 +88,6 @@ export::
|
|||
$(MAKE) -C config export
|
||||
$(MAKE) tier_nspr
|
||||
|
||||
install::
|
||||
ifdef MOZ_LDAP_XPCOM
|
||||
$(MAKE) -C directory/c-sdk real_install DESTDIR=$(DESTDIR) libdir=$(mozappdir) includedir=$(includedir)/ldap
|
||||
endif
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
||||
# After we build tier toolkit, go back and build the tools from previous dirs
|
||||
|
@ -139,7 +140,14 @@ endif # WINNT
|
|||
ifeq ($(OS_ARCH),WINNT)
|
||||
# we want to copy PDB files on Windows
|
||||
MAKE_SYM_STORE_ARGS := -c
|
||||
DUMP_SYMS_BIN := $(topsrcdir)/toolkit/airbag/tools/win32/dump_syms.exe
|
||||
ifdef PDBSTR_PATH
|
||||
MAKE_SYM_STORE_ARGS += -i
|
||||
endif
|
||||
ifeq (,$(CYGWIN_WRAPPER))
|
||||
# this doesn't work with Cygwin Python
|
||||
MAKE_SYM_STORE_ARGS += --vcs-info
|
||||
endif
|
||||
DUMP_SYMS_BIN ?= $(topsrcdir)/toolkit/crashreporter/tools/win32/dump_syms.exe
|
||||
# PDB files don't get moved to dist, so we need to scan the whole objdir
|
||||
MAKE_SYM_STORE_PATH := .
|
||||
endif
|
||||
|
@ -152,11 +160,11 @@ else
|
|||
MAKE_SYM_STORE_ARGS := -a $(OS_TEST) --vcs-info
|
||||
MAKE_SYM_STORE_PATH := $(DIST)/bin
|
||||
endif
|
||||
DUMP_SYMS_BIN := $(DIST)/host/bin/dump_syms
|
||||
DUMP_SYMS_BIN ?= $(DIST)/host/bin/dump_syms
|
||||
endif
|
||||
ifeq ($(OS_ARCH),Linux)
|
||||
ifeq (,$(filter-out Linux SunOS,$(OS_ARCH)))
|
||||
MAKE_SYM_STORE_ARGS := --vcs-info
|
||||
DUMP_SYMS_BIN := $(DIST)/host/bin/dump_syms
|
||||
DUMP_SYMS_BIN ?= $(DIST)/host/bin/dump_syms
|
||||
MAKE_SYM_STORE_PATH := $(DIST)/bin
|
||||
endif
|
||||
|
||||
|
@ -164,26 +172,29 @@ ifdef MOZ_SYMBOLS_EXTRA_BUILDID
|
|||
EXTRA_BUILDID := -$(MOZ_SYMBOLS_EXTRA_BUILDID)
|
||||
endif
|
||||
|
||||
SYMBOL_ARCHIVE_BASENAME = \
|
||||
$(MOZ_APP_NAME)-$(MOZ_APP_VERSION)-$(OS_ARCH)-$(BUILDID)$(EXTRA_BUILDID)
|
||||
|
||||
buildsymbols:
|
||||
ifdef MOZ_AIRBAG
|
||||
ifdef MOZ_CRASHREPORTER
|
||||
echo building symbol store
|
||||
mkdir -p $(DIST)/crashreporter-symbols/$(BUILDID)
|
||||
$(PYTHON) $(topsrcdir)/toolkit/airbag/tools/symbolstore.py \
|
||||
$(PYTHON) $(topsrcdir)/toolkit/crashreporter/tools/symbolstore.py \
|
||||
$(MAKE_SYM_STORE_ARGS) -s $(topsrcdir) $(DUMP_SYMS_BIN) \
|
||||
$(DIST)/crashreporter-symbols/$(BUILDID) \
|
||||
$(MAKE_SYM_STORE_PATH) > \
|
||||
$(DIST)/crashreporter-symbols/$(BUILDID)/$(MOZ_APP_NAME)-$(MOZ_APP_VERSION)-$(OS_ARCH)-$(BUILDID)$(EXTRA_BUILDID)-symbols.txt
|
||||
$(DIST)/crashreporter-symbols/$(BUILDID)/$(SYMBOL_ARCHIVE_BASENAME)-symbols.txt
|
||||
echo packing symbols
|
||||
mkdir -p $(topsrcdir)/../$(BUILDID)
|
||||
cd $(DIST)/crashreporter-symbols/$(BUILDID) && \
|
||||
zip -r9D ../crashreporter-symbols-$(BUILDID).zip .
|
||||
mv $(DIST)/crashreporter-symbols/crashreporter-symbols-$(BUILDID).zip \
|
||||
zip -r9D ../crashreporter-symbols-$(SYMBOL_ARCHIVE_BASENAME).zip .
|
||||
mv $(DIST)/crashreporter-symbols/crashreporter-symbols-$(SYMBOL_ARCHIVE_BASENAME).zip \
|
||||
$(topsrcdir)/../$(BUILDID)
|
||||
endif # MOZ_AIRBAG
|
||||
endif # MOZ_CRASHREPORTER
|
||||
|
||||
uploadsymbols:
|
||||
ifdef MOZ_AIRBAG
|
||||
$(topsrcdir)/toolkit/airbag/tools/upload_symbols.sh $(topsrcdir)/../$(BUILDID)/crashreporter-symbols-$(BUILDID).zip
|
||||
ifdef MOZ_CRASHREPORTER
|
||||
$(topsrcdir)/toolkit/crashreporter/tools/upload_symbols.sh $(topsrcdir)/../$(BUILDID)/crashreporter-symbols-$(SYMBOL_ARCHIVE_BASENAME).zip
|
||||
endif
|
||||
|
||||
ifeq ($(OS_ARCH),WINNT)
|
||||
|
@ -198,4 +209,23 @@ deliver: splitsymbols rebase signnss
|
|||
|
||||
endif # WINNT
|
||||
|
||||
ifneq (,$(wildcard $(DIST)/bin/application.ini))
|
||||
BUILDID = $(shell $(PYTHON) $(srcdir)/config/printconfigsetting.py $(DIST)/bin/application.ini App BuildID)
|
||||
else
|
||||
BUILDID = $(shell $(PYTHON) $(srcdir)/config/printconfigsetting.py $(DIST)/bin/platform.ini Build BuildID)
|
||||
endif
|
||||
|
||||
#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: clobber_all
|
||||
else
|
||||
maybe_clobber_profiledbuild:
|
||||
endif
|
||||
else
|
||||
maybe_clobber_profiledbuild:
|
||||
endif
|
||||
|
||||
.PHONY: maybe_clobber_profiledbuild
|
||||
|
|
314
README.txt
314
README.txt
|
@ -1,306 +1,20 @@
|
|||
==============================================================
|
||||
For information on how to build Mozilla from the source code, see:
|
||||
|
||||
= = = = = = = = = = Mozilla Read Me = = = = = = = = = = =
|
||||
http://developer.mozilla.org/en/docs/Build_Documentation
|
||||
|
||||
==============================================================
|
||||
To have your bug fix / feature added to Mozilla, you should create a patch and
|
||||
submit it to Bugzilla (http://bugzilla.mozilla.org). Instructions are at:
|
||||
|
||||
Mozilla is subject to the terms detailed in the license
|
||||
agreement accompanying it.
|
||||
http://developer.mozilla.org/en/docs/Creating_a_patch
|
||||
http://developer.mozilla.org/en/docs/Getting_your_patch_in_the_tree
|
||||
|
||||
This Read Me file contains information about system
|
||||
requirements and installation instructions for the Windows,
|
||||
Mac OS, and Linux builds of Mozilla.
|
||||
If you have a question about developing Mozilla, and can't find the solution
|
||||
on http://developer.mozilla.org, you can try asking your question in a
|
||||
mozilla.* Usenet group, or on IRC at irc.mozilla.org. [The Mozilla news groups
|
||||
are accessible on Google Groups, or news.mozilla.org with a NNTP reader.]
|
||||
|
||||
For more info on Mozilla, see www.mozilla.org. To submit bugs
|
||||
or other feedback, see the Navigator QA menu and check out
|
||||
Bugzilla at http://bugzilla.mozilla.org for links to known
|
||||
bugs, bug-writing guidelines, and more. You can also get help
|
||||
with Bugzilla by pointing your IRC client to #mozillazine
|
||||
at irc.mozilla.org.
|
||||
You can download nightly development builds from the the Mozilla FTP server.
|
||||
Keep in mind that nightly builds, which are used by Mozilla developers for
|
||||
testing, may be buggy. Firefox nightlies, for example, can be found at:
|
||||
|
||||
|
||||
==============================================================
|
||||
|
||||
Getting Mozilla
|
||||
|
||||
==============================================================
|
||||
|
||||
You can download nightly builds of Mozilla from the
|
||||
Mozilla.org FTP site at
|
||||
|
||||
ftp://ftp.mozilla.org/pub/mozilla.org/mozilla/nightly/
|
||||
|
||||
For the very latest builds, see
|
||||
|
||||
ftp://ftp.mozilla.org/pub/mozilla.org/mozilla/nightly/latest-trunk
|
||||
|
||||
Keep in mind that nightly builds, which are used by
|
||||
Mozilla.org developers for testing, may be buggy. If you are
|
||||
looking for a more polished version of Mozilla, Mozilla.org
|
||||
releases Milestone builds of Mozilla every six weeks or so
|
||||
that you can download from
|
||||
|
||||
http://www.mozilla.org/releases
|
||||
|
||||
Be sure to read the Mozilla release notes for information
|
||||
on known problems and installation issues with Mozilla.
|
||||
The release notes can be found at the preceding URL along
|
||||
with the milestone releases themselves.
|
||||
|
||||
Note: Please use Talkback builds whenever possible. These
|
||||
builds allow transmission of crash data back to Mozilla
|
||||
developers, improved crash analysis, and posting of crash
|
||||
information to our crash-data newsgroup.
|
||||
|
||||
|
||||
==============================================================
|
||||
|
||||
System Requirements
|
||||
|
||||
==============================================================
|
||||
|
||||
*All Platforms
|
||||
|
||||
To view and use the new streamlined "Modern" theme,
|
||||
your display monitor should be set to display
|
||||
thousands of colors. For users who cannot set their
|
||||
displays to use more than 256 colors, Mozilla.org
|
||||
recommends using the "Classic" theme for Mozilla.
|
||||
|
||||
To select the Modern theme after you have installed
|
||||
Mozilla, from the Navigator browser, open the View
|
||||
menu, and then open then open the Apply Theme submenu
|
||||
and choose Modern.
|
||||
|
||||
*Mac OS
|
||||
|
||||
-Mac OS X or later
|
||||
-PowerPC processor (266 MHz or faster recommended)
|
||||
-64 MB RAM
|
||||
-36 MB of free hard disk space
|
||||
|
||||
*Windows
|
||||
|
||||
-Windows 95, 98, Me, NT4, 2000 or XP
|
||||
-Intel Pentium class processor (233 MHz or faster
|
||||
recommended)
|
||||
-64 MB RAM
|
||||
-26 MB free hard disk space
|
||||
|
||||
*Linux
|
||||
|
||||
-The following library versions (or compatible) are
|
||||
required: glibc 2.1, XFree86 3.3.x, GTK 1.2.x, Glib
|
||||
1.2.x, Libstdc++ 2.9.0. Red Hat Linux 6.0,
|
||||
Debian 2.1, and SuSE 6.2 (or later) installations
|
||||
should work.
|
||||
-Red Hat 6.x users who want to install the Mozilla
|
||||
RPM must have at least version 4.0.2 of rpm
|
||||
installed.
|
||||
-Intel Pentium class processor (233 MHz or faster
|
||||
recommended)
|
||||
-64MB RAM
|
||||
-26MB free hard disk space
|
||||
|
||||
|
||||
==============================================================
|
||||
|
||||
Installation Instructions
|
||||
|
||||
==============================================================
|
||||
|
||||
For Mac OS and Windows users, it is strongly recommended that
|
||||
you exit all programs before running the setup program. Also,
|
||||
you should temporarily disable virus-detection software.
|
||||
|
||||
For Linux users, note that the installation instructions use
|
||||
the bash shell. If you're not using bash, adjust the commands
|
||||
accordingly.
|
||||
|
||||
For all platforms, install into a clean (new) directory.
|
||||
Installing on top of previously released builds may cause
|
||||
problems.
|
||||
|
||||
Note: These instructions do not tell you how to build Mozilla.
|
||||
For info on building the Mozilla source, see
|
||||
|
||||
http://www.mozilla.org/source.html
|
||||
|
||||
|
||||
Windows Installation Instructions
|
||||
---------------------------------
|
||||
|
||||
Note: For Windows NT/2000/XP systems, you need Administrator
|
||||
privileges to install Mozilla. If you see an "Error 5" message
|
||||
during installation, make sure you're running the installation
|
||||
with Administrator privileges.
|
||||
|
||||
|
||||
To install Mozilla by downloading the Mozilla installer,
|
||||
follow these steps:
|
||||
|
||||
1. Click the the mozilla-win32-installer.exe link on
|
||||
the site you're downloading Mozilla from to download
|
||||
the installer file to your machine.
|
||||
|
||||
2. Navigate to where you downloaded the file and
|
||||
double-click the Mozilla program icon on your machine
|
||||
to begin the Setup program.
|
||||
|
||||
3. Follow the on-screen instructions in the setup
|
||||
program. The program starts automatically the first
|
||||
time.
|
||||
|
||||
|
||||
To install Mozilla by downloading the .zip file and
|
||||
installing manually, follow these steps:
|
||||
|
||||
1. Click the mozilla-win32-talkback.zip link or the
|
||||
mozilla-win32.zip link on the site you're down-
|
||||
loading Mozilla from to download the .zip file to
|
||||
your machine.
|
||||
|
||||
2. Navigate to where you downloaded the file and
|
||||
double-click the compressed file.
|
||||
|
||||
Note: This step assumes you already have a recent
|
||||
version of WinZip installed, and that you know how to
|
||||
use it. If not, you can get WinZip and information
|
||||
about the program at www.winzip.com.
|
||||
|
||||
3. Extract the .zip file to a directory such as
|
||||
C:\Program Files\mozilla.org\Mozilla.
|
||||
|
||||
4. To start Mozilla, navigate to the directory you
|
||||
extracted Mozilla to and double-click the Mozilla.exe
|
||||
icon.
|
||||
|
||||
|
||||
Mac OS X Installation Instructions
|
||||
----------------------------------
|
||||
|
||||
To install Mozilla by downloading the Mozilla disk image,
|
||||
follow these steps:
|
||||
|
||||
1. Click the mozilla-mac-MachO.dmg.gz link to download
|
||||
it to your machine. By default, the download file is
|
||||
downloaded to your desktop.
|
||||
|
||||
2. Once you have downloaded the .dmg.gz file, drag it
|
||||
onto Stuffit Expander to decompress it. If the disk
|
||||
image doesn't mount automatically, double-click on the
|
||||
.dmg file to mount it. If that fails, and the file
|
||||
does not look like a disk image file, do a "Show Info"
|
||||
on the file, and, in the "Open with application"
|
||||
category, choose Disk Copy. In Mac OS 10.2, you can
|
||||
use "Open with" from the context menu.
|
||||
|
||||
3. Once the disk image mounts, open it, and drag the
|
||||
Mozilla icon onto your hard disk.
|
||||
|
||||
4. We recommend that you copy it to the Applications
|
||||
folder.
|
||||
|
||||
5. Now Eject the disk image.
|
||||
|
||||
6. If you like, you can drag Mozilla to your dock to
|
||||
have it easily accessible at all times. You might also
|
||||
wish to select Mozilla as your default browser in the
|
||||
Internet system preferences pane (under the Web tab).
|
||||
|
||||
|
||||
Linux Installation Instructions
|
||||
-------------------------------
|
||||
|
||||
Note: If you install in the default directory (which is
|
||||
usually /usr/local/mozilla), or any other directory where
|
||||
only the root user normally has write-access, you must
|
||||
start Mozilla first as root before other users can start
|
||||
the program. Doing so generates a set of files required
|
||||
for later use by other users.
|
||||
|
||||
|
||||
To install Mozilla by downloading the Mozilla installer,
|
||||
follow these steps:
|
||||
|
||||
1. Create a directory named mozilla (mkdir mozilla)
|
||||
and change to that directory (cd mozilla).
|
||||
|
||||
2. Click the link on the site you're downloading
|
||||
Mozilla from to download the installer file
|
||||
(called mozilla-1686-pc-linux-gnu-installer.tar.gz)
|
||||
to your machine.
|
||||
|
||||
3. Change to the mozilla directory (cd mozilla) and
|
||||
decompress the archive with the following command:
|
||||
|
||||
tar zxvf moz*.tar.gz
|
||||
|
||||
The installer is now located in a subdirectory of
|
||||
Mozilla named mozilla-installer.
|
||||
|
||||
4. Change to the mozilla-installer directory
|
||||
(cd mozilla-installer) and run the installer with the
|
||||
./mozilla-installer command.
|
||||
|
||||
5. Follow the instructions in the install wizard for
|
||||
installing Mozilla.
|
||||
|
||||
Note: If you have a slower machine, be aware that the
|
||||
installation may take some time. In this case, the
|
||||
installation progress may appear to hang indefinitely,
|
||||
even though the installation is still in process.
|
||||
|
||||
6. To start Mozilla, change to the directory where you
|
||||
installed it and run the ./mozilla command.
|
||||
|
||||
|
||||
To install Mozilla by downloading the tar.gz file:
|
||||
|
||||
1. Create a directory named "mozilla" (mkdir mozilla)
|
||||
and change to that directory (cd mozilla).
|
||||
|
||||
2. Click the link on the site you're downloading
|
||||
Mozilla from to download the non-installer
|
||||
(mozilla*.tar.gz) file into the mozilla directory.
|
||||
|
||||
3. Change to the mozilla directory (cd mozilla) and
|
||||
decompress the file with the following command:
|
||||
|
||||
tar zxvf moz*.tar.gz
|
||||
|
||||
This creates a "mozilla" directory under your mozilla
|
||||
directory.
|
||||
|
||||
4. Change to the mozilla directory (cd mozilla).
|
||||
|
||||
5. Run Mozilla with the following run script:
|
||||
|
||||
./mozilla
|
||||
|
||||
|
||||
To hook up Mozilla complete with icon to the GNOME Panel,
|
||||
follow these steps:
|
||||
|
||||
1. Click the GNOME Main Menu button, open the Panel menu,
|
||||
and then open the Add to Panel submenu and choose Launcher.
|
||||
|
||||
2. Right-click the icon for Mozilla on the Panel and
|
||||
enter the following command:
|
||||
directory_name./mozilla
|
||||
|
||||
where directory_name is the name of the directory
|
||||
you downloaded mozilla to. For example, the default
|
||||
directory that Mozilla suggests is /usr/local/mozilla.
|
||||
|
||||
3. Type in a name for the icon, and type in a comment
|
||||
if you wish.
|
||||
|
||||
4. Click the icon button and type in the following as
|
||||
the icon's location:
|
||||
|
||||
directory_name/icons/mozicon50.xpm
|
||||
|
||||
where directory name is the directory where you
|
||||
installed Mozilla. For example, the default directory
|
||||
is /usr/local/mozilla/icons/mozicon50.xpm.
|
||||
ftp://ftp.mozilla.org/pub/firefox/nightly/latest-trunk/
|
||||
|
|
|
@ -43,7 +43,7 @@ VPATH = @srcdir@
|
|||
include $(DEPTH)/config/autoconf.mk
|
||||
|
||||
MODULE = accessibility
|
||||
DIRS = public src build
|
||||
DIRS = public src build tests
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
||||
|
|
|
@ -79,6 +79,7 @@ endif
|
|||
|
||||
EXTRA_DSO_LIBS = \
|
||||
gkgfx \
|
||||
thebes \
|
||||
$(NULL)
|
||||
|
||||
EXTRA_DSO_LDOPTS = \
|
||||
|
@ -92,10 +93,6 @@ ifeq ($(MOZ_WIDGET_TOOLKIT),gtk2)
|
|||
EXTRA_DSO_LDOPTS += $(MOZ_GTK2_LIBS)
|
||||
endif
|
||||
|
||||
ifeq ($(MOZ_WIDGET_TOOLKIT),cocoa)
|
||||
EXTRA_DSO_LDOPTS += -framework Cocoa
|
||||
endif
|
||||
|
||||
ifeq ($(OS_ARCH),WINNT)
|
||||
OS_LIBS += oleaut32.lib
|
||||
endif
|
||||
|
|
|
@ -105,17 +105,29 @@ include $(topsrcdir)/config/rules.mk
|
|||
|
||||
OS_LIBS = \
|
||||
kernel32.lib \
|
||||
rpcndr.lib \
|
||||
rpcns4.lib \
|
||||
rpcrt4.lib \
|
||||
ole32.lib \
|
||||
oleaut32.lib \
|
||||
$(NULL)
|
||||
|
||||
$(MIDL_GENERATED_FILES): $(addprefix $(IA2DIR)/,$(MIDL_INTERFACES) $(MIDL_ENUMS))
|
||||
for idl in $^; do \
|
||||
# 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::
|
||||
|
|
|
@ -87,7 +87,6 @@ SRCDIR_CSRCS = $(addprefix $(srcdir)/,$(CSRCS))
|
|||
|
||||
OS_LIBS = \
|
||||
kernel32.lib \
|
||||
rpcndr.lib \
|
||||
rpcns4.lib \
|
||||
rpcrt4.lib \
|
||||
oleaut32.lib \
|
||||
|
|
|
@ -44,19 +44,19 @@ interface nsIDocument;
|
|||
interface nsIFrame;
|
||||
interface nsObjectFrame;
|
||||
interface nsIContent;
|
||||
interface nsITimer;
|
||||
|
||||
[uuid(0e9e2f00-b6f1-440d-821f-6b09d264cdaf)]
|
||||
[uuid(27386cf1-f27e-4d2d-9bf4-c4621d50d299)]
|
||||
interface nsIAccessibilityService : nsIAccessibleRetrieval
|
||||
{
|
||||
nsIAccessible createOuterDocAccessible(in nsIDOMNode aNode);
|
||||
nsIAccessible createRootAccessible(in nsIPresShell aShell, in nsIDocument aDocument);
|
||||
|
||||
nsIAccessible createHTML4ButtonAccessible(in nsISupports aFrame);
|
||||
nsIAccessible createHTMLAreaAccessible(in nsIWeakReference aPresShell, in nsIDOMNode aDOMNode, in nsIAccessible aAccParent);
|
||||
nsIAccessible createHyperTextAccessible(in nsISupports aFrame);
|
||||
nsIAccessible createHTMLBRAccessible(in nsISupports aFrame);
|
||||
nsIAccessible createHTMLButtonAccessible(in nsISupports aFrame);
|
||||
nsIAccessible createHTMLAccessibleByMarkup(in nsIFrame aFrame, in nsIWeakReference aWeakShell, in nsIDOMNode aDOMNode, in AString aRole);
|
||||
nsIAccessible createHTMLAccessibleByMarkup(in nsIFrame aFrame, in nsIWeakReference aWeakShell, in nsIDOMNode aDOMNode);
|
||||
nsIAccessible createHTMLLIAccessible(in nsISupports aFrame, in nsISupports aBulletFrame, in AString aBulletText);
|
||||
nsIAccessible createHTMLCheckboxAccessible(in nsISupports aFrame);
|
||||
nsIAccessible createHTMLComboboxAccessible(in nsIDOMNode aNode, in nsIWeakReference aPresShell);
|
||||
|
@ -101,6 +101,17 @@ interface nsIAccessibilityService : nsIAccessibleRetrieval
|
|||
void invalidateSubtreeFor(in nsIPresShell aPresShell,
|
||||
in nsIContent aChangedContent,
|
||||
in PRUint32 aEvent);
|
||||
|
||||
/**
|
||||
* An internal doc load event has occured. Handle the event and remove it from the list.
|
||||
* @param aTimer The timer created to handle this doc load event
|
||||
* @param aClosure The nsIWebProgress* for the load event
|
||||
* @param aEventType The type of load event, one of: nsIAccessibleEvent::EVENT_DOCUMENT_LOAD_START,
|
||||
* nsIAccessibleEvent::EVENT_DOCUMENT_LOAD_COMPLETE or
|
||||
* nsIAccessibleEvent::EVENT_DOCUMENT_LOAD_STOPPED
|
||||
*/
|
||||
void processDocLoadEvent(in nsITimer aTimer, in voidPtr aClosure, in PRUint32 aEventType);
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -186,7 +186,8 @@ interface nsIAccessible : nsISupports
|
|||
* 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
|
||||
* @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,
|
||||
|
@ -194,6 +195,10 @@ interface nsIAccessible : nsISupports
|
|||
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
nsIAccessible getChildAtPoint(in long x, in long y);
|
||||
|
||||
|
|
|
@ -58,7 +58,7 @@ interface nsIDOMWindow;
|
|||
*
|
||||
* @status UNDER_REVIEW
|
||||
*/
|
||||
[scriptable, uuid(6cc11286-e02d-4a8d-960a-e7a61161b230)]
|
||||
[scriptable, uuid(b7ae45bd-21e9-4ed5-a67e-86448b25d56b)]
|
||||
interface nsIAccessibleDocument : nsISupports
|
||||
{
|
||||
/**
|
||||
|
@ -120,5 +120,6 @@ interface nsIAccessibleDocument : nsISupports
|
|||
* @return An first nsIAccessible found by crawling up the DOM node
|
||||
* to the document root.
|
||||
*/
|
||||
nsIAccessible getAccessibleInParentChain(in nsIDOMNode aDOMNode);
|
||||
nsIAccessible getAccessibleInParentChain(in nsIDOMNode aDOMNode,
|
||||
in boolean aCanCreate);
|
||||
};
|
||||
|
|
|
@ -61,38 +61,41 @@ interface nsIDOMNode;
|
|||
*
|
||||
* @status UNDER_REVIEW
|
||||
*/
|
||||
[scriptable, uuid(18612bcb-79bd-45c1-92e9-07aded5fd0f5)]
|
||||
[scriptable, uuid(ba448f0e-a761-48c8-a0f5-1f25e23d4fe4)]
|
||||
interface nsIAccessibleEvent : nsISupports
|
||||
{
|
||||
/**
|
||||
* An object has been created.
|
||||
*/
|
||||
const unsigned long EVENT_CREATE = 0x0001;
|
||||
const unsigned long EVENT_DOM_CREATE = 0x0001;
|
||||
|
||||
/**
|
||||
* An object has been destroyed.
|
||||
*/
|
||||
const unsigned long EVENT_DESTROY = 0x0002;
|
||||
const unsigned long EVENT_DOM_DESTROY = 0x0002;
|
||||
|
||||
/**
|
||||
* A hidden object is shown.
|
||||
* An object's properties or content have changed significantly so that the
|
||||
* type of object has really changed, and therefore the accessible should be
|
||||
* destroyed or recreated.
|
||||
*/
|
||||
const unsigned long EVENT_SHOW = 0x0003;
|
||||
const unsigned long EVENT_DOM_SIGNIFICANT_CHANGE = 0x0003;
|
||||
|
||||
/**
|
||||
* An object is hidden.
|
||||
* A hidden object is shown -- this is a layout occurance and is thus asynchronous
|
||||
*/
|
||||
const unsigned long EVENT_HIDE = 0x0004;
|
||||
const unsigned long EVENT_ASYNCH_SHOW = 0x0004;
|
||||
|
||||
/**
|
||||
* A container object has added, removed, or reordered its children.
|
||||
* An object is hidden -- this is a layout occurance and is thus asynchronous
|
||||
*/
|
||||
const unsigned long EVENT_REORDER = 0x0005;
|
||||
const unsigned long EVENT_ASYNCH_HIDE = 0x0005;
|
||||
|
||||
/**
|
||||
* An object has a new parent object.
|
||||
* An object had a significant layout change which could affect
|
||||
* the type of accessible object -- this is a layout occurance and is thus asynchronous
|
||||
*/
|
||||
const unsigned long EVENT_PARENT_CHANGE = 0x0006;
|
||||
const unsigned long EVENT_ASYNCH_SIGNIFICANT_CHANGE = 0x0006;
|
||||
|
||||
/**
|
||||
* The active descendant of a component has changed. The active descendant
|
||||
|
@ -469,10 +472,15 @@ interface nsIAccessibleEvent : nsISupports
|
|||
*/
|
||||
const unsigned long EVENT_INTERNAL_LOAD = 0x005B;
|
||||
|
||||
/**
|
||||
* An object's children have changed
|
||||
*/
|
||||
const unsigned long EVENT_REORDER = 0x005C;
|
||||
|
||||
/**
|
||||
* Help make sure event map does not get out-of-line.
|
||||
*/
|
||||
const unsigned long EVENT_LAST_ENTRY = 0x005C;
|
||||
const unsigned long EVENT_LAST_ENTRY = 0x005D;
|
||||
|
||||
/**
|
||||
* The type of event, based on the enumerated event values
|
||||
|
@ -498,6 +506,12 @@ interface nsIAccessibleEvent : nsISupports
|
|||
* 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
|
||||
*/
|
||||
attribute boolean isFromUserInput;
|
||||
};
|
||||
|
||||
|
||||
|
@ -539,6 +553,11 @@ interface nsIAccessibleTextChangeEvent : nsIAccessibleEvent
|
|||
* Returns true if text was inserted, otherwise false.
|
||||
*/
|
||||
boolean isInserted();
|
||||
|
||||
/**
|
||||
* The inserted or removed text
|
||||
*/
|
||||
readonly attribute DOMString modifiedText;
|
||||
};
|
||||
|
||||
[scriptable, uuid(b9076dce-4cd3-4e3d-a7f6-7f33a7f40c31)]
|
||||
|
@ -550,3 +569,17 @@ interface nsIAccessibleCaretMoveEvent: nsIAccessibleEvent
|
|||
readonly attribute long caretOffset;
|
||||
};
|
||||
|
||||
[scriptable, uuid(a9485c7b-5861-4695-8441-fab0235b205d)]
|
||||
interface nsIAccessibleTableChangeEvent: nsIAccessibleEvent
|
||||
{
|
||||
/**
|
||||
* Return the row or column index.
|
||||
*/
|
||||
readonly attribute long rowOrColIndex;
|
||||
|
||||
/**
|
||||
* Return the number of rows or cols
|
||||
*/
|
||||
readonly attribute long numRowsOrCols;
|
||||
};
|
||||
|
||||
|
|
|
@ -43,19 +43,73 @@
|
|||
interface nsIURI;
|
||||
interface nsIAccessible;
|
||||
|
||||
[scriptable, uuid(a492c7d6-1dd1-11b2-9bc0-80614884799a)]
|
||||
/**
|
||||
* 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
|
||||
{
|
||||
readonly attribute long anchors;
|
||||
/**
|
||||
* 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;
|
||||
|
||||
nsIURI getURI (in long i);
|
||||
/**
|
||||
* 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;
|
||||
|
||||
nsIAccessible getObject (in long i);
|
||||
/**
|
||||
* 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;
|
||||
|
||||
boolean isValid ();
|
||||
boolean isSelected ();
|
||||
/**
|
||||
* 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);
|
||||
};
|
||||
|
||||
/*
|
||||
|
|
|
@ -42,16 +42,38 @@
|
|||
#include "nsISupports.idl"
|
||||
#include "nsIAccessibleHyperLink.idl"
|
||||
|
||||
[scriptable, uuid(dec56474-2887-4d44-9826-1594cfe4a2f4)]
|
||||
/**
|
||||
* A cross-platform interface that deals with text which contains hyperlinks.
|
||||
*/
|
||||
|
||||
[scriptable, uuid(d56bd454-8ff3-4edc-b266-baeada00267b)]
|
||||
interface nsIAccessibleHyperText : nsISupports
|
||||
{
|
||||
readonly attribute long links;
|
||||
|
||||
nsIAccessibleHyperLink getLink (in long index);
|
||||
/**
|
||||
* Returns the number of links contained within this hypertext object.
|
||||
*/
|
||||
readonly attribute long linkCount;
|
||||
|
||||
/*
|
||||
* Return the link index at this character index.
|
||||
* Return value of -1 indicates no link at that index.
|
||||
* Returns the link index at the given character index.
|
||||
* Each link is an embedded object representing exactly 1 character within
|
||||
* the hypertext.
|
||||
*
|
||||
* @param charIndex the 0-based character index.
|
||||
*
|
||||
* @returns long 0-based link's index.
|
||||
* A return value of -1 indicates no link is present at that index.
|
||||
*/
|
||||
long getLinkIndex(in long charIndex);
|
||||
|
||||
/**
|
||||
* Retrieves the nsIAccessibleHyperLink object at the given link index.
|
||||
*
|
||||
* @param linkIndex 0-based index of the link that is to be retrieved.
|
||||
* This can be retrieved via getLinkIndex (see above).
|
||||
*
|
||||
* @returns nsIAccessibleHyperLink Object representing the link properties
|
||||
* or NS_ERROR_INVALID_ARG if there is no link at that index.
|
||||
*/
|
||||
nsIAccessibleHyperLink getLink(in long linkIndex);
|
||||
};
|
||||
|
|
|
@ -40,11 +40,27 @@
|
|||
*
|
||||
* @status UNDER_REVIEW
|
||||
*/
|
||||
[scriptable, uuid(6e80cec3-ff7f-48f2-9823-0b962a0ed508)]
|
||||
[scriptable, uuid(09086623-0f09-4310-ac56-c2cda7c29648)]
|
||||
interface nsIAccessibleImage : nsISupports
|
||||
{
|
||||
void getImageBounds(out long x,
|
||||
out long y,
|
||||
out long width,
|
||||
out long height);
|
||||
/**
|
||||
* 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);
|
||||
};
|
||||
|
||||
|
|
|
@ -45,13 +45,19 @@
|
|||
object. For that XBL binding of element should implement the interface.
|
||||
*/
|
||||
|
||||
[scriptable, uuid(7250d0f0-732d-4981-b73e-dd5d71b16183)]
|
||||
[scriptable, uuid(3f7f9194-c625-4a85-8148-6d92d34897fa)]
|
||||
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;
|
||||
|
@ -69,37 +75,43 @@ interface nsIAccessibleProvider : nsISupports
|
|||
const long XULDropmarker = 0x00001007;
|
||||
const long XULGroupbox = 0x00001008;
|
||||
const long XULImage = 0x00001009;
|
||||
const long XULLink = 0x00001010;
|
||||
const long XULListbox = 0x00001011;
|
||||
const long XULListitem = 0x00001012;
|
||||
const long XULMenubar = 0x00001013;
|
||||
const long XULMenuitem = 0x00001014;
|
||||
const long XULMenupopup = 0x00001015;
|
||||
const long XULMenuSeparator = 0x00001016;
|
||||
const long XULProgressMeter = 0x00001017;
|
||||
const long XULStatusBar = 0x00001018;
|
||||
const long XULRadioButton = 0x00001019;
|
||||
const long XULRadioGroup = 0x00001020;
|
||||
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;
|
||||
|
||||
/** The single tab in a dialog or tabbrowser/editor interface */
|
||||
const long XULTab = 0x00001021;
|
||||
const long XULTab = 0x00001017;
|
||||
|
||||
/** A combination of a tabs object and a tabpanels object */
|
||||
const long XULTabBox = 0x00001022;
|
||||
const long XULTabBox = 0x00001018;
|
||||
|
||||
/** The collection of tab objects, useable in the TabBox and independant of
|
||||
as well */
|
||||
const long XULTabs = 0x00001023;
|
||||
const long XULTabs = 0x00001019;
|
||||
|
||||
const long XULText = 0x00001024;
|
||||
const long XULTextBox = 0x00001025;
|
||||
const long XULTree = 0x00001026;
|
||||
const long XULTreeColumns = 0x00001027;
|
||||
const long XULTreeColumnitem = 0x00001028;
|
||||
const long XULToolbar = 0x00001029;
|
||||
const long XULToolbarSeparator = 0x00001030;
|
||||
const long XULTooltip = 0x00001031;
|
||||
const long XULToolbarButton = 0x00001032;
|
||||
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;
|
||||
|
||||
|
||||
/**
|
||||
|
|
|
@ -57,6 +57,9 @@ interface nsIAccessibleRelation : nsISupports
|
|||
*/
|
||||
const unsigned long RELATION_CONTROLLED_BY = 0x01;
|
||||
|
||||
// First relation
|
||||
const unsigned long RELATION_FIRST = RELATION_CONTROLLED_BY;
|
||||
|
||||
/**
|
||||
* This object is interactive and controls some attribute of a target object.
|
||||
*/
|
||||
|
@ -135,6 +138,9 @@ interface nsIAccessibleRelation : nsISupports
|
|||
*/
|
||||
const unsigned long RELATION_DESCRIPTION_FOR = 0x0f;
|
||||
|
||||
// Last relation that is standard to desktop accessibility APIs
|
||||
const unsigned long RELATION_LAST = RELATION_DESCRIPTION_FOR;
|
||||
|
||||
/**
|
||||
* Part of a form/dialog with a related default button. It is used for
|
||||
* MSAA only, no for IA2 nor ATK.
|
||||
|
|
|
@ -56,7 +56,7 @@ interface nsIDOMDOMStringList;
|
|||
*
|
||||
* @status UNDER_REVIEW
|
||||
*/
|
||||
[scriptable, uuid(2d8c1b1b-7a3f-4962-8a88-81ca019c11e9)]
|
||||
[scriptable, uuid(244e4c67-a1d3-44f2-9cab-cdaa31b68046)]
|
||||
interface nsIAccessibleRetrieval : nsISupports
|
||||
{
|
||||
/**
|
||||
|
@ -155,7 +155,24 @@ interface nsIAccessibleRetrieval : nsISupports
|
|||
* @param aStates - accessible states.
|
||||
* @param aExtraStates - accessible extra states.
|
||||
*/
|
||||
nsIDOMDOMStringList getStringStates(in unsigned long aStates, in unsigned long aExtraStates);
|
||||
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);
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -44,7 +44,7 @@
|
|||
* @note - When adding a new role, be sure to also add it to nsRoleMap.h for
|
||||
* each platform.
|
||||
*/
|
||||
[scriptable, uuid(d6d73bc4-0fe9-46a1-a8dd-6d93b041e54b)]
|
||||
[scriptable, uuid(8c0f68f8-164a-4078-a9ee-36a7d180f0e4)]
|
||||
interface nsIAccessibleRole : nsISupports
|
||||
{
|
||||
/**
|
||||
|
@ -61,7 +61,7 @@ interface nsIAccessibleRole : nsISupports
|
|||
/**
|
||||
* 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="wairole:menubar".
|
||||
* xul:menubar or role="menubar".
|
||||
*/
|
||||
const unsigned long ROLE_MENUBAR = 2;
|
||||
|
||||
|
@ -98,7 +98,7 @@ interface nsIAccessibleRole : nsISupports
|
|||
* 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="wairole:alert", xforms:message.
|
||||
* role="alert", xforms:message.
|
||||
*/
|
||||
const unsigned long ROLE_ALERT = 8;
|
||||
|
||||
|
@ -110,20 +110,20 @@ interface nsIAccessibleRole : nsISupports
|
|||
const unsigned long ROLE_WINDOW = 9;
|
||||
|
||||
/**
|
||||
* XXX: document this.
|
||||
* A sub-document (<frame> or <iframe>)
|
||||
*/
|
||||
const unsigned long ROLE_CLIENT = 10;
|
||||
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="wairole:menu".
|
||||
* 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="wairole:menuitem".
|
||||
* role="menuitem".
|
||||
*/
|
||||
const unsigned long ROLE_MENUITEM = 12;
|
||||
|
||||
|
@ -134,13 +134,13 @@ interface nsIAccessibleRole : nsISupports
|
|||
|
||||
/**
|
||||
* Represents a main window for an application. It is used for
|
||||
* role="wairole:application". Also refer to ROLE_APP_ROOT
|
||||
* 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="wairole:document".
|
||||
* an application window. It is used for role="document".
|
||||
*/
|
||||
const unsigned long ROLE_DOCUMENT = 15;
|
||||
|
||||
|
@ -160,7 +160,7 @@ interface nsIAccessibleRole : nsISupports
|
|||
|
||||
/**
|
||||
* Represents a dialog box or message box. It is used for xul:dialog,
|
||||
* role="wairole:dialog".
|
||||
* role="dialog".
|
||||
*/
|
||||
const unsigned long ROLE_DIALOG = 18;
|
||||
|
||||
|
@ -172,21 +172,21 @@ interface nsIAccessibleRole : nsISupports
|
|||
/**
|
||||
* 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="wairole:group".
|
||||
* 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="wairole:separator".
|
||||
* 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="wairole:toolbar".
|
||||
* is used for xul:toolbar, role="toolbar".
|
||||
*/
|
||||
const unsigned long ROLE_TOOLBAR = 22;
|
||||
|
||||
|
@ -201,7 +201,7 @@ interface nsIAccessibleRole : nsISupports
|
|||
/**
|
||||
* Represents a table that contains rows and columns of cells, and optionally,
|
||||
* row headers and column headers. It is used for html:table,
|
||||
* role="wairole:grid". Also refer to the following roles: ROLE_COLUMNHEADER,
|
||||
* role="grid". Also refer to the following roles: ROLE_COLUMNHEADER,
|
||||
* ROLE_ROWHEADER, ROLE_COLUMN, ROLE_ROW, ROLE_CELL.
|
||||
*/
|
||||
const unsigned long ROLE_TABLE = 24;
|
||||
|
@ -209,13 +209,13 @@ interface nsIAccessibleRole : nsISupports
|
|||
/**
|
||||
* 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="wairole:colheader". Also refer to ROLE_TABLE.
|
||||
* 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="wairole:rowheader". Also, see ROLE_TABLE.
|
||||
* It is used for role="rowheader". Also, see ROLE_TABLE.
|
||||
*/
|
||||
const unsigned long ROLE_ROWHEADER = 26;
|
||||
|
||||
|
@ -231,7 +231,7 @@ interface nsIAccessibleRole : nsISupports
|
|||
|
||||
/**
|
||||
* Represents a cell within a table. Is is used for html:td,
|
||||
* role="wairole:gridcell". Also, see ROLE_TABLE.
|
||||
* role="gridcell". Also, see ROLE_TABLE.
|
||||
*/
|
||||
const unsigned long ROLE_CELL = 29;
|
||||
|
||||
|
@ -256,7 +256,7 @@ interface nsIAccessibleRole : nsISupports
|
|||
|
||||
/**
|
||||
* Represents a list box, allowing the user to select one or more items. It
|
||||
* is used for xul:listbox, html:select@size, role="wairole:list". See also
|
||||
* is used for xul:listbox, html:select@size, role="list". See also
|
||||
* ROLE_LIST_ITEM.
|
||||
*/
|
||||
const unsigned long ROLE_LIST = 33;
|
||||
|
@ -269,25 +269,25 @@ interface nsIAccessibleRole : nsISupports
|
|||
/**
|
||||
* 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="wairole:tree".
|
||||
* 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="wairole:treeitem".
|
||||
* 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="wairole:treeitem". Also refer to ROLE_PAGETABLIST.
|
||||
* 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="wairole:tabpanel".
|
||||
* role="tabpanel".
|
||||
*/
|
||||
const unsigned long ROLE_PROPERTYPAGE = 38;
|
||||
|
||||
|
@ -306,7 +306,7 @@ interface nsIAccessibleRole : nsISupports
|
|||
* 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:lablel,
|
||||
* role="wairole:label" or role="wairole:description", xforms:output.
|
||||
* role="label" or role="description", xforms:output.
|
||||
*/
|
||||
const unsigned long ROLE_STATICTEXT = 41;
|
||||
|
||||
|
@ -317,13 +317,13 @@ interface nsIAccessibleRole : nsISupports
|
|||
|
||||
/**
|
||||
* Represents a push button control. It is used for xul:button, html:button,
|
||||
* role="wairole:button", xforms:trigger, xforms:submit.
|
||||
* role="button", xforms:trigger, xforms:submit.
|
||||
*/
|
||||
const unsigned long ROLE_PUSHBUTTON = 43;
|
||||
|
||||
/**
|
||||
* Represents a check box control. It is used for xul:checkbox,
|
||||
* html:input@type="checkbox", role="wairole:checkbox", boolean xforms:input.
|
||||
* html:input@type="checkbox", role="checkbox", boolean xforms:input.
|
||||
*/
|
||||
const unsigned long ROLE_CHECKBUTTON = 44;
|
||||
|
||||
|
@ -332,14 +332,14 @@ interface nsIAccessibleRole : nsISupports
|
|||
* 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="wairole: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="wairole:combobox".
|
||||
* xul:menulist, role="combobox".
|
||||
*/
|
||||
const unsigned long ROLE_COMBOBOX = 46;
|
||||
|
||||
|
@ -351,7 +351,7 @@ interface nsIAccessibleRole : nsISupports
|
|||
/**
|
||||
* Represents a progress bar, dynamically showing the user the percent
|
||||
* complete of an operation in progress. It is used for xul:progressmeter,
|
||||
* role="wairole:progressbar".
|
||||
* role="progressbar".
|
||||
*/
|
||||
const unsigned long ROLE_PROGRESSBAR = 48;
|
||||
|
||||
|
@ -369,7 +369,7 @@ interface nsIAccessibleRole : nsISupports
|
|||
/**
|
||||
* 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="wairole:slider", xforms:range.
|
||||
* role="slider", xforms:range.
|
||||
*/
|
||||
const unsigned long ROLE_SLIDER = 51;
|
||||
|
||||
|
@ -392,7 +392,8 @@ interface nsIAccessibleRole : nsISupports
|
|||
const unsigned long ROLE_ANIMATION = 54;
|
||||
|
||||
/**
|
||||
* Represents a mathematical equation. It is used by MATHML.
|
||||
* 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;
|
||||
|
||||
|
@ -418,7 +419,7 @@ interface nsIAccessibleRole : nsISupports
|
|||
|
||||
/**
|
||||
* Represents a container of page tab controls. Is it used for xul:tabs,
|
||||
* DHTML: role="wairole:tabs". Also refer to ROLE_PAGETAB.
|
||||
* DHTML: role="tabs". Also refer to ROLE_PAGETAB.
|
||||
*/
|
||||
const unsigned long ROLE_PAGETABLIST = 60;
|
||||
|
||||
|
@ -741,12 +742,37 @@ interface nsIAccessibleRole : nsISupports
|
|||
/**
|
||||
* A item of list that is shown by combobox;
|
||||
*/
|
||||
const unsigned long ROLE_COMBOBOX_LISTITEM = 115;
|
||||
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;
|
||||
|
||||
/**
|
||||
* It's not role actually. This contanst is important to help ensure
|
||||
* nsRoleMap's are synchronized.
|
||||
*/
|
||||
const unsigned long ROLE_LAST_ENTRY = 116;
|
||||
const unsigned long ROLE_LAST_ENTRY = 121;
|
||||
};
|
||||
|
||||
|
|
|
@ -45,9 +45,15 @@ typedef long nsAccessibleTextBoundary;
|
|||
|
||||
interface nsIAccessible;
|
||||
|
||||
[scriptable, uuid(17389a66-5cc5-4550-80e0-49e7b63990a4)]
|
||||
[scriptable, uuid(caa4f543-070e-4705-8428-2e53575c41bb)]
|
||||
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 PRInt32 TEXT_OFFSET_END_OF_TEXT = -1;
|
||||
const PRInt32 TEXT_OFFSET_CARET = -2;
|
||||
|
||||
const nsAccessibleTextBoundary BOUNDARY_CHAR = 0;
|
||||
const nsAccessibleTextBoundary BOUNDARY_WORD_START = 1;
|
||||
const nsAccessibleTextBoundary BOUNDARY_WORD_END = 2;
|
||||
|
@ -57,6 +63,10 @@ interface nsIAccessibleText : nsISupports
|
|||
const nsAccessibleTextBoundary BOUNDARY_LINE_END = 6;
|
||||
const nsAccessibleTextBoundary 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;
|
||||
|
@ -160,6 +170,9 @@ interface nsIAccessibleText : nsISupports
|
|||
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);
|
||||
|
@ -167,6 +180,36 @@ interface nsIAccessibleText : nsISupports
|
|||
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);
|
||||
};
|
||||
|
||||
/*
|
||||
|
|
|
@ -19,6 +19,10 @@
|
|||
* Portions created by the Initial Developer are Copyright (C) 2002
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Louie Zhao <Louie.Zhao@sun.com> (original author)
|
||||
* Alexander Surkov <surkov.alexander@gmail.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
|
@ -37,17 +41,55 @@
|
|||
#include "nsITreeColumns.idl"
|
||||
|
||||
interface nsIAccessible;
|
||||
|
||||
/**
|
||||
* A cross-platform interface that supports cache for tree item
|
||||
* A private interface to operate with tree accessible.
|
||||
*
|
||||
* @status UNDER_REVIEW
|
||||
*/
|
||||
[scriptable, uuid(CC742DA2-9C25-4D04-96CD-DA407D676C6D)]
|
||||
[uuid(7e0f50b0-6444-4372-b00f-4ce81c6b058a)]
|
||||
interface nsIAccessibleTreeCache : nsISupports
|
||||
{
|
||||
/**
|
||||
* Get tree item from cache according to row and column, create if doesn't exist in cache
|
||||
* "aColumn" can be nsnull
|
||||
* Get tree item from cache according to row and column, create if doesn't
|
||||
* exist in cache.
|
||||
*
|
||||
* @param aRow the given row index
|
||||
* @param aColumn the given column object. If is is nsnull then primary
|
||||
* column is used. It makes sense for ATK only.
|
||||
*/
|
||||
[noscript] nsIAccessible getCachedTreeitemAccessible(in PRInt32 aRow, in nsITreeColumn aColumn);
|
||||
nsIAccessible getCachedTreeitemAccessible(in long aRow,
|
||||
in nsITreeColumn aColumn);
|
||||
|
||||
/**
|
||||
* Invalidates the number of cached treeitem accessibles.
|
||||
*
|
||||
* @param aRow row index the invalidation starts from
|
||||
* @param aCount the number of treeitem accessibles to invalidate,
|
||||
* the number sign specifies whether rows have been
|
||||
* inserted (plus) or removed (minus)
|
||||
*/
|
||||
void invalidateCache(in long aRow, in long aCount);
|
||||
|
||||
/**
|
||||
* Fires name change events for invalidated area of tree.
|
||||
*
|
||||
* @param aStartRow row index invalidation starts from
|
||||
* @param aEndRow row index invalidation ends, -1 means last row index
|
||||
* @param aStartCol column index invalidation starts from
|
||||
* @param aEndCol column index invalidation ends, -1 mens last column
|
||||
* index
|
||||
*/
|
||||
void treeViewInvalidated(in long aStartRow, in long aEndRow,
|
||||
in long aStartCol, in long aEndCol);
|
||||
};
|
||||
|
||||
[uuid(b71532f9-53b2-4647-a5b2-1c5f57e9aed6)]
|
||||
interface nsPIAccessibleTreeItem : nsISupports
|
||||
{
|
||||
/**
|
||||
* Get/set cached name.
|
||||
*/
|
||||
attribute AString cachedName;
|
||||
};
|
||||
|
||||
|
|
|
@ -80,12 +80,17 @@ interface nsIAccessibleScrollType : nsISupports
|
|||
* 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. Note,
|
||||
* keep them synchronized with IA2CoordinateType.
|
||||
* These constants define which coordinate system a point is located in.
|
||||
*/
|
||||
[scriptable, uuid(c9fbdf10-619e-436f-bf4b-8566686f1577)]
|
||||
interface nsIAccessibleCoordinateType : nsISupports
|
||||
|
@ -106,3 +111,4 @@ interface nsIAccessibleCoordinateType : nsISupports
|
|||
*/
|
||||
const unsigned long COORDTYPE_PARENT_RELATIVE = 0x02;
|
||||
};
|
||||
|
||||
|
|
|
@ -40,8 +40,12 @@
|
|||
|
||||
interface nsIAccessible;
|
||||
interface nsIAccessibleEvent;
|
||||
%{C++
|
||||
struct nsRoleMapEntry;
|
||||
%}
|
||||
[ptr] native nsRoleMapEntryPtr(nsRoleMapEntry);
|
||||
|
||||
[uuid(817ae493-b238-4fbc-a623-d20ed81eebcd)]
|
||||
[uuid(893ee16d-c157-4d5f-b236-60b3b2bef6a5)]
|
||||
interface nsPIAccessible : nsISupports
|
||||
{
|
||||
/**
|
||||
|
@ -64,6 +68,11 @@ interface nsPIAccessible : nsISupports
|
|||
*/
|
||||
void getCachedParent(out nsIAccessible aAccParent);
|
||||
|
||||
/**
|
||||
* Return first child accessible only if cached.
|
||||
*/
|
||||
void getCachedFirstChild(out nsIAccessible aAccFirstChild);
|
||||
|
||||
/**
|
||||
* Set the child count to -1 (unknown) and null out cached child pointers
|
||||
*/
|
||||
|
@ -74,12 +83,10 @@ interface nsPIAccessible : nsISupports
|
|||
*
|
||||
* @param aEvent - DOM event
|
||||
* @param aTarget - target of DOM event
|
||||
* @param aData - additional information for accessible event.
|
||||
*
|
||||
* XXX: eventually this method will be removed (see bug 377022)
|
||||
*/
|
||||
void fireToolkitEvent(in unsigned long aEvent, in nsIAccessible aTarget,
|
||||
in voidPtr aData);
|
||||
void fireToolkitEvent(in unsigned long aEvent, in nsIAccessible aTarget);
|
||||
|
||||
/**
|
||||
* Fire accessible event.
|
||||
|
@ -100,6 +107,23 @@ interface nsPIAccessible : nsISupports
|
|||
* Returns text of accessible if accessible has text role otherwise empty
|
||||
* string.
|
||||
*/
|
||||
AString getContentText();
|
||||
void appendTextTo(out AString aString, in unsigned long aStartOffset,
|
||||
in unsigned long aLength);
|
||||
|
||||
/**
|
||||
* Set the ARIA role map entry for a new accessible.
|
||||
* For a newly created accessible, specify which role map entry should be used.
|
||||
* @param aRoleMapEntry The ARIA nsRoleMapEntry* for the accessible, or
|
||||
* nsnull if none.
|
||||
*/
|
||||
void setRoleMapEntry(in nsRoleMapEntryPtr aRoleMapEntry);
|
||||
|
||||
/**
|
||||
* Maps ARIA state attributes to state of accessible. Note the given state
|
||||
* argument should hold states for accessible before you pass it into this
|
||||
* method.
|
||||
* @param in/out where to fill the states into.
|
||||
*/
|
||||
void getARIAState(out unsigned long aState);
|
||||
};
|
||||
|
||||
|
|
|
@ -41,7 +41,7 @@
|
|||
interface nsIAccessNode;
|
||||
interface nsIContent;
|
||||
|
||||
[uuid(08811f23-1298-4882-9a68-6f1466c28007)]
|
||||
[uuid(fa9cafac-9562-49ad-afcf-911ab1e4e4fb)]
|
||||
|
||||
interface nsPIAccessibleDocument : nsISupports
|
||||
{
|
||||
|
@ -61,7 +61,6 @@ interface nsPIAccessibleDocument : nsISupports
|
|||
void invalidateCacheSubtree(in nsIContent aChangeContent,
|
||||
in PRUint32 aChangeEvent);
|
||||
void cacheAccessNode(in voidPtr aUniqueID, in nsIAccessNode aAccessNode);
|
||||
void destroy();
|
||||
void flushPendingEvents();
|
||||
void fireDocLoadEvents(in PRUint32 aEventType);
|
||||
void fireAnchorJumpEvent();
|
||||
|
|
|
@ -50,6 +50,7 @@ REQUIRES = content \
|
|||
dom \
|
||||
editor \
|
||||
gfx \
|
||||
thebes \
|
||||
intl \
|
||||
layout \
|
||||
locale \
|
||||
|
|
|
@ -124,6 +124,8 @@ static GType GetAtkTypeForMai(MaiInterfaceType type)
|
|||
return G_TYPE_INVALID;
|
||||
}
|
||||
|
||||
static const char* kNonUserInputEvent = ":system";
|
||||
|
||||
static const GInterfaceInfo atk_if_infos[] = {
|
||||
{(GInterfaceInitFunc)componentInterfaceInitCB,
|
||||
(GInterfaceFinalizeFunc) NULL, NULL},
|
||||
|
@ -300,6 +302,7 @@ nsAccessibleWrap::nsAccessibleWrap(nsIDOMNode* aNode,
|
|||
|
||||
nsAccessibleWrap::~nsAccessibleWrap()
|
||||
{
|
||||
NS_ASSERTION(!mAtkObject, "ShutdownAtkObject() is not called");
|
||||
|
||||
#ifdef MAI_LOGGING
|
||||
++mAccWrapDeleted;
|
||||
|
@ -425,9 +428,6 @@ nsAccessibleWrap::CreateMaiInterfaces(void)
|
|||
interfacesBits |= 1 << MAI_INTERFACE_ACTION;
|
||||
}
|
||||
|
||||
PRUint32 accRole;
|
||||
GetRole(&accRole);
|
||||
|
||||
//nsIAccessibleText
|
||||
nsCOMPtr<nsIAccessibleText> accessInterfaceText;
|
||||
QueryInterface(NS_GET_IID(nsIAccessibleText),
|
||||
|
@ -444,14 +444,6 @@ nsAccessibleWrap::CreateMaiInterfaces(void)
|
|||
interfacesBits |= 1 << MAI_INTERFACE_EDITABLE_TEXT;
|
||||
}
|
||||
|
||||
//nsIAccessibleSelection
|
||||
nsCOMPtr<nsIAccessibleSelectable> accessInterfaceSelection;
|
||||
QueryInterface(NS_GET_IID(nsIAccessibleSelectable),
|
||||
getter_AddRefs(accessInterfaceSelection));
|
||||
if (accessInterfaceSelection) {
|
||||
interfacesBits |= 1 << MAI_INTERFACE_SELECTION;
|
||||
}
|
||||
|
||||
//nsIAccessibleValue
|
||||
nsCOMPtr<nsIAccessibleValue> accessInterfaceValue;
|
||||
QueryInterface(NS_GET_IID(nsIAccessibleValue),
|
||||
|
@ -460,34 +452,6 @@ nsAccessibleWrap::CreateMaiInterfaces(void)
|
|||
interfacesBits |= 1 << MAI_INTERFACE_VALUE;
|
||||
}
|
||||
|
||||
//nsIAccessibleHypertext
|
||||
PRInt32 linkCount = 0;
|
||||
nsCOMPtr<nsIAccessibleHyperText> accessInterfaceHypertext;
|
||||
QueryInterface(NS_GET_IID(nsIAccessibleHyperText),
|
||||
getter_AddRefs(accessInterfaceHypertext));
|
||||
if (accessInterfaceHypertext) {
|
||||
nsresult rv = accessInterfaceHypertext->GetLinks(&linkCount);
|
||||
if (NS_SUCCEEDED(rv) && (linkCount > 0)) {
|
||||
interfacesBits |= 1 << MAI_INTERFACE_HYPERTEXT;
|
||||
}
|
||||
}
|
||||
|
||||
//nsIAccessibleHyperLink
|
||||
nsCOMPtr<nsIAccessibleHyperLink> accessInterfaceHyperlink;
|
||||
QueryInterface(NS_GET_IID(nsIAccessibleHyperLink),
|
||||
getter_AddRefs(accessInterfaceHyperlink));
|
||||
if (accessInterfaceHyperlink) {
|
||||
interfacesBits |= 1 << MAI_INTERFACE_HYPERLINK_IMPL;
|
||||
}
|
||||
|
||||
//nsIAccessibleTable
|
||||
nsCOMPtr<nsIAccessibleTable> accessInterfaceTable;
|
||||
QueryInterface(NS_GET_IID(nsIAccessibleTable),
|
||||
getter_AddRefs(accessInterfaceTable));
|
||||
if (accessInterfaceTable) {
|
||||
interfacesBits |= 1 << MAI_INTERFACE_TABLE;
|
||||
}
|
||||
|
||||
//nsIAccessibleDocument
|
||||
nsCOMPtr<nsIAccessibleDocument> accessInterfaceDocument;
|
||||
QueryInterface(NS_GET_IID(nsIAccessibleDocument),
|
||||
|
@ -504,6 +468,40 @@ nsAccessibleWrap::CreateMaiInterfaces(void)
|
|||
interfacesBits |= 1 << MAI_INTERFACE_IMAGE;
|
||||
}
|
||||
|
||||
//nsIAccessibleHyperLink
|
||||
nsCOMPtr<nsIAccessibleHyperLink> accessInterfaceHyperlink;
|
||||
QueryInterface(NS_GET_IID(nsIAccessibleHyperLink),
|
||||
getter_AddRefs(accessInterfaceHyperlink));
|
||||
if (accessInterfaceHyperlink) {
|
||||
interfacesBits |= 1 << MAI_INTERFACE_HYPERLINK_IMPL;
|
||||
}
|
||||
|
||||
if (!MustPrune(this)) { // These interfaces require children
|
||||
//nsIAccessibleHypertext
|
||||
nsCOMPtr<nsIAccessibleHyperText> accessInterfaceHypertext;
|
||||
QueryInterface(NS_GET_IID(nsIAccessibleHyperText),
|
||||
getter_AddRefs(accessInterfaceHypertext));
|
||||
if (accessInterfaceHypertext) {
|
||||
interfacesBits |= 1 << MAI_INTERFACE_HYPERTEXT;
|
||||
}
|
||||
|
||||
//nsIAccessibleTable
|
||||
nsCOMPtr<nsIAccessibleTable> accessInterfaceTable;
|
||||
QueryInterface(NS_GET_IID(nsIAccessibleTable),
|
||||
getter_AddRefs(accessInterfaceTable));
|
||||
if (accessInterfaceTable) {
|
||||
interfacesBits |= 1 << MAI_INTERFACE_TABLE;
|
||||
}
|
||||
|
||||
//nsIAccessibleSelection
|
||||
nsCOMPtr<nsIAccessibleSelectable> accessInterfaceSelection;
|
||||
QueryInterface(NS_GET_IID(nsIAccessibleSelectable),
|
||||
getter_AddRefs(accessInterfaceSelection));
|
||||
if (accessInterfaceSelection) {
|
||||
interfacesBits |= 1 << MAI_INTERFACE_SELECTION;
|
||||
}
|
||||
}
|
||||
|
||||
return interfacesBits;
|
||||
}
|
||||
|
||||
|
@ -796,20 +794,14 @@ GetAttributeSet(nsIAccessible* aAccessible)
|
|||
|
||||
if (attributes) {
|
||||
// Deal with attributes that we only need to expose in ATK
|
||||
PRUint32 state, extraState;
|
||||
aAccessible->GetFinalState(&state, &extraState);
|
||||
PRUint32 state;
|
||||
aAccessible->GetFinalState(&state, nsnull);
|
||||
if (state & nsIAccessibleStates::STATE_HASPOPUP) {
|
||||
// There is no ATK state for haspopup, must use object attribute to expose the same info
|
||||
nsAutoString oldValueUnused;
|
||||
attributes->SetStringProperty(NS_LITERAL_CSTRING("haspopup"), NS_LITERAL_STRING("true"),
|
||||
oldValueUnused);
|
||||
}
|
||||
if (state & nsIAccessibleStates::STATE_CHECKABLE) {
|
||||
// There is no ATK state for haspopup, must use object attribute to expose the same info
|
||||
nsAutoString oldValueUnused;
|
||||
attributes->SetStringProperty(NS_LITERAL_CSTRING("checkable"), NS_LITERAL_STRING("true"),
|
||||
oldValueUnused);
|
||||
}
|
||||
|
||||
nsCOMPtr<nsISimpleEnumerator> propEnum;
|
||||
nsresult rv = attributes->Enumerate(getter_AddRefs(propEnum));
|
||||
|
@ -872,7 +864,7 @@ gint
|
|||
getChildCountCB(AtkObject *aAtkObj)
|
||||
{
|
||||
nsAccessibleWrap *accWrap = GetAccessibleWrap(aAtkObj);
|
||||
if (!accWrap) {
|
||||
if (!accWrap || nsAccessibleWrap::MustPrune(accWrap)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -881,7 +873,7 @@ getChildCountCB(AtkObject *aAtkObj)
|
|||
accWrap->QueryInterface(NS_GET_IID(nsIAccessibleHyperText), getter_AddRefs(hyperText));
|
||||
if (hyperText) {
|
||||
// If HyperText, then number of links matches number of children
|
||||
hyperText->GetLinks(&count);
|
||||
hyperText->GetLinkCount(&count);
|
||||
}
|
||||
else {
|
||||
nsCOMPtr<nsIAccessibleText> accText;
|
||||
|
@ -906,29 +898,28 @@ refChildCB(AtkObject *aAtkObj, gint aChildIndex)
|
|||
// or we should cache an array of children in each nsAccessible
|
||||
// (instead of mNextSibling on the children)
|
||||
nsAccessibleWrap *accWrap = GetAccessibleWrap(aAtkObj);
|
||||
if (!accWrap) {
|
||||
if (!accWrap || nsAccessibleWrap::MustPrune(accWrap)) {
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsIAccessible> accChild;
|
||||
nsCOMPtr<nsIAccessibleHyperText> hyperText;
|
||||
accWrap->QueryInterface(NS_GET_IID(nsIAccessibleHyperText), getter_AddRefs(hyperText));
|
||||
if (hyperText) {
|
||||
// If HyperText, then number of links matches number of children
|
||||
nsCOMPtr<nsIAccessibleHyperLink> hyperLink;
|
||||
rv = hyperText->GetLink(aChildIndex, getter_AddRefs(hyperLink));
|
||||
hyperText->GetLink(aChildIndex, getter_AddRefs(hyperLink));
|
||||
accChild = do_QueryInterface(hyperLink);
|
||||
}
|
||||
else {
|
||||
nsCOMPtr<nsIAccessibleText> accText;
|
||||
accWrap->QueryInterface(NS_GET_IID(nsIAccessibleText), getter_AddRefs(accText));
|
||||
if (!accText) { // Accessible Text that is not HyperText has no children
|
||||
rv = accWrap->GetChildAt(aChildIndex, getter_AddRefs(accChild));
|
||||
accWrap->GetChildAt(aChildIndex, getter_AddRefs(accChild));
|
||||
}
|
||||
}
|
||||
|
||||
if (NS_FAILED(rv) || !accChild)
|
||||
if (!accChild)
|
||||
return nsnull;
|
||||
|
||||
AtkObject* childAtkObj = nsAccessibleWrap::GetAtkObject(accChild);
|
||||
|
@ -1118,16 +1109,15 @@ nsAccessibleWrap::FireAccessibleEvent(nsIAccessibleEvent *aEvent)
|
|||
rv = aEvent->GetEventType(&type);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsAccEvent *event = reinterpret_cast<nsAccEvent*>(aEvent);
|
||||
void *eventData = event->mEventData;
|
||||
|
||||
AtkObject *atkObj = nsAccessibleWrap::GetAtkObject(accessible);
|
||||
|
||||
// We don't create ATK objects for nsIAccessible plain text leaves,
|
||||
// just return NS_OK in such case
|
||||
if (!atkObj) {
|
||||
NS_ASSERTION(type == nsIAccessibleEvent::EVENT_SHOW ||
|
||||
type == nsIAccessibleEvent::EVENT_HIDE,
|
||||
NS_ASSERTION(type == nsIAccessibleEvent::EVENT_ASYNCH_SHOW ||
|
||||
type == nsIAccessibleEvent::EVENT_ASYNCH_HIDE ||
|
||||
type == nsIAccessibleEvent::EVENT_DOM_CREATE ||
|
||||
type == nsIAccessibleEvent::EVENT_DOM_DESTROY,
|
||||
"Event other than SHOW and HIDE fired for plain text leaves");
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -1137,18 +1127,14 @@ nsAccessibleWrap::FireAccessibleEvent(nsIAccessibleEvent *aEvent)
|
|||
return NS_OK; // Node is shut down
|
||||
}
|
||||
|
||||
AtkTableChange * pAtkTableChange = nsnull;
|
||||
|
||||
switch (type) {
|
||||
case nsIAccessibleEvent::EVENT_STATE_CHANGE:
|
||||
return FireAtkStateChangeEvent(aEvent, atkObj);
|
||||
|
||||
case nsIAccessibleEvent::EVENT_TEXT_CHANGED:
|
||||
case nsIAccessibleEvent::EVENT_TEXT_REMOVED:
|
||||
case nsIAccessibleEvent::EVENT_TEXT_INSERTED:
|
||||
return FireAtkTextChangedEvent(aEvent, atkObj);
|
||||
|
||||
case nsIAccessibleEvent::EVENT_PROPERTY_CHANGED:
|
||||
return FireAtkPropChangedEvent(aEvent, atkObj);
|
||||
|
||||
case nsIAccessibleEvent::EVENT_FOCUS:
|
||||
{
|
||||
MAI_LOG_DEBUG(("\n\nReceived: EVENT_FOCUS\n"));
|
||||
|
@ -1210,73 +1196,83 @@ nsAccessibleWrap::FireAccessibleEvent(nsIAccessibleEvent *aEvent)
|
|||
break;
|
||||
|
||||
case nsIAccessibleEvent::EVENT_TABLE_ROW_INSERT:
|
||||
{
|
||||
MAI_LOG_DEBUG(("\n\nReceived: EVENT_TABLE_ROW_INSERT\n"));
|
||||
NS_ASSERTION(eventData, "Event needs event data");
|
||||
if (!eventData)
|
||||
break;
|
||||
nsCOMPtr<nsIAccessibleTableChangeEvent> tableEvent = do_QueryInterface(aEvent);
|
||||
NS_ENSURE_TRUE(tableEvent, NS_ERROR_FAILURE);
|
||||
|
||||
pAtkTableChange = reinterpret_cast<AtkTableChange *>(eventData);
|
||||
PRInt32 rowIndex, numRows;
|
||||
tableEvent->GetRowOrColIndex(&rowIndex);
|
||||
tableEvent->GetNumRowsOrCols(&numRows);
|
||||
|
||||
g_signal_emit_by_name(atkObj,
|
||||
"row_inserted",
|
||||
// After which the rows are inserted
|
||||
pAtkTableChange->index,
|
||||
rowIndex,
|
||||
// The number of the inserted
|
||||
pAtkTableChange->count);
|
||||
break;
|
||||
numRows);
|
||||
} break;
|
||||
|
||||
case nsIAccessibleEvent::EVENT_TABLE_ROW_DELETE:
|
||||
{
|
||||
MAI_LOG_DEBUG(("\n\nReceived: EVENT_TABLE_ROW_DELETE\n"));
|
||||
NS_ASSERTION(eventData, "Event needs event data");
|
||||
if (!eventData)
|
||||
break;
|
||||
nsCOMPtr<nsIAccessibleTableChangeEvent> tableEvent = do_QueryInterface(aEvent);
|
||||
NS_ENSURE_TRUE(tableEvent, NS_ERROR_FAILURE);
|
||||
|
||||
pAtkTableChange = reinterpret_cast<AtkTableChange *>(eventData);
|
||||
PRInt32 rowIndex, numRows;
|
||||
tableEvent->GetRowOrColIndex(&rowIndex);
|
||||
tableEvent->GetNumRowsOrCols(&numRows);
|
||||
|
||||
g_signal_emit_by_name(atkObj,
|
||||
"row_deleted",
|
||||
// After which the rows are deleted
|
||||
pAtkTableChange->index,
|
||||
rowIndex,
|
||||
// The number of the deleted
|
||||
pAtkTableChange->count);
|
||||
break;
|
||||
numRows);
|
||||
} break;
|
||||
|
||||
case nsIAccessibleEvent::EVENT_TABLE_ROW_REORDER:
|
||||
{
|
||||
MAI_LOG_DEBUG(("\n\nReceived: EVENT_TABLE_ROW_REORDER\n"));
|
||||
g_signal_emit_by_name(atkObj, "row_reordered");
|
||||
break;
|
||||
}
|
||||
|
||||
case nsIAccessibleEvent::EVENT_TABLE_COLUMN_INSERT:
|
||||
{
|
||||
MAI_LOG_DEBUG(("\n\nReceived: EVENT_TABLE_COLUMN_INSERT\n"));
|
||||
NS_ASSERTION(eventData, "Event needs event data");
|
||||
if (!eventData)
|
||||
break;
|
||||
nsCOMPtr<nsIAccessibleTableChangeEvent> tableEvent = do_QueryInterface(aEvent);
|
||||
NS_ENSURE_TRUE(tableEvent, NS_ERROR_FAILURE);
|
||||
|
||||
pAtkTableChange = reinterpret_cast<AtkTableChange *>(eventData);
|
||||
PRInt32 colIndex, numCols;
|
||||
tableEvent->GetRowOrColIndex(&colIndex);
|
||||
tableEvent->GetNumRowsOrCols(&numCols);
|
||||
|
||||
g_signal_emit_by_name(atkObj,
|
||||
"column_inserted",
|
||||
// After which the columns are inserted
|
||||
pAtkTableChange->index,
|
||||
colIndex,
|
||||
// The number of the inserted
|
||||
pAtkTableChange->count);
|
||||
break;
|
||||
numCols);
|
||||
} break;
|
||||
|
||||
case nsIAccessibleEvent::EVENT_TABLE_COLUMN_DELETE:
|
||||
{
|
||||
MAI_LOG_DEBUG(("\n\nReceived: EVENT_TABLE_COLUMN_DELETE\n"));
|
||||
NS_ASSERTION(eventData, "Event needs event data");
|
||||
if (!eventData)
|
||||
break;
|
||||
nsCOMPtr<nsIAccessibleTableChangeEvent> tableEvent = do_QueryInterface(aEvent);
|
||||
NS_ENSURE_TRUE(tableEvent, NS_ERROR_FAILURE);
|
||||
|
||||
pAtkTableChange = reinterpret_cast<AtkTableChange *>(eventData);
|
||||
PRInt32 colIndex, numCols;
|
||||
tableEvent->GetRowOrColIndex(&colIndex);
|
||||
tableEvent->GetNumRowsOrCols(&numCols);
|
||||
|
||||
g_signal_emit_by_name(atkObj,
|
||||
"column_deleted",
|
||||
// After which the columns are deleted
|
||||
pAtkTableChange->index,
|
||||
colIndex,
|
||||
// The number of the deleted
|
||||
pAtkTableChange->count);
|
||||
break;
|
||||
numCols);
|
||||
} break;
|
||||
|
||||
case nsIAccessibleEvent::EVENT_TABLE_COLUMN_REORDER:
|
||||
MAI_LOG_DEBUG(("\n\nReceived: EVENT_TABLE_COLUMN_REORDER\n"));
|
||||
|
@ -1288,19 +1284,12 @@ nsAccessibleWrap::FireAccessibleEvent(nsIAccessibleEvent *aEvent)
|
|||
g_signal_emit_by_name(atkObj, "visible_data_changed");
|
||||
break;
|
||||
|
||||
case nsIAccessibleEvent::EVENT_HYPERTEXT_LINK_SELECTED:
|
||||
MAI_LOG_DEBUG(("\n\nReceived: EVENT_HYPERTEXT_LINK_SELECTED\n"));
|
||||
atk_focus_tracker_notify(atkObj);
|
||||
g_signal_emit_by_name(atkObj,
|
||||
"link_selected",
|
||||
// Selected link index
|
||||
*(gint *)eventData);
|
||||
break;
|
||||
|
||||
case nsIAccessibleEvent::EVENT_SHOW:
|
||||
case nsIAccessibleEvent::EVENT_DOM_CREATE:
|
||||
case nsIAccessibleEvent::EVENT_ASYNCH_SHOW:
|
||||
return FireAtkShowHideEvent(aEvent, atkObj, PR_TRUE);
|
||||
|
||||
case nsIAccessibleEvent::EVENT_HIDE:
|
||||
case nsIAccessibleEvent::EVENT_DOM_DESTROY:
|
||||
case nsIAccessibleEvent::EVENT_ASYNCH_HIDE:
|
||||
return FireAtkShowHideEvent(aEvent, atkObj, PR_FALSE);
|
||||
|
||||
/*
|
||||
|
@ -1354,11 +1343,6 @@ nsAccessibleWrap::FireAccessibleEvent(nsIAccessibleEvent *aEvent)
|
|||
MAI_LOG_DEBUG(("\n\nReceived: EVENT_DOCUMENT_LOAD_STOPPED\n"));
|
||||
g_signal_emit_by_name (atkObj, "load_stopped");
|
||||
} break;
|
||||
case nsIAccessibleEvent::EVENT_DOCUMENT_ATTRIBUTES_CHANGED:
|
||||
{
|
||||
MAI_LOG_DEBUG(("\n\nReceived: EVENT_DOCUMENT_ATTRIBUTES_CHANGED\n"));
|
||||
g_signal_emit_by_name (atkObj, "attributes_changed");
|
||||
} break;
|
||||
|
||||
case nsIAccessibleEvent::EVENT_MENUPOPUP_START:
|
||||
MAI_LOG_DEBUG(("\n\nReceived: EVENT_MENUPOPUP_START\n"));
|
||||
|
@ -1423,7 +1407,7 @@ nsresult
|
|||
nsAccessibleWrap::FireAtkTextChangedEvent(nsIAccessibleEvent *aEvent,
|
||||
AtkObject *aObject)
|
||||
{
|
||||
MAI_LOG_DEBUG(("\n\nReceived: EVENT_TEXT_CHANGED\n"));
|
||||
MAI_LOG_DEBUG(("\n\nReceived: EVENT_TEXT_REMOVED/INSERTED\n"));
|
||||
|
||||
nsCOMPtr<nsIAccessibleTextChangeEvent> event =
|
||||
do_QueryInterface(aEvent);
|
||||
|
@ -1438,80 +1422,12 @@ nsAccessibleWrap::FireAtkTextChangedEvent(nsIAccessibleEvent *aEvent,
|
|||
PRBool isInserted;
|
||||
event->IsInserted(&isInserted);
|
||||
|
||||
g_signal_emit_by_name (aObject,
|
||||
isInserted ? \
|
||||
"text_changed::insert":"text_changed::delete",
|
||||
start,
|
||||
length);
|
||||
PRBool isFromUserInput;
|
||||
event->GetIsFromUserInput(&isFromUserInput);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsAccessibleWrap::FireAtkPropChangedEvent(nsIAccessibleEvent *aEvent,
|
||||
AtkObject *aObject)
|
||||
{
|
||||
MAI_LOG_DEBUG(("\n\nReceived: EVENT_PROPERTY_CHANGED\n"));
|
||||
|
||||
AtkPropertyChange *pAtkPropChange;
|
||||
AtkPropertyValues values = { NULL };
|
||||
nsAccessibleWrap *oldAccWrap = nsnull, *newAccWrap = nsnull;
|
||||
|
||||
nsAccEvent *event = reinterpret_cast<nsAccEvent*>(aEvent);
|
||||
|
||||
pAtkPropChange = reinterpret_cast<AtkPropertyChange *>(event->mEventData);
|
||||
values.property_name = sAtkPropertyNameArray[pAtkPropChange->type];
|
||||
|
||||
NS_ASSERTION(pAtkPropChange, "Event needs event data");
|
||||
if (!pAtkPropChange)
|
||||
return NS_OK;
|
||||
|
||||
MAI_LOG_DEBUG(("\n\nthe type of EVENT_PROPERTY_CHANGED: %d\n\n",
|
||||
pAtkPropChange->type));
|
||||
|
||||
switch (pAtkPropChange->type) {
|
||||
case PROP_TABLE_CAPTION:
|
||||
case PROP_TABLE_SUMMARY:
|
||||
|
||||
if (pAtkPropChange->oldvalue)
|
||||
oldAccWrap = reinterpret_cast<nsAccessibleWrap *>
|
||||
(pAtkPropChange->oldvalue);
|
||||
|
||||
if (pAtkPropChange->newvalue)
|
||||
newAccWrap = reinterpret_cast<nsAccessibleWrap *>
|
||||
(pAtkPropChange->newvalue);
|
||||
|
||||
if (oldAccWrap && newAccWrap) {
|
||||
g_value_init(&values.old_value, G_TYPE_POINTER);
|
||||
g_value_set_pointer(&values.old_value,
|
||||
oldAccWrap->GetAtkObject());
|
||||
g_value_init(&values.new_value, G_TYPE_POINTER);
|
||||
g_value_set_pointer(&values.new_value,
|
||||
newAccWrap->GetAtkObject());
|
||||
}
|
||||
break;
|
||||
|
||||
case PROP_TABLE_COLUMN_DESCRIPTION:
|
||||
case PROP_TABLE_COLUMN_HEADER:
|
||||
case PROP_TABLE_ROW_HEADER:
|
||||
case PROP_TABLE_ROW_DESCRIPTION:
|
||||
g_value_init(&values.new_value, G_TYPE_INT);
|
||||
g_value_set_int(&values.new_value,
|
||||
*reinterpret_cast<gint *>
|
||||
(pAtkPropChange->newvalue));
|
||||
break;
|
||||
|
||||
//Perhaps need more cases in the future
|
||||
default:
|
||||
g_value_init (&values.old_value, G_TYPE_POINTER);
|
||||
g_value_set_pointer (&values.old_value, pAtkPropChange->oldvalue);
|
||||
g_value_init (&values.new_value, G_TYPE_POINTER);
|
||||
g_value_set_pointer (&values.new_value, pAtkPropChange->newvalue);
|
||||
}
|
||||
|
||||
char *signal_name = g_strconcat("property_change::",
|
||||
values.property_name, NULL);
|
||||
g_signal_emit_by_name(aObject, signal_name, &values, NULL);
|
||||
char *signal_name = g_strconcat(isInserted ? "text_changed::insert" : "text_changed::delete",
|
||||
isFromUserInput ? "" : kNonUserInputEvent, NULL);
|
||||
g_signal_emit_by_name(aObject, signal_name, start, length);
|
||||
g_free (signal_name);
|
||||
|
||||
return NS_OK;
|
||||
|
@ -1522,31 +1438,20 @@ nsAccessibleWrap::FireAtkShowHideEvent(nsIAccessibleEvent *aEvent,
|
|||
AtkObject *aObject, PRBool aIsAdded)
|
||||
{
|
||||
if (aIsAdded)
|
||||
MAI_LOG_DEBUG(("\n\nReceived: EVENT_SHOW\n"));
|
||||
MAI_LOG_DEBUG(("\n\nReceived: Show event\n"));
|
||||
else
|
||||
MAI_LOG_DEBUG(("\n\nReceived: EVENT_HIDE\n"));
|
||||
MAI_LOG_DEBUG(("\n\nReceived: Hide event\n"));
|
||||
|
||||
nsCOMPtr<nsIAccessible> accessible;
|
||||
aEvent->GetAccessible(getter_AddRefs(accessible));
|
||||
NS_ENSURE_STATE(accessible);
|
||||
|
||||
nsCOMPtr<nsIAccessible> parentAccessible;
|
||||
accessible->GetParent(getter_AddRefs(parentAccessible));
|
||||
NS_ENSURE_STATE(parentAccessible);
|
||||
|
||||
PRInt32 indexInParent = -1;
|
||||
accessible->GetIndexInParent(&indexInParent);
|
||||
|
||||
AtkObject *parentObject = GetAtkObject(parentAccessible);
|
||||
PRInt32 indexInParent = getIndexInParentCB(aObject);
|
||||
AtkObject *parentObject = getParentCB(aObject);
|
||||
NS_ENSURE_STATE(parentObject);
|
||||
|
||||
g_signal_emit_by_name(parentObject,
|
||||
aIsAdded ? \
|
||||
"children_changed::add" : \
|
||||
"children_changed::remove",
|
||||
indexInParent,
|
||||
aObject,
|
||||
NULL);
|
||||
PRBool isFromUserInput;
|
||||
aEvent->GetIsFromUserInput(&isFromUserInput);
|
||||
char *signal_name = g_strconcat(aIsAdded ? "children_changed::add" : "children_changed::remove",
|
||||
isFromUserInput ? "" : kNonUserInputEvent, NULL);
|
||||
g_signal_emit_by_name(parentObject, signal_name, indexInParent, aObject, NULL);
|
||||
g_free(signal_name);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
|
|
@ -43,6 +43,8 @@
|
|||
#include "nsMai.h"
|
||||
#include "nsAppRootAccessible.h"
|
||||
#include "prlink.h"
|
||||
#include "prenv.h"
|
||||
#include "nsIPrefBranch.h"
|
||||
#include "nsIServiceManager.h"
|
||||
#include "nsAutoPtr.h"
|
||||
|
||||
|
@ -54,12 +56,19 @@ GType g_atk_hyperlink_impl_type = G_TYPE_INVALID;
|
|||
static PRBool sATKChecked = PR_FALSE;
|
||||
static PRLibrary *sATKLib = nsnull;
|
||||
static const char sATKLibName[] = "libatk-1.0.so.0";
|
||||
static const char sATKHyperlinkImplGetTypeSymbol[] = "atk_hyperlink_impl_get_type";
|
||||
static const char sATKHyperlinkImplGetTypeSymbol[] =
|
||||
"atk_hyperlink_impl_get_type";
|
||||
static const char sAccEnv [] = "GNOME_ACCESSIBILITY";
|
||||
static const char sSysPrefService [] =
|
||||
"@mozilla.org/system-preference-service;1";
|
||||
static const char sAccessibilityKey [] =
|
||||
"config.use_system_prefs.accessibility";
|
||||
|
||||
/* gail function pointer */
|
||||
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) (void);
|
||||
|
||||
/* maiutil */
|
||||
|
@ -222,6 +231,7 @@ mai_util_class_init(MaiUtilClass *klass)
|
|||
// 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 =
|
||||
|
@ -299,6 +309,12 @@ mai_util_remove_global_event_listener(guint remove_listener)
|
|||
}
|
||||
}
|
||||
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);
|
||||
}
|
||||
|
@ -404,6 +420,12 @@ mai_util_add_key_event_listener (AtkKeySnoopFunc listener,
|
|||
static void
|
||||
mai_util_remove_key_event_listener (guint remove_listener)
|
||||
{
|
||||
if (!key_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(key_listener_list, GUINT_TO_POINTER (remove_listener));
|
||||
if (g_hash_table_size(key_listener_list) == 0) {
|
||||
gtk_key_snooper_remove(key_snooper_id);
|
||||
|
@ -501,11 +523,32 @@ nsApplicationAccessibleWrap::nsApplicationAccessibleWrap():
|
|||
nsApplicationAccessibleWrap::~nsApplicationAccessibleWrap()
|
||||
{
|
||||
MAI_LOG_DEBUG(("======Destory AppRootAcc=%p\n", (void*)this));
|
||||
nsAccessibleWrap::ShutdownAtkObject();
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsApplicationAccessibleWrap::Init()
|
||||
{
|
||||
// XXX following code is copied from widget/src/gtk2/nsWindow.cpp
|
||||
// we should put it to somewhere that can be used from both modules
|
||||
// see bug 390761
|
||||
|
||||
// check if accessibility enabled/disabled by environment variable
|
||||
PRBool isGnomeATEnabled = PR_FALSE;
|
||||
const char *envValue = PR_GetEnv(sAccEnv);
|
||||
if (envValue) {
|
||||
isGnomeATEnabled = !!atoi(envValue);
|
||||
} else {
|
||||
//check gconf-2 setting
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsIPrefBranch> sysPrefService =
|
||||
do_GetService(sSysPrefService, &rv);
|
||||
if (NS_SUCCEEDED(rv) && sysPrefService) {
|
||||
sysPrefService->GetBoolPref(sAccessibilityKey, &isGnomeATEnabled);
|
||||
}
|
||||
}
|
||||
|
||||
if (isGnomeATEnabled) {
|
||||
// load and initialize gail library
|
||||
nsresult rv = LoadGtkModule(sGail);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
|
@ -528,6 +571,7 @@ nsApplicationAccessibleWrap::Init()
|
|||
}
|
||||
else
|
||||
MAI_LOG_DEBUG(("Fail to load lib: %s\n", sAtkBridge.libName));
|
||||
}
|
||||
|
||||
return nsApplicationAccessible::Init();
|
||||
}
|
||||
|
|
|
@ -55,43 +55,3 @@ nsDocAccessibleWrap::~nsDocAccessibleWrap()
|
|||
{
|
||||
}
|
||||
|
||||
void nsDocAccessibleWrap::SetEditor(nsIEditor* aEditor)
|
||||
{
|
||||
// Recreate atkobject if editable interface is changing
|
||||
PRBool needRecreate = mAtkObject && (mEditor != aEditor)
|
||||
&& (!mEditor || !aEditor);
|
||||
nsDocAccessible::SetEditor(aEditor);
|
||||
|
||||
if (needRecreate) {
|
||||
// Get parent atkobject and index in parent
|
||||
AtkObject* oldAtkObj = mAtkObject;
|
||||
// getParentCB
|
||||
AtkObject* parentAtkObj = atk_object_get_parent(oldAtkObj);
|
||||
// getIndexInParentCB
|
||||
PRInt32 index = atk_object_get_index_in_parent(oldAtkObj);
|
||||
|
||||
// Clear old atkobject
|
||||
ShutdownAtkObject();
|
||||
|
||||
// Get new atkobject
|
||||
GetAtkObject();
|
||||
|
||||
// Emit children_changed events
|
||||
if (parentAtkObj && (index >= 0)) {
|
||||
g_signal_emit_by_name(parentAtkObj, "children_changed::remove", index,
|
||||
oldAtkObj, NULL);
|
||||
g_signal_emit_by_name(parentAtkObj, "children_changed::add", index,
|
||||
mAtkObject, NULL);
|
||||
}
|
||||
|
||||
// Set every child's parent to new created atkobject
|
||||
nsCOMPtr<nsIAccessible> accChild;
|
||||
while (NextChild(accChild)) {
|
||||
if (IsEmbeddedObject(accChild)) {
|
||||
AtkObject* childAtkObj = nsAccessibleWrap::GetAtkObject(accChild);
|
||||
atk_object_set_parent(childAtkObj, mAtkObject);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -54,10 +54,6 @@ public:
|
|||
nsDocAccessibleWrap(nsIDOMNode *aNode, nsIWeakReference *aShell);
|
||||
virtual ~nsDocAccessibleWrap();
|
||||
|
||||
// Override SetEditor because we need to recreate atkobject
|
||||
// when editable interface is added/removed
|
||||
void SetEditor(nsIEditor* aEditor);
|
||||
|
||||
PRBool mActivated;
|
||||
};
|
||||
|
||||
|
|
|
@ -69,7 +69,6 @@ struct MaiAtkHyperlink
|
|||
* hyperlink instance.
|
||||
*/
|
||||
MaiHyperlink *maiHyperlink;
|
||||
gchar *uri;
|
||||
};
|
||||
|
||||
struct MaiAtkHyperlinkClass
|
||||
|
@ -175,7 +174,6 @@ MaiHyperlink::Initialize(AtkHyperlink *aObj, MaiHyperlink *aHyperlink)
|
|||
|
||||
/* initialize hyperlink */
|
||||
MAI_ATK_HYPERLINK(aObj)->maiHyperlink = aHyperlink;
|
||||
MAI_ATK_HYPERLINK(aObj)->uri = nsnull;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -206,8 +204,6 @@ finalizeCB(GObject *aObj)
|
|||
return;
|
||||
|
||||
MaiAtkHyperlink *maiAtkHyperlink = MAI_ATK_HYPERLINK(aObj);
|
||||
if (maiAtkHyperlink->uri)
|
||||
g_free(maiAtkHyperlink->uri);
|
||||
maiAtkHyperlink->maiHyperlink = nsnull;
|
||||
|
||||
/* call parent finalize function */
|
||||
|
@ -222,8 +218,6 @@ getUriCB(AtkHyperlink *aLink, gint aLinkIndex)
|
|||
NS_ENSURE_TRUE(accHyperlink, nsnull);
|
||||
|
||||
MaiAtkHyperlink *maiAtkHyperlink = MAI_ATK_HYPERLINK(aLink);
|
||||
if (maiAtkHyperlink->uri)
|
||||
return g_strdup(maiAtkHyperlink->uri);
|
||||
|
||||
nsCOMPtr<nsIURI> uri;
|
||||
nsresult rv = accHyperlink->GetURI(aLinkIndex,getter_AddRefs(uri));
|
||||
|
@ -232,8 +226,7 @@ getUriCB(AtkHyperlink *aLink, gint aLinkIndex)
|
|||
nsCAutoString cautoStr;
|
||||
rv = uri->GetSpec(cautoStr);
|
||||
|
||||
maiAtkHyperlink->uri = ToNewCString(cautoStr);
|
||||
return g_strdup(maiAtkHyperlink->uri);
|
||||
return g_strdup(cautoStr.get());
|
||||
}
|
||||
|
||||
AtkObject *
|
||||
|
@ -243,7 +236,7 @@ getObjectCB(AtkHyperlink *aLink, gint aLinkIndex)
|
|||
NS_ENSURE_TRUE(accHyperlink, nsnull);
|
||||
|
||||
nsCOMPtr<nsIAccessible> accObj;
|
||||
accHyperlink->GetObject(aLinkIndex, getter_AddRefs(accObj));
|
||||
accHyperlink->GetAnchor(aLinkIndex, getter_AddRefs(accObj));
|
||||
NS_ENSURE_TRUE(accObj, nsnull);
|
||||
|
||||
AtkObject *atkObj = nsAccessibleWrap::GetAtkObject(accObj);
|
||||
|
@ -282,7 +275,7 @@ isValidCB(AtkHyperlink *aLink)
|
|||
NS_ENSURE_TRUE(accHyperlink, FALSE);
|
||||
|
||||
PRBool isValid = PR_FALSE;
|
||||
nsresult rv = accHyperlink->IsValid(&isValid);
|
||||
nsresult rv = accHyperlink->GetValid(&isValid);
|
||||
return (NS_FAILED(rv)) ? FALSE : static_cast<gboolean>(isValid);
|
||||
}
|
||||
|
||||
|
@ -293,7 +286,7 @@ getAnchorCountCB(AtkHyperlink *aLink)
|
|||
NS_ENSURE_TRUE(accHyperlink, -1);
|
||||
|
||||
PRInt32 count = -1;
|
||||
nsresult rv = accHyperlink->GetAnchors(&count);
|
||||
nsresult rv = accHyperlink->GetAnchorCount(&count);
|
||||
return (NS_FAILED(rv)) ? -1 : static_cast<gint>(count);
|
||||
}
|
||||
|
||||
|
|
|
@ -69,12 +69,16 @@ refAccessibleAtPointCB(AtkComponent *aComponent,
|
|||
AtkCoordType aCoordType)
|
||||
{
|
||||
nsAccessibleWrap *accWrap = GetAccessibleWrap(ATK_OBJECT(aComponent));
|
||||
if (!accWrap)
|
||||
if (!accWrap || nsAccessibleWrap::MustPrune(accWrap))
|
||||
return nsnull;
|
||||
|
||||
// or ATK_XY_SCREEN what is definition this in nsIAccessible ???
|
||||
// nsIAccessible getChildAtPoint (x,y) is in screen pixels.
|
||||
if (aCoordType == ATK_XY_WINDOW) {
|
||||
/* deal with the coord type */
|
||||
nsCOMPtr<nsIDOMNode> domNode;
|
||||
accWrap->GetDOMNode(getter_AddRefs(domNode));
|
||||
nsIntPoint winCoords = nsAccUtils::GetScreenCoordsForWindow(domNode);
|
||||
aAccX += winCoords.x;
|
||||
aAccY += winCoords.y;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIAccessible> pointAcc;
|
||||
|
@ -111,32 +115,11 @@ getExtentsCB(AtkComponent *aComponent,
|
|||
if (NS_FAILED(rv))
|
||||
return;
|
||||
if (aCoordType == ATK_XY_WINDOW) {
|
||||
// Make coordinates relative to top level window instead of screen
|
||||
nsCOMPtr<nsIDOMNode> domNode;
|
||||
accWrap->GetDOMNode(getter_AddRefs(domNode));
|
||||
nsCOMPtr<nsIDocShellTreeItem> treeItem = nsAccessNode::GetDocShellTreeItemFor(domNode);
|
||||
nsCOMPtr<nsIDocShellTreeItem> rootTreeItem;
|
||||
treeItem->GetRootTreeItem(getter_AddRefs(rootTreeItem));
|
||||
nsCOMPtr<nsIDOMDocument> domDoc = do_GetInterface(rootTreeItem);
|
||||
nsCOMPtr<nsIDOMDocumentView> docView(do_QueryInterface(domDoc));
|
||||
if (!docView) {
|
||||
return;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIDOMAbstractView> abstractView;
|
||||
docView->GetDefaultView(getter_AddRefs(abstractView));
|
||||
nsCOMPtr<nsIDOMWindowInternal> windowInter(do_QueryInterface(abstractView));
|
||||
if (!windowInter) {
|
||||
return;
|
||||
}
|
||||
|
||||
PRInt32 screenX, screenY;
|
||||
if (NS_FAILED(windowInter->GetScreenX(&screenX)) ||
|
||||
NS_FAILED(windowInter->GetScreenY(&screenY))) {
|
||||
return;
|
||||
}
|
||||
nsAccX -= screenX;
|
||||
nsAccY -= screenY;
|
||||
nsIntPoint winCoords = nsAccUtils::GetScreenCoordsForWindow(domNode);
|
||||
nsAccX -= winCoords.x;
|
||||
nsAccY -= winCoords.y;
|
||||
}
|
||||
|
||||
*aAccX = nsAccX;
|
||||
|
|
|
@ -97,10 +97,7 @@ setTextContentsCB(AtkEditableText *aText, const gchar *aString)
|
|||
MAI_LOG_DEBUG(("EditableText: setTextContentsCB, aString=%s", aString));
|
||||
|
||||
NS_ConvertUTF8toUTF16 strContent(aString);
|
||||
nsresult rv = accText->SetTextContents(strContent);
|
||||
|
||||
NS_ASSERTION(NS_SUCCEEDED(rv),
|
||||
"MaiInterfaceEditableText::SetTextContents, failed\n");
|
||||
accText->SetTextContents(strContent);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -125,9 +122,7 @@ insertTextCB(AtkEditableText *aText,
|
|||
// nsresult rv = accText->InsertText(strContent, aLength, &pos);
|
||||
// *aPosition = pos;
|
||||
|
||||
nsresult rv = accText->InsertText(strContent, *aPosition);
|
||||
NS_ASSERTION(NS_SUCCEEDED(rv),
|
||||
"MaiInterfaceEditableText::InsertText, failed\n");
|
||||
accText->InsertText(strContent, *aPosition);
|
||||
|
||||
MAI_LOG_DEBUG(("EditableText: insert aString=%s, aLength=%d, aPosition=%d",
|
||||
aString, aLength, *aPosition));
|
||||
|
@ -148,9 +143,7 @@ copyTextCB(AtkEditableText *aText, gint aStartPos, gint aEndPos)
|
|||
|
||||
MAI_LOG_DEBUG(("EditableText: copyTextCB, aStartPos=%d, aEndPos=%d",
|
||||
aStartPos, aEndPos));
|
||||
nsresult rv = accText->CopyText(aStartPos, aEndPos);
|
||||
NS_ASSERTION(NS_SUCCEEDED(rv),
|
||||
"MaiInterfaceEditableText::CopyText, failed\n");
|
||||
accText->CopyText(aStartPos, aEndPos);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -167,9 +160,7 @@ cutTextCB(AtkEditableText *aText, gint aStartPos, gint aEndPos)
|
|||
return;
|
||||
MAI_LOG_DEBUG(("EditableText: cutTextCB, aStartPos=%d, aEndPos=%d",
|
||||
aStartPos, aEndPos));
|
||||
nsresult rv = accText->CutText(aStartPos, aEndPos);
|
||||
NS_ASSERTION(NS_SUCCEEDED(rv),
|
||||
"MaiInterfaceEditableText::CutText, failed\n");
|
||||
accText->CutText(aStartPos, aEndPos);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -187,9 +178,7 @@ deleteTextCB(AtkEditableText *aText, gint aStartPos, gint aEndPos)
|
|||
|
||||
MAI_LOG_DEBUG(("EditableText: deleteTextCB, aStartPos=%d, aEndPos=%d",
|
||||
aStartPos, aEndPos));
|
||||
nsresult rv = accText->DeleteText(aStartPos, aEndPos);
|
||||
NS_ASSERTION(NS_SUCCEEDED(rv),
|
||||
"MaiInterfaceEditableText::DeleteText, failed\n");
|
||||
accText->DeleteText(aStartPos, aEndPos);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -206,7 +195,5 @@ pasteTextCB(AtkEditableText *aText, gint aPosition)
|
|||
return;
|
||||
|
||||
MAI_LOG_DEBUG(("EditableText: pasteTextCB, aPosition=%d", aPosition));
|
||||
nsresult rv = accText->PasteText(aPosition);
|
||||
NS_ASSERTION(NS_SUCCEEDED(rv),
|
||||
"MaiInterfaceEditableText::PasteText, failed\n");
|
||||
accText->PasteText(aPosition);
|
||||
}
|
||||
|
|
|
@ -86,13 +86,13 @@ getLinkCountCB(AtkHypertext *aText)
|
|||
if (!accWrap)
|
||||
return -1;
|
||||
|
||||
nsCOMPtr<nsIAccessibleHyperText> accHyperlink;
|
||||
nsCOMPtr<nsIAccessibleHyperText> hyperText;
|
||||
accWrap->QueryInterface(NS_GET_IID(nsIAccessibleHyperText),
|
||||
getter_AddRefs(accHyperlink));
|
||||
NS_ENSURE_TRUE(accHyperlink, -1);
|
||||
getter_AddRefs(hyperText));
|
||||
NS_ENSURE_TRUE(hyperText, -1);
|
||||
|
||||
PRInt32 count = -1;
|
||||
nsresult rv = accHyperlink->GetLinks(&count);
|
||||
nsresult rv = hyperText->GetLinkCount(&count);
|
||||
NS_ENSURE_SUCCESS(rv, -1);
|
||||
|
||||
return count;
|
||||
|
@ -105,13 +105,13 @@ getLinkIndexCB(AtkHypertext *aText, gint aCharIndex)
|
|||
if (!accWrap)
|
||||
return -1;
|
||||
|
||||
nsCOMPtr<nsIAccessibleHyperText> accHyperlink;
|
||||
nsCOMPtr<nsIAccessibleHyperText> hyperText;
|
||||
accWrap->QueryInterface(NS_GET_IID(nsIAccessibleHyperText),
|
||||
getter_AddRefs(accHyperlink));
|
||||
NS_ENSURE_TRUE(accHyperlink, -1);
|
||||
getter_AddRefs(hyperText));
|
||||
NS_ENSURE_TRUE(hyperText, -1);
|
||||
|
||||
PRInt32 index = -1;
|
||||
nsresult rv = accHyperlink->GetLinkIndex(aCharIndex, &index);
|
||||
nsresult rv = hyperText->GetLinkIndex(aCharIndex, &index);
|
||||
NS_ENSURE_SUCCESS(rv, -1);
|
||||
|
||||
return index;
|
||||
|
|
|
@ -68,9 +68,12 @@ getImagePositionCB(AtkImage *aImage, gint *aAccX, gint *aAccY,
|
|||
if (!image)
|
||||
return;
|
||||
|
||||
PRInt32 width, height; // dummy
|
||||
image->GetImageBounds(aAccX, aAccY, &width, &height);
|
||||
// TODO: translate (x,y) accroding aCoordType. see bug 369821
|
||||
PRUint32 geckoCoordType = (aCoordType == ATK_XY_WINDOW) ?
|
||||
nsIAccessibleCoordinateType::COORDTYPE_WINDOW_RELATIVE :
|
||||
nsIAccessibleCoordinateType::COORDTYPE_SCREEN_RELATIVE;
|
||||
|
||||
// Returned in screen coordinates
|
||||
image->GetImagePosition(geckoCoordType, aAccX, aAccY);
|
||||
}
|
||||
|
||||
const gchar *
|
||||
|
@ -92,6 +95,5 @@ getImageSizeCB(AtkImage *aImage, gint *aAccWidth, gint *aAccHeight)
|
|||
if (!image)
|
||||
return;
|
||||
|
||||
PRInt32 x,y; // dummy
|
||||
image->GetImageBounds(&x, &y, aAccWidth, aAccHeight);
|
||||
image->GetImageSize(aAccWidth, aAccHeight);
|
||||
}
|
||||
|
|
|
@ -287,7 +287,7 @@ getColumnHeaderCB(AtkTable *aTable, gint aColumn)
|
|||
//
|
||||
// 1. "getColumnHeaderCB" defined in AtkTableIface should return object
|
||||
// whose role is "ATK_ROLE_TABLE_COLUMN_HEADER", which is implemented
|
||||
// by nsXULTreeColumnitemAccessible.
|
||||
// by nsXULTreeColumnItemAccessible.
|
||||
//
|
||||
// 2. "GetColumnHeader" defined in nsIAccessibleTable returns
|
||||
// nsXULTreeColumnsAccessibleWrap, which exports nsIAccessibleTable and is
|
||||
|
@ -343,7 +343,10 @@ getRowHeaderCB(AtkTable *aTable, gint aRow)
|
|||
AtkObject*
|
||||
getSummaryCB(AtkTable *aTable)
|
||||
{
|
||||
/* ??? in nsIAccessibleTable, it returns a nsAString */
|
||||
// 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 nsIAccessibleTable::summary to get a summary as a string which is not
|
||||
// mapped directly to ATK.
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
|
|
|
@ -256,12 +256,13 @@ getRunAttributesCB(AtkText *aText, gint aOffset,
|
|||
|
||||
nsCOMPtr<nsIAccessible> accessibleWithAttrs;
|
||||
PRInt32 startOffset = 0, endOffset = 0;
|
||||
nsresult rv = accText->GetAttributeRange(aOffset,
|
||||
&startOffset, &endOffset,
|
||||
nsresult rv =
|
||||
accText->GetAttributeRange(aOffset, &startOffset, &endOffset,
|
||||
getter_AddRefs(accessibleWithAttrs));
|
||||
*aStartOffset = startOffset;
|
||||
*aEndOffset = endOffset;
|
||||
NS_ENSURE_SUCCESS(rv, nsnull);
|
||||
if (NS_FAILED(rv))
|
||||
return nsnull;
|
||||
|
||||
return GetAttributeSet(accessibleWithAttrs);
|
||||
}
|
||||
|
@ -396,6 +397,7 @@ getTextSelectionCountCB(AtkText *aText)
|
|||
nsCOMPtr<nsIAccessibleText> accText;
|
||||
accWrap->QueryInterface(NS_GET_IID(nsIAccessibleText),
|
||||
getter_AddRefs(accText));
|
||||
NS_ENSURE_TRUE(accText, nsnull);
|
||||
|
||||
PRInt32 selectionCount;
|
||||
nsresult rv = accText->GetSelectionCount(&selectionCount);
|
||||
|
|
|
@ -56,7 +56,7 @@ static const PRUint32 atkRoleMap[] = {
|
|||
ATK_ROLE_UNKNOWN, // nsIAccessibleRole::ROLE_CARET 7
|
||||
ATK_ROLE_ALERT, // nsIAccessibleRole::ROLE_ALERT 8
|
||||
ATK_ROLE_WINDOW, // nsIAccessibleRole::ROLE_WINDOW 9
|
||||
ATK_ROLE_PANEL, // nsIAccessibleRole::ROLE_CLIENT 10
|
||||
ATK_ROLE_INTERNAL_FRAME, // nsIAccessibleRole::ROLE_INTERNAL_FRAME 10
|
||||
ATK_ROLE_MENU, // nsIAccessibleRole::ROLE_MENUPOPUP 11
|
||||
ATK_ROLE_MENU_ITEM, // nsIAccessibleRole::ROLE_MENUITEM 12
|
||||
ATK_ROLE_TOOL_TIP, // nsIAccessibleRole::ROLE_TOOLTIP 13
|
||||
|
@ -161,7 +161,12 @@ static const PRUint32 atkRoleMap[] = {
|
|||
ATK_ROLE_MENU, // nsIAccessibleRole::ROLE_PARENT_MENUITEM 112
|
||||
ATK_ROLE_CALENDAR, // nsIAccessibleRole::ROLE_CALENDAR 113
|
||||
ATK_ROLE_MENU, // nsIAccessibleRole::ROLE_COMBOBOX_LIST 114
|
||||
ATK_ROLE_MENU_ITEM, // nsIAccessibleRole::ROLE_COMBOBOX_LISTITEM 115
|
||||
ATK_ROLE_MENU_ITEM, // nsIAccessibleRole::ROLE_COMBOBOX_OPTION 115
|
||||
ATK_ROLE_IMAGE, // nsIAccessibleRole::ROLE_IMAGE_MAP 116
|
||||
ATK_ROLE_LIST_ITEM, // nsIAccessibleRole::ROLE_OPTION 117
|
||||
ATK_ROLE_LIST_ITEM, // nsIAccessibleRole::ROLE_RICH_OPTION 118
|
||||
ATK_ROLE_LIST, // nsIAccessibleRole::ROLE_LISTBOX 119
|
||||
ATK_ROLE_UNKNOWN, // nsIAccessibleRole::ROLE_FLAT_EQUATION 120
|
||||
kROLE_ATK_LAST_ENTRY // nsIAccessibleRole::ROLE_LAST_ENTRY
|
||||
};
|
||||
|
||||
|
|
|
@ -46,5 +46,11 @@ nsNativeRootAccessibleWrap::nsNativeRootAccessibleWrap(AtkObject *aAccessible):
|
|||
nsRootAccessible(nsnull, nsnull)
|
||||
{
|
||||
g_object_ref(aAccessible);
|
||||
nsAccessibleWrap::mAtkObject = aAccessible;
|
||||
mAtkObject = aAccessible;
|
||||
}
|
||||
|
||||
nsNativeRootAccessibleWrap::~nsNativeRootAccessibleWrap()
|
||||
{
|
||||
g_object_unref(mAtkObject);
|
||||
mAtkObject = nsnull;
|
||||
}
|
||||
|
|
|
@ -55,6 +55,7 @@ class nsNativeRootAccessibleWrap: public nsRootAccessible
|
|||
{
|
||||
public:
|
||||
nsNativeRootAccessibleWrap(AtkObject *aAccessible);
|
||||
~nsNativeRootAccessibleWrap();
|
||||
};
|
||||
|
||||
#endif /* __NS_ROOT_ACCESSIBLE_WRAP_H__ */
|
||||
|
|
|
@ -68,7 +68,7 @@ NS_IMETHODIMP nsXULTreeAccessibleWrap::GetChildCount(PRInt32 *aAccChildCount)
|
|||
// created and appended by XUL tree accessible implementation
|
||||
PRInt32 rowCount, colCount = 1;
|
||||
mTreeView->GetRowCount(&rowCount);
|
||||
mFirstChild->GetChildCount(&colCount);
|
||||
GetColumns(&colCount);
|
||||
|
||||
*aAccChildCount += rowCount * colCount;
|
||||
}
|
||||
|
@ -87,16 +87,21 @@ NS_IMETHODIMP nsXULTreeAccessibleWrap::GetSummary(nsAString &aSummary)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsXULTreeAccessibleWrap::GetColumns(PRInt32 *aColumns)
|
||||
NS_IMETHODIMP nsXULTreeAccessibleWrap::GetColumns(PRInt32 *aColumnCount)
|
||||
{
|
||||
nsresult rv = NS_OK;
|
||||
NS_ENSURE_ARG_POINTER(aColumnCount);
|
||||
*aColumnCount = 0;
|
||||
|
||||
nsCOMPtr<nsIAccessible> acc;
|
||||
rv = nsAccessible::GetFirstChild(getter_AddRefs(acc));
|
||||
NS_ENSURE_TRUE(acc, NS_ERROR_FAILURE);
|
||||
nsCOMPtr<nsITreeColumn> column;
|
||||
column = GetFirstVisibleColumn(mTree);
|
||||
if (!column)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
rv = acc->GetChildCount(aColumns);
|
||||
return *aColumns > 0 ? rv : NS_ERROR_FAILURE;
|
||||
do {
|
||||
(*aColumnCount)++;
|
||||
} while ((column = GetNextVisibleColumn(column)));
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsXULTreeAccessibleWrap::GetColumnHeader(nsIAccessibleTable **aColumnHeader)
|
||||
|
@ -261,10 +266,11 @@ NS_IMETHODIMP nsXULTreeAccessibleWrap::GetIndexAt(PRInt32 aRow, PRInt32 aColumn,
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsXULTreeAccessibleWrap::GetColumnAtIndex(PRInt32 aIndex, PRInt32 *_retval)
|
||||
NS_IMETHODIMP nsXULTreeAccessibleWrap::GetColumnAtIndex(PRInt32 aIndex, PRInt32 *aColumn)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(_retval);
|
||||
NS_ENSURE_ARG_POINTER(aColumn);
|
||||
|
||||
*aColumn = -1;
|
||||
nsresult rv = NS_OK;
|
||||
|
||||
PRInt32 columns;
|
||||
|
@ -274,15 +280,18 @@ NS_IMETHODIMP nsXULTreeAccessibleWrap::GetColumnAtIndex(PRInt32 aIndex, PRInt32
|
|||
PRInt32 treeCols;
|
||||
nsAccessible::GetChildCount(&treeCols);
|
||||
|
||||
*_retval = (aIndex - treeCols) % columns;
|
||||
if (aIndex >= treeCols) {
|
||||
*aColumn = (aIndex - treeCols) % columns;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsXULTreeAccessibleWrap::GetRowAtIndex(PRInt32 aIndex, PRInt32 *_retval)
|
||||
NS_IMETHODIMP nsXULTreeAccessibleWrap::GetRowAtIndex(PRInt32 aIndex, PRInt32 *aRow)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(_retval);
|
||||
NS_ENSURE_ARG_POINTER(aRow);
|
||||
|
||||
*aRow = -1;
|
||||
nsresult rv = NS_OK;
|
||||
|
||||
PRInt32 columns;
|
||||
|
@ -292,7 +301,9 @@ NS_IMETHODIMP nsXULTreeAccessibleWrap::GetRowAtIndex(PRInt32 aIndex, PRInt32 *_r
|
|||
PRInt32 treeCols;
|
||||
nsAccessible::GetChildCount(&treeCols);
|
||||
|
||||
*_retval = (aIndex - treeCols) / columns;
|
||||
if (aIndex >= treeCols) {
|
||||
*aRow = (aIndex - treeCols) / columns;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -430,7 +441,7 @@ NS_IMETHODIMP nsXULTreeAccessibleWrap::IsProbablyForLayout(PRBool *aIsProbablyFo
|
|||
}
|
||||
|
||||
// --------------------------------------------------------
|
||||
// nsXULTreeAccessibleWrap Accessible
|
||||
// nsXULTreeColumnsAccessibleWrap Accessible
|
||||
// --------------------------------------------------------
|
||||
NS_IMPL_ISUPPORTS_INHERITED1(nsXULTreeColumnsAccessibleWrap, nsXULTreeColumnsAccessible, nsIAccessibleTable)
|
||||
|
||||
|
|
|
@ -55,8 +55,12 @@ public:
|
|||
nsXULTreeAccessibleWrap(nsIDOMNode* aDOMNode, nsIWeakReference* aShell);
|
||||
virtual ~nsXULTreeAccessibleWrap() {}
|
||||
|
||||
// nsIAccessible
|
||||
NS_IMETHOD GetChildCount(PRInt32 *_retval);
|
||||
NS_IMETHOD ChangeSelection(PRInt32 aIndex, PRUint8 aMethod, PRBool *aSelState);
|
||||
|
||||
protected:
|
||||
NS_IMETHOD ChangeSelection(PRInt32 aIndex, PRUint8 aMethod,
|
||||
PRBool *aSelState);
|
||||
};
|
||||
|
||||
class nsXULTreeColumnsAccessibleWrap : public nsXULTreeColumnsAccessible,
|
||||
|
|
|
@ -54,6 +54,7 @@ REQUIRES = appshell \
|
|||
dom \
|
||||
editor \
|
||||
gfx \
|
||||
thebes \
|
||||
intl \
|
||||
layout \
|
||||
locale \
|
||||
|
|
|
@ -46,10 +46,9 @@
|
|||
* 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.
|
||||
*
|
||||
* XXX Should we store attribute names in this table as atoms instead of strings?
|
||||
* Definition of nsRoleMapEntry and nsStateMapEntry contains comments explaining this table.
|
||||
*
|
||||
* When no nsIAccessibleRole neum mapping exists for an ARIA role, the
|
||||
* 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.
|
||||
*
|
||||
|
@ -57,143 +56,142 @@
|
|||
* banner, contentinfo, main, navigation, note, search, secondary, seealso, breadcrumbs
|
||||
*/
|
||||
|
||||
static const nsStateMapEntry kEndEntry = {0, 0, 0}; // To fill in array of state mappings
|
||||
static const nsStateMapEntry kEndEntry = {nsnull, 0, 0}; // To fill in array of state mappings
|
||||
|
||||
nsRoleMapEntry nsARIAMap::gWAIRoleMap[] =
|
||||
{
|
||||
{"alert", nsIAccessibleRole::ROLE_ALERT, eNameOkFromChildren, eNoValue, kNoReqStates, kEndEntry},
|
||||
{"alert", nsIAccessibleRole::ROLE_ALERT, eNameLabelOrTitle, eNoValue, kNoReqStates, kEndEntry},
|
||||
{"alertdialog", nsIAccessibleRole::ROLE_ALERT, eNameOkFromChildren, eNoValue, kNoReqStates, kEndEntry},
|
||||
{"application", nsIAccessibleRole::ROLE_APPLICATION, eNameLabelOrTitle, eNoValue, kNoReqStates, kEndEntry},
|
||||
{"button", nsIAccessibleRole::ROLE_PUSHBUTTON, eNameOkFromChildren, eNoValue, kNoReqStates,
|
||||
{"disabled", kBoolState, nsIAccessibleStates::STATE_UNAVAILABLE},
|
||||
{"pressed", kBoolState, nsIAccessibleStates::STATE_PRESSED}, kEndEntry},
|
||||
{&nsAccessibilityAtoms::aria_pressed, kBoolState, nsIAccessibleStates::STATE_PRESSED},
|
||||
{&nsAccessibilityAtoms::aria_pressed, "mixed", nsIAccessibleStates::STATE_MIXED}, kEndEntry},
|
||||
{"checkbox", nsIAccessibleRole::ROLE_CHECKBUTTON, eNameOkFromChildren, eNoValue, nsIAccessibleStates::STATE_CHECKABLE,
|
||||
{"disabled", kBoolState, nsIAccessibleStates::STATE_UNAVAILABLE},
|
||||
{"checked", kBoolState, nsIAccessibleStates::STATE_CHECKED},
|
||||
{"readonly", kBoolState, nsIAccessibleStates::STATE_READONLY}, kEndEntry},
|
||||
{"checkboxtristate", nsIAccessibleRole::ROLE_CHECKBUTTON, eNameOkFromChildren, eNoValue, nsIAccessibleStates::STATE_CHECKABLE,
|
||||
{"disabled", kBoolState, nsIAccessibleStates::STATE_UNAVAILABLE},
|
||||
{"checked", kBoolState, nsIAccessibleStates::STATE_CHECKED},
|
||||
{"checked", "mixed", nsIAccessibleStates::STATE_MIXED},
|
||||
{"readonly", kBoolState, nsIAccessibleStates::STATE_READONLY}, kEndEntry},
|
||||
{&nsAccessibilityAtoms::aria_checked, kBoolState, nsIAccessibleStates::STATE_CHECKED},
|
||||
{&nsAccessibilityAtoms::aria_checked, "mixed", nsIAccessibleStates::STATE_MIXED},
|
||||
{&nsAccessibilityAtoms::aria_readonly, kBoolState, nsIAccessibleStates::STATE_READONLY}, kEndEntry},
|
||||
{"columnheader", nsIAccessibleRole::ROLE_COLUMNHEADER, eNameOkFromChildren, eNoValue, kNoReqStates,
|
||||
{"disabled", kBoolState, nsIAccessibleStates::STATE_UNAVAILABLE},
|
||||
{"selected", kBoolState, nsIAccessibleStates::STATE_SELECTED | nsIAccessibleStates::STATE_SELECTABLE},
|
||||
{"selected", "false", nsIAccessibleStates::STATE_SELECTABLE},
|
||||
{"readonly", kBoolState, nsIAccessibleStates::STATE_READONLY}, kEndEntry},
|
||||
{"combobox", nsIAccessibleRole::ROLE_COMBOBOX, eNameLabelOrTitle, eHasValueMinMax, kNoReqStates,
|
||||
{"disabled", kBoolState, nsIAccessibleStates::STATE_UNAVAILABLE},
|
||||
{"readonly", kBoolState, nsIAccessibleStates::STATE_READONLY},
|
||||
{"expanded", kBoolState, nsIAccessibleStates::STATE_EXPANDED},
|
||||
{"multiselectable", kBoolState, nsIAccessibleStates::STATE_MULTISELECTABLE | nsIAccessibleStates::STATE_EXTSELECTABLE}, kEndEntry},
|
||||
{&nsAccessibilityAtoms::aria_selected, kBoolState, nsIAccessibleStates::STATE_SELECTED | nsIAccessibleStates::STATE_SELECTABLE},
|
||||
{&nsAccessibilityAtoms::aria_selected, "false", nsIAccessibleStates::STATE_SELECTABLE},
|
||||
{&nsAccessibilityAtoms::aria_readonly, kBoolState, nsIAccessibleStates::STATE_READONLY}, kEndEntry},
|
||||
{"combobox", nsIAccessibleRole::ROLE_COMBOBOX, eNameLabelOrTitle, eHasValueMinMax,
|
||||
nsIAccessibleStates::STATE_COLLAPSED | nsIAccessibleStates::STATE_HASPOPUP,
|
||||
// Manually map EXT_STATE_SUPPORTS_AUTOCOMPLETION aria-autocomplete
|
||||
{&nsAccessibilityAtoms::aria_readonly, kBoolState, nsIAccessibleStates::STATE_READONLY},
|
||||
{&nsAccessibilityAtoms::aria_expanded, kBoolState, nsIAccessibleStates::STATE_EXPANDED}, kEndEntry},
|
||||
{"description", nsIAccessibleRole::ROLE_TEXT_CONTAINER, eNameOkFromChildren, eNoValue, kNoReqStates, kEndEntry},
|
||||
{"dialog", nsIAccessibleRole::ROLE_DIALOG, eNameLabelOrTitle, eNoValue, kNoReqStates, kEndEntry},
|
||||
{"document", nsIAccessibleRole::ROLE_DOCUMENT, eNameLabelOrTitle, eNoValue, kNoReqStates, kEndEntry},
|
||||
{"grid", nsIAccessibleRole::ROLE_TABLE, eNameLabelOrTitle, eNoValue, nsIAccessibleStates::STATE_FOCUSABLE,
|
||||
{"disabled", kBoolState, nsIAccessibleStates::STATE_UNAVAILABLE},
|
||||
{"multiselectable", kBoolState, nsIAccessibleStates::STATE_MULTISELECTABLE | nsIAccessibleStates::STATE_EXTSELECTABLE},
|
||||
{"readonly", kBoolState, nsIAccessibleStates::STATE_READONLY}, kEndEntry},
|
||||
{&nsAccessibilityAtoms::aria_multiselectable, kBoolState, nsIAccessibleStates::STATE_MULTISELECTABLE | nsIAccessibleStates::STATE_EXTSELECTABLE},
|
||||
{&nsAccessibilityAtoms::aria_readonly, kBoolState, nsIAccessibleStates::STATE_READONLY}, kEndEntry},
|
||||
{"gridcell", nsIAccessibleRole::ROLE_CELL, eNameOkFromChildren, eNoValue, kNoReqStates,
|
||||
{"disabled", kBoolState, nsIAccessibleStates::STATE_UNAVAILABLE},
|
||||
{"expanded", kBoolState, nsIAccessibleStates::STATE_EXPANDED},
|
||||
{"expanded", "false", nsIAccessibleStates::STATE_COLLAPSED},
|
||||
{"selected", kBoolState, nsIAccessibleStates::STATE_SELECTED | nsIAccessibleStates::STATE_SELECTABLE},
|
||||
{"selected", "false", nsIAccessibleStates::STATE_SELECTABLE},
|
||||
{"readonly", kBoolState, nsIAccessibleStates::STATE_READONLY}, kEndEntry},
|
||||
{&nsAccessibilityAtoms::aria_expanded, kBoolState, nsIAccessibleStates::STATE_EXPANDED},
|
||||
{&nsAccessibilityAtoms::aria_expanded, "false", nsIAccessibleStates::STATE_COLLAPSED},
|
||||
{&nsAccessibilityAtoms::aria_selected, kBoolState, nsIAccessibleStates::STATE_SELECTED | nsIAccessibleStates::STATE_SELECTABLE},
|
||||
{&nsAccessibilityAtoms::aria_selected, "false", nsIAccessibleStates::STATE_SELECTABLE},
|
||||
{&nsAccessibilityAtoms::aria_readonly, kBoolState, nsIAccessibleStates::STATE_READONLY}, kEndEntry},
|
||||
{"group", nsIAccessibleRole::ROLE_GROUPING, eNameLabelOrTitle, eNoValue, kNoReqStates, kEndEntry},
|
||||
{"heading", nsIAccessibleRole::ROLE_HEADING, eNameLabelOrTitle, eNoValue, kNoReqStates, kEndEntry},
|
||||
{"img", nsIAccessibleRole::ROLE_GRAPHIC, eNameLabelOrTitle, eNoValue, kNoReqStates, kEndEntry},
|
||||
{"label", nsIAccessibleRole::ROLE_LABEL, eNameOkFromChildren, eNoValue, kNoReqStates, kEndEntry},
|
||||
{"link", nsIAccessibleRole::ROLE_LINK, eNameOkFromChildren, eNoValue, nsIAccessibleStates::STATE_LINKED,
|
||||
{"disabled", kBoolState, nsIAccessibleStates::STATE_UNAVAILABLE}, kEndEntry},
|
||||
{"list", nsIAccessibleRole::ROLE_LIST, eNameLabelOrTitle, eNoValue, kNoReqStates,
|
||||
{"readonly", kBoolState, nsIAccessibleStates::STATE_READONLY},
|
||||
{"multiselectable", kBoolState, nsIAccessibleStates::STATE_MULTISELECTABLE | nsIAccessibleStates::STATE_EXTSELECTABLE}, kEndEntry},
|
||||
{"listbox", nsIAccessibleRole::ROLE_LIST, eNameLabelOrTitle, eNoValue, kNoReqStates,
|
||||
{"disabled", kBoolState, nsIAccessibleStates::STATE_UNAVAILABLE},
|
||||
{"readonly", kBoolState, nsIAccessibleStates::STATE_READONLY},
|
||||
{"multiselectable", kBoolState, nsIAccessibleStates::STATE_MULTISELECTABLE | nsIAccessibleStates::STATE_EXTSELECTABLE}, kEndEntry},
|
||||
{"listitem", nsIAccessibleRole::ROLE_LISTITEM, eNameOkFromChildren, eNoValue, kNoReqStates,
|
||||
{"selected", kBoolState, nsIAccessibleStates::STATE_SELECTED | nsIAccessibleStates::STATE_SELECTABLE},
|
||||
{"selected", "false", nsIAccessibleStates::STATE_SELECTABLE},
|
||||
{"checked", kBoolState, nsIAccessibleStates::STATE_CHECKED | nsIAccessibleStates::STATE_CHECKABLE},
|
||||
{"checked", "false", nsIAccessibleStates::STATE_CHECKABLE}, kEndEntry},
|
||||
{"menu", nsIAccessibleRole::ROLE_MENUPOPUP, eNameLabelOrTitle, eNoValue, kNoReqStates,
|
||||
{"disabled", kBoolState, nsIAccessibleStates::STATE_UNAVAILABLE}, kEndEntry},
|
||||
{"menubar", nsIAccessibleRole::ROLE_MENUBAR, eNameLabelOrTitle, eNoValue, kNoReqStates,
|
||||
{"disabled", kBoolState, nsIAccessibleStates::STATE_UNAVAILABLE}, kEndEntry},
|
||||
{"link", nsIAccessibleRole::ROLE_LINK, eNameOkFromChildren, eNoValue, nsIAccessibleStates::STATE_LINKED, kEndEntry},
|
||||
{"list", nsIAccessibleRole::ROLE_LIST, eNameLabelOrTitle, eNoValue, nsIAccessibleStates::STATE_READONLY,
|
||||
{&nsAccessibilityAtoms::aria_multiselectable, kBoolState, nsIAccessibleStates::STATE_MULTISELECTABLE | nsIAccessibleStates::STATE_EXTSELECTABLE}, kEndEntry},
|
||||
{"listbox", nsIAccessibleRole::ROLE_LISTBOX, eNameLabelOrTitle, eNoValue, kNoReqStates,
|
||||
{&nsAccessibilityAtoms::aria_readonly, kBoolState, nsIAccessibleStates::STATE_READONLY},
|
||||
{&nsAccessibilityAtoms::aria_multiselectable, kBoolState, nsIAccessibleStates::STATE_MULTISELECTABLE | nsIAccessibleStates::STATE_EXTSELECTABLE}, kEndEntry},
|
||||
{"listitem", nsIAccessibleRole::ROLE_LISTITEM, eNameOkFromChildren, eNoValue, nsIAccessibleStates::STATE_READONLY,
|
||||
{&nsAccessibilityAtoms::aria_selected, kBoolState, nsIAccessibleStates::STATE_SELECTED | nsIAccessibleStates::STATE_SELECTABLE},
|
||||
{&nsAccessibilityAtoms::aria_selected, "false", nsIAccessibleStates::STATE_SELECTABLE},
|
||||
{&nsAccessibilityAtoms::aria_checked, kBoolState, nsIAccessibleStates::STATE_CHECKED | nsIAccessibleStates::STATE_CHECKABLE},
|
||||
{&nsAccessibilityAtoms::aria_checked, "mixed", nsIAccessibleStates::STATE_MIXED | nsIAccessibleStates::STATE_CHECKABLE},
|
||||
{&nsAccessibilityAtoms::aria_checked, "false", nsIAccessibleStates::STATE_CHECKABLE}, kEndEntry},
|
||||
{"math", nsIAccessibleRole::ROLE_FLAT_EQUATION, eNameLabelOrTitle, eNoValue, kNoReqStates, kEndEntry},
|
||||
{"menu", nsIAccessibleRole::ROLE_MENUPOPUP, eNameLabelOrTitle, eNoValue, kNoReqStates, kEndEntry},
|
||||
{"menubar", nsIAccessibleRole::ROLE_MENUBAR, eNameLabelOrTitle, eNoValue, kNoReqStates, kEndEntry},
|
||||
{"menuitem", nsIAccessibleRole::ROLE_MENUITEM, eNameOkFromChildren, eNoValue, kNoReqStates,
|
||||
{"disabled", kBoolState, nsIAccessibleStates::STATE_UNAVAILABLE},
|
||||
{"checked", kBoolState, nsIAccessibleStates::STATE_CHECKED | nsIAccessibleStates::STATE_CHECKABLE},
|
||||
{"checked", "mixed", nsIAccessibleStates::STATE_MIXED},
|
||||
{"checked", "false", nsIAccessibleStates::STATE_CHECKABLE}, kEndEntry},
|
||||
{"menuitemcheckbox", nsIAccessibleRole::ROLE_MENUITEM, eNameOkFromChildren, eNoValue, nsIAccessibleStates::STATE_CHECKABLE,
|
||||
{"disabled", kBoolState, nsIAccessibleStates::STATE_UNAVAILABLE},
|
||||
{"checked", kBoolState, nsIAccessibleStates::STATE_CHECKED }, kEndEntry},
|
||||
{"menuitemradio", nsIAccessibleRole::ROLE_MENUITEM, eNameOkFromChildren, eNoValue, nsIAccessibleStates::STATE_CHECKABLE,
|
||||
{"disabled", kBoolState, nsIAccessibleStates::STATE_UNAVAILABLE},
|
||||
{"checked", kBoolState, nsIAccessibleStates::STATE_CHECKED }, kEndEntry},
|
||||
{"option", nsIAccessibleRole::ROLE_LISTITEM, eNameOkFromChildren, eNoValue, kNoReqStates,
|
||||
{"disabled", kBoolState, nsIAccessibleStates::STATE_UNAVAILABLE},
|
||||
{"selected", kBoolState, nsIAccessibleStates::STATE_SELECTED | nsIAccessibleStates::STATE_SELECTABLE},
|
||||
{"selected", "false", nsIAccessibleStates::STATE_SELECTABLE},
|
||||
{"checked", kBoolState, nsIAccessibleStates::STATE_CHECKED | nsIAccessibleStates::STATE_CHECKABLE},
|
||||
{"checked", "false", nsIAccessibleStates::STATE_CHECKABLE}, kEndEntry},
|
||||
{"progressbar", nsIAccessibleRole::ROLE_PROGRESSBAR, eNameLabelOrTitle, eHasValueMinMax, nsIAccessibleStates::STATE_READONLY,
|
||||
{"disabled", kBoolState, nsIAccessibleStates::STATE_UNAVAILABLE}, kEndEntry},
|
||||
{&nsAccessibilityAtoms::aria_checked, kBoolState, nsIAccessibleStates::STATE_CHECKED | nsIAccessibleStates::STATE_CHECKABLE},
|
||||
{&nsAccessibilityAtoms::aria_checked, "mixed", nsIAccessibleStates::STATE_MIXED | nsIAccessibleStates::STATE_CHECKABLE},
|
||||
{&nsAccessibilityAtoms::aria_checked, "false", nsIAccessibleStates::STATE_CHECKABLE}, kEndEntry},
|
||||
{"menuitemcheckbox", nsIAccessibleRole::ROLE_CHECK_MENU_ITEM, eNameOkFromChildren, eNoValue, nsIAccessibleStates::STATE_CHECKABLE,
|
||||
{&nsAccessibilityAtoms::aria_checked, kBoolState, nsIAccessibleStates::STATE_CHECKED },
|
||||
{&nsAccessibilityAtoms::aria_checked, "mixed", nsIAccessibleStates::STATE_MIXED}, kEndEntry},
|
||||
{"menuitemradio", nsIAccessibleRole::ROLE_RADIO_MENU_ITEM, eNameOkFromChildren, eNoValue, nsIAccessibleStates::STATE_CHECKABLE,
|
||||
{&nsAccessibilityAtoms::aria_checked, kBoolState, nsIAccessibleStates::STATE_CHECKED }, kEndEntry},
|
||||
{"option", nsIAccessibleRole::ROLE_OPTION, eNameOkFromChildren, eNoValue, kNoReqStates,
|
||||
{&nsAccessibilityAtoms::aria_selected, kBoolState, nsIAccessibleStates::STATE_SELECTED | nsIAccessibleStates::STATE_SELECTABLE},
|
||||
{&nsAccessibilityAtoms::aria_selected, "false", nsIAccessibleStates::STATE_SELECTABLE},
|
||||
{&nsAccessibilityAtoms::aria_checked, kBoolState, nsIAccessibleStates::STATE_CHECKED | nsIAccessibleStates::STATE_CHECKABLE},
|
||||
{&nsAccessibilityAtoms::aria_checked, "mixed", nsIAccessibleStates::STATE_MIXED | nsIAccessibleStates::STATE_CHECKABLE},
|
||||
{&nsAccessibilityAtoms::aria_checked, "false", nsIAccessibleStates::STATE_CHECKABLE}, kEndEntry},
|
||||
{"presentation", nsIAccessibleRole::ROLE_NOTHING, eNameLabelOrTitle, eNoValue, kNoReqStates, kEndEntry},
|
||||
{"progressbar", nsIAccessibleRole::ROLE_PROGRESSBAR, eNameLabelOrTitle, eHasValueMinMax, nsIAccessibleStates::STATE_READONLY, kEndEntry},
|
||||
{"radio", nsIAccessibleRole::ROLE_RADIOBUTTON, eNameOkFromChildren, eNoValue, kNoReqStates,
|
||||
{"disabled", kBoolState, nsIAccessibleStates::STATE_UNAVAILABLE},
|
||||
{"checked", kBoolState, nsIAccessibleStates::STATE_CHECKED}, kEndEntry},
|
||||
{"radiogroup", nsIAccessibleRole::ROLE_GROUPING, eNameLabelOrTitle, eNoValue, kNoReqStates,
|
||||
{"disabled", kBoolState, nsIAccessibleStates::STATE_UNAVAILABLE}, kEndEntry},
|
||||
{&nsAccessibilityAtoms::aria_checked, kBoolState, nsIAccessibleStates::STATE_CHECKED}, kEndEntry},
|
||||
{"radiogroup", nsIAccessibleRole::ROLE_GROUPING, eNameLabelOrTitle, eNoValue, kNoReqStates, kEndEntry},
|
||||
{"region", nsIAccessibleRole::ROLE_PANE, eNameLabelOrTitle, eNoValue, kNoReqStates, kEndEntry},
|
||||
{"row", nsIAccessibleRole::ROLE_ROW, eNameOkFromChildren, eNoValue, kNoReqStates,
|
||||
{"disabled", kBoolState, nsIAccessibleStates::STATE_UNAVAILABLE},
|
||||
{"selected", kBoolState, nsIAccessibleStates::STATE_SELECTED | nsIAccessibleStates::STATE_SELECTABLE},
|
||||
{"selected", "false", nsIAccessibleStates::STATE_SELECTABLE},
|
||||
{"expanded", kBoolState, nsIAccessibleStates::STATE_EXPANDED},
|
||||
{"expanded", "false", nsIAccessibleStates::STATE_COLLAPSED}, kEndEntry},
|
||||
{&nsAccessibilityAtoms::aria_selected, kBoolState, nsIAccessibleStates::STATE_SELECTED | nsIAccessibleStates::STATE_SELECTABLE},
|
||||
{&nsAccessibilityAtoms::aria_selected, "false", nsIAccessibleStates::STATE_SELECTABLE},
|
||||
{&nsAccessibilityAtoms::aria_expanded, kBoolState, nsIAccessibleStates::STATE_EXPANDED},
|
||||
{&nsAccessibilityAtoms::aria_expanded, "false", nsIAccessibleStates::STATE_COLLAPSED}, kEndEntry},
|
||||
{"rowheader", nsIAccessibleRole::ROLE_ROWHEADER, eNameOkFromChildren, eNoValue, kNoReqStates,
|
||||
{"disabled", kBoolState, nsIAccessibleStates::STATE_UNAVAILABLE},
|
||||
{"selected", kBoolState, nsIAccessibleStates::STATE_SELECTED | nsIAccessibleStates::STATE_SELECTABLE},
|
||||
{"selected", "false", nsIAccessibleStates::STATE_SELECTABLE},
|
||||
{"readonly", kBoolState, nsIAccessibleStates::STATE_READONLY}, kEndEntry},
|
||||
{"secret", nsIAccessibleRole::ROLE_PASSWORD_TEXT, eNameLabelOrTitle, eNoValue, nsIAccessibleStates::STATE_PROTECTED,
|
||||
// Manually map EXT_STATE_SINGLE_LINE and EXT_STATE_MULTI_LINE FROM aaa:multiline
|
||||
{"disabled", kBoolState, nsIAccessibleStates::STATE_UNAVAILABLE}, kEndEntry},
|
||||
{&nsAccessibilityAtoms::aria_selected, kBoolState, nsIAccessibleStates::STATE_SELECTED | nsIAccessibleStates::STATE_SELECTABLE},
|
||||
{&nsAccessibilityAtoms::aria_selected, "false", nsIAccessibleStates::STATE_SELECTABLE},
|
||||
{&nsAccessibilityAtoms::aria_readonly, kBoolState, nsIAccessibleStates::STATE_READONLY}, kEndEntry},
|
||||
{"section", nsIAccessibleRole::ROLE_SECTION, eNameLabelOrTitle, eNoValue, kNoReqStates, kEndEntry},
|
||||
{"separator", nsIAccessibleRole::ROLE_SEPARATOR, eNameLabelOrTitle, eNoValue, kNoReqStates, kEndEntry},
|
||||
{"slider", nsIAccessibleRole::ROLE_SLIDER, eNameLabelOrTitle, eHasValueMinMax, kNoReqStates,
|
||||
{"disabled", kBoolState, nsIAccessibleStates::STATE_UNAVAILABLE},
|
||||
{"readonly", kBoolState, nsIAccessibleStates::STATE_READONLY}, kEndEntry},
|
||||
{&nsAccessibilityAtoms::aria_readonly, kBoolState, nsIAccessibleStates::STATE_READONLY}, kEndEntry},
|
||||
{"spinbutton", nsIAccessibleRole::ROLE_SPINBUTTON, eNameLabelOrTitle, eHasValueMinMax, kNoReqStates,
|
||||
{"disabled", kBoolState, nsIAccessibleStates::STATE_UNAVAILABLE},
|
||||
{"readonly", kBoolState, nsIAccessibleStates::STATE_READONLY}, kEndEntry},
|
||||
{&nsAccessibilityAtoms::aria_readonly, kBoolState, nsIAccessibleStates::STATE_READONLY}, kEndEntry},
|
||||
{"status", nsIAccessibleRole::ROLE_STATUSBAR, eNameLabelOrTitle, eNoValue, kNoReqStates, kEndEntry},
|
||||
{"tab", nsIAccessibleRole::ROLE_PAGETAB, eNameOkFromChildren, eNoValue, kNoReqStates,
|
||||
{"disabled", kBoolState, nsIAccessibleStates::STATE_UNAVAILABLE}, kEndEntry},
|
||||
{"tab", nsIAccessibleRole::ROLE_PAGETAB, eNameOkFromChildren, eNoValue, kNoReqStates, kEndEntry},
|
||||
{"tablist", nsIAccessibleRole::ROLE_PAGETABLIST, eNameLabelOrTitle, eNoValue, kNoReqStates, kEndEntry},
|
||||
{"tabpanel", nsIAccessibleRole::ROLE_PROPERTYPAGE, eNameLabelOrTitle, eNoValue, kNoReqStates, kEndEntry},
|
||||
{"textbox", nsIAccessibleRole::ROLE_ENTRY, eNameLabelOrTitle, eHasValueMinMax, kNoReqStates,
|
||||
// Manually map EXT_STATE_SINGLE_LINE and EXT_STATE_MULTI_LINE FROM aaa:multiline
|
||||
{"disabled", kBoolState, nsIAccessibleStates::STATE_UNAVAILABLE},
|
||||
{"readonly", kBoolState, nsIAccessibleStates::STATE_READONLY}, kEndEntry},
|
||||
{"toolbar", nsIAccessibleRole::ROLE_TOOLBAR, eNameLabelOrTitle, eNoValue, kNoReqStates,
|
||||
{"disabled", kBoolState, nsIAccessibleStates::STATE_UNAVAILABLE}, kEndEntry},
|
||||
{"textbox", nsIAccessibleRole::ROLE_ENTRY, eNameLabelOrTitle, eNoValue, kNoReqStates,
|
||||
// Manually map EXT_STATE_SINGLE_LINE and EXT_STATE_MULTI_LINE FROM aria-multiline
|
||||
// Manually map EXT_STATE_SUPPORTS_AUTOCOMPLETION aria-autocomplete
|
||||
{&nsAccessibilityAtoms::aria_autocomplete, "list", nsIAccessibleStates::STATE_HASPOPUP},
|
||||
{&nsAccessibilityAtoms::aria_autocomplete, "both", nsIAccessibleStates::STATE_HASPOPUP},
|
||||
{&nsAccessibilityAtoms::aria_readonly, kBoolState, nsIAccessibleStates::STATE_READONLY}, kEndEntry},
|
||||
{"toolbar", nsIAccessibleRole::ROLE_TOOLBAR, eNameLabelOrTitle, eNoValue, kNoReqStates, kEndEntry},
|
||||
{"tooltip", nsIAccessibleRole::ROLE_TOOLTIP, eNameOkFromChildren, eNoValue, kNoReqStates, kEndEntry},
|
||||
{"tree", nsIAccessibleRole::ROLE_OUTLINE, eNameLabelOrTitle, eNoValue, kNoReqStates,
|
||||
{"disabled", kBoolState, nsIAccessibleStates::STATE_UNAVAILABLE},
|
||||
{"readonly", kBoolState, nsIAccessibleStates::STATE_READONLY},
|
||||
{"multiselectable", kBoolState, nsIAccessibleStates::STATE_MULTISELECTABLE | nsIAccessibleStates::STATE_EXTSELECTABLE}, kEndEntry},
|
||||
{&nsAccessibilityAtoms::aria_readonly, kBoolState, nsIAccessibleStates::STATE_READONLY},
|
||||
{&nsAccessibilityAtoms::aria_multiselectable, kBoolState, nsIAccessibleStates::STATE_MULTISELECTABLE | nsIAccessibleStates::STATE_EXTSELECTABLE}, kEndEntry},
|
||||
{"treegrid", nsIAccessibleRole::ROLE_TREE_TABLE, eNameLabelOrTitle, eNoValue, kNoReqStates,
|
||||
{"disabled", kBoolState, nsIAccessibleStates::STATE_UNAVAILABLE},
|
||||
{"readonly", kBoolState, nsIAccessibleStates::STATE_READONLY},
|
||||
{"multiselectable", kBoolState, nsIAccessibleStates::STATE_MULTISELECTABLE | nsIAccessibleStates::STATE_EXTSELECTABLE}, kEndEntry},
|
||||
{&nsAccessibilityAtoms::aria_readonly, kBoolState, nsIAccessibleStates::STATE_READONLY},
|
||||
{&nsAccessibilityAtoms::aria_multiselectable, kBoolState, nsIAccessibleStates::STATE_MULTISELECTABLE | nsIAccessibleStates::STATE_EXTSELECTABLE}, kEndEntry},
|
||||
{"treeitem", nsIAccessibleRole::ROLE_OUTLINEITEM, eNameOkFromChildren, eNoValue, kNoReqStates,
|
||||
{"disabled", kBoolState, nsIAccessibleStates::STATE_UNAVAILABLE},
|
||||
{"selected", kBoolState, nsIAccessibleStates::STATE_SELECTED | nsIAccessibleStates::STATE_SELECTABLE},
|
||||
{"selected", "false", nsIAccessibleStates::STATE_SELECTABLE},
|
||||
{"expanded", kBoolState, nsIAccessibleStates::STATE_EXPANDED},
|
||||
{"expanded", "false", nsIAccessibleStates::STATE_COLLAPSED},
|
||||
{"checked", kBoolState, nsIAccessibleStates::STATE_CHECKED | nsIAccessibleStates::STATE_CHECKABLE},
|
||||
{"checked", "mixed", nsIAccessibleStates::STATE_MIXED},
|
||||
{"checked", "false", nsIAccessibleStates::STATE_CHECKABLE},},
|
||||
{nsnull, nsIAccessibleRole::ROLE_NOTHING, eNameLabelOrTitle, eNoValue, kNoReqStates, kEndEntry} // Last item
|
||||
{&nsAccessibilityAtoms::aria_selected, kBoolState, nsIAccessibleStates::STATE_SELECTED | nsIAccessibleStates::STATE_SELECTABLE},
|
||||
{&nsAccessibilityAtoms::aria_selected, "false", nsIAccessibleStates::STATE_SELECTABLE},
|
||||
{&nsAccessibilityAtoms::aria_expanded, kBoolState, nsIAccessibleStates::STATE_EXPANDED},
|
||||
{&nsAccessibilityAtoms::aria_expanded, "false", nsIAccessibleStates::STATE_COLLAPSED},
|
||||
{&nsAccessibilityAtoms::aria_checked, kBoolState, nsIAccessibleStates::STATE_CHECKED | nsIAccessibleStates::STATE_CHECKABLE},
|
||||
{&nsAccessibilityAtoms::aria_checked, "mixed", nsIAccessibleStates::STATE_MIXED | nsIAccessibleStates::STATE_CHECKABLE},
|
||||
{&nsAccessibilityAtoms::aria_checked, "false", nsIAccessibleStates::STATE_CHECKABLE},},
|
||||
};
|
||||
|
||||
PRUint32 nsARIAMap::gWAIRoleMapLength = NS_ARRAY_LENGTH(nsARIAMap::gWAIRoleMap);
|
||||
|
||||
nsRoleMapEntry nsARIAMap::gLandmarkRoleMap = {
|
||||
"",
|
||||
nsIAccessibleRole::ROLE_NOTHING,
|
||||
eNameLabelOrTitle,
|
||||
eNoValue,
|
||||
kNoReqStates,
|
||||
kEndEntry
|
||||
};
|
||||
|
||||
nsRoleMapEntry nsARIAMap::gEmptyRoleMap = {
|
||||
"",
|
||||
nsIAccessibleRole::ROLE_NOTHING,
|
||||
eNameLabelOrTitle,
|
||||
eNoValue,
|
||||
kNoReqStates,
|
||||
kEndEntry
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -202,11 +200,12 @@ nsRoleMapEntry nsARIAMap::gWAIRoleMap[] =
|
|||
* whether there is an ARIA role or not:
|
||||
*/
|
||||
nsStateMapEntry nsARIAMap::gWAIUnivStateMap[] = {
|
||||
{"required", kBoolState, nsIAccessibleStates::STATE_REQUIRED},
|
||||
{"invalid", kBoolState, nsIAccessibleStates::STATE_INVALID},
|
||||
{"haspopup", kBoolState, nsIAccessibleStates::STATE_HASPOPUP},
|
||||
{"busy", "true", nsIAccessibleStates::STATE_BUSY},
|
||||
{"busy", "error", nsIAccessibleStates::STATE_INVALID},
|
||||
{&nsAccessibilityAtoms::aria_required, kBoolState, nsIAccessibleStates::STATE_REQUIRED},
|
||||
{&nsAccessibilityAtoms::aria_invalid, kBoolState, nsIAccessibleStates::STATE_INVALID},
|
||||
{&nsAccessibilityAtoms::aria_haspopup, kBoolState, nsIAccessibleStates::STATE_HASPOPUP},
|
||||
{&nsAccessibilityAtoms::aria_busy, "true", nsIAccessibleStates::STATE_BUSY},
|
||||
{&nsAccessibilityAtoms::aria_busy, "error", nsIAccessibleStates::STATE_INVALID},
|
||||
{&nsAccessibilityAtoms::aria_disabled, kBoolState, nsIAccessibleStates::STATE_UNAVAILABLE},
|
||||
kEndEntry
|
||||
};
|
||||
|
||||
|
|
|
@ -41,6 +41,7 @@
|
|||
#define _nsARIAMap_H_
|
||||
|
||||
#include "prtypes.h"
|
||||
#include "nsAccessibilityAtoms.h"
|
||||
|
||||
// Name mapping rule: can the name be computed from descendants?
|
||||
enum ENameRule
|
||||
|
@ -66,7 +67,7 @@ enum ENameRule
|
|||
enum EValueRule
|
||||
{
|
||||
eNoValue,
|
||||
eHasValueMinMax // Supports value, min and max from aaa:valuenow, valuemin and valuemax
|
||||
eHasValueMinMax // Supports value, min and max from aria-valuenow, aria-valuemin and aria-valuemax
|
||||
};
|
||||
|
||||
// Used for an nsStateMapEntry if a given state attribute supports "true" and "false"
|
||||
|
@ -79,7 +80,7 @@ enum EValueRule
|
|||
// nsStateMapEntry.state
|
||||
struct nsStateMapEntry
|
||||
{
|
||||
const char* attributeName; // magic value of nsnull means last entry in map
|
||||
nsIAtom** attributeName; // nsnull indicates last entry in map
|
||||
const char* attributeValue; // magic value of kBoolState (0) means supports "true" and "false"
|
||||
PRUint32 state; // If match, this is the nsIAccessibleStates to map to
|
||||
};
|
||||
|
@ -103,7 +104,7 @@ struct nsRoleMapEntry
|
|||
PRUint32 state; // or kNoReqStates if no nsIAccessibleStates are automatic for this role.
|
||||
|
||||
// ARIA properties supported for this role
|
||||
// (in other words, the aaa:foo attribute to nsIAccessibleStates mapping rules)
|
||||
// (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.
|
||||
|
@ -124,7 +125,29 @@ struct nsRoleMapEntry
|
|||
*/
|
||||
struct nsARIAMap
|
||||
{
|
||||
/**
|
||||
* Array of supported ARIA role map entries and its length.
|
||||
*/
|
||||
static nsRoleMapEntry gWAIRoleMap[];
|
||||
static PRUint32 gWAIRoleMapLength;
|
||||
|
||||
/**
|
||||
* Landmark role map entry. Used when specified ARIA role isn't mapped to
|
||||
* accessibility API.
|
||||
*/
|
||||
static nsRoleMapEntry gLandmarkRoleMap;
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
static nsRoleMapEntry gEmptyRoleMap;
|
||||
|
||||
/**
|
||||
* State map of ARIA states applied to any accessible not depending on
|
||||
* the role.
|
||||
*/
|
||||
static nsStateMapEntry gWAIUnivStateMap[];
|
||||
};
|
||||
|
||||
|
|
|
@ -53,6 +53,7 @@
|
|||
#include "nsIDOMElement.h"
|
||||
#include "nsIDOMHTMLDocument.h"
|
||||
#include "nsIDOMHTMLElement.h"
|
||||
#include "nsIDOMNSDocument.h"
|
||||
#include "nsIDOMNSHTMLElement.h"
|
||||
#include "nsIDOMViewCSS.h"
|
||||
#include "nsIDOMWindow.h"
|
||||
|
@ -85,15 +86,19 @@ nsIStringBundle *nsAccessNode::gKeyStringBundle = 0;
|
|||
nsITimer *nsAccessNode::gDoCommandTimer = 0;
|
||||
nsIDOMNode *nsAccessNode::gLastFocusedNode = 0;
|
||||
PRBool nsAccessNode::gIsAccessibilityActive = PR_FALSE;
|
||||
PRBool nsAccessNode::gIsShuttingDownApp = PR_FALSE;
|
||||
PRBool nsAccessNode::gIsCacheDisabled = PR_FALSE;
|
||||
PRBool nsAccessNode::gIsFormFillEnabled = PR_FALSE;
|
||||
nsInterfaceHashtable<nsVoidHashKey, nsIAccessNode> nsAccessNode::gGlobalDocAccessibleCache;
|
||||
nsAccessNodeHashtable nsAccessNode::gGlobalDocAccessibleCache;
|
||||
|
||||
nsApplicationAccessibleWrap *nsAccessNode::gApplicationAccessible = nsnull;
|
||||
|
||||
nsIAccessibilityService *nsAccessNode::sAccService = nsnull;
|
||||
nsIAccessibilityService *nsAccessNode::GetAccService()
|
||||
{
|
||||
if (!gIsAccessibilityActive)
|
||||
return nsnull;
|
||||
|
||||
if (!sAccService) {
|
||||
nsresult rv = CallGetService("@mozilla.org/accessibilityService;1",
|
||||
&sAccService);
|
||||
|
@ -174,12 +179,29 @@ NS_IMETHODIMP nsAccessNode::Init()
|
|||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
void* uniqueID;
|
||||
GetUniqueID(&uniqueID);
|
||||
nsCOMPtr<nsPIAccessibleDocument> privateDocAccessible =
|
||||
do_QueryInterface(docAccessible);
|
||||
NS_ASSERTION(privateDocAccessible, "No private docaccessible for docaccessible");
|
||||
privateDocAccessible->CacheAccessNode(uniqueID, this);
|
||||
|
||||
// Make sure an ancestor in real content is cached
|
||||
// so that nsDocAccessible::RefreshNodes() can find the anonymous subtree to release when
|
||||
// the root node goes away
|
||||
nsCOMPtr<nsIContent> content = do_QueryInterface(mDOMNode);
|
||||
if (content && (content->IsNativeAnonymous() ||
|
||||
content->GetBindingParent())) {
|
||||
// Specific examples of where this is used: <input type="file"> and <xul:findbar>
|
||||
nsCOMPtr<nsIAccessible> parentAccessible;
|
||||
docAccessible->GetAccessibleInParentChain(mDOMNode, PR_TRUE, getter_AddRefs(parentAccessible));
|
||||
if (parentAccessible) {
|
||||
PRInt32 childCountUnused;
|
||||
parentAccessible->GetChildCount(&childCountUnused);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef DEBUG_A11Y
|
||||
mIsInitialized = PR_TRUE;
|
||||
#endif
|
||||
|
@ -204,8 +226,10 @@ NS_IMETHODIMP nsAccessNode::GetUniqueID(void **aUniqueID)
|
|||
|
||||
NS_IMETHODIMP nsAccessNode::GetOwnerWindow(void **aWindow)
|
||||
{
|
||||
*aWindow = nsnull;
|
||||
nsCOMPtr<nsIAccessibleDocument> docAccessible(GetDocAccessible());
|
||||
NS_ASSERTION(docAccessible, "No root accessible pointer back, Init() not called.");
|
||||
if (!docAccessible)
|
||||
return NS_ERROR_FAILURE; // This node or doc accessible is shut down
|
||||
return docAccessible->GetWindowHandle(aWindow);
|
||||
}
|
||||
|
||||
|
@ -223,16 +247,18 @@ nsAccessNode::GetApplicationAccessible()
|
|||
if (!gApplicationAccessible)
|
||||
return nsnull;
|
||||
|
||||
// Addref on create. Will Release in ShutdownXPAccessibility()
|
||||
NS_ADDREF(gApplicationAccessible);
|
||||
|
||||
nsresult rv = gApplicationAccessible->Init();
|
||||
if (NS_FAILED(rv)) {
|
||||
NS_RELEASE(gApplicationAccessible);
|
||||
gApplicationAccessible = nsnull;
|
||||
return nsnull;
|
||||
}
|
||||
}
|
||||
|
||||
NS_ADDREF(gApplicationAccessible);
|
||||
NS_ADDREF(gApplicationAccessible); // Addref because we're a getter
|
||||
return gApplicationAccessible;
|
||||
}
|
||||
|
||||
|
@ -288,6 +314,8 @@ void nsAccessNode::ShutdownXPAccessibility()
|
|||
if (!gIsAccessibilityActive) {
|
||||
return;
|
||||
}
|
||||
gIsShuttingDownApp = PR_TRUE;
|
||||
|
||||
NS_IF_RELEASE(gStringBundle);
|
||||
NS_IF_RELEASE(gKeyStringBundle);
|
||||
NS_IF_RELEASE(gDoCommandTimer);
|
||||
|
@ -295,10 +323,13 @@ void nsAccessNode::ShutdownXPAccessibility()
|
|||
NS_IF_RELEASE(sAccService);
|
||||
|
||||
nsApplicationAccessibleWrap::Unload();
|
||||
NS_IF_RELEASE(gApplicationAccessible);
|
||||
|
||||
ClearCache(gGlobalDocAccessibleCache);
|
||||
|
||||
// Release gApplicationAccessible after everything else is shutdown
|
||||
// so we don't accidently create it again while tearing down root accessibles
|
||||
NS_IF_RELEASE(gApplicationAccessible);
|
||||
gApplicationAccessible = nsnull;
|
||||
|
||||
gIsAccessibilityActive = PR_FALSE;
|
||||
NotifyA11yInitOrShutdown();
|
||||
}
|
||||
|
@ -337,7 +368,7 @@ already_AddRefed<nsIAccessibleDocument> nsAccessNode::GetDocAccessible()
|
|||
already_AddRefed<nsRootAccessible> nsAccessNode::GetRootAccessible()
|
||||
{
|
||||
nsCOMPtr<nsIDocShellTreeItem> docShellTreeItem =
|
||||
GetDocShellTreeItemFor(mDOMNode);
|
||||
nsAccUtils::GetDocShellTreeItemFor(mDOMNode);
|
||||
NS_ASSERTION(docShellTreeItem, "No docshell tree item for mDOMNode");
|
||||
if (!docShellTreeItem) {
|
||||
return nsnull;
|
||||
|
@ -368,16 +399,7 @@ nsIFrame* nsAccessNode::GetFrame()
|
|||
return nsnull;
|
||||
|
||||
nsCOMPtr<nsIContent> content(do_QueryInterface(mDOMNode));
|
||||
while (content) {
|
||||
nsIFrame* frame = shell->GetPrimaryFrameFor(content);
|
||||
if (frame) {
|
||||
return frame;
|
||||
}
|
||||
nsCOMPtr<nsIContent> tempContent = content->GetParent();
|
||||
content = tempContent;
|
||||
}
|
||||
|
||||
return nsnull;
|
||||
return content ? shell->GetPrimaryFrameFor(content) : nsnull;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
|
@ -424,7 +446,8 @@ nsAccessNode::GetInnerHTML(nsAString& aInnerHTML)
|
|||
NS_IMETHODIMP
|
||||
nsAccessNode::ScrollTo(PRUint32 aScrollType)
|
||||
{
|
||||
NS_ENSURE_TRUE(mDOMNode, NS_ERROR_FAILURE);
|
||||
if (IsDefunct())
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
nsCOMPtr<nsIPresShell> shell(GetPresShell());
|
||||
NS_ENSURE_TRUE(shell, NS_ERROR_FAILURE);
|
||||
|
@ -435,42 +458,28 @@ nsAccessNode::ScrollTo(PRUint32 aScrollType)
|
|||
nsCOMPtr<nsIContent> content = frame->GetContent();
|
||||
NS_ENSURE_TRUE(content, NS_ERROR_FAILURE);
|
||||
|
||||
PRInt32 vPercent, hPercent;
|
||||
switch (aScrollType)
|
||||
{
|
||||
case nsIAccessibleScrollType::SCROLL_TYPE_TOP_LEFT:
|
||||
vPercent = NS_PRESSHELL_SCROLL_TOP;
|
||||
hPercent = NS_PRESSHELL_SCROLL_LEFT;
|
||||
break;
|
||||
case nsIAccessibleScrollType::SCROLL_TYPE_BOTTOM_RIGHT:
|
||||
vPercent = NS_PRESSHELL_SCROLL_BOTTOM;
|
||||
hPercent = NS_PRESSHELL_SCROLL_RIGHT;
|
||||
break;
|
||||
case nsIAccessibleScrollType::SCROLL_TYPE_TOP_EDGE:
|
||||
vPercent = NS_PRESSHELL_SCROLL_TOP;
|
||||
hPercent = NS_PRESSHELL_SCROLL_ANYWHERE;
|
||||
break;
|
||||
case nsIAccessibleScrollType::SCROLL_TYPE_BOTTOM_EDGE:
|
||||
vPercent = NS_PRESSHELL_SCROLL_BOTTOM;
|
||||
hPercent = NS_PRESSHELL_SCROLL_ANYWHERE;
|
||||
break;
|
||||
case nsIAccessibleScrollType::SCROLL_TYPE_LEFT_EDGE:
|
||||
vPercent = NS_PRESSHELL_SCROLL_ANYWHERE;
|
||||
hPercent = NS_PRESSHELL_SCROLL_LEFT;
|
||||
break;
|
||||
case nsIAccessibleScrollType::SCROLL_TYPE_RIGHT_EDGE:
|
||||
vPercent = NS_PRESSHELL_SCROLL_ANYWHERE;
|
||||
hPercent = NS_PRESSHELL_SCROLL_RIGHT;
|
||||
break;
|
||||
}
|
||||
|
||||
PRInt16 vPercent, hPercent;
|
||||
nsAccUtils::ConvertScrollTypeToPercents(aScrollType, &vPercent, &hPercent);
|
||||
return shell->ScrollContentIntoView(content, vPercent, hPercent);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsAccessNode::ScrollToPoint(PRUint32 aCoordinateType, PRInt32 aX, PRInt32 aY)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
nsIFrame *frame = GetFrame();
|
||||
if (!frame)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
nsIntPoint coords;
|
||||
nsresult rv = nsAccUtils::ConvertToScreenCoords(aX, aY, aCoordinateType,
|
||||
this, &coords);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsIFrame *parentFrame = frame;
|
||||
while ((parentFrame = parentFrame->GetParent()))
|
||||
nsAccUtils::ScrollFrameToPoint(parentFrame, frame, coords);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
|
@ -655,11 +664,16 @@ void nsAccessNode::GetComputedStyleDeclaration(const nsAString& aPseudoElt,
|
|||
/***************** Hashtable of nsIAccessNode's *****************/
|
||||
|
||||
already_AddRefed<nsIAccessibleDocument>
|
||||
nsAccessNode::GetDocAccessibleFor(nsIWeakReference *aPresShell)
|
||||
nsAccessNode::GetDocAccessibleFor(nsIDocument *aDocument)
|
||||
{
|
||||
if (!aDocument) {
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
nsIAccessibleDocument *docAccessible = nsnull;
|
||||
nsCOMPtr<nsIAccessNode> accessNode;
|
||||
gGlobalDocAccessibleCache.Get(static_cast<void*>(aPresShell), getter_AddRefs(accessNode));
|
||||
gGlobalDocAccessibleCache.Get(static_cast<void*>(aDocument),
|
||||
getter_AddRefs(accessNode));
|
||||
if (accessNode) {
|
||||
CallQueryInterface(accessNode, &docAccessible);
|
||||
}
|
||||
|
@ -667,15 +681,26 @@ nsAccessNode::GetDocAccessibleFor(nsIWeakReference *aPresShell)
|
|||
}
|
||||
|
||||
already_AddRefed<nsIAccessibleDocument>
|
||||
nsAccessNode::GetDocAccessibleFor(nsISupports *aContainer, PRBool aCanCreate)
|
||||
nsAccessNode::GetDocAccessibleFor(nsIWeakReference *aWeakShell)
|
||||
{
|
||||
nsCOMPtr<nsIPresShell> presShell(do_QueryReferent(aWeakShell));
|
||||
if (!presShell) {
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
return nsAccessNode::GetDocAccessibleFor(presShell->GetDocument());
|
||||
}
|
||||
|
||||
already_AddRefed<nsIAccessibleDocument>
|
||||
nsAccessNode::GetDocAccessibleFor(nsIDocShellTreeItem *aContainer,
|
||||
PRBool aCanCreate)
|
||||
{
|
||||
if (!aCanCreate) {
|
||||
nsCOMPtr<nsIDocShell> docShell(do_QueryInterface(aContainer));
|
||||
NS_ASSERTION(docShell, "This method currently only supports docshells");
|
||||
nsCOMPtr<nsIPresShell> presShell;
|
||||
docShell->GetPresShell(getter_AddRefs(presShell));
|
||||
nsCOMPtr<nsIWeakReference> weakShell(do_GetWeakReference(presShell));
|
||||
return weakShell ? GetDocAccessibleFor(weakShell) : nsnull;
|
||||
return presShell ? GetDocAccessibleFor(presShell->GetDocument()) : nsnull;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIDOMNode> node = GetDOMNodeForContainer(aContainer);
|
||||
|
@ -696,8 +721,16 @@ already_AddRefed<nsIAccessibleDocument>
|
|||
nsAccessNode::GetDocAccessibleFor(nsIDOMNode *aNode)
|
||||
{
|
||||
nsCOMPtr<nsIPresShell> eventShell = GetPresShellFor(aNode);
|
||||
nsCOMPtr<nsIWeakReference> weakEventShell(do_GetWeakReference(eventShell));
|
||||
return weakEventShell? GetDocAccessibleFor(weakEventShell) : nsnull;
|
||||
if (eventShell) {
|
||||
return GetDocAccessibleFor(eventShell->GetDocument());
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIDocument> doc(do_QueryInterface(aNode));
|
||||
if (doc) {
|
||||
return GetDocAccessibleFor(doc);
|
||||
}
|
||||
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
already_AddRefed<nsIPresShell>
|
||||
|
@ -717,30 +750,6 @@ nsAccessNode::GetPresShellFor(nsIDOMNode *aNode)
|
|||
return presShell;
|
||||
}
|
||||
|
||||
|
||||
already_AddRefed<nsIDocShellTreeItem>
|
||||
nsAccessNode::GetDocShellTreeItemFor(nsIDOMNode *aStartNode)
|
||||
{
|
||||
if (!aStartNode) {
|
||||
return nsnull;
|
||||
}
|
||||
nsCOMPtr<nsIDOMDocument> domDoc;
|
||||
aStartNode->GetOwnerDocument(getter_AddRefs(domDoc));
|
||||
nsCOMPtr<nsIDocument> doc(do_QueryInterface(domDoc));
|
||||
if (!doc) {
|
||||
doc = do_QueryInterface(aStartNode);
|
||||
}
|
||||
NS_ASSERTION(doc, "No document for node passed in");
|
||||
NS_ENSURE_TRUE(doc, nsnull);
|
||||
nsCOMPtr<nsISupports> container = doc->GetContainer();
|
||||
nsIDocShellTreeItem *docShellTreeItem = nsnull;
|
||||
if (container) {
|
||||
CallQueryInterface(container, &docShellTreeItem);
|
||||
}
|
||||
|
||||
return docShellTreeItem;
|
||||
}
|
||||
|
||||
already_AddRefed<nsIDOMNode>
|
||||
nsAccessNode::GetDOMNodeForContainer(nsISupports *aContainer)
|
||||
{
|
||||
|
@ -762,7 +771,8 @@ nsAccessNode::GetDOMNodeForContainer(nsISupports *aContainer)
|
|||
return node;
|
||||
}
|
||||
|
||||
void nsAccessNode::PutCacheEntry(nsInterfaceHashtable<nsVoidHashKey, nsIAccessNode> &aCache,
|
||||
void
|
||||
nsAccessNode::PutCacheEntry(nsAccessNodeHashtable& aCache,
|
||||
void* aUniqueID,
|
||||
nsIAccessNode *aAccessNode)
|
||||
{
|
||||
|
@ -774,7 +784,8 @@ void nsAccessNode::PutCacheEntry(nsInterfaceHashtable<nsVoidHashKey, nsIAccessNo
|
|||
aCache.Put(aUniqueID, aAccessNode);
|
||||
}
|
||||
|
||||
void nsAccessNode::GetCacheEntry(nsInterfaceHashtable<nsVoidHashKey, nsIAccessNode> &aCache,
|
||||
void
|
||||
nsAccessNode::GetCacheEntry(nsAccessNodeHashtable& aCache,
|
||||
void* aUniqueID,
|
||||
nsIAccessNode **aAccessNode)
|
||||
{
|
||||
|
@ -783,13 +794,17 @@ void nsAccessNode::GetCacheEntry(nsInterfaceHashtable<nsVoidHashKey, nsIAccessNo
|
|||
|
||||
PLDHashOperator nsAccessNode::ClearCacheEntry(const void* aKey, nsCOMPtr<nsIAccessNode>& aAccessNode, void* aUserArg)
|
||||
{
|
||||
NS_ASSERTION(aAccessNode, "Calling ClearCacheEntry with a NULL pointer!");
|
||||
if (aAccessNode) {
|
||||
nsCOMPtr<nsPIAccessNode> privateAccessNode(do_QueryInterface(aAccessNode));
|
||||
privateAccessNode->Shutdown();
|
||||
}
|
||||
|
||||
return PL_DHASH_REMOVE;
|
||||
}
|
||||
|
||||
void nsAccessNode::ClearCache(nsInterfaceHashtable<nsVoidHashKey, nsIAccessNode> &aCache)
|
||||
void
|
||||
nsAccessNode::ClearCache(nsAccessNodeHashtable& aCache)
|
||||
{
|
||||
aCache.Enumerate(ClearCacheEntry, nsnull);
|
||||
}
|
||||
|
|
|
@ -49,7 +49,6 @@
|
|||
#include "nsIAccessNode.h"
|
||||
#include "nsIContent.h"
|
||||
#include "nsPIAccessNode.h"
|
||||
#include "nsIDocShellTreeItem.h"
|
||||
#include "nsIDOMNode.h"
|
||||
#include "nsINameSpaceManager.h"
|
||||
#include "nsIStringBundle.h"
|
||||
|
@ -65,34 +64,13 @@ class nsIDOMNodeList;
|
|||
class nsITimer;
|
||||
class nsRootAccessible;
|
||||
class nsApplicationAccessibleWrap;
|
||||
class nsIDocShellTreeItem;
|
||||
|
||||
#define ACCESSIBLE_BUNDLE_URL "chrome://global-platform/locale/accessible.properties"
|
||||
#define PLATFORM_KEYS_BUNDLE_URL "chrome://global-platform/locale/platformKeys.properties"
|
||||
|
||||
/* hashkey wrapper using void* KeyType
|
||||
*
|
||||
* @see nsTHashtable::EntryType for specification
|
||||
*/
|
||||
class nsVoidHashKey : public PLDHashEntryHdr
|
||||
{
|
||||
public:
|
||||
typedef const void* KeyType;
|
||||
typedef const void* KeyTypePointer;
|
||||
|
||||
nsVoidHashKey(KeyTypePointer aKey) : mValue(aKey) { }
|
||||
nsVoidHashKey(const nsVoidHashKey& toCopy) : mValue(toCopy.mValue) { }
|
||||
~nsVoidHashKey() { }
|
||||
|
||||
KeyType GetKey() const { return mValue; }
|
||||
PRBool KeyEquals(KeyTypePointer aKey) const { return aKey == mValue; }
|
||||
|
||||
static KeyTypePointer KeyToPointer(KeyType aKey) { return aKey; }
|
||||
static PLDHashNumber HashKey(KeyTypePointer aKey) { return NS_PTR_TO_INT32(aKey) >> 2; }
|
||||
enum { ALLOW_MEMMOVE = PR_TRUE };
|
||||
|
||||
private:
|
||||
const void* mValue;
|
||||
};
|
||||
typedef nsInterfaceHashtable<nsVoidPtrHashKey, nsIAccessNode>
|
||||
nsAccessNodeHashtable;
|
||||
|
||||
class nsAccessNode: public nsIAccessNode, public nsPIAccessNode
|
||||
{
|
||||
|
@ -113,40 +91,23 @@ class nsAccessNode: public nsIAccessNode, public nsPIAccessNode
|
|||
static already_AddRefed<nsApplicationAccessibleWrap> GetApplicationAccessible();
|
||||
|
||||
// Static methods for handling per-document cache
|
||||
static void PutCacheEntry(nsInterfaceHashtable<nsVoidHashKey, nsIAccessNode>& aCache,
|
||||
static void PutCacheEntry(nsAccessNodeHashtable& aCache,
|
||||
void* aUniqueID, nsIAccessNode *aAccessNode);
|
||||
static void GetCacheEntry(nsInterfaceHashtable<nsVoidHashKey, nsIAccessNode>& aCache, void* aUniqueID,
|
||||
nsIAccessNode **aAccessNode);
|
||||
static void ClearCache(nsInterfaceHashtable<nsVoidHashKey, nsIAccessNode>& aCache);
|
||||
static void GetCacheEntry(nsAccessNodeHashtable& aCache,
|
||||
void* aUniqueID, nsIAccessNode **aAccessNode);
|
||||
static void ClearCache(nsAccessNodeHashtable& aCache);
|
||||
|
||||
static PLDHashOperator PR_CALLBACK ClearCacheEntry(const void* aKey, nsCOMPtr<nsIAccessNode>& aAccessNode, void* aUserArg);
|
||||
|
||||
// Static cache methods for global document cache
|
||||
static already_AddRefed<nsIAccessibleDocument> GetDocAccessibleFor(nsIWeakReference *aPresShell);
|
||||
static already_AddRefed<nsIAccessibleDocument> GetDocAccessibleFor(nsISupports *aContainer, PRBool aCanCreate = PR_FALSE);
|
||||
static already_AddRefed<nsIAccessibleDocument> GetDocAccessibleFor(nsIDocument *aDocument);
|
||||
static already_AddRefed<nsIAccessibleDocument> GetDocAccessibleFor(nsIWeakReference *aWeakShell);
|
||||
static already_AddRefed<nsIAccessibleDocument> GetDocAccessibleFor(nsIDocShellTreeItem *aContainer, PRBool aCanCreate = PR_FALSE);
|
||||
static already_AddRefed<nsIAccessibleDocument> GetDocAccessibleFor(nsIDOMNode *aNode);
|
||||
|
||||
static already_AddRefed<nsIDocShellTreeItem> GetDocShellTreeItemFor(nsIDOMNode *aStartNode);
|
||||
static already_AddRefed<nsIDOMNode> GetDOMNodeForContainer(nsISupports *aContainer);
|
||||
static already_AddRefed<nsIPresShell> GetPresShellFor(nsIDOMNode *aStartNode);
|
||||
|
||||
// Return PR_TRUE if there is a role attribute
|
||||
static PRBool HasRoleAttribute(nsIContent *aContent)
|
||||
{
|
||||
return (aContent->IsNodeOfType(nsINode::eHTML) && aContent->HasAttr(kNameSpaceID_None, nsAccessibilityAtoms::role)) ||
|
||||
aContent->HasAttr(kNameSpaceID_XHTML, nsAccessibilityAtoms::role) ||
|
||||
aContent->HasAttr(kNameSpaceID_XHTML2_Unofficial, nsAccessibilityAtoms::role);
|
||||
}
|
||||
|
||||
// Return PR_TRUE if there is a role attribute, and fill it into aRole
|
||||
static PRBool GetRoleAttribute(nsIContent *aContent, nsAString& aRole)
|
||||
{
|
||||
aRole.Truncate();
|
||||
return (aContent->IsNodeOfType(nsINode::eHTML) && aContent->GetAttr(kNameSpaceID_None, nsAccessibilityAtoms::role, aRole)) ||
|
||||
aContent->GetAttr(kNameSpaceID_XHTML, nsAccessibilityAtoms::role, aRole) ||
|
||||
aContent->GetAttr(kNameSpaceID_XHTML2_Unofficial, nsAccessibilityAtoms::role, aRole);
|
||||
}
|
||||
|
||||
static void GetComputedStyleDeclaration(const nsAString& aPseudoElt,
|
||||
nsIDOMElement *aElement,
|
||||
nsIDOMCSSStyleDeclaration **aCssDecl);
|
||||
|
@ -157,6 +118,11 @@ class nsAccessNode: public nsIAccessNode, public nsPIAccessNode
|
|||
static nsIAccessibilityService* GetAccService();
|
||||
already_AddRefed<nsIDOMNode> GetCurrentFocus();
|
||||
|
||||
/**
|
||||
* Returns true when the accessible is defunct.
|
||||
*/
|
||||
virtual PRBool IsDefunct() { return !mDOMNode; }
|
||||
|
||||
protected:
|
||||
nsresult MakeAccessNode(nsIDOMNode *aNode, nsIAccessNode **aAccessNode);
|
||||
already_AddRefed<nsIPresShell> GetPresShell();
|
||||
|
@ -181,10 +147,11 @@ protected:
|
|||
static nsIStringBundle *gKeyStringBundle;
|
||||
static nsITimer *gDoCommandTimer;
|
||||
static PRBool gIsAccessibilityActive;
|
||||
static PRBool gIsShuttingDownApp;
|
||||
static PRBool gIsCacheDisabled;
|
||||
static PRBool gIsFormFillEnabled;
|
||||
|
||||
static nsInterfaceHashtable<nsVoidHashKey, nsIAccessNode> gGlobalDocAccessibleCache;
|
||||
static nsAccessNodeHashtable gGlobalDocAccessibleCache;
|
||||
|
||||
private:
|
||||
static nsIAccessibilityService *sAccService;
|
||||
|
|
|
@ -79,17 +79,22 @@ ACCESSIBILITY_ATOM(inlineFrame, "InlineFrame")
|
|||
ACCESSIBILITY_ATOM(objectFrame, "ObjectFrame")
|
||||
ACCESSIBILITY_ATOM(scrollFrame, "ScrollFrame")
|
||||
ACCESSIBILITY_ATOM(textFrame, "TextFrame")
|
||||
ACCESSIBILITY_ATOM(tableCaptionFrame, "TableCaptionFrame")
|
||||
ACCESSIBILITY_ATOM(tableCellFrame, "TableCellFrame")
|
||||
ACCESSIBILITY_ATOM(tableOuterFrame, "TableOuterFrame")
|
||||
ACCESSIBILITY_ATOM(tableRowGroupFrame, "TableRowGroupFrame")
|
||||
ACCESSIBILITY_ATOM(tableRowFrame, "TableRowFrame")
|
||||
|
||||
// Alphabetical list of tag names
|
||||
ACCESSIBILITY_ATOM(a, "a")
|
||||
ACCESSIBILITY_ATOM(abbr, "abbr")
|
||||
ACCESSIBILITY_ATOM(acronym, "acronym")
|
||||
ACCESSIBILITY_ATOM(area, "area")
|
||||
ACCESSIBILITY_ATOM(autocomplete, "autocomplete")
|
||||
ACCESSIBILITY_ATOM(blockquote, "blockquote")
|
||||
ACCESSIBILITY_ATOM(br, "br")
|
||||
ACCESSIBILITY_ATOM(body, "body")
|
||||
ACCESSIBILITY_ATOM(caption, "caption") // XUL
|
||||
ACCESSIBILITY_ATOM(choices, "choices") // XForms
|
||||
ACCESSIBILITY_ATOM(description, "description") // XUL
|
||||
ACCESSIBILITY_ATOM(dd, "dd")
|
||||
|
@ -111,6 +116,10 @@ ACCESSIBILITY_ATOM(label, "label")
|
|||
ACCESSIBILITY_ATOM(legend, "legend")
|
||||
ACCESSIBILITY_ATOM(li, "li")
|
||||
ACCESSIBILITY_ATOM(link, "link")
|
||||
ACCESSIBILITY_ATOM(listcols, "listcols") // XUL
|
||||
ACCESSIBILITY_ATOM(listcol, "listcol") // XUL
|
||||
ACCESSIBILITY_ATOM(listhead, "listhead") // XUL
|
||||
ACCESSIBILITY_ATOM(listheader, "listheader") // XUL
|
||||
ACCESSIBILITY_ATOM(map, "map")
|
||||
ACCESSIBILITY_ATOM(math, "math")
|
||||
ACCESSIBILITY_ATOM(menu, "menu") // XUL
|
||||
|
@ -124,6 +133,7 @@ ACCESSIBILITY_ATOM(select, "select")
|
|||
ACCESSIBILITY_ATOM(select1, "select1") // XForms
|
||||
ACCESSIBILITY_ATOM(svg, "svg")
|
||||
ACCESSIBILITY_ATOM(table, "table")
|
||||
ACCESSIBILITY_ATOM(tabpanels, "tabpanels") // XUL
|
||||
ACCESSIBILITY_ATOM(tbody, "tbody")
|
||||
ACCESSIBILITY_ATOM(td, "td")
|
||||
ACCESSIBILITY_ATOM(th, "th")
|
||||
|
@ -139,33 +149,35 @@ ACCESSIBILITY_ATOM(tooltip, "tooltip") // XUL
|
|||
ACCESSIBILITY_ATOM(tr, "tr")
|
||||
ACCESSIBILITY_ATOM(ul, "ul")
|
||||
|
||||
// DHTML accessibility relationship attributes
|
||||
ACCESSIBILITY_ATOM(controls, "controls")
|
||||
ACCESSIBILITY_ATOM(describedby, "describedby")
|
||||
ACCESSIBILITY_ATOM(flowto, "flowto")
|
||||
ACCESSIBILITY_ATOM(labelledby, "labelledby")
|
||||
ACCESSIBILITY_ATOM(owns, "owns")
|
||||
|
||||
// Alphabetical list of attributes
|
||||
ACCESSIBILITY_ATOM(acceltext, "acceltext")
|
||||
ACCESSIBILITY_ATOM(accesskey, "accesskey")
|
||||
ACCESSIBILITY_ATOM(alt, "alt")
|
||||
ACCESSIBILITY_ATOM(anonid, "anonid") // Used for ID's in XBL
|
||||
ACCESSIBILITY_ATOM(autocomplete, "autocomplete") // Used as attribute value too
|
||||
ACCESSIBILITY_ATOM(contenteditable, "contenteditable")
|
||||
ACCESSIBILITY_ATOM(control, "control")
|
||||
ACCESSIBILITY_ATOM(cycles, "cycles") // used for XUL cycler attribute
|
||||
ACCESSIBILITY_ATOM(data, "data")
|
||||
ACCESSIBILITY_ATOM(disabled, "disabled")
|
||||
ACCESSIBILITY_ATOM(_class, "class")
|
||||
ACCESSIBILITY_ATOM(cycles, "cycles") // used for XUL cycler attribute
|
||||
ACCESSIBILITY_ATOM(curpos, "curpos") // XUL
|
||||
ACCESSIBILITY_ATOM(data, "data")
|
||||
ACCESSIBILITY_ATOM(droppable, "droppable") // XUL combo box
|
||||
ACCESSIBILITY_ATOM(editable, "editable")
|
||||
ACCESSIBILITY_ATOM(_for, "for")
|
||||
ACCESSIBILITY_ATOM(href, "href")
|
||||
ACCESSIBILITY_ATOM(id, "id")
|
||||
ACCESSIBILITY_ATOM(hidden, "hidden") // XUL tree columns
|
||||
ACCESSIBILITY_ATOM(href, "href") // XUL, XLink
|
||||
ACCESSIBILITY_ATOM(increment, "increment") // XUL
|
||||
ACCESSIBILITY_ATOM(lang, "lang")
|
||||
ACCESSIBILITY_ATOM(multiline, "multiline")
|
||||
ACCESSIBILITY_ATOM(linkedPanel, "linkedpanel") // XUL
|
||||
ACCESSIBILITY_ATOM(maxpos, "maxpos") // XUL
|
||||
ACCESSIBILITY_ATOM(minpos, "minpos") // XUL
|
||||
ACCESSIBILITY_ATOM(multiline, "multiline") // XUL
|
||||
ACCESSIBILITY_ATOM(name, "name")
|
||||
ACCESSIBILITY_ATOM(onclick, "onclick")
|
||||
ACCESSIBILITY_ATOM(readonly, "readonly")
|
||||
ACCESSIBILITY_ATOM(simple, "simple") // XLink
|
||||
ACCESSIBILITY_ATOM(src, "src")
|
||||
ACCESSIBILITY_ATOM(selected, "selected")
|
||||
ACCESSIBILITY_ATOM(summary, "summary")
|
||||
ACCESSIBILITY_ATOM(tabindex, "tabindex")
|
||||
ACCESSIBILITY_ATOM(title, "title")
|
||||
|
@ -174,24 +186,58 @@ ACCESSIBILITY_ATOM(type, "type")
|
|||
ACCESSIBILITY_ATOM(value, "value")
|
||||
|
||||
// ARIA (DHTML accessibility) attributes
|
||||
ACCESSIBILITY_ATOM(activedescendant, "activedescendant")
|
||||
ACCESSIBILITY_ATOM(checked, "checked")
|
||||
ACCESSIBILITY_ATOM(droppable, "droppable")
|
||||
ACCESSIBILITY_ATOM(expanded, "expanded")
|
||||
ACCESSIBILITY_ATOM(invalid, "invalid")
|
||||
ACCESSIBILITY_ATOM(level, "level")
|
||||
ACCESSIBILITY_ATOM(multiselectable, "multiselectable")
|
||||
ACCESSIBILITY_ATOM(posinset, "posinset")
|
||||
ACCESSIBILITY_ATOM(required, "required")
|
||||
// Also add to nsARIAMap.cpp and nsARIAMap.h
|
||||
// ARIA role attribute
|
||||
ACCESSIBILITY_ATOM(role, "role")
|
||||
ACCESSIBILITY_ATOM(selected, "selected")
|
||||
ACCESSIBILITY_ATOM(setsize, "setsize")
|
||||
ACCESSIBILITY_ATOM(valuenow, "valuenow") // For DHTML widget values
|
||||
ACCESSIBILITY_ATOM(valuemin, "valuemin")
|
||||
ACCESSIBILITY_ATOM(valuemax, "valuemax")
|
||||
ACCESSIBILITY_ATOM(hidden, "hidden")
|
||||
ACCESSIBILITY_ATOM(aria_activedescendant, "aria-activedescendant")
|
||||
ACCESSIBILITY_ATOM(aria_atomic, "aria-atomic")
|
||||
ACCESSIBILITY_ATOM(aria_autocomplete, "aria-autocomplete")
|
||||
ACCESSIBILITY_ATOM(aria_busy, "aria-busy")
|
||||
ACCESSIBILITY_ATOM(aria_channel, "aria-channel")
|
||||
ACCESSIBILITY_ATOM(aria_checked, "aria-checked")
|
||||
ACCESSIBILITY_ATOM(aria_controls, "aria-controls")
|
||||
ACCESSIBILITY_ATOM(aria_datatype, "aria-datatype")
|
||||
ACCESSIBILITY_ATOM(aria_describedby, "aria-describedby")
|
||||
ACCESSIBILITY_ATOM(aria_droppable, "aria-droppable")
|
||||
ACCESSIBILITY_ATOM(aria_disabled, "aria-disabled")
|
||||
ACCESSIBILITY_ATOM(aria_dropeffect, "aria-dropeffect")
|
||||
ACCESSIBILITY_ATOM(aria_expanded, "aria-expanded")
|
||||
ACCESSIBILITY_ATOM(aria_flowto, "aria-flowto")
|
||||
ACCESSIBILITY_ATOM(aria_grab, "aria-grab")
|
||||
ACCESSIBILITY_ATOM(aria_haspopup, "aria-haspopup")
|
||||
ACCESSIBILITY_ATOM(aria_invalid, "aria-invalid")
|
||||
ACCESSIBILITY_ATOM(aria_labelledby, "aria-labelledby")
|
||||
ACCESSIBILITY_ATOM(aria_level, "aria-level")
|
||||
ACCESSIBILITY_ATOM(aria_live, "aria-live")
|
||||
ACCESSIBILITY_ATOM(aria_multiline, "aria-multiline")
|
||||
ACCESSIBILITY_ATOM(aria_multiselectable, "aria-multiselectable")
|
||||
ACCESSIBILITY_ATOM(aria_owns, "aria-owns")
|
||||
ACCESSIBILITY_ATOM(aria_posinset, "aria-posinset")
|
||||
ACCESSIBILITY_ATOM(aria_pressed, "aria-pressed")
|
||||
ACCESSIBILITY_ATOM(aria_readonly, "aria-readonly")
|
||||
ACCESSIBILITY_ATOM(aria_relevant, "aria-relevant")
|
||||
ACCESSIBILITY_ATOM(aria_required, "aria-required")
|
||||
ACCESSIBILITY_ATOM(aria_selected, "aria-selected")
|
||||
ACCESSIBILITY_ATOM(aria_setsize, "aria-setsize")
|
||||
ACCESSIBILITY_ATOM(aria_sort, "aria-sort")
|
||||
ACCESSIBILITY_ATOM(aria_valuenow, "aria-valuenow")
|
||||
ACCESSIBILITY_ATOM(aria_valuemin, "aria-valuemin")
|
||||
ACCESSIBILITY_ATOM(aria_valuemax, "aria-valuemax")
|
||||
ACCESSIBILITY_ATOM(aria_valuetext, "aria-valuetext")
|
||||
|
||||
// misc atoms
|
||||
// a form property used to obtain the default label
|
||||
// of an HTML button from the button frame
|
||||
ACCESSIBILITY_ATOM(defaultLabel, "defaultLabel")
|
||||
|
||||
// Object attributes
|
||||
ACCESSIBILITY_ATOM(tableCellIndex, "table-cell-index")
|
||||
ACCESSIBILITY_ATOM(containerAtomic, "container-atomic")
|
||||
ACCESSIBILITY_ATOM(containerBusy, "container-busy")
|
||||
ACCESSIBILITY_ATOM(containerChannel, "container-channel")
|
||||
ACCESSIBILITY_ATOM(containerLive, "container-live")
|
||||
ACCESSIBILITY_ATOM(containerRelevant, "container-relevant")
|
||||
ACCESSIBILITY_ATOM(level, "level")
|
||||
ACCESSIBILITY_ATOM(lineNumber, "line-number")
|
||||
ACCESSIBILITY_ATOM(posinset, "posinset")
|
||||
ACCESSIBILITY_ATOM(setsize, "setsize")
|
||||
|
|
|
@ -40,9 +40,10 @@
|
|||
#include "nsAccessibilityAtoms.h"
|
||||
#include "nsAccessibilityService.h"
|
||||
#include "nsAccessibilityUtils.h"
|
||||
#include "nsARIAMap.h"
|
||||
#include "nsIContentViewer.h"
|
||||
#include "nsCURILoader.h"
|
||||
#include "nsDocAccessible.h"
|
||||
#include "nsHTMLAreaAccessible.h"
|
||||
#include "nsHTMLImageAccessibleWrap.h"
|
||||
#include "nsHTMLLinkAccessible.h"
|
||||
#include "nsHTMLSelectAccessible.h"
|
||||
|
@ -88,6 +89,7 @@
|
|||
#include "nsXULFormControlAccessible.h"
|
||||
#include "nsXULMenuAccessibleWrap.h"
|
||||
#include "nsXULSelectAccessible.h"
|
||||
#include "nsXULSliderAccessible.h"
|
||||
#include "nsXULTabAccessible.h"
|
||||
#include "nsXULTextAccessible.h"
|
||||
#include "nsXULTreeAccessibleWrap.h"
|
||||
|
@ -154,10 +156,21 @@ nsAccessibilityService::Observe(nsISupports *aSubject, const char *aTopic,
|
|||
observerService->RemoveObserver(this, NS_XPCOM_SHUTDOWN_OBSERVER_ID);
|
||||
}
|
||||
nsCOMPtr<nsIWebProgress> progress(do_GetService(NS_DOCUMENTLOADER_SERVICE_CONTRACTID));
|
||||
if (progress) {
|
||||
if (progress)
|
||||
progress->RemoveProgressListener(static_cast<nsIWebProgressListener*>(this));
|
||||
}
|
||||
nsAccessNodeWrap::ShutdownAccessibility();
|
||||
// Cancel and release load timers
|
||||
while (mLoadTimers.Count() > 0 ) {
|
||||
nsCOMPtr<nsITimer> timer = mLoadTimers.ObjectAt(0);
|
||||
void *closure = nsnull;
|
||||
timer->GetClosure(&closure);
|
||||
if (closure) {
|
||||
nsIWebProgress *webProgress = static_cast<nsIWebProgress*>(closure);
|
||||
NS_RELEASE(webProgress); // Release nsIWebProgress for timer
|
||||
}
|
||||
timer->Cancel();
|
||||
mLoadTimers.RemoveObjectAt(0);
|
||||
}
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -168,58 +181,94 @@ NS_IMETHODIMP nsAccessibilityService::OnStateChange(nsIWebProgress *aWebProgress
|
|||
{
|
||||
NS_ASSERTION(aStateFlags & STATE_IS_DOCUMENT, "Other notifications excluded");
|
||||
|
||||
if (0 == (aStateFlags & (STATE_START | STATE_STOP))) {
|
||||
if (!aWebProgress || 0 == (aStateFlags & (STATE_START | STATE_STOP))) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsCAutoString name;
|
||||
aRequest->GetName(name);
|
||||
if (name.EqualsLiteral("about:blank"))
|
||||
return NS_OK;
|
||||
|
||||
if (NS_FAILED(aStatus) && (aStateFlags & STATE_START))
|
||||
return NS_OK;
|
||||
|
||||
nsCOMPtr<nsITimer> timer = do_CreateInstance("@mozilla.org/timer;1");
|
||||
if (!timer)
|
||||
return NS_OK;
|
||||
mLoadTimers.AppendObject(timer);
|
||||
NS_ADDREF(aWebProgress);
|
||||
|
||||
if (aStateFlags & STATE_START)
|
||||
timer->InitWithFuncCallback(StartLoadCallback, aWebProgress, 0,
|
||||
nsITimer::TYPE_ONE_SHOT);
|
||||
else if (NS_SUCCEEDED(aStatus))
|
||||
timer->InitWithFuncCallback(EndLoadCallback, aWebProgress, 0,
|
||||
nsITimer::TYPE_ONE_SHOT);
|
||||
else // Failed end load
|
||||
timer->InitWithFuncCallback(FailedLoadCallback, aWebProgress, 0,
|
||||
nsITimer::TYPE_ONE_SHOT);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsAccessibilityService::ProcessDocLoadEvent(nsITimer *aTimer, void *aClosure, PRUint32 aEventType)
|
||||
{
|
||||
nsCOMPtr<nsIDOMWindow> domWindow;
|
||||
aWebProgress->GetDOMWindow(getter_AddRefs(domWindow));
|
||||
NS_ASSERTION(domWindow, "DOM Window for state change is null");
|
||||
NS_ENSURE_TRUE(domWindow, NS_ERROR_FAILURE);
|
||||
nsIWebProgress *webProgress = static_cast<nsIWebProgress*>(aClosure);
|
||||
webProgress->GetDOMWindow(getter_AddRefs(domWindow));
|
||||
NS_RELEASE(webProgress);
|
||||
mLoadTimers.RemoveObject(aTimer);
|
||||
NS_ENSURE_STATE(domWindow);
|
||||
|
||||
nsCOMPtr<nsIDOMDocument> domDoc;
|
||||
domWindow->GetDocument(getter_AddRefs(domDoc));
|
||||
nsCOMPtr<nsIDOMNode> domDocRootNode(do_QueryInterface(domDoc));
|
||||
NS_ENSURE_TRUE(domDocRootNode, NS_ERROR_FAILURE);
|
||||
|
||||
// Get the accessible for the new document.
|
||||
// If it not created yet this will create it & cache it, as well as
|
||||
// set up event listeners so that MSAA/ATK toolkit and internal
|
||||
// accessibility events will get fired.
|
||||
nsCOMPtr<nsIAccessible> accessible;
|
||||
GetAccessibleFor(domDocRootNode, getter_AddRefs(accessible));
|
||||
nsCOMPtr<nsPIAccessibleDocument> docAccessible =
|
||||
do_QueryInterface(accessible);
|
||||
NS_ENSURE_TRUE(docAccessible, NS_ERROR_FAILURE);
|
||||
|
||||
PRUint32 eventType = 0;
|
||||
if ((aStateFlags & STATE_STOP) && NS_SUCCEEDED(aStatus)) {
|
||||
eventType = nsIAccessibleEvent::EVENT_DOCUMENT_LOAD_COMPLETE;
|
||||
} else if ((aStateFlags & STATE_STOP) && (aStatus & NS_BINDING_ABORTED)) {
|
||||
eventType = nsIAccessibleEvent::EVENT_DOCUMENT_LOAD_STOPPED;
|
||||
} else if (aStateFlags & STATE_START) {
|
||||
eventType = nsIAccessibleEvent::EVENT_DOCUMENT_LOAD_START;
|
||||
if (aEventType == nsIAccessibleEvent::EVENT_DOCUMENT_LOAD_START) {
|
||||
nsCOMPtr<nsIWebNavigation> webNav(do_GetInterface(domWindow));
|
||||
nsCOMPtr<nsIDocShell> docShell(do_QueryInterface(webNav));
|
||||
NS_ENSURE_TRUE(docShell, NS_ERROR_FAILURE);
|
||||
NS_ENSURE_STATE(docShell);
|
||||
PRUint32 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) {
|
||||
eventType = nsIAccessibleEvent::EVENT_DOCUMENT_RELOAD;
|
||||
aEventType = nsIAccessibleEvent::EVENT_DOCUMENT_RELOAD;
|
||||
}
|
||||
}
|
||||
|
||||
if (eventType == 0)
|
||||
return NS_OK; //no actural event need to be fired
|
||||
nsCOMPtr<nsIDOMDocument> domDoc;
|
||||
domWindow->GetDocument(getter_AddRefs(domDoc));
|
||||
nsCOMPtr<nsIDOMNode> docNode = do_QueryInterface(domDoc);
|
||||
NS_ENSURE_STATE(docNode);
|
||||
|
||||
docAccessible->FireDocLoadEvents(eventType);
|
||||
nsCOMPtr<nsIAccessible> accessible;
|
||||
GetAccessibleFor(docNode, getter_AddRefs(accessible));
|
||||
nsCOMPtr<nsPIAccessibleDocument> privDocAccessible = do_QueryInterface(accessible);
|
||||
NS_ENSURE_STATE(privDocAccessible);
|
||||
privDocAccessible->FireDocLoadEvents(aEventType);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void nsAccessibilityService::StartLoadCallback(nsITimer *aTimer, void *aClosure)
|
||||
{
|
||||
nsIAccessibilityService *accService = nsAccessNode::GetAccService();
|
||||
if (accService)
|
||||
accService->ProcessDocLoadEvent(aTimer, aClosure, nsIAccessibleEvent::EVENT_DOCUMENT_LOAD_START);
|
||||
}
|
||||
|
||||
void nsAccessibilityService::EndLoadCallback(nsITimer *aTimer, void *aClosure)
|
||||
{
|
||||
nsIAccessibilityService *accService = nsAccessNode::GetAccService();
|
||||
if (accService)
|
||||
accService->ProcessDocLoadEvent(aTimer, aClosure, nsIAccessibleEvent::EVENT_DOCUMENT_LOAD_COMPLETE);
|
||||
}
|
||||
|
||||
void nsAccessibilityService::FailedLoadCallback(nsITimer *aTimer, void *aClosure)
|
||||
{
|
||||
nsIAccessibilityService *accService = nsAccessNode::GetAccService();
|
||||
if (accService)
|
||||
accService->ProcessDocLoadEvent(aTimer, aClosure, nsIAccessibleEvent::EVENT_DOCUMENT_LOAD_STOPPED);
|
||||
}
|
||||
|
||||
/* void onProgressChange (in nsIWebProgress aWebProgress, in nsIRequest aRequest, in long aCurSelfProgress, in long aMaxSelfProgress, in long aCurTotalProgress, in long aMaxTotalProgress); */
|
||||
NS_IMETHODIMP nsAccessibilityService::OnProgressChange(nsIWebProgress *aWebProgress,
|
||||
nsIRequest *aRequest, PRInt32 aCurSelfProgress, PRInt32 aMaxSelfProgress,
|
||||
|
@ -365,6 +414,25 @@ nsAccessibilityService::CreateRootAccessible(nsIPresShell *aShell,
|
|||
nsCOMPtr<nsIWeakReference> weakShell(do_GetWeakReference(presShell));
|
||||
|
||||
nsCOMPtr<nsISupports> container = aDocument->GetContainer();
|
||||
nsCOMPtr<nsIDocShell> docShell = do_QueryInterface(container);
|
||||
NS_ENSURE_TRUE(docShell, NS_ERROR_FAILURE);
|
||||
nsCOMPtr<nsIContentViewer> contentViewer;
|
||||
docShell->GetContentViewer(getter_AddRefs(contentViewer));
|
||||
NS_ENSURE_TRUE(contentViewer, NS_ERROR_FAILURE); // Doc was already shut down
|
||||
PRUint32 busyFlags;
|
||||
docShell->GetBusyFlags(&busyFlags);
|
||||
if (busyFlags != nsIDocShell::BUSY_FLAGS_NONE) {
|
||||
nsCOMPtr<nsIWebNavigation> webNav(do_GetInterface(docShell));
|
||||
nsCOMPtr<nsIURI> uri;
|
||||
webNav->GetCurrentURI(getter_AddRefs(uri));
|
||||
NS_ENSURE_STATE(uri);
|
||||
nsCAutoString url;
|
||||
uri->GetSpec(url);
|
||||
if (url.EqualsLiteral("about:blank")) {
|
||||
return NS_OK; // No load events for a busy about:blank -- they are often temporary
|
||||
}
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIDocShellTreeItem> docShellTreeItem =
|
||||
do_QueryInterface(container);
|
||||
NS_ENSURE_TRUE(docShellTreeItem, NS_ERROR_FAILURE);
|
||||
|
@ -385,6 +453,10 @@ nsAccessibilityService::CreateRootAccessible(nsIPresShell *aShell,
|
|||
|
||||
nsCOMPtr<nsPIAccessNode> privateAccessNode(do_QueryInterface(*aRootAcc));
|
||||
privateAccessNode->Init();
|
||||
nsRoleMapEntry *roleMapEntry = nsAccUtils::GetRoleMapEntry(rootNode);
|
||||
nsCOMPtr<nsPIAccessible> privateAccessible =
|
||||
do_QueryInterface(privateAccessNode);
|
||||
privateAccessible->SetRoleMapEntry(roleMapEntry);
|
||||
|
||||
NS_ADDREF(*aRootAcc);
|
||||
|
||||
|
@ -412,19 +484,6 @@ nsAccessibilityService::CreateHTML4ButtonAccessible(nsISupports *aFrame, nsIAcce
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsAccessibilityService::CreateHTMLAreaAccessible(nsIWeakReference *aShell, nsIDOMNode *aDOMNode, nsIAccessible *aParent,
|
||||
nsIAccessible **_retval)
|
||||
{
|
||||
*_retval = new nsHTMLAreaAccessible(aDOMNode, aParent, aShell);
|
||||
|
||||
if (! *_retval)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
NS_ADDREF(*_retval);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsAccessibilityService::CreateHTMLButtonAccessible(nsISupports *aFrame, nsIAccessible **_retval)
|
||||
{
|
||||
|
@ -447,7 +506,6 @@ nsresult
|
|||
nsAccessibilityService::CreateHTMLAccessibleByMarkup(nsIFrame *aFrame,
|
||||
nsIWeakReference *aWeakShell,
|
||||
nsIDOMNode *aNode,
|
||||
const nsAString& aRole,
|
||||
nsIAccessible **aAccessible)
|
||||
{
|
||||
// This method assumes we're in an HTML namespace.
|
||||
|
@ -1009,26 +1067,38 @@ nsAccessibilityService::GetStringStates(PRUint32 aStates, PRUint32 aExtraStates,
|
|||
stringStates->Add(NS_LITERAL_STRING("checkable"));
|
||||
|
||||
//extraStates
|
||||
if (aExtraStates & nsIAccessibleStates::EXT_STATE_SUPPORTS_AUTOCOMPLETION)
|
||||
stringStates->Add(NS_LITERAL_STRING("autocompletion"));
|
||||
if (aExtraStates & nsIAccessibleStates::EXT_STATE_DEFUNCT)
|
||||
stringStates->Add(NS_LITERAL_STRING("defunct"));
|
||||
if (aExtraStates & nsIAccessibleStates::EXT_STATE_SELECTABLE_TEXT)
|
||||
stringStates->Add(NS_LITERAL_STRING("selectable text"));
|
||||
if (aExtraStates & nsIAccessibleStates::EXT_STATE_EDITABLE)
|
||||
stringStates->Add(NS_LITERAL_STRING("editable"));
|
||||
if (aExtraStates & nsIAccessibleStates::EXT_STATE_ACTIVE)
|
||||
stringStates->Add(NS_LITERAL_STRING("active"));
|
||||
if (aExtraStates & nsIAccessibleStates::EXT_STATE_EXPANDABLE)
|
||||
stringStates->Add(NS_LITERAL_STRING("expandable"));
|
||||
if (aExtraStates & nsIAccessibleStates::EXT_STATE_MODAL)
|
||||
stringStates->Add(NS_LITERAL_STRING("modal"));
|
||||
if (aExtraStates & nsIAccessibleStates::EXT_STATE_MULTI_LINE)
|
||||
stringStates->Add(NS_LITERAL_STRING("multi line"));
|
||||
if (aExtraStates & nsIAccessibleStates::EXT_STATE_SENSITIVE)
|
||||
stringStates->Add(NS_LITERAL_STRING("sensitive"));
|
||||
if (aExtraStates & nsIAccessibleStates::EXT_STATE_HORIZONTAL)
|
||||
stringStates->Add(NS_LITERAL_STRING("horizontal"));
|
||||
if (aExtraStates & nsIAccessibleStates::EXT_STATE_OPAQUE)
|
||||
stringStates->Add(NS_LITERAL_STRING("opaque"));
|
||||
if (aExtraStates & nsIAccessibleStates::EXT_STATE_SINGLE_LINE)
|
||||
stringStates->Add(NS_LITERAL_STRING("single line"));
|
||||
if (aExtraStates & nsIAccessibleStates::EXT_STATE_TRANSIENT)
|
||||
stringStates->Add(NS_LITERAL_STRING("transient"));
|
||||
if (aExtraStates & nsIAccessibleStates::EXT_STATE_VERTICAL)
|
||||
stringStates->Add(NS_LITERAL_STRING("vertical"));
|
||||
if (aExtraStates & nsIAccessibleStates::EXT_STATE_STALE)
|
||||
stringStates->Add(NS_LITERAL_STRING("stale"));
|
||||
if (aExtraStates & nsIAccessibleStates::EXT_STATE_ENABLED)
|
||||
stringStates->Add(NS_LITERAL_STRING("enabled"));
|
||||
if (aExtraStates & nsIAccessibleStates::EXT_STATE_SENSITIVE)
|
||||
stringStates->Add(NS_LITERAL_STRING("sensitive"));
|
||||
if (aExtraStates & nsIAccessibleStates::EXT_STATE_EXPANDABLE)
|
||||
stringStates->Add(NS_LITERAL_STRING("expandable"));
|
||||
|
||||
//unknown states
|
||||
PRUint32 stringStatesLength = 0;
|
||||
|
@ -1041,6 +1111,38 @@ nsAccessibilityService::GetStringStates(PRUint32 aStates, PRUint32 aExtraStates,
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
// nsIAccessibleRetrieval::getStringEventType()
|
||||
NS_IMETHODIMP
|
||||
nsAccessibilityService::GetStringEventType(PRUint32 aEventType,
|
||||
nsAString& aString)
|
||||
{
|
||||
NS_ASSERTION(nsIAccessibleEvent::EVENT_LAST_ENTRY == NS_ARRAY_LENGTH(kEventTypeNames),
|
||||
"nsIAccessibleEvent constants are out of sync to kEventTypeNames");
|
||||
|
||||
if (aEventType >= NS_ARRAY_LENGTH(kEventTypeNames)) {
|
||||
aString.AssignLiteral("unknown");
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
CopyUTF8toUTF16(kEventTypeNames[aEventType], aString);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// nsIAccessibleRetrieval::getStringRelationType()
|
||||
NS_IMETHODIMP
|
||||
nsAccessibilityService::GetStringRelationType(PRUint32 aRelationType,
|
||||
nsAString& aString)
|
||||
{
|
||||
if (aRelationType >= NS_ARRAY_LENGTH(kRelationTypeNames)) {
|
||||
aString.AssignLiteral("unknown");
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
CopyUTF8toUTF16(kRelationTypeNames[aRelationType], aString);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* GetAccessibleFor - get an nsIAccessible from a DOM node
|
||||
*/
|
||||
|
@ -1145,7 +1247,8 @@ NS_IMETHODIMP nsAccessibilityService::GetAccessibleInWeakShell(nsIDOMNode *aNode
|
|||
}
|
||||
|
||||
nsresult nsAccessibilityService::InitAccessible(nsIAccessible *aAccessibleIn,
|
||||
nsIAccessible **aAccessibleOut)
|
||||
nsIAccessible **aAccessibleOut,
|
||||
nsRoleMapEntry *aRoleMapEntry)
|
||||
{
|
||||
if (!aAccessibleIn) {
|
||||
return NS_ERROR_FAILURE; // No accessible to init
|
||||
|
@ -1156,11 +1259,41 @@ nsresult nsAccessibilityService::InitAccessible(nsIAccessible *aAccessibleIn,
|
|||
NS_ASSERTION(privateAccessNode, "All accessibles must support nsPIAccessNode");
|
||||
nsresult rv = privateAccessNode->Init(); // Add to cache, etc.
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
nsCOMPtr<nsPIAccessible> privateAccessible =
|
||||
do_QueryInterface(privateAccessNode);
|
||||
privateAccessible->SetRoleMapEntry(aRoleMapEntry);
|
||||
NS_ADDREF(*aAccessibleOut = aAccessibleIn);
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
static PRBool HasRelatedContent(nsIContent *aContent)
|
||||
{
|
||||
nsAutoString id;
|
||||
if (!aContent || !nsAccUtils::GetID(aContent, id) || id.IsEmpty()) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
nsIAtom *relationAttrs[] = {nsAccessibilityAtoms::aria_labelledby,
|
||||
nsAccessibilityAtoms::aria_describedby,
|
||||
nsAccessibilityAtoms::aria_owns,
|
||||
nsAccessibilityAtoms::aria_controls,
|
||||
nsAccessibilityAtoms::aria_flowto};
|
||||
if (nsAccUtils::FindNeighbourPointingToNode(aContent, relationAttrs, NS_ARRAY_LENGTH(relationAttrs))) {
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
nsIContent *ancestorContent = aContent;
|
||||
while ((ancestorContent = ancestorContent->GetParent()) != nsnull) {
|
||||
if (ancestorContent->HasAttr(kNameSpaceID_None, nsAccessibilityAtoms::aria_activedescendant)) {
|
||||
// ancestor has activedescendant property, this content could be active
|
||||
return PR_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsAccessibilityService::GetAccessible(nsIDOMNode *aNode,
|
||||
nsIPresShell *aPresShell,
|
||||
nsIWeakReference *aWeakShell,
|
||||
|
@ -1260,7 +1393,7 @@ NS_IMETHODIMP nsAccessibilityService::GetAccessible(nsIDOMNode *aNode,
|
|||
#endif
|
||||
if (!frame || content != frame->GetContent()) {
|
||||
// Frame hint not correct, get true frame, we try to optimize away from this
|
||||
frame = aPresShell->GetPrimaryFrameFor(content);
|
||||
frame = aPresShell->GetRealPrimaryFrameFor(content);
|
||||
if (frame) {
|
||||
#ifdef DEBUG_A11Y_FRAME_OPTIMIZATION
|
||||
// Frame hint debugging
|
||||
|
@ -1316,18 +1449,22 @@ NS_IMETHODIMP nsAccessibilityService::GetAccessible(nsIDOMNode *aNode,
|
|||
if (content->IsNodeOfType(nsINode::eTEXT)) {
|
||||
// --- Create HTML for visible text frames ---
|
||||
if (frame->IsEmpty()) {
|
||||
nsAutoString renderedWhitespace;
|
||||
frame->GetRenderedText(&renderedWhitespace, nsnull, nsnull, 0, 1);
|
||||
if (renderedWhitespace.IsEmpty()) {
|
||||
// Really empty -- nothing is rendered
|
||||
*aIsHidden = PR_TRUE;
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
frame->GetAccessible(getter_AddRefs(newAcc));
|
||||
return InitAccessible(newAcc, aAccessible);
|
||||
return InitAccessible(newAcc, aAccessible, nsnull);
|
||||
}
|
||||
|
||||
nsAutoString role;
|
||||
if (nsAccessNode::GetRoleAttribute(content, role) &&
|
||||
StringEndsWith(role, NS_LITERAL_STRING(":presentation")) &&
|
||||
!content->IsFocusable()) {
|
||||
// Only create accessible for role=":presentation" if it is focusable --
|
||||
nsRoleMapEntry *roleMapEntry = nsAccUtils::GetRoleMapEntry(aNode);
|
||||
if (roleMapEntry && !nsCRT::strcmp(roleMapEntry->roleString, "presentation") &&
|
||||
!content->IsFocusable()) { // For presentation only
|
||||
// Only create accessible for role of "presentation" if it is focusable --
|
||||
// in that case we need an accessible in case it gets focused, we
|
||||
// don't want focus ever to be 'lost'
|
||||
return NS_OK;
|
||||
|
@ -1351,48 +1488,84 @@ NS_IMETHODIMP nsAccessibilityService::GetAccessible(nsIDOMNode *aNode,
|
|||
nsIAccessibleRole::ROLE_EQUATION);
|
||||
}
|
||||
} else if (!newAcc) { // HTML accessibles
|
||||
// Prefer to use markup (mostly tag name, perhaps attributes) to
|
||||
// decide if and what kind of accessible to create.
|
||||
CreateHTMLAccessibleByMarkup(frame, aWeakShell, aNode, role, getter_AddRefs(newAcc));
|
||||
PRBool tryTagNameOrFrame = PR_TRUE;
|
||||
|
||||
PRBool tryFrame = (newAcc == nsnull);
|
||||
if (!content->IsFocusable()) {
|
||||
// If we're in unfocusable table-related subcontent, check for the
|
||||
// Presentation role on the containing table
|
||||
nsIAtom *tag = content->Tag();
|
||||
if (tag == nsAccessibilityAtoms::td ||
|
||||
tag == nsAccessibilityAtoms::th ||
|
||||
tag == nsAccessibilityAtoms::tr ||
|
||||
tag == nsAccessibilityAtoms::tbody ||
|
||||
tag == nsAccessibilityAtoms::tfoot ||
|
||||
tag == nsAccessibilityAtoms::thead) {
|
||||
nsIAtom *frameType = frame->GetType();
|
||||
if (!roleMapEntry &&
|
||||
(frameType == nsAccessibilityAtoms::tableCaptionFrame ||
|
||||
frameType == nsAccessibilityAtoms::tableCellFrame ||
|
||||
frameType == nsAccessibilityAtoms::tableRowGroupFrame ||
|
||||
frameType == nsAccessibilityAtoms::tableRowFrame)) {
|
||||
// Table-related frames don't get table-related roles
|
||||
// unless they are inside a table, but they may still get generic
|
||||
// accessibles
|
||||
nsIContent *tableContent = content;
|
||||
nsAutoString tableRole;
|
||||
while ((tableContent = tableContent->GetParent()) != nsnull) {
|
||||
if (tableContent->Tag() == nsAccessibilityAtoms::table) {
|
||||
nsIFrame *tableFrame = aPresShell->GetPrimaryFrameFor(tableContent);
|
||||
if (!tableFrame || tableFrame->GetType() != nsAccessibilityAtoms::tableOuterFrame ||
|
||||
nsAccessNode::HasRoleAttribute(tableContent)) {
|
||||
// Table that we're a descendant of is not styled as a table,
|
||||
// and has no table accessible for an ancestor, or
|
||||
// table that we're a descendant of is presentational
|
||||
tryFrame = PR_FALSE;
|
||||
if (!tableFrame)
|
||||
continue;
|
||||
if (tableFrame->GetType() == nsAccessibilityAtoms::tableOuterFrame) {
|
||||
nsCOMPtr<nsIDOMNode> tableNode(do_QueryInterface(tableContent));
|
||||
nsCOMPtr<nsIAccessible> tableAccessible;
|
||||
GetAccessibleInShell(tableNode, aPresShell, getter_AddRefs(tableAccessible));
|
||||
if (!tableAccessible && !content->IsFocusable()) {
|
||||
#ifdef DEBUG
|
||||
nsRoleMapEntry *tableRoleMapEntry = nsAccUtils::GetRoleMapEntry(tableNode);
|
||||
NS_ASSERTION(tableRoleMapEntry &&
|
||||
!nsCRT::strcmp(tableRoleMapEntry->roleString, "presentation"),
|
||||
"No accessible for parent table and it didn't have role of presentation");
|
||||
#endif
|
||||
// Table-related descendants of presentation table are also presentation
|
||||
// Don't create accessibles for them unless they need to fire focus events
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
if (tableAccessible && nsAccessible::Role(tableAccessible) != nsIAccessibleRole::ROLE_TABLE) {
|
||||
NS_ASSERTION(!roleMapEntry, "Should not be changing ARIA role, just overriding impl class role");
|
||||
// Not in table: override role (roleMap entry was null).
|
||||
roleMapEntry = &nsARIAMap::gEmptyRoleMap;
|
||||
}
|
||||
break;
|
||||
}
|
||||
else if (tableContent->Tag() == nsAccessibilityAtoms::table) {
|
||||
// Stop before we are fooled by any additional table ancestors
|
||||
// This table cell frameis part of a separate ancestor table.
|
||||
tryTagNameOrFrame = PR_FALSE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!tableContent)
|
||||
tryTagNameOrFrame = PR_FALSE;
|
||||
}
|
||||
|
||||
if (tryFrame) {
|
||||
if (frame->GetRect().IsEmpty()) {
|
||||
if (tryTagNameOrFrame) {
|
||||
// Prefer to use markup (mostly tag name, perhaps attributes) to
|
||||
// decide if and what kind of accessible to create.
|
||||
// The method creates accessibles for table related content too therefore
|
||||
// we do not call it if accessibles for table related content are
|
||||
// prevented above.
|
||||
rv = CreateHTMLAccessibleByMarkup(frame, aWeakShell, aNode,
|
||||
getter_AddRefs(newAcc));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
if (!newAcc) {
|
||||
// Do not create accessible object subtrees for non-rendered table
|
||||
// captions. This could not be done in
|
||||
// nsTableCaptionFrame::GetAccessible() because the descendants of
|
||||
// the table caption would still be created. By setting
|
||||
// *aIsHidden = PR_TRUE we ensure that no descendant accessibles are
|
||||
// created.
|
||||
if (frame->GetType() == nsAccessibilityAtoms::tableCaptionFrame &&
|
||||
frame->GetRect().IsEmpty()) {
|
||||
// XXX This is not the ideal place for this code, but right now there
|
||||
// is no better place:
|
||||
*aIsHidden = PR_TRUE;
|
||||
return NS_OK;
|
||||
}
|
||||
frame->GetAccessible(getter_AddRefs(newAcc)); // Try using frame to do it
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!newAcc) {
|
||||
GetAccessibleForDeckChildren(aNode, getter_AddRefs(newAcc));
|
||||
|
@ -1403,13 +1576,10 @@ NS_IMETHODIMP nsAccessibilityService::GetAccessible(nsIDOMNode *aNode,
|
|||
// We don't do this for <body>, <html>, <window>, <dialog> etc. which
|
||||
// correspond to the doc accessible and will be created in any case
|
||||
if (!newAcc && content->Tag() != nsAccessibilityAtoms::body && content->GetParent() &&
|
||||
(content->IsFocusable() ||
|
||||
(frame->IsFocusable() ||
|
||||
(isHTML && nsAccUtils::HasListener(content, NS_LITERAL_STRING("click"))) ||
|
||||
content->HasAttr(kNameSpaceID_WAIProperties, nsAccessibilityAtoms::describedby) ||
|
||||
content->HasAttr(kNameSpaceID_WAIProperties, nsAccessibilityAtoms::labelledby) ||
|
||||
content->HasAttr(kNameSpaceID_WAIProperties, nsAccessibilityAtoms::required) ||
|
||||
content->HasAttr(kNameSpaceID_WAIProperties, nsAccessibilityAtoms::invalid) ||
|
||||
!role.IsEmpty())) {
|
||||
HasUniversalAriaProperty(content, aWeakShell) || roleMapEntry ||
|
||||
HasRelatedContent(content) || nsAccUtils::IsXLink(content))) {
|
||||
// This content is focusable or has an interesting dynamic content accessibility property.
|
||||
// If it's interesting we need it in the accessibility hierarchy so that events or
|
||||
// other accessibles can point to it, or so that it can hold a state, etc.
|
||||
|
@ -1423,7 +1593,30 @@ NS_IMETHODIMP nsAccessibilityService::GetAccessible(nsIDOMNode *aNode,
|
|||
}
|
||||
}
|
||||
|
||||
return InitAccessible(newAcc, aAccessible);
|
||||
return InitAccessible(newAcc, aAccessible, roleMapEntry);
|
||||
}
|
||||
|
||||
PRBool
|
||||
nsAccessibilityService::HasUniversalAriaProperty(nsIContent *aContent,
|
||||
nsIWeakReference *aWeakShell)
|
||||
{
|
||||
return aContent->HasAttr(kNameSpaceID_None, nsAccessibilityAtoms::aria_atomic) ||
|
||||
aContent->HasAttr(kNameSpaceID_None, nsAccessibilityAtoms::aria_busy) ||
|
||||
aContent->HasAttr(kNameSpaceID_None, nsAccessibilityAtoms::aria_channel) ||
|
||||
aContent->HasAttr(kNameSpaceID_None, nsAccessibilityAtoms::aria_controls) ||
|
||||
aContent->HasAttr(kNameSpaceID_None, nsAccessibilityAtoms::aria_datatype) ||
|
||||
aContent->HasAttr(kNameSpaceID_None, nsAccessibilityAtoms::aria_describedby) ||
|
||||
aContent->HasAttr(kNameSpaceID_None, nsAccessibilityAtoms::aria_dropeffect) ||
|
||||
aContent->HasAttr(kNameSpaceID_None, nsAccessibilityAtoms::aria_flowto) ||
|
||||
aContent->HasAttr(kNameSpaceID_None, nsAccessibilityAtoms::aria_grab) ||
|
||||
aContent->HasAttr(kNameSpaceID_None, nsAccessibilityAtoms::aria_haspopup) ||
|
||||
aContent->HasAttr(kNameSpaceID_None, nsAccessibilityAtoms::aria_invalid) ||
|
||||
aContent->HasAttr(kNameSpaceID_None, nsAccessibilityAtoms::aria_labelledby) ||
|
||||
aContent->HasAttr(kNameSpaceID_None, nsAccessibilityAtoms::aria_live) ||
|
||||
aContent->HasAttr(kNameSpaceID_None, nsAccessibilityAtoms::aria_owns) ||
|
||||
aContent->HasAttr(kNameSpaceID_None, nsAccessibilityAtoms::aria_relevant) ||
|
||||
aContent->HasAttr(kNameSpaceID_None, nsAccessibilityAtoms::aria_required) ||
|
||||
aContent->HasAttr(kNameSpaceID_None, nsAccessibilityAtoms::aria_sort);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
|
@ -1519,6 +1712,8 @@ nsresult nsAccessibilityService::GetAccessibleByType(nsIDOMNode *aNode,
|
|||
switch (type)
|
||||
{
|
||||
#ifdef MOZ_XUL
|
||||
case nsIAccessibleProvider::NoAccessible:
|
||||
return NS_OK;
|
||||
// XUL controls
|
||||
case nsIAccessibleProvider::XULAlert:
|
||||
*aAccessible = new nsXULAlertAccessible(aNode, weakShell);
|
||||
|
@ -1566,6 +1761,15 @@ nsresult nsAccessibilityService::GetAccessibleByType(nsIDOMNode *aNode,
|
|||
case nsIAccessibleProvider::XULListbox:
|
||||
*aAccessible = new nsXULListboxAccessible(aNode, weakShell);
|
||||
break;
|
||||
case nsIAccessibleProvider::XULListCell:
|
||||
*aAccessible = new nsXULListCellAccessible(aNode, weakShell);
|
||||
break;
|
||||
case nsIAccessibleProvider::XULListHead:
|
||||
*aAccessible = new nsXULColumnsAccessible(aNode, weakShell);
|
||||
break;
|
||||
case nsIAccessibleProvider::XULListHeader:
|
||||
*aAccessible = new nsXULColumnItemAccessible(aNode, weakShell);
|
||||
break;
|
||||
case nsIAccessibleProvider::XULListitem:
|
||||
*aAccessible = new nsXULListitemAccessible(aNode, weakShell);
|
||||
break;
|
||||
|
@ -1597,12 +1801,18 @@ nsresult nsAccessibilityService::GetAccessibleByType(nsIDOMNode *aNode,
|
|||
case nsIAccessibleProvider::XULMenuSeparator:
|
||||
*aAccessible = new nsXULMenuSeparatorAccessible(aNode, weakShell);
|
||||
break;
|
||||
case nsIAccessibleProvider::XULPane:
|
||||
*aAccessible = new nsEnumRoleAccessible(aNode, weakShell, nsIAccessibleRole::ROLE_PANE);
|
||||
break;
|
||||
case nsIAccessibleProvider::XULProgressMeter:
|
||||
*aAccessible = new nsXULProgressMeterAccessible(aNode, weakShell);
|
||||
break;
|
||||
case nsIAccessibleProvider::XULStatusBar:
|
||||
*aAccessible = new nsXULStatusBarAccessible(aNode, weakShell);
|
||||
break;
|
||||
case nsIAccessibleProvider::XULScale:
|
||||
*aAccessible = new nsXULSliderAccessible(aNode, weakShell);
|
||||
break;
|
||||
case nsIAccessibleProvider::XULRadioButton:
|
||||
*aAccessible = new nsXULRadioButtonAccessible(aNode, weakShell);
|
||||
break;
|
||||
|
@ -1624,14 +1834,17 @@ nsresult nsAccessibilityService::GetAccessibleByType(nsIDOMNode *aNode,
|
|||
case nsIAccessibleProvider::XULTextBox:
|
||||
*aAccessible = new nsXULTextFieldAccessible(aNode, weakShell);
|
||||
break;
|
||||
case nsIAccessibleProvider::XULThumb:
|
||||
*aAccessible = new nsXULThumbAccessible(aNode, weakShell);
|
||||
break;
|
||||
case nsIAccessibleProvider::XULTree:
|
||||
*aAccessible = new nsXULTreeAccessibleWrap(aNode, weakShell);
|
||||
break;
|
||||
case nsIAccessibleProvider::XULTreeColumns:
|
||||
*aAccessible = new nsXULTreeColumnsAccessibleWrap(aNode, weakShell);
|
||||
break;
|
||||
case nsIAccessibleProvider::XULTreeColumnitem:
|
||||
*aAccessible = new nsXULTreeColumnitemAccessible(aNode, weakShell);
|
||||
case nsIAccessibleProvider::XULTreeColumnItem:
|
||||
*aAccessible = new nsXULColumnItemAccessible(aNode, weakShell);
|
||||
break;
|
||||
case nsIAccessibleProvider::XULToolbar:
|
||||
*aAccessible = new nsXULToolbarAccessible(aNode, weakShell);
|
||||
|
@ -1765,15 +1978,17 @@ NS_IMETHODIMP nsAccessibilityService::InvalidateSubtreeFor(nsIPresShell *aShell,
|
|||
nsIContent *aChangeContent,
|
||||
PRUint32 aEvent)
|
||||
{
|
||||
NS_ASSERTION(aEvent == nsIAccessibleEvent::EVENT_REORDER ||
|
||||
aEvent == nsIAccessibleEvent::EVENT_SHOW ||
|
||||
aEvent == nsIAccessibleEvent::EVENT_HIDE,
|
||||
NS_ASSERTION(aEvent == nsIAccessibleEvent::EVENT_ASYNCH_SIGNIFICANT_CHANGE ||
|
||||
aEvent == nsIAccessibleEvent::EVENT_ASYNCH_SHOW ||
|
||||
aEvent == nsIAccessibleEvent::EVENT_ASYNCH_HIDE ||
|
||||
aEvent == nsIAccessibleEvent::EVENT_DOM_SIGNIFICANT_CHANGE ||
|
||||
aEvent == nsIAccessibleEvent::EVENT_DOM_CREATE ||
|
||||
aEvent == nsIAccessibleEvent::EVENT_DOM_DESTROY,
|
||||
"Incorrect aEvent passed in");
|
||||
|
||||
nsCOMPtr<nsIWeakReference> weakShell(do_GetWeakReference(aShell));
|
||||
NS_ASSERTION(aShell, "No pres shell in call to InvalidateSubtreeFor");
|
||||
NS_ENSURE_ARG_POINTER(aShell);
|
||||
nsCOMPtr<nsIAccessibleDocument> accessibleDoc =
|
||||
nsAccessNode::GetDocAccessibleFor(weakShell);
|
||||
nsAccessNode::GetDocAccessibleFor(aShell->GetDocument());
|
||||
nsCOMPtr<nsPIAccessibleDocument> privateAccessibleDoc =
|
||||
do_QueryInterface(accessibleDoc);
|
||||
if (!privateAccessibleDoc) {
|
||||
|
@ -1831,7 +2046,20 @@ nsAccessibilityService::GetAccessibleForDeckChildren(nsIDOMNode *aNode, nsIAcces
|
|||
frame->GetType() == nsAccessibilityAtoms::scrollFrame)) {
|
||||
parentFrame = frame->GetParent();
|
||||
if (parentFrame && parentFrame->GetType() == nsAccessibilityAtoms::deckFrame) {
|
||||
*aAccessible = new nsEnumRoleAccessible(aNode, weakShell, nsIAccessibleRole::ROLE_PROPERTYPAGE);
|
||||
// If deck frame is for xul:tabpanels element then the given node has
|
||||
// tabpanel accessible.
|
||||
nsCOMPtr<nsIContent> parentContent = parentFrame->GetContent();
|
||||
if (parentContent->NodeInfo()->Equals(nsAccessibilityAtoms::tabpanels,
|
||||
kNameSpaceID_XUL)) {
|
||||
*aAccessible = new nsXULTabpanelAccessible(aNode, weakShell);
|
||||
} else {
|
||||
*aAccessible =
|
||||
new nsEnumRoleAccessible(aNode, weakShell,
|
||||
nsIAccessibleRole::ROLE_PROPERTYPAGE);
|
||||
}
|
||||
|
||||
NS_ENSURE_TRUE(*aAccessible, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
NS_ADDREF(*aAccessible);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -40,7 +40,10 @@
|
|||
#define __nsAccessibilityService_h__
|
||||
|
||||
#include "nsIAccessibilityService.h"
|
||||
#include "nsCOMArray.h"
|
||||
#include "nsIObserver.h"
|
||||
#include "nsITimer.h"
|
||||
#include "nsIWebProgress.h"
|
||||
#include "nsIWebProgressListener.h"
|
||||
#include "nsWeakReference.h"
|
||||
|
||||
|
@ -51,7 +54,101 @@ class nsObjectFrame;
|
|||
class nsIDocShell;
|
||||
class nsIPresShell;
|
||||
class nsIContent;
|
||||
struct nsRoleMapEntry;
|
||||
|
||||
class nsAccessibilityService : public nsIAccessibilityService,
|
||||
public nsIObserver,
|
||||
public nsIWebProgressListener,
|
||||
public nsSupportsWeakReference
|
||||
{
|
||||
public:
|
||||
nsAccessibilityService();
|
||||
virtual ~nsAccessibilityService();
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSIACCESSIBLERETRIEVAL
|
||||
NS_DECL_NSIACCESSIBILITYSERVICE
|
||||
NS_DECL_NSIOBSERVER
|
||||
NS_DECL_NSIWEBPROGRESSLISTENER
|
||||
|
||||
/**
|
||||
* Return presentation shell for the given node.
|
||||
*
|
||||
* @param aNode - the given DOM node.
|
||||
*/
|
||||
static nsresult GetShellFromNode(nsIDOMNode *aNode,
|
||||
nsIWeakReference **weakShell);
|
||||
|
||||
/**
|
||||
* Return accessibility service (static instance of this class).
|
||||
*/
|
||||
static nsresult GetAccessibilityService(nsIAccessibilityService** aResult);
|
||||
|
||||
private:
|
||||
/**
|
||||
* Return presentation shell, DOM node for the given frame.
|
||||
*
|
||||
* @param aFrame - the given frame
|
||||
* @param aRealFrame [out] - the given frame casted to nsIFrame
|
||||
* @param aShell [out] - presentation shell for DOM node associated with the
|
||||
* given frame
|
||||
* @param aContent [out] - DOM node associated with the given frame
|
||||
*/
|
||||
nsresult GetInfo(nsISupports *aFrame, nsIFrame **aRealFrame,
|
||||
nsIWeakReference **aShell,
|
||||
nsIDOMNode **aContent);
|
||||
|
||||
/**
|
||||
* Initialize an accessible and cache it. The method should be called for
|
||||
* every created accessible.
|
||||
*
|
||||
* @param aAccessibleIn - accessible to initialize.
|
||||
* @param aAcccessibleOut - set to the same thing as aAccessibleIn, unless there was
|
||||
* an error initializing the accessible, in which case
|
||||
* it is set to nsnull
|
||||
* @param aRoleMapEntry - The role map entry role the ARIA role or nsnull if none
|
||||
*/
|
||||
nsresult InitAccessible(nsIAccessible *aAccessibleIn, nsIAccessible **aAccessibleOut,
|
||||
nsRoleMapEntry *aRoleMapEntry = nsnull);
|
||||
|
||||
/**
|
||||
* Return accessible object for elements implementing nsIAccessibleProvider
|
||||
* interface.
|
||||
*
|
||||
* @param aNode - DOM node that accessible is returned for.
|
||||
*/
|
||||
nsresult GetAccessibleByType(nsIDOMNode *aNode, nsIAccessible **aAccessible);
|
||||
|
||||
/**
|
||||
* Return accessible object if parent is a deck frame.
|
||||
*
|
||||
* @param aNode - DOMNode that accessible is returned for.
|
||||
*/
|
||||
nsresult GetAccessibleForDeckChildren(nsIDOMNode *aNode,
|
||||
nsIAccessible **aAccessible);
|
||||
|
||||
static nsAccessibilityService *gAccessibilityService;
|
||||
|
||||
/**
|
||||
* Does this content node have a universal ARIA property set on it?
|
||||
* A universal ARIA property is one that can be defined on any element even if there is no role.
|
||||
*
|
||||
* @param aContent The content node to test
|
||||
* @param aWeakShell A weak reference to the pres shell
|
||||
* @return PR_TRUE if there is a universal ARIA property set on the node
|
||||
*/
|
||||
PRBool HasUniversalAriaProperty(nsIContent *aContent, nsIWeakReference *aWeakShell);
|
||||
|
||||
static void StartLoadCallback(nsITimer *aTimer, void *aClosure);
|
||||
static void EndLoadCallback(nsITimer *aTimer, void *aClosure);
|
||||
static void FailedLoadCallback(nsITimer *aTimer, void *aClosure);
|
||||
nsCOMArray<nsITimer> mLoadTimers;
|
||||
};
|
||||
|
||||
/**
|
||||
* Map nsIAccessibleRole constants to strings. Used by
|
||||
* nsIAccessibleRetrieval::getStringRole() method.
|
||||
*/
|
||||
static const char kRoleNames[][20] = {
|
||||
"nothing", //ROLE_NOTHING
|
||||
"titlebar", //ROLE_TITLEBAR
|
||||
|
@ -63,7 +160,7 @@ static const char kRoleNames[][20] = {
|
|||
"caret", //ROLE_CARET
|
||||
"alert", //ROLE_ALERT
|
||||
"window", //ROLE_WINDOW
|
||||
"client", //ROLE_CLIENT
|
||||
"internal frame", //ROLE_INTERNAL_FRAME
|
||||
"menupopup", //ROLE_MENUPOPUP
|
||||
"menuitem", //ROLE_MENUITEM
|
||||
"tooltip", //ROLE_TOOLTIP
|
||||
|
@ -168,45 +265,137 @@ static const char kRoleNames[][20] = {
|
|||
"parent menuitem", //ROLE_PARENT_MENUITEM
|
||||
"calendar", //ROLE_CALENDAR
|
||||
"combobox list", //ROLE_COMBOBOX_LIST
|
||||
"combobox listitem" //ROLE_COMBOBOX_LISTITEM
|
||||
"combobox option", //ROLE_COMBOBOX_OPTION
|
||||
"image map", //ROLE_IMAGE_MAP
|
||||
"listbox option", //ROLE_OPTION
|
||||
"listbox rich option", //ROLE_RICH_OPTION
|
||||
"listbox", //ROLE_LISTBOX
|
||||
"flat equation" //ROLE_FLAT_EQUATION
|
||||
};
|
||||
|
||||
class nsAccessibilityService : public nsIAccessibilityService,
|
||||
public nsIObserver,
|
||||
public nsIWebProgressListener,
|
||||
public nsSupportsWeakReference
|
||||
{
|
||||
public:
|
||||
nsAccessibilityService();
|
||||
virtual ~nsAccessibilityService();
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSIACCESSIBLERETRIEVAL
|
||||
NS_DECL_NSIACCESSIBILITYSERVICE
|
||||
NS_DECL_NSIOBSERVER
|
||||
NS_DECL_NSIWEBPROGRESSLISTENER
|
||||
|
||||
static nsresult GetShellFromNode(nsIDOMNode *aNode, nsIWeakReference **weakShell);
|
||||
static nsresult GetAccessibilityService(nsIAccessibilityService** aResult);
|
||||
|
||||
private:
|
||||
nsresult GetInfo(nsISupports* aFrame, nsIFrame** aRealFrame, nsIWeakReference** aShell, nsIDOMNode** aContent);
|
||||
void GetOwnerFor(nsIPresShell *aPresShell, nsIPresShell **aOwnerShell, nsIContent **aOwnerContent);
|
||||
nsIContent* FindContentForDocShell(nsIPresShell* aPresShell, nsIContent* aContent, nsIDocShell* aDocShell);
|
||||
static nsAccessibilityService *gAccessibilityService;
|
||||
nsresult InitAccessible(nsIAccessible *aAccessibleIn, nsIAccessible **aAccessibleOut);
|
||||
/**
|
||||
* Map nsIAccessibleEvents constants to strings. Used by
|
||||
* nsIAccessibleRetrieval::getStringEventType() method.
|
||||
*/
|
||||
static const char kEventTypeNames[][40] = {
|
||||
"unknown", //
|
||||
"DOM node create", // EVENT_DOM_CREATE
|
||||
"DOM node destroy", // EVENT_DOM_DESTROY
|
||||
"DOM node significant change", // EVENT_DOM_SIGNIFICANT_CHANGE
|
||||
"async show", // EVENT_ASYNCH_SHOW
|
||||
"async hide", // EVENT_ASYNCH_HIDE
|
||||
"async significant change", // EVENT_ASYNCH_SIGNIFICANT_CHANGE
|
||||
"active decendent change", // EVENT_ACTIVE_DECENDENT_CHANGED
|
||||
"focus", // EVENT_FOCUS
|
||||
"state change", // EVENT_STATE_CHANGE
|
||||
"location change", // EVENT_LOCATION_CHANGE
|
||||
"name changed", // EVENT_NAME_CHANGE
|
||||
"description change", // EVENT_DESCRIPTION_CHANGE
|
||||
"value change", // EVENT_VALUE_CHANGE
|
||||
"help change", // EVENT_HELP_CHANGE
|
||||
"default action change", // EVENT_DEFACTION_CHANGE
|
||||
"action change", // EVENT_ACTION_CHANGE
|
||||
"accelerator change", // EVENT_ACCELERATOR_CHANGE
|
||||
"selection", // EVENT_SELECTION
|
||||
"selection add", // EVENT_SELECTION_ADD
|
||||
"selection remove", // EVENT_SELECTION_REMOVE
|
||||
"selection within", // EVENT_SELECTION_WITHIN
|
||||
"alert", // EVENT_ALERT
|
||||
"foreground", // EVENT_FOREGROUND
|
||||
"menu start", // EVENT_MENU_START
|
||||
"menu end", // EVENT_MENU_END
|
||||
"menupopup start", // EVENT_MENUPOPUP_START
|
||||
"menupopup end", // EVENT_MENUPOPUP_END
|
||||
"capture start", // EVENT_CAPTURE_START
|
||||
"capture end", // EVENT_CAPTURE_END
|
||||
"movesize start", // EVENT_MOVESIZE_START
|
||||
"movesize end", // EVENT_MOVESIZE_END
|
||||
"contexthelp start", // EVENT_CONTEXTHELP_START
|
||||
"contexthelp end", // EVENT_CONTEXTHELP_END
|
||||
"dragdrop start", // EVENT_DRAGDROP_START
|
||||
"dragdrop end", // EVENT_DRAGDROP_END
|
||||
"dialog start", // EVENT_DIALOG_START
|
||||
"dialog end", // EVENT_DIALOG_END
|
||||
"scrolling start", // EVENT_SCROLLING_START
|
||||
"scrolling end", // EVENT_SCROLLING_END
|
||||
"minimize start", // EVENT_MINIMIZE_START
|
||||
"minimize end", // EVENT_MINIMIZE_END
|
||||
"document load start", // EVENT_DOCUMENT_LOAD_START
|
||||
"document load complete", // EVENT_DOCUMENT_LOAD_COMPLETE
|
||||
"document reload", // EVENT_DOCUMENT_RELOAD
|
||||
"document load stopped", // EVENT_DOCUMENT_LOAD_STOPPED
|
||||
"document attributes changed", // EVENT_DOCUMENT_ATTRIBUTES_CHANGED
|
||||
"document content changed", // EVENT_DOCUMENT_CONTENT_CHANGED
|
||||
"property changed", // EVENT_PROPERTY_CHANGED
|
||||
"selection changed", // EVENT_SELECTION_CHANGED
|
||||
"text attribute changed", // EVENT_TEXT_ATTRIBUTE_CHANGED
|
||||
"text caret moved", // EVENT_TEXT_CARET_MOVED
|
||||
"text changed", // EVENT_TEXT_CHANGED
|
||||
"text inserted", // EVENT_TEXT_INSERTED
|
||||
"text removed", // EVENT_TEXT_REMOVED
|
||||
"text updated", // EVENT_TEXT_UPDATED
|
||||
"text selection changed", // EVENT_TEXT_SELECTION_CHANGED
|
||||
"visible data changed", // EVENT_VISIBLE_DATA_CHANGED
|
||||
"text column changed", // EVENT_TEXT_COLUMN_CHANGED
|
||||
"section changed", // EVENT_SECTION_CHANGED
|
||||
"table caption changed", // EVENT_TABLE_CAPTION_CHANGED
|
||||
"table model changed", // EVENT_TABLE_MODEL_CHANGED
|
||||
"table summary changed", // EVENT_TABLE_SUMMARY_CHANGED
|
||||
"table row description changed", // EVENT_TABLE_ROW_DESCRIPTION_CHANGED
|
||||
"table row header changed", // EVENT_TABLE_ROW_HEADER_CHANGED
|
||||
"table row insert", // EVENT_TABLE_ROW_INSERT
|
||||
"table row delete", // EVENT_TABLE_ROW_DELETE
|
||||
"table row reorder", // EVENT_TABLE_ROW_REORDER
|
||||
"table column description changed", // EVENT_TABLE_COLUMN_DESCRIPTION_CHANGED
|
||||
"table column header changed", // EVENT_TABLE_COLUMN_HEADER_CHANGED
|
||||
"table column insert", // EVENT_TABLE_COLUMN_INSERT
|
||||
"table column delete", // EVENT_TABLE_COLUMN_DELETE
|
||||
"table column reorder", // EVENT_TABLE_COLUMN_REORDER
|
||||
"window activate", // EVENT_WINDOW_ACTIVATE
|
||||
"window create", // EVENT_WINDOW_CREATE
|
||||
"window deactivate", // EVENT_WINDOW_DEACTIVATE
|
||||
"window destroy", // EVENT_WINDOW_DESTROY
|
||||
"window maximize", // EVENT_WINDOW_MAXIMIZE
|
||||
"window minimize", // EVENT_WINDOW_MINIMIZE
|
||||
"window resize", // EVENT_WINDOW_RESIZE
|
||||
"window restore", // EVENT_WINDOW_RESTORE
|
||||
"hyperlink end index changed", // EVENT_HYPERLINK_END_INDEX_CHANGED
|
||||
"hyperlink number of anchors changed", // EVENT_HYPERLINK_NUMBER_OF_ANCHORS_CHANGED
|
||||
"hyperlink selected link changed", // EVENT_HYPERLINK_SELECTED_LINK_CHANGED
|
||||
"hypertext link activated", // EVENT_HYPERTEXT_LINK_ACTIVATED
|
||||
"hypertext link selected", // EVENT_HYPERTEXT_LINK_SELECTED
|
||||
"hyperlink start index changed", // EVENT_HYPERLINK_START_INDEX_CHANGED
|
||||
"hypertext changed", // EVENT_HYPERTEXT_CHANGED
|
||||
"hypertext links count changed", // EVENT_HYPERTEXT_NLINKS_CHANGED
|
||||
"object attribute changed", // EVENT_OBJECT_ATTRIBUTE_CHANGED
|
||||
"page changed", // EVENT_PAGE_CHANGED
|
||||
"internal load", // EVENT_INTERNAL_LOAD
|
||||
"reorder" // EVENT_REORDER
|
||||
};
|
||||
|
||||
/**
|
||||
* Return accessible object for elements implementing nsIAccessibleProvider
|
||||
* interface.
|
||||
* Map nsIAccessibleRelation constants to strings. Used by
|
||||
* nsIAccessibleRetrieval::getStringRelationType() method.
|
||||
*/
|
||||
nsresult GetAccessibleByType(nsIDOMNode *aNode, nsIAccessible **aAccessible);
|
||||
PRBool HasListener(nsIContent *aContent, nsAString& aEventType);
|
||||
|
||||
/**
|
||||
* Return accessible object if parent is a deck frame
|
||||
*/
|
||||
nsresult GetAccessibleForDeckChildren(nsIDOMNode *aNode, nsIAccessible **aAccessible);
|
||||
static const char kRelationTypeNames[][20] = {
|
||||
"unknown", // RELATION_NUL
|
||||
"controlled by", // RELATION_CONTROLLED_BY
|
||||
"controller for", // RELATION_CONTROLLER_FOR
|
||||
"label for", // RELATION_LABEL_FOR
|
||||
"labelled by", // RELATION_LABELLED_BY
|
||||
"member of", // RELATION_MEMBER_OF
|
||||
"node child of", // RELATION_NODE_CHILD_OF
|
||||
"flows to", // RELATION_FLOWS_TO
|
||||
"flows from", // RELATION_FLOWS_FROM
|
||||
"subwindow of", // RELATION_SUBWINDOW_OF
|
||||
"embeds", // RELATION_EMBEDS
|
||||
"embedded by", // RELATION_EMBEDDED_BY
|
||||
"popup for", // RELATION_POPUP_FOR
|
||||
"parent window of", // RELATION_PARENT_WINDOW_OF
|
||||
"described by", // RELATION_DESCRIBED_BY
|
||||
"description for", // RELATION_DESCRIPTION_FOR
|
||||
"default button" // RELATION_DEFAULT_BUTTON
|
||||
};
|
||||
|
||||
#endif /* __nsIAccessibilityService_h__ */
|
||||
|
||||
|
|
|
@ -38,17 +38,47 @@
|
|||
|
||||
#include "nsAccessibilityUtils.h"
|
||||
|
||||
#include "nsIAccessibleStates.h"
|
||||
#include "nsIAccessibleTypes.h"
|
||||
#include "nsPIAccessible.h"
|
||||
#include "nsPIAccessNode.h"
|
||||
#include "nsAccessibleEventData.h"
|
||||
|
||||
#include "nsAccessible.h"
|
||||
#include "nsARIAMap.h"
|
||||
#include "nsIDocument.h"
|
||||
#include "nsIDOMAbstractView.h"
|
||||
#include "nsIDOM3Node.h"
|
||||
#include "nsIDOMDocument.h"
|
||||
#include "nsIDOMDocumentView.h"
|
||||
#include "nsIDOMDocumentXBL.h"
|
||||
#include "nsIDOMNodeList.h"
|
||||
#include "nsIDOMRange.h"
|
||||
#include "nsIDOMXULContainerElement.h"
|
||||
#include "nsIDOMXULSelectCntrlEl.h"
|
||||
#include "nsIDOMXULSelectCntrlItemEl.h"
|
||||
#include "nsIDOMWindowInternal.h"
|
||||
#include "nsIEventListenerManager.h"
|
||||
#include "nsIPresShell.h"
|
||||
#include "nsPresContext.h"
|
||||
#include "nsIScrollableFrame.h"
|
||||
#include "nsIEventStateManager.h"
|
||||
#include "nsISelection2.h"
|
||||
#include "nsISelectionController.h"
|
||||
|
||||
#include "nsContentCID.h"
|
||||
#include "nsComponentManagerUtils.h"
|
||||
#include "nsIInterfaceRequestorUtils.h"
|
||||
#include "nsWhitespaceTokenizer.h"
|
||||
|
||||
static NS_DEFINE_IID(kRangeCID, NS_RANGE_CID);
|
||||
|
||||
void
|
||||
nsAccUtils::GetAccAttr(nsIPersistentProperties *aAttributes, nsIAtom *aAttrName,
|
||||
nsAString& aAttrValue)
|
||||
{
|
||||
aAttrValue.Truncate();
|
||||
|
||||
nsCAutoString attrName;
|
||||
aAttrName->ToUTF8String(attrName);
|
||||
aAttributes->GetStringProperty(attrName, aAttrValue);
|
||||
|
@ -149,26 +179,129 @@ nsAccUtils::SetAccAttrsForXULSelectControlItem(nsIDOMNode *aNode,
|
|||
if (!control)
|
||||
return;
|
||||
|
||||
PRUint32 itemsCount;
|
||||
PRUint32 itemsCount = 0;
|
||||
control->GetItemCount(&itemsCount);
|
||||
PRInt32 indexOf;
|
||||
|
||||
PRInt32 indexOf = 0;
|
||||
control->GetIndexOfItem(item, &indexOf);
|
||||
|
||||
SetAccGroupAttrs(aAttributes, 0, indexOf + 1, itemsCount);
|
||||
PRUint32 setSize = itemsCount, posInSet = indexOf;
|
||||
for (PRUint32 index = 0; index < itemsCount; index++) {
|
||||
nsCOMPtr<nsIDOMXULSelectControlItemElement> currItem;
|
||||
control->GetItemAtIndex(index, getter_AddRefs(currItem));
|
||||
nsCOMPtr<nsIDOMNode> currNode(do_QueryInterface(currItem));
|
||||
|
||||
nsCOMPtr<nsIAccessible> itemAcc;
|
||||
nsAccessNode::GetAccService()->GetAccessibleFor(currNode,
|
||||
getter_AddRefs(itemAcc));
|
||||
if (!itemAcc ||
|
||||
nsAccessible::State(itemAcc) & nsIAccessibleStates::STATE_INVISIBLE) {
|
||||
setSize--;
|
||||
if (index < static_cast<PRUint32>(indexOf))
|
||||
posInSet--;
|
||||
}
|
||||
}
|
||||
|
||||
SetAccGroupAttrs(aAttributes, 0, posInSet + 1, setSize);
|
||||
}
|
||||
|
||||
void
|
||||
nsAccUtils::SetAccAttrsForXULContainerItem(nsIDOMNode *aNode,
|
||||
nsIPersistentProperties *aAttributes)
|
||||
{
|
||||
nsCOMPtr<nsIDOMXULContainerItemElement> item(do_QueryInterface(aNode));
|
||||
if (!item)
|
||||
return;
|
||||
|
||||
nsCOMPtr<nsIDOMXULContainerElement> container;
|
||||
item->GetParentContainer(getter_AddRefs(container));
|
||||
if (!container)
|
||||
return;
|
||||
|
||||
// Get item count.
|
||||
PRUint32 itemsCount = 0;
|
||||
container->GetItemCount(&itemsCount);
|
||||
|
||||
// Get item index.
|
||||
PRInt32 indexOf = 0;
|
||||
container->GetIndexOfItem(item, &indexOf);
|
||||
|
||||
PRUint32 setSize = itemsCount, posInSet = indexOf;
|
||||
for (PRUint32 index = 0; index < itemsCount; index++) {
|
||||
nsCOMPtr<nsIDOMXULElement> currItem;
|
||||
container->GetItemAtIndex(index, getter_AddRefs(currItem));
|
||||
nsCOMPtr<nsIDOMNode> currNode(do_QueryInterface(currItem));
|
||||
|
||||
nsCOMPtr<nsIAccessible> itemAcc;
|
||||
nsAccessNode::GetAccService()->GetAccessibleFor(currNode,
|
||||
getter_AddRefs(itemAcc));
|
||||
if (!itemAcc ||
|
||||
nsAccessible::State(itemAcc) & nsIAccessibleStates::STATE_INVISIBLE) {
|
||||
setSize--;
|
||||
if (index < static_cast<PRUint32>(indexOf))
|
||||
posInSet--;
|
||||
}
|
||||
}
|
||||
|
||||
// Get level of the item.
|
||||
PRInt32 level = -1;
|
||||
while (container) {
|
||||
level++;
|
||||
|
||||
nsCOMPtr<nsIDOMXULContainerElement> parentContainer;
|
||||
container->GetParentContainer(getter_AddRefs(parentContainer));
|
||||
parentContainer.swap(container);
|
||||
}
|
||||
|
||||
SetAccGroupAttrs(aAttributes, level, posInSet + 1, setSize);
|
||||
}
|
||||
|
||||
PRBool
|
||||
nsAccUtils::HasListener(nsIContent *aContent, const nsAString& aEventType)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aContent);
|
||||
NS_ENSURE_TRUE(aContent, PR_FALSE);
|
||||
nsCOMPtr<nsIEventListenerManager> listenerManager;
|
||||
aContent->GetListenerManager(PR_FALSE, getter_AddRefs(listenerManager));
|
||||
|
||||
return listenerManager && listenerManager->HasListenersFor(aEventType);
|
||||
}
|
||||
|
||||
PRUint32
|
||||
nsAccUtils::GetAccessKeyFor(nsIContent *aContent)
|
||||
{
|
||||
if (!aContent)
|
||||
return 0;
|
||||
|
||||
// Accesskeys are registered by @accesskey attribute only. At first check
|
||||
// whether it is presented on the given element to avoid the slow
|
||||
// nsIEventStateManager::GetRegisteredAccessKey() method.
|
||||
if (!aContent->HasAttr(kNameSpaceID_None, nsAccessibilityAtoms::accesskey))
|
||||
return 0;
|
||||
|
||||
nsCOMPtr<nsIDocument> doc = aContent->GetOwnerDoc();
|
||||
if (!doc)
|
||||
return 0;
|
||||
|
||||
nsCOMPtr<nsIPresShell> presShell = doc->GetPrimaryShell();
|
||||
if (!presShell)
|
||||
return 0;
|
||||
|
||||
nsPresContext *presContext = presShell->GetPresContext();
|
||||
if (!presContext)
|
||||
return 0;
|
||||
|
||||
nsIEventStateManager *esm = presContext->EventStateManager();
|
||||
if (!esm)
|
||||
return 0;
|
||||
|
||||
PRUint32 key = 0;
|
||||
esm->GetRegisteredAccessKey(aContent, &key);
|
||||
return key;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsAccUtils::FireAccEvent(PRUint32 aEventType, nsIAccessible *aAccessible)
|
||||
nsAccUtils::FireAccEvent(PRUint32 aEventType, nsIAccessible *aAccessible,
|
||||
PRBool aIsAsynch)
|
||||
{
|
||||
NS_ENSURE_ARG(aAccessible);
|
||||
|
||||
|
@ -176,9 +309,682 @@ nsAccUtils::FireAccEvent(PRUint32 aEventType, nsIAccessible *aAccessible)
|
|||
NS_ASSERTION(pAccessible, "Accessible doesn't implement nsPIAccessible");
|
||||
|
||||
nsCOMPtr<nsIAccessibleEvent> event =
|
||||
new nsAccEvent(aEventType, aAccessible, nsnull);
|
||||
new nsAccEvent(aEventType, aAccessible, aIsAsynch);
|
||||
NS_ENSURE_TRUE(event, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
return pAccessible->FireAccessibleEvent(event);
|
||||
}
|
||||
|
||||
PRBool
|
||||
nsAccUtils::IsAncestorOf(nsIDOMNode *aPossibleAncestorNode,
|
||||
nsIDOMNode *aPossibleDescendantNode)
|
||||
{
|
||||
NS_ENSURE_TRUE(aPossibleAncestorNode && aPossibleDescendantNode, PR_FALSE);
|
||||
|
||||
nsCOMPtr<nsIDOMNode> loopNode = aPossibleDescendantNode;
|
||||
nsCOMPtr<nsIDOMNode> parentNode;
|
||||
while (NS_SUCCEEDED(loopNode->GetParentNode(getter_AddRefs(parentNode))) &&
|
||||
parentNode) {
|
||||
if (parentNode == aPossibleAncestorNode) {
|
||||
return PR_TRUE;
|
||||
}
|
||||
loopNode.swap(parentNode);
|
||||
}
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
PRBool
|
||||
nsAccUtils::AreSiblings(nsIDOMNode *aDOMNode1,
|
||||
nsIDOMNode *aDOMNode2)
|
||||
{
|
||||
NS_ENSURE_TRUE(aDOMNode1 && aDOMNode2, PR_FALSE);
|
||||
|
||||
nsCOMPtr<nsIDOMNode> parentNode1, parentNode2;
|
||||
if (NS_SUCCEEDED(aDOMNode1->GetParentNode(getter_AddRefs(parentNode1))) &&
|
||||
NS_SUCCEEDED(aDOMNode2->GetParentNode(getter_AddRefs(parentNode2))) &&
|
||||
parentNode1 == parentNode2) {
|
||||
return PR_TRUE;
|
||||
}
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
already_AddRefed<nsIAccessible>
|
||||
nsAccUtils::GetAncestorWithRole(nsIAccessible *aDescendant, PRUint32 aRole)
|
||||
{
|
||||
nsCOMPtr<nsIAccessible> parentAccessible = aDescendant, testRoleAccessible;
|
||||
while (NS_SUCCEEDED(parentAccessible->GetParent(getter_AddRefs(testRoleAccessible))) &&
|
||||
testRoleAccessible) {
|
||||
PRUint32 testRole;
|
||||
testRoleAccessible->GetFinalRole(&testRole);
|
||||
if (testRole == aRole) {
|
||||
nsIAccessible *returnAccessible = testRoleAccessible;
|
||||
NS_ADDREF(returnAccessible);
|
||||
return returnAccessible;
|
||||
}
|
||||
nsCOMPtr<nsIAccessibleDocument> docAccessible = do_QueryInterface(testRoleAccessible);
|
||||
if (docAccessible) {
|
||||
break;
|
||||
}
|
||||
parentAccessible.swap(testRoleAccessible);
|
||||
}
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
void
|
||||
nsAccUtils::GetARIATreeItemParent(nsIAccessible *aStartTreeItem, nsIContent *aStartContent,
|
||||
nsIAccessible **aTreeItemParentResult)
|
||||
{
|
||||
*aTreeItemParentResult = nsnull;
|
||||
nsAutoString levelStr;
|
||||
PRInt32 level = 0;
|
||||
if (aStartContent->GetAttr(kNameSpaceID_None, nsAccessibilityAtoms::aria_level, levelStr)) {
|
||||
// This is a tree that uses aria-level to define levels, so find the first previous
|
||||
// sibling accessible where level is defined to be less than the current level
|
||||
PRInt32 success;
|
||||
level = levelStr.ToInteger(&success);
|
||||
if (level > 1 && NS_SUCCEEDED(success)) {
|
||||
nsCOMPtr<nsIAccessible> currentAccessible = aStartTreeItem, prevAccessible;
|
||||
while (PR_TRUE) {
|
||||
currentAccessible->GetPreviousSibling(getter_AddRefs(prevAccessible));
|
||||
currentAccessible.swap(prevAccessible);
|
||||
nsCOMPtr<nsIAccessNode> accessNode = do_QueryInterface(currentAccessible);
|
||||
if (!accessNode) {
|
||||
break; // Reached top of tree, no higher level found
|
||||
}
|
||||
PRUint32 role;
|
||||
currentAccessible->GetFinalRole(&role);
|
||||
if (role != nsIAccessibleRole::ROLE_OUTLINEITEM)
|
||||
continue;
|
||||
nsCOMPtr<nsIDOMNode> treeItemNode;
|
||||
accessNode->GetDOMNode(getter_AddRefs(treeItemNode));
|
||||
nsCOMPtr<nsIContent> treeItemContent = do_QueryInterface(treeItemNode);
|
||||
if (treeItemContent &&
|
||||
treeItemContent->GetAttr(kNameSpaceID_None,
|
||||
nsAccessibilityAtoms::aria_level, levelStr)) {
|
||||
if (levelStr.ToInteger(&success) < level && NS_SUCCEEDED(success)) {
|
||||
NS_ADDREF(*aTreeItemParentResult = currentAccessible);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Possibly a tree arranged by using role="group" to organize levels
|
||||
// In this case the parent of the tree item will be a group and the
|
||||
// previous sibling of that should be the tree item parent.
|
||||
// Or, if the parent is something other than a tree we will return that.
|
||||
nsCOMPtr<nsIAccessible> parentAccessible;
|
||||
aStartTreeItem->GetParent(getter_AddRefs(parentAccessible));
|
||||
if (!parentAccessible)
|
||||
return;
|
||||
PRUint32 role;
|
||||
parentAccessible->GetFinalRole(&role);
|
||||
if (role != nsIAccessibleRole::ROLE_GROUPING) {
|
||||
NS_ADDREF(*aTreeItemParentResult = parentAccessible);
|
||||
return; // The container for the tree items
|
||||
}
|
||||
nsCOMPtr<nsIAccessible> prevAccessible;
|
||||
parentAccessible->GetPreviousSibling(getter_AddRefs(prevAccessible));
|
||||
if (!prevAccessible)
|
||||
return;
|
||||
prevAccessible->GetFinalRole(&role);
|
||||
if (role == nsIAccessibleRole::ROLE_TEXT_LEAF) {
|
||||
// XXX Sometimes an empty text accessible is in the hierarchy here,
|
||||
// although the text does not appear to be rendered, GetRenderedText() says that it is
|
||||
// so we need to skip past it to find the true previous sibling
|
||||
nsCOMPtr<nsIAccessible> tempAccessible = prevAccessible;
|
||||
tempAccessible->GetPreviousSibling(getter_AddRefs(prevAccessible));
|
||||
if (!prevAccessible)
|
||||
return;
|
||||
prevAccessible->GetFinalRole(&role);
|
||||
}
|
||||
if (role == nsIAccessibleRole::ROLE_OUTLINEITEM) {
|
||||
// Previous sibling of parent group is a tree item -- this is the conceptual tree item parent
|
||||
NS_ADDREF(*aTreeItemParentResult = prevAccessible);
|
||||
}
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsAccUtils::ScrollSubstringTo(nsIFrame *aFrame,
|
||||
nsIDOMNode *aStartNode, PRInt32 aStartIndex,
|
||||
nsIDOMNode *aEndNode, PRInt32 aEndIndex,
|
||||
PRUint32 aScrollType)
|
||||
{
|
||||
PRInt16 vPercent, hPercent;
|
||||
ConvertScrollTypeToPercents(aScrollType, &vPercent, &hPercent);
|
||||
|
||||
return ScrollSubstringTo(aFrame, aStartNode, aStartIndex, aEndNode, aEndIndex,
|
||||
vPercent, hPercent);
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsAccUtils::ScrollSubstringTo(nsIFrame *aFrame,
|
||||
nsIDOMNode *aStartNode, PRInt32 aStartIndex,
|
||||
nsIDOMNode *aEndNode, PRInt32 aEndIndex,
|
||||
PRInt16 aVPercent, PRInt16 aHPercent)
|
||||
{
|
||||
if (!aFrame || !aStartNode || !aEndNode)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
nsPresContext *presContext = aFrame->PresContext();
|
||||
|
||||
nsCOMPtr<nsIDOMRange> scrollToRange = do_CreateInstance(kRangeCID);
|
||||
NS_ENSURE_TRUE(scrollToRange, NS_ERROR_FAILURE);
|
||||
|
||||
nsCOMPtr<nsISelectionController> selCon;
|
||||
aFrame->GetSelectionController(presContext, getter_AddRefs(selCon));
|
||||
NS_ENSURE_TRUE(selCon, NS_ERROR_FAILURE);
|
||||
|
||||
scrollToRange->SetStart(aStartNode, aStartIndex);
|
||||
scrollToRange->SetEnd(aEndNode, aEndIndex);
|
||||
|
||||
nsCOMPtr<nsISelection> selection1;
|
||||
selCon->GetSelection(nsISelectionController::SELECTION_ACCESSIBILITY,
|
||||
getter_AddRefs(selection1));
|
||||
|
||||
nsCOMPtr<nsISelection2> selection(do_QueryInterface(selection1));
|
||||
if (selection) {
|
||||
selection->RemoveAllRanges();
|
||||
selection->AddRange(scrollToRange);
|
||||
|
||||
selection->ScrollIntoView(nsISelectionController::SELECTION_ANCHOR_REGION,
|
||||
PR_TRUE, aVPercent, aHPercent);
|
||||
|
||||
selection->CollapseToStart();
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
nsAccUtils::ScrollFrameToPoint(nsIFrame *aScrollableFrame,
|
||||
nsIFrame *aFrame,
|
||||
const nsIntPoint& aPoint)
|
||||
{
|
||||
nsIScrollableFrame *scrollableFrame = nsnull;
|
||||
CallQueryInterface(aScrollableFrame, &scrollableFrame);
|
||||
if (!scrollableFrame)
|
||||
return;
|
||||
|
||||
nsPresContext *presContext = aFrame->PresContext();
|
||||
|
||||
nsIntRect frameRect = aFrame->GetScreenRectExternal();
|
||||
PRInt32 devDeltaX = aPoint.x - frameRect.x;
|
||||
PRInt32 devDeltaY = aPoint.y - frameRect.y;
|
||||
|
||||
nsPoint deltaPoint;
|
||||
deltaPoint.x = presContext->DevPixelsToAppUnits(devDeltaX);
|
||||
deltaPoint.y = presContext->DevPixelsToAppUnits(devDeltaY);
|
||||
|
||||
nsPoint scrollPoint = scrollableFrame->GetScrollPosition();
|
||||
scrollPoint -= deltaPoint;
|
||||
|
||||
scrollableFrame->ScrollTo(scrollPoint);
|
||||
}
|
||||
|
||||
void
|
||||
nsAccUtils::ConvertScrollTypeToPercents(PRUint32 aScrollType,
|
||||
PRInt16 *aVPercent,
|
||||
PRInt16 *aHPercent)
|
||||
{
|
||||
switch (aScrollType)
|
||||
{
|
||||
case nsIAccessibleScrollType::SCROLL_TYPE_TOP_LEFT:
|
||||
*aVPercent = NS_PRESSHELL_SCROLL_TOP;
|
||||
*aHPercent = NS_PRESSHELL_SCROLL_LEFT;
|
||||
break;
|
||||
case nsIAccessibleScrollType::SCROLL_TYPE_BOTTOM_RIGHT:
|
||||
*aVPercent = NS_PRESSHELL_SCROLL_BOTTOM;
|
||||
*aHPercent = NS_PRESSHELL_SCROLL_RIGHT;
|
||||
break;
|
||||
case nsIAccessibleScrollType::SCROLL_TYPE_TOP_EDGE:
|
||||
*aVPercent = NS_PRESSHELL_SCROLL_TOP;
|
||||
*aHPercent = NS_PRESSHELL_SCROLL_ANYWHERE;
|
||||
break;
|
||||
case nsIAccessibleScrollType::SCROLL_TYPE_BOTTOM_EDGE:
|
||||
*aVPercent = NS_PRESSHELL_SCROLL_BOTTOM;
|
||||
*aHPercent = NS_PRESSHELL_SCROLL_ANYWHERE;
|
||||
break;
|
||||
case nsIAccessibleScrollType::SCROLL_TYPE_LEFT_EDGE:
|
||||
*aVPercent = NS_PRESSHELL_SCROLL_ANYWHERE;
|
||||
*aHPercent = NS_PRESSHELL_SCROLL_LEFT;
|
||||
break;
|
||||
case nsIAccessibleScrollType::SCROLL_TYPE_RIGHT_EDGE:
|
||||
*aVPercent = NS_PRESSHELL_SCROLL_ANYWHERE;
|
||||
*aHPercent = NS_PRESSHELL_SCROLL_RIGHT;
|
||||
break;
|
||||
default:
|
||||
*aVPercent = NS_PRESSHELL_SCROLL_ANYWHERE;
|
||||
*aHPercent = NS_PRESSHELL_SCROLL_ANYWHERE;
|
||||
}
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsAccUtils::ConvertToScreenCoords(PRInt32 aX, PRInt32 aY,
|
||||
PRUint32 aCoordinateType,
|
||||
nsIAccessNode *aAccessNode,
|
||||
nsIntPoint *aCoords)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aCoords);
|
||||
|
||||
aCoords->MoveTo(aX, aY);
|
||||
|
||||
switch (aCoordinateType) {
|
||||
case nsIAccessibleCoordinateType::COORDTYPE_SCREEN_RELATIVE:
|
||||
break;
|
||||
|
||||
case nsIAccessibleCoordinateType::COORDTYPE_WINDOW_RELATIVE:
|
||||
{
|
||||
NS_ENSURE_ARG(aAccessNode);
|
||||
*aCoords += GetScreenCoordsForWindow(aAccessNode);
|
||||
break;
|
||||
}
|
||||
|
||||
case nsIAccessibleCoordinateType::COORDTYPE_PARENT_RELATIVE:
|
||||
{
|
||||
NS_ENSURE_ARG(aAccessNode);
|
||||
*aCoords += GetScreenCoordsForParent(aAccessNode);
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsAccUtils::ConvertScreenCoordsTo(PRInt32 *aX, PRInt32 *aY,
|
||||
PRUint32 aCoordinateType,
|
||||
nsIAccessNode *aAccessNode)
|
||||
{
|
||||
switch (aCoordinateType) {
|
||||
case nsIAccessibleCoordinateType::COORDTYPE_SCREEN_RELATIVE:
|
||||
break;
|
||||
|
||||
case nsIAccessibleCoordinateType::COORDTYPE_WINDOW_RELATIVE:
|
||||
{
|
||||
NS_ENSURE_ARG(aAccessNode);
|
||||
nsIntPoint coords = GetScreenCoordsForWindow(aAccessNode);
|
||||
*aX -= coords.x;
|
||||
*aY -= coords.y;
|
||||
break;
|
||||
}
|
||||
|
||||
case nsIAccessibleCoordinateType::COORDTYPE_PARENT_RELATIVE:
|
||||
{
|
||||
NS_ENSURE_ARG(aAccessNode);
|
||||
nsIntPoint coords = GetScreenCoordsForParent(aAccessNode);
|
||||
*aX -= coords.x;
|
||||
*aY -= coords.y;
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsIntPoint
|
||||
nsAccUtils::GetScreenCoordsForWindow(nsIDOMNode *aNode)
|
||||
{
|
||||
nsIntPoint coords(0, 0);
|
||||
nsCOMPtr<nsIDocShellTreeItem> treeItem(GetDocShellTreeItemFor(aNode));
|
||||
if (!treeItem)
|
||||
return coords;
|
||||
|
||||
nsCOMPtr<nsIDocShellTreeItem> rootTreeItem;
|
||||
treeItem->GetRootTreeItem(getter_AddRefs(rootTreeItem));
|
||||
nsCOMPtr<nsIDOMDocument> domDoc = do_GetInterface(rootTreeItem);
|
||||
nsCOMPtr<nsIDOMDocumentView> docView(do_QueryInterface(domDoc));
|
||||
if (!docView)
|
||||
return coords;
|
||||
|
||||
nsCOMPtr<nsIDOMAbstractView> abstractView;
|
||||
docView->GetDefaultView(getter_AddRefs(abstractView));
|
||||
nsCOMPtr<nsIDOMWindowInternal> windowInter(do_QueryInterface(abstractView));
|
||||
if (!windowInter)
|
||||
return coords;
|
||||
|
||||
windowInter->GetScreenX(&coords.x);
|
||||
windowInter->GetScreenY(&coords.y);
|
||||
return coords;
|
||||
}
|
||||
|
||||
nsIntPoint
|
||||
nsAccUtils::GetScreenCoordsForWindow(nsIAccessNode *aAccessNode)
|
||||
{
|
||||
nsCOMPtr<nsIDOMNode> DOMNode;
|
||||
aAccessNode->GetDOMNode(getter_AddRefs(DOMNode));
|
||||
if (DOMNode)
|
||||
return GetScreenCoordsForWindow(DOMNode);
|
||||
|
||||
return nsIntPoint(0, 0);
|
||||
}
|
||||
|
||||
nsIntPoint
|
||||
nsAccUtils::GetScreenCoordsForParent(nsIAccessNode *aAccessNode)
|
||||
{
|
||||
nsCOMPtr<nsPIAccessNode> parent;
|
||||
nsCOMPtr<nsIAccessible> accessible(do_QueryInterface(aAccessNode));
|
||||
if (accessible) {
|
||||
nsCOMPtr<nsIAccessible> parentAccessible;
|
||||
accessible->GetParent(getter_AddRefs(parentAccessible));
|
||||
parent = do_QueryInterface(parentAccessible);
|
||||
} else {
|
||||
nsCOMPtr<nsIAccessNode> parentAccessNode;
|
||||
aAccessNode->GetParentNode(getter_AddRefs(parentAccessNode));
|
||||
parent = do_QueryInterface(parentAccessNode);
|
||||
}
|
||||
|
||||
if (!parent)
|
||||
return nsIntPoint(0, 0);
|
||||
|
||||
nsIFrame *parentFrame = parent->GetFrame();
|
||||
if (!parentFrame)
|
||||
return nsIntPoint(0, 0);
|
||||
|
||||
nsIntRect parentRect = parentFrame->GetScreenRectExternal();
|
||||
return nsIntPoint(parentRect.x, parentRect.y);
|
||||
}
|
||||
|
||||
already_AddRefed<nsIDocShellTreeItem>
|
||||
nsAccUtils::GetDocShellTreeItemFor(nsIDOMNode *aNode)
|
||||
{
|
||||
if (!aNode)
|
||||
return nsnull;
|
||||
|
||||
nsCOMPtr<nsIDOMDocument> domDoc;
|
||||
aNode->GetOwnerDocument(getter_AddRefs(domDoc));
|
||||
nsCOMPtr<nsIDocument> doc(do_QueryInterface(domDoc));
|
||||
if (!doc)
|
||||
doc = do_QueryInterface(aNode);
|
||||
|
||||
NS_ASSERTION(doc, "No document for node passed in");
|
||||
NS_ENSURE_TRUE(doc, nsnull);
|
||||
|
||||
nsCOMPtr<nsISupports> container = doc->GetContainer();
|
||||
nsIDocShellTreeItem *docShellTreeItem = nsnull;
|
||||
if (container)
|
||||
CallQueryInterface(container, &docShellTreeItem);
|
||||
|
||||
return docShellTreeItem;
|
||||
}
|
||||
|
||||
PRBool
|
||||
nsAccUtils::GetID(nsIContent *aContent, nsAString& aID)
|
||||
{
|
||||
nsIAtom *idAttribute = aContent->GetIDAttributeName();
|
||||
return idAttribute ? aContent->GetAttr(kNameSpaceID_None, idAttribute, aID) : PR_FALSE;
|
||||
}
|
||||
|
||||
PRBool
|
||||
nsAccUtils::IsXLink(nsIContent *aContent)
|
||||
{
|
||||
if (!aContent)
|
||||
return PR_FALSE;
|
||||
|
||||
return aContent->AttrValueIs(kNameSpaceID_XLink, nsAccessibilityAtoms::type,
|
||||
nsAccessibilityAtoms::simple, eCaseMatters) &&
|
||||
aContent->HasAttr(kNameSpaceID_XLink, nsAccessibilityAtoms::href);
|
||||
}
|
||||
|
||||
nsIContent*
|
||||
nsAccUtils::FindNeighbourPointingToNode(nsIContent *aForNode,
|
||||
nsIAtom *aRelationAttr,
|
||||
nsIAtom *aTagName,
|
||||
PRUint32 aAncestorLevelsToSearch)
|
||||
{
|
||||
return FindNeighbourPointingToNode(aForNode, &aRelationAttr, 1, aTagName, aAncestorLevelsToSearch);
|
||||
}
|
||||
|
||||
nsIContent*
|
||||
nsAccUtils::FindNeighbourPointingToNode(nsIContent *aForNode,
|
||||
nsIAtom **aRelationAttrs,
|
||||
PRUint32 aAttrNum,
|
||||
nsIAtom *aTagName,
|
||||
PRUint32 aAncestorLevelsToSearch)
|
||||
{
|
||||
nsCOMPtr<nsIContent> binding;
|
||||
nsAutoString controlID;
|
||||
if (!nsAccUtils::GetID(aForNode, controlID)) {
|
||||
binding = aForNode->GetBindingParent();
|
||||
if (binding == aForNode)
|
||||
return nsnull;
|
||||
|
||||
aForNode->GetAttr(kNameSpaceID_None, nsAccessibilityAtoms::anonid, controlID);
|
||||
if (controlID.IsEmpty())
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
// Look for label in subtrees of nearby ancestors
|
||||
PRUint32 count = 0;
|
||||
nsIContent *labelContent = nsnull;
|
||||
nsIContent *prevSearched = nsnull;
|
||||
|
||||
while (!labelContent && ++count <= aAncestorLevelsToSearch &&
|
||||
(aForNode = aForNode->GetParent()) != nsnull) {
|
||||
|
||||
if (aForNode == binding) {
|
||||
// When we reach the binding parent, make sure to check
|
||||
// all of its anonymous child subtrees
|
||||
nsCOMPtr<nsIDocument> doc = aForNode->GetCurrentDoc();
|
||||
nsCOMPtr<nsIDOMDocumentXBL> xblDoc(do_QueryInterface(doc));
|
||||
if (!xblDoc)
|
||||
return nsnull;
|
||||
|
||||
nsCOMPtr<nsIDOMNodeList> nodes;
|
||||
nsCOMPtr<nsIDOMElement> forElm(do_QueryInterface(aForNode));
|
||||
xblDoc->GetAnonymousNodes(forElm, getter_AddRefs(nodes));
|
||||
if (!nodes)
|
||||
return nsnull;
|
||||
|
||||
PRUint32 length;
|
||||
nsresult rv = nodes->GetLength(&length);
|
||||
if (NS_FAILED(rv))
|
||||
return nsnull;
|
||||
|
||||
for (PRUint32 index = 0; index < length && !labelContent; index++) {
|
||||
nsCOMPtr<nsIDOMNode> node;
|
||||
rv = nodes->Item(index, getter_AddRefs(node));
|
||||
if (NS_FAILED(rv))
|
||||
return nsnull;
|
||||
|
||||
nsCOMPtr<nsIContent> content = do_QueryInterface(node);
|
||||
if (!content)
|
||||
return nsnull;
|
||||
|
||||
if (content != prevSearched) {
|
||||
labelContent = FindDescendantPointingToID(&controlID, content,
|
||||
aRelationAttrs, aAttrNum,
|
||||
nsnull, aTagName);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
labelContent = FindDescendantPointingToID(&controlID, aForNode,
|
||||
aRelationAttrs, aAttrNum,
|
||||
prevSearched, aTagName);
|
||||
prevSearched = aForNode;
|
||||
}
|
||||
|
||||
return labelContent;
|
||||
}
|
||||
|
||||
// Pass in aAriaProperty = null and aRelationAttr == nsnull if any <label> will do
|
||||
nsIContent*
|
||||
nsAccUtils::FindDescendantPointingToID(const nsString *aId,
|
||||
nsIContent *aLookContent,
|
||||
nsIAtom **aRelationAttrs,
|
||||
PRUint32 aAttrNum,
|
||||
nsIContent *aExcludeContent,
|
||||
nsIAtom *aTagType)
|
||||
{
|
||||
// Surround id with spaces for search
|
||||
nsCAutoString idWithSpaces(' ');
|
||||
LossyAppendUTF16toASCII(*aId, idWithSpaces);
|
||||
idWithSpaces += ' ';
|
||||
return FindDescendantPointingToIDImpl(idWithSpaces, aLookContent,
|
||||
aRelationAttrs, aAttrNum,
|
||||
aExcludeContent, aTagType);
|
||||
}
|
||||
|
||||
nsIContent*
|
||||
nsAccUtils::FindDescendantPointingToID(const nsString *aId,
|
||||
nsIContent *aLookContent,
|
||||
nsIAtom *aRelationAttr,
|
||||
nsIContent *aExcludeContent,
|
||||
nsIAtom *aTagType)
|
||||
{
|
||||
return FindDescendantPointingToID(aId, aLookContent, &aRelationAttr, 1, aExcludeContent, aTagType);
|
||||
}
|
||||
|
||||
nsIContent*
|
||||
nsAccUtils::FindDescendantPointingToIDImpl(nsCString& aIdWithSpaces,
|
||||
nsIContent *aLookContent,
|
||||
nsIAtom **aRelationAttrs,
|
||||
PRUint32 aAttrNum,
|
||||
nsIContent *aExcludeContent,
|
||||
nsIAtom *aTagType)
|
||||
{
|
||||
NS_ENSURE_TRUE(aLookContent, nsnull);
|
||||
NS_ENSURE_TRUE(aRelationAttrs && *aRelationAttrs, nsnull);
|
||||
|
||||
if (!aTagType || aLookContent->Tag() == aTagType) {
|
||||
// Tag matches
|
||||
// Check for ID in the attributes aRelationAttrs, which can be a list
|
||||
for (PRUint32 i = 0; i < aAttrNum; i++) {
|
||||
nsAutoString idList;
|
||||
if (aLookContent->GetAttr(kNameSpaceID_None, aRelationAttrs[i], idList)) {
|
||||
idList.Insert(' ', 0); // Surround idlist with spaces for search
|
||||
idList.Append(' ');
|
||||
// idList is now a set of id's with spaces around each,
|
||||
// and id also has spaces around it.
|
||||
// If id is a substring of idList then we have a match
|
||||
if (idList.Find(aIdWithSpaces) != -1) {
|
||||
return aLookContent;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (aTagType) {
|
||||
// Don't bother to search descendants of an element with matching tag.
|
||||
// That would be like looking for a nested <label> or <description>
|
||||
return nsnull;
|
||||
}
|
||||
}
|
||||
|
||||
// Recursively search descendants for match
|
||||
PRUint32 count = 0;
|
||||
nsIContent *child;
|
||||
nsIContent *labelContent = nsnull;
|
||||
|
||||
while ((child = aLookContent->GetChildAt(count++)) != nsnull) {
|
||||
if (child != aExcludeContent) {
|
||||
labelContent = FindDescendantPointingToIDImpl(aIdWithSpaces, child,
|
||||
aRelationAttrs, aAttrNum,
|
||||
aExcludeContent, aTagType);
|
||||
if (labelContent) {
|
||||
return labelContent;
|
||||
}
|
||||
}
|
||||
}
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
nsRoleMapEntry*
|
||||
nsAccUtils::GetRoleMapEntry(nsIDOMNode *aNode)
|
||||
{
|
||||
nsIContent *content = nsAccessible::GetRoleContent(aNode);
|
||||
nsAutoString roleString;
|
||||
if (!content || !content->GetAttr(kNameSpaceID_None, nsAccessibilityAtoms::role, roleString)) {
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
nsWhitespaceTokenizer tokenizer(roleString);
|
||||
while (tokenizer.hasMoreTokens()) {
|
||||
// Do a binary search through table for the next role in role list
|
||||
const char *role = NS_LossyConvertUTF16toASCII(tokenizer.nextToken()).get();
|
||||
PRInt32 low = 0;
|
||||
PRInt32 high = nsARIAMap::gWAIRoleMapLength;
|
||||
while (low <= high) {
|
||||
PRInt32 index = low + ((high - low) / 2);
|
||||
PRInt32 compare = PL_strcmp(role, nsARIAMap::gWAIRoleMap[index].roleString);
|
||||
if (compare == 0) {
|
||||
// The role attribute maps to an entry in the role table
|
||||
return &nsARIAMap::gWAIRoleMap[index];
|
||||
}
|
||||
if (compare < 0) {
|
||||
high = index - 1;
|
||||
}
|
||||
else {
|
||||
low = index + 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Always use some entry if there is a role string
|
||||
// To ensure an accessible object is created
|
||||
return &nsARIAMap::gLandmarkRoleMap;
|
||||
}
|
||||
|
||||
PRBool
|
||||
nsAccUtils::IsARIAPropForObjectAttr(nsIAtom *aAtom)
|
||||
{
|
||||
return aAtom != nsAccessibilityAtoms::aria_activedescendant &&
|
||||
aAtom != nsAccessibilityAtoms::aria_checked &&
|
||||
aAtom != nsAccessibilityAtoms::aria_controls &&
|
||||
aAtom != nsAccessibilityAtoms::aria_describedby &&
|
||||
aAtom != nsAccessibilityAtoms::aria_disabled &&
|
||||
aAtom != nsAccessibilityAtoms::aria_expanded &&
|
||||
aAtom != nsAccessibilityAtoms::aria_flowto &&
|
||||
aAtom != nsAccessibilityAtoms::aria_invalid &&
|
||||
aAtom != nsAccessibilityAtoms::aria_haspopup &&
|
||||
aAtom != nsAccessibilityAtoms::aria_labelledby &&
|
||||
aAtom != nsAccessibilityAtoms::aria_multiline &&
|
||||
aAtom != nsAccessibilityAtoms::aria_multiselectable &&
|
||||
aAtom != nsAccessibilityAtoms::aria_owns &&
|
||||
aAtom != nsAccessibilityAtoms::aria_pressed &&
|
||||
aAtom != nsAccessibilityAtoms::aria_readonly &&
|
||||
aAtom != nsAccessibilityAtoms::aria_relevant &&
|
||||
aAtom != nsAccessibilityAtoms::aria_required &&
|
||||
aAtom != nsAccessibilityAtoms::aria_selected &&
|
||||
aAtom != nsAccessibilityAtoms::aria_valuemax &&
|
||||
aAtom != nsAccessibilityAtoms::aria_valuemin &&
|
||||
aAtom != nsAccessibilityAtoms::aria_valuenow &&
|
||||
aAtom != nsAccessibilityAtoms::aria_valuetext;
|
||||
}
|
||||
|
||||
void nsAccUtils::GetLiveContainerAttributes(nsIPersistentProperties *aAttributes,
|
||||
nsIContent *aStartContent, nsIContent *aTopContent)
|
||||
{
|
||||
nsAutoString atomic, live, relevant, channel, busy;
|
||||
nsIContent *ancestor = aStartContent;
|
||||
while (ancestor) {
|
||||
if (relevant.IsEmpty() &&
|
||||
ancestor->GetAttr(kNameSpaceID_None, nsAccessibilityAtoms::aria_relevant, relevant))
|
||||
SetAccAttr(aAttributes, nsAccessibilityAtoms::containerRelevant, relevant);
|
||||
if (live.IsEmpty() &&
|
||||
ancestor->GetAttr(kNameSpaceID_None, nsAccessibilityAtoms::aria_live, live))
|
||||
SetAccAttr(aAttributes, nsAccessibilityAtoms::containerLive, live);
|
||||
if (channel.IsEmpty() &&
|
||||
ancestor->GetAttr(kNameSpaceID_None, nsAccessibilityAtoms::aria_channel, channel))
|
||||
SetAccAttr(aAttributes, nsAccessibilityAtoms::containerChannel, channel);
|
||||
if (atomic.IsEmpty() &&
|
||||
ancestor->GetAttr(kNameSpaceID_None, nsAccessibilityAtoms::aria_atomic, atomic))
|
||||
SetAccAttr(aAttributes, nsAccessibilityAtoms::containerAtomic, atomic);
|
||||
if (busy.IsEmpty() &&
|
||||
ancestor->GetAttr(kNameSpaceID_None, nsAccessibilityAtoms::aria_busy, busy))
|
||||
SetAccAttr(aAttributes, nsAccessibilityAtoms::containerBusy, busy);
|
||||
if (ancestor == aTopContent)
|
||||
break;
|
||||
ancestor = ancestor->GetParent();
|
||||
if (!ancestor) {
|
||||
ancestor = aTopContent; // Use <body>/<frameset>
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -41,10 +41,16 @@
|
|||
|
||||
#include "nsAccessibilityAtoms.h"
|
||||
#include "nsIAccessible.h"
|
||||
#include "nsIAccessNode.h"
|
||||
#include "nsARIAMap.h"
|
||||
|
||||
#include "nsIDOMNode.h"
|
||||
#include "nsIPersistentProperties2.h"
|
||||
#include "nsIContent.h"
|
||||
#include "nsIFrame.h"
|
||||
#include "nsIDocShellTreeItem.h"
|
||||
#include "nsPoint.h"
|
||||
#include "nsIAccessibleDocument.h"
|
||||
|
||||
class nsAccUtils
|
||||
{
|
||||
|
@ -102,16 +108,290 @@ public:
|
|||
static void SetAccAttrsForXULSelectControlItem(nsIDOMNode *aNode,
|
||||
nsIPersistentProperties *aAttributes);
|
||||
|
||||
/**
|
||||
* Set group attributes - 'level', 'setsize', 'posinset'.
|
||||
*
|
||||
* @param aNode XUL element that implements
|
||||
* nsIDOMXULContainerItemElement interface
|
||||
* @param aAttributes attributes container
|
||||
*/
|
||||
static void SetAccAttrsForXULContainerItem(nsIDOMNode *aNode,
|
||||
nsIPersistentProperties *aAttributes);
|
||||
|
||||
/**
|
||||
* Return true if the given node has registered event listener of the given
|
||||
* type.
|
||||
*/
|
||||
static PRBool HasListener(nsIContent *aContent, const nsAString& aEventType);
|
||||
|
||||
/**
|
||||
* Return an accesskey registered on the given element by
|
||||
* nsIEventStateManager or 0 if there is no registered accesskey.
|
||||
*
|
||||
* @param aContent - the given element.
|
||||
*/
|
||||
static PRUint32 GetAccessKeyFor(nsIContent *aContent);
|
||||
|
||||
/**
|
||||
* Fire accessible event of the given type for the given accessible.
|
||||
*/
|
||||
static nsresult FireAccEvent(PRUint32 aEventType, nsIAccessible *aAccessible);
|
||||
static nsresult FireAccEvent(PRUint32 aEventType, nsIAccessible *aAccessible,
|
||||
PRBool aIsAsynch = PR_FALSE);
|
||||
|
||||
/**
|
||||
* Is the first passed in node an ancestor of the second?
|
||||
* Note: A node is not considered to be the ancestor of itself.
|
||||
* @param aPossibleAncestorNode -- node to test for ancestor-ness of aPossibleDescendantNode
|
||||
* @param aPossibleDescendantNode -- node to test for descendant-ness of aPossibleAncestorNode
|
||||
* @return PR_TRUE if aPossibleAncestorNode is an ancestor of aPossibleDescendantNode
|
||||
*/
|
||||
static PRBool IsAncestorOf(nsIDOMNode *aPossibleAncestorNode,
|
||||
nsIDOMNode *aPossibleDescendantNode);
|
||||
|
||||
/**
|
||||
* Are the first node and the second siblings?
|
||||
* @return PR_TRUE if aDOMNode1 and aDOMNode2 have same parent
|
||||
*/
|
||||
static PRBool AreSiblings(nsIDOMNode *aDOMNode1,
|
||||
nsIDOMNode *aDOMNode2);
|
||||
|
||||
/**
|
||||
* If an ancestor in this document exists with the given role, return it
|
||||
* @param aDescendant Descendant to start search with
|
||||
* @param aRole Role to find matching ancestor for
|
||||
* @return The ancestor accessible with the given role, or nsnull if no match is found
|
||||
*/
|
||||
static already_AddRefed<nsIAccessible>
|
||||
GetAncestorWithRole(nsIAccessible *aDescendant, PRUint32 aRole);
|
||||
|
||||
/**
|
||||
* For an ARIA tree item , get the accessible that represents its conceptual parent.
|
||||
* This method will use the correct method for the given way the tree is constructed.
|
||||
* The conceptual parent is what the user sees as the parent, not the DOM or accessible parent.
|
||||
* @param aStartTreeItem The tree item to get the parent for
|
||||
* @param aStartTreeItemContent The content node for the tree item
|
||||
* @param The tree item's parent, or null if none
|
||||
*/
|
||||
static void
|
||||
GetARIATreeItemParent(nsIAccessible *aStartTreeItem,
|
||||
nsIContent *aStartTreeItemContent,
|
||||
nsIAccessible **aTreeItemParent);
|
||||
|
||||
/**
|
||||
* Helper method to scroll range into view, used for implementation of
|
||||
* nsIAccessibleText::scrollSubstringTo().
|
||||
*
|
||||
* @param aFrame the frame for accessible the range belongs to.
|
||||
* @param aStartNode start node of a range
|
||||
* @param aStartOffset an offset inside the start node
|
||||
* @param aEndNode end node of a range
|
||||
* @param aEndOffset an offset inside the end node
|
||||
* @param aScrollType the place a range should be scrolled to
|
||||
*/
|
||||
static nsresult ScrollSubstringTo(nsIFrame *aFrame,
|
||||
nsIDOMNode *aStartNode, PRInt32 aStartIndex,
|
||||
nsIDOMNode *aEndNode, PRInt32 aEndIndex,
|
||||
PRUint32 aScrollType);
|
||||
|
||||
/** Helper method to scroll range into view, used for implementation of
|
||||
* nsIAccessibleText::scrollSubstringTo[Point]().
|
||||
*
|
||||
* @param aFrame the frame for accessible the range belongs to.
|
||||
* @param aStartNode start node of a range
|
||||
* @param aStartOffset an offset inside the start node
|
||||
* @param aEndNode end node of a range
|
||||
* @param aEndOffset an offset inside the end node
|
||||
* @param aVPercent how to align vertically, specified in percents
|
||||
* @param aHPercent how to align horizontally, specified in percents
|
||||
*/
|
||||
static nsresult ScrollSubstringTo(nsIFrame *aFrame,
|
||||
nsIDOMNode *aStartNode, PRInt32 aStartIndex,
|
||||
nsIDOMNode *aEndNode, PRInt32 aEndIndex,
|
||||
PRInt16 aVPercent, PRInt16 aHPercent);
|
||||
|
||||
/**
|
||||
* Scrolls the given frame to the point, used for implememntation of
|
||||
* nsIAccessNode::scrollToPoint and nsIAccessibleText::scrollSubstringToPoint.
|
||||
*
|
||||
* @param aScrollableFrame the scrollable frame
|
||||
* @param aFrame the frame to scroll
|
||||
* @param aPoint the point scroll to
|
||||
*/
|
||||
static void ScrollFrameToPoint(nsIFrame *aScrollableFrame,
|
||||
nsIFrame *aFrame, const nsIntPoint& aPoint);
|
||||
|
||||
/**
|
||||
* Converts scroll type constant defined in nsIAccessibleScrollType to
|
||||
* vertical and horizontal percents.
|
||||
*/
|
||||
static void ConvertScrollTypeToPercents(PRUint32 aScrollType,
|
||||
PRInt16 *aVPercent,
|
||||
PRInt16 *aHPercent);
|
||||
|
||||
/**
|
||||
* Converts the given coordinates to coordinates relative screen.
|
||||
*
|
||||
* @param aX [in] the given x coord
|
||||
* @param aY [in] the given y coord
|
||||
* @param aCoordinateType [in] specifies coordinates origin (refer to
|
||||
* nsIAccessibleCoordinateType)
|
||||
* @param aAccessNode [in] the accessible if coordinates are given
|
||||
* relative it.
|
||||
* @param aCoords [out] converted coordinates
|
||||
*/
|
||||
static nsresult ConvertToScreenCoords(PRInt32 aX, PRInt32 aY,
|
||||
PRUint32 aCoordinateType,
|
||||
nsIAccessNode *aAccessNode,
|
||||
nsIntPoint *aCoords);
|
||||
|
||||
/**
|
||||
* Converts the given coordinates relative screen to another coordinate
|
||||
* system.
|
||||
*
|
||||
* @param aX [in, out] the given x coord
|
||||
* @param aY [in, out] the given y coord
|
||||
* @param aCoordinateType [in] specifies coordinates origin (refer to
|
||||
* nsIAccessibleCoordinateType)
|
||||
* @param aAccessNode [in] the accessible if coordinates are given
|
||||
* relative it
|
||||
*/
|
||||
static nsresult ConvertScreenCoordsTo(PRInt32 *aX, PRInt32 *aY,
|
||||
PRUint32 aCoordinateType,
|
||||
nsIAccessNode *aAccessNode);
|
||||
|
||||
/**
|
||||
* Returns coordinates relative screen for the top level window.
|
||||
*
|
||||
* @param aNode the DOM node hosted in the window.
|
||||
*/
|
||||
static nsIntPoint GetScreenCoordsForWindow(nsIDOMNode *aNode);
|
||||
|
||||
/**
|
||||
* Returns coordinates relative screen for the top level window.
|
||||
*
|
||||
* @param aAccessNode the accessible hosted in the window
|
||||
*/
|
||||
static nsIntPoint GetScreenCoordsForWindow(nsIAccessNode *aAccessNode);
|
||||
|
||||
/**
|
||||
* Returns coordinates relative screen for the parent of the given accessible.
|
||||
*
|
||||
* @param aAccessNode the accessible
|
||||
*/
|
||||
static nsIntPoint GetScreenCoordsForParent(nsIAccessNode *aAccessNode);
|
||||
|
||||
/**
|
||||
* Return document shell tree item for the given DOM node.
|
||||
*/
|
||||
static already_AddRefed<nsIDocShellTreeItem>
|
||||
GetDocShellTreeItemFor(nsIDOMNode *aNode);
|
||||
|
||||
/**
|
||||
* Get the ID for an element, in some types of XML this may not be the ID attribute
|
||||
* @param aContent Node to get the ID for
|
||||
* @param aID Where to put ID string
|
||||
* @return PR_TRUE if there is an ID set for this node
|
||||
*/
|
||||
static PRBool GetID(nsIContent *aContent, nsAString& aID);
|
||||
|
||||
/**
|
||||
* Check if the given element is XLink.
|
||||
*
|
||||
* @param aContent the given element
|
||||
* @return PR_TRUE if the given element is XLink
|
||||
*/
|
||||
static PRBool IsXLink(nsIContent *aContent);
|
||||
|
||||
/**
|
||||
* 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 The DOM node to get the role map entry for
|
||||
* @return A pointer to the role map entry for the ARIA role, or nsnull if none
|
||||
*/
|
||||
static nsRoleMapEntry* GetRoleMapEntry(nsIDOMNode *aNode);
|
||||
|
||||
/**
|
||||
* Search element in neighborhood of the given element by tag name and
|
||||
* attribute value that equals to ID attribute of the given element.
|
||||
* ID attribute can be either 'id' attribute or 'anonid' if the element is
|
||||
* anonymous.
|
||||
* The first matched content will be returned.
|
||||
*
|
||||
* @param aForNode - the given element the search is performed for
|
||||
* @param aRelationAttrs - an array of attributes, element is attribute name of searched element, ignored if aAriaProperty passed in
|
||||
* @param aAttrNum - how many attributes in aRelationAttrs
|
||||
* @param aTagName - tag name of searched element, or nsnull for any -- ignored if aAriaProperty passed in
|
||||
* @param aAncestorLevelsToSearch - points how is the neighborhood of the
|
||||
* given element big.
|
||||
*/
|
||||
static nsIContent *FindNeighbourPointingToNode(nsIContent *aForNode,
|
||||
nsIAtom **aRelationAttrs,
|
||||
PRUint32 aAttrNum,
|
||||
nsIAtom *aTagName = nsnull,
|
||||
PRUint32 aAncestorLevelsToSearch = 5);
|
||||
|
||||
/**
|
||||
* Overloaded version of FindNeighbourPointingToNode to accept only one
|
||||
* relation attribute.
|
||||
*/
|
||||
static nsIContent *FindNeighbourPointingToNode(nsIContent *aForNode,
|
||||
nsIAtom *aRelationAttr,
|
||||
nsIAtom *aTagName = nsnull,
|
||||
PRUint32 aAncestorLevelsToSearch = 5);
|
||||
|
||||
/**
|
||||
* Search for element that satisfies the requirements in subtree of the given
|
||||
* element. The requirements are tag name, attribute name and value of
|
||||
* attribute.
|
||||
* The first matched content will be returned.
|
||||
*
|
||||
* @param aId - value of searched attribute
|
||||
* @param aLookContent - element that search is performed inside
|
||||
* @param aRelationAttrs - an array of searched attributes
|
||||
* @param aAttrNum - how many attributes in aRelationAttrs
|
||||
* @param if both aAriaProperty and aRelationAttrs are null, then any element with aTagType will do
|
||||
* @param aExcludeContent - element that is skiped for search
|
||||
* @param aTagType - tag name of searched element, by default it is 'label' --
|
||||
* ignored if aAriaProperty passed in
|
||||
*/
|
||||
static nsIContent *FindDescendantPointingToID(const nsString *aId,
|
||||
nsIContent *aLookContent,
|
||||
nsIAtom **aRelationAttrs,
|
||||
PRUint32 aAttrNum = 1,
|
||||
nsIContent *aExcludeContent = nsnull,
|
||||
nsIAtom *aTagType = nsAccessibilityAtoms::label);
|
||||
|
||||
/**
|
||||
* Overloaded version of FindDescendantPointingToID to accept only one
|
||||
* relation attribute.
|
||||
*/
|
||||
static nsIContent *FindDescendantPointingToID(const nsString *aId,
|
||||
nsIContent *aLookContent,
|
||||
nsIAtom *aRelationAttr,
|
||||
nsIContent *aExcludeContent = nsnull,
|
||||
nsIAtom *aTagType = nsAccessibilityAtoms::label);
|
||||
|
||||
// Helper for FindDescendantPointingToID(), same args
|
||||
static nsIContent *FindDescendantPointingToIDImpl(nsCString& aIdWithSpaces,
|
||||
nsIContent *aLookContent,
|
||||
nsIAtom **aRelationAttrs,
|
||||
PRUint32 aAttrNum = 1,
|
||||
nsIContent *aExcludeContent = nsnull,
|
||||
nsIAtom *aTagType = nsAccessibilityAtoms::label);
|
||||
|
||||
// Return PR_TRUE if the ARIA property should always be exposed as an object attribute
|
||||
static PRBool IsARIAPropForObjectAttr(nsIAtom *aAtom);
|
||||
|
||||
|
||||
/**
|
||||
* Get container-foo live region attributes for the given node
|
||||
* @param aAttributes Where to store the attributes
|
||||
* @param aStartContent Node to start from
|
||||
* @param aTopContent Node to end at
|
||||
*/
|
||||
static void GetLiveContainerAttributes(nsIPersistentProperties *aAttributes,
|
||||
nsIContent *aStartContent, nsIContent *aTopContent);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -67,6 +67,9 @@ class nsIDOMNode;
|
|||
class nsIAtom;
|
||||
class nsIView;
|
||||
|
||||
#define NS_OK_NO_ARIA_VALUE \
|
||||
NS_ERROR_GENERATE_SUCCESS(NS_ERROR_MODULE_GENERAL, 0x21)
|
||||
|
||||
// When mNextSibling is set to this, it indicates there ar eno more siblings
|
||||
#define DEAD_END_ACCESSIBLE static_cast<nsIAccessible*>((void*)1)
|
||||
|
||||
|
@ -111,7 +114,6 @@ public:
|
|||
NS_DECL_NSIACCESSIBLEVALUE
|
||||
|
||||
// nsIAccessNode
|
||||
NS_IMETHOD Init();
|
||||
NS_IMETHOD Shutdown();
|
||||
|
||||
/**
|
||||
|
@ -128,30 +130,22 @@ public:
|
|||
*/
|
||||
virtual nsresult GetAttributesInternal(nsIPersistentProperties *aAttributes);
|
||||
|
||||
/**
|
||||
* Maps ARIA state attributes to state of accessible. Note the given state
|
||||
* argument should hold states for accessible before you pass it into this
|
||||
* method.
|
||||
*/
|
||||
nsresult GetARIAState(PRUint32 *aState);
|
||||
|
||||
#ifdef MOZ_ACCESSIBILITY_ATK
|
||||
static PRBool FindTextFrame(PRInt32 &index, nsPresContext *aPresContext, nsIFrame *aCurFrame,
|
||||
nsIFrame **aFirstTextFrame, const nsIFrame *aTextFrame);
|
||||
#endif
|
||||
|
||||
#ifdef DEBUG_A11Y
|
||||
static PRBool IsTextInterfaceSupportCorrect(nsIAccessible *aAccessible);
|
||||
#endif
|
||||
|
||||
static PRBool IsCorrectFrameType(nsIFrame* aFrame, nsIAtom* aAtom);
|
||||
static PRUint32 State(nsIAccessible *aAcc) { PRUint32 state; aAcc->GetFinalState(&state, nsnull); return state; }
|
||||
static PRUint32 Role(nsIAccessible *aAcc) { PRUint32 role; aAcc->GetFinalRole(&role); return role; }
|
||||
static PRUint32 State(nsIAccessible *aAcc) { PRUint32 state = 0; if (aAcc) aAcc->GetFinalState(&state, nsnull); return state; }
|
||||
static PRUint32 Role(nsIAccessible *aAcc) { PRUint32 role = nsIAccessibleRole::ROLE_NOTHING; if (aAcc) aAcc->GetFinalRole(&role); return role; }
|
||||
static PRBool IsText(nsIAccessible *aAcc) { PRUint32 role = Role(aAcc); return role == nsIAccessibleRole::ROLE_TEXT_LEAF || role == nsIAccessibleRole::ROLE_STATICTEXT; }
|
||||
static PRBool IsEmbeddedObject(nsIAccessible *aAcc) { PRUint32 role = Role(aAcc); return role != nsIAccessibleRole::ROLE_TEXT_LEAF && role != nsIAccessibleRole::ROLE_WHITESPACE && role != nsIAccessibleRole::ROLE_STATICTEXT; }
|
||||
static PRInt32 TextLength(nsIAccessible *aAccessible);
|
||||
static PRInt32 TextLength(nsIAccessible *aAccessible); // Returns -1 on failure
|
||||
static PRBool IsLeaf(nsIAccessible *aAcc) { PRInt32 numChildren; aAcc->GetChildCount(&numChildren); return numChildren > 0; }
|
||||
static PRBool IsNodeRelevant(nsIDOMNode *aNode); // Is node something that could have an attached accessible
|
||||
/**
|
||||
* When exposing to platform accessibility APIs, should the children be pruned off?
|
||||
*/
|
||||
static PRBool MustPrune(nsIAccessible *aAccessible);
|
||||
|
||||
already_AddRefed<nsIAccessible> GetParent() {
|
||||
nsIAccessible *parent = nsnull;
|
||||
|
@ -159,6 +153,15 @@ public:
|
|||
return parent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the nsIContent* to check for ARIA attributes on -- this may not always
|
||||
* be the DOM node for the accessible. Specifically, for doc accessibles, it is not
|
||||
* the document node, but either the root element or <body> in HTML.
|
||||
* @param aDOMNode The DOM node for the accessible that may be affected by ARIA
|
||||
* @return The nsIContent which may have ARIA markup
|
||||
*/
|
||||
static nsIContent *GetRoleContent(nsIDOMNode *aDOMNode);
|
||||
|
||||
protected:
|
||||
PRBool MappedAttrState(nsIContent *aContent, PRUint32 *aStateInOut, nsStateMapEntry *aStateMapEntry);
|
||||
virtual nsIFrame* GetBoundsFrame();
|
||||
|
@ -166,67 +169,19 @@ protected:
|
|||
PRBool IsVisible(PRBool *aIsOffscreen);
|
||||
|
||||
// Relation helpers
|
||||
nsresult GetTextFromRelationID(nsIAtom *aIDAttrib, nsString &aName);
|
||||
|
||||
/**
|
||||
* Search element in neighborhood of the given element by tag name and
|
||||
* attribute value that equals to ID attribute of the current element.
|
||||
* ID attribute can be either 'id' attribute or 'anonid' if the element is
|
||||
* anonymous.
|
||||
* For a given ARIA relation, such as labelledby or describedby, get the collated text
|
||||
* for the subtree that's pointed to.
|
||||
*
|
||||
* @param aRelationAttr - attribute name of searched element
|
||||
* @param aRelationNamespaceID - namespace id of searched attribute, by default
|
||||
* empty namespace
|
||||
* @param aAncestorLevelsToSearch - points how is the neighborhood of the
|
||||
* given element big.
|
||||
* @param aIDProperty The ARIA relationship property to get the text for
|
||||
* @param aName Where to put the text
|
||||
* @return error or success code
|
||||
*/
|
||||
already_AddRefed<nsIDOMNode> FindNeighbourPointingToThis(nsIAtom *aRelationAttr,
|
||||
PRUint32 aRelationNameSpaceID = kNameSpaceID_None,
|
||||
PRUint32 aAncestorLevelsToSearch = 0);
|
||||
|
||||
/**
|
||||
* Search element in neighborhood of the given element by tag name and
|
||||
* attribute value that equals to ID attribute of the given element.
|
||||
* ID attribute can be either 'id' attribute or 'anonid' if the element is
|
||||
* anonymous.
|
||||
*
|
||||
* @param aForNode - the given element the search is performed for
|
||||
* @param aTagName - tag name of searched element
|
||||
* @param aRelationAttr - attribute name of searched element
|
||||
* @param aRelationNamespaceID - namespace id of searched attribute, by default
|
||||
* empty namespace
|
||||
* @param aAncestorLevelsToSearch - points how is the neighborhood of the
|
||||
* given element big.
|
||||
*/
|
||||
static nsIContent *FindNeighbourPointingToNode(nsIContent *aForNode,
|
||||
nsIAtom *aTagName,
|
||||
nsIAtom *aRelationAttr,
|
||||
PRUint32 aRelationNameSpaceID = kNameSpaceID_None,
|
||||
PRUint32 aAncestorLevelsToSearch = 5);
|
||||
|
||||
/**
|
||||
* Search for element that satisfies the requirements in subtree of the given
|
||||
* element. The requirements are tag name, attribute name and value of
|
||||
* attribute.
|
||||
*
|
||||
* @param aId - value of searched attribute
|
||||
* @param aLookContent - element that search is performed inside
|
||||
* @param aRelationAttr - searched attribute
|
||||
* @param aRelationNamespaceID - namespace id of searched attribute, by default
|
||||
* empty namespace
|
||||
* @param aExcludeContent - element that is skiped for search
|
||||
* @param aTagType - tag name of searched element, by default it is 'label'
|
||||
*/
|
||||
static nsIContent *FindDescendantPointingToID(const nsAString *aId,
|
||||
nsIContent *aLookContent,
|
||||
nsIAtom *aRelationAttr,
|
||||
PRUint32 aRelationNamespaceID = kNameSpaceID_None,
|
||||
nsIContent *aExcludeContent = nsnull,
|
||||
nsIAtom *aTagType = nsAccessibilityAtoms::label);
|
||||
nsresult GetTextFromRelationID(nsIAtom *aIDProperty, nsString &aName);
|
||||
|
||||
static nsIContent *GetHTMLLabelContent(nsIContent *aForNode);
|
||||
static nsIContent *GetLabelContent(nsIContent *aForNode);
|
||||
static nsIContent *GetRoleContent(nsIDOMNode *aDOMNode);
|
||||
|
||||
// Name helpers
|
||||
nsresult GetHTMLName(nsAString& _retval, PRBool aCanAggregateSubtree = PR_TRUE);
|
||||
|
@ -275,6 +230,22 @@ protected:
|
|||
// Check the visibility across both parent content and chrome
|
||||
PRBool CheckVisibilityInParentChain(nsIDocument* aDocument, nsIView* aView);
|
||||
|
||||
/**
|
||||
* Get the container node for an atomic region, defined by aria-atomic="true"
|
||||
* @return the container node
|
||||
*/
|
||||
nsIDOMNode* GetAtomicRegion();
|
||||
|
||||
/**
|
||||
* Get numeric value of the given ARIA attribute.
|
||||
*
|
||||
* @param aAriaProperty - the ARIA property we're using
|
||||
* @param aValue - value of the attribute
|
||||
*
|
||||
* @return - NS_OK_NO_ARIA_VALUE if there is no setted ARIA attribute
|
||||
*/
|
||||
nsresult GetAttrValue(nsIAtom *aAriaProperty, double *aValue);
|
||||
|
||||
// Data Members
|
||||
nsCOMPtr<nsIAccessible> mParent;
|
||||
nsIAccessible *mFirstChild, *mNextSibling;
|
||||
|
|
|
@ -37,26 +37,145 @@
|
|||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "nsAccessibleEventData.h"
|
||||
#include "nsAccessibilityAtoms.h"
|
||||
#include "nsIAccessibilityService.h"
|
||||
#include "nsIAccessNode.h"
|
||||
#include "nsIDocument.h"
|
||||
#include "nsIDOMDocument.h"
|
||||
#include "nsIEventStateManager.h"
|
||||
#include "nsIPersistentProperties2.h"
|
||||
#include "nsIServiceManager.h"
|
||||
#ifdef MOZ_XUL
|
||||
#include "nsIDOMXULMultSelectCntrlEl.h"
|
||||
#include "nsXULTreeAccessible.h"
|
||||
#endif
|
||||
#include "nsIAccessibleText.h"
|
||||
#include "nsIContent.h"
|
||||
#include "nsIPresShell.h"
|
||||
#include "nsPresContext.h"
|
||||
|
||||
NS_IMPL_ISUPPORTS1(nsAccEvent, nsIAccessibleEvent)
|
||||
PRBool nsAccEvent::gLastEventFromUserInput = PR_FALSE;
|
||||
nsIDOMNode* nsAccEvent::gLastEventNodeWeak = 0;
|
||||
|
||||
NS_IMPL_ISUPPORTS2(nsAccEvent, nsAccEvent, nsIAccessibleEvent)
|
||||
|
||||
nsAccEvent::nsAccEvent(PRUint32 aEventType, nsIAccessible *aAccessible,
|
||||
void *aEventData):
|
||||
mEventType(aEventType), mAccessible(aAccessible), mEventData(aEventData)
|
||||
PRBool aIsAsynch, EEventRule aEventRule):
|
||||
mEventType(aEventType), mAccessible(aAccessible), mEventRule(aEventRule)
|
||||
{
|
||||
CaptureIsFromUserInput(aIsAsynch);
|
||||
}
|
||||
|
||||
nsAccEvent::nsAccEvent(PRUint32 aEventType, nsIDOMNode *aDOMNode,
|
||||
void *aEventData):
|
||||
mEventType(aEventType), mDOMNode(aDOMNode), mEventData(aEventData)
|
||||
PRBool aIsAsynch, EEventRule aEventRule):
|
||||
mEventType(aEventType), mDOMNode(aDOMNode), mEventRule(aEventRule)
|
||||
{
|
||||
CaptureIsFromUserInput(aIsAsynch);
|
||||
}
|
||||
|
||||
void nsAccEvent::GetLastEventAttributes(nsIDOMNode *aNode,
|
||||
nsIPersistentProperties *aAttributes)
|
||||
{
|
||||
if (aNode == gLastEventNodeWeak) {
|
||||
// Only provide event-from-input for last event's node
|
||||
nsAutoString oldValueUnused;
|
||||
aAttributes->SetStringProperty(NS_LITERAL_CSTRING("event-from-input"),
|
||||
gLastEventFromUserInput ? NS_LITERAL_STRING("true") :
|
||||
NS_LITERAL_STRING("false"),
|
||||
oldValueUnused);
|
||||
}
|
||||
}
|
||||
|
||||
void nsAccEvent::CaptureIsFromUserInput(PRBool aIsAsynch)
|
||||
{
|
||||
nsCOMPtr<nsIDOMNode> eventNode;
|
||||
GetDOMNode(getter_AddRefs(eventNode));
|
||||
if (!eventNode) {
|
||||
NS_NOTREACHED("There should always be a DOM node for an event");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!aIsAsynch) {
|
||||
PrepareForEvent(eventNode);
|
||||
mIsFromUserInput = gLastEventFromUserInput;
|
||||
}
|
||||
// For asynch, cannot calculate if from user input.
|
||||
// Don't reset global last input state here, do it
|
||||
// at the end of FlushPendingEvents()
|
||||
|
||||
mIsFromUserInput = gLastEventFromUserInput;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsAccEvent::GetIsFromUserInput(PRBool *aIsFromUserInput)
|
||||
{
|
||||
*aIsFromUserInput = mIsFromUserInput;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsAccEvent::SetIsFromUserInput(PRBool aIsFromUserInput)
|
||||
{
|
||||
mIsFromUserInput = aIsFromUserInput;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void nsAccEvent::PrepareForEvent(nsIAccessibleEvent *aEvent,
|
||||
PRBool aForceIsFromUserInput)
|
||||
{
|
||||
gLastEventFromUserInput = aForceIsFromUserInput;
|
||||
nsCOMPtr<nsIDOMNode> eventNode;
|
||||
aEvent->GetDOMNode(getter_AddRefs(eventNode));
|
||||
if (!gLastEventFromUserInput) { // Caller is not forcing user input flag
|
||||
aEvent->GetIsFromUserInput(&gLastEventFromUserInput);
|
||||
if (!gLastEventFromUserInput) {
|
||||
// Event does not have user input flag set to true
|
||||
// One more try -- check to see if we are currently responding to user input
|
||||
PrepareForEvent(eventNode);
|
||||
}
|
||||
}
|
||||
gLastEventNodeWeak = eventNode;
|
||||
// Make sure this event remembers whether it is from user input
|
||||
aEvent->SetIsFromUserInput(gLastEventFromUserInput);
|
||||
}
|
||||
|
||||
void nsAccEvent::PrepareForEvent(nsIDOMNode *aEventNode,
|
||||
PRBool aForceIsFromUserInput)
|
||||
{
|
||||
if (!aEventNode) {
|
||||
return;
|
||||
}
|
||||
|
||||
gLastEventNodeWeak = aEventNode;
|
||||
if (aForceIsFromUserInput) {
|
||||
gLastEventFromUserInput = PR_TRUE;
|
||||
return;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIDOMDocument> domDoc;
|
||||
aEventNode->GetOwnerDocument(getter_AddRefs(domDoc));
|
||||
if (!domDoc) { // IF the node is a document itself
|
||||
domDoc = do_QueryInterface(aEventNode);
|
||||
}
|
||||
nsCOMPtr<nsIDocument> doc = do_QueryInterface(domDoc);
|
||||
if (!doc) {
|
||||
NS_NOTREACHED("There should always be a document for an event");
|
||||
return;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIPresShell> presShell = doc->GetPrimaryShell();
|
||||
if (!presShell) {
|
||||
NS_NOTREACHED("Threre should always be an pres shell for an event");
|
||||
return;
|
||||
}
|
||||
|
||||
nsIEventStateManager *esm = presShell->GetPresContext()->EventStateManager();
|
||||
if (!esm) {
|
||||
NS_NOTREACHED("There should always be an ESM for an event");
|
||||
return;
|
||||
}
|
||||
|
||||
gLastEventFromUserInput = esm->IsHandlingUserInputExternal();
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
|
@ -163,6 +282,94 @@ nsAccEvent::GetAccessibleByNode()
|
|||
return accessible;
|
||||
}
|
||||
|
||||
/* static */
|
||||
void
|
||||
nsAccEvent::ApplyEventRules(nsCOMArray<nsIAccessibleEvent> &aEventsToFire)
|
||||
{
|
||||
PRUint32 numQueuedEvents = aEventsToFire.Count();
|
||||
for (PRInt32 tail = numQueuedEvents - 1; tail >= 0; tail --) {
|
||||
nsRefPtr<nsAccEvent> tailEvent = GetAccEventPtr(aEventsToFire[tail]);
|
||||
switch(tailEvent->mEventRule) {
|
||||
case nsAccEvent::eCoalesceFromSameSubtree:
|
||||
{
|
||||
for (PRInt32 index = 0; index < tail; index ++) {
|
||||
nsRefPtr<nsAccEvent> thisEvent = GetAccEventPtr(aEventsToFire[index]);
|
||||
if (thisEvent->mEventType != tailEvent->mEventType)
|
||||
continue; // Different type
|
||||
|
||||
if (thisEvent->mEventRule == nsAccEvent::eAllowDupes ||
|
||||
thisEvent->mEventRule == nsAccEvent::eDoNotEmit)
|
||||
continue; // Do not need to check
|
||||
|
||||
if (thisEvent->mDOMNode == tailEvent->mDOMNode) {
|
||||
// Dupe
|
||||
thisEvent->mEventRule = nsAccEvent::eDoNotEmit;
|
||||
continue;
|
||||
}
|
||||
if (nsAccUtils::IsAncestorOf(tailEvent->mDOMNode,
|
||||
thisEvent->mDOMNode)) {
|
||||
// thisDOMNode is a descendant of tailDOMNode
|
||||
// Do not emit thisEvent, also apply this result to sibling
|
||||
// nodes of thisDOMNode.
|
||||
thisEvent->mEventRule = nsAccEvent::eDoNotEmit;
|
||||
ApplyToSiblings(aEventsToFire, 0, index, thisEvent->mEventType,
|
||||
thisEvent->mDOMNode, nsAccEvent::eDoNotEmit);
|
||||
continue;
|
||||
}
|
||||
if (nsAccUtils::IsAncestorOf(thisEvent->mDOMNode,
|
||||
tailEvent->mDOMNode)) {
|
||||
// tailDOMNode is a descendant of thisDOMNode
|
||||
// Do not emit tailEvent, also apply this result to sibling
|
||||
// nodes of tailDOMNode.
|
||||
tailEvent->mEventRule = nsAccEvent::eDoNotEmit;
|
||||
ApplyToSiblings(aEventsToFire, 0, tail, tailEvent->mEventType,
|
||||
tailEvent->mDOMNode, nsAccEvent::eDoNotEmit);
|
||||
break;
|
||||
}
|
||||
} // for (index)
|
||||
|
||||
if (tailEvent->mEventRule != nsAccEvent::eDoNotEmit) {
|
||||
// Not in another event node's subtree, and no other event is in
|
||||
// this event node's subtree.
|
||||
// This event should be emitted
|
||||
// Apply this result to sibling nodes of tailDOMNode
|
||||
ApplyToSiblings(aEventsToFire, 0, tail, tailEvent->mEventType,
|
||||
tailEvent->mDOMNode, nsAccEvent::eAllowDupes);
|
||||
}
|
||||
} break; // case eCoalesceFromSameSubtree
|
||||
|
||||
case nsAccEvent::eRemoveDupes:
|
||||
{
|
||||
// Check for repeat events.
|
||||
for (PRInt32 index = 0; index < tail; index ++) {
|
||||
nsRefPtr<nsAccEvent> accEvent = GetAccEventPtr(aEventsToFire[index]);
|
||||
if (accEvent->mEventType == tailEvent->mEventType &&
|
||||
accEvent->mEventRule == tailEvent->mEventRule &&
|
||||
accEvent->mDOMNode == tailEvent->mDOMNode) {
|
||||
accEvent->mEventRule = nsAccEvent::eDoNotEmit;
|
||||
}
|
||||
}
|
||||
} break; // case eRemoveDupes
|
||||
} // switch
|
||||
} // for (tail)
|
||||
}
|
||||
|
||||
/* static */
|
||||
void
|
||||
nsAccEvent::ApplyToSiblings(nsCOMArray<nsIAccessibleEvent> &aEventsToFire,
|
||||
PRUint32 aStart, PRUint32 aEnd,
|
||||
PRUint32 aEventType, nsIDOMNode* aDOMNode,
|
||||
EEventRule aEventRule)
|
||||
{
|
||||
for (PRUint32 index = aStart; index < aEnd; index ++) {
|
||||
nsRefPtr<nsAccEvent> accEvent = GetAccEventPtr(aEventsToFire[index]);
|
||||
if (accEvent->mEventType == aEventType &&
|
||||
accEvent->mEventRule != nsAccEvent::eDoNotEmit &&
|
||||
nsAccUtils::AreSiblings(accEvent->mDOMNode, aDOMNode)) {
|
||||
accEvent->mEventRule = aEventRule;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// nsAccStateChangeEvent
|
||||
NS_IMPL_ISUPPORTS_INHERITED1(nsAccStateChangeEvent, nsAccEvent,
|
||||
|
@ -172,7 +379,7 @@ nsAccStateChangeEvent::
|
|||
nsAccStateChangeEvent(nsIAccessible *aAccessible,
|
||||
PRUint32 aState, PRBool aIsExtraState,
|
||||
PRBool aIsEnabled):
|
||||
nsAccEvent(::nsIAccessibleEvent::EVENT_STATE_CHANGE, aAccessible, nsnull),
|
||||
nsAccEvent(::nsIAccessibleEvent::EVENT_STATE_CHANGE, aAccessible),
|
||||
mState(aState), mIsExtraState(aIsExtraState), mIsEnabled(aIsEnabled)
|
||||
{
|
||||
}
|
||||
|
@ -181,7 +388,7 @@ nsAccStateChangeEvent::
|
|||
nsAccStateChangeEvent(nsIDOMNode *aNode,
|
||||
PRUint32 aState, PRBool aIsExtraState,
|
||||
PRBool aIsEnabled):
|
||||
nsAccEvent(::nsIAccessibleEvent::EVENT_STATE_CHANGE, aNode, nsnull),
|
||||
nsAccEvent(::nsIAccessibleEvent::EVENT_STATE_CHANGE, aNode),
|
||||
mState(aState), mIsExtraState(aIsExtraState), mIsEnabled(aIsEnabled)
|
||||
{
|
||||
}
|
||||
|
@ -189,7 +396,7 @@ nsAccStateChangeEvent::
|
|||
nsAccStateChangeEvent::
|
||||
nsAccStateChangeEvent(nsIDOMNode *aNode,
|
||||
PRUint32 aState, PRBool aIsExtraState):
|
||||
nsAccEvent(::nsIAccessibleEvent::EVENT_STATE_CHANGE, aNode, nsnull),
|
||||
nsAccEvent(::nsIAccessibleEvent::EVENT_STATE_CHANGE, aNode),
|
||||
mState(aState), mIsExtraState(aIsExtraState)
|
||||
{
|
||||
// Use GetAccessibleByNode() because we do not want to store an accessible
|
||||
|
@ -198,7 +405,7 @@ nsAccStateChangeEvent::
|
|||
nsCOMPtr<nsIAccessible> accessible(GetAccessibleByNode());
|
||||
if (accessible) {
|
||||
PRUint32 state = 0, extraState = 0;
|
||||
accessible->GetFinalState(&state, &extraState);
|
||||
accessible->GetFinalState(&state, mIsExtraState ? &extraState : nsnull);
|
||||
mIsEnabled = ((mIsExtraState ? extraState : state) & mState) != 0;
|
||||
} else {
|
||||
mIsEnabled = PR_FALSE;
|
||||
|
@ -233,10 +440,16 @@ NS_IMPL_ISUPPORTS_INHERITED1(nsAccTextChangeEvent, nsAccEvent,
|
|||
|
||||
nsAccTextChangeEvent::
|
||||
nsAccTextChangeEvent(nsIAccessible *aAccessible,
|
||||
PRInt32 aStart, PRUint32 aLength, PRBool aIsInserted):
|
||||
nsAccEvent(::nsIAccessibleEvent::EVENT_TEXT_CHANGED, aAccessible, nsnull),
|
||||
PRInt32 aStart, PRUint32 aLength, PRBool aIsInserted, PRBool aIsAsynch):
|
||||
nsAccEvent(aIsInserted ? nsIAccessibleEvent::EVENT_TEXT_INSERTED : nsIAccessibleEvent::EVENT_TEXT_REMOVED,
|
||||
aAccessible, aIsAsynch),
|
||||
mStart(aStart), mLength(aLength), mIsInserted(aIsInserted)
|
||||
{
|
||||
nsCOMPtr<nsIAccessibleText> textAccessible = do_QueryInterface(aAccessible);
|
||||
NS_ASSERTION(textAccessible, "Should not be firing test change event for non-text accessible!!!");
|
||||
if (textAccessible) {
|
||||
textAccessible->GetText(aStart, aStart + aLength, mModifiedText);
|
||||
}
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
|
@ -260,20 +473,27 @@ nsAccTextChangeEvent::IsInserted(PRBool *aIsInserted)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsAccTextChangeEvent::GetModifiedText(nsAString& aModifiedText)
|
||||
{
|
||||
aModifiedText = mModifiedText;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// nsAccCaretMoveEvent
|
||||
NS_IMPL_ISUPPORTS_INHERITED1(nsAccCaretMoveEvent, nsAccEvent,
|
||||
nsIAccessibleCaretMoveEvent)
|
||||
|
||||
nsAccCaretMoveEvent::
|
||||
nsAccCaretMoveEvent(nsIAccessible *aAccessible, PRInt32 aCaretOffset) :
|
||||
nsAccEvent(::nsIAccessibleEvent::EVENT_TEXT_CARET_MOVED, aAccessible, nsnull),
|
||||
nsAccEvent(::nsIAccessibleEvent::EVENT_TEXT_CARET_MOVED, aAccessible, PR_TRUE), // Currently always asynch
|
||||
mCaretOffset(aCaretOffset)
|
||||
{
|
||||
}
|
||||
|
||||
nsAccCaretMoveEvent::
|
||||
nsAccCaretMoveEvent(nsIDOMNode *aNode) :
|
||||
nsAccEvent(::nsIAccessibleEvent::EVENT_TEXT_CARET_MOVED, aNode, nsnull),
|
||||
nsAccEvent(::nsIAccessibleEvent::EVENT_TEXT_CARET_MOVED, aNode, PR_TRUE), // Currently always asynch
|
||||
mCaretOffset(-1)
|
||||
{
|
||||
}
|
||||
|
@ -287,3 +507,33 @@ nsAccCaretMoveEvent::GetCaretOffset(PRInt32* aCaretOffset)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
// nsAccTableChangeEvent
|
||||
NS_IMPL_ISUPPORTS_INHERITED1(nsAccTableChangeEvent, nsAccEvent,
|
||||
nsIAccessibleTableChangeEvent)
|
||||
|
||||
nsAccTableChangeEvent::
|
||||
nsAccTableChangeEvent(nsIAccessible *aAccessible, PRUint32 aEventType,
|
||||
PRInt32 aRowOrColIndex, PRInt32 aNumRowsOrCols, PRBool aIsAsynch):
|
||||
nsAccEvent(aEventType, aAccessible, aIsAsynch),
|
||||
mRowOrColIndex(aRowOrColIndex), mNumRowsOrCols(aNumRowsOrCols)
|
||||
{
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsAccTableChangeEvent::GetRowOrColIndex(PRInt32* aRowOrColIndex)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aRowOrColIndex);
|
||||
|
||||
*aRowOrColIndex = mRowOrColIndex;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsAccTableChangeEvent::GetNumRowsOrCols(PRInt32* aNumRowsOrCols)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aNumRowsOrCols);
|
||||
|
||||
*aNumRowsOrCols = mNumRowsOrCols;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -41,37 +41,153 @@
|
|||
#ifndef _nsAccessibleEventData_H_
|
||||
#define _nsAccessibleEventData_H_
|
||||
|
||||
#include "nsAutoPtr.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsCOMArray.h"
|
||||
#include "nsIAccessibleEvent.h"
|
||||
#include "nsIAccessible.h"
|
||||
#include "nsIAccessibleDocument.h"
|
||||
#include "nsIDOMNode.h"
|
||||
#include "nsString.h"
|
||||
|
||||
class nsIPresShell;
|
||||
|
||||
#define NS_ACCEVENT_IMPL_CID \
|
||||
{ /* 55b89892-a83d-4252-ba78-cbdf53a86936 */ \
|
||||
0x55b89892, \
|
||||
0xa83d, \
|
||||
0x4252, \
|
||||
{ 0xba, 0x78, 0xcb, 0xdf, 0x53, 0xa8, 0x69, 0x36 } \
|
||||
}
|
||||
|
||||
class nsAccEvent: public nsIAccessibleEvent
|
||||
{
|
||||
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.
|
||||
eAllowDupes,
|
||||
// eCoalesceFromSameSubtree : For events of the same type from the same
|
||||
// subtree or the same node, only the umbrelle event on the ancestor
|
||||
// will be emitted.
|
||||
eCoalesceFromSameSubtree,
|
||||
// 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
|
||||
};
|
||||
|
||||
NS_DECLARE_STATIC_IID_ACCESSOR(NS_ACCEVENT_IMPL_CID)
|
||||
|
||||
// Initialize with an nsIAccessible
|
||||
nsAccEvent(PRUint32 aEventType, nsIAccessible *aAccessible, void *aEventData);
|
||||
nsAccEvent(PRUint32 aEventType, nsIAccessible *aAccessible,
|
||||
PRBool aIsAsynch = PR_FALSE,
|
||||
EEventRule aEventRule = eRemoveDupes);
|
||||
// Initialize with an nsIDOMNode
|
||||
nsAccEvent(PRUint32 aEventType, nsIDOMNode *aDOMNode, void *aEventData);
|
||||
nsAccEvent(PRUint32 aEventType, nsIDOMNode *aDOMNode,
|
||||
PRBool aIsAsynch = PR_FALSE,
|
||||
EEventRule aEventRule = eRemoveDupes);
|
||||
virtual ~nsAccEvent() {}
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSIACCESSIBLEEVENT
|
||||
|
||||
static void GetLastEventAttributes(nsIDOMNode *aNode,
|
||||
nsIPersistentProperties *aAttributes);
|
||||
|
||||
protected:
|
||||
already_AddRefed<nsIAccessible> GetAccessibleByNode();
|
||||
|
||||
void CaptureIsFromUserInput(PRBool aIsAsynch);
|
||||
PRBool mIsFromUserInput;
|
||||
|
||||
private:
|
||||
PRUint32 mEventType;
|
||||
EEventRule mEventRule;
|
||||
nsCOMPtr<nsIAccessible> mAccessible;
|
||||
nsCOMPtr<nsIDOMNode> mDOMNode;
|
||||
nsCOMPtr<nsIAccessibleDocument> mDocAccessible;
|
||||
|
||||
static PRBool gLastEventFromUserInput;
|
||||
static nsIDOMNode* gLastEventNodeWeak;
|
||||
|
||||
public:
|
||||
void *mEventData;
|
||||
static PRUint32 EventType(nsIAccessibleEvent *aAccEvent) {
|
||||
PRUint32 eventType;
|
||||
aAccEvent->GetEventType(&eventType);
|
||||
return eventType;
|
||||
}
|
||||
static EEventRule EventRule(nsIAccessibleEvent *aAccEvent) {
|
||||
nsRefPtr<nsAccEvent> accEvent = GetAccEventPtr(aAccEvent);
|
||||
return accEvent->mEventRule;
|
||||
}
|
||||
static PRBool IsFromUserInput(nsIAccessibleEvent *aAccEvent) {
|
||||
PRBool isFromUserInput;
|
||||
aAccEvent->GetIsFromUserInput(&isFromUserInput);
|
||||
return isFromUserInput;
|
||||
}
|
||||
|
||||
static void ResetLastInputState()
|
||||
{gLastEventFromUserInput = PR_FALSE; gLastEventNodeWeak = nsnull; }
|
||||
|
||||
/**
|
||||
* Find and cache the last input state. This will be called automatically
|
||||
* for synchronous events. For asynchronous events it should be
|
||||
* called from the synchronous code which is the true source of the event,
|
||||
* before the event is fired.
|
||||
* @param aChangeNode that event will be on
|
||||
* @param aForceIsFromUserInput PR_TRUE if the caller knows that this event was
|
||||
* caused by user input
|
||||
*/
|
||||
static void PrepareForEvent(nsIDOMNode *aChangeNode,
|
||||
PRBool aForceIsFromUserInput = PR_FALSE);
|
||||
|
||||
/**
|
||||
* The input state was previously stored with the nsIAccessibleEvent,
|
||||
* so use that state now -- call this when about to flush an event that
|
||||
* was waiting in an event queue
|
||||
*/
|
||||
static void PrepareForEvent(nsIAccessibleEvent *aEvent,
|
||||
PRBool aForceIsFromUserInput = PR_FALSE);
|
||||
|
||||
/**
|
||||
* Apply event rules to pending events, this method is called in
|
||||
* FlushingPendingEvents().
|
||||
* Result of this method:
|
||||
* Event rule of filtered events will be set to eDoNotEmit.
|
||||
* Events with other event rule are good to emit.
|
||||
*/
|
||||
static void ApplyEventRules(nsCOMArray<nsIAccessibleEvent> &aEventsToFire);
|
||||
|
||||
private:
|
||||
static already_AddRefed<nsAccEvent> GetAccEventPtr(nsIAccessibleEvent *aAccEvent) {
|
||||
nsAccEvent* accEvent = nsnull;
|
||||
aAccEvent->QueryInterface(NS_GET_IID(nsAccEvent), (void**)&accEvent);
|
||||
return accEvent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply aEventRule to same type event that from sibling nodes of aDOMNode.
|
||||
* @param aEventsToFire array of pending events
|
||||
* @param aStart start index of pending events to be scanned
|
||||
* @param aEnd end index to be scanned (not included)
|
||||
* @param aEventType target event type
|
||||
* @param aDOMNode target are siblings of this node
|
||||
* @param aEventRule the event rule to be applied
|
||||
* (should be eDoNotEmit or eAllowDupes)
|
||||
*/
|
||||
static void ApplyToSiblings(nsCOMArray<nsIAccessibleEvent> &aEventsToFire,
|
||||
PRUint32 aStart, PRUint32 aEnd,
|
||||
PRUint32 aEventType, nsIDOMNode* aDOMNode,
|
||||
EEventRule aEventRule);
|
||||
};
|
||||
|
||||
NS_DEFINE_STATIC_IID_ACCESSOR(nsAccEvent, NS_ACCEVENT_IMPL_CID)
|
||||
|
||||
class nsAccStateChangeEvent: public nsAccEvent,
|
||||
public nsIAccessibleStateChangeEvent
|
||||
{
|
||||
|
@ -101,8 +217,8 @@ class nsAccTextChangeEvent: public nsAccEvent,
|
|||
public nsIAccessibleTextChangeEvent
|
||||
{
|
||||
public:
|
||||
nsAccTextChangeEvent(nsIAccessible *aAccessible,
|
||||
PRInt32 aStart, PRUint32 aLength, PRBool aIsInserted);
|
||||
nsAccTextChangeEvent(nsIAccessible *aAccessible, PRInt32 aStart, PRUint32 aLength,
|
||||
PRBool aIsInserted, PRBool aIsAsynch = PR_FALSE);
|
||||
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
NS_FORWARD_NSIACCESSIBLEEVENT(nsAccEvent::)
|
||||
|
@ -112,6 +228,7 @@ private:
|
|||
PRInt32 mStart;
|
||||
PRUint32 mLength;
|
||||
PRBool mIsInserted;
|
||||
nsString mModifiedText;
|
||||
};
|
||||
|
||||
class nsAccCaretMoveEvent: public nsAccEvent,
|
||||
|
@ -129,12 +246,20 @@ private:
|
|||
PRInt32 mCaretOffset;
|
||||
};
|
||||
|
||||
// XXX todo: We might want to use XPCOM interfaces instead of struct
|
||||
// e.g., nsAccessibleTableChangeEvent: public nsIAccessibleTableChangeEvent
|
||||
class nsAccTableChangeEvent : public nsAccEvent,
|
||||
public nsIAccessibleTableChangeEvent {
|
||||
public:
|
||||
nsAccTableChangeEvent(nsIAccessible *aAccessible, PRUint32 aEventType,
|
||||
PRInt32 aRowOrColIndex, PRInt32 aNumRowsOrCols,
|
||||
PRBool aIsAsynch);
|
||||
|
||||
struct AtkTableChange {
|
||||
PRUint32 index; // the start row/column after which the rows are inserted/deleted.
|
||||
PRUint32 count; // the number of inserted/deleted rows/columns
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_FORWARD_NSIACCESSIBLEEVENT(nsAccEvent::)
|
||||
NS_DECL_NSIACCESSIBLETABLECHANGEEVENT
|
||||
|
||||
private:
|
||||
PRUint32 mRowOrColIndex; // the start row/column after which the rows are inserted/deleted.
|
||||
PRUint32 mNumRowsOrCols; // the number of inserted/deleted rows/columns
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -74,6 +74,9 @@ nsAccessibleRelation::GetTarget(PRUint32 aIndex, nsIAccessible **aTarget)
|
|||
{
|
||||
NS_ENSURE_ARG_POINTER(aTarget);
|
||||
|
||||
if (aIndex != 0)
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
|
||||
NS_IF_ADDREF(*aTarget = mTarget);
|
||||
return NS_OK;
|
||||
}
|
||||
|
|
|
@ -230,6 +230,7 @@ void nsAccessibleTreeWalker::UpdateFrame(PRBool aTryFirstChild)
|
|||
return;
|
||||
}
|
||||
if (aTryFirstChild) {
|
||||
nsIContent *containerContent = mState.frame->GetContent();
|
||||
mState.frame = mState.frame->GetFirstChild(nsnull);
|
||||
// temporary workaround for Bug 359210. We never want to walk frames.
|
||||
// Aaron Leventhal will refix :before and :after content later without walking frames.
|
||||
|
@ -253,6 +254,17 @@ void nsAccessibleTreeWalker::UpdateFrame(PRBool aTryFirstChild)
|
|||
mState.siblingIndex = eSiblingsWalkFrames;
|
||||
}
|
||||
#endif
|
||||
// Special case: <input type="file">
|
||||
// We should still need to walk frames inside the file control frame
|
||||
// This special case may turn into a more general rule after Firefox 3,
|
||||
// if HTML 5 controls use nsIAnonymousContentCreator
|
||||
if (containerContent->Tag() == nsAccessibilityAtoms::input &&
|
||||
containerContent->AttrValueIs(kNameSpaceID_None, nsAccessibilityAtoms::type,
|
||||
NS_LITERAL_STRING("file"), eIgnoreCase) &&
|
||||
mState.frame && mState.siblingIndex < 0) {
|
||||
mState.domNode = do_QueryInterface(mState.frame->GetContent());
|
||||
mState.siblingIndex = eSiblingsWalkFrames;
|
||||
}
|
||||
}
|
||||
else {
|
||||
mState.frame = mState.frame->GetNextSibling();
|
||||
|
|
|
@ -91,14 +91,6 @@ nsApplicationAccessible::GetName(nsAString& aName)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsApplicationAccessible::GetDescription(nsAString& aDescription)
|
||||
{
|
||||
GetName(aDescription);
|
||||
aDescription.AppendLiteral(" Application Accessible");
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsApplicationAccessible::GetRole(PRUint32 *aRole)
|
||||
{
|
||||
|
@ -180,6 +172,15 @@ nsApplicationAccessible::GetPreviousSibling(nsIAccessible **aPreviousSibling)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsApplicationAccessible::GetIndexInParent(PRInt32 *aIndexInParent)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aIndexInParent);
|
||||
|
||||
*aIndexInParent = -1;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
nsApplicationAccessible::CacheChildren()
|
||||
{
|
||||
|
@ -189,6 +190,7 @@ nsApplicationAccessible::CacheChildren()
|
|||
}
|
||||
|
||||
if (mAccChildCount == eChildCountUninitialized) {
|
||||
mAccChildCount = 0;// Prevent reentry
|
||||
nsCOMPtr<nsISimpleEnumerator> enumerator;
|
||||
mChildren->Enumerate(getter_AddRefs(enumerator));
|
||||
|
||||
|
|
|
@ -69,13 +69,13 @@ public:
|
|||
|
||||
// nsIAccessible
|
||||
NS_IMETHOD GetName(nsAString & aName);
|
||||
NS_IMETHOD GetDescription(nsAString & aDescription);
|
||||
NS_IMETHOD GetRole(PRUint32 *aRole);
|
||||
NS_IMETHOD GetFinalRole(PRUint32 *aFinalRole);
|
||||
NS_IMETHOD GetState(PRUint32 *aState, PRUint32 *aExtraState);
|
||||
NS_IMETHOD GetParent(nsIAccessible * *aParent);
|
||||
NS_IMETHOD GetNextSibling(nsIAccessible * *aNextSibling);
|
||||
NS_IMETHOD GetPreviousSibling(nsIAccessible **aPreviousSibling);
|
||||
NS_IMETHOD GetIndexInParent(PRInt32 *aIndexInParent);
|
||||
NS_IMETHOD GetChildAt(PRInt32 aChildNum, nsIAccessible **aChild);
|
||||
|
||||
// nsApplicationAccessible
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
*
|
||||
* Contributor(s):
|
||||
* John Gaunt (jgaunt@netscape.com)
|
||||
* Alexander Surkov <surkov.alexander@gmail.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either of the GNU General Public License Version 2 or later (the "GPL"),
|
||||
|
@ -42,6 +43,7 @@
|
|||
#include "nsIAccessibleDocument.h"
|
||||
#include "nsAccessibleWrap.h"
|
||||
#include "nsAccessibilityUtils.h"
|
||||
#include "nsIDOMNSHTMLElement.h"
|
||||
#include "nsGUIEvent.h"
|
||||
#include "nsHyperTextAccessibleWrap.h"
|
||||
#include "nsILink.h"
|
||||
|
@ -92,11 +94,11 @@ nsLeafAccessible::GetAllowsAnonChildAccessibles(PRBool *aAllowsAnonChildren)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
//----------------
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// nsLinkableAccessible
|
||||
//----------------
|
||||
|
||||
nsLinkableAccessible::nsLinkableAccessible(nsIDOMNode* aNode, nsIWeakReference* aShell) :
|
||||
nsLinkableAccessible::
|
||||
nsLinkableAccessible(nsIDOMNode* aNode, nsIWeakReference* aShell) :
|
||||
nsHyperTextAccessibleWrap(aNode, aShell),
|
||||
mActionContent(nsnull),
|
||||
mIsLink(PR_FALSE),
|
||||
|
@ -106,16 +108,19 @@ nsLinkableAccessible::nsLinkableAccessible(nsIDOMNode* aNode, nsIWeakReference*
|
|||
|
||||
NS_IMPL_ISUPPORTS_INHERITED0(nsLinkableAccessible, nsHyperTextAccessibleWrap)
|
||||
|
||||
NS_IMETHODIMP nsLinkableAccessible::TakeFocus()
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// nsLinkableAccessible. nsIAccessible
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsLinkableAccessible::TakeFocus()
|
||||
{
|
||||
if (mActionContent && mActionContent->IsFocusable()) {
|
||||
mActionContent->SetFocus(nsCOMPtr<nsPresContext>(GetPresContext()));
|
||||
}
|
||||
nsCOMPtr<nsIAccessible> actionAcc = GetActionAccessible();
|
||||
if (actionAcc)
|
||||
return actionAcc->TakeFocus();
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* long GetState (); */
|
||||
NS_IMETHODIMP
|
||||
nsLinkableAccessible::GetState(PRUint32 *aState, PRUint32 *aExtraState)
|
||||
{
|
||||
|
@ -124,58 +129,48 @@ nsLinkableAccessible::GetState(PRUint32 *aState, PRUint32 *aExtraState)
|
|||
|
||||
if (mIsLink) {
|
||||
*aState |= nsIAccessibleStates::STATE_LINKED;
|
||||
nsCOMPtr<nsILink> link = do_QueryInterface(mActionContent);
|
||||
if (link) {
|
||||
nsLinkState linkState;
|
||||
link->GetLinkState(linkState);
|
||||
if (linkState == eLinkState_Visited) {
|
||||
nsCOMPtr<nsIAccessible> actionAcc = GetActionAccessible();
|
||||
if (actionAcc && (State(actionAcc) & nsIAccessibleStates::STATE_TRAVERSED))
|
||||
*aState |= nsIAccessibleStates::STATE_TRAVERSED;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// XXX What if we're in a contenteditable container?
|
||||
// We may need to go up the parent chain unless a better API is found
|
||||
nsCOMPtr<nsIAccessible> docAccessible =
|
||||
do_QueryInterface(nsCOMPtr<nsIAccessibleDocument>(GetDocAccessible()));
|
||||
if (docAccessible) {
|
||||
PRUint32 docState = 0, docExtraState = 0;
|
||||
rv = docAccessible->GetFinalState(&docState, &docExtraState);
|
||||
if (NS_SUCCEEDED(rv) &&
|
||||
(docExtraState & nsIAccessibleStates::EXT_STATE_EDITABLE)) {
|
||||
// Links not focusable in editor
|
||||
*aState &= ~(nsIAccessibleStates::STATE_FOCUSED |
|
||||
nsIAccessibleStates::STATE_FOCUSABLE);
|
||||
}
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsLinkableAccessible::GetValue(nsAString& _retval)
|
||||
NS_IMETHODIMP
|
||||
nsLinkableAccessible::GetValue(nsAString& aValue)
|
||||
{
|
||||
aValue.Truncate();
|
||||
|
||||
nsHyperTextAccessible::GetValue(aValue);
|
||||
if (!aValue.IsEmpty())
|
||||
return NS_OK;
|
||||
|
||||
if (mIsLink) {
|
||||
nsCOMPtr<nsIDOMNode> linkNode(do_QueryInterface(mActionContent));
|
||||
nsCOMPtr<nsIPresShell> presShell(do_QueryReferent(mWeakShell));
|
||||
if (linkNode && presShell)
|
||||
return presShell->GetLinkLocation(linkNode, _retval);
|
||||
nsCOMPtr<nsIAccessible> actionAcc = GetActionAccessible();
|
||||
if (actionAcc)
|
||||
return actionAcc->GetValue(aValue);
|
||||
}
|
||||
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
|
||||
/* PRUint8 getAccNumActions (); */
|
||||
NS_IMETHODIMP nsLinkableAccessible::GetNumActions(PRUint8 *aNumActions)
|
||||
NS_IMETHODIMP
|
||||
nsLinkableAccessible::GetNumActions(PRUint8 *aNumActions)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aNumActions);
|
||||
|
||||
*aNumActions = mActionContent ? 1 : 0;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* nsAString GetActionName (in PRUint8 Aindex); */
|
||||
NS_IMETHODIMP nsLinkableAccessible::GetActionName(PRUint8 aIndex, nsAString& aName)
|
||||
NS_IMETHODIMP
|
||||
nsLinkableAccessible::GetActionName(PRUint8 aIndex, nsAString& aName)
|
||||
{
|
||||
// Action 0 (default action): Jump to link
|
||||
aName.Truncate();
|
||||
|
||||
// Action 0 (default action): Jump to link
|
||||
if (aIndex == eAction_Jump) {
|
||||
if (mIsLink) {
|
||||
aName.AssignLiteral("jump");
|
||||
|
@ -190,96 +185,125 @@ NS_IMETHODIMP nsLinkableAccessible::GetActionName(PRUint8 aIndex, nsAString& aNa
|
|||
return NS_ERROR_INVALID_ARG;
|
||||
}
|
||||
|
||||
/* void accDoAction (in PRUint8 index); */
|
||||
NS_IMETHODIMP nsLinkableAccessible::DoAction(PRUint8 index)
|
||||
NS_IMETHODIMP
|
||||
nsLinkableAccessible::DoAction(PRUint8 aIndex)
|
||||
{
|
||||
// Action 0 (default action): Jump to link
|
||||
if (index == eAction_Jump) {
|
||||
if (mActionContent) {
|
||||
return DoCommand(mActionContent);
|
||||
}
|
||||
}
|
||||
nsCOMPtr<nsIAccessible> actionAcc = GetActionAccessible();
|
||||
if (actionAcc)
|
||||
return actionAcc->DoAction(aIndex);
|
||||
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsLinkableAccessible::GetKeyboardShortcut(nsAString& aKeyboardShortcut)
|
||||
NS_IMETHODIMP
|
||||
nsLinkableAccessible::GetKeyboardShortcut(nsAString& aKeyboardShortcut)
|
||||
{
|
||||
if (mActionContent) {
|
||||
nsCOMPtr<nsIDOMNode> actionNode(do_QueryInterface(mActionContent));
|
||||
if (actionNode && mDOMNode != actionNode) {
|
||||
nsCOMPtr<nsIAccessible> accessible;
|
||||
nsCOMPtr<nsIAccessibilityService> accService =
|
||||
do_GetService("@mozilla.org/accessibilityService;1");
|
||||
accService->GetAccessibleInWeakShell(actionNode, mWeakShell,
|
||||
getter_AddRefs(accessible));
|
||||
if (accessible) {
|
||||
accessible->GetKeyboardShortcut(aKeyboardShortcut);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
aKeyboardShortcut.Truncate();
|
||||
|
||||
nsCOMPtr<nsIAccessible> actionAcc = GetActionAccessible();
|
||||
if (actionAcc)
|
||||
return actionAcc->GetKeyboardShortcut(aKeyboardShortcut);
|
||||
|
||||
return nsAccessible::GetKeyboardShortcut(aKeyboardShortcut);
|
||||
}
|
||||
|
||||
void nsLinkableAccessible::CacheActionContent()
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// nsLinkableAccessible. nsIAccessibleHyperLink
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsLinkableAccessible::GetURI(PRInt32 aIndex, nsIURI **aURI)
|
||||
{
|
||||
for (nsCOMPtr<nsIContent> walkUpContent(do_QueryInterface(mDOMNode));
|
||||
walkUpContent;
|
||||
walkUpContent = walkUpContent->GetParent()) {
|
||||
nsIAtom *tag = walkUpContent->Tag();
|
||||
if ((tag == nsAccessibilityAtoms::a || tag == nsAccessibilityAtoms::area) &&
|
||||
walkUpContent->IsNodeOfType(nsINode::eHTML)) {
|
||||
nsCOMPtr<nsILink> link = do_QueryInterface(walkUpContent);
|
||||
if (link) {
|
||||
// Currently we do not expose <link> tags, because they are not typically
|
||||
// in <body> and rendered.
|
||||
// We do not yet support xlinks
|
||||
nsCOMPtr<nsIURI> uri;
|
||||
link->GetHrefURI(getter_AddRefs(uri));
|
||||
if (uri) {
|
||||
mActionContent = walkUpContent;
|
||||
mIsLink = PR_TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (nsAccUtils::HasListener(walkUpContent, NS_LITERAL_STRING("click"))) {
|
||||
mActionContent = walkUpContent;
|
||||
mIsOnclick = PR_TRUE;
|
||||
break;
|
||||
}
|
||||
if (mIsLink) {
|
||||
nsCOMPtr<nsIAccessible> actionAcc = GetActionAccessible();
|
||||
if (actionAcc) {
|
||||
nsCOMPtr<nsIAccessibleHyperLink> hyperLinkAcc =
|
||||
do_QueryInterface(actionAcc);
|
||||
NS_ASSERTION(hyperLinkAcc,
|
||||
"nsIAccessibleHyperLink isn't implemented.");
|
||||
|
||||
if (hyperLinkAcc)
|
||||
return hyperLinkAcc->GetURI(aIndex, aURI);
|
||||
}
|
||||
}
|
||||
|
||||
// nsIAccessibleHyperLink::GetURI()
|
||||
NS_IMETHODIMP nsLinkableAccessible::GetURI(PRInt32 aIndex, nsIURI **aURI)
|
||||
{
|
||||
// XXX Also implement this for nsHTMLImageAccessible file names
|
||||
*aURI = nsnull;
|
||||
if (aIndex != 0 || !mIsLink || !SameCOMIdentity(mDOMNode, mActionContent)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsILink> link(do_QueryInterface(mActionContent));
|
||||
if (link) {
|
||||
return link->GetHrefURI(aURI);
|
||||
}
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// nsLinkableAccessible. nsPIAccessNode
|
||||
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsLinkableAccessible::Init()
|
||||
NS_IMETHODIMP
|
||||
nsLinkableAccessible::Init()
|
||||
{
|
||||
CacheActionContent();
|
||||
return nsHyperTextAccessibleWrap::Init();
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsLinkableAccessible::Shutdown()
|
||||
NS_IMETHODIMP
|
||||
nsLinkableAccessible::Shutdown()
|
||||
{
|
||||
mActionContent = nsnull;
|
||||
return nsHyperTextAccessibleWrap::Shutdown();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// nsLinkableAccessible
|
||||
|
||||
void
|
||||
nsLinkableAccessible::CacheActionContent()
|
||||
{
|
||||
nsCOMPtr<nsIContent> walkUpContent(do_QueryInterface(mDOMNode));
|
||||
PRBool isOnclick = nsAccUtils::HasListener(walkUpContent,
|
||||
NS_LITERAL_STRING("click"));
|
||||
|
||||
if (isOnclick) {
|
||||
mActionContent = walkUpContent;
|
||||
mIsOnclick = PR_TRUE;
|
||||
return;
|
||||
}
|
||||
|
||||
while ((walkUpContent = walkUpContent->GetParent())) {
|
||||
isOnclick = nsAccUtils::HasListener(walkUpContent,
|
||||
NS_LITERAL_STRING("click"));
|
||||
|
||||
nsCOMPtr<nsIDOMNode> walkUpNode(do_QueryInterface(walkUpContent));
|
||||
|
||||
nsCOMPtr<nsIAccessible> walkUpAcc;
|
||||
GetAccService()->GetAccessibleInWeakShell(walkUpNode, mWeakShell,
|
||||
getter_AddRefs(walkUpAcc));
|
||||
|
||||
if (walkUpAcc && Role(walkUpAcc) == nsIAccessibleRole::ROLE_LINK &&
|
||||
(State(walkUpAcc) & nsIAccessibleStates::STATE_LINKED)) {
|
||||
mIsLink = PR_TRUE;
|
||||
mActionContent = walkUpContent;
|
||||
return;
|
||||
}
|
||||
|
||||
if (isOnclick) {
|
||||
mActionContent = walkUpContent;
|
||||
mIsOnclick = PR_TRUE;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
already_AddRefed<nsIAccessible>
|
||||
nsLinkableAccessible::GetActionAccessible()
|
||||
{
|
||||
// Return accessible for the action content if it's different from node of
|
||||
// this accessible. If the action accessible is not null then it is used to
|
||||
// redirect methods calls otherwise we use method implementation from the
|
||||
// base class.
|
||||
nsCOMPtr<nsIDOMNode> actionNode(do_QueryInterface(mActionContent));
|
||||
if (!actionNode || mDOMNode == actionNode)
|
||||
return nsnull;
|
||||
|
||||
nsIAccessible *accessible = nsnull;
|
||||
GetAccService()->GetAccessibleInWeakShell(actionNode, mWeakShell,
|
||||
&accessible);
|
||||
return accessible;
|
||||
}
|
||||
|
||||
//---------------------
|
||||
// nsEnumRoleAccessible
|
||||
//---------------------
|
||||
|
|
|
@ -63,6 +63,8 @@ public:
|
|||
NS_IMETHOD GetLastChild(nsIAccessible **_retval);
|
||||
NS_IMETHOD GetChildCount(PRInt32 *_retval);
|
||||
NS_IMETHOD GetAllowsAnonChildAccessibles(PRBool *aAllowsAnonChildren);
|
||||
NS_IMETHOD GetChildAtPoint(PRInt32 aX, PRInt32 aY, nsIAccessible **aAccessible)
|
||||
{ NS_ENSURE_ARG_POINTER(aAccessible); NS_ADDREF(*aAccessible = this); return NS_OK; } // Don't walk into these
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -76,7 +78,10 @@ public:
|
|||
enum { eAction_Jump = 0 };
|
||||
|
||||
nsLinkableAccessible(nsIDOMNode* aNode, nsIWeakReference* aShell);
|
||||
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
|
||||
// nsIAccessible
|
||||
NS_IMETHOD GetNumActions(PRUint8 *_retval);
|
||||
NS_IMETHOD GetActionName(PRUint8 aIndex, nsAString& aName);
|
||||
NS_IMETHOD DoAction(PRUint8 index);
|
||||
|
@ -84,12 +89,25 @@ public:
|
|||
NS_IMETHOD GetValue(nsAString& _retval);
|
||||
NS_IMETHOD TakeFocus();
|
||||
NS_IMETHOD GetKeyboardShortcut(nsAString& _retval);
|
||||
|
||||
// nsIHyperLinkAccessible
|
||||
NS_IMETHOD GetURI(PRInt32 i, nsIURI **aURI);
|
||||
|
||||
// nsPIAccessNode
|
||||
NS_IMETHOD Init();
|
||||
NS_IMETHOD Shutdown();
|
||||
|
||||
protected:
|
||||
/**
|
||||
* Return an accessible for cached action node.
|
||||
*/
|
||||
already_AddRefed<nsIAccessible> GetActionAccessible();
|
||||
|
||||
/**
|
||||
* Cache action node.
|
||||
*/
|
||||
virtual void CacheActionContent();
|
||||
|
||||
nsCOMPtr<nsIContent> mActionContent;
|
||||
PRPackedBool mIsLink;
|
||||
PRPackedBool mIsOnclick;
|
||||
|
|
|
@ -73,20 +73,28 @@ void nsCaretAccessible::Shutdown()
|
|||
ClearControlSelectionListener(); // Clear the selection listener for the currently focused control
|
||||
mLastTextAccessible = nsnull;
|
||||
mLastUsedSelection = nsnull;
|
||||
mRootAccessible = nsnull;
|
||||
}
|
||||
|
||||
nsresult nsCaretAccessible::ClearControlSelectionListener()
|
||||
{
|
||||
nsCOMPtr<nsISelectionPrivate> selPrivate(do_QueryReferent(mCurrentControlSelection));
|
||||
NS_ENSURE_TRUE(selPrivate, NS_ERROR_FAILURE);
|
||||
|
||||
mCurrentControlSelection = nsnull;
|
||||
mCurrentControl = nsnull;
|
||||
mCurrentControlSelection = nsnull;
|
||||
|
||||
nsCOMPtr<nsISelectionPrivate> selPrivate(do_QueryReferent(mCurrentControlSelection));
|
||||
if (!selPrivate) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
return selPrivate->RemoveSelectionListener(this);
|
||||
}
|
||||
|
||||
nsresult nsCaretAccessible::SetControlSelectionListener(nsIDOMNode *aCurrentNode)
|
||||
{
|
||||
NS_ENSURE_TRUE(mRootAccessible, NS_ERROR_FAILURE);
|
||||
|
||||
ClearControlSelectionListener();
|
||||
|
||||
mCurrentControl = aCurrentNode;
|
||||
mLastTextAccessible = nsnull;
|
||||
|
||||
|
@ -120,7 +128,6 @@ nsresult nsCaretAccessible::SetControlSelectionListener(nsIDOMNode *aCurrentNode
|
|||
nsCOMPtr<nsISelection> domSel;
|
||||
selCon->GetSelection(nsISelectionController::SELECTION_NORMAL, getter_AddRefs(domSel));
|
||||
|
||||
ClearControlSelectionListener();
|
||||
nsCOMPtr<nsISelectionPrivate> selPrivate(do_QueryInterface(domSel));
|
||||
NS_ENSURE_TRUE(selPrivate, NS_ERROR_FAILURE);
|
||||
|
||||
|
@ -128,11 +135,12 @@ nsresult nsCaretAccessible::SetControlSelectionListener(nsIDOMNode *aCurrentNode
|
|||
return selPrivate->AddSelectionListener(this);
|
||||
}
|
||||
|
||||
nsresult nsCaretAccessible::AddDocSelectionListener(nsIDOMDocument *aDoc)
|
||||
nsresult
|
||||
nsCaretAccessible::AddDocSelectionListener(nsIPresShell *aShell)
|
||||
{
|
||||
nsCOMPtr<nsIDocument> doc = do_QueryInterface(aDoc);
|
||||
NS_ENSURE_TRUE(doc, NS_ERROR_FAILURE);
|
||||
nsCOMPtr<nsISelectionController> selCon = do_QueryInterface(doc->GetPrimaryShell());
|
||||
NS_ENSURE_TRUE(mRootAccessible, NS_ERROR_FAILURE);
|
||||
|
||||
nsCOMPtr<nsISelectionController> selCon = do_QueryInterface(aShell);
|
||||
NS_ENSURE_TRUE(selCon, NS_ERROR_FAILURE);
|
||||
|
||||
nsCOMPtr<nsISelection> domSel;
|
||||
|
@ -143,12 +151,10 @@ nsresult nsCaretAccessible::AddDocSelectionListener(nsIDOMDocument *aDoc)
|
|||
return selPrivate->AddSelectionListener(this);
|
||||
}
|
||||
|
||||
nsresult nsCaretAccessible::RemoveDocSelectionListener(nsIDOMDocument *aDoc)
|
||||
nsresult
|
||||
nsCaretAccessible::RemoveDocSelectionListener(nsIPresShell *aShell)
|
||||
{
|
||||
nsCOMPtr<nsIDocument> doc = do_QueryInterface(aDoc);
|
||||
NS_ENSURE_TRUE(doc, NS_ERROR_FAILURE);
|
||||
|
||||
nsCOMPtr<nsISelectionController> selCon = do_QueryInterface(doc->GetPrimaryShell());
|
||||
nsCOMPtr<nsISelectionController> selCon = do_QueryInterface(aShell);
|
||||
NS_ENSURE_TRUE(selCon, NS_ERROR_FAILURE);
|
||||
|
||||
nsCOMPtr<nsISelection> domSel;
|
||||
|
@ -161,13 +167,16 @@ nsresult nsCaretAccessible::RemoveDocSelectionListener(nsIDOMDocument *aDoc)
|
|||
|
||||
NS_IMETHODIMP nsCaretAccessible::NotifySelectionChanged(nsIDOMDocument *aDoc, nsISelection *aSel, PRInt16 aReason)
|
||||
{
|
||||
NS_ENSURE_TRUE(mRootAccessible, NS_ERROR_FAILURE);
|
||||
|
||||
mLastUsedSelection = do_GetWeakReference(aSel);
|
||||
|
||||
nsCOMPtr<nsIDocument> doc = do_QueryInterface(aDoc);
|
||||
NS_ENSURE_TRUE(doc, NS_OK);
|
||||
nsIPresShell *presShell = doc->GetPrimaryShell();
|
||||
NS_ENSURE_TRUE(presShell, NS_OK);
|
||||
|
||||
// Get first nnsIAccessibleText in parent chain and fire caret-move, selection-change event for it
|
||||
// Get first nsIAccessibleText in parent chain and fire caret-move, selection-change event for it
|
||||
nsCOMPtr<nsIAccessible> accessible;
|
||||
nsIAccessibilityService *accService = mRootAccessible->GetAccService();
|
||||
NS_ENSURE_TRUE(accService, NS_ERROR_FAILURE);
|
||||
|
@ -178,6 +187,20 @@ NS_IMETHODIMP nsCaretAccessible::NotifySelectionChanged(nsIDOMDocument *aDoc, ns
|
|||
mLastTextAccessible = nsnull;
|
||||
return NS_OK; // No selection
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIAccessibleDocument> docAccessible =
|
||||
nsAccessNode::GetDocAccessibleFor(focusNode);
|
||||
nsCOMPtr<nsIAccessible> accessibleForDoc =
|
||||
do_QueryInterface(docAccessible);
|
||||
if (!accessibleForDoc) {
|
||||
return NS_OK;
|
||||
}
|
||||
PRUint32 docState;
|
||||
accessibleForDoc->GetFinalState(&docState, nsnull);
|
||||
if (docState & nsIAccessibleStates::STATE_BUSY) {
|
||||
return NS_OK; // Don't fire caret moves until doc loaded
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIDOMNode> nodeWithCaret = focusNode;
|
||||
|
||||
nsCOMPtr<nsIAccessibleText> textAcc;
|
||||
|
@ -221,7 +244,7 @@ NS_IMETHODIMP nsCaretAccessible::NotifySelectionChanged(nsIDOMDocument *aDoc, ns
|
|||
new nsAccCaretMoveEvent(focusNode);
|
||||
NS_ENSURE_TRUE(event, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
return mRootAccessible->FireDelayedAccessibleEvent(event, PR_FALSE);
|
||||
return mRootAccessible->FireDelayedAccessibleEvent(event);
|
||||
}
|
||||
|
||||
nsRect
|
||||
|
@ -230,6 +253,7 @@ nsCaretAccessible::GetCaretRect(nsIWidget **aOutWidget)
|
|||
nsRect caretRect;
|
||||
NS_ENSURE_TRUE(aOutWidget, caretRect);
|
||||
*aOutWidget = nsnull;
|
||||
NS_ENSURE_TRUE(mRootAccessible, caretRect);
|
||||
|
||||
if (!mLastTextAccessible) {
|
||||
return caretRect; // Return empty rect
|
||||
|
@ -245,13 +269,15 @@ nsCaretAccessible::GetCaretRect(nsIWidget **aOutWidget)
|
|||
nsCOMPtr<nsIPresShell> presShell = mRootAccessible->GetPresShellFor(lastNodeWithCaret);
|
||||
NS_ENSURE_TRUE(presShell, caretRect);
|
||||
|
||||
nsICaret *caret;
|
||||
presShell->GetCaret(&caret);
|
||||
nsCOMPtr<nsICaret> caret;
|
||||
presShell->GetCaret(getter_AddRefs(caret));
|
||||
NS_ENSURE_TRUE(caret, caretRect);
|
||||
|
||||
PRBool isCollapsed;
|
||||
nsIView *view;
|
||||
nsCOMPtr<nsISelection> caretSelection(do_QueryReferent(mLastUsedSelection));
|
||||
NS_ENSURE_TRUE(caretSelection, caretRect);
|
||||
|
||||
caret->GetCaretCoordinates(nsICaret::eRenderingViewCoordinates, caretSelection,
|
||||
&caretRect, &isCollapsed, &view);
|
||||
if (!view || caretRect.IsEmpty()) {
|
||||
|
|
|
@ -103,17 +103,19 @@ public:
|
|||
* Start listening to selection events for a given document
|
||||
* More than one document's selection events can be listened to
|
||||
* at the same time, by a given nsCaretAccessible
|
||||
* @param aDocument Document to listen to selection events for.
|
||||
* @param aShell PresShell for document to listen to selection events from.
|
||||
*/
|
||||
nsresult AddDocSelectionListener(nsIDOMDocument *aDoc);
|
||||
nsresult AddDocSelectionListener(nsIPresShell *aShell);
|
||||
|
||||
/**
|
||||
* Stop listening to selection events for a given document
|
||||
* If the document goes away, this method needs to be called for
|
||||
* that document by the owner of the caret
|
||||
* @param aDocument Document to listen to selection events for.
|
||||
* that document by the owner of the caret. We use presShell because
|
||||
* instead of document because it is more direct than getting it from
|
||||
* the document, and in any case it is unavailable from the doc after a pagehide.
|
||||
* @param aShell PresShell for document to no longer listen to selection events from.
|
||||
*/
|
||||
nsresult RemoveDocSelectionListener(nsIDOMDocument *aDoc);
|
||||
nsresult RemoveDocSelectionListener(nsIPresShell *aShell);
|
||||
|
||||
nsRect GetCaretRect(nsIWidget **aOutWidget);
|
||||
|
||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -74,13 +74,14 @@ class nsDocAccessible : public nsHyperTextAccessibleWrap,
|
|||
virtual ~nsDocAccessible();
|
||||
|
||||
NS_IMETHOD GetRole(PRUint32 *aRole);
|
||||
NS_IMETHOD SetRoleMapEntry(nsRoleMapEntry* aRoleMapEntry);
|
||||
NS_IMETHOD GetName(nsAString& aName);
|
||||
NS_IMETHOD GetValue(nsAString& aValue);
|
||||
NS_IMETHOD GetDescription(nsAString& aDescription);
|
||||
NS_IMETHOD GetARIAState(PRUint32 *aState);
|
||||
NS_IMETHOD GetState(PRUint32 *aState, PRUint32 *aExtraState);
|
||||
NS_IMETHOD GetAttributes(nsIPersistentProperties **aAttributes);
|
||||
NS_IMETHOD GetFocusedChild(nsIAccessible **aFocusedChild);
|
||||
NS_IMETHOD GetParent(nsIAccessible **aParent);
|
||||
NS_IMETHOD GetAttributes(nsIPersistentProperties **aAttributes);
|
||||
NS_IMETHOD TakeFocus(void);
|
||||
|
||||
// ----- nsIScrollPositionListener ---------------------------
|
||||
|
@ -99,19 +100,33 @@ class nsDocAccessible : public nsHyperTextAccessibleWrap,
|
|||
// nsPIAccessNode
|
||||
NS_IMETHOD_(nsIFrame *) GetFrame(void);
|
||||
|
||||
// Non-virtual
|
||||
// nsIAccessibleText
|
||||
NS_IMETHOD GetAssociatedEditor(nsIEditor **aEditor);
|
||||
|
||||
/**
|
||||
* Non-virtual method to fire a delayed event after a 0 length timeout
|
||||
*
|
||||
* @param aEvent - the nsIAccessibleEvent event type
|
||||
* @param aDOMNode - DOM node the accesible event should be fired for
|
||||
* @param aAllowDupes - eAllowDupes: more than one event of the same type is allowed.
|
||||
* eCoalesceFromSameSubtree: if two events are in the same subtree,
|
||||
* only the event on ancestor is used
|
||||
* eRemoveDupes (default): events of the same type are discarded
|
||||
* (the last one is used)
|
||||
*
|
||||
* @param aIsAsynch - set to PR_TRUE if this is not being called from code
|
||||
* synchronous with a DOM event
|
||||
*/
|
||||
nsresult FireDelayedToolkitEvent(PRUint32 aEvent, nsIDOMNode *aDOMNode,
|
||||
void *aData, PRBool aAllowDupes = PR_FALSE);
|
||||
nsAccEvent::EEventRule aAllowDupes = nsAccEvent::eRemoveDupes,
|
||||
PRBool aIsAsynch = PR_FALSE);
|
||||
|
||||
/**
|
||||
* Fire accessible event in timeout.
|
||||
*
|
||||
* @param aAllowDupes - if false then delayed events of the same type and
|
||||
* for the same DOM node in the event queue won't
|
||||
* be fired.
|
||||
* @param aEvent - the event to fire
|
||||
*/
|
||||
nsresult FireDelayedAccessibleEvent(nsIAccessibleEvent *aEvent,
|
||||
PRBool aAllowDupes = PR_FALSE);
|
||||
nsresult FireDelayedAccessibleEvent(nsIAccessibleEvent *aEvent);
|
||||
|
||||
void ShutdownChildDocuments(nsIDocShellTreeItem *aStart);
|
||||
|
||||
|
@ -121,37 +136,93 @@ class nsDocAccessible : public nsHyperTextAccessibleWrap,
|
|||
virtual nsresult RemoveEventListeners();
|
||||
void AddScrollListener();
|
||||
void RemoveScrollListener();
|
||||
void RefreshNodes(nsIDOMNode *aStartNode, PRUint32 aChangeEvent);
|
||||
static void ScrollTimerCallback(nsITimer *aTimer, void *aClosure);
|
||||
void CheckForEditor();
|
||||
virtual void SetEditor(nsIEditor *aEditor);
|
||||
virtual already_AddRefed<nsIEditor> GetEditor() { nsIEditor *editor = mEditor; NS_IF_ADDREF(editor); return editor; }
|
||||
|
||||
/**
|
||||
* Fires accessible events when ARIA attribute is chaned.
|
||||
* For any accessibles in this subtree, invalidate their knowledge of
|
||||
* their children. Only weak refrences are destroyed, not accessibles.
|
||||
* @param aStartNode The root of the subrtee to invalidate accessible child refs in
|
||||
*/
|
||||
void InvalidateChildrenInSubtree(nsIDOMNode *aStartNode);
|
||||
void RefreshNodes(nsIDOMNode *aStartNode);
|
||||
static void ScrollTimerCallback(nsITimer *aTimer, void *aClosure);
|
||||
|
||||
/**
|
||||
* Fires accessible events when attribute is changed.
|
||||
*
|
||||
* @param aContent - node that attribute is changed for
|
||||
* @param aNameSpaceID - namespace of changed attribute
|
||||
* @param aAttribute - changed attribute
|
||||
*/
|
||||
void AttributeChangedImpl(nsIContent* aContent, PRInt32 aNameSpaceID, nsIAtom* aAttribute);
|
||||
|
||||
/**
|
||||
* Fires accessible events when ARIA attribute is changed.
|
||||
*
|
||||
* @param aContent - node that attribute is changed for
|
||||
* @param aAttribute - changed attribute
|
||||
*/
|
||||
void ARIAAttributeChanged(nsIContent* aContent, nsIAtom* aAttribute);
|
||||
|
||||
nsInterfaceHashtable<nsVoidHashKey, nsIAccessNode> mAccessNodeCache;
|
||||
/**
|
||||
* Fire text changed event for character data changed. The method is used
|
||||
* from nsIMutationObserver methods.
|
||||
*
|
||||
* @param aContent the text node holding changed data
|
||||
* @param aInfo info structure describing how the data was changed
|
||||
* @param aIsInserted the flag pointed whether removed or inserted
|
||||
* characters should be cause of event
|
||||
*/
|
||||
void FireTextChangeEventForText(nsIContent *aContent,
|
||||
CharacterDataChangeInfo* aInfo,
|
||||
PRBool aIsInserted);
|
||||
|
||||
/**
|
||||
* Create a text change event for a changed node
|
||||
* @param aContainerAccessible, the first accessible in the container
|
||||
* @param aChangeNode, the node that is being inserted or removed, or shown/hidden
|
||||
* @param aAccessibleForChangeNode, the accessible for that node, or nsnull if none exists
|
||||
* @param aIsInserting, is aChangeNode being created or shown (vs. removed or hidden)
|
||||
*/
|
||||
already_AddRefed<nsIAccessibleTextChangeEvent>
|
||||
CreateTextChangeEventForNode(nsIAccessible *aContainerAccessible,
|
||||
nsIDOMNode *aChangeNode,
|
||||
nsIAccessible *aAccessibleForNode,
|
||||
PRBool aIsInserting,
|
||||
PRBool aIsAsynch);
|
||||
|
||||
/**
|
||||
* Fire show/hide events for either the current node if it has an accessible,
|
||||
* or the first-line accessible descendants of the given node.
|
||||
*
|
||||
* @param aDOMNode the given node
|
||||
* @param aEventType event type to fire an event
|
||||
* @param aAvoidOnThisNode Call with PR_TRUE the first time to prevent event firing on root node for change
|
||||
* @param aDelay whether to fire the event on a delay
|
||||
* @param aForceIsFromUserInput the event is known to be from user input
|
||||
*/
|
||||
nsresult FireShowHideEvents(nsIDOMNode *aDOMNode, PRBool aAvoidOnThisNode, PRUint32 aEventType,
|
||||
PRBool aDelay, PRBool aForceIsFromUserInput);
|
||||
|
||||
/**
|
||||
* If the given accessible object is a ROLE_ENTRY, fire a value change event for it
|
||||
*/
|
||||
void FireValueChangeForTextFields(nsIAccessible *aPossibleTextFieldAccessible);
|
||||
|
||||
nsAccessNodeHashtable mAccessNodeCache;
|
||||
void *mWnd;
|
||||
nsCOMPtr<nsIDocument> mDocument;
|
||||
nsCOMPtr<nsITimer> mScrollWatchTimer;
|
||||
nsCOMPtr<nsITimer> mFireEventTimer;
|
||||
PRUint16 mScrollPositionChangedTicks; // Used for tracking scroll events
|
||||
PRPackedBool mIsContentLoaded;
|
||||
PRPackedBool mIsLoadCompleteFired;
|
||||
nsCOMArray<nsIAccessibleEvent> mEventsToFire;
|
||||
nsCOMPtr<nsIEditor> mEditor;
|
||||
|
||||
protected:
|
||||
PRBool mIsAnchor;
|
||||
PRBool mIsAnchorJumped;
|
||||
|
||||
private:
|
||||
static void DocLoadCallback(nsITimer *aTimer, void *aClosure);
|
||||
nsCOMPtr<nsITimer> mDocLoadTimer;
|
||||
static PRUint32 gLastFocusedAccessiblesState;
|
||||
static nsIAtom *gLastFocusedFrameType;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -52,29 +52,10 @@ nsOuterDocAccessible::nsOuterDocAccessible(nsIDOMNode* aNode,
|
|||
{
|
||||
}
|
||||
|
||||
/* attribute wstring accName; */
|
||||
NS_IMETHODIMP nsOuterDocAccessible::GetName(nsAString& aName)
|
||||
{
|
||||
nsCOMPtr<nsIAccessible> accessible;
|
||||
GetFirstChild(getter_AddRefs(accessible));
|
||||
nsCOMPtr<nsIAccessibleDocument> accDoc(do_QueryInterface(accessible));
|
||||
if (!accDoc) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
nsresult rv = accDoc->GetTitle(aName);
|
||||
if (NS_FAILED(rv) || aName.IsEmpty()) {
|
||||
rv = nsAccessible::GetName(aName);
|
||||
if (aName.IsEmpty()) {
|
||||
rv = accDoc->GetURL(aName);
|
||||
}
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
/* unsigned long getRole (); */
|
||||
NS_IMETHODIMP nsOuterDocAccessible::GetRole(PRUint32 *aRole)
|
||||
{
|
||||
*aRole = nsIAccessibleRole::ROLE_CLIENT;
|
||||
*aRole = nsIAccessibleRole::ROLE_INTERNAL_FRAME;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -86,6 +67,24 @@ nsOuterDocAccessible::GetState(PRUint32 *aState, PRUint32 *aExtraState)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsOuterDocAccessible::GetChildAtPoint(PRInt32 aX, PRInt32 aY,
|
||||
nsIAccessible **aAccessible)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aAccessible);
|
||||
*aAccessible = nsnull;
|
||||
if (!mDOMNode) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
PRInt32 docX, docY, docWidth, docHeight;
|
||||
GetBounds(&docX, &docY, &docWidth, &docHeight);
|
||||
if (aX < docX || aX >= docX + docWidth || aY < docY || aY >= docY + docHeight) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
return GetFirstChild(aAccessible); // Always return the inner doc unless bounds outside of it
|
||||
}
|
||||
|
||||
void nsOuterDocAccessible::CacheChildren()
|
||||
{
|
||||
// An outer doc accessible usually has 1 nsDocAccessible child,
|
||||
|
@ -98,7 +97,8 @@ void nsOuterDocAccessible::CacheChildren()
|
|||
return;
|
||||
}
|
||||
|
||||
SetFirstChild(nsnull);
|
||||
InvalidateChildren();
|
||||
mAccChildCount = 0;
|
||||
|
||||
// In these variable names, "outer" relates to the nsOuterDocAccessible
|
||||
// as opposed to the nsDocAccessibleWrap which is "inner".
|
||||
|
@ -110,14 +110,12 @@ void nsOuterDocAccessible::CacheChildren()
|
|||
|
||||
nsCOMPtr<nsIDocument> outerDoc = content->GetDocument();
|
||||
if (!outerDoc) {
|
||||
mAccChildCount = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
nsIDocument *innerDoc = outerDoc->GetSubDocumentFor(content);
|
||||
nsCOMPtr<nsIDOMNode> innerNode(do_QueryInterface(innerDoc));
|
||||
if (!innerNode) {
|
||||
mAccChildCount = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -128,7 +126,6 @@ void nsOuterDocAccessible::CacheChildren()
|
|||
nsCOMPtr<nsPIAccessible> privateInnerAccessible =
|
||||
do_QueryInterface(innerAccessible);
|
||||
if (!privateInnerAccessible) {
|
||||
mAccChildCount = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -139,3 +136,15 @@ void nsOuterDocAccessible::CacheChildren()
|
|||
privateInnerAccessible->SetNextSibling(nsnull);
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsOuterDocAccessible::GetAttributesInternal(nsIPersistentProperties *aAttributes)
|
||||
{
|
||||
nsAutoString tag;
|
||||
aAttributes->GetStringProperty(NS_LITERAL_CSTRING("tag"), tag);
|
||||
if (!tag.IsEmpty()) {
|
||||
// We're overriding the ARIA attributes on an sub document, but we don't want to
|
||||
// override the other attributes
|
||||
return NS_OK;
|
||||
}
|
||||
return nsAccessible::GetAttributesInternal(aAttributes);
|
||||
}
|
||||
|
|
|
@ -52,10 +52,12 @@ class nsOuterDocAccessible : public nsAccessibleWrap
|
|||
nsOuterDocAccessible(nsIDOMNode* aNode,
|
||||
nsIWeakReference* aShell);
|
||||
|
||||
NS_IMETHOD GetName(nsAString& aName);
|
||||
NS_IMETHOD GetRole(PRUint32 *aRole);
|
||||
NS_IMETHOD GetState(PRUint32 *aState, PRUint32 *aExtraState);
|
||||
NS_IMETHOD GetChildAtPoint(PRInt32 aX, PRInt32 aY,
|
||||
nsIAccessible **aAccessible);
|
||||
void CacheChildren();
|
||||
nsresult GetAttributesInternal(nsIPersistentProperties *aAttributes);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -53,6 +53,7 @@
|
|||
#include "nsIDOMHTMLImageElement.h"
|
||||
#include "nsIDOMHTMLInputElement.h"
|
||||
#include "nsIDOMHTMLSelectElement.h"
|
||||
#include "nsIDOMDataContainerEvent.h"
|
||||
#include "nsIDOMNSEvent.h"
|
||||
#include "nsIDOMXULMenuListElement.h"
|
||||
#include "nsIDOMXULMultSelectCntrlEl.h"
|
||||
|
@ -105,8 +106,7 @@ NS_IMPL_RELEASE_INHERITED(nsRootAccessible, nsDocAccessible)
|
|||
// construction
|
||||
//-----------------------------------------------------
|
||||
nsRootAccessible::nsRootAccessible(nsIDOMNode *aDOMNode, nsIWeakReference* aShell):
|
||||
nsDocAccessibleWrap(aDOMNode, aShell),
|
||||
mIsInDHTMLMenu(PR_FALSE)
|
||||
nsDocAccessibleWrap(aDOMNode, aShell)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -133,7 +133,7 @@ NS_IMETHODIMP nsRootAccessible::GetName(nsAString& aName)
|
|||
}
|
||||
|
||||
nsCOMPtr<nsIDocShellTreeItem> docShellAsItem =
|
||||
GetDocShellTreeItemFor(mDOMNode);
|
||||
nsAccUtils::GetDocShellTreeItemFor(mDOMNode);
|
||||
NS_ENSURE_TRUE(docShellAsItem, NS_ERROR_FAILURE);
|
||||
|
||||
nsCOMPtr<nsIDocShellTreeOwner> treeOwner;
|
||||
|
@ -192,7 +192,8 @@ PRUint32 nsRootAccessible::GetChromeFlags()
|
|||
// Return the flag set for the top level window as defined
|
||||
// by nsIWebBrowserChrome::CHROME_WINDOW_[FLAGNAME]
|
||||
// Not simple: nsIXULWindow is not just a QI from nsIDOMWindow
|
||||
nsCOMPtr<nsIDocShellTreeItem> treeItem = GetDocShellTreeItemFor(mDOMNode);
|
||||
nsCOMPtr<nsIDocShellTreeItem> treeItem =
|
||||
nsAccUtils::GetDocShellTreeItemFor(mDOMNode);
|
||||
NS_ENSURE_TRUE(treeItem, 0);
|
||||
nsCOMPtr<nsIDocShellTreeOwner> treeOwner;
|
||||
treeItem->GetTreeOwner(getter_AddRefs(treeOwner));
|
||||
|
@ -212,6 +213,8 @@ nsRootAccessible::GetState(PRUint32 *aState, PRUint32 *aExtraState)
|
|||
{
|
||||
nsresult rv = nsDocAccessibleWrap::GetState(aState, aExtraState);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
if (!mDOMNode)
|
||||
return NS_OK;
|
||||
|
||||
#ifdef MOZ_XUL
|
||||
PRUint32 chromeFlags = GetChromeFlags();
|
||||
|
@ -235,12 +238,14 @@ nsRootAccessible::GetState(PRUint32 *aState, PRUint32 *aExtraState)
|
|||
if (privateDOMWindow) {
|
||||
nsIFocusController *focusController =
|
||||
privateDOMWindow->GetRootFocusController();
|
||||
if (focusController) {
|
||||
PRBool isActive = PR_FALSE;
|
||||
focusController->GetActive(&isActive);
|
||||
if (isActive) {
|
||||
*aExtraState |= nsIAccessibleStates::EXT_STATE_ACTIVE;
|
||||
}
|
||||
}
|
||||
}
|
||||
#ifdef MOZ_XUL
|
||||
if (GetChromeFlags() & nsIWebBrowserChrome::CHROME_MODAL) {
|
||||
*aExtraState |= nsIAccessibleStates::EXT_STATE_MODAL;
|
||||
|
@ -268,18 +273,23 @@ nsRootAccessible::GetChromeEventHandler(nsIDOMEventTarget **aChromeTarget)
|
|||
}
|
||||
|
||||
const char* const docEvents[] = {
|
||||
#ifdef DEBUG
|
||||
// Capture mouse over events and fire fake DRAGDROPSTART event to simplify
|
||||
// debugging a11y objects with event viewers
|
||||
"mouseover",
|
||||
#endif
|
||||
// capture DOM focus events
|
||||
"focus",
|
||||
// capture Form change events
|
||||
"select",
|
||||
// capture NameChange events (fired whenever name changes, immediately after, whether focus moves or not)
|
||||
"NameChange",
|
||||
// capture ValueChange events (fired whenever value changes, immediately after, whether focus moves or not)
|
||||
"ValueChange",
|
||||
// capture AlertActive events (fired whenever alert pops up)
|
||||
"AlertActive",
|
||||
// add ourself as a TreeViewChanged listener (custom event fired in nsTreeBodyFrame.cpp)
|
||||
"TreeViewChanged",
|
||||
"TreeRowCountChanged",
|
||||
"TreeInvalidated",
|
||||
// add ourself as a OpenStateChange listener (custom event fired in tree.xml)
|
||||
"OpenStateChange",
|
||||
// add ourself as a CheckboxStateChange listener (custom event fired in nsHTMLInputElement.cpp)
|
||||
|
@ -323,14 +333,6 @@ nsresult nsRootAccessible::AddEventListeners()
|
|||
mCaretAccessible = new nsCaretAccessible(this);
|
||||
}
|
||||
|
||||
// Fire accessible focus event for pre-existing focus, but wait until all internal
|
||||
// focus events are finished for window initialization.
|
||||
mFireFocusTimer = do_CreateInstance("@mozilla.org/timer;1");
|
||||
if (mFireFocusTimer) {
|
||||
mFireFocusTimer->InitWithFuncCallback(FireFocusCallback, this,
|
||||
0, nsITimer::TYPE_ONE_SHOT);
|
||||
}
|
||||
|
||||
return nsDocAccessible::AddEventListeners();
|
||||
}
|
||||
|
||||
|
@ -351,12 +353,16 @@ nsresult nsRootAccessible::RemoveEventListeners()
|
|||
target->RemoveEventListener(NS_LITERAL_STRING("pagehide"), this, PR_TRUE);
|
||||
}
|
||||
|
||||
// Do this before removing clearing caret accessible, so that it can use
|
||||
// shutdown the caret accessible's selection listener
|
||||
nsDocAccessible::RemoveEventListeners();
|
||||
|
||||
if (mCaretAccessible) {
|
||||
mCaretAccessible->Shutdown();
|
||||
mCaretAccessible = nsnull;
|
||||
}
|
||||
|
||||
return nsDocAccessible::RemoveEventListeners();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsCaretAccessible*
|
||||
|
@ -378,7 +384,7 @@ void nsRootAccessible::TryFireEarlyLoadEvent(nsIDOMNode *aDocNode)
|
|||
// This also works for firing events for error pages
|
||||
|
||||
nsCOMPtr<nsIDocShellTreeItem> treeItem =
|
||||
GetDocShellTreeItemFor(aDocNode);
|
||||
nsAccUtils::GetDocShellTreeItemFor(aDocNode);
|
||||
NS_ASSERTION(treeItem, "No docshelltreeitem for aDocNode");
|
||||
if (!treeItem) {
|
||||
return;
|
||||
|
@ -388,6 +394,9 @@ void nsRootAccessible::TryFireEarlyLoadEvent(nsIDOMNode *aDocNode)
|
|||
if (itemType != nsIDocShellTreeItem::typeContent) {
|
||||
return;
|
||||
}
|
||||
|
||||
// The doc accessible should already be created as a result of the
|
||||
// OnStateChange() for the initiation of page loading
|
||||
nsCOMPtr<nsIDocShellTreeNode> treeNode(do_QueryInterface(treeItem));
|
||||
if (treeNode) {
|
||||
PRInt32 subDocuments;
|
||||
|
@ -399,33 +408,17 @@ void nsRootAccessible::TryFireEarlyLoadEvent(nsIDOMNode *aDocNode)
|
|||
nsCOMPtr<nsIDocShellTreeItem> rootContentTreeItem;
|
||||
treeItem->GetSameTypeRootTreeItem(getter_AddRefs(rootContentTreeItem));
|
||||
NS_ASSERTION(rootContentTreeItem, "No root content tree item");
|
||||
if (!rootContentTreeItem) { // Not at root of content
|
||||
return;
|
||||
}
|
||||
if (rootContentTreeItem != treeItem) {
|
||||
nsCOMPtr<nsIAccessibleDocument> rootContentDocAccessible =
|
||||
GetDocAccessibleFor(rootContentTreeItem);
|
||||
nsCOMPtr<nsIAccessible> rootContentAccessible =
|
||||
do_QueryInterface(rootContentDocAccessible);
|
||||
if (!rootContentAccessible) {
|
||||
return;
|
||||
}
|
||||
PRUint32 state = State(rootContentAccessible);
|
||||
if (state & nsIAccessibleStates::STATE_BUSY) {
|
||||
// Don't fire page load events on subdocuments for initial page load of entire page
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (rootContentTreeItem == treeItem) {
|
||||
// No frames or iframes, so we can fire the doc load finished event early
|
||||
FireDelayedToolkitEvent(nsIAccessibleEvent::EVENT_INTERNAL_LOAD, aDocNode,
|
||||
nsnull, PR_FALSE);
|
||||
FireDelayedToolkitEvent(nsIAccessibleEvent::EVENT_INTERNAL_LOAD, aDocNode);
|
||||
}
|
||||
}
|
||||
|
||||
PRBool nsRootAccessible::FireAccessibleFocusEvent(nsIAccessible *aAccessible,
|
||||
nsIDOMNode *aNode,
|
||||
nsIDOMEvent *aFocusEvent,
|
||||
PRBool aForceEvent)
|
||||
PRBool aForceEvent,
|
||||
PRBool aIsAsynch)
|
||||
{
|
||||
if (mCaretAccessible) {
|
||||
nsCOMPtr<nsIDOMNSEvent> nsevent(do_QueryInterface(aFocusEvent));
|
||||
|
@ -441,21 +434,30 @@ PRBool nsRootAccessible::FireAccessibleFocusEvent(nsIAccessible *aAccessible,
|
|||
nsCOMPtr<nsIDOMEventTarget> domEventTarget;
|
||||
nsevent->GetOriginalTarget(getter_AddRefs(domEventTarget));
|
||||
nsCOMPtr<nsIDOMNode> realFocusedNode(do_QueryInterface(domEventTarget));
|
||||
if (!realFocusedNode) {
|
||||
// When FireCurrentFocusEvent() synthesizes a focus event,
|
||||
// the orignal target does not exist, so use the passed-in node
|
||||
// which is the relevant focused node
|
||||
realFocusedNode = aNode;
|
||||
}
|
||||
if (realFocusedNode) {
|
||||
mCaretAccessible->SetControlSelectionListener(realFocusedNode);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Check for aaa:activedescendant, which changes which element has focus
|
||||
// Check for aria-activedescendant, which changes which element has focus
|
||||
nsCOMPtr<nsIDOMNode> finalFocusNode = aNode;
|
||||
nsCOMPtr<nsIAccessible> finalFocusAccessible = aAccessible;
|
||||
nsCOMPtr<nsIContent> finalFocusContent = do_QueryInterface(aNode);
|
||||
nsCOMPtr<nsIContent> finalFocusContent = GetRoleContent(finalFocusNode);
|
||||
if (finalFocusContent) {
|
||||
nsAutoString id;
|
||||
if (finalFocusContent->GetAttr(kNameSpaceID_WAIProperties, nsAccessibilityAtoms::activedescendant, id)) {
|
||||
if (finalFocusContent->GetAttr(kNameSpaceID_None, nsAccessibilityAtoms::aria_activedescendant, id)) {
|
||||
nsCOMPtr<nsIDOMDocument> domDoc;
|
||||
aNode->GetOwnerDocument(getter_AddRefs(domDoc));
|
||||
if (!domDoc) { // Maybe the passed-in node actually is a doc
|
||||
domDoc = do_QueryInterface(aNode);
|
||||
}
|
||||
if (!domDoc) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
@ -463,12 +465,11 @@ PRBool nsRootAccessible::FireAccessibleFocusEvent(nsIAccessible *aAccessible,
|
|||
domDoc->GetElementById(id, getter_AddRefs(relatedEl));
|
||||
finalFocusNode = do_QueryInterface(relatedEl);
|
||||
if (!finalFocusNode) {
|
||||
return PR_FALSE;
|
||||
// If aria-activedescendant is set to nonextistant ID, then treat as focus
|
||||
// on the activedescendant container (which has real DOM focus)
|
||||
finalFocusNode = aNode;
|
||||
}
|
||||
GetAccService()->GetAccessibleFor(finalFocusNode, getter_AddRefs(finalFocusAccessible));
|
||||
// For activedescendant, the ARIA spec does not require that the user agent
|
||||
// checks whether finalFocusNode is actually a descendant of the element with
|
||||
// the activedescendant attribute.
|
||||
finalFocusAccessible = nsnull;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -477,26 +478,57 @@ PRBool nsRootAccessible::FireAccessibleFocusEvent(nsIAccessible *aAccessible,
|
|||
return PR_FALSE;
|
||||
}
|
||||
|
||||
if (!finalFocusAccessible) {
|
||||
GetAccService()->GetAccessibleFor(finalFocusNode, getter_AddRefs(finalFocusAccessible));
|
||||
// For activedescendant, the ARIA spec does not require that the user agent
|
||||
// checks whether finalFocusNode is actually a descendant of the element with
|
||||
// the activedescendant attribute.
|
||||
if (!finalFocusAccessible) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
gLastFocusedAccessiblesState = State(finalFocusAccessible);
|
||||
PRUint32 role = Role(finalFocusAccessible);
|
||||
if (role == nsIAccessibleRole::ROLE_MENUITEM) {
|
||||
if (!mIsInDHTMLMenu) { // Entering menus
|
||||
if (!mCurrentARIAMenubar) { // Entering menus
|
||||
PRUint32 naturalRole; // The natural role is the role that this type of element normally has
|
||||
finalFocusAccessible->GetRole(&naturalRole);
|
||||
if (role != naturalRole) { // Must be a DHTML menuitem
|
||||
nsAccUtils::FireAccEvent(nsIAccessibleEvent::EVENT_MENU_START, this);
|
||||
mIsInDHTMLMenu = nsIAccessibleRole::ROLE_MENUITEM;
|
||||
nsCOMPtr<nsIAccessible> menuBarAccessible =
|
||||
nsAccUtils::GetAncestorWithRole(finalFocusAccessible, nsIAccessibleRole::ROLE_MENUBAR);
|
||||
nsCOMPtr<nsIAccessNode> menuBarAccessNode = do_QueryInterface(menuBarAccessible);
|
||||
if (menuBarAccessNode) {
|
||||
menuBarAccessNode->GetDOMNode(getter_AddRefs(mCurrentARIAMenubar));
|
||||
if (mCurrentARIAMenubar) {
|
||||
nsAccUtils::FireAccEvent(nsIAccessibleEvent::EVENT_MENU_START, menuBarAccessible);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (mIsInDHTMLMenu) {
|
||||
nsAccUtils::FireAccEvent(nsIAccessibleEvent::EVENT_MENU_END, this);
|
||||
mIsInDHTMLMenu = PR_FALSE;
|
||||
}
|
||||
}
|
||||
else if (mCurrentARIAMenubar) {
|
||||
nsCOMPtr<nsIAccessibleEvent> menuEndEvent =
|
||||
new nsAccEvent(nsIAccessibleEvent::EVENT_MENU_END, mCurrentARIAMenubar,
|
||||
PR_FALSE, nsAccEvent::eAllowDupes);
|
||||
if (menuEndEvent) {
|
||||
FireDelayedAccessibleEvent(menuEndEvent);
|
||||
}
|
||||
mCurrentARIAMenubar = nsnull;
|
||||
}
|
||||
|
||||
NS_IF_RELEASE(gLastFocusedNode);
|
||||
gLastFocusedNode = finalFocusNode;
|
||||
NS_IF_ADDREF(gLastFocusedNode);
|
||||
|
||||
nsCOMPtr<nsIContent> focusContent = do_QueryInterface(gLastFocusedNode);
|
||||
nsIFrame *focusFrame = nsnull;
|
||||
if (focusContent) {
|
||||
nsCOMPtr<nsIPresShell> shell = nsAccessNode::GetPresShellFor(gLastFocusedNode);
|
||||
focusFrame = shell->GetRealPrimaryFrameFor(focusContent);
|
||||
}
|
||||
gLastFocusedFrameType = (focusFrame && focusFrame->GetStyleVisibility()->IsVisible()) ? focusFrame->GetType() : 0;
|
||||
|
||||
nsCOMPtr<nsIAccessibleDocument> docAccessible = do_QueryInterface(finalFocusAccessible);
|
||||
if (docAccessible) {
|
||||
// Doc is gaining focus, but actual focus may be on an element within document
|
||||
|
@ -505,12 +537,14 @@ PRBool nsRootAccessible::FireAccessibleFocusEvent(nsIAccessible *aAccessible,
|
|||
// Suppress document focus, because real DOM focus will be fired next,
|
||||
// and that's what we care about
|
||||
// Make sure we never fire focus for the nsRootAccessible (mDOMNode)
|
||||
|
||||
return PR_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
FireDelayedToolkitEvent(nsIAccessibleEvent::EVENT_FOCUS,
|
||||
finalFocusNode, nsnull);
|
||||
finalFocusNode, nsAccEvent::eRemoveDupes,
|
||||
aIsAsynch);
|
||||
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
@ -564,6 +598,9 @@ nsresult nsRootAccessible::HandleEventWithTarget(nsIDOMEvent* aEvent,
|
|||
aEvent->GetType(eventType);
|
||||
nsAutoString localName;
|
||||
aTargetNode->GetLocalName(localName);
|
||||
#ifdef MOZ_XUL
|
||||
PRBool isTree = localName.EqualsLiteral("tree");
|
||||
#endif
|
||||
#ifdef DEBUG_A11Y
|
||||
// Very useful for debugging, please leave this here.
|
||||
if (eventType.EqualsLiteral("AlertActive")) {
|
||||
|
@ -574,11 +611,6 @@ nsresult nsRootAccessible::HandleEventWithTarget(nsIDOMEvent* aEvent,
|
|||
}
|
||||
#endif
|
||||
|
||||
nsCOMPtr<nsIPresShell> eventShell = GetPresShellFor(aTargetNode);
|
||||
if (!eventShell) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsIAccessibilityService *accService = GetAccService();
|
||||
NS_ENSURE_TRUE(accService, NS_ERROR_FAILURE);
|
||||
|
||||
|
@ -589,16 +621,20 @@ nsresult nsRootAccessible::HandleEventWithTarget(nsIDOMEvent* aEvent,
|
|||
// so that we don't destroy something still in use, like wizard page.
|
||||
// And we only get cached document accessible to destroy, so that we don't
|
||||
// create it just to destroy it.
|
||||
nsCOMPtr<nsIWeakReference> weakShell(do_GetWeakReference(eventShell));
|
||||
nsCOMPtr<nsIAccessible> accessible;
|
||||
accService->GetCachedAccessible(aTargetNode, weakShell, getter_AddRefs(accessible));
|
||||
nsCOMPtr<nsPIAccessibleDocument> privateAccDoc = do_QueryInterface(accessible);
|
||||
if (privateAccDoc) {
|
||||
privateAccDoc->Destroy();
|
||||
nsCOMPtr<nsIDocument> doc(do_QueryInterface(aTargetNode));
|
||||
nsCOMPtr<nsIAccessibleDocument> accDoc = GetDocAccessibleFor(doc);
|
||||
nsCOMPtr<nsPIAccessNode> privateAcc = do_QueryInterface(accDoc);
|
||||
if (privateAcc) {
|
||||
privateAcc->Shutdown();
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIPresShell> eventShell = GetPresShellFor(aTargetNode);
|
||||
if (!eventShell) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
if (eventType.EqualsLiteral("DOMContentLoaded")) {
|
||||
// Don't create the doc accessible until load scripts have a chance to set
|
||||
// role attribute for <body> or <html> element, because the value of
|
||||
|
@ -607,12 +643,31 @@ nsresult nsRootAccessible::HandleEventWithTarget(nsIDOMEvent* aEvent,
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
if (eventType.EqualsLiteral("TreeViewChanged")) {
|
||||
NS_ENSURE_TRUE(localName.EqualsLiteral("tree"), NS_OK);
|
||||
nsCOMPtr<nsIContent> treeContent = do_QueryInterface(aTargetNode);
|
||||
#ifdef MOZ_XUL
|
||||
if (eventType.EqualsLiteral("TreeViewChanged")) { // Always asynch, always from user input
|
||||
if (!isTree)
|
||||
return NS_OK;
|
||||
|
||||
nsCOMPtr<nsIContent> treeContent = do_QueryInterface(aTargetNode);
|
||||
nsAccEvent::PrepareForEvent(aTargetNode, PR_TRUE);
|
||||
return accService->InvalidateSubtreeFor(eventShell, treeContent,
|
||||
nsIAccessibleEvent::EVENT_REORDER);
|
||||
nsIAccessibleEvent::EVENT_DOM_SIGNIFICANT_CHANGE);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (eventType.EqualsLiteral("popuphiding")) {
|
||||
// If accessible focus was on or inside popup that closes,
|
||||
// then restore it to true current focus.
|
||||
// This is the case when we've been getting DOMMenuItemActive events
|
||||
// inside of a combo box that closes. The real focus is on the combo box.
|
||||
// It's also the case when a popup gets focus in ATK -- when it closes
|
||||
// we need to fire an event to restore focus to where it was
|
||||
if (!gLastFocusedNode ||
|
||||
!nsAccUtils::IsAncestorOf(aTargetNode, gLastFocusedNode)) {
|
||||
return NS_OK; // And was not focused on an item inside the popup
|
||||
}
|
||||
// Focus was on or inside of a popup that's being hidden
|
||||
FireCurrentFocusEvent();
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIAccessible> accessible;
|
||||
|
@ -622,6 +677,14 @@ nsresult nsRootAccessible::HandleEventWithTarget(nsIDOMEvent* aEvent,
|
|||
if (!privAcc)
|
||||
return NS_OK;
|
||||
|
||||
#ifdef MOZ_XUL
|
||||
if (eventType.EqualsLiteral("TreeRowCountChanged"))
|
||||
return HandleTreeRowCountChangedEvent(aEvent, accessible, localName);
|
||||
|
||||
if (eventType.EqualsLiteral("TreeInvalidated"))
|
||||
return HandleTreeInvalidatedEvent(aEvent, accessible, localName);
|
||||
#endif
|
||||
|
||||
if (eventType.EqualsLiteral("RadioStateChange")) {
|
||||
PRUint32 state = State(accessible);
|
||||
|
||||
|
@ -646,7 +709,7 @@ nsresult nsRootAccessible::HandleEventWithTarget(nsIDOMEvent* aEvent,
|
|||
if (eventType.EqualsLiteral("CheckboxStateChange")) {
|
||||
PRUint32 state = State(accessible);
|
||||
|
||||
PRBool isEnabled = state & nsIAccessibleStates::STATE_CHECKED;
|
||||
PRBool isEnabled = !!(state & nsIAccessibleStates::STATE_CHECKED);
|
||||
|
||||
nsCOMPtr<nsIAccessibleStateChangeEvent> accEvent =
|
||||
new nsAccStateChangeEvent(accessible,
|
||||
|
@ -659,7 +722,7 @@ nsresult nsRootAccessible::HandleEventWithTarget(nsIDOMEvent* aEvent,
|
|||
nsCOMPtr<nsIAccessible> treeItemAccessible;
|
||||
#ifdef MOZ_XUL
|
||||
// If it's a tree element, need the currently selected item
|
||||
if (localName.EqualsLiteral("tree")) {
|
||||
if (isTree) {
|
||||
nsCOMPtr<nsIDOMXULMultiSelectControlElement> multiSelect =
|
||||
do_QueryInterface(aTargetNode);
|
||||
if (multiSelect) {
|
||||
|
@ -715,6 +778,19 @@ nsresult nsRootAccessible::HandleEventWithTarget(nsIDOMEvent* aEvent,
|
|||
else
|
||||
#endif
|
||||
if (eventType.EqualsLiteral("focus")) {
|
||||
if (aTargetNode == mDOMNode && mDOMNode != gLastFocusedNode) {
|
||||
// Got focus event for the window, we will make sure that an accessible
|
||||
// focus event for initial focus is fired. We do this on a short timer
|
||||
// because the initial focus may not have been set yet.
|
||||
if (!mFireFocusTimer) {
|
||||
mFireFocusTimer = do_CreateInstance("@mozilla.org/timer;1");
|
||||
}
|
||||
if (mFireFocusTimer) {
|
||||
mFireFocusTimer->InitWithFuncCallback(FireFocusCallback, this,
|
||||
0, nsITimer::TYPE_ONE_SHOT);
|
||||
}
|
||||
}
|
||||
|
||||
// Keep a reference to the target node. We might want to change
|
||||
// it to the individual radio button or selected item, and send
|
||||
// the focus event to that.
|
||||
|
@ -746,9 +822,6 @@ nsresult nsRootAccessible::HandleEventWithTarget(nsIDOMEvent* aEvent,
|
|||
}
|
||||
FireAccessibleFocusEvent(accessible, focusedItem, aEvent);
|
||||
}
|
||||
else if (eventType.EqualsLiteral("NameChange")) {
|
||||
nsAccUtils::FireAccEvent(nsIAccessibleEvent::EVENT_NAME_CHANGE, accessible);
|
||||
}
|
||||
else if (eventType.EqualsLiteral("AlertActive")) {
|
||||
nsAccUtils::FireAccEvent(nsIAccessibleEvent::EVENT_ALERT, accessible);
|
||||
}
|
||||
|
@ -764,34 +837,12 @@ nsresult nsRootAccessible::HandleEventWithTarget(nsIDOMEvent* aEvent,
|
|||
// The accessible for it stays the same no matter where it moves.
|
||||
// AT's expect to get an EVENT_SHOW for the tooltip.
|
||||
// In event callback the tooltip's accessible will be ready.
|
||||
event = nsIAccessibleEvent::EVENT_SHOW;
|
||||
event = nsIAccessibleEvent::EVENT_ASYNCH_SHOW;
|
||||
}
|
||||
if (event) {
|
||||
nsAccUtils::FireAccEvent(event, accessible);
|
||||
}
|
||||
}
|
||||
|
||||
else if (eventType.EqualsLiteral("popuphiding")) {
|
||||
// If accessible focus was on or inside popup that closes,
|
||||
// then restore it to true current focus.
|
||||
// This is the case when we've been getting DOMMenuItemActive events
|
||||
// inside of a combo box that closes. The real focus is on the combo box.
|
||||
// It's also the case when a popup gets focus in ATK -- when it closes
|
||||
// we need to fire an event to restore focus to where it was
|
||||
if (!gLastFocusedNode) {
|
||||
return NS_OK;
|
||||
}
|
||||
if (gLastFocusedNode != aTargetNode) {
|
||||
// Was not focused on popup
|
||||
nsCOMPtr<nsIDOMNode> parentOfFocus;
|
||||
gLastFocusedNode->GetParentNode(getter_AddRefs(parentOfFocus));
|
||||
if (parentOfFocus != aTargetNode) {
|
||||
return NS_OK; // And was not focused on an item inside the popup
|
||||
}
|
||||
}
|
||||
// Focus was on or inside of a popup that's being hidden
|
||||
FireCurrentFocusEvent();
|
||||
}
|
||||
else if (eventType.EqualsLiteral("DOMMenuInactive")) {
|
||||
if (Role(accessible) == nsIAccessibleRole::ROLE_MENUPOPUP) {
|
||||
nsAccUtils::FireAccEvent(nsIAccessibleEvent::EVENT_MENUPOPUP_END,
|
||||
|
@ -799,42 +850,82 @@ nsresult nsRootAccessible::HandleEventWithTarget(nsIDOMEvent* aEvent,
|
|||
}
|
||||
}
|
||||
else if (eventType.EqualsLiteral("DOMMenuItemActive")) {
|
||||
PRBool fireFocus = PR_FALSE;
|
||||
if (!treeItemAccessible) {
|
||||
#ifdef MOZ_XUL
|
||||
if (isTree) {
|
||||
return NS_OK; // Tree with nothing selected
|
||||
}
|
||||
#endif
|
||||
nsCOMPtr<nsPIAccessNode> menuAccessNode = do_QueryInterface(accessible);
|
||||
NS_ENSURE_TRUE(menuAccessNode, NS_ERROR_FAILURE);
|
||||
nsIFrame* menuFrame = menuAccessNode->GetFrame();
|
||||
NS_ENSURE_TRUE(menuFrame, NS_ERROR_FAILURE);
|
||||
nsIMenuFrame* imenuFrame;
|
||||
CallQueryInterface(menuFrame, &imenuFrame);
|
||||
NS_ENSURE_TRUE(imenuFrame, NS_ERROR_FAILURE);
|
||||
if (imenuFrame->IsOnMenuBar()) {
|
||||
if (!imenuFrame->IsOnActiveMenuBar()) {
|
||||
if (imenuFrame)
|
||||
fireFocus = PR_TRUE;
|
||||
// QI failed for nsIMenuFrame means it's not on menu bar
|
||||
if (imenuFrame && imenuFrame->IsOnMenuBar() &&
|
||||
!imenuFrame->IsOnActiveMenuBar()) {
|
||||
// It is a top level menuitem. Only fire a focus event when the menu bar
|
||||
// is active.
|
||||
return NS_OK;
|
||||
}
|
||||
} else {
|
||||
nsCOMPtr<nsIAccessible> containerAccessible;
|
||||
accessible->GetParent(getter_AddRefs(containerAccessible));
|
||||
NS_ENSURE_TRUE(containerAccessible, NS_ERROR_FAILURE);
|
||||
// It is not top level menuitem
|
||||
// Only fire focus event if it is not inside collapsed popup
|
||||
if (State(containerAccessible) & nsIAccessibleStates::STATE_COLLAPSED)
|
||||
// and not a listitem of a combo box
|
||||
if (State(containerAccessible) & nsIAccessibleStates::STATE_COLLAPSED) {
|
||||
nsCOMPtr<nsIAccessible> containerParent;
|
||||
containerAccessible->GetParent(getter_AddRefs(containerParent));
|
||||
NS_ENSURE_TRUE(containerParent, NS_ERROR_FAILURE);
|
||||
if (Role(containerParent) != nsIAccessibleRole::ROLE_COMBOBOX) {
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
FireAccessibleFocusEvent(accessible, aTargetNode, aEvent, PR_TRUE);
|
||||
}
|
||||
else if (eventType.EqualsLiteral("DOMMenuBarActive")) {
|
||||
nsAccUtils::FireAccEvent(nsIAccessibleEvent::EVENT_MENU_START, accessible);
|
||||
}
|
||||
else if (eventType.EqualsLiteral("DOMMenuBarInactive")) {
|
||||
nsAccUtils::FireAccEvent(nsIAccessibleEvent::EVENT_MENU_END, accessible);
|
||||
if (!fireFocus) {
|
||||
nsCOMPtr<nsIDOMNode> realFocusedNode = GetCurrentFocus();
|
||||
nsCOMPtr<nsIContent> realFocusedContent = do_QueryInterface(realFocusedNode);
|
||||
nsCOMPtr<nsIContent> targetContent = do_QueryInterface(aTargetNode);
|
||||
nsIContent *containerContent = targetContent;
|
||||
while (containerContent) {
|
||||
nsCOMPtr<nsIDOMXULPopupElement> popup = do_QueryInterface(containerContent);
|
||||
if (popup || containerContent == realFocusedContent) {
|
||||
// If we're inside the focus or a popup we can fire focus events
|
||||
// for the changed active item
|
||||
fireFocus = PR_TRUE;
|
||||
break;
|
||||
}
|
||||
containerContent = containerContent->GetParent();
|
||||
}
|
||||
}
|
||||
if (fireFocus) {
|
||||
nsAccEvent::PrepareForEvent(aTargetNode, PR_TRUE); // Always asynch, always from user input
|
||||
FireAccessibleFocusEvent(accessible, aTargetNode, aEvent, PR_TRUE, PR_TRUE);
|
||||
}
|
||||
}
|
||||
else if (eventType.EqualsLiteral("DOMMenuBarActive")) { // Always asynch, always from user input
|
||||
nsAccEvent::PrepareForEvent(aTargetNode, PR_TRUE);
|
||||
nsAccUtils::FireAccEvent(nsIAccessibleEvent::EVENT_MENU_START, accessible, PR_TRUE);
|
||||
}
|
||||
else if (eventType.EqualsLiteral("DOMMenuBarInactive")) { // Always asynch, always from user input
|
||||
nsAccEvent::PrepareForEvent(aTargetNode, PR_TRUE);
|
||||
nsAccUtils::FireAccEvent(nsIAccessibleEvent::EVENT_MENU_END, accessible, PR_TRUE);
|
||||
FireCurrentFocusEvent();
|
||||
}
|
||||
else if (eventType.EqualsLiteral("ValueChange")) {
|
||||
nsAccUtils::FireAccEvent(nsIAccessibleEvent::EVENT_VALUE_CHANGE, accessible);
|
||||
FireDelayedToolkitEvent(nsIAccessibleEvent::EVENT_VALUE_CHANGE, aTargetNode, nsAccEvent::eRemoveDupes);
|
||||
}
|
||||
#ifdef DEBUG
|
||||
else if (eventType.EqualsLiteral("mouseover")) {
|
||||
nsAccUtils::FireAccEvent(nsIAccessibleEvent::EVENT_DRAGDROP_START, accessible);
|
||||
}
|
||||
#endif
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -886,15 +977,18 @@ nsRootAccessible::Init()
|
|||
|
||||
NS_IMETHODIMP nsRootAccessible::Shutdown()
|
||||
{
|
||||
// Called manually or by nsAccessNode::LastRelease()
|
||||
if (!mWeakShell) {
|
||||
return NS_OK; // Already shutdown
|
||||
}
|
||||
|
||||
nsRefPtr<nsApplicationAccessibleWrap> root = GetApplicationAccessible();
|
||||
NS_ENSURE_STATE(root);
|
||||
|
||||
root->RemoveRootAccessible(this);
|
||||
|
||||
// Called manually or by nsAccessNode::LastRelease()
|
||||
if (!mWeakShell) {
|
||||
return NS_OK; // Already shutdown
|
||||
}
|
||||
mCurrentARIAMenubar = nsnull;
|
||||
|
||||
if (mFireFocusTimer) {
|
||||
mFireFocusTimer->Cancel();
|
||||
mFireFocusTimer = nsnull;
|
||||
|
@ -925,6 +1019,9 @@ nsRootAccessible::GetContentDocShell(nsIDocShellTreeItem *aStart)
|
|||
}
|
||||
nsCOMPtr<nsIAccessible> ancestor;
|
||||
accessible->GetParent(getter_AddRefs(ancestor));
|
||||
if (ancestor == this) {
|
||||
break; // Don't check past original root accessible we started with
|
||||
}
|
||||
accessible.swap(ancestor);
|
||||
}
|
||||
|
||||
|
@ -958,7 +1055,8 @@ NS_IMETHODIMP nsRootAccessible::GetAccessibleRelated(PRUint32 aRelationType,
|
|||
return nsDocAccessibleWrap::GetAccessibleRelated(aRelationType, aRelated);
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIDocShellTreeItem> treeItem = GetDocShellTreeItemFor(mDOMNode);
|
||||
nsCOMPtr<nsIDocShellTreeItem> treeItem =
|
||||
nsAccUtils::GetDocShellTreeItemFor(mDOMNode);
|
||||
nsCOMPtr<nsIDocShellTreeItem> contentTreeItem = GetContentDocShell(treeItem);
|
||||
// there may be no content area, so we need a null check
|
||||
if (contentTreeItem) {
|
||||
|
@ -979,7 +1077,7 @@ NS_IMETHODIMP nsRootAccessible::FireDocLoadEvents(PRUint32 aEventType)
|
|||
}
|
||||
|
||||
nsCOMPtr<nsIDocShellTreeItem> docShellTreeItem =
|
||||
nsAccessNode::GetDocShellTreeItemFor(mDOMNode);
|
||||
nsAccUtils::GetDocShellTreeItemFor(mDOMNode);
|
||||
NS_ASSERTION(docShellTreeItem, "No doc shell tree item for document");
|
||||
NS_ENSURE_TRUE(docShellTreeItem, NS_ERROR_FAILURE);
|
||||
PRInt32 contentType;
|
||||
|
@ -994,3 +1092,82 @@ NS_IMETHODIMP nsRootAccessible::FireDocLoadEvents(PRUint32 aEventType)
|
|||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsRootAccessible::HandleTreeRowCountChangedEvent(nsIDOMEvent *aEvent,
|
||||
nsIAccessible *aAccessible,
|
||||
const nsAString& aTargetName)
|
||||
{
|
||||
if (!aTargetName.EqualsLiteral("tree"))
|
||||
return NS_OK;
|
||||
|
||||
nsCOMPtr<nsIDOMDataContainerEvent> dataEvent(do_QueryInterface(aEvent));
|
||||
if (!dataEvent)
|
||||
return NS_OK;
|
||||
|
||||
nsCOMPtr<nsIVariant> indexVariant;
|
||||
dataEvent->GetData(NS_LITERAL_STRING("index"),
|
||||
getter_AddRefs(indexVariant));
|
||||
if (!indexVariant)
|
||||
return NS_OK;
|
||||
|
||||
nsCOMPtr<nsIVariant> countVariant;
|
||||
dataEvent->GetData(NS_LITERAL_STRING("count"),
|
||||
getter_AddRefs(countVariant));
|
||||
if (!countVariant)
|
||||
return NS_OK;
|
||||
|
||||
PRInt32 index, count;
|
||||
indexVariant->GetAsInt32(&index);
|
||||
countVariant->GetAsInt32(&count);
|
||||
|
||||
nsCOMPtr<nsIAccessibleTreeCache> treeAccCache(do_QueryInterface(aAccessible));
|
||||
NS_ENSURE_STATE(treeAccCache);
|
||||
|
||||
return treeAccCache->InvalidateCache(index, count);
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsRootAccessible::HandleTreeInvalidatedEvent(nsIDOMEvent *aEvent,
|
||||
nsIAccessible *aAccessible,
|
||||
const nsAString& aTargetName)
|
||||
{
|
||||
if (!aTargetName.EqualsLiteral("tree"))
|
||||
return NS_OK;
|
||||
|
||||
nsCOMPtr<nsIDOMDataContainerEvent> dataEvent(do_QueryInterface(aEvent));
|
||||
if (!dataEvent)
|
||||
return NS_OK;
|
||||
|
||||
PRInt32 startRow = 0, endRow = -1, startCol = 0, endCol = -1;
|
||||
|
||||
nsCOMPtr<nsIVariant> startRowVariant;
|
||||
dataEvent->GetData(NS_LITERAL_STRING("startrow"),
|
||||
getter_AddRefs(startRowVariant));
|
||||
if (startRowVariant)
|
||||
startRowVariant->GetAsInt32(&startRow);
|
||||
|
||||
nsCOMPtr<nsIVariant> endRowVariant;
|
||||
dataEvent->GetData(NS_LITERAL_STRING("endrow"),
|
||||
getter_AddRefs(endRowVariant));
|
||||
if (endRowVariant)
|
||||
endRowVariant->GetAsInt32(&endRow);
|
||||
|
||||
nsCOMPtr<nsIVariant> startColVariant;
|
||||
dataEvent->GetData(NS_LITERAL_STRING("startcolumn"),
|
||||
getter_AddRefs(startColVariant));
|
||||
if (startColVariant)
|
||||
startColVariant->GetAsInt32(&startCol);
|
||||
|
||||
nsCOMPtr<nsIVariant> endColVariant;
|
||||
dataEvent->GetData(NS_LITERAL_STRING("endcolumn"),
|
||||
getter_AddRefs(endColVariant));
|
||||
if (endColVariant)
|
||||
endColVariant->GetAsInt32(&endCol);
|
||||
|
||||
nsCOMPtr<nsIAccessibleTreeCache> treeAcc(do_QueryInterface(aAccessible));
|
||||
NS_ENSURE_STATE(treeAcc);
|
||||
|
||||
return treeAcc->TreeViewInvalidated(startRow, endRow, startCol, endCol);
|
||||
}
|
||||
|
||||
|
|
|
@ -101,7 +101,8 @@ class nsRootAccessible : public nsDocAccessibleWrap,
|
|||
PRBool FireAccessibleFocusEvent(nsIAccessible *aFocusAccessible,
|
||||
nsIDOMNode *aFocusNode,
|
||||
nsIDOMEvent *aFocusEvent,
|
||||
PRBool aForceEvent = PR_FALSE);
|
||||
PRBool aForceEvent = PR_FALSE,
|
||||
PRBool aIsAsynch = PR_FALSE);
|
||||
|
||||
nsCaretAccessible *GetCaretAccessible();
|
||||
|
||||
|
@ -118,13 +119,28 @@ class nsRootAccessible : public nsDocAccessibleWrap,
|
|||
void TryFireEarlyLoadEvent(nsIDOMNode *aDocNode);
|
||||
void FireCurrentFocusEvent();
|
||||
void GetChromeEventHandler(nsIDOMEventTarget **aChromeTarget);
|
||||
|
||||
/**
|
||||
* Handles 'TreeRowCountChanged' event. Used in HandleEventWithTarget().
|
||||
*/
|
||||
nsresult HandleTreeRowCountChangedEvent(nsIDOMEvent *aEvent,
|
||||
nsIAccessible *aAccessible,
|
||||
const nsAString& aTargetName);
|
||||
|
||||
/**
|
||||
* Handles 'TreeInvalidated' event. Used in HandleEventWithTarget().
|
||||
*/
|
||||
nsresult HandleTreeInvalidatedEvent(nsIDOMEvent *aEvent,
|
||||
nsIAccessible *aAccessible,
|
||||
const nsAString& aTargetName);
|
||||
|
||||
#ifdef MOZ_XUL
|
||||
PRUint32 GetChromeFlags();
|
||||
#endif
|
||||
already_AddRefed<nsIDocShellTreeItem>
|
||||
GetContentDocShell(nsIDocShellTreeItem *aStart);
|
||||
nsRefPtr<nsCaretAccessible> mCaretAccessible;
|
||||
PRPackedBool mIsInDHTMLMenu;
|
||||
nsCOMPtr<nsIDOMNode> mCurrentARIAMenubar;
|
||||
};
|
||||
|
||||
NS_DEFINE_STATIC_IID_ACCESSOR(nsRootAccessible, NS_ROOTACCESSIBLE_IMPL_CID)
|
||||
|
|
|
@ -50,7 +50,10 @@ nsLinkableAccessible(aDOMNode, aShell)
|
|||
{
|
||||
}
|
||||
|
||||
NS_IMPL_ISUPPORTS_INHERITED0(nsTextAccessible, nsLinkableAccessible)
|
||||
// Make sure we don't support text or other irrelevant interfaces.
|
||||
// We have nsLinkableAccessible in our inheritance chain as a convenience in order to
|
||||
// get link actions and states on the text accessibles. Windows screen readers expect that.
|
||||
NS_IMPL_ISUPPORTS_INHERITED2(nsTextAccessible, nsAccessNode, nsIAccessible, nsPIAccessible)
|
||||
|
||||
/**
|
||||
* We are text
|
||||
|
@ -89,16 +92,11 @@ NS_IMETHODIMP nsTextAccessible::GetChildCount(PRInt32 *_retval)
|
|||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsTextAccessible::GetContentText(nsAString& aText)
|
||||
nsTextAccessible::AppendTextTo(nsAString& aText, PRUint32 aStartOffset, PRUint32 aLength)
|
||||
{
|
||||
nsresult rv = nsLinkableAccessible::GetContentText(aText);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsIFrame *frame = GetFrame();
|
||||
if (!frame)
|
||||
return NS_OK;
|
||||
NS_ENSURE_TRUE(frame, NS_ERROR_FAILURE);
|
||||
|
||||
frame->GetContent()->AppendTextTo(aText);
|
||||
return NS_OK;
|
||||
return frame->GetRenderedText(&aText, nsnull, nsnull, aStartOffset, aLength);
|
||||
}
|
||||
|
||||
|
|
|
@ -60,7 +60,7 @@ public:
|
|||
NS_IMETHOD GetChildCount(PRInt32 *_retval);
|
||||
|
||||
// nsPIAccessible
|
||||
NS_IMETHOD GetContentText(nsAString& aText);
|
||||
NS_IMETHOD AppendTextTo(nsAString& aText, PRUint32 aStartOffset, PRUint32 aLength);
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -47,20 +47,25 @@ MODULE = accessibility
|
|||
LIBRARY_NAME = accessibility_html_s
|
||||
LIBXUL_LIBRARY = 1
|
||||
|
||||
REQUIRES = content \
|
||||
REQUIRES = composer \
|
||||
content \
|
||||
docshell \
|
||||
dom \
|
||||
editor \
|
||||
gfx \
|
||||
imglib2 \
|
||||
intl \
|
||||
js \
|
||||
layout \
|
||||
locale \
|
||||
necko \
|
||||
string \
|
||||
thebes \
|
||||
view \
|
||||
webshell \
|
||||
widget \
|
||||
xpcom \
|
||||
xpconnect \
|
||||
$(NULL)
|
||||
|
||||
ifeq ($(MOZ_WIDGET_TOOLKIT),gtk2)
|
||||
|
|
|
@ -37,7 +37,6 @@
|
|||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "nsHTMLAreaAccessible.h"
|
||||
#include "nsIAccessibilityService.h"
|
||||
#include "nsIServiceManager.h"
|
||||
#include "nsIDOMElement.h"
|
||||
#include "nsIDOMHTMLAreaElement.h"
|
||||
|
@ -46,28 +45,36 @@
|
|||
#include "nsIImageMap.h"
|
||||
|
||||
|
||||
// --- area -----
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// nsHTMLAreaAccessible
|
||||
|
||||
nsHTMLAreaAccessible::nsHTMLAreaAccessible(nsIDOMNode *aDomNode, nsIAccessible *aParent, nsIWeakReference* aShell):
|
||||
nsLinkableAccessible(aDomNode, aShell)
|
||||
nsHTMLAreaAccessible::
|
||||
nsHTMLAreaAccessible(nsIDOMNode *aDomNode, nsIAccessible *aParent,
|
||||
nsIWeakReference* aShell):
|
||||
nsHTMLLinkAccessible(aDomNode, aShell)
|
||||
{
|
||||
}
|
||||
|
||||
/* wstring getName (); */
|
||||
NS_IMETHODIMP nsHTMLAreaAccessible::GetName(nsAString & aName)
|
||||
{
|
||||
nsCOMPtr<nsIContent> content(do_QueryInterface(mDOMNode));
|
||||
if (!content) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// nsIAccessible
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsHTMLAreaAccessible::GetName(nsAString & aName)
|
||||
{
|
||||
aName.Truncate();
|
||||
|
||||
if (IsDefunct())
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
if (mRoleMapEntry) {
|
||||
nsresult rv = nsAccessible::GetName(aName);
|
||||
if (!aName.IsEmpty()) {
|
||||
return rv;
|
||||
}
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
if (!aName.IsEmpty())
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIContent> content(do_QueryInterface(mDOMNode));
|
||||
if (!content->GetAttr(kNameSpaceID_None, nsAccessibilityAtoms::alt,
|
||||
aName) &&
|
||||
!content->GetAttr(kNameSpaceID_None, nsAccessibilityAtoms::title,
|
||||
|
@ -78,47 +85,49 @@ NS_IMETHODIMP nsHTMLAreaAccessible::GetName(nsAString & aName)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
/* unsigned long getRole (); */
|
||||
NS_IMETHODIMP nsHTMLAreaAccessible::GetRole(PRUint32 *_retval)
|
||||
NS_IMETHODIMP
|
||||
nsHTMLAreaAccessible::GetDescription(nsAString& aDescription)
|
||||
{
|
||||
*_retval = nsIAccessibleRole::ROLE_LINK;
|
||||
return NS_OK;
|
||||
}
|
||||
aDescription.Truncate();
|
||||
|
||||
/* wstring getDescription (); */
|
||||
NS_IMETHODIMP nsHTMLAreaAccessible::GetDescription(nsAString& _retval)
|
||||
{
|
||||
// Still to do - follow IE's standard here
|
||||
nsCOMPtr<nsIDOMHTMLAreaElement> area(do_QueryInterface(mDOMNode));
|
||||
if (area)
|
||||
area->GetShape(_retval);
|
||||
area->GetShape(aDescription);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
/* nsIAccessible getFirstChild (); */
|
||||
NS_IMETHODIMP nsHTMLAreaAccessible::GetFirstChild(nsIAccessible **_retval)
|
||||
NS_IMETHODIMP
|
||||
nsHTMLAreaAccessible::GetFirstChild(nsIAccessible **aChild)
|
||||
{
|
||||
*_retval = nsnull;
|
||||
NS_ENSURE_ARG_POINTER(aChild);
|
||||
|
||||
*aChild = nsnull;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* nsIAccessible getLastChild (); */
|
||||
NS_IMETHODIMP nsHTMLAreaAccessible::GetLastChild(nsIAccessible **_retval)
|
||||
NS_IMETHODIMP
|
||||
nsHTMLAreaAccessible::GetLastChild(nsIAccessible **aChild)
|
||||
{
|
||||
*_retval = nsnull;
|
||||
NS_ENSURE_ARG_POINTER(aChild);
|
||||
|
||||
*aChild = nsnull;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* long getAccChildCount (); */
|
||||
NS_IMETHODIMP nsHTMLAreaAccessible::GetChildCount(PRInt32 *_retval)
|
||||
NS_IMETHODIMP
|
||||
nsHTMLAreaAccessible::GetChildCount(PRInt32 *aCount)
|
||||
{
|
||||
*_retval = 0;
|
||||
NS_ENSURE_ARG_POINTER(aCount);
|
||||
|
||||
*aCount = 0;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* void accGetBounds (out long x, out long y, out long width, out long height); */
|
||||
NS_IMETHODIMP nsHTMLAreaAccessible::GetBounds(PRInt32 *x, PRInt32 *y, PRInt32 *width, PRInt32 *height)
|
||||
NS_IMETHODIMP
|
||||
nsHTMLAreaAccessible::GetBounds(PRInt32 *x, PRInt32 *y,
|
||||
PRInt32 *width, PRInt32 *height)
|
||||
{
|
||||
// Essentially this uses GetRect on mAreas of nsImageMap from nsImageFrame
|
||||
|
||||
|
|
|
@ -39,23 +39,29 @@
|
|||
#ifndef _nsHTMLAreaAccessible_H_
|
||||
#define _nsHTMLAreaAccessible_H_
|
||||
|
||||
#include "nsBaseWidgetAccessible.h"
|
||||
#include "nsHTMLLinkAccessible.h"
|
||||
|
||||
/* Accessible for image map areas - must be child of image
|
||||
*/
|
||||
|
||||
class nsHTMLAreaAccessible : public nsLinkableAccessible
|
||||
class nsHTMLAreaAccessible : public nsHTMLLinkAccessible
|
||||
{
|
||||
|
||||
public:
|
||||
nsHTMLAreaAccessible(nsIDOMNode *domNode, nsIAccessible *accParent, nsIWeakReference* aShell);
|
||||
NS_IMETHOD GetName(nsAString & _retval);
|
||||
NS_IMETHOD GetRole(PRUint32 *_retval);
|
||||
nsHTMLAreaAccessible(nsIDOMNode *domNode, nsIAccessible *accParent,
|
||||
nsIWeakReference* aShell);
|
||||
|
||||
// nsIAccessible
|
||||
NS_IMETHOD GetName(nsAString & aName);
|
||||
NS_IMETHOD GetDescription(nsAString& aDescription);
|
||||
|
||||
NS_IMETHOD GetFirstChild(nsIAccessible **_retval);
|
||||
NS_IMETHOD GetLastChild(nsIAccessible **_retval);
|
||||
NS_IMETHOD GetChildCount(PRInt32 *_retval);
|
||||
NS_IMETHOD GetDescription(nsAString& _retval);
|
||||
|
||||
NS_IMETHOD GetBounds(PRInt32 *x, PRInt32 *y, PRInt32 *width, PRInt32 *height);
|
||||
NS_IMETHOD GetChildAtPoint(PRInt32 aX, PRInt32 aY, nsIAccessible **aAccessible)
|
||||
{ NS_ENSURE_ARG_POINTER(aAccessible); NS_ADDREF(*aAccessible = this); return NS_OK; } // Don't walk into these
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -48,9 +48,13 @@
|
|||
#include "nsIDOMHTMLFormElement.h"
|
||||
#include "nsIDOMHTMLLegendElement.h"
|
||||
#include "nsIDOMHTMLTextAreaElement.h"
|
||||
#include "nsIEditor.h"
|
||||
#include "nsIFrame.h"
|
||||
#include "nsINameSpaceManager.h"
|
||||
#include "nsISelectionController.h"
|
||||
#include "jsapi.h"
|
||||
#include "nsIJSContextStack.h"
|
||||
#include "nsIServiceManager.h"
|
||||
#include "nsITextControlFrame.h"
|
||||
|
||||
// --- checkbox -----
|
||||
|
@ -102,6 +106,8 @@ nsHTMLCheckboxAccessible::GetState(PRUint32 *aState, PRUint32 *aExtraState)
|
|||
{
|
||||
nsresult rv = nsFormControlAccessible::GetState(aState, aExtraState);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
if (!mDOMNode)
|
||||
return NS_OK;
|
||||
|
||||
*aState |= nsIAccessibleStates::STATE_CHECKABLE;
|
||||
|
||||
|
@ -129,6 +135,8 @@ nsHTMLRadioButtonAccessible::GetState(PRUint32 *aState, PRUint32 *aExtraState)
|
|||
{
|
||||
nsresult rv = nsAccessibleWrap::GetState(aState, aExtraState);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
if (!mDOMNode)
|
||||
return NS_OK;
|
||||
|
||||
*aState |= nsIAccessibleStates::STATE_CHECKABLE;
|
||||
|
||||
|
@ -245,11 +253,13 @@ NS_IMETHODIMP nsHTMLButtonAccessible::DoAction(PRUint8 index)
|
|||
NS_IMETHODIMP
|
||||
nsHTMLButtonAccessible::GetState(PRUint32 *aState, PRUint32 *aExtraState)
|
||||
{
|
||||
nsCOMPtr<nsIDOMElement> element(do_QueryInterface(mDOMNode));
|
||||
NS_ENSURE_TRUE(element, NS_ERROR_FAILURE);
|
||||
|
||||
nsresult rv = nsHyperTextAccessibleWrap::GetState(aState, aExtraState);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
if (!mDOMNode)
|
||||
return NS_OK;
|
||||
|
||||
nsCOMPtr<nsIDOMElement> element(do_QueryInterface(mDOMNode));
|
||||
NS_ENSURE_TRUE(element, NS_ERROR_FAILURE);
|
||||
|
||||
nsAutoString buttonType;
|
||||
element->GetAttribute(NS_LITERAL_STRING("type"), buttonType);
|
||||
|
@ -286,8 +296,7 @@ NS_IMETHODIMP nsHTMLButtonAccessible::GetName(nsAString& aName)
|
|||
nsIFrame* frame = GetFrame();
|
||||
if (frame) {
|
||||
nsIFormControlFrame* fcFrame;
|
||||
frame->QueryInterface(NS_GET_IID(nsIFormControlFrame),
|
||||
(void**) &fcFrame);
|
||||
CallQueryInterface(frame, &fcFrame);
|
||||
if (fcFrame)
|
||||
fcFrame->GetFormProperty(nsAccessibilityAtoms::defaultLabel, name);
|
||||
}
|
||||
|
@ -347,11 +356,13 @@ NS_IMETHODIMP nsHTML4ButtonAccessible::GetRole(PRUint32 *_retval)
|
|||
NS_IMETHODIMP
|
||||
nsHTML4ButtonAccessible::GetState(PRUint32 *aState, PRUint32 *aExtraState)
|
||||
{
|
||||
nsCOMPtr<nsIDOMElement> element(do_QueryInterface(mDOMNode));
|
||||
NS_ENSURE_TRUE(element, NS_ERROR_FAILURE); // Button accessible shut down
|
||||
|
||||
nsresult rv = nsHyperTextAccessibleWrap::GetState(aState, aExtraState);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
if (!mDOMNode)
|
||||
return NS_OK;
|
||||
|
||||
nsCOMPtr<nsIDOMElement> element(do_QueryInterface(mDOMNode));
|
||||
NS_ASSERTION(element, "No element for button's dom node!");
|
||||
|
||||
*aState |= nsIAccessibleStates::STATE_FOCUSABLE;
|
||||
|
||||
|
@ -370,23 +381,7 @@ nsHyperTextAccessibleWrap(aNode, aShell)
|
|||
{
|
||||
}
|
||||
|
||||
NS_IMPL_ISUPPORTS_INHERITED1(nsHTMLTextFieldAccessible, nsHyperTextAccessibleWrap,
|
||||
nsIAccessibleText)
|
||||
|
||||
NS_IMETHODIMP nsHTMLTextFieldAccessible::Init()
|
||||
{
|
||||
CheckForEditor();
|
||||
return nsHyperTextAccessibleWrap::Init();
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsHTMLTextFieldAccessible::Shutdown()
|
||||
{
|
||||
if (mEditor) {
|
||||
mEditor->RemoveEditActionListener(this);
|
||||
mEditor = nsnull;
|
||||
}
|
||||
return nsHyperTextAccessibleWrap::Shutdown();
|
||||
}
|
||||
NS_IMPL_ISUPPORTS_INHERITED3(nsHTMLTextFieldAccessible, nsAccessible, nsHyperTextAccessible, nsIAccessibleText, nsIAccessibleEditableText)
|
||||
|
||||
NS_IMETHODIMP nsHTMLTextFieldAccessible::GetRole(PRUint32 *aRole)
|
||||
{
|
||||
|
@ -445,6 +440,8 @@ nsHTMLTextFieldAccessible::GetState(PRUint32 *aState, PRUint32 *aExtraState)
|
|||
{
|
||||
nsresult rv = nsHyperTextAccessibleWrap::GetState(aState, aExtraState);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
if (!mDOMNode)
|
||||
return NS_OK;
|
||||
|
||||
// can be focusable, focused, protected. readonly, unavailable, selected
|
||||
nsCOMPtr<nsIContent> content(do_QueryInterface(mDOMNode));
|
||||
|
@ -543,25 +540,29 @@ NS_IMETHODIMP nsHTMLTextFieldAccessible::DoAction(PRUint8 index)
|
|||
return NS_ERROR_INVALID_ARG;
|
||||
}
|
||||
|
||||
void nsHTMLTextFieldAccessible::SetEditor(nsIEditor* aEditor)
|
||||
{
|
||||
mEditor = aEditor;
|
||||
if (mEditor)
|
||||
mEditor->AddEditActionListener(this);
|
||||
}
|
||||
|
||||
void nsHTMLTextFieldAccessible::CheckForEditor()
|
||||
NS_IMETHODIMP nsHTMLTextFieldAccessible::GetAssociatedEditor(nsIEditor **aEditor)
|
||||
{
|
||||
*aEditor = nsnull;
|
||||
nsCOMPtr<nsIDOMNSEditableElement> editableElt(do_QueryInterface(mDOMNode));
|
||||
if (!editableElt) {
|
||||
return;
|
||||
}
|
||||
NS_ENSURE_TRUE(editableElt, NS_ERROR_FAILURE);
|
||||
|
||||
// nsGenericHTMLElement::GetEditor has a security check.
|
||||
// Make sure we're not restricted by the permissions of
|
||||
// whatever script is currently running.
|
||||
nsCOMPtr<nsIJSContextStack> stack =
|
||||
do_GetService("@mozilla.org/js/xpc/ContextStack;1");
|
||||
PRBool pushed = stack && NS_SUCCEEDED(stack->Push(nsnull));
|
||||
|
||||
nsCOMPtr<nsIEditor> editor;
|
||||
nsresult rv = editableElt->GetEditor(getter_AddRefs(editor));
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
SetEditor(editor);
|
||||
nsresult rv = editableElt->GetEditor(aEditor);
|
||||
|
||||
if (pushed) {
|
||||
JSContext* cx;
|
||||
stack->Pop(&cx);
|
||||
NS_ASSERTION(!cx, "context should be null");
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
// --- groupbox -----
|
||||
|
|
|
@ -102,12 +102,10 @@ class nsHTMLTextFieldAccessible : public nsHyperTextAccessibleWrap
|
|||
public:
|
||||
enum { eAction_Click = 0 };
|
||||
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
|
||||
nsHTMLTextFieldAccessible(nsIDOMNode* aNode, nsIWeakReference* aShell);
|
||||
|
||||
NS_IMETHOD Init();
|
||||
NS_IMETHOD Shutdown();
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
|
||||
NS_IMETHOD GetRole(PRUint32 *_retval);
|
||||
NS_IMETHOD GetName(nsAString& aName);
|
||||
NS_IMETHOD GetValue(nsAString& _retval);
|
||||
|
@ -116,12 +114,8 @@ public:
|
|||
NS_IMETHOD GetActionName(PRUint8 aIndex, nsAString& aName);
|
||||
NS_IMETHOD DoAction(PRUint8 index);
|
||||
|
||||
protected:
|
||||
// Editor helpers, subclasses of nsHyperTextAccessible may have editor
|
||||
virtual void SetEditor(nsIEditor *aEditor);
|
||||
virtual already_AddRefed<nsIEditor> GetEditor() { nsIEditor *editor = mEditor; NS_IF_ADDREF(editor); return editor; }
|
||||
void CheckForEditor();
|
||||
nsCOMPtr<nsIEditor> mEditor;
|
||||
// nsIAccessibleEditableText
|
||||
NS_IMETHOD GetAssociatedEditor(nsIEditor **aEditor);
|
||||
};
|
||||
|
||||
class nsHTMLGroupboxAccessible : public nsHyperTextAccessibleWrap
|
||||
|
|
|
@ -38,13 +38,16 @@
|
|||
|
||||
#include "imgIContainer.h"
|
||||
#include "imgIRequest.h"
|
||||
|
||||
#include "nsHTMLImageAccessible.h"
|
||||
#include "nsAccessibilityAtoms.h"
|
||||
#include "nsIAccessibilityService.h"
|
||||
#include "nsHTMLAreaAccessible.h"
|
||||
|
||||
#include "nsIDOMHTMLCollection.h"
|
||||
#include "nsIDocument.h"
|
||||
#include "nsIHTMLDocument.h"
|
||||
#include "nsIImageLoadingContent.h"
|
||||
#include "nsILink.h"
|
||||
#include "nsIPresShell.h"
|
||||
#include "nsIServiceManager.h"
|
||||
#include "nsIDOMHTMLImageElement.h"
|
||||
|
@ -53,8 +56,13 @@
|
|||
|
||||
// --- image -----
|
||||
|
||||
const PRUint32 kDefaultImageCacheSize = 256;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// nsHTMLImageAccessible
|
||||
|
||||
nsHTMLImageAccessible::nsHTMLImageAccessible(nsIDOMNode* aDOMNode, nsIWeakReference* aShell):
|
||||
nsLinkableAccessible(aDOMNode, aShell)
|
||||
nsLinkableAccessible(aDOMNode, aShell), mAccessNodeCache(nsnull)
|
||||
{
|
||||
nsCOMPtr<nsIDOMElement> element(do_QueryInterface(aDOMNode));
|
||||
nsCOMPtr<nsIPresShell> shell(do_QueryReferent(mWeakShell));
|
||||
|
@ -73,9 +81,18 @@ nsLinkableAccessible(aDOMNode, aShell)
|
|||
mMapElement = htmlDoc->GetImageMap(mapElementName);
|
||||
}
|
||||
}
|
||||
|
||||
if (mMapElement) {
|
||||
mAccessNodeCache = new nsAccessNodeHashtable();
|
||||
mAccessNodeCache->Init(kDefaultImageCacheSize);
|
||||
}
|
||||
}
|
||||
|
||||
NS_IMPL_ISUPPORTS_INHERITED1(nsHTMLImageAccessible, nsLinkableAccessible, nsIAccessibleImage)
|
||||
NS_IMPL_ISUPPORTS_INHERITED1(nsHTMLImageAccessible, nsAccessible,
|
||||
nsIAccessibleImage)
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// nsIAccessible
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsHTMLImageAccessible::GetState(PRUint32 *aState, PRUint32 *aExtraState)
|
||||
|
@ -85,6 +102,8 @@ nsHTMLImageAccessible::GetState(PRUint32 *aState, PRUint32 *aExtraState)
|
|||
|
||||
nsresult rv = nsLinkableAccessible::GetState(aState, aExtraState);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
if (!mDOMNode)
|
||||
return NS_OK;
|
||||
|
||||
nsCOMPtr<nsIImageLoadingContent> content(do_QueryInterface(mDOMNode));
|
||||
nsCOMPtr<imgIRequest> imageRequest;
|
||||
|
@ -111,69 +130,45 @@ nsHTMLImageAccessible::GetState(PRUint32 *aState, PRUint32 *aExtraState)
|
|||
/* wstring getName (); */
|
||||
NS_IMETHODIMP nsHTMLImageAccessible::GetName(nsAString& aName)
|
||||
{
|
||||
nsCOMPtr<nsIContent> content(do_QueryInterface(mDOMNode));
|
||||
if (!content) {
|
||||
return NS_ERROR_FAILURE; // Node has been shut down
|
||||
}
|
||||
aName.Truncate();
|
||||
if (IsDefunct())
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
if (!content->GetAttr(kNameSpaceID_None, nsAccessibilityAtoms::alt,
|
||||
aName)) {
|
||||
if (mRoleMapEntry) {
|
||||
nsCOMPtr<nsIContent> content(do_QueryInterface(mDOMNode));
|
||||
NS_ASSERTION(content, "Image node always supports nsIContent");
|
||||
|
||||
// No alt attribute means AT can repair if there is no accessible name
|
||||
// alt="" with no title or aria-labelledby means image is presentational and
|
||||
// AT should leave accessible name empty
|
||||
PRBool hasAltAttrib =
|
||||
content->GetAttr(kNameSpaceID_None, nsAccessibilityAtoms::alt, aName);
|
||||
if (aName.IsEmpty()) {
|
||||
if (content->HasAttr(kNameSpaceID_None, nsAccessibilityAtoms::aria_labelledby)) {
|
||||
// Use HTML label or DHTML accessibility's labelledby attribute for name
|
||||
// GetHTMLName will also try title attribute as a last resort
|
||||
return GetHTMLName(aName, PR_FALSE);
|
||||
GetHTMLName(aName, PR_FALSE);
|
||||
}
|
||||
if (aName.IsEmpty()) { // No name from alt or aria-labelledby
|
||||
content->GetAttr(kNameSpaceID_None, nsAccessibilityAtoms::title, aName);
|
||||
if (!hasAltAttrib && aName.IsEmpty()) {
|
||||
// Still no accessible name and no alt attribute is present.
|
||||
// SetIsVoid() is different from empty string -- this means a name was not
|
||||
// provided by author and AT repair of the name is allowed.
|
||||
aName.SetIsVoid(PR_TRUE);
|
||||
}
|
||||
if (!content->GetAttr(kNameSpaceID_None, nsAccessibilityAtoms::title,
|
||||
aName)) {
|
||||
aName.SetIsVoid(PR_TRUE); // No alt or title
|
||||
}
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* wstring getRole (); */
|
||||
NS_IMETHODIMP nsHTMLImageAccessible::GetRole(PRUint32 *_retval)
|
||||
{
|
||||
*_retval = nsIAccessibleRole::ROLE_GRAPHIC;
|
||||
*_retval = mMapElement ? nsIAccessibleRole::ROLE_IMAGE_MAP :
|
||||
nsIAccessibleRole::ROLE_GRAPHIC;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
already_AddRefed<nsIAccessible> nsHTMLImageAccessible::CreateAreaAccessible(PRInt32 areaNum)
|
||||
{
|
||||
if (!mMapElement)
|
||||
return nsnull;
|
||||
|
||||
nsCOMPtr<nsIDOMHTMLCollection> mapAreas;
|
||||
mMapElement->GetAreas(getter_AddRefs(mapAreas));
|
||||
if (!mapAreas)
|
||||
return nsnull;
|
||||
|
||||
nsCOMPtr<nsIDOMNode> domNode;
|
||||
mapAreas->Item(areaNum,getter_AddRefs(domNode));
|
||||
if (!domNode)
|
||||
return nsnull;
|
||||
|
||||
nsCOMPtr<nsIAccessibilityService> accService(do_GetService("@mozilla.org/accessibilityService;1"));
|
||||
if (!accService)
|
||||
return nsnull;
|
||||
if (accService) {
|
||||
nsIAccessible* acc = nsnull;
|
||||
accService->GetCachedAccessible(domNode, mWeakShell, &acc);
|
||||
if (!acc) {
|
||||
accService->CreateHTMLAreaAccessible(mWeakShell, domNode, this, &acc);
|
||||
nsCOMPtr<nsPIAccessNode> accessNode(do_QueryInterface(acc));
|
||||
if (accessNode) {
|
||||
accessNode->Init();
|
||||
}
|
||||
}
|
||||
return acc;
|
||||
}
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
|
||||
void nsHTMLImageAccessible::CacheChildren()
|
||||
{
|
||||
if (!mWeakShell) {
|
||||
|
@ -186,14 +181,10 @@ void nsHTMLImageAccessible::CacheChildren()
|
|||
return;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIDOMHTMLCollection> mapAreas;
|
||||
if (mMapElement) {
|
||||
mMapElement->GetAreas(getter_AddRefs(mapAreas));
|
||||
}
|
||||
if (!mapAreas) {
|
||||
mAccChildCount = 0;
|
||||
nsCOMPtr<nsIDOMHTMLCollection> mapAreas = GetAreaCollection();
|
||||
if (!mapAreas)
|
||||
return;
|
||||
}
|
||||
|
||||
PRUint32 numMapAreas;
|
||||
mapAreas->GetLength(&numMapAreas);
|
||||
|
@ -202,7 +193,7 @@ void nsHTMLImageAccessible::CacheChildren()
|
|||
nsCOMPtr<nsIAccessible> areaAccessible;
|
||||
nsCOMPtr<nsPIAccessible> privatePrevAccessible;
|
||||
while (childCount < (PRInt32)numMapAreas &&
|
||||
(areaAccessible = CreateAreaAccessible(childCount)) != nsnull) {
|
||||
(areaAccessible = GetAreaAccessible(mapAreas, childCount)) != nsnull) {
|
||||
if (privatePrevAccessible) {
|
||||
privatePrevAccessible->SetNextSibling(areaAccessible);
|
||||
}
|
||||
|
@ -242,7 +233,175 @@ NS_IMETHODIMP nsHTMLImageAccessible::DoAction(PRUint8 index)
|
|||
return nsLinkableAccessible::DoAction(index);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsHTMLImageAccessible::GetImageBounds(PRInt32 *x, PRInt32 *y, PRInt32 *width, PRInt32 *height)
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// nsIAccessibleHyperLink
|
||||
NS_IMETHODIMP
|
||||
nsHTMLImageAccessible::GetAnchorCount(PRInt32 *aAnchorCount)
|
||||
{
|
||||
return GetBounds(x, y, width, height);
|
||||
NS_ENSURE_ARG_POINTER(aAnchorCount);
|
||||
|
||||
if (!mMapElement)
|
||||
return nsLinkableAccessible::GetAnchorCount(aAnchorCount);
|
||||
|
||||
return GetChildCount(aAnchorCount);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsHTMLImageAccessible::GetURI(PRInt32 aIndex, nsIURI **aURI)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aURI);
|
||||
*aURI = nsnull;
|
||||
|
||||
if (!mMapElement)
|
||||
return nsLinkableAccessible::GetURI(aIndex, aURI);
|
||||
|
||||
nsCOMPtr<nsIDOMHTMLCollection> mapAreas = GetAreaCollection();
|
||||
if (!mapAreas)
|
||||
return NS_OK;
|
||||
|
||||
nsCOMPtr<nsIDOMNode> domNode;
|
||||
mapAreas->Item(aIndex, getter_AddRefs(domNode));
|
||||
if (!domNode)
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
|
||||
nsCOMPtr<nsILink> link(do_QueryInterface(domNode));
|
||||
if (link)
|
||||
link->GetHrefURI(aURI);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsHTMLImageAccessible::GetAnchor(PRInt32 aIndex, nsIAccessible **aAccessible)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aAccessible);
|
||||
*aAccessible = nsnull;
|
||||
|
||||
if (!mMapElement)
|
||||
return nsLinkableAccessible::GetAnchor(aIndex, aAccessible);
|
||||
|
||||
nsCOMPtr<nsIDOMHTMLCollection> mapAreas = GetAreaCollection();
|
||||
if (mapAreas) {
|
||||
nsCOMPtr<nsIAccessible> accessible;
|
||||
accessible = GetAreaAccessible(mapAreas, aIndex);
|
||||
if (!accessible)
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
|
||||
NS_ADDREF(*aAccessible = accessible);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// nsIAccessibleImage
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsHTMLImageAccessible::GetImagePosition(PRUint32 aCoordType,
|
||||
PRInt32 *aX, PRInt32 *aY)
|
||||
{
|
||||
PRInt32 width, height;
|
||||
nsresult rv = GetBounds(aX, aY, &width, &height);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
return nsAccUtils::ConvertScreenCoordsTo(aX, aY, aCoordType, this);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsHTMLImageAccessible::GetImageSize(PRInt32 *aWidth, PRInt32 *aHeight)
|
||||
{
|
||||
PRInt32 x, y;
|
||||
return GetBounds(&x, &y, aWidth, aHeight);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// nsPIAccessNode
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsHTMLImageAccessible::Shutdown()
|
||||
{
|
||||
nsLinkableAccessible::Shutdown();
|
||||
|
||||
if (mAccessNodeCache) {
|
||||
ClearCache(*mAccessNodeCache);
|
||||
delete mAccessNodeCache;
|
||||
mAccessNodeCache = nsnull;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// nsHTMLImageAccessible
|
||||
|
||||
nsresult
|
||||
nsHTMLImageAccessible::GetAttributesInternal(nsIPersistentProperties *aAttributes)
|
||||
{
|
||||
if (IsDefunct())
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
nsresult rv = nsLinkableAccessible::GetAttributesInternal(aAttributes);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsCOMPtr<nsIContent> content(do_QueryInterface(mDOMNode));
|
||||
|
||||
nsAutoString src;
|
||||
content->GetAttr(kNameSpaceID_None, nsAccessibilityAtoms::src, src);
|
||||
if (!src.IsEmpty())
|
||||
nsAccUtils::SetAccAttr(aAttributes, nsAccessibilityAtoms::src, src);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
already_AddRefed<nsIDOMHTMLCollection>
|
||||
nsHTMLImageAccessible::GetAreaCollection()
|
||||
{
|
||||
if (!mMapElement)
|
||||
return nsnull;
|
||||
|
||||
nsIDOMHTMLCollection *mapAreas = nsnull;
|
||||
nsresult rv = mMapElement->GetAreas(&mapAreas);
|
||||
if (NS_FAILED(rv))
|
||||
return nsnull;
|
||||
|
||||
return mapAreas;
|
||||
}
|
||||
|
||||
already_AddRefed<nsIAccessible>
|
||||
nsHTMLImageAccessible::GetAreaAccessible(nsIDOMHTMLCollection *aAreaCollection,
|
||||
PRInt32 aAreaNum)
|
||||
{
|
||||
if (!aAreaCollection)
|
||||
return nsnull;
|
||||
|
||||
nsCOMPtr<nsIDOMNode> domNode;
|
||||
aAreaCollection->Item(aAreaNum,getter_AddRefs(domNode));
|
||||
if (!domNode)
|
||||
return nsnull;
|
||||
|
||||
nsCOMPtr<nsIAccessNode> accessNode;
|
||||
GetCacheEntry(*mAccessNodeCache, (void*)(aAreaNum),
|
||||
getter_AddRefs(accessNode));
|
||||
|
||||
if (!accessNode) {
|
||||
accessNode = new nsHTMLAreaAccessible(domNode, this, mWeakShell);
|
||||
if (!accessNode)
|
||||
return nsnull;
|
||||
|
||||
nsCOMPtr<nsPIAccessNode> privateAccessNode(do_QueryInterface(accessNode));
|
||||
NS_ASSERTION(privateAccessNode,
|
||||
"Accessible doesn't implement nsPIAccessNode");
|
||||
|
||||
nsresult rv = privateAccessNode->Init();
|
||||
if (NS_FAILED(rv))
|
||||
return nsnull;
|
||||
|
||||
PutCacheEntry(*mAccessNodeCache, (void*)(aAreaNum), accessNode);
|
||||
}
|
||||
|
||||
nsIAccessible *accessible = nsnull;
|
||||
CallQueryInterface(accessNode, &accessible);
|
||||
|
||||
return accessible;
|
||||
}
|
||||
|
|
|
@ -60,17 +60,42 @@ public:
|
|||
|
||||
nsHTMLImageAccessible(nsIDOMNode* aDomNode, nsIWeakReference* aShell);
|
||||
|
||||
// nsIAccessible
|
||||
NS_IMETHOD GetName(nsAString& _retval);
|
||||
NS_IMETHOD GetState(PRUint32 *aState, PRUint32 *aExtraState);
|
||||
NS_IMETHOD GetRole(PRUint32 *_retval);
|
||||
NS_IMETHOD DoAction(PRUint8 index);
|
||||
|
||||
NS_IMETHOD GetImageBounds(PRInt32 *x, PRInt32 *y, PRInt32 *width, PRInt32 *height);
|
||||
// nsIAccessibleHyperLink
|
||||
NS_IMETHOD GetAnchorCount(PRInt32 *aAnchorCount);
|
||||
NS_IMETHOD GetURI(PRInt32 aIndex, nsIURI **aURI);
|
||||
NS_IMETHOD GetAnchor(PRInt32 aIndex, nsIAccessible **aAccessible);
|
||||
|
||||
// nsPIAccessNode
|
||||
NS_IMETHOD Shutdown();
|
||||
|
||||
// nsIAccessibleImage
|
||||
NS_DECL_NSIACCESSIBLEIMAGE
|
||||
|
||||
// nsAccessible
|
||||
virtual nsresult GetAttributesInternal(nsIPersistentProperties *aAttributes);
|
||||
|
||||
protected:
|
||||
// nsAccessible
|
||||
virtual void CacheChildren();
|
||||
already_AddRefed<nsIAccessible> CreateAreaAccessible(PRInt32 areaNum);
|
||||
|
||||
already_AddRefed<nsIDOMHTMLCollection> GetAreaCollection();
|
||||
already_AddRefed<nsIAccessible>
|
||||
GetAreaAccessible(nsIDOMHTMLCollection* aAreaNodes, PRInt32 aAreaNum);
|
||||
|
||||
// Reference on linked map element if any.
|
||||
nsCOMPtr<nsIDOMHTMLMapElement> mMapElement;
|
||||
|
||||
// Cache of area accessibles. We do not use common cache because images can
|
||||
// share area elements but we need to have separate area accessibles for
|
||||
// each image accessible.
|
||||
nsAccessNodeHashtable *mAccessNodeCache;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
@ -20,7 +20,8 @@
|
|||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Author: Aaron Leventhal (aaronl@netscape.com)
|
||||
* Aaron Leventhal <aleventh@us.ibm.com> (original author)
|
||||
* Alexander Surkov <surkov.alexander@gmail.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either of the GNU General Public License Version 2 or later (the "GPL"),
|
||||
|
@ -37,39 +38,53 @@
|
|||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "nsHTMLLinkAccessible.h"
|
||||
#include "nsAccessibilityAtoms.h"
|
||||
#include "nsIAccessibleEvent.h"
|
||||
#include "nsINameSpaceManager.h"
|
||||
|
||||
NS_IMPL_ISUPPORTS_INHERITED0(nsHTMLLinkAccessible, nsLinkableAccessible)
|
||||
#include "nsILink.h"
|
||||
|
||||
nsHTMLLinkAccessible::nsHTMLLinkAccessible(nsIDOMNode* aDomNode, nsIWeakReference* aShell):
|
||||
nsLinkableAccessible(aDomNode, aShell)
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// nsHTMLLinkAccessible
|
||||
|
||||
nsHTMLLinkAccessible::nsHTMLLinkAccessible(nsIDOMNode* aDomNode,
|
||||
nsIWeakReference* aShell):
|
||||
nsHyperTextAccessibleWrap(aDomNode, aShell)
|
||||
{
|
||||
}
|
||||
|
||||
/* wstring getName (); */
|
||||
NS_IMETHODIMP nsHTMLLinkAccessible::GetName(nsAString& aName)
|
||||
// Expose nsIAccessibleHyperLink unconditionally
|
||||
NS_IMPL_ISUPPORTS_INHERITED1(nsHTMLLinkAccessible, nsHyperTextAccessibleWrap,
|
||||
nsIAccessibleHyperLink)
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// nsIAccessible
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsHTMLLinkAccessible::GetName(nsAString& aName)
|
||||
{
|
||||
if (!mActionContent)
|
||||
aName.Truncate();
|
||||
|
||||
if (IsDefunct())
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
return AppendFlatStringFromSubtree(mActionContent, &aName);
|
||||
nsCOMPtr<nsIContent> content(do_QueryInterface(mDOMNode));
|
||||
return AppendFlatStringFromSubtree(content, &aName);
|
||||
}
|
||||
|
||||
/* unsigned long getRole (); */
|
||||
NS_IMETHODIMP nsHTMLLinkAccessible::GetRole(PRUint32 *_retval)
|
||||
NS_IMETHODIMP
|
||||
nsHTMLLinkAccessible::GetRole(PRUint32 *aRole)
|
||||
{
|
||||
*_retval = nsIAccessibleRole::ROLE_LINK;
|
||||
NS_ENSURE_ARG_POINTER(aRole);
|
||||
|
||||
*aRole = nsIAccessibleRole::ROLE_LINK;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsHTMLLinkAccessible::GetState(PRUint32 *aState, PRUint32 *aExtraState)
|
||||
{
|
||||
nsresult rv = nsLinkableAccessible::GetState(aState, aExtraState);
|
||||
nsresult rv = nsHyperTextAccessibleWrap::GetState(aState, aExtraState);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
if (!mDOMNode)
|
||||
return NS_OK;
|
||||
|
||||
*aState &= ~nsIAccessibleStates::STATE_READONLY;
|
||||
|
||||
|
@ -82,5 +97,91 @@ nsHTMLLinkAccessible::GetState(PRUint32 *aState, PRUint32 *aExtraState)
|
|||
*aState |= nsIAccessibleStates::STATE_SELECTABLE;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsILink> link = do_QueryInterface(mDOMNode);
|
||||
NS_ENSURE_STATE(link);
|
||||
|
||||
nsLinkState linkState;
|
||||
link->GetLinkState(linkState);
|
||||
if (linkState == eLinkState_NotLink) {
|
||||
// This is a named anchor, not a link with also a name attribute. bail out.
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
*aState |= nsIAccessibleStates::STATE_LINKED;
|
||||
|
||||
if (linkState == eLinkState_Visited)
|
||||
*aState |= nsIAccessibleStates::STATE_TRAVERSED;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsHTMLLinkAccessible::GetValue(nsAString& aValue)
|
||||
{
|
||||
aValue.Truncate();
|
||||
|
||||
nsresult rv = nsHyperTextAccessible::GetValue(aValue);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
if (!aValue.IsEmpty())
|
||||
return NS_OK;
|
||||
|
||||
nsCOMPtr<nsIPresShell> presShell(do_QueryReferent(mWeakShell));
|
||||
if (mDOMNode && presShell)
|
||||
return presShell->GetLinkLocation(mDOMNode, aValue);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsHTMLLinkAccessible::GetNumActions(PRUint8 *aNumActions)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aNumActions);
|
||||
|
||||
*aNumActions = 1;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsHTMLLinkAccessible::GetActionName(PRUint8 aIndex, nsAString& aName)
|
||||
{
|
||||
// Action 0 (default action): Jump to link
|
||||
aName.Truncate();
|
||||
if (aIndex != eAction_Jump)
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
|
||||
aName.AssignLiteral("jump");
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsHTMLLinkAccessible::DoAction(PRUint8 aIndex)
|
||||
{
|
||||
// Action 0 (default action): Jump to link
|
||||
if (aIndex != eAction_Jump)
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
|
||||
if (IsDefunct())
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
nsCOMPtr<nsIContent> content(do_QueryInterface(mDOMNode));
|
||||
return DoCommand(content);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// nsIAccessibleHyperLink
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsHTMLLinkAccessible::GetURI(PRInt32 aIndex, nsIURI **aURI)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aURI);
|
||||
*aURI = nsnull;
|
||||
|
||||
if (aIndex != 0)
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
|
||||
nsCOMPtr<nsILink> link(do_QueryInterface(mDOMNode));
|
||||
NS_ENSURE_STATE(link);
|
||||
|
||||
return link->GetHrefURI(aURI);
|
||||
}
|
||||
|
|
|
@ -20,7 +20,8 @@
|
|||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Author: Aaron Leventhal (aaronl@netscape.com)
|
||||
* Aaron Leventhal <aleventh@us.ibm.com> (original author)
|
||||
* Alexander Surkov <surkov.alexander@gmail.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either of the GNU General Public License Version 2 or later (the "GPL"),
|
||||
|
@ -39,19 +40,30 @@
|
|||
#ifndef _nsHTMLLinkAccessible_H_
|
||||
#define _nsHTMLLinkAccessible_H_
|
||||
|
||||
#include "nsBaseWidgetAccessible.h"
|
||||
#include "nsHyperTextAccessibleWrap.h"
|
||||
|
||||
class nsHTMLLinkAccessible : public nsLinkableAccessible
|
||||
class nsHTMLLinkAccessible : public nsHyperTextAccessibleWrap
|
||||
{
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
|
||||
public:
|
||||
nsHTMLLinkAccessible(nsIDOMNode* aDomNode, nsIWeakReference* aShell);
|
||||
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
|
||||
// nsIAccessible
|
||||
NS_IMETHOD GetName(nsAString& _retval);
|
||||
NS_IMETHOD GetRole(PRUint32 *_retval);
|
||||
NS_IMETHOD GetName(nsAString& aName);
|
||||
NS_IMETHOD GetRole(PRUint32 *aRole);
|
||||
NS_IMETHOD GetState(PRUint32 *aState, PRUint32 *aExtraState);
|
||||
NS_IMETHOD GetValue(nsAString& aValue);
|
||||
|
||||
NS_IMETHOD GetNumActions(PRUint8 *aNumActions);
|
||||
NS_IMETHOD GetActionName(PRUint8 aIndex, nsAString& aName);
|
||||
NS_IMETHOD DoAction(PRUint8 aIndex);
|
||||
|
||||
// nsIAccessibleHyperLink
|
||||
NS_IMETHOD GetURI(PRInt32 aIndex, nsIURI **aURI);
|
||||
|
||||
protected:
|
||||
enum { eAction_Jump = 0 };
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -330,9 +330,21 @@ nsHTMLSelectListAccessible::GetState(PRUint32 *aState, PRUint32 *aExtraState)
|
|||
{
|
||||
nsresult rv = nsHTMLSelectableAccessible::GetState(aState, aExtraState);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
if (!mDOMNode)
|
||||
return NS_OK;
|
||||
|
||||
nsCOMPtr<nsIDOMHTMLSelectElement> select (do_QueryInterface(mDOMNode));
|
||||
if (select) {
|
||||
if (*aState | nsIAccessibleStates::STATE_FOCUSED) {
|
||||
// Treat first focusable option node as actual focus, in order
|
||||
// to avoid confusing JAWS, which needs focus on the option
|
||||
nsCOMPtr<nsIDOMNode> focusedOption;
|
||||
nsHTMLSelectOptionAccessible::GetFocusedOptionNode(mDOMNode,
|
||||
getter_AddRefs(focusedOption));
|
||||
if (focusedOption) { // Clear focused state since it is on option
|
||||
*aState &= ~nsIAccessibleStates::STATE_FOCUSED;
|
||||
}
|
||||
}
|
||||
PRBool multiple;
|
||||
select->GetMultiple(&multiple);
|
||||
if ( multiple )
|
||||
|
@ -394,6 +406,7 @@ nsHTMLSelectListAccessible::CacheOptSiblings(nsIAccessibilityService *aAccServic
|
|||
|
||||
PRUint32 numChildren = aParentContent->GetChildCount();
|
||||
nsCOMPtr<nsIAccessible> lastGoodAccessible(aLastGoodAccessible);
|
||||
nsCOMPtr<nsIAccessible> newAccessible;
|
||||
|
||||
for (PRUint32 count = 0; count < numChildren; count ++) {
|
||||
nsIContent *childContent = aParentContent->GetChildAt(count);
|
||||
|
@ -402,14 +415,19 @@ nsHTMLSelectListAccessible::CacheOptSiblings(nsIAccessibilityService *aAccServic
|
|||
}
|
||||
nsCOMPtr<nsIAtom> tag = childContent->Tag();
|
||||
if (tag == nsAccessibilityAtoms::option || tag == nsAccessibilityAtoms::optgroup) {
|
||||
lastGoodAccessible = AccessibleForOption(aAccService,
|
||||
newAccessible = AccessibleForOption(aAccService,
|
||||
childContent,
|
||||
lastGoodAccessible,
|
||||
aChildCount);
|
||||
if (newAccessible) {
|
||||
lastGoodAccessible = newAccessible;
|
||||
}
|
||||
if (tag == nsAccessibilityAtoms::optgroup) {
|
||||
lastGoodAccessible = CacheOptSiblings(aAccService, childContent,
|
||||
lastGoodAccessible,
|
||||
aChildCount);
|
||||
newAccessible = CacheOptSiblings(aAccService, childContent,
|
||||
lastGoodAccessible, aChildCount);
|
||||
if (newAccessible) {
|
||||
lastGoodAccessible = newAccessible;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -440,6 +458,11 @@ void nsHTMLSelectListAccessible::CacheChildren()
|
|||
return;
|
||||
}
|
||||
|
||||
if (mAccChildCount != eChildCountUninitialized) {
|
||||
return;
|
||||
}
|
||||
|
||||
mAccChildCount = 0; // Avoid reentry
|
||||
PRInt32 childCount = 0;
|
||||
nsCOMPtr<nsIAccessible> lastGoodAccessible =
|
||||
CacheOptSiblings(accService, selectContent, nsnull, &childCount);
|
||||
|
@ -479,10 +502,10 @@ nsHyperTextAccessibleWrap(aDOMNode, aShell)
|
|||
NS_IMETHODIMP nsHTMLSelectOptionAccessible::GetRole(PRUint32 *aRole)
|
||||
{
|
||||
if (mParent && Role(mParent) == nsIAccessibleRole::ROLE_COMBOBOX_LIST) {
|
||||
*aRole = nsIAccessibleRole::ROLE_COMBOBOX_LISTITEM;
|
||||
*aRole = nsIAccessibleRole::ROLE_COMBOBOX_OPTION;
|
||||
}
|
||||
else {
|
||||
*aRole = nsIAccessibleRole::ROLE_LISTITEM;
|
||||
*aRole = nsIAccessibleRole::ROLE_OPTION;
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -598,9 +621,9 @@ nsHTMLSelectOptionAccessible::GetState(PRUint32 *aState, PRUint32 *aExtraState)
|
|||
// Upcall to nsAccessible, but skip nsHyperTextAccessible impl
|
||||
// because we don't want EXT_STATE_EDITABLE or EXT_STATE_SELECTABLE_TEXT
|
||||
nsresult rv = nsAccessible::GetState(aState, aExtraState);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
if (!mDOMNode)
|
||||
return NS_OK;
|
||||
|
||||
PRUint32 selectState, selectExtState;
|
||||
nsCOMPtr<nsIContent> selectContent = GetSelectState(&selectState,
|
||||
|
@ -616,6 +639,18 @@ nsHTMLSelectOptionAccessible::GetState(PRUint32 *aState, PRUint32 *aExtraState)
|
|||
if (0 == (*aState & nsIAccessibleStates::STATE_UNAVAILABLE)) {
|
||||
*aState |= (nsIAccessibleStates::STATE_FOCUSABLE |
|
||||
nsIAccessibleStates::STATE_SELECTABLE);
|
||||
// When the list is focused but no option is actually focused,
|
||||
// Firefox draws a focus ring around the first non-disabled option.
|
||||
// We need to indicated STATE_FOCUSED in that case, because it
|
||||
// prevents JAWS from ignoring the list
|
||||
// GetFocusedOptionNode() ensures that an option node is
|
||||
// returned in this case, as long as some focusable option exists
|
||||
// in the listbox
|
||||
nsCOMPtr<nsIDOMNode> focusedOptionNode;
|
||||
GetFocusedOptionNode(selectNode, getter_AddRefs(focusedOptionNode));
|
||||
if (focusedOptionNode == mDOMNode) {
|
||||
*aState |= nsIAccessibleStates::STATE_FOCUSED;
|
||||
}
|
||||
}
|
||||
|
||||
// Are we selected?
|
||||
|
@ -782,6 +817,22 @@ nsresult nsHTMLSelectOptionAccessible::GetFocusedOptionNode(nsIDOMNode *aListNod
|
|||
// when there is more than 1 item selected. We need the focused item, not
|
||||
// the first selected item.
|
||||
focusedOptionIndex = listFrame->GetSelectedIndex();
|
||||
if (focusedOptionIndex == -1) {
|
||||
nsCOMPtr<nsIDOMNode> nextOption;
|
||||
while (PR_TRUE) {
|
||||
++ focusedOptionIndex;
|
||||
options->Item(focusedOptionIndex, getter_AddRefs(nextOption));
|
||||
nsCOMPtr<nsIDOMHTMLOptionElement> optionElement = do_QueryInterface(nextOption);
|
||||
if (!optionElement) {
|
||||
break;
|
||||
}
|
||||
PRBool disabled;
|
||||
optionElement->GetDisabled(&disabled);
|
||||
if (!disabled) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else // Combo boxes can only have 1 selected option, so they can use the dom interface for this
|
||||
rv = selectElement->GetSelectedIndex(&focusedOptionIndex);
|
||||
|
@ -1019,7 +1070,6 @@ NS_IMETHODIMP nsHTMLComboboxAccessible::Shutdown()
|
|||
/**
|
||||
* As a nsHTMLComboboxAccessible we can have the following states:
|
||||
* STATE_FOCUSED
|
||||
* STATE_READONLY
|
||||
* STATE_FOCUSABLE
|
||||
* STATE_HASPOPUP
|
||||
* STATE_EXPANDED
|
||||
|
@ -1031,10 +1081,14 @@ nsHTMLComboboxAccessible::GetState(PRUint32 *aState, PRUint32 *aExtraState)
|
|||
// Get focus status from base class
|
||||
nsresult rv = nsAccessible::GetState(aState, aExtraState);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
if (!mDOMNode)
|
||||
return NS_OK;
|
||||
|
||||
nsIFrame *frame = GetBoundsFrame();
|
||||
nsIComboboxControlFrame *comboFrame = nsnull;
|
||||
if (frame) {
|
||||
frame->QueryInterface(NS_GET_IID(nsIComboboxControlFrame), (void**)&comboFrame);
|
||||
}
|
||||
|
||||
if (comboFrame && comboFrame->IsDroppedDown()) {
|
||||
*aState |= nsIAccessibleStates::STATE_EXPANDED;
|
||||
|
@ -1045,7 +1099,6 @@ nsHTMLComboboxAccessible::GetState(PRUint32 *aState, PRUint32 *aExtraState)
|
|||
}
|
||||
|
||||
*aState |= nsIAccessibleStates::STATE_HASPOPUP |
|
||||
nsIAccessibleStates::STATE_READONLY |
|
||||
nsIAccessibleStates::STATE_FOCUSABLE;
|
||||
|
||||
return NS_OK;
|
||||
|
@ -1055,7 +1108,7 @@ NS_IMETHODIMP nsHTMLComboboxAccessible::GetDescription(nsAString& aDescription)
|
|||
{
|
||||
aDescription.Truncate();
|
||||
// First check to see if combo box itself has a description, perhaps through
|
||||
// tooltip (title attribute) or via aaa:describedby
|
||||
// tooltip (title attribute) or via aria-describedby
|
||||
nsAccessible::GetDescription(aDescription);
|
||||
if (!aDescription.IsEmpty()) {
|
||||
return NS_OK;
|
||||
|
@ -1204,6 +1257,7 @@ void nsHTMLComboboxTextFieldAccessible::CacheChildren()
|
|||
|
||||
// Allows only 1 child
|
||||
if (mAccChildCount == eChildCountUninitialized) {
|
||||
mAccChildCount = 0; // Prevent reentry
|
||||
nsAccessibleTreeWalker walker(mWeakShell, mDOMNode, PR_TRUE);
|
||||
// Seed the frame hint early while we're still on a container node.
|
||||
// This is better than doing the GetPrimaryFrameFor() later on
|
||||
|
@ -1339,6 +1393,7 @@ NS_IMETHODIMP nsHTMLComboboxButtonAccessible::GetName(nsAString& aName)
|
|||
* STATE_PRESSED
|
||||
* STATE_FOCUSED
|
||||
* STATE_FOCUSABLE
|
||||
* STATE_INVISIBLE
|
||||
*/
|
||||
NS_IMETHODIMP
|
||||
nsHTMLComboboxButtonAccessible::GetState(PRUint32 *aState, PRUint32 *aExtraState)
|
||||
|
@ -1346,17 +1401,23 @@ nsHTMLComboboxButtonAccessible::GetState(PRUint32 *aState, PRUint32 *aExtraState
|
|||
// Get focus status from base class
|
||||
nsresult rv = nsAccessible::GetState(aState, aExtraState);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
if (!mDOMNode)
|
||||
return NS_OK;
|
||||
|
||||
nsIFrame *boundsFrame = GetBoundsFrame();
|
||||
nsIComboboxControlFrame* comboFrame;
|
||||
nsIComboboxControlFrame* comboFrame = nsnull;
|
||||
if (boundsFrame)
|
||||
boundsFrame->QueryInterface(NS_GET_IID(nsIComboboxControlFrame), (void**)&comboFrame);
|
||||
if (!comboFrame)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
if (comboFrame->IsDroppedDown())
|
||||
*aState |= nsIAccessibleStates::STATE_PRESSED;
|
||||
|
||||
if (!comboFrame) {
|
||||
*aState |= nsIAccessibleStates::STATE_INVISIBLE;
|
||||
}
|
||||
else {
|
||||
*aState |= nsIAccessibleStates::STATE_FOCUSABLE;
|
||||
if (comboFrame->IsDroppedDown()) {
|
||||
*aState |= nsIAccessibleStates::STATE_PRESSED;
|
||||
}
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -1399,9 +1460,12 @@ nsHTMLComboboxListAccessible::GetState(PRUint32 *aState, PRUint32 *aExtraState)
|
|||
// Get focus status from base class
|
||||
nsresult rv = nsAccessible::GetState(aState, aExtraState);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
if (!mDOMNode)
|
||||
return NS_OK;
|
||||
|
||||
nsIFrame *boundsFrame = GetBoundsFrame();
|
||||
nsIComboboxControlFrame* comboFrame = nsnull;
|
||||
if (boundsFrame)
|
||||
boundsFrame->QueryInterface(NS_GET_IID(nsIComboboxControlFrame), (void**)&comboFrame);
|
||||
|
||||
if (comboFrame && comboFrame->IsDroppedDown())
|
||||
|
|
|
@ -58,7 +58,10 @@
|
|||
#include "nsIServiceManager.h"
|
||||
#include "nsITableLayout.h"
|
||||
#include "nsITableCellLayout.h"
|
||||
#include "nsLayoutErrors.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// nsHTMLTableCellAccessible
|
||||
|
||||
NS_IMPL_ISUPPORTS_INHERITED0(nsHTMLTableCellAccessible, nsHyperTextAccessible)
|
||||
|
||||
|
@ -74,18 +77,69 @@ NS_IMETHODIMP nsHTMLTableCellAccessible::GetRole(PRUint32 *aResult)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsHTMLTableCellAccessible::GetState(PRUint32 *aState, PRUint32 *aExtraState)
|
||||
nsresult
|
||||
nsHTMLTableCellAccessible::GetAttributesInternal(nsIPersistentProperties *aAttributes)
|
||||
{
|
||||
nsresult rv = nsAccessible::GetState(aState, aExtraState);
|
||||
if (IsDefunct())
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
nsresult rv = nsHyperTextAccessibleWrap::GetAttributesInternal(aAttributes);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// Inherit all states except focusable state since table cells cannot be
|
||||
// focused.
|
||||
*aState &= ~nsIAccessibleStates::STATE_FOCUSABLE;
|
||||
nsCOMPtr<nsIContent> content(do_QueryInterface(mDOMNode));
|
||||
|
||||
nsCOMPtr<nsIPresShell> shell = GetPresShell();
|
||||
NS_ENSURE_STATE(shell);
|
||||
|
||||
nsIFrame *frame = shell->GetPrimaryFrameFor(content);
|
||||
NS_ASSERTION(frame, "The frame cannot be obtaied for HTML table cell.");
|
||||
NS_ENSURE_STATE(frame);
|
||||
|
||||
nsITableCellLayout *cellLayout = nsnull;
|
||||
CallQueryInterface(frame, &cellLayout);
|
||||
NS_ENSURE_STATE(cellLayout);
|
||||
|
||||
PRInt32 rowIdx = -1, cellIdx = -1;
|
||||
rv = cellLayout->GetCellIndexes(rowIdx, cellIdx);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsCOMPtr<nsIAccessible> childAcc(this);
|
||||
|
||||
nsCOMPtr<nsIAccessible> parentAcc;
|
||||
rv = childAcc->GetParent(getter_AddRefs(parentAcc));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
while (parentAcc) {
|
||||
if (Role(parentAcc) == nsIAccessibleRole::ROLE_TABLE) {
|
||||
// Table accessible must implement nsIAccessibleTable interface but if
|
||||
// it isn't happen (for example because of ARIA usage) we shouldn't fail
|
||||
// on getting other attributes.
|
||||
nsCOMPtr<nsIAccessibleTable> tableAcc(do_QueryInterface(parentAcc));
|
||||
if (!tableAcc)
|
||||
return NS_OK;
|
||||
|
||||
PRInt32 idx = -1;
|
||||
rv = tableAcc->GetIndexAt(rowIdx, cellIdx, &idx);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsAutoString stringIdx;
|
||||
stringIdx.AppendInt(idx);
|
||||
nsAccUtils::SetAccAttr(aAttributes, nsAccessibilityAtoms::tableCellIndex,
|
||||
stringIdx);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
parentAcc.swap(childAcc);
|
||||
rv = childAcc->GetParent(getter_AddRefs(parentAcc));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// nsHTMLTableAccessible
|
||||
|
||||
NS_IMPL_ISUPPORTS_INHERITED1(nsHTMLTableAccessible, nsAccessible, nsIAccessibleTable)
|
||||
|
||||
nsHTMLTableAccessible::nsHTMLTableAccessible(nsIDOMNode* aDomNode, nsIWeakReference* aShell):
|
||||
|
@ -146,10 +200,7 @@ nsHTMLTableAccessible::GetState(PRUint32 *aState, PRUint32 *aExtraState)
|
|||
{
|
||||
nsresult rv= nsAccessible::GetState(aState, aExtraState);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
*aState |= nsIAccessibleStates::STATE_READONLY;
|
||||
// Inherit all states except focusable state since tables cannot be focused.
|
||||
*aState &= ~nsIAccessibleStates::STATE_FOCUSABLE;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -522,6 +573,8 @@ NS_IMETHODIMP
|
|||
nsHTMLTableAccessible::CellRefAt(PRInt32 aRow, PRInt32 aColumn,
|
||||
nsIAccessible **aTableCellAccessible)
|
||||
{
|
||||
NS_ENSURE_TRUE(IsValidRow(aRow) && IsValidColumn(aColumn), NS_ERROR_INVALID_ARG);
|
||||
|
||||
nsresult rv = NS_OK;
|
||||
|
||||
nsCOMPtr<nsIDOMElement> cellElement;
|
||||
|
@ -542,20 +595,13 @@ nsHTMLTableAccessible::GetIndexAt(PRInt32 aRow, PRInt32 aColumn,
|
|||
{
|
||||
NS_ENSURE_ARG_POINTER(aIndex);
|
||||
|
||||
nsresult rv = NS_OK;
|
||||
nsCOMPtr<nsIDOMElement> domElement;
|
||||
rv = GetCellAt(aRow, aColumn, *getter_AddRefs(domElement));
|
||||
NS_ENSURE_TRUE(IsValidRow(aRow) && IsValidColumn(aColumn), NS_ERROR_INVALID_ARG);
|
||||
|
||||
nsITableLayout *tableLayout = nsnull;
|
||||
nsresult rv = GetTableLayout(&tableLayout);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsCOMPtr<nsIAccessible> accessible;
|
||||
GetAccService()->GetCachedAccessible(domElement, mWeakShell, getter_AddRefs(accessible));
|
||||
if (accessible) {
|
||||
rv = accessible->GetIndexInParent(aIndex);
|
||||
} else {
|
||||
// not found the corresponding cell
|
||||
*aIndex = -1;
|
||||
}
|
||||
return rv;
|
||||
return tableLayout->GetIndexByRowAndColumn(aRow, aColumn, aIndex);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
|
@ -563,13 +609,12 @@ nsHTMLTableAccessible::GetColumnAtIndex(PRInt32 aIndex, PRInt32 *aColumn)
|
|||
{
|
||||
NS_ENSURE_ARG_POINTER(aColumn);
|
||||
|
||||
nsCOMPtr<nsIAccessible> child;
|
||||
GetChildAt(aIndex, getter_AddRefs(child));
|
||||
nsCOMPtr<nsPIAccessNode> childNode(do_QueryInterface(child));
|
||||
nsIFrame* frame = childNode->GetFrame();
|
||||
nsCOMPtr<nsITableCellLayout> cellLayout(do_QueryInterface(frame));
|
||||
NS_ENSURE_TRUE(cellLayout, NS_ERROR_FAILURE);
|
||||
return cellLayout->GetColIndex(*aColumn);
|
||||
nsITableLayout *tableLayout = nsnull;
|
||||
nsresult rv = GetTableLayout(&tableLayout);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
PRInt32 row;
|
||||
return tableLayout->GetRowAndColumnByIndex(aIndex, &row, aColumn);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
|
@ -577,19 +622,20 @@ nsHTMLTableAccessible::GetRowAtIndex(PRInt32 aIndex, PRInt32 *aRow)
|
|||
{
|
||||
NS_ENSURE_ARG_POINTER(aRow);
|
||||
|
||||
nsCOMPtr<nsIAccessible> child;
|
||||
GetChildAt(aIndex, getter_AddRefs(child));
|
||||
nsCOMPtr<nsPIAccessNode> childNode(do_QueryInterface(child));
|
||||
nsIFrame* frame = childNode->GetFrame();
|
||||
nsCOMPtr<nsITableCellLayout> cellLayout(do_QueryInterface(frame));
|
||||
NS_ENSURE_TRUE(cellLayout, NS_ERROR_FAILURE);
|
||||
return cellLayout->GetRowIndex(*aRow);
|
||||
nsITableLayout *tableLayout = nsnull;
|
||||
nsresult rv = GetTableLayout(&tableLayout);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
PRInt32 column;
|
||||
return tableLayout->GetRowAndColumnByIndex(aIndex, aRow, &column);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsHTMLTableAccessible::GetColumnExtentAt(PRInt32 aRow, PRInt32 aColumn,
|
||||
PRInt32 *_retval)
|
||||
{
|
||||
NS_ENSURE_TRUE(IsValidRow(aRow) && IsValidColumn(aColumn), NS_ERROR_INVALID_ARG);
|
||||
|
||||
nsresult rv = NS_OK;
|
||||
|
||||
nsCOMPtr<nsIDOMElement> domElement;
|
||||
|
@ -606,6 +652,8 @@ NS_IMETHODIMP
|
|||
nsHTMLTableAccessible::GetRowExtentAt(PRInt32 aRow, PRInt32 aColumn,
|
||||
PRInt32 *_retval)
|
||||
{
|
||||
NS_ENSURE_TRUE(IsValidRow(aRow) && IsValidColumn(aColumn), NS_ERROR_INVALID_ARG);
|
||||
|
||||
nsresult rv = NS_OK;
|
||||
|
||||
nsCOMPtr<nsIDOMElement> domElement;
|
||||
|
@ -635,6 +683,8 @@ nsHTMLTableAccessible::IsColumnSelected(PRInt32 aColumn, PRBool *_retval)
|
|||
{
|
||||
NS_ENSURE_ARG_POINTER(_retval);
|
||||
|
||||
NS_ENSURE_TRUE(IsValidColumn(aColumn), NS_ERROR_INVALID_ARG);
|
||||
|
||||
nsresult rv = NS_OK;
|
||||
|
||||
PRInt32 rows;
|
||||
|
@ -657,6 +707,8 @@ nsHTMLTableAccessible::IsRowSelected(PRInt32 aRow, PRBool *_retval)
|
|||
{
|
||||
NS_ENSURE_ARG_POINTER(_retval);
|
||||
|
||||
NS_ENSURE_TRUE(IsValidRow(aRow), NS_ERROR_INVALID_ARG);
|
||||
|
||||
nsresult rv = NS_OK;
|
||||
|
||||
PRInt32 columns;
|
||||
|
@ -676,9 +728,15 @@ nsHTMLTableAccessible::IsRowSelected(PRInt32 aRow, PRBool *_retval)
|
|||
|
||||
NS_IMETHODIMP
|
||||
nsHTMLTableAccessible::IsCellSelected(PRInt32 aRow, PRInt32 aColumn,
|
||||
PRBool *_retval)
|
||||
PRBool *aIsSelected)
|
||||
{
|
||||
nsITableLayout *tableLayout;
|
||||
NS_ENSURE_ARG_POINTER(aIsSelected);
|
||||
*aIsSelected = PR_FALSE;
|
||||
|
||||
NS_ENSURE_TRUE(IsValidRow(aRow) && IsValidColumn(aColumn),
|
||||
NS_ERROR_INVALID_ARG);
|
||||
|
||||
nsITableLayout *tableLayout = nsnull;
|
||||
nsresult rv = GetTableLayout(&tableLayout);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
|
@ -686,11 +744,30 @@ nsHTMLTableAccessible::IsCellSelected(PRInt32 aRow, PRInt32 aColumn,
|
|||
PRInt32 startRowIndex = 0, startColIndex = 0,
|
||||
rowSpan, colSpan, actualRowSpan, actualColSpan;
|
||||
|
||||
return tableLayout->GetCellDataAt(aRow, aColumn,
|
||||
*getter_AddRefs(domElement),
|
||||
startRowIndex, startColIndex, rowSpan,
|
||||
colSpan, actualRowSpan, actualColSpan,
|
||||
*_retval);
|
||||
rv = tableLayout->GetCellDataAt(aRow, aColumn, *getter_AddRefs(domElement),
|
||||
startRowIndex, startColIndex,
|
||||
rowSpan, colSpan,
|
||||
actualRowSpan, actualColSpan, *aIsSelected);
|
||||
|
||||
if (rv == NS_TABLELAYOUT_CELL_NOT_FOUND)
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
return rv;
|
||||
}
|
||||
|
||||
PRBool
|
||||
nsHTMLTableAccessible::IsValidColumn(PRInt32 aColumn)
|
||||
{
|
||||
PRInt32 colCount = 0;
|
||||
nsresult rv = GetColumns(&colCount);
|
||||
return NS_SUCCEEDED(rv) && (aColumn >= 0) && (aColumn < colCount);
|
||||
}
|
||||
|
||||
PRBool
|
||||
nsHTMLTableAccessible::IsValidRow(PRInt32 aRow)
|
||||
{
|
||||
PRInt32 rowCount = 0;
|
||||
nsresult rv = GetRows(&rowCount);
|
||||
return NS_SUCCEEDED(rv) && (aRow >= 0) && (aRow < rowCount);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
|
@ -836,26 +913,22 @@ nsHTMLTableAccessible::GetTableNode(nsIDOMNode **_retval)
|
|||
}
|
||||
|
||||
nsresult
|
||||
nsHTMLTableAccessible::GetTableLayout(nsITableLayout **aLayoutObject)
|
||||
nsHTMLTableAccessible::GetTableLayout(nsITableLayout **aTableLayout)
|
||||
{
|
||||
*aLayoutObject = nsnull;
|
||||
|
||||
nsresult rv = NS_OK;
|
||||
*aTableLayout = nsnull;
|
||||
|
||||
nsCOMPtr<nsIDOMNode> tableNode;
|
||||
rv = GetTableNode(getter_AddRefs(tableNode));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
GetTableNode(getter_AddRefs(tableNode));
|
||||
nsCOMPtr<nsIContent> tableContent(do_QueryInterface(tableNode));
|
||||
if (!tableContent) {
|
||||
return NS_ERROR_FAILURE; // Table shut down
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIContent> content(do_QueryInterface(tableNode));
|
||||
NS_ENSURE_TRUE(content, NS_ERROR_FAILURE);
|
||||
nsCOMPtr<nsIPresShell> shell = GetPresShell();
|
||||
NS_ENSURE_TRUE(shell, NS_ERROR_FAILURE);
|
||||
|
||||
nsIPresShell *presShell = content->GetDocument()->GetPrimaryShell();
|
||||
|
||||
nsCOMPtr<nsISupports> layoutObject;
|
||||
rv = presShell->GetLayoutObjectFor(content, getter_AddRefs(layoutObject));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
return CallQueryInterface(layoutObject, aLayoutObject);
|
||||
nsIFrame *frame = shell->GetPrimaryFrameFor(tableContent);
|
||||
return frame ? CallQueryInterface(frame, aTableLayout) : NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
nsresult
|
||||
|
@ -867,15 +940,18 @@ nsHTMLTableAccessible::GetCellAt(PRInt32 aRowIndex,
|
|||
rowSpan, colSpan, actualRowSpan, actualColSpan;
|
||||
PRBool isSelected;
|
||||
|
||||
nsITableLayout *tableLayout;
|
||||
nsITableLayout *tableLayout = nsnull;
|
||||
nsresult rv = GetTableLayout(&tableLayout);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
return tableLayout->GetCellDataAt(aRowIndex, aColIndex, aCell,
|
||||
rv = tableLayout->GetCellDataAt(aRowIndex, aColIndex, aCell,
|
||||
startRowIndex, startColIndex,
|
||||
rowSpan, colSpan,
|
||||
actualRowSpan, actualColSpan,
|
||||
isSelected);
|
||||
actualRowSpan, actualColSpan, isSelected);
|
||||
|
||||
if (rv == NS_TABLELAYOUT_CELL_NOT_FOUND)
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsHTMLTableAccessible::GetDescription(nsAString& aDescription)
|
||||
|
@ -921,7 +997,7 @@ PRBool nsHTMLTableAccessible::HasDescendant(char *aTagName, PRBool aAllowEmpty)
|
|||
nsAutoString tagName;
|
||||
tagName.AssignWithConversion(aTagName);
|
||||
tableElt->GetElementsByTagName(tagName, getter_AddRefs(nodeList));
|
||||
NS_ENSURE_TRUE(nodeList, NS_ERROR_FAILURE);
|
||||
NS_ENSURE_TRUE(nodeList, PR_FALSE);
|
||||
PRUint32 length;
|
||||
nodeList->GetLength(&length);
|
||||
|
||||
|
@ -995,7 +1071,7 @@ NS_IMETHODIMP nsHTMLTableAccessible::IsProbablyForLayout(PRBool *aIsProbablyForL
|
|||
RETURN_LAYOUT_ANSWER(PR_FALSE, "Has role attribute");
|
||||
}
|
||||
|
||||
if (HasRoleAttribute(content)) {
|
||||
if (content->HasAttr(kNameSpaceID_None, nsAccessibilityAtoms::role)) {
|
||||
RETURN_LAYOUT_ANSWER(PR_TRUE, "Has role attribute, and role is table");
|
||||
}
|
||||
|
||||
|
@ -1030,7 +1106,9 @@ NS_IMETHODIMP nsHTMLTableAccessible::IsProbablyForLayout(PRBool *aIsProbablyForL
|
|||
// Check to see if there are visible borders on the cells
|
||||
// XXX currently, we just check the first cell -- do we really need to do more?
|
||||
nsCOMPtr<nsIDOMElement> cellElement;
|
||||
GetCellAt(0, 0, *getter_AddRefs(cellElement));
|
||||
nsresult rv = GetCellAt(0, 0, *getter_AddRefs(cellElement));
|
||||
NS_ENSURE_SUCCESS(rv, NS_ERROR_FAILURE);
|
||||
|
||||
nsCOMPtr<nsIContent> cellContent(do_QueryInterface(cellElement));
|
||||
NS_ENSURE_TRUE(cellContent, NS_ERROR_FAILURE);
|
||||
nsCOMPtr<nsIPresShell> shell(GetPresShell());
|
||||
|
|
|
@ -45,19 +45,23 @@
|
|||
class nsHTMLTableCellAccessible : public nsHyperTextAccessibleWrap
|
||||
{
|
||||
public:
|
||||
nsHTMLTableCellAccessible(nsIDOMNode* aDomNode, nsIWeakReference* aShell);
|
||||
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
|
||||
nsHTMLTableCellAccessible(nsIDOMNode* aDomNode, nsIWeakReference* aShell);
|
||||
NS_IMETHOD GetRole(PRUint32 *aResult);
|
||||
NS_IMETHOD GetState(PRUint32 *aState, PRUint32 *aExtraState);
|
||||
// nsIAccessible
|
||||
NS_IMETHOD GetRole(PRUint32 *aRole);
|
||||
|
||||
// nsAccessible
|
||||
virtual nsresult GetAttributesInternal(nsIPersistentProperties *aAttributes);
|
||||
};
|
||||
|
||||
class nsITableLayout;
|
||||
|
||||
// XXX For now debugging descriptions are always on via SHOW_LAYOUT_HEURISTIC
|
||||
// This will allow release trunk builds to be used by testers to refine the algorithm
|
||||
// Change to |#define SHOW_LAYOUT_HEURISTIC DEBUG| before final release
|
||||
#define SHOW_LAYOUT_HEURISTIC
|
||||
// To turn on table debugging descriptions define SHOW_LAYOUT_HEURISTIC
|
||||
// This allow release trunk builds to be used by testers to refine the
|
||||
// data vs. layout heuristic
|
||||
// #define SHOW_LAYOUT_HEURISTIC
|
||||
|
||||
class nsHTMLTableAccessible : public nsAccessibleWrap,
|
||||
public nsIAccessibleTable
|
||||
|
@ -74,6 +78,20 @@ public:
|
|||
NS_IMETHOD GetDescription(nsAString& aDescription);
|
||||
NS_IMETHOD GetAccessibleRelated(PRUint32 aRelationType, nsIAccessible **aRelated);
|
||||
|
||||
/**
|
||||
* Returns true if the column index is in the valid column range.
|
||||
*
|
||||
* @param aColumn The index to check for validity.
|
||||
*/
|
||||
PRBool IsValidColumn(PRInt32 aColumn);
|
||||
|
||||
/**
|
||||
* Returns true if the given index is in the valid row range.
|
||||
*
|
||||
* @param aRow The index to check for validity.
|
||||
*/
|
||||
PRBool IsValidRow(PRInt32 aRow);
|
||||
|
||||
protected:
|
||||
|
||||
/**
|
||||
|
|
|
@ -56,32 +56,15 @@ nsTextAccessibleWrap(aDomNode, aShell)
|
|||
NS_IMETHODIMP nsHTMLTextAccessible::GetName(nsAString& aName)
|
||||
{
|
||||
aName.Truncate();
|
||||
if (!mDOMNode) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
nsIFrame *frame = GetFrame();
|
||||
NS_ENSURE_TRUE(frame, NS_ERROR_FAILURE);
|
||||
|
||||
nsAutoString name;
|
||||
nsresult rv = mDOMNode->GetNodeValue(name);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
if (!frame->GetStyleText()->WhiteSpaceIsSignificant()) {
|
||||
// Replace \r\n\t in markup with space unless in this is preformatted text
|
||||
// where those characters are significant
|
||||
name.ReplaceChar("\r\n\t", ' ');
|
||||
}
|
||||
aName = name;
|
||||
return rv;
|
||||
return AppendTextTo(aName, 0, PR_UINT32_MAX);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsHTMLTextAccessible::GetRole(PRUint32 *aRole)
|
||||
{
|
||||
nsIFrame *frame = GetFrame();
|
||||
NS_ENSURE_TRUE(frame, NS_ERROR_NULL_POINTER);
|
||||
|
||||
if (frame->IsGeneratedContentFrame()) {
|
||||
// Don't return on null frame -- we still return a role
|
||||
// after accessible is shutdown/DEFUNCT
|
||||
if (frame && frame->IsGeneratedContentFrame()) {
|
||||
*aRole = nsIAccessibleRole::ROLE_STATICTEXT;
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -94,6 +77,8 @@ nsHTMLTextAccessible::GetState(PRUint32 *aState, PRUint32 *aExtraState)
|
|||
{
|
||||
nsresult rv = nsTextAccessible::GetState(aState, aExtraState);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
if (!mDOMNode)
|
||||
return NS_OK;
|
||||
|
||||
nsCOMPtr<nsIAccessible> docAccessible =
|
||||
do_QueryInterface(nsCOMPtr<nsIAccessibleDocument>(GetDocAccessible()));
|
||||
|
@ -137,16 +122,6 @@ NS_IMETHODIMP nsHTMLHRAccessible::GetRole(PRUint32 *aRole)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsHTMLHRAccessible::GetState(PRUint32 *aState, PRUint32 *aExtraState)
|
||||
{
|
||||
nsresult rv = nsLeafAccessible::GetState(aState, aExtraState);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
*aState &= ~nsIAccessibleStates::STATE_FOCUSABLE;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsHTMLBRAccessible::nsHTMLBRAccessible(nsIDOMNode* aDomNode, nsIWeakReference* aShell):
|
||||
nsLeafAccessible(aDomNode, aShell)
|
||||
{
|
||||
|
@ -162,6 +137,9 @@ NS_IMETHODIMP
|
|||
nsHTMLBRAccessible::GetState(PRUint32 *aState, PRUint32 *aExtraState)
|
||||
{
|
||||
*aState = nsIAccessibleStates::STATE_READONLY;
|
||||
if (aExtraState) {
|
||||
*aExtraState = mDOMNode ? 0 : nsIAccessibleStates::EXT_STATE_DEFUNCT;
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -171,6 +149,10 @@ NS_IMETHODIMP nsHTMLBRAccessible::GetName(nsAString& aName)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
// A label is an element (not a leaf) and thus can support advanced interfaces.
|
||||
// We need to skip over nsTextAccessible QI which prevents that
|
||||
NS_IMPL_ISUPPORTS_INHERITED0(nsHTMLLabelAccessible, nsLinkableAccessible)
|
||||
|
||||
nsHTMLLabelAccessible::nsHTMLLabelAccessible(nsIDOMNode* aDomNode, nsIWeakReference* aShell):
|
||||
nsTextAccessible(aDomNode, aShell)
|
||||
{
|
||||
|
@ -205,9 +187,10 @@ nsHTMLLabelAccessible::GetState(PRUint32 *aState, PRUint32 *aExtraState)
|
|||
{
|
||||
nsresult rv = nsTextAccessible::GetState(aState, aExtraState);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
if (mDOMNode) {
|
||||
*aState &= (nsIAccessibleStates::STATE_LINKED |
|
||||
nsIAccessibleStates::STATE_TRAVERSED); // Only use link states
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -367,9 +350,14 @@ nsHTMLListBulletAccessible::GetParent(nsIAccessible **aParentAccessible)
|
|||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsHTMLListBulletAccessible::GetContentText(nsAString& aText)
|
||||
nsHTMLListBulletAccessible::AppendTextTo(nsAString& aText, PRUint32 aStartOffset,
|
||||
PRUint32 aLength)
|
||||
{
|
||||
aText = mBulletText;
|
||||
PRUint32 maxLength = mBulletText.Length() - aStartOffset;
|
||||
if (aLength > maxLength) {
|
||||
aLength = maxLength;
|
||||
}
|
||||
aText += nsDependentSubstring(mBulletText, aStartOffset, aLength);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -63,7 +63,6 @@ class nsHTMLHRAccessible : public nsLeafAccessible
|
|||
public:
|
||||
nsHTMLHRAccessible(nsIDOMNode* aDomNode, nsIWeakReference* aShell);
|
||||
NS_IMETHOD GetRole(PRUint32 *aRole);
|
||||
NS_IMETHOD GetState(PRUint32 *aState, PRUint32 *aExtraState);
|
||||
};
|
||||
|
||||
class nsHTMLBRAccessible : public nsLeafAccessible
|
||||
|
@ -79,6 +78,7 @@ class nsHTMLLabelAccessible : public nsTextAccessible
|
|||
{
|
||||
public:
|
||||
nsHTMLLabelAccessible(nsIDOMNode* aDomNode, nsIWeakReference* aShell);
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
NS_IMETHOD GetName(nsAString& _retval);
|
||||
NS_IMETHOD GetRole(PRUint32 *_retval);
|
||||
NS_IMETHOD GetState(PRUint32 *aState, PRUint32 *aExtraState);
|
||||
|
@ -111,7 +111,7 @@ public:
|
|||
NS_IMETHOD GetParent(nsIAccessible **aParentAccessible);
|
||||
|
||||
// nsPIAccessible
|
||||
NS_IMETHOD GetContentText(nsAString& aText);
|
||||
NS_IMETHOD AppendTextTo(nsAString& aText, PRUint32 aStartOffset, PRUint32 aLength);
|
||||
|
||||
protected:
|
||||
// XXX: Ideally we'd get the bullet text directly from the bullet frame via
|
||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -45,8 +45,6 @@
|
|||
#include "nsIAccessibleHyperText.h"
|
||||
#include "nsIAccessibleEditableText.h"
|
||||
#include "nsAccessibleEventData.h"
|
||||
#include "nsIEditActionListener.h"
|
||||
#include "nsIEditor.h"
|
||||
#include "nsFrameSelection.h"
|
||||
#include "nsISelectionController.h"
|
||||
|
||||
|
@ -55,16 +53,25 @@ enum EGetTextType { eGetBefore=-1, eGetAt=0, eGetAfter=1 };
|
|||
// This character marks where in the text returned via nsIAccessibleText(),
|
||||
// that embedded object characters exist
|
||||
const PRUnichar kEmbeddedObjectChar = 0xfffc;
|
||||
const PRUnichar kImaginaryEmbeddedObjectChar = ' ';
|
||||
const PRUnichar kForcedNewLineChar = '\n';
|
||||
|
||||
#define NS_HYPERTEXTACCESSIBLE_IMPL_CID \
|
||||
{ /* 245f3bc9-224f-4839-a92e-95239705f30b */ \
|
||||
0x245f3bc9, \
|
||||
0x224f, \
|
||||
0x4839, \
|
||||
{ 0xa9, 0x2e, 0x95, 0x23, 0x97, 0x05, 0xf3, 0x0b } \
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Special Accessible that knows how contain both text and embedded objects
|
||||
*/
|
||||
class nsHyperTextAccessible : public nsAccessibleWrap,
|
||||
public nsIAccessibleText,
|
||||
public nsIAccessibleHyperText,
|
||||
public nsIAccessibleEditableText,
|
||||
public nsIEditActionListener
|
||||
public nsIAccessibleEditableText
|
||||
{
|
||||
public:
|
||||
nsHyperTextAccessible(nsIDOMNode* aNode, nsIWeakReference* aShell);
|
||||
|
@ -72,16 +79,69 @@ public:
|
|||
NS_DECL_NSIACCESSIBLETEXT
|
||||
NS_DECL_NSIACCESSIBLEHYPERTEXT
|
||||
NS_DECL_NSIACCESSIBLEEDITABLETEXT
|
||||
NS_DECL_NSIEDITACTIONLISTENER
|
||||
NS_DECLARE_STATIC_IID_ACCESSOR(NS_HYPERTEXTACCESSIBLE_IMPL_CID)
|
||||
|
||||
NS_IMETHOD GetRole(PRUint32 *aRole);
|
||||
NS_IMETHOD GetState(PRUint32 *aState, PRUint32 *aExtraState);
|
||||
virtual nsresult GetAttributesInternal(nsIPersistentProperties *aAttributes);
|
||||
void CacheChildren();
|
||||
|
||||
protected:
|
||||
PRBool IsHyperText();
|
||||
// Convert content offset to rendered text offset
|
||||
static nsresult ContentToRenderedOffset(nsIFrame *aFrame, PRInt32 aContentOffset,
|
||||
PRUint32 *aRenderedOffset);
|
||||
|
||||
// Convert rendered text offset to content offset
|
||||
static nsresult RenderedToContentOffset(nsIFrame *aFrame, PRUint32 aRenderedOffset,
|
||||
PRInt32 *aContentOffset);
|
||||
|
||||
/**
|
||||
* Turn a DOM Node and offset into a character offset into this hypertext.
|
||||
* Will look for closest match when the DOM node does not have an accessible
|
||||
* object associated with it. Will return an offset for the end of
|
||||
* the string if the node is not found.
|
||||
*
|
||||
* @param aNode - the node to look for
|
||||
* @param aNodeOffset - the offset to look for
|
||||
* if -1 just look directly for the node
|
||||
* if >=0 and aNode is text, this represents a char offset
|
||||
* if >=0 and aNode is not text, this represents a child node offset
|
||||
* @param aResultOffset - the character offset into the current
|
||||
* nsHyperTextAccessible
|
||||
* @param aFinalAccessible [optional] - returns the accessible child which
|
||||
* contained the offset, if it is within
|
||||
* the current nsHyperTextAccessible,
|
||||
* otherwise it is set to nsnull.
|
||||
* @param aIsEndOffset - if PR_TRUE, then then this offset is not inclusive. The character
|
||||
* indicated by the offset returned is at [offset - 1]. This means
|
||||
* if the passed-in offset is really in a descendant, then the offset returned
|
||||
* will come just after the relevant embedded object characer.
|
||||
* If PR_FALSE, then the offset is inclusive. The character indicated
|
||||
* by the offset returned is at [offset]. If the passed-in offset in inside a
|
||||
* descendant, then the returned offset will be on the relevant embedded object char.
|
||||
*/
|
||||
nsresult DOMPointToHypertextOffset(nsIDOMNode* aNode, PRInt32 aNodeOffset,
|
||||
PRInt32 *aHypertextOffset,
|
||||
nsIAccessible **aFinalAccessible = nsnull,
|
||||
PRBool aIsEndOffset = PR_FALSE);
|
||||
|
||||
/**
|
||||
* Turn a start and end hypertext offsets into DOM range.
|
||||
*
|
||||
* @param aStartHTOffset [in] the given start hypertext offset
|
||||
* @param aEndHTOffset [in] the given end hypertext offset
|
||||
* @param aStartNode [out] start node of the range
|
||||
* @param aStartOffset [out] start offset of the range
|
||||
* @param aEndNode [out] end node of the range
|
||||
* @param aEndOffset [out] end offset of the range
|
||||
*/
|
||||
nsresult HypertextOffsetsToDOMRange(PRInt32 aStartHTOffset,
|
||||
PRInt32 aEndHTOffset,
|
||||
nsIDOMNode **aStartNode,
|
||||
PRInt32 *aStartOffset,
|
||||
nsIDOMNode **aEndNode,
|
||||
PRInt32 *aEndOffset);
|
||||
|
||||
protected:
|
||||
/*
|
||||
* This does the work for nsIAccessibleText::GetText[At|Before|After]Offset
|
||||
* @param aType, eGetBefore, eGetAt, eGetAfter
|
||||
|
@ -97,54 +157,86 @@ protected:
|
|||
nsAString & aText);
|
||||
|
||||
/**
|
||||
* Used by GetPosAndText to move backward/forward from a given point by word/line/etc.
|
||||
* @param aPresShell, the current presshell we're moving in
|
||||
* @param aFromFrame, the starting frame we're moving from
|
||||
* @param aFromOffset, the starting offset we're moving from
|
||||
* @param aAmount, how much are we moving (word/line/etc.) ?
|
||||
* @param aDirection, forward or backward?
|
||||
* @param aNeedsStart, for word and line cases, are we basing this on the start or end?
|
||||
* @return, the resulting offset into this hypertext
|
||||
* Used by GetTextHelper() to move backward/forward from a given point
|
||||
* by word/line/etc.
|
||||
*
|
||||
* @param aPresShell the current presshell we're moving in
|
||||
* @param aFromFrame the starting frame we're moving from
|
||||
* @param aFromOffset the starting offset we're moving from
|
||||
* @param aFromAccessible the starting accessible we're moving from
|
||||
* @param aAmount how much are we moving (word/line/etc.) ?
|
||||
* @param aDirection forward or backward?
|
||||
* @param aNeedsStart for word and line cases, are we basing this on
|
||||
* the start or end?
|
||||
* @return the resulting offset into this hypertext
|
||||
*/
|
||||
PRInt32 GetRelativeOffset(nsIPresShell *aPresShell, nsIFrame *aFromFrame, PRInt32 aFromOffset,
|
||||
nsSelectionAmount aAmount, nsDirection aDirection, PRBool aNeedsStart);
|
||||
PRInt32 GetRelativeOffset(nsIPresShell *aPresShell, nsIFrame *aFromFrame,
|
||||
PRInt32 aFromOffset, nsIAccessible *aFromAccessible,
|
||||
nsSelectionAmount aAmount, nsDirection aDirection,
|
||||
PRBool aNeedsStart);
|
||||
|
||||
/**
|
||||
* Given a start offset and end offset, get substring information. Different info is returned depending
|
||||
* on what optional paramters are provided.
|
||||
* @param aStartOffset, the start offset into the hyper text. This is also an out parameter used to return
|
||||
* the offset into the start frame's text content (start frame is the @return)
|
||||
* @param aEndOffset, the endoffset into the hyper text. This is also an out parameter used to return
|
||||
* the offset into the end frame's text content
|
||||
* @param aText (optional), return the substring's text
|
||||
* @param aEndFrame (optional), return the end frame for this substring
|
||||
* @param aBoundsRect (optional), return the bounds rectangle for this substring
|
||||
* Provides information for substring that is defined by the given start
|
||||
* and end offsets for this hyper text.
|
||||
*
|
||||
* @param aStartOffset [inout] the start offset into the hyper text. This
|
||||
* is also an out parameter used to return the offset
|
||||
* into the start frame's rendered text content
|
||||
* (start frame is the @return)
|
||||
*
|
||||
* @param aEndOffset [inout] the end offset into the hyper text. This is
|
||||
* also an out parameter used to return
|
||||
* the offset into the end frame's rendered
|
||||
* text content.
|
||||
*
|
||||
* @param aText [out, optional] return the substring's text
|
||||
* @param aEndFrame [out, optional] return the end frame for this
|
||||
* substring
|
||||
* @param aBoundsRect [out, optional] return the bounds rectangle for this
|
||||
* substring
|
||||
* @param aStartAcc [out, optional] return the start accessible for this
|
||||
* substring
|
||||
* @param aEndAcc [out, optional] return the end accessible for this
|
||||
* substring
|
||||
* @return the start frame for this substring
|
||||
*/
|
||||
nsIFrame* GetPosAndText(PRInt32& aStartOffset, PRInt32& aEndOffset, nsAString *aText = nsnull,
|
||||
nsIFrame **aEndFrame = nsnull, nsIntRect *aBoundsRect = nsnull);
|
||||
/**
|
||||
* Turn a DOM Node and offset into a character offset into this hypertext. Will look for closest match
|
||||
* when the DOM node does not have an accessible object associated with it.
|
||||
* Will return an offset for the end of the string if the node is not found.
|
||||
* @param aNode, the node to look for
|
||||
* @param aNodeOffset, the offset to look for
|
||||
* @param aResult, the character offset into the current nsHyperTextAccessible
|
||||
* @param aFinalAccessible (optional), returns the accessible child which contained the offset,
|
||||
* if it is within the current nsHyperTextAccessible, otherwise
|
||||
* it is set to nsnull.
|
||||
* @return failure/success code
|
||||
*/
|
||||
nsresult DOMPointToOffset(nsIDOMNode* aNode, PRInt32 aNodeOffset, PRInt32 *aResultOffset,
|
||||
nsIAccessible **aFinalAccessible = nsnull);
|
||||
nsIntRect GetBoundsForString(nsIFrame *aFrame, PRInt32 aStartOffset, PRInt32 aLength);
|
||||
nsIFrame* GetPosAndText(PRInt32& aStartOffset, PRInt32& aEndOffset,
|
||||
nsAString *aText = nsnull,
|
||||
nsIFrame **aEndFrame = nsnull,
|
||||
nsIntRect *aBoundsRect = nsnull,
|
||||
nsIAccessible **aStartAcc = nsnull,
|
||||
nsIAccessible **aEndAcc = nsnull);
|
||||
|
||||
// Editor helpers, subclasses of nsHyperTextAccessible may have editor
|
||||
virtual void SetEditor(nsIEditor *aEditor) { return; }
|
||||
virtual already_AddRefed<nsIEditor> GetEditor() { return nsnull; }
|
||||
nsIntRect GetBoundsForString(nsIFrame *aFrame, PRUint32 aStartRenderedOffset, PRUint32 aEndRenderedOffset);
|
||||
|
||||
// Selection helpers
|
||||
nsresult GetSelections(nsISelectionController **aSelCon, nsISelection **aDomSel);
|
||||
|
||||
/**
|
||||
* Get the relevant selection interfaces and ranges for the current hyper text
|
||||
* @param aSelCon The selection controller for the current hyper text, or nsnull if not needed
|
||||
* @param aDomSel The selection interface for the current hyper text, or nsnull if not needed
|
||||
* @param aRanges The selected ranges within the current subtree, or nsnull if not needed
|
||||
*/
|
||||
nsresult GetSelections(nsISelectionController **aSelCon,
|
||||
nsISelection **aDomSel = nsnull,
|
||||
nsCOMArray<nsIDOMRange>* aRanges = nsnull);
|
||||
nsresult SetSelectionRange(PRInt32 aStartPos, PRInt32 aEndPos);
|
||||
|
||||
/**
|
||||
* Provide the line number for the caret, relative to the
|
||||
* current DOM node.
|
||||
* @return 1-based index for the line number with the caret
|
||||
*/
|
||||
PRInt32 GetCaretLineNumber();
|
||||
|
||||
// Helpers
|
||||
nsresult GetDOMPointByFrameOffset(nsIFrame *aFrame, PRInt32 aOffset,
|
||||
nsIAccessible *aAccessible,
|
||||
nsIDOMNode **aNode, PRInt32 *aNodeOffset);
|
||||
};
|
||||
|
||||
NS_DEFINE_STATIC_IID_ACCESSOR(nsHyperTextAccessible,
|
||||
NS_HYPERTEXTACCESSIBLE_IMPL_CID)
|
||||
|
||||
#endif // _nsHyperTextAccessible_H_
|
||||
|
||||
|
|
|
@ -51,6 +51,7 @@ REQUIRES = content \
|
|||
dom \
|
||||
editor \
|
||||
gfx \
|
||||
thebes \
|
||||
intl \
|
||||
locale \
|
||||
string \
|
||||
|
|
|
@ -44,6 +44,7 @@
|
|||
|
||||
#include "nsRect.h"
|
||||
#include "nsCoord.h"
|
||||
#include "nsObjCExceptions.h"
|
||||
|
||||
#include "nsIAccessible.h"
|
||||
#include "nsIAccessibleText.h"
|
||||
|
@ -73,9 +74,13 @@ ConvertCocoaToGeckoPoint(NSPoint &aInPoint, nsPoint &aOutPoint)
|
|||
static inline id <mozAccessible>
|
||||
GetObjectOrRepresentedView(id <mozAccessible> anObject)
|
||||
{
|
||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
|
||||
|
||||
if ([anObject hasRepresentedView])
|
||||
return [anObject representedView];
|
||||
return anObject;
|
||||
|
||||
NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
|
||||
}
|
||||
|
||||
// returns the passed in object if it is not ignored. if it's ignored, will return
|
||||
|
@ -83,6 +88,8 @@ GetObjectOrRepresentedView(id <mozAccessible> anObject)
|
|||
static inline id
|
||||
GetClosestInterestingAccessible(id anObject)
|
||||
{
|
||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
|
||||
|
||||
// this object is not ignored, so let's return it.
|
||||
if (![anObject accessibilityIsIgnored])
|
||||
return GetObjectOrRepresentedView(anObject);
|
||||
|
@ -101,14 +108,20 @@ GetClosestInterestingAccessible(id anObject)
|
|||
return GetObjectOrRepresentedView(unignoredObject);
|
||||
|
||||
return unignoredObject;
|
||||
|
||||
NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
|
||||
}
|
||||
|
||||
static inline mozAccessible*
|
||||
GetNativeFromGeckoAccessible(nsIAccessible *anAccessible)
|
||||
{
|
||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSNULL;
|
||||
|
||||
mozAccessible *native = nil;
|
||||
anAccessible->GetNativeInterface ((void**)&native);
|
||||
return native;
|
||||
|
||||
NS_OBJC_END_TRY_ABORT_BLOCK_NSNULL;
|
||||
}
|
||||
|
||||
#pragma mark -
|
||||
|
@ -117,6 +130,8 @@ GetNativeFromGeckoAccessible(nsIAccessible *anAccessible)
|
|||
|
||||
- (id)initWithAccessible:(nsAccessibleWrap*)geckoAccessible
|
||||
{
|
||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
|
||||
|
||||
if ((self = [super init])) {
|
||||
mGeckoAccessible = geckoAccessible;
|
||||
mIsExpired = NO;
|
||||
|
@ -128,25 +143,37 @@ GetNativeFromGeckoAccessible(nsIAccessible *anAccessible)
|
|||
}
|
||||
|
||||
return self;
|
||||
|
||||
NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
|
||||
}
|
||||
|
||||
- (void)dealloc
|
||||
{
|
||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK;
|
||||
|
||||
[mChildren release];
|
||||
[super dealloc];
|
||||
|
||||
NS_OBJC_END_TRY_ABORT_BLOCK;
|
||||
}
|
||||
|
||||
#pragma mark -
|
||||
|
||||
- (BOOL)accessibilityIsIgnored
|
||||
{
|
||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_RETURN;
|
||||
|
||||
// unknown (either unimplemented, or irrelevant) elements are marked as ignored
|
||||
// as well as expired elements.
|
||||
return mIsExpired || [[self role] isEqualToString:NSAccessibilityUnknownRole];
|
||||
|
||||
NS_OBJC_END_TRY_ABORT_BLOCK_RETURN(NO);
|
||||
}
|
||||
|
||||
- (NSArray*)accessibilityAttributeNames
|
||||
{
|
||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
|
||||
|
||||
// if we're expired, we don't support any attributes.
|
||||
if (mIsExpired)
|
||||
return [NSArray array];
|
||||
|
@ -177,10 +204,14 @@ GetNativeFromGeckoAccessible(nsIAccessible *anAccessible)
|
|||
}
|
||||
|
||||
return generalAttributes;
|
||||
|
||||
NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
|
||||
}
|
||||
|
||||
- (id)accessibilityAttributeValue:(NSString*)attribute
|
||||
{
|
||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
|
||||
|
||||
if (mIsExpired)
|
||||
return nil;
|
||||
|
||||
|
@ -227,18 +258,26 @@ GetNativeFromGeckoAccessible(nsIAccessible *anAccessible)
|
|||
NSLog (@"!!! %@ can't respond to attribute %@", self, attribute);
|
||||
#endif
|
||||
return nil; // be nice and return empty string instead?
|
||||
|
||||
NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
|
||||
}
|
||||
|
||||
- (BOOL)accessibilityIsAttributeSettable:(NSString*)attribute
|
||||
{
|
||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_RETURN;
|
||||
|
||||
if ([attribute isEqualToString:NSAccessibilityFocusedAttribute])
|
||||
return [self canBeFocused];
|
||||
|
||||
return NO;
|
||||
|
||||
NS_OBJC_END_TRY_ABORT_BLOCK_RETURN(NO);
|
||||
}
|
||||
|
||||
- (void)accessibilitySetValue:(id)value forAttribute:(NSString*)attribute
|
||||
{
|
||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK;
|
||||
|
||||
#ifdef DEBUG_hakan
|
||||
NSLog (@"[%@] %@='%@'", self, attribute, value);
|
||||
#endif
|
||||
|
@ -246,6 +285,8 @@ GetNativeFromGeckoAccessible(nsIAccessible *anAccessible)
|
|||
// we only support focusing elements so far.
|
||||
if ([attribute isEqualToString:NSAccessibilityFocusedAttribute] && [value boolValue])
|
||||
[self focus];
|
||||
|
||||
NS_OBJC_END_TRY_ABORT_BLOCK;
|
||||
}
|
||||
|
||||
- (id)accessibilityHitTest:(NSPoint)point
|
||||
|
@ -315,6 +356,8 @@ GetNativeFromGeckoAccessible(nsIAccessible *anAccessible)
|
|||
|
||||
- (id <mozAccessible>)parent
|
||||
{
|
||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
|
||||
|
||||
nsCOMPtr<nsIAccessible> accessibleParent(mGeckoAccessible->GetUnignoredParent());
|
||||
if (accessibleParent) {
|
||||
id nativeParent = GetNativeFromGeckoAccessible(accessibleParent);
|
||||
|
@ -332,6 +375,8 @@ GetNativeFromGeckoAccessible(nsIAccessible *anAccessible)
|
|||
NSAssert1 (nativeParent, @"!!! we can't find a parent for %@", self);
|
||||
|
||||
return GetClosestInterestingAccessible(nativeParent);
|
||||
|
||||
NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
|
||||
}
|
||||
|
||||
- (BOOL)hasRepresentedView
|
||||
|
@ -353,6 +398,8 @@ GetNativeFromGeckoAccessible(nsIAccessible *anAccessible)
|
|||
// returns nil when there are no children.
|
||||
- (NSArray*)children
|
||||
{
|
||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
|
||||
|
||||
if (mChildren)
|
||||
return mChildren;
|
||||
|
||||
|
@ -385,10 +432,14 @@ GetNativeFromGeckoAccessible(nsIAccessible *anAccessible)
|
|||
#endif
|
||||
|
||||
return mChildren;
|
||||
|
||||
NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
|
||||
}
|
||||
|
||||
- (NSValue*)position
|
||||
{
|
||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
|
||||
|
||||
PRInt32 x, y, width, height;
|
||||
mGeckoAccessible->GetBounds (&x, &y, &width, &height);
|
||||
NSPoint p = NSMakePoint (x, y);
|
||||
|
@ -404,13 +455,19 @@ GetNativeFromGeckoAccessible(nsIAccessible *anAccessible)
|
|||
p.y = mainScreenHeight - p.y - height;
|
||||
|
||||
return [NSValue valueWithPoint:p];
|
||||
|
||||
NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
|
||||
}
|
||||
|
||||
- (NSValue*)size
|
||||
{
|
||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
|
||||
|
||||
PRInt32 x, y, width, height;
|
||||
mGeckoAccessible->GetBounds (&x, &y, &width, &height);
|
||||
return [NSValue valueWithSize:NSMakeSize (width, height)];
|
||||
|
||||
NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
|
||||
}
|
||||
|
||||
- (NSString*)role
|
||||
|
@ -428,45 +485,69 @@ GetNativeFromGeckoAccessible(nsIAccessible *anAccessible)
|
|||
|
||||
- (NSString*)title
|
||||
{
|
||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
|
||||
|
||||
nsAutoString title;
|
||||
mGeckoAccessible->GetName (title);
|
||||
return title.IsEmpty() ? nil : [NSString stringWithCharacters:title.BeginReading() length:title.Length()];
|
||||
|
||||
NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
|
||||
}
|
||||
|
||||
- (id)value
|
||||
{
|
||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
|
||||
|
||||
nsAutoString value;
|
||||
mGeckoAccessible->GetValue (value);
|
||||
return value.IsEmpty() ? nil : [NSString stringWithCharacters:value.BeginReading() length:value.Length()];
|
||||
|
||||
NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
|
||||
}
|
||||
|
||||
- (void)valueDidChange
|
||||
{
|
||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK;
|
||||
|
||||
#ifdef DEBUG_hakan
|
||||
NSLog(@"%@'s value changed!", self);
|
||||
#endif
|
||||
// sending out a notification is expensive, so we don't do it other than for really important objects,
|
||||
// like mozTextAccessible.
|
||||
|
||||
NS_OBJC_END_TRY_ABORT_BLOCK;
|
||||
}
|
||||
|
||||
- (NSString*)customDescription
|
||||
{
|
||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
|
||||
|
||||
nsAutoString desc;
|
||||
mGeckoAccessible->GetDescription (desc);
|
||||
return desc.IsEmpty() ? nil : [NSString stringWithCharacters:desc.BeginReading() length:desc.Length()];
|
||||
|
||||
NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
|
||||
}
|
||||
|
||||
- (NSString*)help
|
||||
{
|
||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
|
||||
|
||||
nsAutoString helpText;
|
||||
mGeckoAccessible->GetHelp (helpText);
|
||||
return helpText.IsEmpty() ? nil : [NSString stringWithCharacters:helpText.BeginReading() length:helpText.Length()];
|
||||
|
||||
NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
|
||||
}
|
||||
|
||||
// objc-style description (from NSObject); not to be confused with the accessible description above.
|
||||
- (NSString*)description
|
||||
{
|
||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
|
||||
|
||||
return [NSString stringWithFormat:@"(%p) %@", self, [self role]];
|
||||
|
||||
NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
|
||||
}
|
||||
|
||||
- (BOOL)isFocused
|
||||
|
@ -500,35 +581,51 @@ GetNativeFromGeckoAccessible(nsIAccessible *anAccessible)
|
|||
// changed to us.
|
||||
- (void)didReceiveFocus
|
||||
{
|
||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK;
|
||||
|
||||
#ifdef DEBUG_hakan
|
||||
NSLog (@"%@ received focus!", self);
|
||||
#endif
|
||||
NSAssert1(![self accessibilityIsIgnored], @"trying to set focus to ignored element! (%@)", self);
|
||||
NSAccessibilityPostNotification(GetObjectOrRepresentedView(self),
|
||||
NSAccessibilityFocusedUIElementChangedNotification);
|
||||
|
||||
NS_OBJC_END_TRY_ABORT_BLOCK;
|
||||
}
|
||||
|
||||
- (NSWindow*)window
|
||||
{
|
||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
|
||||
|
||||
nsAccessibleWrap *accWrap = static_cast<nsAccessibleWrap*>(mGeckoAccessible);
|
||||
NSWindow *nativeWindow = nil;
|
||||
accWrap->GetNativeWindow ((void**)&nativeWindow);
|
||||
|
||||
NSAssert1(nativeWindow, @"Could not get native window for %@", self);
|
||||
return nativeWindow;
|
||||
|
||||
NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
|
||||
}
|
||||
|
||||
- (void)invalidateChildren
|
||||
{
|
||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK;
|
||||
|
||||
// make room for new children
|
||||
[mChildren release];
|
||||
mChildren = nil;
|
||||
|
||||
NS_OBJC_END_TRY_ABORT_BLOCK;
|
||||
}
|
||||
|
||||
- (void)expire
|
||||
{
|
||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK;
|
||||
|
||||
[self invalidateChildren];
|
||||
mIsExpired = YES;
|
||||
|
||||
NS_OBJC_END_TRY_ABORT_BLOCK;
|
||||
}
|
||||
|
||||
- (BOOL)isExpired
|
||||
|
@ -546,6 +643,8 @@ GetNativeFromGeckoAccessible(nsIAccessible *anAccessible)
|
|||
// parent.
|
||||
- (void)sanityCheckChildren:(NSArray *)children
|
||||
{
|
||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK;
|
||||
|
||||
NSAssert(![self accessibilityIsIgnored], @"can't sanity check children of an ignored accessible!");
|
||||
NSEnumerator *iter = [children objectEnumerator];
|
||||
mozAccessible *curObj = nil;
|
||||
|
@ -558,20 +657,32 @@ GetNativeFromGeckoAccessible(nsIAccessible *anAccessible)
|
|||
NSAssert2([curObj parent] == realSelf,
|
||||
@"!!! %@ not returning %@ as AXParent, even though it is a AXChild of it!", curObj, realSelf);
|
||||
}
|
||||
|
||||
NS_OBJC_END_TRY_ABORT_BLOCK;
|
||||
}
|
||||
|
||||
- (void)sanityCheckChildren
|
||||
{
|
||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK;
|
||||
|
||||
[self sanityCheckChildren:[self children]];
|
||||
|
||||
NS_OBJC_END_TRY_ABORT_BLOCK;
|
||||
}
|
||||
|
||||
- (void)printHierarchy
|
||||
{
|
||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK;
|
||||
|
||||
[self printHierarchyWithLevel:0];
|
||||
|
||||
NS_OBJC_END_TRY_ABORT_BLOCK;
|
||||
}
|
||||
|
||||
- (void)printHierarchyWithLevel:(unsigned)level
|
||||
{
|
||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK;
|
||||
|
||||
NSAssert(![self isExpired], @"!!! trying to print hierarchy of expired object!");
|
||||
|
||||
// print this node
|
||||
|
@ -597,6 +708,8 @@ GetNativeFromGeckoAccessible(nsIAccessible *anAccessible)
|
|||
// print every child node's subtree, increasing the indenting
|
||||
// by two for every level.
|
||||
[object printHierarchyWithLevel:(level+1)];
|
||||
|
||||
NS_OBJC_END_TRY_ABORT_BLOCK;
|
||||
}
|
||||
|
||||
#endif /* DEBUG */
|
||||
|
|
|
@ -38,6 +38,8 @@
|
|||
|
||||
#include "nsAccessibleWrap.h"
|
||||
|
||||
#include "nsObjCExceptions.h"
|
||||
|
||||
#import "mozAccessible.h"
|
||||
|
||||
/* Wrapper class.
|
||||
|
@ -56,15 +58,23 @@
|
|||
struct AccessibleWrapper {
|
||||
mozAccessible *object;
|
||||
AccessibleWrapper (nsAccessibleWrap *parent, Class classType) {
|
||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK;
|
||||
|
||||
object = (mozAccessible*)[[classType alloc] initWithAccessible:parent];
|
||||
|
||||
NS_OBJC_END_TRY_ABORT_BLOCK;
|
||||
}
|
||||
|
||||
~AccessibleWrapper () {
|
||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK;
|
||||
|
||||
// if some third-party still holds on to the object, it's important that it is marked
|
||||
// as expired, so it can't do any harm (e.g., walk into an expired hierarchy of nodes).
|
||||
[object expire];
|
||||
|
||||
[object release];
|
||||
|
||||
NS_OBJC_END_TRY_ABORT_BLOCK;
|
||||
}
|
||||
|
||||
mozAccessible* getNativeObject () {
|
||||
|
@ -72,6 +82,10 @@ struct AccessibleWrapper {
|
|||
}
|
||||
|
||||
PRBool isIgnored () {
|
||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_RETURN;
|
||||
|
||||
return (PRBool)[object accessibilityIsIgnored];
|
||||
|
||||
NS_OBJC_END_TRY_ABORT_BLOCK_RETURN(PR_FALSE);
|
||||
}
|
||||
};
|
||||
|
|
|
@ -39,6 +39,8 @@
|
|||
#import "mozActionElements.h"
|
||||
#import "nsIAccessible.h"
|
||||
|
||||
#include "nsObjCExceptions.h"
|
||||
|
||||
extern const NSString *kInstanceDescriptionAttribute; // NSAccessibilityDescriptionAttribute
|
||||
extern const NSString *kTopLevelUIElementAttribute; // NSAccessibilityTopLevelUIElementAttribute
|
||||
|
||||
|
@ -53,6 +55,8 @@ enum CheckboxValue {
|
|||
|
||||
- (NSArray*)accessibilityAttributeNames
|
||||
{
|
||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
|
||||
|
||||
static NSArray *attributes = nil;
|
||||
if (!attributes) {
|
||||
attributes = [[NSArray alloc] initWithObjects:NSAccessibilityParentAttribute, // required
|
||||
|
@ -70,13 +74,19 @@ enum CheckboxValue {
|
|||
nil];
|
||||
}
|
||||
return attributes;
|
||||
|
||||
NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
|
||||
}
|
||||
|
||||
- (id)accessibilityAttributeValue:(NSString *)attribute
|
||||
{
|
||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
|
||||
|
||||
if ([attribute isEqualToString:NSAccessibilityChildrenAttribute])
|
||||
return nil;
|
||||
return [super accessibilityAttributeValue:attribute];
|
||||
|
||||
NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
|
||||
}
|
||||
|
||||
- (BOOL)accessibilityIsIgnored
|
||||
|
@ -86,24 +96,36 @@ enum CheckboxValue {
|
|||
|
||||
- (NSArray*)accessibilityActionNames
|
||||
{
|
||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
|
||||
|
||||
if ([self isEnabled])
|
||||
return [NSArray arrayWithObject:NSAccessibilityPressAction];
|
||||
|
||||
return nil;
|
||||
|
||||
NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
|
||||
}
|
||||
|
||||
- (NSString*)accessibilityActionDescription:(NSString*)action
|
||||
{
|
||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
|
||||
|
||||
if ([action isEqualToString:NSAccessibilityPressAction])
|
||||
return @"press button"; // XXX: localize this later?
|
||||
|
||||
return nil;
|
||||
|
||||
NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
|
||||
}
|
||||
|
||||
- (void)accessibilityPerformAction:(NSString*)action
|
||||
{
|
||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK;
|
||||
|
||||
if ([action isEqualToString:NSAccessibilityPressAction])
|
||||
[self click];
|
||||
|
||||
NS_OBJC_END_TRY_ABORT_BLOCK;
|
||||
}
|
||||
|
||||
- (void)click
|
||||
|
@ -119,6 +141,8 @@ enum CheckboxValue {
|
|||
|
||||
- (NSString*)accessibilityActionDescription:(NSString*)action
|
||||
{
|
||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
|
||||
|
||||
if ([action isEqualToString:NSAccessibilityPressAction]) {
|
||||
if ([self isChecked] != kUnchecked)
|
||||
return @"uncheck checkbox"; // XXX: localize this later?
|
||||
|
@ -127,6 +151,8 @@ enum CheckboxValue {
|
|||
}
|
||||
|
||||
return nil;
|
||||
|
||||
NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
|
||||
}
|
||||
|
||||
- (int)isChecked
|
||||
|
@ -144,7 +170,11 @@ enum CheckboxValue {
|
|||
|
||||
- (id)value
|
||||
{
|
||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
|
||||
|
||||
return [NSNumber numberWithInt:[self isChecked]];
|
||||
|
||||
NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
|
||||
}
|
||||
|
||||
@end
|
||||
|
@ -153,6 +183,8 @@ enum CheckboxValue {
|
|||
|
||||
- (NSArray *)accessibilityAttributeNames
|
||||
{
|
||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
|
||||
|
||||
static NSArray *attributes = nil;
|
||||
|
||||
if (!attributes) {
|
||||
|
@ -171,18 +203,26 @@ enum CheckboxValue {
|
|||
nil];
|
||||
}
|
||||
return attributes;
|
||||
|
||||
NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
|
||||
}
|
||||
|
||||
- (id)accessibilityAttributeValue:(NSString *)attribute
|
||||
{
|
||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
|
||||
|
||||
if ([attribute isEqualToString:NSAccessibilityChildrenAttribute]) {
|
||||
return [super children];
|
||||
}
|
||||
return [super accessibilityAttributeValue:attribute];
|
||||
|
||||
NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
|
||||
}
|
||||
|
||||
- (NSArray *)accessibilityActionNames
|
||||
{
|
||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
|
||||
|
||||
if ([self isEnabled]) {
|
||||
return [NSArray arrayWithObjects:NSAccessibilityPressAction,
|
||||
#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_4
|
||||
|
@ -191,19 +231,27 @@ enum CheckboxValue {
|
|||
nil];
|
||||
}
|
||||
return nil;
|
||||
|
||||
NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
|
||||
}
|
||||
|
||||
- (NSString *)accessibilityActionDescription:(NSString *)action
|
||||
{
|
||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
|
||||
|
||||
#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_4
|
||||
if ([action isEqualToString:NSAccessibilityShowMenuAction])
|
||||
return @"show menu";
|
||||
#endif
|
||||
return [super accessibilityActionDescription:action];
|
||||
|
||||
NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
|
||||
}
|
||||
|
||||
- (void)accessibilityPerformAction:(NSString *)action
|
||||
{
|
||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK;
|
||||
|
||||
// both the ShowMenu and Click action do the same thing.
|
||||
if ([self isEnabled]) {
|
||||
// TODO: this should bring up the menu, but currently doesn't.
|
||||
|
@ -211,6 +259,8 @@ enum CheckboxValue {
|
|||
// the action needed to show the menu.
|
||||
[super click];
|
||||
}
|
||||
|
||||
NS_OBJC_END_TRY_ABORT_BLOCK;
|
||||
}
|
||||
|
||||
@end
|
||||
|
|
|
@ -37,6 +37,7 @@
|
|||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "nsRootAccessibleWrap.h"
|
||||
#include "nsObjCExceptions.h"
|
||||
|
||||
#import "mozDocAccessible.h"
|
||||
|
||||
|
@ -57,6 +58,8 @@ static id <mozAccessible, mozView> getNativeViewFromRootAccessible (nsAccessible
|
|||
// return the AXParent that our parallell NSView tells us about.
|
||||
- (id)parent
|
||||
{
|
||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
|
||||
|
||||
if (!mParallelView)
|
||||
mParallelView = (id<mozView, mozAccessible>)[self representedView];
|
||||
|
||||
|
@ -65,6 +68,8 @@ static id <mozAccessible, mozView> getNativeViewFromRootAccessible (nsAccessible
|
|||
|
||||
NSAssert(mParallelView, @"we're a root accessible w/o native view?");
|
||||
return [super parent];
|
||||
|
||||
NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
|
||||
}
|
||||
|
||||
- (BOOL)hasRepresentedView
|
||||
|
@ -75,6 +80,8 @@ static id <mozAccessible, mozView> getNativeViewFromRootAccessible (nsAccessible
|
|||
// this will return our parallell NSView. see mozDocAccessible.h
|
||||
- (id)representedView
|
||||
{
|
||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
|
||||
|
||||
if (mParallelView)
|
||||
return (id)mParallelView;
|
||||
|
||||
|
@ -82,6 +89,8 @@ static id <mozAccessible, mozView> getNativeViewFromRootAccessible (nsAccessible
|
|||
|
||||
NSAssert(mParallelView, @"can't return root accessible's native parallel view.");
|
||||
return mParallelView;
|
||||
|
||||
NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
|
||||
}
|
||||
|
||||
- (BOOL)isRoot
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
#include "nsAccessibleWrap.h"
|
||||
#include "nsObjCExceptions.h"
|
||||
|
||||
#import "mozTextAccessible.h"
|
||||
|
||||
|
@ -18,11 +19,15 @@ extern const NSString *kTopLevelUIElementAttribute; // NSAccessibilityTopLevel
|
|||
|
||||
- (id)initWithAccessible:(nsAccessibleWrap*)accessible
|
||||
{
|
||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
|
||||
|
||||
if ((self = [super initWithAccessible:accessible])) {
|
||||
CallQueryInterface(accessible, &mGeckoTextAccessible);
|
||||
CallQueryInterface(accessible, &mGeckoEditableTextAccessible);
|
||||
}
|
||||
return self;
|
||||
|
||||
NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
|
||||
}
|
||||
|
||||
- (BOOL)accessibilityIsIgnored
|
||||
|
@ -32,6 +37,8 @@ extern const NSString *kTopLevelUIElementAttribute; // NSAccessibilityTopLevel
|
|||
|
||||
- (NSArray*)accessibilityAttributeNames
|
||||
{
|
||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
|
||||
|
||||
static NSArray *supportedAttributes = nil;
|
||||
if (!supportedAttributes) {
|
||||
// standard attributes that are shared and supported by all generic elements.
|
||||
|
@ -59,10 +66,14 @@ extern const NSString *kTopLevelUIElementAttribute; // NSAccessibilityTopLevel
|
|||
nil];
|
||||
}
|
||||
return supportedAttributes;
|
||||
|
||||
NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
|
||||
}
|
||||
|
||||
- (id)accessibilityAttributeValue:(NSString*)attribute
|
||||
{
|
||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
|
||||
|
||||
if ([attribute isEqualToString:NSAccessibilityNumberOfCharactersAttribute])
|
||||
return [NSNumber numberWithInt:[self textLength]];
|
||||
if ([attribute isEqualToString:NSAccessibilitySelectedTextRangeAttribute])
|
||||
|
@ -72,23 +83,33 @@ extern const NSString *kTopLevelUIElementAttribute; // NSAccessibilityTopLevel
|
|||
|
||||
// let mozAccessible handle all other attributes
|
||||
return [super accessibilityAttributeValue:attribute];
|
||||
|
||||
NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
|
||||
}
|
||||
|
||||
- (BOOL)accessibilityIsAttributeSettable:(NSString*)attribute
|
||||
{
|
||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_RETURN;
|
||||
|
||||
if ([attribute isEqualToString:NSAccessibilityValueAttribute])
|
||||
return [self isReadOnly];
|
||||
|
||||
return [super accessibilityIsAttributeSettable:attribute];
|
||||
|
||||
NS_OBJC_END_TRY_ABORT_BLOCK_RETURN(NO);
|
||||
}
|
||||
|
||||
- (void)accessibilitySetValue:(id)value forAttribute:(NSString *)attribute
|
||||
{
|
||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK;
|
||||
|
||||
if ([attribute isEqualToString:NSAccessibilityValueAttribute]) {
|
||||
if ([value isKindOfClass:[NSString class]])
|
||||
[self setText:(NSString*)value];
|
||||
} else
|
||||
[super accessibilitySetValue:value forAttribute:attribute];
|
||||
|
||||
NS_OBJC_END_TRY_ABORT_BLOCK;
|
||||
}
|
||||
|
||||
- (NSString*)subrole
|
||||
|
@ -99,15 +120,21 @@ extern const NSString *kTopLevelUIElementAttribute; // NSAccessibilityTopLevel
|
|||
|
||||
- (void)expire
|
||||
{
|
||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK;
|
||||
|
||||
NS_IF_RELEASE(mGeckoTextAccessible);
|
||||
NS_IF_RELEASE(mGeckoEditableTextAccessible);
|
||||
[super expire];
|
||||
|
||||
NS_OBJC_END_TRY_ABORT_BLOCK;
|
||||
}
|
||||
|
||||
#pragma mark -
|
||||
|
||||
- (BOOL)isReadOnly
|
||||
{
|
||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_RETURN;
|
||||
|
||||
if ([[self role] isEqualToString:NSAccessibilityStaticTextRole])
|
||||
return YES;
|
||||
|
||||
|
@ -118,27 +145,39 @@ extern const NSString *kTopLevelUIElementAttribute; // NSAccessibilityTopLevel
|
|||
}
|
||||
|
||||
return NO;
|
||||
|
||||
NS_OBJC_END_TRY_ABORT_BLOCK_RETURN(NO);
|
||||
}
|
||||
|
||||
- (void)setText:(NSString*)newString
|
||||
{
|
||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK;
|
||||
|
||||
if (mGeckoEditableTextAccessible) {
|
||||
mGeckoEditableTextAccessible->SetTextContents(NS_ConvertUTF8toUTF16([newString UTF8String]));
|
||||
}
|
||||
|
||||
NS_OBJC_END_TRY_ABORT_BLOCK;
|
||||
}
|
||||
|
||||
- (long)textLength
|
||||
{
|
||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_RETURN;
|
||||
|
||||
if (mGeckoTextAccessible) {
|
||||
PRInt32 charCount = 0;
|
||||
mGeckoTextAccessible->GetCharacterCount(&charCount);
|
||||
return charCount;
|
||||
}
|
||||
return 0;
|
||||
|
||||
NS_OBJC_END_TRY_ABORT_BLOCK_RETURN(0);
|
||||
}
|
||||
|
||||
- (long)selectedTextLength
|
||||
{
|
||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_RETURN;
|
||||
|
||||
if (mGeckoTextAccessible) {
|
||||
PRInt32 start, end;
|
||||
start = end = 0;
|
||||
|
@ -146,10 +185,14 @@ extern const NSString *kTopLevelUIElementAttribute; // NSAccessibilityTopLevel
|
|||
return (end - start);
|
||||
}
|
||||
return 0;
|
||||
|
||||
NS_OBJC_END_TRY_ABORT_BLOCK_RETURN(0);
|
||||
}
|
||||
|
||||
- (NSString*)selectedText
|
||||
{
|
||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
|
||||
|
||||
if (mGeckoTextAccessible) {
|
||||
PRInt32 start, end;
|
||||
start = end = 0;
|
||||
|
@ -161,10 +204,14 @@ extern const NSString *kTopLevelUIElementAttribute; // NSAccessibilityTopLevel
|
|||
}
|
||||
}
|
||||
return nil;
|
||||
|
||||
NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
|
||||
}
|
||||
|
||||
- (NSValue*)selectedTextRange
|
||||
{
|
||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
|
||||
|
||||
if (mGeckoTextAccessible) {
|
||||
PRInt32 start, end;
|
||||
start = end = 0;
|
||||
|
@ -172,14 +219,20 @@ extern const NSString *kTopLevelUIElementAttribute; // NSAccessibilityTopLevel
|
|||
return [NSValue valueWithRange:NSMakeRange(start, start-end)];
|
||||
}
|
||||
return nil;
|
||||
|
||||
NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
|
||||
}
|
||||
|
||||
#pragma mark -
|
||||
|
||||
- (void)valueDidChange
|
||||
{
|
||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK;
|
||||
|
||||
NSAccessibilityPostNotification([self hasRepresentedView] ? [self representedView] : self,
|
||||
NSAccessibilityValueChangedNotification);
|
||||
|
||||
NS_OBJC_END_TRY_ABORT_BLOCK;
|
||||
}
|
||||
|
||||
@end
|
||||
|
@ -188,6 +241,8 @@ extern const NSString *kTopLevelUIElementAttribute; // NSAccessibilityTopLevel
|
|||
|
||||
- (NSArray*)accessibilityAttributeNames
|
||||
{
|
||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
|
||||
|
||||
static NSArray *supportedAttributes = nil;
|
||||
if (!supportedAttributes) {
|
||||
// standard attributes that are shared and supported by all generic elements.
|
||||
|
@ -218,10 +273,14 @@ extern const NSString *kTopLevelUIElementAttribute; // NSAccessibilityTopLevel
|
|||
nil];
|
||||
}
|
||||
return supportedAttributes;
|
||||
|
||||
NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
|
||||
}
|
||||
|
||||
- (NSArray *)accessibilityActionNames
|
||||
{
|
||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
|
||||
|
||||
if ([self isEnabled]) {
|
||||
return [NSArray arrayWithObjects:NSAccessibilityConfirmAction,
|
||||
#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_4
|
||||
|
@ -230,10 +289,14 @@ extern const NSString *kTopLevelUIElementAttribute; // NSAccessibilityTopLevel
|
|||
nil];
|
||||
}
|
||||
return nil;
|
||||
|
||||
NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
|
||||
}
|
||||
|
||||
- (NSString *)accessibilityActionDescription:(NSString *)action
|
||||
{
|
||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
|
||||
|
||||
#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_4
|
||||
if ([action isEqualToString:NSAccessibilityShowMenuAction])
|
||||
return @"show menu";
|
||||
|
@ -242,10 +305,14 @@ extern const NSString *kTopLevelUIElementAttribute; // NSAccessibilityTopLevel
|
|||
return @"confirm";
|
||||
|
||||
return [super accessibilityActionDescription:action];
|
||||
|
||||
NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
|
||||
}
|
||||
|
||||
- (void)accessibilityPerformAction:(NSString *)action
|
||||
{
|
||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK;
|
||||
|
||||
// both the ShowMenu and Click action do the same thing.
|
||||
if ([self isEnabled]) {
|
||||
#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_4
|
||||
|
@ -255,6 +322,8 @@ extern const NSString *kTopLevelUIElementAttribute; // NSAccessibilityTopLevel
|
|||
if ([action isEqualToString:NSAccessibilityConfirmAction])
|
||||
[self confirm];
|
||||
}
|
||||
|
||||
NS_OBJC_END_TRY_ABORT_BLOCK;
|
||||
}
|
||||
|
||||
- (void)showMenu
|
||||
|
|
|
@ -79,17 +79,6 @@ class nsAccessibleWrap : public nsAccessible
|
|||
|
||||
NS_IMETHOD FireAccessibleEvent(nsIAccessibleEvent *aEvent);
|
||||
|
||||
// we'll flatten buttons and checkboxes. usually they have a text node
|
||||
// child, that is their title. Works in conjunction with IsPruned() below.
|
||||
PRBool IsFlat() {
|
||||
PRUint32 role = Role(this);
|
||||
return (role == nsIAccessibleRole::ROLE_CHECKBUTTON ||
|
||||
role == nsIAccessibleRole::ROLE_PUSHBUTTON ||
|
||||
role == nsIAccessibleRole::ROLE_TOGGLE_BUTTON ||
|
||||
role == nsIAccessibleRole::ROLE_SPLITBUTTON ||
|
||||
role == nsIAccessibleRole::ROLE_ENTRY);
|
||||
}
|
||||
|
||||
// ignored means that the accessible might still have children, but is not displayed
|
||||
// to the user. it also has no native accessible object represented for it.
|
||||
PRBool IsIgnored();
|
||||
|
@ -117,10 +106,11 @@ class nsAccessibleWrap : public nsAccessible
|
|||
|
||||
nsCOMPtr<nsIAccessible> curParent = GetParent();
|
||||
while (curParent) {
|
||||
nsAccessibleWrap *ancestorWrap = static_cast<nsAccessibleWrap*>((nsIAccessible*)curParent.get());
|
||||
if (ancestorWrap->IsFlat())
|
||||
if (MustPrune(curParent))
|
||||
return PR_TRUE;
|
||||
curParent = static_cast<nsAccessibleWrap*>((nsIAccessible*)curParent.get())->GetParent();
|
||||
nsCOMPtr<nsIAccessible> newParent;
|
||||
curParent->GetParent(getter_AddRefs(newParent));
|
||||
curParent.swap(newParent);
|
||||
}
|
||||
// no parent was flat
|
||||
return PR_FALSE;
|
||||
|
|
|
@ -39,6 +39,7 @@
|
|||
#include "nsAccessibleWrap.h"
|
||||
#include "nsIAccessibleDocument.h"
|
||||
#include "nsIAccessibleText.h"
|
||||
#include "nsObjCExceptions.h"
|
||||
|
||||
#import "nsRoleMap.h"
|
||||
|
||||
|
@ -100,6 +101,8 @@ nsAccessibleWrap::GetNativeWindow (void **aOutNativeWindow)
|
|||
objc_class*
|
||||
nsAccessibleWrap::GetNativeType ()
|
||||
{
|
||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
|
||||
|
||||
PRUint32 role = Role(this);
|
||||
switch (role) {
|
||||
case nsIAccessibleRole::ROLE_PUSHBUTTON:
|
||||
|
@ -138,6 +141,8 @@ nsAccessibleWrap::GetNativeType ()
|
|||
}
|
||||
|
||||
return nil;
|
||||
|
||||
NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
|
||||
}
|
||||
|
||||
// this method is very important. it is fired when an accessible object "dies". after this point
|
||||
|
@ -157,6 +162,8 @@ nsAccessibleWrap::Shutdown ()
|
|||
NS_IMETHODIMP
|
||||
nsAccessibleWrap::FireAccessibleEvent(nsIAccessibleEvent *aEvent)
|
||||
{
|
||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT;
|
||||
|
||||
NS_ENSURE_ARG_POINTER(aEvent);
|
||||
|
||||
nsresult rv = nsAccessible::FireAccessibleEvent(aEvent);
|
||||
|
@ -190,23 +197,29 @@ nsAccessibleWrap::FireAccessibleEvent(nsIAccessibleEvent *aEvent)
|
|||
}
|
||||
|
||||
return NS_OK;
|
||||
|
||||
NS_OBJC_END_TRY_ABORT_BLOCK_NSRESULT;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsAccessibleWrap::InvalidateChildren ()
|
||||
{
|
||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT;
|
||||
|
||||
if (mNativeWrapper) {
|
||||
mozAccessible *object = mNativeWrapper->getNativeObject();
|
||||
[object invalidateChildren];
|
||||
}
|
||||
return nsAccessible::InvalidateChildren();
|
||||
|
||||
NS_OBJC_END_TRY_ABORT_BLOCK_NSRESULT;
|
||||
}
|
||||
|
||||
PRInt32
|
||||
nsAccessibleWrap::GetUnignoredChildCount(PRBool aDeepCount)
|
||||
{
|
||||
// if we're flat, we have no children.
|
||||
if (IsFlat())
|
||||
if (MustPrune(this))
|
||||
return 0;
|
||||
|
||||
PRInt32 childCount = 0;
|
||||
|
@ -222,7 +235,7 @@ nsAccessibleWrap::GetUnignoredChildCount(PRBool aDeepCount)
|
|||
++childCount;
|
||||
|
||||
// if it's flat, we don't care to inspect its children.
|
||||
if (childWrap->IsFlat())
|
||||
if (MustPrune(childWrap))
|
||||
continue;
|
||||
|
||||
if (aDeepCount) {
|
||||
|
@ -253,14 +266,14 @@ nsAccessibleWrap::GetUnignoredChildren(nsTArray<nsRefPtr<nsAccessibleWrap> > &aC
|
|||
nsCOMPtr<nsIAccessible> curAcc;
|
||||
|
||||
// we're flat; there are no children.
|
||||
if (IsFlat())
|
||||
if (MustPrune(this))
|
||||
return;
|
||||
|
||||
while (NextChild(curAcc)) {
|
||||
nsAccessibleWrap *childWrap = static_cast<nsAccessibleWrap*>((nsIAccessible*)curAcc.get());
|
||||
if (childWrap->IsIgnored()) {
|
||||
// element is ignored, so try adding its children as substitutes, if it has any.
|
||||
if (!childWrap->IsFlat()) {
|
||||
if (!MustPrune(childWrap)) {
|
||||
nsTArray<nsRefPtr<nsAccessibleWrap> > children;
|
||||
childWrap->GetUnignoredChildren(children);
|
||||
if (!children.IsEmpty()) {
|
||||
|
|
|
@ -52,7 +52,7 @@ static const NSString* AXRoles [] = {
|
|||
NSAccessibilityUnknownRole, // ROLE_CARET. unused on OS X
|
||||
NSAccessibilityWindowRole, // ROLE_ALERT
|
||||
NSAccessibilityWindowRole, // ROLE_WINDOW. irrelevant on OS X; all window a11y is handled by the system.
|
||||
@"AXWebArea", // ROLE_CLIENT
|
||||
@"AXWebArea", // ROLE_INTERNAL_FRAME
|
||||
NSAccessibilityMenuRole, // ROLE_MENUPOPUP. the parent of menuitems
|
||||
NSAccessibilityMenuItemRole, // ROLE_MENUITEM.
|
||||
@"AXHelpTag", // ROLE_TOOLTIP. 10.4+ only, so we re-define the constant.
|
||||
|
@ -157,6 +157,11 @@ static const NSString* AXRoles [] = {
|
|||
NSAccessibilityMenuItemRole, // ROLE_PARENT_MENUITEM
|
||||
NSAccessibilityGroupRole, // ROLE_CALENDAR
|
||||
NSAccessibilityMenuRole, // ROLE_COMBOBOX_LIST
|
||||
NSAccessibilityMenuItemRole, // ROLE_COMBOBOX_LISTITEM
|
||||
NSAccessibilityMenuItemRole, // ROLE_COMBOBOX_OPTION
|
||||
NSAccessibilityImageRole, // ROLE_IMAGE_MAP
|
||||
NSAccessibilityRowRole, // ROLE_OPTION
|
||||
NSAccessibilityRowRole, // ROLE_RICH_OPTION
|
||||
NSAccessibilityListRole, // ROLE_LISTBOX
|
||||
NSAccessibilityUnknownRole, // ROLE_FLAT_EQUATION
|
||||
@"ROLE_LAST_ENTRY" // ROLE_LAST_ENTRY. bogus role that will never be shown (just marks the end of this array)!
|
||||
};
|
||||
|
|
|
@ -36,9 +36,12 @@
|
|||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsRootAccessibleWrap.h"
|
||||
|
||||
#include "mozDocAccessible.h"
|
||||
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsObjCExceptions.h"
|
||||
#include "nsIWidget.h"
|
||||
#include "nsIViewManager.h"
|
||||
|
||||
|
@ -57,7 +60,11 @@ nsRootAccessibleWrap::~nsRootAccessibleWrap()
|
|||
objc_class*
|
||||
nsRootAccessibleWrap::GetNativeType ()
|
||||
{
|
||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
|
||||
|
||||
return [mozRootAccessible class];
|
||||
|
||||
NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -43,7 +43,7 @@
|
|||
#include "AccessibleAction_i.c"
|
||||
|
||||
#include "nsIAccessible.h"
|
||||
|
||||
#include "nsAccessNodeWrap.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsString.h"
|
||||
#include "nsIDOMDOMStringList.h"
|
||||
|
@ -69,35 +69,45 @@ CAccessibleAction::QueryInterface(REFIID iid, void** ppv)
|
|||
STDMETHODIMP
|
||||
CAccessibleAction::nActions(long *aNumActions)
|
||||
{
|
||||
__try {
|
||||
*aNumActions = 0;
|
||||
|
||||
nsCOMPtr<nsIAccessible> acc(do_QueryInterface(this));
|
||||
if (!acc)
|
||||
return E_FAIL;
|
||||
|
||||
PRUint8 count = 0;
|
||||
nsresult rv = acc->GetNumActions(&count);
|
||||
*aNumActions = count;
|
||||
if (NS_FAILED(rv))
|
||||
return GetHRESULT(rv);
|
||||
|
||||
if (NS_SUCCEEDED(rv))
|
||||
return NS_OK;
|
||||
*aNumActions = count;
|
||||
return S_OK;
|
||||
|
||||
} __except(nsAccessNodeWrap::FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
STDMETHODIMP
|
||||
CAccessibleAction::doAction(long aActionIndex)
|
||||
{
|
||||
__try {
|
||||
nsCOMPtr<nsIAccessible> acc(do_QueryInterface(this));
|
||||
if (!acc)
|
||||
return E_FAIL;
|
||||
|
||||
PRUint8 index = static_cast<PRUint8>(aActionIndex);
|
||||
if (NS_SUCCEEDED(acc->DoAction(index)))
|
||||
return S_OK;
|
||||
nsresult rv = acc->DoAction(index);
|
||||
return GetHRESULT(rv);
|
||||
|
||||
} __except(nsAccessNodeWrap::FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
STDMETHODIMP
|
||||
CAccessibleAction::get_description(long aActionIndex, BSTR *aDescription)
|
||||
{
|
||||
__try {
|
||||
*aDescription = NULL;
|
||||
|
||||
nsCOMPtr<nsIAccessible> acc(do_QueryInterface(this));
|
||||
|
@ -106,15 +116,19 @@ CAccessibleAction::get_description(long aActionIndex, BSTR *aDescription)
|
|||
|
||||
nsAutoString description;
|
||||
PRUint8 index = static_cast<PRUint8>(aActionIndex);
|
||||
if (NS_FAILED(acc->GetActionDescription(index, description)))
|
||||
return E_FAIL;
|
||||
nsresult rv = acc->GetActionDescription(index, description);
|
||||
if (NS_FAILED(rv))
|
||||
return GetHRESULT(rv);
|
||||
|
||||
if (!description.IsVoid()) {
|
||||
return ::SysReAllocStringLen(aDescription, description.get(),
|
||||
if (description.IsEmpty())
|
||||
return S_FALSE;
|
||||
|
||||
*aDescription = ::SysAllocStringLen(description.get(),
|
||||
description.Length());
|
||||
}
|
||||
return *aDescription ? S_OK : E_OUTOFMEMORY;
|
||||
|
||||
return S_OK;
|
||||
} __except(nsAccessNodeWrap::FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
STDMETHODIMP
|
||||
|
@ -122,8 +136,9 @@ CAccessibleAction::get_keyBinding(long aActionIndex, long aNumMaxBinding,
|
|||
BSTR **aKeyBinding,
|
||||
long *aNumBinding)
|
||||
{
|
||||
__try {
|
||||
*aKeyBinding = NULL;
|
||||
aNumBinding = 0;
|
||||
*aNumBinding = 0;
|
||||
|
||||
nsCOMPtr<nsIAccessible> acc(do_QueryInterface(this));
|
||||
if (!acc)
|
||||
|
@ -133,37 +148,53 @@ CAccessibleAction::get_keyBinding(long aActionIndex, long aNumMaxBinding,
|
|||
PRUint8 index = static_cast<PRUint8>(aActionIndex);
|
||||
nsresult rv = acc->GetKeyBindings(index, getter_AddRefs(keys));
|
||||
if (NS_FAILED(rv))
|
||||
return E_FAIL;
|
||||
return GetHRESULT(rv);
|
||||
|
||||
PRUint32 length = 0;
|
||||
keys->GetLength(&length);
|
||||
|
||||
PRBool aUseNumMaxBinding = length > static_cast<PRUint32>(aNumMaxBinding);
|
||||
if (length == 0)
|
||||
return S_FALSE;
|
||||
|
||||
PRUint32 maxBinding = static_cast<PRUint32>(aNumMaxBinding);
|
||||
|
||||
PRUint32 numBinding = length > maxBinding ? maxBinding : length;
|
||||
*aNumBinding = numBinding;
|
||||
|
||||
*aKeyBinding = new BSTR[numBinding];
|
||||
*aKeyBinding = static_cast<BSTR*>(nsMemory::Alloc((numBinding) * sizeof(BSTR*)));
|
||||
if (!*aKeyBinding)
|
||||
return E_OUTOFMEMORY;
|
||||
|
||||
for (PRUint32 i = 0; i < numBinding; i++) {
|
||||
PRBool outOfMemory = PR_FALSE;
|
||||
PRUint32 i = 0;
|
||||
for (; i < numBinding; i++) {
|
||||
nsAutoString key;
|
||||
keys->Item(i, key);
|
||||
HRESULT hr = ::SysReAllocStringLen(aKeyBinding[i], key.get(),
|
||||
key.Length());
|
||||
if (FAILED(hr))
|
||||
return hr;
|
||||
*(aKeyBinding[i]) = ::SysAllocStringLen(key.get(), key.Length());
|
||||
|
||||
if (!*(aKeyBinding[i])) {
|
||||
outOfMemory = PR_TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (outOfMemory) {
|
||||
for (PRUint32 j = 0; j < i; j++)
|
||||
::SysFreeString(*(aKeyBinding[j]));
|
||||
|
||||
nsMemory::Free(*aKeyBinding);
|
||||
*aKeyBinding = NULL;
|
||||
|
||||
return E_OUTOFMEMORY;
|
||||
}
|
||||
return S_OK;
|
||||
|
||||
} __except(nsAccessNodeWrap::FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
STDMETHODIMP
|
||||
CAccessibleAction::get_name(long aActionIndex, BSTR *aName)
|
||||
{
|
||||
__try {
|
||||
*aName = NULL;
|
||||
|
||||
nsCOMPtr<nsIAccessible> acc(do_QueryInterface(this));
|
||||
|
@ -172,18 +203,27 @@ CAccessibleAction::get_name(long aActionIndex, BSTR *aName)
|
|||
|
||||
nsAutoString name;
|
||||
PRUint8 index = static_cast<PRUint8>(aActionIndex);
|
||||
if (NS_FAILED(acc->GetActionName(index, name)))
|
||||
nsresult rv = acc->GetActionName(index, name);
|
||||
if (NS_FAILED(rv))
|
||||
return GetHRESULT(rv);
|
||||
|
||||
if (name.IsEmpty())
|
||||
return S_FALSE;
|
||||
|
||||
*aName = ::SysAllocStringLen(name.get(), name.Length());
|
||||
return *aName ? S_OK : E_OUTOFMEMORY;
|
||||
|
||||
} __except(nsAccessNodeWrap::FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
|
||||
return E_FAIL;
|
||||
|
||||
if (!name.IsVoid())
|
||||
return ::SysReAllocStringLen(aName, name.get(), name.Length());
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP
|
||||
CAccessibleAction::get_localizedName(long aActionIndex, BSTR *aLocalizedName)
|
||||
{
|
||||
__try {
|
||||
*aLocalizedName = NULL;
|
||||
} __except(nsAccessNodeWrap::FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
|
||||
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
|
|
|
@ -45,6 +45,7 @@
|
|||
#include "nsIAccessNode.h"
|
||||
#include "nsIAccessible.h"
|
||||
#include "nsIAccessibleStates.h"
|
||||
#include "nsAccessNodeWrap.h"
|
||||
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsString.h"
|
||||
|
@ -80,6 +81,7 @@ CAccessibleComponent::QueryInterface(REFIID iid, void** ppv)
|
|||
STDMETHODIMP
|
||||
CAccessibleComponent::get_locationInParent(long *aX, long *aY)
|
||||
{
|
||||
__try {
|
||||
*aX = 0;
|
||||
*aY = 0;
|
||||
|
||||
|
@ -88,10 +90,10 @@ CAccessibleComponent::get_locationInParent(long *aX, long *aY)
|
|||
return E_FAIL;
|
||||
|
||||
// If the object is not on any screen the returned position is (0,0).
|
||||
PRUint32 states = 0, extraStates = 0;
|
||||
nsresult rv = acc->GetFinalState(&states, &extraStates);
|
||||
PRUint32 states = 0;
|
||||
nsresult rv = acc->GetFinalState(&states, nsnull);
|
||||
if (NS_FAILED(rv))
|
||||
return E_FAIL;
|
||||
return GetHRESULT(rv);
|
||||
|
||||
if (states & nsIAccessibleStates::STATE_INVISIBLE)
|
||||
return S_OK;
|
||||
|
@ -99,12 +101,12 @@ CAccessibleComponent::get_locationInParent(long *aX, long *aY)
|
|||
PRInt32 x = 0, y = 0, width = 0, height = 0;
|
||||
rv = acc->GetBounds(&x, &y, &width, &height);
|
||||
if (NS_FAILED(rv))
|
||||
return E_FAIL;
|
||||
return GetHRESULT(rv);
|
||||
|
||||
nsCOMPtr<nsIAccessible> parentAcc;
|
||||
rv = acc->GetParent(getter_AddRefs(parentAcc));
|
||||
if (NS_FAILED(rv))
|
||||
return E_FAIL;
|
||||
return GetHRESULT(rv);
|
||||
|
||||
// The coordinates of the returned position are relative to this object's
|
||||
// parent or relative to the screen on which this object is rendered if it
|
||||
|
@ -112,7 +114,7 @@ CAccessibleComponent::get_locationInParent(long *aX, long *aY)
|
|||
if (!parentAcc) {
|
||||
*aX = x;
|
||||
*aY = y;
|
||||
return NS_OK;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
// The coordinates of the bounding box are given relative to the parent's
|
||||
|
@ -120,31 +122,42 @@ CAccessibleComponent::get_locationInParent(long *aX, long *aY)
|
|||
PRInt32 parentx = 0, parenty = 0;
|
||||
rv = acc->GetBounds(&parentx, &parenty, &width, &height);
|
||||
if (NS_FAILED(rv))
|
||||
return E_FAIL;
|
||||
return GetHRESULT(rv);
|
||||
|
||||
*aX = x - parentx;
|
||||
*aY = y - parenty;
|
||||
|
||||
return S_OK;
|
||||
|
||||
} __except(nsAccessNodeWrap::FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
STDMETHODIMP
|
||||
CAccessibleComponent::get_foreground(IA2Color *aForeground)
|
||||
{
|
||||
__try {
|
||||
return GetARGBValueFromCSSProperty(NS_LITERAL_STRING("color"), aForeground);
|
||||
} __except(nsAccessNodeWrap::FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
|
||||
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
STDMETHODIMP
|
||||
CAccessibleComponent::get_background(IA2Color *aBackground)
|
||||
{
|
||||
__try {
|
||||
return GetARGBValueFromCSSProperty(NS_LITERAL_STRING("background-color"),
|
||||
aBackground);
|
||||
} __except(nsAccessNodeWrap::FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
|
||||
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
HRESULT
|
||||
CAccessibleComponent::GetARGBValueFromCSSProperty(const nsAString& aPropName,
|
||||
IA2Color *aColorValue)
|
||||
{
|
||||
__try {
|
||||
*aColorValue = 0;
|
||||
|
||||
nsCOMPtr<nsIAccessNode> acc(do_QueryInterface(this));
|
||||
|
@ -155,67 +168,69 @@ CAccessibleComponent::GetARGBValueFromCSSProperty(const nsAString& aPropName,
|
|||
nsresult rv = acc->GetComputedStyleCSSValue(EmptyString(), aPropName,
|
||||
getter_AddRefs(cssValue));
|
||||
if (NS_FAILED(rv) || !cssValue)
|
||||
return E_FAIL;
|
||||
return GetHRESULT(rv);
|
||||
|
||||
nsCOMPtr<nsIDOMRGBColor> rgbColor;
|
||||
rv = cssValue->GetRGBColorValue(getter_AddRefs(rgbColor));
|
||||
if (NS_FAILED(rv) || !rgbColor)
|
||||
return E_FAIL;
|
||||
return GetHRESULT(rv);
|
||||
|
||||
nsCOMPtr<nsIDOMNSRGBAColor> rgbaColor(do_QueryInterface(rgbColor));
|
||||
if (!rgbaColor)
|
||||
return E_FAIL;
|
||||
return GetHRESULT(rv);
|
||||
|
||||
// get alpha
|
||||
nsCOMPtr<nsIDOMCSSPrimitiveValue> alphaValue;
|
||||
rv = rgbaColor->GetAlpha(getter_AddRefs(alphaValue));
|
||||
if (NS_FAILED(rv) || !alphaValue)
|
||||
return E_FAIL;
|
||||
return GetHRESULT(rv);
|
||||
|
||||
float alpha = 0.0;
|
||||
rv = alphaValue->GetFloatValue(nsIDOMCSSPrimitiveValue::CSS_NUMBER, &alpha);
|
||||
if (NS_FAILED(rv))
|
||||
return E_FAIL;
|
||||
return GetHRESULT(rv);
|
||||
|
||||
// get red
|
||||
nsCOMPtr<nsIDOMCSSPrimitiveValue> redValue;
|
||||
rv = rgbaColor->GetRed(getter_AddRefs(redValue));
|
||||
if (NS_FAILED(rv) || !redValue)
|
||||
return E_FAIL;
|
||||
return GetHRESULT(rv);
|
||||
|
||||
float red = 0.0;
|
||||
rv = redValue->GetFloatValue(nsIDOMCSSPrimitiveValue::CSS_NUMBER, &red);
|
||||
if (NS_FAILED(rv))
|
||||
return E_FAIL;
|
||||
return GetHRESULT(rv);
|
||||
|
||||
// get green
|
||||
nsCOMPtr<nsIDOMCSSPrimitiveValue> greenValue;
|
||||
rv = rgbaColor->GetGreen(getter_AddRefs(greenValue));
|
||||
if (NS_FAILED(rv) || !greenValue)
|
||||
return E_FAIL;
|
||||
return GetHRESULT(rv);
|
||||
|
||||
float green = 0.0;
|
||||
rv = greenValue->GetFloatValue(nsIDOMCSSPrimitiveValue::CSS_NUMBER, &green);
|
||||
if (NS_FAILED(rv))
|
||||
return E_FAIL;
|
||||
return GetHRESULT(rv);
|
||||
|
||||
// get blue
|
||||
nsCOMPtr<nsIDOMCSSPrimitiveValue> blueValue;
|
||||
rv = rgbaColor->GetBlue(getter_AddRefs(blueValue));
|
||||
if (NS_FAILED(rv) || !blueValue)
|
||||
return E_FAIL;
|
||||
return GetHRESULT(rv);
|
||||
|
||||
float blue = 0.0;
|
||||
rv = blueValue->GetFloatValue(nsIDOMCSSPrimitiveValue::CSS_NUMBER, &blue);
|
||||
if (NS_FAILED(rv))
|
||||
return E_FAIL;
|
||||
return GetHRESULT(rv);
|
||||
|
||||
// compose ARGB value
|
||||
*aColorValue = (((IA2Color) blue) << IA2BlueShift) |
|
||||
(((IA2Color) green) << IA2GreenShift) |
|
||||
(((IA2Color) red) << IA2RedShift) |
|
||||
(((IA2Color) (alpha * 0xff)) << IA2AlphaShift);
|
||||
|
||||
return S_OK;
|
||||
|
||||
} __except(nsAccessNodeWrap::FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
|
|
|
@ -42,6 +42,7 @@
|
|||
|
||||
#include "nsIAccessibleEditableText.h"
|
||||
#include "AccessibleEditableText_i.c"
|
||||
#include "nsAccessNodeWrap.h"
|
||||
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsString.h"
|
||||
|
@ -77,71 +78,98 @@ CAccessibleEditableText::QueryInterface(REFIID iid, void** ppv)
|
|||
STDMETHODIMP
|
||||
CAccessibleEditableText::copyText(long aStartOffset, long aEndOffset)
|
||||
{
|
||||
__try {
|
||||
GET_NSIACCESSIBLEEDITABLETEXT
|
||||
|
||||
nsresult rv = textAcc->CopyText(aStartOffset, aEndOffset);
|
||||
return NS_FAILED(rv) ? E_FAIL : S_OK;
|
||||
return GetHRESULT(rv);
|
||||
|
||||
} __except(nsAccessNodeWrap::FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
STDMETHODIMP
|
||||
CAccessibleEditableText::deleteText(long aStartOffset, long aEndOffset)
|
||||
{
|
||||
__try {
|
||||
GET_NSIACCESSIBLEEDITABLETEXT
|
||||
|
||||
nsresult rv = textAcc->DeleteText(aStartOffset, aEndOffset);
|
||||
return NS_FAILED(rv) ? E_FAIL : S_OK;
|
||||
return GetHRESULT(rv);
|
||||
|
||||
} __except(nsAccessNodeWrap::FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
STDMETHODIMP
|
||||
CAccessibleEditableText::insertText(long aOffset, BSTR *aText)
|
||||
{
|
||||
__try {
|
||||
GET_NSIACCESSIBLEEDITABLETEXT
|
||||
|
||||
PRUint32 length = ::SysStringLen(*aText);
|
||||
nsAutoString text(*aText, length);
|
||||
|
||||
nsresult rv = textAcc->InsertText(text, aOffset);
|
||||
return NS_FAILED(rv) ? E_FAIL : S_OK;
|
||||
return GetHRESULT(rv);
|
||||
|
||||
} __except(nsAccessNodeWrap::FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
STDMETHODIMP
|
||||
CAccessibleEditableText::cutText(long aStartOffset, long aEndOffset)
|
||||
{
|
||||
__try {
|
||||
GET_NSIACCESSIBLEEDITABLETEXT
|
||||
|
||||
nsresult rv = textAcc->CutText(aStartOffset, aEndOffset);
|
||||
return NS_FAILED(rv) ? E_FAIL : S_OK;
|
||||
return GetHRESULT(rv);
|
||||
|
||||
} __except(nsAccessNodeWrap::FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
STDMETHODIMP
|
||||
CAccessibleEditableText::pasteText(long aOffset)
|
||||
{
|
||||
__try {
|
||||
GET_NSIACCESSIBLEEDITABLETEXT
|
||||
|
||||
nsresult rv = textAcc->PasteText(aOffset);
|
||||
return NS_FAILED(rv) ? E_FAIL : S_OK;
|
||||
return GetHRESULT(rv);
|
||||
|
||||
} __except(nsAccessNodeWrap::FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
STDMETHODIMP
|
||||
CAccessibleEditableText::replaceText(long aStartOffset, long aEndOffset,
|
||||
BSTR *aText)
|
||||
{
|
||||
__try {
|
||||
GET_NSIACCESSIBLEEDITABLETEXT
|
||||
|
||||
nsresult rv = textAcc->DeleteText(aStartOffset, aEndOffset);
|
||||
if (NS_FAILED(rv))
|
||||
return E_FAIL;
|
||||
return GetHRESULT(rv);
|
||||
|
||||
PRUint32 length = ::SysStringLen(*aText);
|
||||
nsAutoString text(*aText, length);
|
||||
|
||||
rv = textAcc->InsertText(text, aStartOffset);
|
||||
return NS_FAILED(rv) ? E_FAIL : S_OK;
|
||||
return GetHRESULT(rv);
|
||||
|
||||
} __except(nsAccessNodeWrap::FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
STDMETHODIMP
|
||||
CAccessibleEditableText::setAttributes(long aStartOffset, long aEndOffset,
|
||||
BSTR *aAttributes)
|
||||
{
|
||||
__try {
|
||||
|
||||
} __except(nsAccessNodeWrap::FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
|
Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше
Загрузка…
Ссылка в новой задаче