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:
Benjamin Smedberg 2008-05-27 13:51:53 -04:00
Родитель d491c5f256 13ed1fcfee
Коммит 5068d70767
13929 изменённых файлов: 1182396 добавлений и 691611 удалений

Просмотреть файл

@ -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,2 +1,3 @@
df7a3c8ffeeaba229067efee5a20e21dae0dd877 MOZILLA_1_9_a4_BASE
4209e16b58411750ac73f761023e46b76b793e2c MOZILLA_1_9_a6_BASE
66a5c7bce7ee86a820d3c0d54fa07cb719be751c MOZILLA_1_9_a7_BASE

Просмотреть файл

@ -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

Просмотреть файл

@ -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;
}

Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше