зеркало из https://github.com/mozilla/gecko-dev.git
Bug 489549 - Buttons of HTML5 audio and video element control set have no accessible names, r=marcoz, davidb, dolske, enndeaking, sr=neil
--HG-- rename : accessible/tests/mochitest/nsIAccessible_actions.js => accessible/tests/mochitest/actions.js
This commit is contained in:
Родитель
e019bae7fa
Коммит
906cbaed37
|
@ -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 \
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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 (!node) {
|
||||
ok(false, "Can't get DOM element for " + aNodeOrID);
|
||||
return null;
|
||||
if (aAccOrNodeOrID instanceof nsIAccessible) {
|
||||
aAccOrNodeOrID.QueryInterface(nsIAccessNode);
|
||||
return aAccOrNodeOrID.DOMNode;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
try {
|
||||
if (aNode.nodeType == nsIDOMNode.ELEMENT_NODE && aNode.hasAttribute("id"))
|
||||
return " '" + aNode.getAttribute("id") + "' ";
|
||||
|
||||
return " '" + aNode.localName + " node' ";
|
||||
} catch (e) {
|
||||
return "no node info";
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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";
|
||||
|
|
|
@ -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
|
||||
};
|
|
@ -17,7 +17,9 @@
|
|||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/a11y/accessible/common.js" />
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/a11y/accessible/nsIAccessible_actions.js" />
|
||||
src="chrome://mochikit/content/a11y/accessible/events.js" />
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/a11y/accessible/actions.js" />
|
||||
|
||||
<script type="application/javascript">
|
||||
<![CDATA[
|
||||
|
@ -48,13 +50,14 @@
|
|||
ID: "buttonmenu",
|
||||
actionName: "press",
|
||||
events: CLICK_EVENTS
|
||||
},
|
||||
}/*, // XXX: bug 490288
|
||||
{
|
||||
ID: "buttonmenu_item",
|
||||
actionName: "click",
|
||||
events: CLICK_EVENTS
|
||||
}
|
||||
}*/
|
||||
];
|
||||
|
||||
testActions(actionsArray);
|
||||
}
|
||||
|
||||
|
@ -63,6 +66,7 @@
|
|||
]]>
|
||||
</script>
|
||||
|
||||
<hbox flex="1" style="overflow: auto;">
|
||||
<body xmlns="http://www.w3.org/1999/xhtml">
|
||||
<a target="_blank"
|
||||
href="https://bugzilla.mozilla.org/show_bug.cgi?id=410765"
|
||||
|
@ -76,6 +80,7 @@
|
|||
</pre>
|
||||
</body>
|
||||
|
||||
<vbox flex="1">
|
||||
<menubar>
|
||||
<menu label="menu" id="menu">
|
||||
<menupopup>
|
||||
|
@ -97,5 +102,7 @@
|
|||
<menuitem label="item1"/>
|
||||
</menupopup>
|
||||
</button>
|
||||
</vbox>
|
||||
</hbox>
|
||||
</window>
|
||||
|
||||
|
|
|
@ -14,7 +14,9 @@
|
|||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/a11y/accessible/common.js"></script>
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/a11y/accessible/nsIAccessible_actions.js"></script>
|
||||
src="chrome://mochikit/content/a11y/accessible/events.js"></script>
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/a11y/accessible/actions.js"></script>
|
||||
|
||||
<script type="application/javascript">
|
||||
function doTest()
|
||||
|
|
|
@ -14,7 +14,9 @@
|
|||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/a11y/accessible/common.js"></script>
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/a11y/accessible/nsIAccessible_actions.js"></script>
|
||||
src="chrome://mochikit/content/a11y/accessible/events.js"></script>
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/a11y/accessible/actions.js"></script>
|
||||
|
||||
<script type="application/javascript">
|
||||
function doTest()
|
||||
|
|
|
@ -14,17 +14,46 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=483573
|
|||
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/a11y/accessible/common.js"></script>
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/a11y/accessible/events.js"></script>
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/a11y/accessible/actions.js"></script>
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/a11y/accessible/role.js"></script>
|
||||
|
||||
<script type="application/javascript">
|
||||
|
||||
function focusChecker(aAcc, aName)
|
||||
{
|
||||
this.type = EVENT_FOCUS;
|
||||
this.target = aAcc;
|
||||
this.getID = function focusChecker_getID()
|
||||
{
|
||||
return "focus handling";
|
||||
},
|
||||
this.check = function focusChecker_check(aEvent)
|
||||
{
|
||||
SimpleTest.executeSoon(
|
||||
function()
|
||||
{
|
||||
is(aEvent.accessible.name, aName,
|
||||
"Wrong name of " + prettyName(aEvent.accessible) + " on focus");
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
function doTest()
|
||||
{
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// test the accessible tree
|
||||
|
||||
var accTree = {
|
||||
role: ROLE_GROUPING,
|
||||
children: [
|
||||
{ // start/stop button
|
||||
role: ROLE_PUSHBUTTON
|
||||
role: ROLE_PUSHBUTTON,
|
||||
name: "Play"
|
||||
},
|
||||
{ // buffer bar
|
||||
role: ROLE_PROGRESSBAR
|
||||
|
@ -39,17 +68,40 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=483573
|
|||
role: ROLE_LABEL
|
||||
},
|
||||
{ // mute button
|
||||
role: ROLE_PUSHBUTTON
|
||||
role: ROLE_PUSHBUTTON,
|
||||
name: "Mute"
|
||||
}
|
||||
]
|
||||
};
|
||||
testAccessibleTree("audio", accTree);
|
||||
|
||||
SimpleTest.finish();
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// test actions of audio controls
|
||||
|
||||
var audioElm = getAccessible("audio");
|
||||
var playBtn = audioElm.firstChild;
|
||||
var muteBtn = audioElm.lastChild;
|
||||
|
||||
var actions = [
|
||||
{
|
||||
ID: playBtn,
|
||||
actionName: "press",
|
||||
events: CLICK_EVENTS,
|
||||
eventSeq: [ new focusChecker(playBtn, "Pause") ],
|
||||
},
|
||||
{
|
||||
ID: muteBtn,
|
||||
actionName: "press",
|
||||
events: CLICK_EVENTS,
|
||||
eventSeq: [ new focusChecker(muteBtn, "Unmute") ],
|
||||
}
|
||||
];
|
||||
|
||||
testActions(actions); // Will call SimpleTest.finish();
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
addLoadEvent(doTest);
|
||||
addA11yLoadEvent(doTest);
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
|
@ -63,6 +115,6 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=483573
|
|||
</pre>
|
||||
|
||||
<audio id="audio" src="chrome://mochikit/content/a11y/accessible/bug461281.ogg"
|
||||
autoplay="true" controls="true">
|
||||
controls="true"></audio>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -1,5 +1,10 @@
|
|||
<?xml version="1.0"?>
|
||||
|
||||
<!DOCTYPE bindings [
|
||||
<!ENTITY % videocontrolsDTD SYSTEM "chrome://global/locale/videocontrols.dtd">
|
||||
%videocontrolsDTD;
|
||||
]>
|
||||
|
||||
<bindings id="videoContolBindings"
|
||||
xmlns="http://www.mozilla.org/xbl"
|
||||
xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
|
||||
|
@ -144,7 +149,9 @@
|
|||
<vbox>
|
||||
<spacer flex="1"/>
|
||||
<hbox class="controlBar" hidden="true">
|
||||
<button class="playButton"/>
|
||||
<button class="playButton"
|
||||
playlabel="&playButton.playLabel;"
|
||||
pauselabel="&playButton.pauseLabel;"/>
|
||||
<stack class="scrubberStack" flex="1">
|
||||
<box class="backgroundBar"/>
|
||||
<progressmeter class="bufferBar"/>
|
||||
|
@ -154,7 +161,9 @@
|
|||
<vbox class="durationBox">
|
||||
<label class="durationLabel"/>
|
||||
</vbox>
|
||||
<button class="muteButton"/>
|
||||
<button class="muteButton"
|
||||
mutelabel="&muteButton.muteLabel;"
|
||||
unmutelabel="&muteButton.unmuteLabel;"/>
|
||||
<stack class="volumeStack" hidden="true">
|
||||
<box class="volumeBackgroundBar"/>
|
||||
<scale class="volumeControl" orient="vertical" dir="reverse" movetoclick="true"/>
|
||||
|
@ -295,8 +304,8 @@
|
|||
this.randomID = Math.random();
|
||||
this.videocontrols.randomID = this.randomID;
|
||||
|
||||
this.playButton.setAttribute("paused", this.video.paused);
|
||||
this.muteButton.setAttribute("muted", this.video.muted);
|
||||
this.setPlayButtonState(this.video.paused);
|
||||
this.setMuteButtonState(this.video.muted);
|
||||
|
||||
var volume = this.video.muted ? 0 : Math.round(this.video.volume * 100);
|
||||
this.volumeControl.value = volume;
|
||||
|
@ -368,15 +377,15 @@
|
|||
|
||||
switch (aEvent.type) {
|
||||
case "play":
|
||||
this.playButton.setAttribute("paused", false);
|
||||
this.setPlayButtonState(false);
|
||||
break;
|
||||
case "pause":
|
||||
case "ended":
|
||||
this.playButton.setAttribute("paused", true);
|
||||
this.setPlayButtonState(true);
|
||||
break;
|
||||
case "volumechange":
|
||||
var volume = this.video.muted ? 0 : Math.round(this.video.volume * 100);
|
||||
this.muteButton.setAttribute("muted", this.video.muted);
|
||||
this.setMuteButtonState(this.video.muted);
|
||||
this.volumeControl.value = volume;
|
||||
break;
|
||||
case "loadedmetadata":
|
||||
|
@ -686,6 +695,24 @@
|
|||
// controlling volume.
|
||||
},
|
||||
|
||||
setPlayButtonState: function(aPaused)
|
||||
{
|
||||
this.playButton.setAttribute("paused", aPaused);
|
||||
|
||||
var attrName = aPaused ? "playlabel" : "pauselabel";
|
||||
var value = this.playButton.getAttribute(attrName);
|
||||
this.playButton.setAttribute("aria-label", value);
|
||||
},
|
||||
|
||||
setMuteButtonState: function(aMuted)
|
||||
{
|
||||
this.muteButton.setAttribute("muted", aMuted);
|
||||
|
||||
var attrName = aMuted ? "unmutelabel" : "mutelabel";
|
||||
var value = this.muteButton.getAttribute(attrName);
|
||||
this.muteButton.setAttribute("aria-label", value);
|
||||
},
|
||||
|
||||
isEventWithin : function (event, parent1, parent2) {
|
||||
function isDescendant (node) {
|
||||
while (node) {
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
<!ENTITY playButton.playLabel "Play">
|
||||
<!ENTITY playButton.pauseLabel "Pause">
|
||||
<!ENTITY muteButton.muteLabel "Mute">
|
||||
<!ENTITY muteButton.unmuteLabel "Unmute">
|
||||
|
|
@ -49,6 +49,7 @@
|
|||
+ locale/@AB_CD@/global/dialog.properties (%chrome/global/dialog.properties)
|
||||
+ locale/@AB_CD@/global/tree.dtd (%chrome/global/tree.dtd)
|
||||
+ locale/@AB_CD@/global/textcontext.dtd (%chrome/global/textcontext.dtd)
|
||||
locale/@AB_CD@/global/videocontrols.dtd (%chrome/global/videocontrols.dtd)
|
||||
+ locale/@AB_CD@/global/viewSource.dtd (%chrome/global/viewSource.dtd)
|
||||
+ locale/@AB_CD@/global/viewSource.properties (%chrome/global/viewSource.properties)
|
||||
+ locale/@AB_CD@/global/wizard.dtd (%chrome/global/wizard.dtd)
|
||||
|
|
Загрузка…
Ссылка в новой задаче