diff --git a/accessible/tests/mochitest/Makefile.in b/accessible/tests/mochitest/Makefile.in index 47c3c994fa9e..85eec7c09e03 100644 --- a/accessible/tests/mochitest/Makefile.in +++ b/accessible/tests/mochitest/Makefile.in @@ -50,13 +50,13 @@ _TEST_FILES =\ moz.png \ $(topsrcdir)/content/media/video/test/bug461281.ogg \ longdesc_src.html \ + actions.js \ attributes.js \ common.js \ events.js \ grid.js \ layout.js \ namerules.xml \ - nsIAccessible_actions.js \ nsIAccessible_name.css \ nsIAccessible_name.js \ nsIAccessible_name.xbl \ diff --git a/accessible/tests/mochitest/actions.js b/accessible/tests/mochitest/actions.js new file mode 100644 index 000000000000..b7d104e16914 --- /dev/null +++ b/accessible/tests/mochitest/actions.js @@ -0,0 +1,127 @@ +//////////////////////////////////////////////////////////////////////////////// +// Event constants + +const MOUSEDOWN_EVENT = 1; +const MOUSEUP_EVENT = 2; +const CLICK_EVENT = 4; +const COMMAND_EVENT = 8; + +const CLICK_EVENTS = MOUSEDOWN_EVENT | MOUSEUP_EVENT | CLICK_EVENT; +const ALL_EVENTS = CLICK_EVENTS | COMMAND_EVENT; + +//////////////////////////////////////////////////////////////////////////////// +// Public functions + +/** + * Test default accessible actions. + * + * Action tester interface is: + * + * var actionObj = { + * // identifier of accessible + * get ID() {}, + * + * // name of default action + * get actionName() {}, + * + * // event constant defined above + * get events() {} + * + * // [optional] an array of invoker's checker objects (see eventQueue + * // constructor events.js) + * get eventSeq() {} + * }; + * + * + * @param aArray [in] an array of action cheker objects + */ +function testActions(aArray) +{ + gActionsQueue = new eventQueue(); + + for (var idx = 0; idx < aArray.length; idx++) { + + var actionObj = aArray[idx]; + var accOrElmOrID = actionObj.ID; + var actionName = actionObj.actionName; + var events = actionObj.events; + + var eventSeq = new Array(); + if (events) { + var elm = getNode(accOrElmOrID); + //alert(elm.QueryInterface(Components.interfaces.nsIDOMNode)); + if (events & MOUSEDOWN_EVENT) + eventSeq.push(new checkerOfActionInvoker("mousedown", elm)); + + if (events & MOUSEUP_EVENT) + eventSeq.push(new checkerOfActionInvoker("mouseup", elm)); + + if (events & CLICK_EVENT) + eventSeq.push(new checkerOfActionInvoker("click", elm, actionObj)); + + if (events & COMMAND_EVENT) + eventSeq.push(new checkerOfActionInvoker("command", elm)); + } + + if (actionObj.eventSeq) + eventSeq = eventSeq.concat(actionObj.eventSeq); + + var invoker = new actionInvoker(accOrElmOrID, actionName, eventSeq); + gActionsQueue.push(invoker); + } + + gActionsQueue.invoke(); +} + +//////////////////////////////////////////////////////////////////////////////// +// Private + +var gActionsQueue = null; + +function actionInvoker(aAccOrElmOrId, aActionName, aEventSeq) +{ + this.invoke = function actionInvoker_invoke() + { + var acc = getAccessible(aAccOrElmOrId); + if (!acc) + return INVOKER_ACTION_FAILED; + + var isThereActions = acc.numActions > 0; + ok(isThereActions, + "No actions on the accessible for " + prettyName(aAccOrElmOrId)); + + if (!isThereActions) + return INVOKER_ACTION_FAILED; + + is(acc.getActionName(0), aActionName, + "Wrong action name of the accessible for " + prettyName(aAccOrElmOrId)); + + try { + acc.doAction(0); + } + catch (e){ + ok(false, "doAction(0) failed with: " + e.name); + return INVOKER_ACTION_FAILED; + } + } + + this.eventSeq = aEventSeq; +} + +function checkerOfActionInvoker(aType, aTarget, aActionObj) +{ + this.type = aType; + + this.target = aTarget; + + this.getID = function getID() + { + return aType + " event handling"; + } + + this.check = function check(aEvent) + { + if (aActionObj && "check" in aActionObj) + aActionObj.check(aEvent); + } +} diff --git a/accessible/tests/mochitest/common.js b/accessible/tests/mochitest/common.js index 826c3d9fb995..26ffc624001c 100644 --- a/accessible/tests/mochitest/common.js +++ b/accessible/tests/mochitest/common.js @@ -121,22 +121,25 @@ function addA11yLoadEvent(aFunc) // Get DOM node/accesible helpers /** - * Return the DOM node. + * Return the DOM node by identifier (may be accessible, DOM node or ID). */ -function getNode(aNodeOrID) +function getNode(aAccOrNodeOrID) { - if (!aNodeOrID) + if (!aAccOrNodeOrID) return null; - var node = aNodeOrID; + if (aAccOrNodeOrID instanceof nsIDOMNode) + return aAccOrNodeOrID; - if (!(aNodeOrID instanceof nsIDOMNode)) { - node = document.getElementById(aNodeOrID); + if (aAccOrNodeOrID instanceof nsIAccessible) { + aAccOrNodeOrID.QueryInterface(nsIAccessNode); + return aAccOrNodeOrID.DOMNode; + } - if (!node) { - ok(false, "Can't get DOM element for " + aNodeOrID); - return null; - } + node = document.getElementById(aAccOrNodeOrID); + if (!node) { + ok(false, "Can't get DOM element for " + aAccOrNodeOrID); + return null; } return node; @@ -343,7 +346,7 @@ function prettyName(aIdentifier) if (aIdentifier instanceof nsIAccessible) { var acc = getAccessible(aIdentifier, [nsIAccessNode]); return getNodePrettyName(acc.DOMNode) + ", role: " + - roleToString(acc.finalRole); + roleToString(acc.role); } if (aIdentifier instanceof nsIDOMNode) @@ -369,8 +372,12 @@ addLoadEvent(initialize); function getNodePrettyName(aNode) { - if (aNode.nodeType == nsIDOMNode.ELEMENT_NODE && aNode.hasAttribute("id")) - return " '" + aNode.getAttribute("id") + "' "; + try { + if (aNode.nodeType == nsIDOMNode.ELEMENT_NODE && aNode.hasAttribute("id")) + return " '" + aNode.getAttribute("id") + "' "; - return " '" + aNode.localName + " node' "; + return " '" + aNode.localName + " node' "; + } catch (e) { + return "no node info"; + } } diff --git a/accessible/tests/mochitest/events.js b/accessible/tests/mochitest/events.js index 19e9965f25f7..0de53bc7665e 100644 --- a/accessible/tests/mochitest/events.js +++ b/accessible/tests/mochitest/events.js @@ -2,6 +2,7 @@ // Constants const EVENT_DOM_DESTROY = nsIAccessibleEvent.EVENT_DOM_DESTROY; +const EVENT_FOCUS = nsIAccessibleEvent.EVENT_FOCUS; const EVENT_NAME_CHANGE = nsIAccessibleEvent.EVENT_NAME_CHANGE; const EVENT_REORDER = nsIAccessibleEvent.EVENT_REORDER; @@ -79,6 +80,12 @@ function unregisterA11yEventListener(aEventType, aEventHandler) //////////////////////////////////////////////////////////////////////////////// // Event queue +/** + * Return value of invoke method of invoker object. Indicates invoker was unable + * to prepare action. + */ +const INVOKER_ACTION_FAILED = 1; + /** * Creates event queue for the given event type. The queue consists of invoker * objects, each of them generates the event of the event type. When queue is @@ -89,7 +96,8 @@ function unregisterA11yEventListener(aEventType, aEventHandler) * Invoker interface is: * * var invoker = { - * // Generates accessible event or event sequence. + * // Generates accessible event or event sequence. If returns + * // INVOKER_ACTION_FAILED constant then stop tests. * invoke: function(){}, * * // [optional] Invoker's check of handled event for correctness. @@ -219,7 +227,11 @@ function eventQueue(aEventType) this.setEventHandler(invoker); - invoker.invoke(); + if (invoker.invoke() == INVOKER_ACTION_FAILED) { + // Invoker failed to prepare action, fail and finish tests. + this.processNextInvoker(); + return; + } if (invoker.doNotExpectEvents) { // Check in timeout invoker didn't fire registered events. @@ -260,6 +272,12 @@ function eventQueue(aEventType) if (gA11yEventDumpID) { // debug stuff + if (aEvent instanceof nsIDOMEvent) { + var info = "Event type: " + aEvent.type; + info += ". Target: " + prettyName(aEvent.originalTarget); + dumpInfoToDOM(info); + } + var currType = this.getEventType(idx); var currTarget = this.getEventTarget(idx); @@ -368,8 +386,10 @@ function eventQueue(aEventType) return target1 == target2; } + // If original target isn't suitable then extend interface to support target + // (original target is used in test_elm_media.html). var target2 = (aEvent instanceof nsIDOMEvent) ? - aEvent.target : aEvent.DOMNode; + aEvent.originalTarget : aEvent.DOMNode; return target1 == target2; } @@ -497,12 +517,20 @@ function removeA11yEventListener(aEventType, aEventHandler) return true; } -function dumpInfoToDOM(aInfo) +/** + * Dumps message to DOM. + * + * @param aInfo [in] the message to dump + * @param aDumpNode [in, optional] host DOM node for dumped message, if ommited + * then global variable gA11yEventDumpID is used + */ +function dumpInfoToDOM(aInfo, aDumpNode) { - if (!gA11yEventDumpID) + var dumpID = gA11yEventDumpID ? gA11yEventDumpID : aDumpNode; + if (!dumpID) return; - var dumpElm = document.getElementById(gA11yEventDumpID); + var dumpElm = document.getElementById(dumpID); var containerTagName = document instanceof nsIDOMHTMLDocument ? "div" : "description"; diff --git a/accessible/tests/mochitest/nsIAccessible_actions.js b/accessible/tests/mochitest/nsIAccessible_actions.js deleted file mode 100644 index 96f2e9f1e9fd..000000000000 --- a/accessible/tests/mochitest/nsIAccessible_actions.js +++ /dev/null @@ -1,135 +0,0 @@ -//////////////////////////////////////////////////////////////////////////////// -// Event constants - -const MOUSEDOWN_EVENT = 1; -const MOUSEUP_EVENT = 2; -const CLICK_EVENT = 4; -const COMMAND_EVENT = 8; - -const CLICK_EVENTS = MOUSEDOWN_EVENT | MOUSEUP_EVENT | CLICK_EVENT; -const ALL_EVENTS = CLICK_EVENTS | COMMAND_EVENT; - -//////////////////////////////////////////////////////////////////////////////// -// Public functions - -function testActions(aArray, aIndex) -{ - if (!aIndex) - aIndex = 0; - - if (aIndex == aArray.length) { - SimpleTest.finish(); - return; - } - - var accOrElmOrID = aArray[aIndex].ID; - var actionName = aArray[aIndex].actionName; - var events = aArray[aIndex].events; - - var elmObj = {}; - var acc = getAccessible(accOrElmOrID, null, elmObj); - var elm = elmObj.value; - - var isThereActions = acc.numActions > 0; - ok(isThereActions, - "No actions on the accessible for " + accOrElmOrID); - - if (!isThereActions) { - SimpleTest.finish(); - return; // Stop test. - } - - is(acc.getActionName(0), actionName, - "Wrong action name of the accessible for " + accOrElmOrID); - - gEventHandler.initialize(accOrElmOrID, elm, events); - - try { - acc.doAction(0); - } - catch (e){ - ok(false, "doAction(0) failed with: " + e.name); - SimpleTest.finish(); - return; - } - - window.setTimeout( - function() - { - gEventHandler.checkEvents(); - testActions(aArray, aIndex + 1); - }, - 200 - ); -} - -//////////////////////////////////////////////////////////////////////////////// -// Private - -var gEventHandler = -{ - initialize: function(aID, aElm, aExpectedEvents) - { - this.ID = aID; - this.element = aElm; - this.mExpectedEvents = aExpectedEvents; - this.mFiredEvents = 0; - - if (this.mExpectedEvents & MOUSEDOWN_EVENT) - aElm.addEventListener("mousedown", this, false); - - if (this.mExpectedEvents & MOUSEUP_EVENT) - aElm.addEventListener("mouseup", this, false); - - if (this.mExpectedEvents & CLICK_EVENT) - aElm.addEventListener("click", this, false); - - if (this.mExpectedEvents & COMMAND_EVENT) - aElm.addEventListener("command", this, false); - }, - - checkEvents: function() - { - if (this.mExpectedEvents & MOUSEDOWN_EVENT) { - ok(this.mFiredEvents & MOUSEDOWN_EVENT, - "mousedown hasn't been fired for " + this.ID); - this.element.removeEventListener("mousedown", this, false); - } - - if (this.mExpectedEvents & MOUSEUP_EVENT) { - ok(this.mFiredEvents & MOUSEUP_EVENT, - "mouseup hasn't been fired for " + this.ID); - this.element.removeEventListener("mouseup", this, false); - } - - if (this.mExpectedEvents & CLICK_EVENT) { - ok(this.mFiredEvents & CLICK_EVENT, - "click hasn't been fired for " + this.ID); - this.element.removeEventListener("click", this, false); - } - - if (this.mExpectedEvents & COMMAND_EVENT) { - ok(this.mFiredEvents & COMMAND_EVENT, - "command hasn't been fired for " + this.ID); - this.element.removeEventListener("command", this, false); - } - }, - - ID: "", - element: null, - - handleEvent : function(aEvent) - { - if (aEvent.type == "mousedown") - this.mFiredEvents |= MOUSEDOWN_EVENT; - else if(aEvent.type == "mouseup") - this.mFiredEvents |= MOUSEUP_EVENT; - else if(aEvent.type == "click") - this.mFiredEvents |= CLICK_EVENT; - else if(aEvent.type == "command") - this.mFiredEvents |= COMMAND_EVENT; - }, - - mExpectedEvents: 0, - mFiredEvents: 0 -}; diff --git a/accessible/tests/mochitest/test_actions.xul b/accessible/tests/mochitest/test_actions.xul index 518ddc008adf..3c07192a4413 100644 --- a/accessible/tests/mochitest/test_actions.xul +++ b/accessible/tests/mochitest/test_actions.xul @@ -17,7 +17,9 @@ - - - Mozilla Bug 410765 - -

- -
-    
- + + + + Mozilla Bug 410765 + +

+ +
+      
+ - - - - - + + + - + + + + + + - - - + - + + + diff --git a/accessible/tests/mochitest/test_actions_aria.html b/accessible/tests/mochitest/test_actions_aria.html index 558e2f367906..b7586d35e2ed 100644 --- a/accessible/tests/mochitest/test_actions_aria.html +++ b/accessible/tests/mochitest/test_actions_aria.html @@ -14,7 +14,9 @@ + src="chrome://mochikit/content/a11y/accessible/events.js"> + + src="chrome://mochikit/content/a11y/accessible/events.js"> + + + @@ -63,6 +115,6 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=483573 diff --git a/toolkit/content/widgets/videocontrols.xml b/toolkit/content/widgets/videocontrols.xml index b69c0770e0dc..07eb15642560 100644 --- a/toolkit/content/widgets/videocontrols.xml +++ b/toolkit/content/widgets/videocontrols.xml @@ -1,5 +1,10 @@ + + %videocontrolsDTD; +]> +