diff --git a/accessible/src/base/nsBaseWidgetAccessible.cpp b/accessible/src/base/nsBaseWidgetAccessible.cpp index a177adcbe6a..52f5edef341 100644 --- a/accessible/src/base/nsBaseWidgetAccessible.cpp +++ b/accessible/src/base/nsBaseWidgetAccessible.cpp @@ -118,7 +118,7 @@ nsLinkableAccessible::TakeFocus() if (actionAcc) return actionAcc->TakeFocus(); - return NS_OK; + return nsHyperTextAccessibleWrap::TakeFocus(); } NS_IMETHODIMP diff --git a/accessible/tests/mochitest/Makefile.in b/accessible/tests/mochitest/Makefile.in index 1d48dd75b11..dfabdbe0556 100644 --- a/accessible/tests/mochitest/Makefile.in +++ b/accessible/tests/mochitest/Makefile.in @@ -64,6 +64,7 @@ _TEST_FILES =\ test_nsIAccessible_actions.xul \ test_nsIAccessible_name.html \ test_nsIAccessible_name.xul \ + test_nsIAccessible_focus.html \ test_nsIAccessibleDocument.html \ test_nsIAccessibleEditableText.html \ test_nsIAccessibleHyperLink.html \ diff --git a/accessible/tests/mochitest/common.js b/accessible/tests/mochitest/common.js index 2c08774fb12..8f353d0fcad 100644 --- a/accessible/tests/mochitest/common.js +++ b/accessible/tests/mochitest/common.js @@ -31,7 +31,7 @@ const nsIObserverService = Components.interfaces.nsIObserverService; const nsIDOMNode = Components.interfaces.nsIDOMNode; //////////////////////////////////////////////////////////////////////////////// -// General +// Accessible general /** * nsIAccessibleRetrieval, initialized when test is loaded. @@ -41,22 +41,27 @@ var gAccRetrieval = null; /** * Return accessible for the given ID attribute or DOM element. * - * @param aElmOrID [in] the ID attribute or DOM element to get an accessible - * for - * @param aInterfaces [in, optional] the accessible interface or the array of - * accessible interfaces to query it/them from obtained - * accessible - * @param aElmObj [out, optional] object to store DOM element which - * accessible is created for + * @param aAccOrElmOrID [in] DOM element or ID attribute to get an accessible + * for or an accessible to query additional interfaces. + * @param aInterfaces [in, optional] the accessible interface or the array of + * accessible interfaces to query it/them from obtained + * accessible + * @param aElmObj [out, optional] object to store DOM element which + * accessible is obtained for */ -function getAccessible(aElmOrID, aInterfaces, aElmObj) +function getAccessible(aAccOrElmOrID, aInterfaces, aElmObj) { var elm = null; - if (aElmOrID instanceof nsIDOMNode) { - elm = aElmOrID; + if (aAccOrElmOrID instanceof nsIAccessible) { + aAccOrElmOrID.QueryInterface(nsIAccessNode); + elm = aAccOrElmOrID.DOMNode; + + } else if (aAccOrElmOrID instanceof nsIDOMNode) { + elm = aAccOrElmOrID; + } else { - var elm = document.getElementById(aElmOrID); + var elm = document.getElementById(aAccOrElmOrID); if (!elm) { ok(false, "Can't get DOM element for " + aID); return null; @@ -66,15 +71,17 @@ function getAccessible(aElmOrID, aInterfaces, aElmObj) if (aElmObj && (typeof aElmObj == "object")) aElmObj.value = elm; - var acc = null; - try { - acc = gAccRetrieval.getAccessibleFor(elm); - } catch (e) { - } - + var acc = (aAccOrElmOrID instanceof nsIAccessible) ? aAccOrElmOrID : null; if (!acc) { - ok(false, "Can't get accessible for " + aID); - return null; + try { + acc = gAccRetrieval.getAccessibleFor(elm); + } catch (e) { + } + + if (!acc) { + ok(false, "Can't get accessible for " + aID); + return null; + } } if (!aInterfaces) @@ -102,17 +109,98 @@ function getAccessible(aElmOrID, aInterfaces, aElmObj) return acc; } +//////////////////////////////////////////////////////////////////////////////// +// Accessible Events + +/** + * Register accessibility event listener. + * + * @param aEventType the accessible event type (see nsIAccessibleEvent for + * available constants). + * @param aEventHandler event listener object, when accessible event of the + * given type is handled then 'handleEvent' method of + * this object is invoked with nsIAccessibleEvent object + * as the first argument. + */ +function registerA11yEventListener(aEventType, aEventHandler) +{ + if (!gA11yEventListenersCount) { + gObserverService = Components.classes["@mozilla.org/observer-service;1"]. + getService(nsIObserverService); + + gObserverService.addObserver(gA11yEventObserver, "accessible-event", + false); + } + + if (!(aEventType in gA11yEventListeners)) + gA11yEventListeners[aEventType] = new Array(); + + gA11yEventListeners[aEventType].push(aEventHandler); + gA11yEventListenersCount++; +} + +/** + * Unregister accessibility event listener. Must be called for every registered + * event listener (see registerA11yEventListener() function) when it's not + * needed. + */ +function unregisterA11yEventListener(aEventType, aEventHandler) +{ + var listenersArray = gA11yEventListeners[aEventType]; + if (listenersArray) { + var index = listenersArray.indexOf(aEventHandler); + listenersArray.splice(index, 1); + + if (!listenersArray.length) { + gA11yEventListeners[aEventType] = null; + delete gA11yEventListeners[aEventType]; + } + } + + gA11yEventListenersCount--; + if (!gA11yEventListenersCount) { + gObserverService.removeObserver(gA11yEventObserver, + "accessible-event"); + } +} + + //////////////////////////////////////////////////////////////////////////////// // Private //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// -// General +// Accessible general function initialize() { gAccRetrieval = Components.classes["@mozilla.org/accessibleRetrieval;1"]. - getService(nsIAccessibleRetrieval); + getService(nsIAccessibleRetrieval); } addLoadEvent(initialize); + +//////////////////////////////////////////////////////////////////////////////// +// Accessible Events + +var gObserverService = null; + +var gA11yEventListeners = {}; +var gA11yEventListenersCount = 0; + +var gA11yEventObserver = +{ + observe: function observe(aSubject, aTopic, aData) + { + if (aTopic != "accessible-event") + return; + + var event = aSubject.QueryInterface(nsIAccessibleEvent); + var listenersArray = gA11yEventListeners[event.eventType]; + if (!listenersArray) + return; + + for (var index = 0; index < listenersArray.length; index++) + listenersArray[index].handleEvent(event); + } +}; diff --git a/accessible/tests/mochitest/test_nsIAccessible_focus.html b/accessible/tests/mochitest/test_nsIAccessible_focus.html new file mode 100644 index 00000000000..4ac7eaf2232 --- /dev/null +++ b/accessible/tests/mochitest/test_nsIAccessible_focus.html @@ -0,0 +1,134 @@ + + + + nsIAccessible::takeFocus testing + + + + + + + + + + + + + + Mozilla Bug 452710 + +

+ +
+  
+ + link + link + + link + + +