diff options
Diffstat (limited to 'accessible/tests/mochitest/name')
-rw-r--r-- | accessible/tests/mochitest/name/a11y.ini | 18 | ||||
-rw-r--r-- | accessible/tests/mochitest/name/markup.js | 425 | ||||
-rw-r--r-- | accessible/tests/mochitest/name/markuprules.xml | 367 | ||||
-rw-r--r-- | accessible/tests/mochitest/name/test_ARIACore_examples.html | 90 | ||||
-rw-r--r-- | accessible/tests/mochitest/name/test_browserui.xhtml | 85 | ||||
-rw-r--r-- | accessible/tests/mochitest/name/test_counterstyle.html | 150 | ||||
-rw-r--r-- | accessible/tests/mochitest/name/test_general.html | 732 | ||||
-rw-r--r-- | accessible/tests/mochitest/name/test_general.xhtml | 343 | ||||
-rw-r--r-- | accessible/tests/mochitest/name/test_link.html | 87 | ||||
-rw-r--r-- | accessible/tests/mochitest/name/test_list.html | 103 | ||||
-rw-r--r-- | accessible/tests/mochitest/name/test_markup.html | 58 | ||||
-rw-r--r-- | accessible/tests/mochitest/name/test_svg.html | 53 | ||||
-rw-r--r-- | accessible/tests/mochitest/name/test_tree.xhtml | 207 |
13 files changed, 2718 insertions, 0 deletions
diff --git a/accessible/tests/mochitest/name/a11y.ini b/accessible/tests/mochitest/name/a11y.ini new file mode 100644 index 0000000000..cfcb49d816 --- /dev/null +++ b/accessible/tests/mochitest/name/a11y.ini @@ -0,0 +1,18 @@ +[DEFAULT] +support-files = + markup.js + markuprules.xml + !/accessible/tests/mochitest/*.js + !/accessible/tests/mochitest/moz.png + +[test_ARIACore_examples.html] +[test_browserui.xhtml] +[test_counterstyle.html] +[test_general.html] +[test_general.xhtml] +[test_link.html] +[test_list.html] +[test_markup.html] +skip-if = (debug && os == 'win') # Bug 1296784 +[test_svg.html] +[test_tree.xhtml] diff --git a/accessible/tests/mochitest/name/markup.js b/accessible/tests/mochitest/name/markup.js new file mode 100644 index 0000000000..a267bd4f7b --- /dev/null +++ b/accessible/tests/mochitest/name/markup.js @@ -0,0 +1,425 @@ +/* import-globals-from ../attributes.js */ +/* import-globals-from ../common.js */ +/* import-globals-from ../events.js */ +/* import-globals-from ../name.js */ + +// ////////////////////////////////////////////////////////////////////////////// +// Name tests described by "markuprules.xml" file. + +var gNameRulesFileURL = "markuprules.xml"; + +var gRuleDoc = null; + +// Debuggin stuff. +var gDumpToConsole = false; + +/** + * Start name tests. Run through markup elements and test names for test + * element (see namerules.xml for details). + */ +function testNames() { + // enableLogging("tree,stack"); // debugging + + var request = new XMLHttpRequest(); + request.open("get", gNameRulesFileURL, false); + request.send(); + + gRuleDoc = request.responseXML; + + var markupElms = evaluateXPath(gRuleDoc, "//rules/rulesample/markup"); + gTestIterator.iterateMarkups(markupElms); +} + +// ////////////////////////////////////////////////////////////////////////////// +// Private section. + +/** + * Helper class to interate through name tests. + */ +var gTestIterator = { + iterateMarkups: function gTestIterator_iterateMarkups(aMarkupElms) { + this.markupElms = aMarkupElms; + + this.iterateNext(); + }, + + iterateRules: function gTestIterator_iterateRules( + aElm, + aContainer, + aRuleSetElm, + aRuleElms, + aTestID + ) { + this.ruleSetElm = aRuleSetElm; + this.ruleElms = aRuleElms; + this.elm = aElm; + this.container = aContainer; + this.testID = aTestID; + + this.iterateNext(); + }, + + iterateNext: function gTestIterator_iterateNext() { + if (this.markupIdx == -1) { + this.markupIdx++; + testNamesForMarkup(this.markupElms[this.markupIdx]); + return; + } + + this.ruleIdx++; + if (this.ruleIdx == this.ruleElms.length) { + // When test is finished then name is empty and no explict-name. + var defaultName = this.ruleSetElm.hasAttribute("defaultName") + ? this.ruleSetElm.getAttribute("defaultName") + : null; + testName( + this.elm, + defaultName, + "Default name test (" + gTestIterator.testID + "). " + ); + testAbsentAttrs(this.elm, { "explicit-name": "true" }); + + this.markupIdx++; + if (this.markupIdx == this.markupElms.length) { + // disableLogging("tree"); // debugging + SimpleTest.finish(); + return; + } + + this.ruleIdx = -1; + + if (gDumpToConsole) { + dump( + "\nPend next markup processing. Wait for reorder event on " + + prettyName(document) + + "'\n" + ); + } + waitForEvent( + EVENT_REORDER, + document, + testNamesForMarkup, + null, + this.markupElms[this.markupIdx] + ); + + document.body.removeChild(this.container); + return; + } + + testNameForRule(this.elm, this.ruleElms[this.ruleIdx]); + }, + + markupElms: null, + markupIdx: -1, + rulesetElm: null, + ruleElms: null, + ruleIdx: -1, + elm: null, + container: null, + testID: "", +}; + +/** + * Process every 'markup' element and test names for it. Used by testNames + * function. + */ +function testNamesForMarkup(aMarkupElm) { + if (gDumpToConsole) { + dump("\nProcessing markup '" + aMarkupElm.getAttribute("id") + "'\n"); + } + + var div = document.createElement("div"); + div.setAttribute("id", "test"); + + var child = aMarkupElm.firstChild; + while (child) { + var newChild = document.importNode(child, true); + div.appendChild(newChild); + child = child.nextSibling; + } + + if (gDumpToConsole) { + dump( + "\nProcessing markup. Wait for reorder event on " + + prettyName(document) + + "'\n" + ); + } + waitForEvent( + EVENT_REORDER, + document, + testNamesForMarkupRules, + null, + aMarkupElm, + div + ); + + document.body.appendChild(div); +} + +function testNamesForMarkupRules(aMarkupElm, aContainer) { + var testID = aMarkupElm.getAttribute("id"); + if (gDumpToConsole) { + dump("\nProcessing markup rules '" + testID + "'\n"); + } + + var expr = "//html/body/div[@id='test']/" + aMarkupElm.getAttribute("ref"); + var elm = evaluateXPath(document, expr, htmlDocResolver)[0]; + + var ruleId = aMarkupElm.getAttribute("ruleset"); + var ruleElm = gRuleDoc.querySelector("[id='" + ruleId + "']"); + var ruleElms = getRuleElmsByRulesetId(ruleId); + + var processMarkupRules = gTestIterator.iterateRules.bind( + gTestIterator, + elm, + aContainer, + ruleElm, + ruleElms, + testID + ); + + // Images may be recreated after we append them into subtree. We need to wait + // in this case. If we are on profiling enabled build then stack tracing + // works and thus let's log instead. Note, that works if you enabled logging + // (refer to testNames() function). + if (isAccessible(elm) || isLogged("stack")) { + processMarkupRules(); + } else { + waitForEvent(EVENT_SHOW, elm, processMarkupRules); + } +} + +/** + * Test name for current rule and current 'markup' element. Used by + * testNamesForMarkup function. + */ +function testNameForRule(aElm, aRuleElm) { + if (aRuleElm.hasAttribute("attr")) { + if (gDumpToConsole) { + dump( + "\nProcessing rule { attr: " + aRuleElm.getAttribute("attr") + " }\n" + ); + } + + testNameForAttrRule(aElm, aRuleElm); + } else if (aRuleElm.hasAttribute("elm")) { + if (gDumpToConsole) { + dump( + "\nProcessing rule { elm: " + + aRuleElm.getAttribute("elm") + + ", elmattr: " + + aRuleElm.getAttribute("elmattr") + + " }\n" + ); + } + + testNameForElmRule(aElm, aRuleElm); + } else if (aRuleElm.getAttribute("fromsubtree") == "true") { + if (gDumpToConsole) { + dump( + "\nProcessing rule { fromsubtree: " + + aRuleElm.getAttribute("fromsubtree") + + " }\n" + ); + } + + testNameForSubtreeRule(aElm, aRuleElm); + } +} + +function testNameForAttrRule(aElm, aRule) { + var name = ""; + + var attr = aRule.getAttribute("attr"); + var attrValue = aElm.getAttribute(attr); + + var type = aRule.getAttribute("type"); + if (type == "string") { + name = attrValue; + } else if (type == "ref" && attrValue) { + var ids = attrValue.split(/\s+/); + for (var idx = 0; idx < ids.length; idx++) { + var labelElm = getNode(ids[idx]); + if (name != "") { + name += " "; + } + + name += labelElm.getAttribute("textequiv"); + } + } + + var msg = "Attribute '" + attr + "' test (" + gTestIterator.testID + "). "; + testName(aElm, name, msg); + + if (aRule.getAttribute("explict-name") != "false") { + testAttrs(aElm, { "explicit-name": "true" }, true); + } else { + testAbsentAttrs(aElm, { "explicit-name": "true" }); + } + + waitForEvent( + EVENT_NAME_CHANGE, + aElm, + gTestIterator.iterateNext, + gTestIterator + ); + + aElm.removeAttribute(attr); +} + +function testNameForElmRule(aElm, aRule) { + var labelElm; + + var tagname = aRule.getAttribute("elm"); + var attrname = aRule.getAttribute("elmattr"); + if (attrname) { + var filter = { + acceptNode: function filter_acceptNode(aNode) { + if ( + aNode.localName == this.mLocalName && + aNode.getAttribute(this.mAttrName) == this.mAttrValue + ) { + return NodeFilter.FILTER_ACCEPT; + } + + return NodeFilter.FILTER_SKIP; + }, + + mLocalName: tagname, + mAttrName: attrname, + mAttrValue: aElm.getAttribute("id"), + }; + + var treeWalker = document.createTreeWalker( + document.body, + NodeFilter.SHOW_ELEMENT, + filter + ); + labelElm = treeWalker.nextNode(); + } else { + // if attrname is empty then look for the element in subtree. + labelElm = aElm.getElementsByTagName(tagname)[0]; + if (!labelElm) { + labelElm = aElm.getElementsByTagName("html:" + tagname)[0]; + } + } + + if (!labelElm) { + ok(false, msg + " Failed to find '" + tagname + "' element."); + gTestIterator.iterateNext(); + return; + } + + var msg = "Element '" + tagname + "' test (" + gTestIterator.testID + ")."; + testName(aElm, labelElm.getAttribute("textequiv"), msg); + testAttrs(aElm, { "explicit-name": "true" }, true); + + var parentNode = labelElm.parentNode; + + if (gDumpToConsole) { + dump( + "\nProcessed elm rule. Wait for name change event on " + + prettyName(aElm) + + "\n" + ); + } + waitForEvent( + EVENT_NAME_CHANGE, + aElm, + gTestIterator.iterateNext, + gTestIterator + ); + + parentNode.removeChild(labelElm); +} + +function testNameForSubtreeRule(aElm, aRule) { + var msg = "From subtree test (" + gTestIterator.testID + ")."; + testName(aElm, aElm.getAttribute("textequiv"), msg); + testAbsentAttrs(aElm, { "explicit-name": "true" }); + + if (gDumpToConsole) { + dump( + "\nProcessed from subtree rule. Wait for reorder event on " + + prettyName(aElm) + + "\n" + ); + } + waitForEvent( + EVENT_NAME_CHANGE, + aElm, + gTestIterator.iterateNext, + gTestIterator + ); + + while (aElm.firstChild) { + aElm.firstChild.remove(); + } +} + +/** + * Return array of 'rule' elements. Used in conjunction with + * getRuleElmsFromRulesetElm() function. + */ +function getRuleElmsByRulesetId(aRulesetId) { + var expr = "//rules/ruledfn/ruleset[@id='" + aRulesetId + "']"; + var rulesetElm = evaluateXPath(gRuleDoc, expr); + return getRuleElmsFromRulesetElm(rulesetElm[0]); +} + +function getRuleElmsFromRulesetElm(aRulesetElm) { + var rulesetId = aRulesetElm.getAttribute("ref"); + if (rulesetId) { + return getRuleElmsByRulesetId(rulesetId); + } + + var ruleElms = []; + + var child = aRulesetElm.firstChild; + while (child) { + if (child.localName == "ruleset") { + ruleElms = ruleElms.concat(getRuleElmsFromRulesetElm(child)); + } + if (child.localName == "rule") { + ruleElms.push(child); + } + + child = child.nextSibling; + } + + return ruleElms; +} + +/** + * Helper method to evaluate xpath expression. + */ +function evaluateXPath(aNode, aExpr, aResolver) { + var xpe = new XPathEvaluator(); + + var resolver = aResolver; + if (!resolver) { + var node = + aNode.ownerDocument == null + ? aNode.documentElement + : aNode.ownerDocument.documentElement; + resolver = xpe.createNSResolver(node); + } + + var result = xpe.evaluate(aExpr, aNode, resolver, 0, null); + var found = []; + var res; + while ((res = result.iterateNext())) { + found.push(res); + } + + return found; +} + +function htmlDocResolver(aPrefix) { + var ns = { + html: "http://www.w3.org/1999/xhtml", + }; + return ns[aPrefix] || null; +} diff --git a/accessible/tests/mochitest/name/markuprules.xml b/accessible/tests/mochitest/name/markuprules.xml new file mode 100644 index 0000000000..045a25b437 --- /dev/null +++ b/accessible/tests/mochitest/name/markuprules.xml @@ -0,0 +1,367 @@ +<?xml version="1.0"?> + +<!-- + This XML file is used to create sequence of accessible name tests. It consist + of two sections. The first section 'ruledfn' declares name computation rules. + The second section 'rulesample' defines markup samples we need to check name + computation rules for. + + <ruledfn> + <ruleset> + <rule> + + Section 'ruledfn' contains 'ruleset' elements. Every 'ruleset' element is + presented by 'rule' elements so that sequence of 'rule' elements gives the + sequence of name computations rules. Every 'rule' element can be one of four + types. + + * <rule attr='' type='string'/> used when name is equal to the value of + attribute presented on the element. + + Example, 'aria-label' attribute. In this case 'rule' element has 'attr' + attribute pointing to attribute name and 'type' attribute with 'string' + value. For example, <rule attr="aria-label" type="string"/>. + + * <rule attr='' type='ref'/> used when name is calculated from elements that + are pointed to by attribute value on the element. + + Example is 'aria-labelledby'. In this case 'rule' element has 'attr' + attribute holding the sequence of IDs of elements used to compute the name, + in addition the 'rule' element has 'type' attribute with 'ref' value. + For example, <rule attr="aria-labelledby" type="ref"/>. + + * <rule elm='' elmattr=''/> used when name is calculated from another + element. These attributes are used to find an element by tagname and + attribute with value equaled to ID of the element. If 'elmattr' is missed + then element from subtree with the given tagname is used. + + Example, html:label@for element, <rule elm="label" elmattr="for"/>. + Example, html:caption element, <rule elm="caption"/> + + * <rule fromsubtree='true'/> used when name is computed from subtree. + + Example, html:button. In this case 'rule' element has 'fromsubtree' + attribute with 'true' value. + + <rulesample> + <markup ruleset=''> + + Section 'rulesample' provides set of markup samples ('markup' elements). Every + 'markup' element contains an element that accessible name will be computed for + (let's call it test element). In addition the 'markup' element contains some + other elements from native markup used in name calculation process for test + element. Test element is pointed to by 'ref' attribute on 'markup' element. + Also 'markup' element has 'ruleset' attribute to indicate ruleset for the test + element. + + How does it work? Let's consider simple example: + <ruledfn> + <ruleset id="aria"> + <rule attr="aria-label" type="string"/> + <rule attr="aria-labelledby" type="ref"/> + </ruleset> + </ruledfn> + <rulesample> + <markup ref="html:div" ruleset="aria"> + <html:span id="label" textequiv="test2">test2</html:span> + <html:div aria-label="test1" + aria-labelledby="label">it's a div</html:div> + </markup> + </rulesample> + + Initially 'markup' element holds markup for all rules specified by 'ruleset' + attribute. This allows us to check if the sequence of name computation rules + is correct. Here 'ruleset' element defines two rules. We get the first rule + which means accessible name is computed from value of 'aria-label' attribute. + Then we check accessible name for the test element and remove 'aria-label' + attribute. After we get the second rule which means we should get IDs from + 'aria-labelledby' attribute and compose accessible name from values of + 'textequiv' attributes (that are supposed to give the desired name for each + element that is being pointed to by aria-labelledby). Check accessible name + and finish test. +--> + +<rules xmlns:html="http://www.w3.org/1999/xhtml" + xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> + + <ruledfn> + + <!-- bricks --> + <ruleset id="ARIA"> + <rule attr="aria-labelledby" type="ref"/> + <rule attr="aria-label" type="string"/> + </ruleset> + + <ruleset id="HTMLControl:Head"> + <ruleset ref="ARIA"/> + <rule elm="label" elmattr="for"/> + </ruleset> + + <!-- general --> + <ruleset id="HTMLControl"> + <ruleset ref="HTMLControl:Head"/> + <rule fromsubtree="true"/> + <rule attr="title" type="string"/> + </ruleset> + + <ruleset id="HTMLElm"> + <ruleset ref="ARIA"/> + <rule attr="title" type="string"/> + </ruleset> + + <!-- specific --> + <ruleset id="HTMLARIAGridCell"> + <ruleset ref="ARIA"/> + <rule fromsubtree="true"/> + <rule attr="title" type="string"/> + </ruleset> + + <ruleset id="HTMLInputButton"> + <ruleset ref="HTMLControl:Head"/> + <rule attr="value" type="string" explict-name="false" reordered="true"/> + <rule attr="title" type="string"/> + </ruleset> + + <ruleset id="HTMLInputSubmit" defaultName="Submit Query"> + <ruleset ref="HTMLControl:Head"/> + <rule attr="value" type="string" explict-name="false"/> + </ruleset> + + <ruleset id="HTMLInputReset" defaultName="Reset"> + <ruleset ref="HTMLControl:Head"/> + <rule attr="value" type="string" explict-name="false"/> + </ruleset> + + <ruleset id="HTMLInputImage"> + <ruleset ref="HTMLControl:Head"/> + <rule attr="alt" type="string"/> + <rule attr="value" type="string"/> + <rule attr="title" type="string"/> + </ruleset> + + <ruleset id="HTMLInputImageNoValidSrc" defaultName="Submit Query"> + <ruleset ref="HTMLControl:Head"/> + <rule attr="alt" type="string" explict-name="false"/> + <rule attr="value" type="string" explict-name="false"/> + </ruleset> + + <ruleset id="HTMLOption"> + <ruleset ref="ARIA"/> + <rule attr="label" type="string"/> + <rule fromsubtree="true"/> + <rule attr="title" type="string"/> + </ruleset> + + <ruleset id="HTMLImg"> + <ruleset ref="ARIA"/> + <rule attr="alt" type="string"/> + <rule attr="title" type="string"/> + </ruleset> + + <ruleset id="HTMLTable"> + <ruleset ref="ARIA"/> + <rule elm="caption"/> + <rule attr="summary" type="string"/> + <rule attr="title" type="string"/> + </ruleset> + </ruledfn> + + <rulesample> + + <markup id="HTMLButtonTest" + ref="html:button" ruleset="HTMLControl"> + <html:span id="l1" textequiv="test2">test2</html:span> + <html:span id="l2" textequiv="test3">test3</html:span> + <html:label for="btn" textequiv="test4">test4</html:label> + <html:button id="btn" + aria-label="test1" + aria-labelledby="l1 l2" + title="test5" + textequiv="press me">press me</html:button> + </markup> + + <markup id="HTMLInputButtonTest" + ref="html:input" ruleset="HTMLInputButton"> + <html:span id="l1" textequiv="test2">test2</html:span> + <html:span id="l2" textequiv="test3">test3</html:span> + <html:label for="btn" textequiv="test4">test4</html:label> + <html:input id="btn" + type="button" + aria-label="test1" + aria-labelledby="l1 l2" + value="name from value" + alt="no name from al" + src="no name from src" + data="no name from data" + title="name from title"/> + </markup> + + <markup id="HTMLInputSubmitTest" + ref="html:input" ruleset="HTMLInputSubmit"> + <html:span id="l1" textequiv="test2">test2</html:span> + <html:span id="l2" textequiv="test3">test3</html:span> + <html:label for="btn-submit" textequiv="test4">test4</html:label> + <html:input id="btn-submit" + type="submit" + aria-label="test1" + aria-labelledby="l1 l2" + value="name from value" + alt="no name from atl" + src="no name from src" + data="no name from data" + title="no name from title"/> + </markup> + + <markup id="HTMLInputResetTest" + ref="html:input" ruleset="HTMLInputReset"> + <html:span id="l1" textequiv="test2">test2</html:span> + <html:span id="l2" textequiv="test3">test3</html:span> + <html:label for="btn-reset" textequiv="test4">test4</html:label> + <html:input id="btn-reset" + type="reset" + aria-label="test1" + aria-labelledby="l1 l2" + value="name from value" + alt="no name from alt" + src="no name from src" + data="no name from data" + title="no name from title"/> + </markup> + + <!-- + Disabled due to intermittent failures (bug 1436323) which became more + frequent due to the landing of bug 1383682. The latter bug made loading + of images from cache much more consistent, which appears to have impacted + the timing for this test case. If the image is switched to a unique + image (e.g. always decoding since there is no cache), the failure rate + increases, presumably because the test is dependent on a specific ordering + of events, and implicitly assumes the image is loaded immediately. + --> + + <!-- + <markup id="HTMLInputImageTest" + ref="html:input" ruleset="HTMLInputImage"> + <html:span id="l1" textequiv="test2">test2</html:span> + <html:span id="l2" textequiv="test3">test3</html:span> + <html:label for="btn-image" textequiv="test4">test4</html:label> + <html:input id="btn-image" + type="image" + aria-label="test1" + aria-labelledby="l1 l2" + alt="name from alt" + value="name from value" + src="../moz.png" + data="no name from data" + title="name from title"/> + </markup> + --> + + <markup id="HTMLInputImageNoValidSrcTest" + ref="html:input" ruleset="HTMLInputImageNoValidSrc"> + <html:span id="l1" textequiv="test2">test2</html:span> + <html:span id="l2" textequiv="test3">test3</html:span> + <html:label for="btn-image" textequiv="test4">test4</html:label> + <html:input id="btn-image" + type="image" + aria-label="test1" + aria-labelledby="l1 l2" + alt="name from alt" + value="name from value" + data="no name from data" + title="no name from title"/> + </markup> + + <markup id="HTMLOptionTest" + ref="html:select/html:option[1]" ruleset="HTMLOption"> + <html:span id="l1" textequiv="test2">test2</html:span> + <html:span id="l2" textequiv="test3">test3</html:span> + <html:select> + <html:option id="opt" + aria-label="test1" + aria-labelledby="l1 l2" + label="test4" + title="test5" + textequiv="option1">option1</html:option> + <html:option>option2</html:option> + </html:select> + </markup> + + <markup id="HTMLImageTest" + ref="html:img" ruleset="HTMLImg"> + <html:span id="l1" textequiv="test2">test2</html:span> + <html:span id="l2" textequiv="test3">test3</html:span> + <html:img id="img" + aria-label="Logo of Mozilla" + aria-labelledby="l1 l2" + alt="Mozilla logo" + title="This is a logo" + src="../moz.png"/> + </markup> + + <markup id="HTMLTdTest" + ref="html:table/html:tr/html:td" ruleset="HTMLElm"> + <html:span id="l1" textequiv="test2">test2</html:span> + <html:span id="l2" textequiv="test3">test3</html:span> + <html:label for="tc" textequiv="test4">test4</html:label> + <html:table> + <html:tr> + <html:td id="tc" + aria-label="test1" + aria-labelledby="l1 l2" + title="test5"> + <html:p>This is a paragraph</html:p> + <html:a href="#">This is a link</html:a> + <html:ul> + <html:li>This is a list</html:li> + </html:ul> + </html:td> + </html:tr> + </html:table> + </markup> + + <markup id="HTMLTdARIAGridCellTest" + ref="html:table/html:tr/html:td" ruleset="HTMLARIAGridCell"> + <html:span id="l1" textequiv="test2">test2</html:span> + <html:span id="l2" textequiv="test3">test3</html:span> + <html:label for="gc" textequiv="test4">test4</html:label> + <html:table> + <html:tr> + <html:td id="gc" + role="gridcell" + aria-label="test1" + aria-labelledby="l1 l2" + textequiv="This is a paragraph This is a link • Listitem1 • Listitem2" + title="This is a paragraph This is a link This is a list"> + <html:p>This is a paragraph</html:p> + <html:a href="#">This is a link</html:a> + <html:ul> + <html:li>Listitem1</html:li> + <html:li>Listitem2</html:li> + </html:ul> + </html:td> + </html:tr> + </html:table> + </markup> + + <markup id="HTMLTableTest" + ref="html:table" ruleset="HTMLTable"> + <html:span id="l1" textequiv="lby_tst6_1">lby_tst6_1</html:span> + <html:span id="l2" textequiv="lby_tst6_2">lby_tst6_2</html:span> + <html:label for="t" textequiv="label_tst6">label_tst6</html:label> + <!-- layout frame are recreated due to varous reasons, here's text frame + placed after caption frame triggres table frame recreation when + caption element is removed from DOM; get rid text node after caption + node to make the test working --> + <html:table id="t" aria-label="arialabel_tst6" + aria-labelledby="l1 l2" + summary="summary_tst6" + title="title_tst6"> + <html:caption textequiv="caption_tst6">caption_tst6</html:caption><html:tr> + <html:td>cell1</html:td> + <html:td>cell2</html:td> + </html:tr> + </html:table> + </markup> + + </rulesample> +</rules> diff --git a/accessible/tests/mochitest/name/test_ARIACore_examples.html b/accessible/tests/mochitest/name/test_ARIACore_examples.html new file mode 100644 index 0000000000..a15fee78f8 --- /dev/null +++ b/accessible/tests/mochitest/name/test_ARIACore_examples.html @@ -0,0 +1,90 @@ +<!DOCTYPE html> +<html> + +<head> + <title>Testing a11y name ccomputation testcases</title> + + <link rel="stylesheet" + type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css" /> + + <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> + + <script type="application/javascript" + src="../common.js"></script> + <script type="application/javascript" + src="../name.js"></script> + + <script type="application/javascript"> + function doTest() { + // All test cases taken from https://www.w3.org/TR/accname-1.1/ + // These were especially called out to demonstrate edge cases. + + // Example 1 from section 4.3.1 under 2.B. + // Element1 should get its name from the text in element3. + // Element2 should not gets name from element1 because that already + // gets its name from another element. + testName("el1", "hello"); + testName("el2", null); + + // Example 2 from section 4.3.1 under 2.C. + // The buttons should get their name from their labels and the links. + testName("del_row1", "Delete Documentation.pdf"); + testName("del_row2", "Delete HolidayLetter.pdf"); + + // Example 3 from section 4.3.1 under 2.F. + // Name should be own content text plus the value of the input plus + // more own inner text, separated by 1 space. + testName("chkbx", "Flash the screen 5 times"); + + // Example 4 from section 4.3.1 under 2.F. + // Name from content should include all the child nodes, including + // table cells. + testName("input_with_html_label", "foo bar baz"); + + SimpleTest.finish(); + } + + SimpleTest.waitForExplicitFinish(); + addA11yLoadEvent(doTest); + </script> + +</head> +<body> + <p id="display"></p> + <div id="content" style="display: none"></div> + <pre id="test"> + </pre> + + <!-- el1 should be labeled, el2 should not. --> + <div id="el1" aria-labelledby="el3"></div> + <div id="el2" aria-labelledby="el1"></div> + <div id="el3"> hello </div> + + <!-- The buttons should be labeled by themselves and the referenced link --> + <ul> + <li> + <a id="file_row1" href="./files/Documentation.pdf">Documentation.pdf</a> + <span role="button" tabindex="0" id="del_row1" aria-label="Delete" + aria-labelledby="del_row1 file_row1"></span> + </li> + <li> + <a id="file_row2" href="./files/HolidayLetter.pdf">HolidayLetter.pdf</a> + <span role="button" tabindex="0" id="del_row2" aria-label="Delete" + aria-labelledby="del_row2 file_row2"></span> + </li> + </ul> + + <!-- Label from combined text and subtree --> + <div id="chkbx" role="checkbox" aria-checked="false">Flash the screen + <span role="textbox" aria-multiline="false"> 5 </span> times</div> + + <!-- Label with name from content should include table --> + <input id="input_with_html_label" /> + <label for="input_with_html_label" id="label"> + <div>foo</div> + <table><tr><td>bar</td></tr></table> + <div>baz</div> + </label> + +</body> +</html> diff --git a/accessible/tests/mochitest/name/test_browserui.xhtml b/accessible/tests/mochitest/name/test_browserui.xhtml new file mode 100644 index 0000000000..b330b177c9 --- /dev/null +++ b/accessible/tests/mochitest/name/test_browserui.xhtml @@ -0,0 +1,85 @@ +<?xml version="1.0"?> +<?xml-stylesheet href="chrome://global/skin" type="text/css"?> +<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css" + type="text/css"?> + +<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" + title="Accessibility Name Calculating Test."> + + <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js" /> + + <script type="application/javascript" + src="../common.js"></script> + <script type="application/javascript" + src="../promisified-events.js"></script> + + <script type="application/javascript"> + <![CDATA[ + const { BrowserTestUtils } = ChromeUtils.import( + "resource://testing-common/BrowserTestUtils.jsm"); + const ABOUT_MOZILLA_URL = "about:mozilla"; + const ABOUT_LICENSE_URL = "about:license"; + + SimpleTest.waitForExplicitFinish(); + + (async () => { + info("Opening a new browser window."); + const win = await BrowserTestUtils.openNewBrowserWindow({ + remote: false, + fission: false, + }); + const winFocused = SimpleTest.promiseFocus(win); + const loaded = BrowserTestUtils.browserLoaded( + win.gBrowser.selectedBrowser); + let docLoaded = waitForEvent(EVENT_DOCUMENT_LOAD_COMPLETE, event => + event.accessible.QueryInterface(nsIAccessibleDocument).URL === ABOUT_LICENSE_URL, + `Loaded tab: ${ABOUT_LICENSE_URL}`); + BrowserTestUtils.loadURI(win.gBrowser.selectedBrowser, + "about:license"); + await loaded; + await docLoaded; + await winFocused; + + info(`Loading a new tab: ${ABOUT_MOZILLA_URL}.`); + docLoaded = waitForEvent(EVENT_DOCUMENT_LOAD_COMPLETE, event => + event.accessible.QueryInterface(nsIAccessibleDocument).URL === ABOUT_MOZILLA_URL, + `Added tab: ${ABOUT_MOZILLA_URL}`); + const tab = win.gBrowser.addTrustedTab(ABOUT_MOZILLA_URL); + await BrowserTestUtils.browserLoaded(tab.linkedBrowser); + await docLoaded; + + info("Focusing on the newly opened tab."); + const focused = waitForEvent(EVENT_FOCUS, event => + event.DOMNode === win.gBrowser.getBrowserAtIndex(1).contentDocument); + await BrowserTestUtils.synthesizeKey("VK_TAB", { ctrlKey: true }, + win.gBrowser.selectedBrowser); + const focusEvent = await focused; + + const title = getAccessible(win.document).name; + const accName = focusEvent.accessible.name; + isnot(title.indexOf(accName), -1, + `Window title contains the name of active tab document (Is "${accName}" in "${title}"?)`); + + await BrowserTestUtils.closeWindow(win); + SimpleTest.finish(); + })(); + ]]> + </script> + + <vbox 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=507382" + title="focus is fired earlier than root accessible name is changed when switching between tabs"> + Mozilla Bug + </a> + <p id="display"></p> + <div id="content" style="display: none"> + </div> + <pre id="test"> + </pre> + </body> + + <vbox id="eventdump"></vbox> + </vbox> +</window> diff --git a/accessible/tests/mochitest/name/test_counterstyle.html b/accessible/tests/mochitest/name/test_counterstyle.html new file mode 100644 index 0000000000..a20aca23f1 --- /dev/null +++ b/accessible/tests/mochitest/name/test_counterstyle.html @@ -0,0 +1,150 @@ +<html> + +<head> + <title>nsIAccessible::name calculation for @counter-style</title> + <link rel="stylesheet" type="text/css" + href="chrome://mochikit/content/tests/SimpleTest/test.css" /> + + <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> + + <script type="application/javascript" + src="../common.js"></script> + <script type="application/javascript" + src="../name.js"></script> + + <style id="counterstyles" type="text/css"> + @counter-style system-alphabetic { + system: alphabetic; + symbols: x y z; + } + @counter-style system-cyclic { + system: cyclic; + symbols: x y z; + } + @counter-style system-numeric { + system: numeric; + symbols: x y z; + } + @counter-style speak-as-bullets { + system: extends decimal; + speak-as: bullets; + } + @counter-style speak-as-numbers { + system: extends system-alphabetic; + speak-as: numbers; + } + @counter-style speak-as-words { + system: additive; + additive-symbols: 20 "twenty ", 9 "nine", 7 "seven", 1 "one"; + speak-as: words; + } + @counter-style speak-as-spell-out { + system: extends system-alphabetic; + speak-as: spell-out; + } + @counter-style speak-as-other { + system: extends decimal; + speak-as: speak-as-words; + } + @counter-style speak-as-loop { + system: extends upper-latin; + speak-as: speak-as-loop0; + } + @counter-style speak-as-loop0 { + system: extends disc; + speak-as: speak-as-loop1; + } + @counter-style speak-as-loop1 { + system: extends decimal; + speak-as: speak-as-loop0; + } + @counter-style speak-as-extended0 { + system: extends decimal; + speak-as: speak-as-extended1; + } + @counter-style speak-as-extended1 { + system: extends speak-as-extended0; + speak-as: disc; + } + @counter-style speak-as-extended2 { + system: extends decimal; + speak-as: speak-as-extended3; + } + @counter-style speak-as-extended3 { + system: extends speak-as-extended2; + } + </style> + + <script type="application/javascript"> + + function doTest() { + function testRule(aRule, aNames, aTodo) { + testName(aRule + "-1", aNames[0], null, aTodo); + testName(aRule + "-7", aNames[1], null, aTodo); + testName(aRule + "-29", aNames[2], null, aTodo); + } + + var spellOutNames = ["X. 1", "Y X. 7", "Y Z Y. 29"]; + var bulletsNames = [kDiscBulletText + "1", + kDiscBulletText + "7", + kDiscBulletText + "29"]; + var numbersNames = ["1. 1", "7. 7", "29. 29"]; + var wordsNames = ["one. 1", "seven. 7", "twenty nine. 29"]; + + testRule("system-alphabetic", spellOutNames, true); // bug 1024178 + testRule("system-cyclic", bulletsNames); + testRule("system-numeric", numbersNames); + + testRule("speak-as-bullets", bulletsNames); + testRule("speak-as-numbers", numbersNames); + testRule("speak-as-words", wordsNames); + testRule("speak-as-spell-out", spellOutNames, true); // bug 1024178 + testRule("speak-as-other", wordsNames); + + testRule("speak-as-loop", bulletsNames); + testRule("speak-as-loop0", bulletsNames); + testRule("speak-as-loop1", numbersNames); + + testRule("speak-as-extended0", bulletsNames); + testRule("speak-as-extended1", bulletsNames); + testRule("speak-as-extended2", numbersNames); + testRule("speak-as-extended3", numbersNames); + + SimpleTest.finish(); + } + + SimpleTest.waitForExplicitFinish(); + addA11yLoadEvent(doTest); + </script> + +</head> + +<body> + + <a target="_blank" + href="https://bugzilla.mozilla.org/show_bug.cgi?id=966166" + title="Bug 966166 - Implement @counter-style rule"> + Bug 966166 + </a> + + <ol id="list"></ol> + + <script type="application/javascript"> + var list = getNode("list"); + var rules = getNode("counterstyles").sheet.cssRules; + var values = [1, 7, 29]; + for (var i = 0; i < rules.length; i++) { + var rule = rules[i]; + for (var j = 0; j < values.length; j++) { + var item = document.createElement("li"); + item.id = rule.name + "-" + values[j]; + item.value = values[j]; + item.textContent = values[j]; + item.setAttribute("style", "list-style-type: " + rule.name); + list.appendChild(item); + } + } + </script> + +</body> +</html> diff --git a/accessible/tests/mochitest/name/test_general.html b/accessible/tests/mochitest/name/test_general.html new file mode 100644 index 0000000000..89314712fb --- /dev/null +++ b/accessible/tests/mochitest/name/test_general.html @@ -0,0 +1,732 @@ +<html> + +<head> + <title>nsIAccessible::name calculation</title> + <link rel="stylesheet" type="text/css" + href="chrome://mochikit/content/tests/SimpleTest/test.css" /> + + <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> + + <script type="application/javascript" + src="../common.js"></script> + <script type="application/javascript" + src="../name.js"></script> + + <script type="application/javascript"> + + function doTest() { + // aria-label + + // Simple label provided via ARIA + testName("btn_simple_aria_label", "I am a button"); + + // aria-label and aria-labelledby, expect aria-labelledby + testName("btn_both_aria_labels", "text I am a button, two"); + + // //////////////////////////////////////////////////////////////////////// + // aria-labelledby + + // Single relation. The value of 'aria-labelledby' contains the ID of + // an element. Gets the name from text node of that element. + testName("btn_labelledby_text", "text"); + + // Multiple relations. The value of 'aria-labelledby' contains the IDs + // of elements. Gets the name from text nodes of those elements. + testName("btn_labelledby_texts", "text1 text2"); + + // //////////////////////////////////////////////////////////////////////// + // Name from named accessible + + testName("input_labelledby_namedacc", "Data"); + + // //////////////////////////////////////////////////////////////////////// + // Name from subtree (single relation labelled_by). + + // Gets the name from text nodes contained by nested elements + testName("btn_labelledby_mixed", "nomore text"); + + // Gets the name from text nodes contained by nested elements, ignores + // hidden elements (bug 443081). + testName("btn_labelledby_mixed_hidden_child", "nomore text2"); + + // Gets the name from hidden text nodes contained by nested elements, + // (label element is hidden entirely), (bug 443081). + testName("btn_labelledby_mixed_hidden", "lala more hidden text"); + + // Gets the name from text nodes contained by nested elements having block + // representation (every text node value in the name should be devided by + // spaces) + testName("btn_labelledby_mixed_block", "text more text"); + + // Gets the name from text nodes contained by html:td. The text nodes + // should not be divided by spaces. + testName("btn_labelledby_mixed_table", "textTEXTtext"); + + // Gets the name from image accessible. + testName("btn_labelledby_mixed_img", "text image"); + + // Gets the name from input accessibles + // Note: if input have label elements then the name isn't calculated + // from them. + testName("btn_labelledby_mixed_input", + "input button Submit Query Reset Submit Query"); + + // Gets the name from the title of object element. + testName("btn_labelledby_mixed_object", "object"); + + // Gets the name from text nodes. Element br adds space between them. + testName("btn_labelledby_mixed_br", "text text"); + + // Gets the name from label content which allows name from subtree, + // ignore @title attribute on label + testName("from_label_ignoretitle", "Country:"); + + // Gets the name from html:p content, which doesn't allow name from + // subtree, ignore @title attribute on label + testName("from_p_ignoretitle", "Choose country from."); + + // Gets the name from html:input value, ignore @title attribute on input + testName("from_input_ignoretitle", "Custom country"); + + // Insert spaces around the control's value to not jamm sibling text nodes + testName("insert_spaces_around_control", "start value end"); + + // Gets the name from @title, ignore whitespace content + testName("from_label_ignore_ws_subtree", "about"); + + // role="alert" doesn't get name from subtree... + testName("alert", null); + // but the subtree is used if referenced by aria-labelledby. + testName("inputLabelledByAlert", "Error"); + + // //////////////////////////////////////////////////////////////////////// + // label element + + // The label element contains the button. The name is calculated from + // this button. + // Note: the name contains the content of the button. + testName("btn_label_inside", "text10text"); + + // The label element and the button are placed in the same form. Gets + // the name from the label subtree. + testName("btn_label_inform", "in form"); + + // The label element is placed outside of form where the button is. + // Take into account the label. + testName("btn_label_outform", "out form"); + + // The label element and the button are in the same document. Gets the + // name from the label subtree. + testName("btn_label_indocument", "in document"); + + // Multiple label elements for single button + testName("btn_label_multi", "label1label2"); + + // Multiple controls inside a label element + testName("ctrl_in_label_1", "Enable a button control"); + testName("ctrl_in_label_2", "button"); + + + // //////////////////////////////////////////////////////////////////////// + // name from children + + // ARIA role button is presented allowing the name calculation from + // children. + testName("btn_children", "14"); + + // html:button, no name from content + testName("btn_nonamefromcontent", null); + + // ARIA role option is presented allowing the name calculation from + // visible children (bug 443081). + testName("lb_opt1_children_hidden", "i am visible"); + + // Get the name from subtree of menuitem crossing role nothing to get + // the name from its children. + testName("tablemenuitem", "menuitem 1"); + + // Get the name from child acronym title attribute rather than from + // acronym content. + testName("label_with_acronym", "O A T F World Wide Web"); + + testName("testArticle", "Test article"); + + testName("h1", "heading"); + testName("aria_heading", "aria_heading"); + + // //////////////////////////////////////////////////////////////////////// + // title attribute + + // If nothing is left. Let's try title attribute. + testName("btn_title", "title"); + + // //////////////////////////////////////////////////////////////////////// + // textarea name + + // textarea's name should have the value, which initially is specified by + // a text child. + testName("textareawithchild", "Story Foo is ended."); + + // new textarea name should reflect the value change. + var elem = document.getElementById("textareawithchild"); + elem.value = "Bar"; + + testName("textareawithchild", "Story Bar is ended."); + + // //////////////////////////////////////////////////////////////////////// + // controls having a value used as a part of computed name + + testName("ctrlvalue_progressbar:input", "foo 5 baz"); + testName("ctrlvalue_scrollbar:input", "foo 5 baz"); + testName("ctrlvalue_slider:input", "foo 5 baz"); + testName("ctrlvalue_spinbutton:input", "foo 5 baz"); + testName("ctrlvalue_combobox:input", "foo 5 baz"); + testName("ctrlvalue_meter:input", "foo 5 baz"); + + + // /////////////////////////////////////////////////////////////////////// + // label with nested combobox (test for 'f' item of name computation guide) + + testName("comboinstart", "One day(s)."); + testName("combo3", "day(s)."); + + testName("textboxinstart", "Two days."); + testName("textbox1", "days."); + + testName("comboinmiddle", "Subscribe to ATOM feed."); + testName("combo4", "Subscribe to ATOM feed."); + + testName("comboinmiddle2", "Play the Haliluya sound when new mail arrives"); + testName("combo5", null); // label isn't used as a name for control + testName("checkbox", "Play the Haliluya sound when new mail arrives"); + testName("comboinmiddle3", "Play the Haliluya sound when new mail arrives"); + testName("combo6", "Play the Haliluya sound when new mail arrives"); + + testName("comboinend", "This day was sunny"); + testName("combo7", "This day was"); + + testName("textboxinend", "This day was sunny"); + testName("textbox2", "This day was"); + + // placeholder + testName("ph_password", "a placeholder"); + testName("ph_text", "a placeholder"); + testName("ph_textarea", "a placeholder"); + testName("ph_text2", "a label"); + testName("ph_textarea2", "a label"); + testName("ph_text3", "a label"); + + // Test equation image + testName("img_eq", "x^2 + y^2 + z^2"); + testName("input_img_eq", "x^2 + y^2 + z^2"); + testName("txt_eq", "x^2 + y^2 + z^2"); + + // ////////////////////////////////////////////////////////////////////// + // tests for duplicate announcement of content + + testName("test_note", null); + + // ////////////////////////////////////////////////////////////////////// + // Tests for name from sub tree of tr element. + + // By default, we want no name. + testName("NoNameForTR", null); + testName("NoNameForNonStandardTR", null); + + // But we want it if the tr has an ARIA role. + testName("NameForTRBecauseStrongARIA", "a b"); + + // But not if it is a weak (landmark) ARIA role + testName("NoNameForTRBecauseWeakARIA", null); + + // Name from sub tree of grouping if requested by other accessible. + testName("grouping", null); + testName("requested_name_from_grouping", "label"); + testName("listitem_containing_block_tbody", "label"); + // Groupings shouldn't be included when calculating from the subtree of + // a treeitem. + testName("treeitem_containing_grouping", "root"); + + // Name from subtree of grouping labelled by an ancestor. + testName("grouping_labelledby_ancestor", "label"); + + // Name from subtree of a container containing text nodes and inline + // elements. There should be no spaces because everyhing is inline. + testName("container_text_inline", "abc"); + // Name from subtree of a container containing text nodes and block + // elements. There should be a space on both sides of the block. + testName("container_text_block", "a b c"); + // Name from subtree of a container containing text nodes and empty + // block elements. There should be space on either side of the blocks, but + // not a double space. + testName("container_text_emptyblock", "a b"); + + SimpleTest.finish(); + } + + SimpleTest.waitForExplicitFinish(); + addA11yLoadEvent(doTest); + </script> + +</head> + +<body> + + <a target="_blank" + href="https://bugzilla.mozilla.org/show_bug.cgi?id=428479" + title="Bug 428479 - Support ARIA role=math"> + Bug 428479 + </a> + <a target="_blank" + href="https://bugzilla.mozilla.org/show_bug.cgi?id=429666" + title="Expose ROLE_DOCUMENT for ARIA landmarks that inherit from document"> + Bug 429666 + </a> + <a target="_blank" + href="https://bugzilla.mozilla.org/show_bug.cgi?id=444279" + title="mochitest for accessible name calculating"> + Bug 444279 + </a> + <a target="_blank" + href="https://bugzilla.mozilla.org/show_bug.cgi?id=459635" + title="nsIAccessible::name calculation for HTML buttons"> + Bug 459635 + </a> + <a target="_blank" + href="https://bugzilla.mozilla.org/show_bug.cgi?id=530081" + title="Clean up our tree walker"> + Bug 530081 + </a><br> + <a target="_blank" + href="https://bugzilla.mozilla.org/show_bug.cgi?id=604391" + title="Use placeholder as name if name is otherwise empty"> + Bug 604391 + </a> + <a target="_blank" + href="https://bugzilla.mozilla.org/show_bug.cgi?id=669312" + title="Accessible name is duplicated when input has a label associated uisng for/id and is wrapped around the input"> + Bug 669312 + </a> + <a target="_blank" + href="https://bugzilla.mozilla.org/show_bug.cgi?id=704416" + title="HTML acronym and abbr names should be provided by @title"> + Bug 704416 + </a> + <a target="_blank" + href="https://bugzilla.mozilla.org/show_bug.cgi?id=812041" + title="ARIA slider and spinbutton don't provide a value for name computation"> + Bug 812041 + </a> + <a target="_blank" + href="https://bugzilla.mozilla.org/show_bug.cgi?id=823927" + title="Text is jammed with control's text in name computation"> + Bug 823927 + </a> + <a target="_blank" + href="https://bugzilla.mozilla.org/show_bug.cgi?id=835666" + title="ARIA combobox selected value is not a part of name computation"> + Bug 835666 + </a> + <a target="_blank" + href="https://bugzilla.mozilla.org/show_bug.cgi?id=833256" + title="role note shouldn't pick up the name from subtree"> + Mozilla Bug 833256 + </a> + <p id="display"></p> + <div id="content" style="display: none"></div> + <pre id="test"> + </pre> + + <!-- aria-label, simple label --> + <span id="btn_simple_aria_label" role="button" aria-label="I am a button"/> + <br/> + <!-- aria-label plus aria-labelledby --> + <span id="btn_both_aria_labels" role="button" aria-label="I am a button, two" + aria-labelledby="labelledby_text btn_both_aria_labels"/> + <br/> + + <!-- aria-labelledby, single relation --> + <span id="labelledby_text">text</span> + <button id="btn_labelledby_text" + aria-labelledby="labelledby_text">1</button> + <br/> + + <!-- aria-labelledby, multiple relations --> + <span id="labelledby_text1">text1</span> + <span id="labelledby_text2">text2</span> + <button id="btn_labelledby_texts" + aria-labelledby="labelledby_text1 labelledby_text2">2</button> + <br/> + + <!-- name from named accessible --> + <input id="labelledby_namedacc" type="checkbox" + aria-label="Data" /> + <input id="input_labelledby_namedacc" + aria-labelledby="labelledby_namedacc" /> + + <!-- the name from subtree, mixed content --> + <span id="labelledby_mixed">no<span>more text</span></span> + <button id="btn_labelledby_mixed" + aria-labelledby="labelledby_mixed">3</button> + <br/> + + <!-- the name from subtree, mixed/hidden content --> + <span id="labelledby_mixed_hidden_child"> + no<span>more + <span style="display: none;">hidden</span> + text2 + <span style="visibility: hidden">hidden2</span> + </span> + </span> + <button id="btn_labelledby_mixed_hidden_child" + aria-labelledby="labelledby_mixed_hidden_child">3.1</button> + <br/> + + <!-- the name from subtree, mixed/completely hidden content --> + <span id="labelledby_mixed_hidden" + style="display: none;">lala <span>more hidden </span>text</span></span> + <button id="btn_labelledby_mixed_hidden" + aria-labelledby="labelledby_mixed_hidden">3.2</button> + <br/> + + <!-- the name from subtree, mixed content, block structure --> + <div id="labelledby_mixed_block"><div>text</div>more text</div></div> + <button id="btn_labelledby_mixed_block" + aria-labelledby="labelledby_mixed_block">4</button> + <br/> + + <!-- the name from subtree, mixed content, table structure --> + <table><tr> + <td id="labelledby_mixed_table">text<span>TEXT</span>text</td> + </tr></table> + <button id="btn_labelledby_mixed_table" + aria-labelledby="labelledby_mixed_table">5</button> + <br/> + + <!-- the name from subtree, child img --> + <span id="labelledby_mixed_img">text<img alt="image"/></span> + <button id="btn_labelledby_mixed_img" + aria-labelledby="labelledby_mixed_img">6</button> + <br/> + + <!-- the name from subtree, child inputs --> + <span id="labelledby_mixed_input"> + <input type="button" id="input_button" title="input button"/> + <input type="submit" id="input_submit"/> + <input type="reset" id="input_reset"/> + <input type="image" id="input_image" title="input image"/> + </span> + <button id="btn_labelledby_mixed_input" + aria-labelledby="labelledby_mixed_input">7</button> + <br/> + + <!-- the name from subtree, child object --> + <span id="labelledby_mixed_object"> + <object data="about:blank" title="object"></object> + </span> + <button id="btn_labelledby_mixed_object" + aria-labelledby="labelledby_mixed_object">8</button> + <br/> + + <!-- the name from subtree, child br --> + <span id="labelledby_mixed_br">text<br/>text</span> + <button id="btn_labelledby_mixed_br" + aria-labelledby="labelledby_mixed_br">9</button> + <br/> + + <!-- the name from subtree, name from label content rather than from its title + attribute --> + <label for="from_label_ignoretitle" + title="Select your country of origin">Country:</label> + <select id="from_label_ignoretitle"> + <option>Germany</option> + <option>Russia</option> + </select> + + <!-- the name from subtree, name from html:p content rather than from its + title attribute --> + <p id="p_ignoretitle" + title="Select your country of origin">Choose country from.</p> + <select id="from_p_ignoretitle" aria-labelledby="p_ignoretitle"> + <option>Germany</option> + <option>Russia</option> + </select> + + <!-- the name from subtree, name from html:input value rather than from its + title attribute --> + <p id="from_input_ignoretitle" aria-labelledby="input_ignoretitle">Country</p> + <input id="input_ignoretitle" + value="Custom country" + title="Input your country of origin"/ > + + <!-- name from subtree, surround control by spaces to not jamm the text --> + <label id="insert_spaces_around_control"> + start<input value="value">end + </label> + + <!-- no name from subtree because it holds whitespaces only --> + <a id="from_label_ignore_ws_subtree" href="about:mozilla" title="about"> </a> + + <!-- Don't use subtree unless referenced by aria-labelledby. --> + <div id="alert" role="alert">Error</div> + <input type="text" id="inputLabelledByAlert" aria-labelledby="alert"> + + <!-- label element, label contains control --> + <label>text<button id="btn_label_inside">10</button>text</label> + <br/> + + <!-- label element, label and the button are in the same form --> + <form> + <label for="btn_label_inform">in form</label> + <button id="btn_label_inform">11</button> + </form> + + <!-- label element, label is outside of the form of the button --> + <label for="btn_label_outform">out form</label> + <form> + <button id="btn_label_outform">12</button> + </form> + + <!-- label element, label and the button are in the same document --> + <label for="btn_label_indocument">in document</label> + <button id="btn_label_indocument">13</button> + + <!-- multiple label elements for single button --> + <label for="btn_label_multi">label1</label> + <label for="btn_label_multi">label2</label> + <button id="btn_label_multi">button</button> + + <!-- a label containing more than one controls --> + <label> + Enable <input id="ctrl_in_label_1" type="checkbox"> a + <input id="ctrl_in_label_2" type="button" value="button"> control + </label> + + <!-- name from children --> + <span id="btn_children" role="button">14</span> + + <!-- no name from content, ARIA role overrides this rule --> + <button id="btn_nonamefromcontent" role="img">1</button> + + <!-- name from children, hidden children --> + <div role="listbox" tabindex="0"> + <div id="lb_opt1_children_hidden" role="option" tabindex="0"> + <span>i am visible</span> + <span style="display:none">i am hidden</span> + </div> + </div> + + <table role="menu"> + <tr role="menuitem" id="tablemenuitem"> + <td>menuitem 1</td> + </tr> + <tr role="menuitem"> + <td>menuitem 2</td> + </tr> + </table> + + <label id="label_with_acronym"> + <acronym title="O A T F">OATF</acronym> + <abbr title="World Wide Web">WWW</abbr> + </label> + + <div id="testArticle" role="article" title="Test article"> + <p>This is a paragraph inside the article.</p> + </div> + + <h1 id="h1" title="oops">heading</h1> + <div role="heading" id="aria_heading">aria_heading</div> + + <!-- name from title attribute --> + <span id="btn_title" role="group" title="title">15</span> + + <!-- A textarea nested in a label with a text child (bug #453371). --> + <form> + <label>Story + <textarea id="textareawithchild" name="name">Foo</textarea> + is ended. + </label> + </form> + + <!-- controls having a value used as part of computed name --> + <input type="checkbox" id="ctrlvalue_progressbar:input"> + <label for="ctrlvalue_progressbar:input"> + foo <span role="progressbar" + aria-valuenow="5" aria-valuemin="1" + aria-valuemax="10">5</span> baz + </label> + + <input type="checkbox" id="ctrlvalue_scrollbar:input" /> + <label for="ctrlvalue_scrollbar:input"> + foo <span role="scrollbar" + aria-valuenow="5" aria-valuemin="1" + aria-valuemax="10">5</span> baz + </label> + + <input type="checkbox" id="ctrlvalue_slider:input"> + <label for="ctrlvalue_slider:input"> + foo <input role="slider" type="range" + value="5" min="1" max="10" + aria-valuenow="5" aria-valuemin="1" + aria-valuemax="10"> baz + </label> + + <input type="checkbox" id="ctrlvalue_spinbutton:input"> + <label for="ctrlvalue_spinbutton:input"> + foo <input role="spinbutton" type="number" + value="5" min="1" max="10" + aria-valuenow="5" aria-valuemin="1" + aria-valuemax="10"> + baz + </label> + + <input type="checkbox" id="ctrlvalue_combobox:input"> + <label for="ctrlvalue_combobox:input"> + foo + <div role="combobox"> + <div role="textbox"></div> + <ul role="listbox" style="list-style-type: none;"> + <li role="option">1</li> + <li role="option" aria-selected="true">5</li> + <li role="option">3</li> + </ul> + </div> + baz + </label> + + <input type="checkbox" id="ctrlvalue_meter:input"> + <label for="ctrlvalue_meter:input"> + foo + <meter>5</meter> + </div> + baz + </label> + + <!-- a label with a nested control in the start, middle and end --> + <form> + <!-- at the start (without and with whitespaces) --> + <label id="comboinstart"><select id="combo3"> + <option>One</option> + <option>Two</option> + </select> + day(s). + </label> + + <label id="textboxinstart"> + <input id="textbox1" value="Two"> + days. + </label> + + <!-- in the middle --> + <label id="comboinmiddle"> + Subscribe to + <select id="combo4" name="occupation"> + <option>ATOM</option> + <option>RSS</option> + </select> + feed. + </label> + + <label id="comboinmiddle2" for="checkbox">Play the + <select id="combo5"> + <option>Haliluya</option> + <option>Hurra</option> + </select> + sound when new mail arrives + </label> + <input id="checkbox" type="checkbox" /> + + <label id="comboinmiddle3" for="combo6">Play the + <select id="combo6"> + <option>Haliluya</option> + <option>Hurra</option> + </select> + sound when new mail arrives + </label> + + <!-- at the end (without and with whitespaces) --> + <label id="comboinend"> + This day was + <select id="combo7" name="occupation"> + <option>sunny</option> + <option>rainy</option> + </select></label> + + <label id="textboxinend"> + This day was + <input id="textbox2" value="sunny"> + </label> + </form> + + <!-- placeholder --> + <input id="ph_password" type="password" value="" placeholder="a placeholder" /> + <input id="ph_text" type="text" placeholder="a placeholder" /> + <textarea id="ph_textarea" cols="5" placeholder="a placeholder"></textarea> + + <!-- placeholder does not win --> + <input id="ph_text2" type="text" aria-label="a label" placeholder="meh" /> + <textarea id="ph_textarea2" cols="5" aria-labelledby="ph_text2" + placeholder="meh"></textarea> + + <label for="ph_text3">a label</label> + <input id="ph_text3" placeholder="meh" /> + + <p>Image: + <img id="img_eq" role="math" src="foo" alt="x^2 + y^2 + z^2"> + <input type="image" id="input_img_eq" src="foo" alt="x^2 + y^2 + z^2"> + </p> + + <p>Text: + <span id="txt_eq" role="math" title="x^2 + y^2 + z^2">x<sup>2</sup> + + y<sup>2</sup> + z<sup>2</sup></span> + + <!-- duplicate announcement --> + <div id="test_note" role="note">subtree</div> + + <!-- No name for tr from its sub tree --> + <table><tr id="NoNameForTR"><th>a</th><td>b</td></tr></table> + <table style="display: block;"> + <tr id="NoNameForNonStandardTR" style="display:block;"> + <th>a</th><td>b</td> + </tr> + </table> + + <!-- Name from sub tree of tr, because it has a strong ARIA role --> + <table><tr id="NameForTRBecauseStrongARIA" role="row"><th>a</th><td>b</td></tr></table> + + <!-- No name for tr because of weak (landmark) role --> + <table><tr id="NoNameForTRBecauseWeakARIA" role="main"><th>a</th><td>b</td></tr></table> + + <!-- Name from subtree of grouping if requested by other object --> + <div id="grouping" role="group">label</div> + <button id="requested_name_from_grouping"aria-labelledby="grouping"></button> + <!-- Name from sub tree of tbody marked as display:block;, which is also a grouping --> + <div id="listitem_containing_block_tbody" role="listitem"> + <table> + <tbody style="display: block;"> + <tr><td>label</td></tr> + </tbody> + </table> + </div> + <!-- Name from subtree of treeitem containing grouping --> + <div id="treeitem_containing_grouping" role="treeitem" aria-level="1" aria-expanded="true">root + <div role="group"> + <div role="treeitem" aria-level="2">sub</div> + </div> + </div> + + <!-- Name from subtree of grouping labelled by an ancestor. --> + <div id="grouping_ancestor_label">label + <div id="grouping_labelledby_ancestor" role="group" aria-labelledby="grouping_ancestor_label"> + This content should not be included in the grouping's label. + </div> + </div> + + <!-- Text nodes and inline elements. --> + <div id="container_text_inline" role="option">a<strong>b</strong>c</div> + <!-- Text nodes and block elements. --> + <div id="container_text_block" role="option">a<p>b</p>c</div> + <!-- Text nodes and empty block elements. --> + <div id="container_text_emptyblock" role="option">a<p></p><p></p>b</div> +</body> +</html> diff --git a/accessible/tests/mochitest/name/test_general.xhtml b/accessible/tests/mochitest/name/test_general.xhtml new file mode 100644 index 0000000000..a1c6f1461e --- /dev/null +++ b/accessible/tests/mochitest/name/test_general.xhtml @@ -0,0 +1,343 @@ +<?xml version="1.0"?> +<?xml-stylesheet href="chrome://global/skin" type="text/css"?> +<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css" + type="text/css"?> + +<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" + xmlns:html="http://www.w3.org/1999/xhtml" + title="Accessibility Name Calculating Test."> + + <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js" /> + + <script type="application/javascript" + src="../common.js"></script> + <script type="application/javascript" + src="../role.js"></script> + <script type="application/javascript" + src="../name.js"></script> + + <script type="application/javascript"> + <![CDATA[ + function doTest() + { + // aria-label + + // Simple label provided via ARIA + testName("btn_simple_aria_label", "I am a button"); + + // aria-label and aria-labelledby, expect aria-labelledby + testName("btn_both_aria_labels", "text I am a button, two"); + + ////////////////////////////////////////////////////////////////////////// + // aria-labelledby + + // Single relation. The value of 'aria-labelledby' contains the ID of + // an element. Gets the name from text node of that element. + testName("btn_labelledby_text", "text"); + + // Multiple relations. The value of 'aria-labelledby' contains the IDs + // of elements. Gets the name from text nodes of those elements. + testName("btn_labelledby_texts", "text1 text2"); + + // Trick cases. Self and recursive referencing. + testName("rememberHistoryDays", "Remember 3 days"); + testName("historyDays", "Remember 3 days"); + testName("rememberAfter", "days"); + + ////////////////////////////////////////////////////////////////////////// + // Name from subtree (single relation labelled_by). + + // Gets the name from text nodes contained by nested elements. + testName("btn_labelledby_mixed", "no more text"); + + // Gets the name from text nodes and selected item of menulist + // (other items are ignored). + testName("btn_labelledby_mixed_menulist", + "no more text selected item more text"); + + // Gets the name from text nodes contained by nested elements, ignores + // hidden elements (bug 443081). + testName("btn_labelledby_mixed_hidden_child", "no more text2"); + + // Gets the name from hidden text nodes contained by nested elements, + // (label element is hidden entirely), (bug 443081) + testName("btn_labelledby_mixed_hidden", "lala more hidden text"); + + + ////////////////////////////////////////////////////////////////////////// + // Name from @label attribute. + + // Gets the name from @label attribute. + testName("btn_labelattr", "labeled element"); + + + ////////////////////////////////////////////////////////////////////////// + // Name for nsIDOMXULSelectControlItemElement. + + // Gets the name from @label attribute. + testName("li_nsIDOMXULSelectControlItemElement", "select control item"); + + + ////////////////////////////////////////////////////////////////////////// + // Name if the XUL element doesn't implement nsIDOMXULSelectControlElement + // and has @label attribute. + + testName("box_not_nsIDOMXULSelectControlElement", "box"); + + + ////////////////////////////////////////////////////////////////////////// + // Name from the label element. + + // The label and button are placed on 2nd level relative common parent. + testName("btn_label_1", "label1"); + + // The label is on 1st, the button is on 5th level relative common parent. + testName("btn_label_2", "label2"); + + // The label and button are siblings. + testName("btn_label_3", "label3"); + + // Multiple labels for single button: XUL button takes the last one. + testName("btn_label_4", "label5"); + + // Label associated with HTML element. + testName("input_label", "input label"); + + + ////////////////////////////////////////////////////////////////////////// + // tooltiptext (if nothing above isn't presented then tooltiptext is used) + testName("box_tooltiptext", "tooltiptext label"); + + + ////////////////////////////////////////////////////////////////////////// + // Name from the @title attribute of <toolbaritem/> (original bug 237249). + + // Direct child of toolbaritem. + testName("toolbaritem_child", null); + + // Child from subtree of toolbaritem. + testName("toolbaritem_hboxbutton", "button"); + + + ////////////////////////////////////////////////////////////////////////// + // name from label inside toolbar button + testName("toolbarbuttonwithlabel", "I am the button"); + + + ////////////////////////////////////////////////////////////////////////// + // Name from children + + // ARIA role button is presented allowing the name calculation from + // children. + testName("box_children", "14"); + + // Button labelled by a text child. + testName("button_text", "Text"); + + // ARIA role option is presented allowing the name calculation from + // the visible children (bug 443081) + testName("lb_opt1_children_hidden", "i am visible"); + + + ////////////////////////////////////////////////////////////////////////// + // Name from aria-labelledby: menuitem label+ listitem label + testName("li_labelledby", "Show an Alert The moment the event starts"); + + ////////////////////////////////////////////////////////////////////////// + // groupbox labeling from first label + testName("groupbox", "Some caption"); + + SimpleTest.finish(); + } + + SimpleTest.waitForExplicitFinish(); + addA11yLoadEvent(doTest); + ]]> + </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=444279" + title="mochitest for accessible name calculating"> + Mozilla Bug 444279 + </a> + <a target="_blank" + href="https://bugzilla.mozilla.org/show_bug.cgi?id=441991" + title="nsXULListitemAccessible::GetName prefers label \ + attribute over aria-labelledby and doesn't allow recursion"> + Mozilla Bug 441991 + </a> + <p id="display"></p> + <div id="content" style="display: none"> + </div> + <pre id="test"> + </pre> + </body> + + <vbox flex="1"> + + <!-- aria-label, simple label --> + <button id="btn_simple_aria_label" aria-label="I am a button"/> + + <!-- aria-label plus aria-labelledby --> + <button id="btn_both_aria_labels" aria-label="I am a button, two" + aria-labelledby="labelledby_text btn_both_aria_labels"/> + + <!-- aria-labelledby, single relation --> + <description id="labelledby_text">text</description> + <button id="btn_labelledby_text" + aria-labelledby="labelledby_text"/> + + <!-- aria-labelledby, multiple relations --> + <description id="labelledby_text1">text1</description> + <description id="labelledby_text2">text2</description> + <button id="btn_labelledby_texts" + aria-labelledby="labelledby_text1 labelledby_text2"/> + + <!-- trick aria-labelledby --> + <checkbox id="rememberHistoryDays" + label="Remember " + aria-labelledby="rememberHistoryDays historyDays rememberAfter"/> + <html:input id="historyDays" value="3" + aria-labelledby="rememberHistoryDays historyDays rememberAfter"/> + <label id="rememberAfter">days</label> + + <!-- the name from subtree, mixed content --> + <description id="labelledby_mixed"> + no<description>more text</description> + </description> + <button id="btn_labelledby_mixed" + aria-labelledby="labelledby_mixed"/> + + <!-- the name from subtree, mixed/hidden content --> + <description id="labelledby_mixed_hidden_child">no<description>more <description hidden="true">hidden</description>text2</description></description> + <button id="btn_labelledby_mixed_hidden_child" + aria-labelledby="labelledby_mixed_hidden_child"/> + + <!-- the name from subtree, mixed/completely hidden content --> + <description id="labelledby_mixed_hidden" + hidden="true">lala <description>more hidden </description>text</description> + <button id="btn_labelledby_mixed_hidden" + aria-labelledby="labelledby_mixed_hidden"/> + <br/> + + <!-- the name from subtree, mixed content, ignore items of menulist --> + <description id="labelledby_mixed_menulist"> + no<description>more text</description> + <menulist> + <menupopup> + <menuitem label="selected item"/> + <menuitem label="item"/> + </menupopup> + </menulist> + more text + </description> + <button id="btn_labelledby_mixed_menulist" + aria-labelledby="labelledby_mixed_menulist"/> + + <!-- @label --> + <button id="btn_labelattr" + label="labeled element"/> + + <!-- nsIDOMXULSelectControlItemElement --> + <richlistbox> + <richlistitem id="li_nsIDOMXULSelectControlItemElement"> + <label value="select control item"/> + </richlistitem> + </richlistbox> + + <!-- not nsIDOMXULSelectControlElement --> + <box id="box_not_nsIDOMXULSelectControlElement" role="group" label="box"/> + + <!-- label element --> + <hbox> + <box> + <label control="btn_label_1">label1</label> + </box> + <label control="btn_label_2">label2</label> + <box> + <button id="btn_label_1"/> + <box> + <box> + <box> + <button id="btn_label_2"/> + </box> + </box> + </box> + </box> + <label control="btn_label_3">label3</label> + <button id="btn_label_3"/> + + <label control="btn_label_4">label4</label> + <label control="btn_label_4">label5</label> + <button id="btn_label_4"/> + + <label control="input_label">input label</label> + <html:input id="input_label"/> + </hbox> + + <!-- tooltiptext --> + <box id="box_tooltiptext" + role="group" + tooltiptext="tooltiptext label"/> + + <!-- the name from @title of toolbaritem --> + <!-- and the name from label of a toolbarbutton --> + <toolbar> + <toolbaritem title="ooospspss"> + <box id="toolbaritem_child" + role="group" + flex="1"> + <hbox role="button" id="toolbaritem_hboxbutton"> + <description value="button"/> + </hbox> + </box> + </toolbaritem> + <toolbarbutton id="toolbarbuttonwithlabel"> + <label flex="1">I am the button</label> + </toolbarbutton> + </toolbar> + + <!-- name from children --> + <box id="box_children" role="button">14</box> + <button id="button_text">Text</button> + + <!-- name from children, hidden children --> + <vbox role="listbox" tabindex="0"> + <hbox id="lb_opt1_children_hidden" role="option" tabindex="0"> + <description>i am visible</description> + <description style="display:none">i am hidden</description> + </hbox> + + <!-- Name from caption sub tree --> + <groupbox id="groupbox"> + <label>Some caption</label> + <checkbox label="some checkbox label" /> + </groupbox> + </vbox> + + <!-- bug 441991; create name from other menuitem label listitem's own label --> + <hbox> + <richlistbox> + <richlistitem id="li_labelledby" + aria-labelledby="menuitem-DISPLAY li_labelledby"> + <label value="The moment the event starts"/> + </richlistitem> + </richlistbox> + <menulist> + <menupopup> + <menuitem id="menuitem-DISPLAY" + value="DISPLAY" + label="Show an Alert"/> + <menuitem id="menuitem-EMAIL" + value="EMAIL" + label="Send an E-mail"/> + </menupopup> + </menulist> + </hbox> + + </vbox> <!-- close tests area --> + </hbox> <!-- close main area --> +</window> diff --git a/accessible/tests/mochitest/name/test_link.html b/accessible/tests/mochitest/name/test_link.html new file mode 100644 index 0000000000..6a289dd44f --- /dev/null +++ b/accessible/tests/mochitest/name/test_link.html @@ -0,0 +1,87 @@ +<html> + +<head> + <title>nsIAccessible::name calculation for HTML links (html:a)</title> + + <link rel="stylesheet" + type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css" /> + + <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> + + <script type="application/javascript" + src="../common.js"></script> + <script type="application/javascript" + src="../name.js"></script> + + <script type="application/javascript"> + function doTest() { + // aria-label + testName("aria_label", "anchor label"); + + // aria-labelledby + testName("aria_labelledby", "text"); + + // name from content + testName("namefromcontent", "1"); + + // name from content + testName("namefromimg", "img title"); + + // no name from content + testName("nonamefromcontent", null); + + // title + testName("title", "title"); + + SimpleTest.finish(); + } + + SimpleTest.waitForExplicitFinish(); + addA11yLoadEvent(doTest); + </script> + +</head> + +<body> + + <a target="_blank" + href="https://bugzilla.mozilla.org/show_bug.cgi?id=459782" + title="nsIAccessible::name calculation for HTML links (html:a)"> + Mozilla Bug 459782 + </a> + <p id="display"></p> + <div id="content" style="display: none"></div> + <pre id="test"> + </pre> + + <!-- aria-label --> + <a id="aria_label" href="mozilla.org" + aria-label="anchor label">1</a> + <br/> + + <!-- aria-labelledby, preferred to html:label --> + <span id="text">text</span> + <label for="aria_labelledby">label</label> + <a id="aria_labelledby" href="mozilla.org" + aria-labelledby="text">1</a> + <br/> + + <!-- name from content, preferred to @title --> + <a id="namefromcontent" href="mozilla.org" + title="title">1</a> + <br/> + + <!-- name from content, preferred to @title --> + <a id="namefromimg" href="mozilla.org" + title="title"><img alt="img title" /></a> + + <!-- no name from content, ARIA role overrides this rule --> + <a id="nonamefromcontent" href="mozilla.org" role="img">1</a> + <br/> + + <!-- no content, name from @title --> + <a id="title" href="mozilla.org" + title="title"></a> + +</body> +</html> diff --git a/accessible/tests/mochitest/name/test_list.html b/accessible/tests/mochitest/name/test_list.html new file mode 100644 index 0000000000..95f0c06d2a --- /dev/null +++ b/accessible/tests/mochitest/name/test_list.html @@ -0,0 +1,103 @@ +<html> + +<head> + <title>nsIAccessible::name calculation for HTML li</title> + <link rel="stylesheet" type="text/css" + href="chrome://mochikit/content/tests/SimpleTest/test.css" /> + + <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> + + <script type="application/javascript" + src="../common.js"></script> + <script type="application/javascript" + src="../name.js"></script> + <script type="application/javascript" + src="../events.js"></script> + + <script type="application/javascript"> + /** + * Alter list item numbering and change list style type. + */ + function bulletUpdate() { + this.eventSeq = [ + new invokerChecker(EVENT_REORDER, getNode("list")), + ]; + + this.invoke = function bulletUpdate_invoke() { + testName("li_end", "1. list end"); + + var li = document.createElement("li"); + li.setAttribute("id", "li_start"); + li.textContent = "list start"; + getNode("list").insertBefore(li, getNode("li_end")); + }; + + this.finalCheck = function bulletUpdate_finalCheck() { + testName("li_start", "1. list start"); + testName("li_end", "2. list end"); + }; + + this.getID = function bulletUpdate_getID() { + return "insertBefore new list item"; + }; + } + function bulletUpdate2() { + this.eventSeq = [ + new invokerChecker(EVENT_REORDER, getNode("li_end")), + ]; + + this.invoke = function bulletUpdate2_invoke() { + // change list style type + var list = getNode("list"); + list.setAttribute("style", "list-style-type: disc;"); + + // Flush both the style change and the resulting layout change. + // Flushing style on its own is not sufficient, because that can + // leave frames marked with NS_FRAME_IS_DIRTY, which will cause + // nsTextFrame::GetRenderedText to report the text of a text + // frame is empty. + list.offsetWidth; // flush layout (which also flushes style) + }; + + this.finalCheck = function bulletUpdate2_finalCheck() { + testName("li_start", kDiscBulletText + "list start"); + testName("li_end", kDiscBulletText + "list end"); + }; + + this.getID = function bulletUpdate2_getID() { + return "Update list item style"; + }; + } + + var gQueue = null; + function doTest() { + gQueue = new eventQueue(); + gQueue.push(new bulletUpdate()); + gQueue.push(new bulletUpdate2()); + gQueue.invoke(); // SimpleTest.finish(); + } + + SimpleTest.waitForExplicitFinish(); + addA11yLoadEvent(doTest); + </script> + +</head> + +<body> + + <a target="_blank" + href="https://bugzilla.mozilla.org/show_bug.cgi?id=634200" + title="crash [@ nsIFrame::StyleVisibility() ]"> + Mozilla Bug 634200 + </a> + <p id="display"></p> + <div id="content" style="display: none"></div> + <pre id="test"> + </pre> + + <ol id="list"> + <li id="li_end">list end</li> + </ol> + +</body> +</html> diff --git a/accessible/tests/mochitest/name/test_markup.html b/accessible/tests/mochitest/name/test_markup.html new file mode 100644 index 0000000000..735027f44f --- /dev/null +++ b/accessible/tests/mochitest/name/test_markup.html @@ -0,0 +1,58 @@ +<html> + +<head> + <title>nsIAccessible::name calculation for elements</title> + <link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css" /> + + <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> + <script src="chrome://mochikit/content/tests/SimpleTest/EventUtils.js"></script> + + <script type="application/javascript" + src="../common.js"></script> + <script type="application/javascript" + src="../events.js"></script> + <script type="application/javascript" + src="../name.js"></script> + <script type="application/javascript" + src="../attributes.js"></script> + + <script type="application/javascript" + src="markup.js"></script> + + <script type="application/javascript"> + // gA11yEventDumpID = "eventdump"; + // gDumpToConsole = true; + // gA11yEventDumpToConsole = true; + + SimpleTest.waitForExplicitFinish(); + addA11yLoadEvent(testNames); + </script> + +</head> + +<body> + + <a target="_blank" + href="https://bugzilla.mozilla.org/show_bug.cgi?id=459635" + title="nsIAccessible::name calculation for elements"> + Bug 459635 + </a> + <a target="_blank" + href="https://bugzilla.mozilla.org/show_bug.cgi?id=666212" + title="summary attribute content mapped to accessible name in MSAA"> + Bug 666212 + </a> + <a target="_blank" + href="https://bugzilla.mozilla.org/show_bug.cgi?id=786163" + title=" Sort out name calculation for HTML input buttons"> + Bug 786163 + </a> + + <p id="display"></p> + <div id="content" style="display: none"></div> + <pre id="test"> + </pre> + + <div id="eventdump"></div> +</body> +</html> diff --git a/accessible/tests/mochitest/name/test_svg.html b/accessible/tests/mochitest/name/test_svg.html new file mode 100644 index 0000000000..535fcdbf20 --- /dev/null +++ b/accessible/tests/mochitest/name/test_svg.html @@ -0,0 +1,53 @@ +<html> + +<head> + <title>Accessible name and description for SVG elements</title> + <link rel="stylesheet" type="text/css" + href="chrome://mochikit/content/tests/SimpleTest/test.css" /> + + <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> + + <script type="application/javascript" + src="../common.js"></script> + <script type="application/javascript" + src="../name.js"></script> + + <script type="application/javascript"> + + function doTest() { + testName("svg1", "A name"); + testDescr("svg1", "A description"); + testName("svg2", "A tooltip"); + testDescr("svg2", ""); + + SimpleTest.finish(); + } + + SimpleTest.waitForExplicitFinish(); + addA11yLoadEvent(doTest); + </script> + +</head> + +<body> + + <a target="_blank" + href="https://bugzilla.mozilla.org/show_bug.cgi?id=459357" + title="Support accessible name computation for SVG"> + Mozilla Bug 459357 + </a> + <p id="display"></p> + <div id="content" style="display: none"></div> + <pre id="test"> + </pre> + + <svg xmlns="http://www.w3.org/2000/svg" version="1.1" id="svg1"> + <title>A name</title> + <desc>A description</title> + </svg> + + <svg xmlns="http://www.w3.org/2000/svg" version="1.1" id="svg2"> + <desc>A tooltip</desc> + </svg> +</body> +</html> diff --git a/accessible/tests/mochitest/name/test_tree.xhtml b/accessible/tests/mochitest/name/test_tree.xhtml new file mode 100644 index 0000000000..3564481d00 --- /dev/null +++ b/accessible/tests/mochitest/name/test_tree.xhtml @@ -0,0 +1,207 @@ +<?xml version="1.0"?> +<?xml-stylesheet href="chrome://global/skin" type="text/css"?> +<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css" + type="text/css"?> + +<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" + title="Accessibility Name Calculating Test."> + + <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js" /> + + <script type="application/javascript" + src="../treeview.js" /> + + <script type="application/javascript" + src="../common.js"></script> + <script type="application/javascript" + src="../role.js"></script> + <script type="application/javascript" + src="../name.js"></script> + <script type="application/javascript" + src="../events.js"></script> + + <script type="application/javascript"> + <![CDATA[ + function treeTester(aID) + { + this.DOMNode = getNode(aID); + + this.invoke = function treeTester_invoke() + { + this.DOMNode.view = new nsTreeTreeView(); + } + + this.check = function treeTester_check(aEvent) + { + var tree = { + role: ROLE_OUTLINE, + children: [ + { + role: ROLE_LIST + }, + { + role: ROLE_OUTLINEITEM, + children: [], + name: "row1col" + }, + { + role: ROLE_OUTLINEITEM, + children: [], + name: "row2_col" + }, + { + role: ROLE_OUTLINEITEM, + children: [], + name: "row2.1_col" + }, + { + role: ROLE_OUTLINEITEM, + children: [], + name: "row2.2_col" + }, + { + role: ROLE_OUTLINEITEM, + children: [], + name: "row3_col" + }, + { + role: ROLE_OUTLINEITEM, + children: [], + name: "row4col" + } + ] + }; + testAccessibleTree(this.DOMNode, tree); + } + + this.getID = function treeTester_getID() + { + return "Tree name testing for " + aID; + } + } + + function tableTester(aID, aIsTable, aCol1ID, aCol2ID) + { + this.DOMNode = getNode(aID); + + this.invoke = function tableTester_invoke() + { + this.DOMNode.view = new nsTableTreeView(2); + } + + this.check = function tableTester_check(aEvent) + { + var tree = { + role: aIsTable ? ROLE_TABLE : ROLE_TREE_TABLE, + children: [ + { + role: ROLE_LIST + }, + { + role: ROLE_ROW, + children: [ + { + role: ROLE_GRID_CELL, + children: [], + name: "row0_" + aCol1ID + }, + { + role: ROLE_GRID_CELL, + children: [], + name: "row0_" + aCol2ID + } + ], + name: "row0_" + aCol1ID + " row0_" + aCol2ID + }, + { + role: ROLE_ROW, + children: [ + { + role: ROLE_GRID_CELL, + children: [], + name: "row1_" + aCol1ID + }, + { + role: ROLE_GRID_CELL, + children: [], + name: "row1_" + aCol2ID + } + ], + name: "row1_" + aCol1ID + " row1_" + aCol2ID + } + ] + }; + testAccessibleTree(this.DOMNode, tree); + } + + this.getID = function tableTester_getID() + { + return "Tree name testing for " + aID; + } + } + + var gQueue = null; + function doTest() + { + gQueue = new eventQueue(EVENT_REORDER); + + gQueue.push(new treeTester("tree")); + gQueue.push(new tableTester("table", true, "t_col1", "t_col2")); + gQueue.push(new tableTester("treetable", false, "tt_col1", "tt_col2")); + + gQueue.invoke(); // Will call SimpleTest.finish() + } + + SimpleTest.waitForExplicitFinish(); + addA11yLoadEvent(doTest); + ]]> + </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=546812" + title="Treegrid row accessible shouldn't inherit name from tree accessible"> + Mozilla Bug 546812 + </a> + <a target="_blank" + href="https://bugzilla.mozilla.org/show_bug.cgi?id=664376" + title="Table rows of XUL trees no longer containing cell content as accessible name"> + Mozilla Bug 664376 + </a> + <p id="display"></p> + <div id="content" style="display: none"> + </div> + <pre id="test"> + </pre> + </body> + + <vbox flex="1"> + + <tree id="tree" flex="1"> + <treecols> + <treecol id="col" flex="1" primary="true" label="column"/> + </treecols> + <treechildren/> + </tree> + + <tree id="table" flex="1"> + <treecols> + <treecol id="t_col1" flex="1" label="column"/> + <treecol id="t_col2" flex="1" label="column 2"/> + </treecols> + <treechildren/> + </tree> + + <tree id="treetable" flex="1"> + <treecols> + <treecol id="tt_col1" flex="1" label="column" primary="true"/> + <treecol id="tt_col2" flex="1" label="column 2"/> + </treecols> + <treechildren/> + </tree> + + </vbox> <!-- close tests area --> + </hbox> <!-- close main area --> +</window> |