COMMIT_MESSAGE

 1AX: Improve accessibility for tables and table components with display flex, grid, block, inline-block, and contents
 2https://bugs.webkit.org/show_bug.cgi?id=258439
 3rdar://problem/111202843
 4
 5Reviewed by NOBODY (OOPS!).
 6
 7https://bugs.webkit.org/show_bug.cgi?id=258223 did the hard work of computing table structure based on the DOM rather
 8than the render tree. But even after that patch, tables and table components with assorted display values were often
 9inaccessible to VoiceOver. This is due to parent-child mismatches caused by anonymous RenderTables, RenderTableRows,
 10and RenderTableCells generated when these display values are used on table components.
 11
 12With this patch, we properly ignore all of these anonymous table renderers, completing the transition of table
 13accessibility to be DOM-based. This matches author expectations and is much more simple to reason about, and fixes
 14the parent-child mismatches that were breaking the accessibility hierarchy.
 15
 16* LayoutTests/accessibility/display-contents/table-expected.txt:
 17* LayoutTests/accessibility/list-detection-expected.txt:
 18* LayoutTests/accessibility/list-detection.html:
 19* LayoutTests/accessibility/table-display-block-expected.txt:
 20* LayoutTests/accessibility/table-display-block.html: Added.
 21* LayoutTests/accessibility/table-display-flex-expected.txt:
 22* LayoutTests/accessibility/table-display-flex.html: Added.
 23* LayoutTests/accessibility/table-display-grid-expected.txt:
 24* LayoutTests/accessibility/table-display-grid.html: Added.
 25* LayoutTests/accessibility/table-display-inline-block-expected.txt:
 26* LayoutTests/accessibility/table-display-inline-block.html: Added.
 27* LayoutTests/platform/glib/accessibility/list-detection-expected.txt:
 28* LayoutTests/platform/ios/TestExpectations:
 29Enable all new tests.
 30* LayoutTests/platform/ios/accessibility/display-contents/table-expected.txt:
 31* LayoutTests/platform/ios/accessibility/table-display-block-expected.txt:
 32* LayoutTests/platform/ios/accessibility/table-display-flex-expected.txt:
 33* LayoutTests/platform/ios/accessibility/table-display-grid-expected.txt:
 34* LayoutTests/platform/ios/accessibility/table-display-inline-block-expected.txt:
 35* LayoutTests/platform/mac/accessibility/generated-content-with-display-table-crash-expected.txt:
 36* Source/WebCore/accessibility/AXObjectCache.cpp:
 37(WebCore::AXObjectCache::createObjectFromRenderer):
 38* Source/WebCore/accessibility/AccessibilityRenderObject.cpp:
 39(WebCore::AccessibilityRenderObject::determineAccessibilityRole):

Source/WebCore/accessibility/AXObjectCache.cpp

@@Ref<AccessibilityObject> AXObjectCache::createObjectFromRenderer(RenderObject* r
698698 return AccessibilityMenuList::create(downcast<RenderMenuList>(renderer));
699699
700700 // standard tables
701  if (is<RenderTable>(renderer) || isAccessibilityTable(node))
 701 if ((is<RenderTable>(renderer) && !renderer->isAnonymous()) || isAccessibilityTable(node))
702702 return AccessibilityTable::create(renderer);
703  if (is<RenderTableRow>(renderer) || isAccessibilityTableRow(node))
 703 if ((is<RenderTableRow>(renderer) && !renderer->isAnonymous()) || isAccessibilityTableRow(node))
704704 return AccessibilityTableRow::create(renderer);
705705 if ((is<RenderTableCell>(renderer) && !renderer->isAnonymous()) || isAccessibilityTableCell(node))
706706 return AccessibilityTableCell::create(renderer);

Source/WebCore/accessibility/AccessibilityRenderObject.cpp

@@AccessibilityRole AccessibilityRenderObject::determineAccessibilityRole()
22432243
22442244 // This return value is what will be used if AccessibilityTableCell determines
22452245 // the cell should not be treated as a cell (e.g. because it is a layout table.
2246  if (is<RenderTableCell>(renderer()))
 2246 if (is<RenderTableCell>(renderer())) {
 2247 if (renderer()->isAnonymous())
 2248 return AccessibilityRole::Ignored;
22472249 return AccessibilityRole::TextGroup;
 2250 }
22482251 // Table sections should be ignored.
22492252 if (m_renderer->isTableSection())
22502253 return AccessibilityRole::Ignored;
22512254
 2255 if (m_renderer->isAnonymous() && (is<RenderTableRow>(m_renderer) || is<RenderTable>(m_renderer)))
 2256 return AccessibilityRole::Ignored;
 2257
22522258 auto treatStyleFormatGroupAsInline = is<RenderInline>(*m_renderer) ? TreatStyleFormatGroupAsInline::Yes : TreatStyleFormatGroupAsInline::No;
22532259 auto roleFromNode = determineAccessibilityRoleFromNode(treatStyleFormatGroupAsInline);
22542260 if (roleFromNode != AccessibilityRole::Unknown)

LayoutTests/accessibility/display-contents/table-expected.txt

@@Performing search traversal of body.
7575
7676{AXRole: AXStaticText AXValue: 2020} (parent: {#r3c2 AXRole: AXCell})
7777
78 {AXRole: AXTable} (parent: {#body AXRole: AXGroup})
79 
8078PASS successfullyParsed is true
8179
8280TEST COMPLETE

LayoutTests/accessibility/list-detection-expected.txt

@@PASS axElement.role == 'AXRole: AXList' is true
5656
5757
5858Inline list elements with an aria role should be a list
59 PASS axElement.role == 'AXRole: AXList' is false
 59PASS axElement.role == 'AXRole: AXList' is true
6060
6161
6262PASS successfullyParsed is true

LayoutTests/accessibility/list-detection.html

6363<div>item</div>
6464</ul>
6565
66 <ul id="list14" role="list" test-description="Inline list elements with an aria role should be a list" is-list="false" style="display: table;">
 66<ul id="list14" role="list" test-description="Inline list elements with an aria role should be a list" is-list="true" style="display: table;">
6767 <li role="listitem" style="display: inline-block;">Item 1</li>
6868 <li role="listitem" style="display: inline-block;">Item 2</li>
6969 <li role="listitem" style="display: inline-block;">Item 3</li>

LayoutTests/accessibility/table-display-block-expected.txt

 1This test ensures that a table with display:block components is accessible.
 2
 3PASS: table.rowCount === 4
 4PASS: table.columnCount === 3
 5PASS: table.cellForColumnAndRow(0, 0).domIdentifier === "r0c0"
 6PASS: table.cellForColumnAndRow(1, 0).domIdentifier === "r0c1"
 7PASS: table.cellForColumnAndRow(2, 0).domIdentifier === "r0c2"
 8PASS: table.cellForColumnAndRow(0, 1).domIdentifier === "r1c0"
 9PASS: table.cellForColumnAndRow(1, 1).domIdentifier === "r1c1"
 10PASS: table.cellForColumnAndRow(2, 1).domIdentifier === "r1c2"
 11PASS: table.cellForColumnAndRow(0, 2).domIdentifier === "r2c0"
 12PASS: table.cellForColumnAndRow(1, 2).domIdentifier === "r2c1"
 13PASS: table.cellForColumnAndRow(2, 2).domIdentifier === "r2c2"
 14PASS: table.cellForColumnAndRow(0, 3).domIdentifier === "r3c0"
 15PASS: table.cellForColumnAndRow(1, 3).domIdentifier === "r3c1"
 16PASS: table.cellForColumnAndRow(2, 3).domIdentifier === "r3c2"
 17
 18Performing search traversal of body.
 19
 20{#table AXRole: AXTable} (parent: {#body AXRole: AXGroup})
 21
 22{#r0 AXRole: AXRow} (parent: {#table AXRole: AXTable})
 23
 24{#r0c0 AXRole: AXCell} (parent: {#r0 AXRole: AXRow})
 25
 26{AXRole: AXStaticText AXValue: Author} (parent: {#r0c0 AXRole: AXCell})
 27
 28{#r0c1 AXRole: AXCell} (parent: {#r0 AXRole: AXRow})
 29
 30{AXRole: AXStaticText AXValue: Title} (parent: {#r0c1 AXRole: AXCell})
 31
 32{#r0c2 AXRole: AXCell} (parent: {#r0 AXRole: AXRow})
 33
 34{AXRole: AXStaticText AXValue: Year} (parent: {#r0c2 AXRole: AXCell})
 35
 36{#r1 AXRole: AXRow} (parent: {#table AXRole: AXTable})
 37
 38{#r1c0 AXRole: AXCell} (parent: {#r1 AXRole: AXRow})
 39
 40{AXRole: AXStaticText AXValue: Stephen Hawking} (parent: {#r1c0 AXRole: AXCell})
 41
 42{#r1c1 AXRole: AXCell} (parent: {#r1 AXRole: AXRow})
 43
 44{AXRole: AXStaticText AXValue: A Brief History of Time} (parent: {#r1c1 AXRole: AXCell})
 45
 46{#r1c2 AXRole: AXCell} (parent: {#r1 AXRole: AXRow})
 47
 48{AXRole: AXStaticText AXValue: 1988} (parent: {#r1c2 AXRole: AXCell})
 49
 50{#r2 AXRole: AXRow} (parent: {#table AXRole: AXTable})
 51
 52{#r2c0 AXRole: AXCell} (parent: {#r2 AXRole: AXRow})
 53
 54{AXRole: AXStaticText AXValue: Carl Sagan} (parent: {#r2c0 AXRole: AXCell})
 55
 56{#r2c1 AXRole: AXCell} (parent: {#r2 AXRole: AXRow})
 57
 58{AXRole: AXStaticText AXValue: Cosmos} (parent: {#r2c1 AXRole: AXCell})
 59
 60{#r2c2 AXRole: AXCell} (parent: {#r2 AXRole: AXRow})
 61
 62{AXRole: AXStaticText AXValue: 1980} (parent: {#r2c2 AXRole: AXCell})
 63
 64{#r3 AXRole: AXRow} (parent: {#table AXRole: AXTable})
 65
 66{#r3c0 AXRole: AXCell} (parent: {#r3 AXRole: AXRow})
 67
 68{AXRole: AXStaticText AXValue: Will Gater} (parent: {#r3c0 AXRole: AXCell})
 69
 70{#r3c1 AXRole: AXCell} (parent: {#r3 AXRole: AXRow})
 71
 72{AXRole: AXStaticText AXValue: The Mysteries of the Universe} (parent: {#r3c1 AXRole: AXCell})
 73
 74{#r3c2 AXRole: AXCell} (parent: {#r3 AXRole: AXRow})
 75
 76{AXRole: AXStaticText AXValue: 2020} (parent: {#r3c2 AXRole: AXCell})
 77
 78PASS successfullyParsed is true
 79
 80TEST COMPLETE
 81This is a table caption
 82Author
 83Title
 84Year
 85Stephen Hawking
 86A Brief History of Time
 871988
 88Carl Sagan
 89Cosmos
 901980
 91Will Gater
 92The Mysteries of the Universe
 932020

LayoutTests/accessibility/table-display-block.html

 1<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
 2<html>
 3<head>
 4<script src="../resources/accessibility-helper.js"></script>
 5<script src="../resources/js-test.js"></script>
 6<style>
 7table, tr, td, th {
 8 display: block;
 9}
 10</style>
 11</head>
 12<body role="group" id="body">
 13
 14<table id="table">
 15<caption>This is a table caption</caption>
 16<thead>
 17 <tr id="r0">
 18 <th id="r0c0">Author</th>
 19 <th id="r0c1">Title</th>
 20 <th id="r0c2">Year</th>
 21 </tr>
 22</thead>
 23<tbody>
 24 <tr id="r1">
 25 <td id="r1c0">Stephen Hawking</td>
 26 <td id="r1c1">A Brief History of Time</td>
 27 <td id="r1c2">1988</td>
 28 </tr>
 29 <tr id="r2">
 30 <td id="r2c0">Carl Sagan</td>
 31 <td id="r2c1">Cosmos</td>
 32 <td id="r2c2">1980</td>
 33 </tr>
 34 <tr id="r3">
 35 <td id="r3c0">Will Gater</td>
 36 <td id="r3c1">The Mysteries of the Universe</td>
 37 <td id="r3c2">2020</td>
 38 </tr>
 39</tbody>
 40</table>
 41
 42<script>
 43var output = "This test ensures that a table with display:block components is accessible.\n\n";
 44
 45if (window.accessibilityController) {
 46 var table = accessibilityController.accessibleElementById("table");
 47 output += expect("table.rowCount", "4");
 48 output += expect("table.columnCount", "3");
 49
 50 for (let row = 0; row < 4; row++) {
 51 for (let column = 0; column < 3; column++)
 52 output += expect(`table.cellForColumnAndRow(${column}, ${row}).domIdentifier`, `"r${row}c${column}"`);
 53 }
 54
 55 output += `\nPerforming search traversal of body.\n`;
 56 function elementDescription(axElement) {
 57 if (!axElement)
 58 return "null";
 59
 60 const role = axElement.role;
 61 const id = axElement.domIdentifier;
 62 let result = `${id ? `#${id} ` : ""}${role}`;
 63 if (role.includes("StaticText"))
 64 result += ` ${accessibilityController.platformName === "ios" ? axElement.description : axElement.stringValue}`;
 65 return result;
 66 }
 67
 68 const container = accessibilityController.accessibleElementById("body");
 69 let searchResult = null;
 70 while (true) {
 71 searchResult = container.uiElementForSearchPredicate(searchResult, true, "AXAnyTypeSearchKey", "", false);
 72 if (!searchResult)
 73 break;
 74 const parentOutput = accessibilityController.platformName === "ios" ? "" : ` (parent: {${elementDescription(searchResult.parentElement())}})`;
 75 output += `\n{${elementDescription(searchResult)}}${parentOutput}\n`;
 76 }
 77 debug(output);
 78}
 79</script>
 80</body>
 81</html>
 82

LayoutTests/accessibility/table-display-flex-expected.txt

 1This test ensures that a table with display:flex components is accessible.
 2
 3PASS: table.rowCount === 4
 4PASS: table.columnCount === 3
 5PASS: table.cellForColumnAndRow(0, 0).domIdentifier === "r0c0"
 6PASS: table.cellForColumnAndRow(1, 0).domIdentifier === "r0c1"
 7PASS: table.cellForColumnAndRow(2, 0).domIdentifier === "r0c2"
 8PASS: table.cellForColumnAndRow(0, 1).domIdentifier === "r1c0"
 9PASS: table.cellForColumnAndRow(1, 1).domIdentifier === "r1c1"
 10PASS: table.cellForColumnAndRow(2, 1).domIdentifier === "r1c2"
 11PASS: table.cellForColumnAndRow(0, 2).domIdentifier === "r2c0"
 12PASS: table.cellForColumnAndRow(1, 2).domIdentifier === "r2c1"
 13PASS: table.cellForColumnAndRow(2, 2).domIdentifier === "r2c2"
 14PASS: table.cellForColumnAndRow(0, 3).domIdentifier === "r3c0"
 15PASS: table.cellForColumnAndRow(1, 3).domIdentifier === "r3c1"
 16PASS: table.cellForColumnAndRow(2, 3).domIdentifier === "r3c2"
 17
 18Performing search traversal of body.
 19
 20{#table AXRole: AXTable} (parent: {#body AXRole: AXGroup})
 21
 22{#r0 AXRole: AXRow} (parent: {#table AXRole: AXTable})
 23
 24{#r0c0 AXRole: AXCell} (parent: {#r0 AXRole: AXRow})
 25
 26{AXRole: AXStaticText AXValue: Author} (parent: {#r0c0 AXRole: AXCell})
 27
 28{#r0c1 AXRole: AXCell} (parent: {#r0 AXRole: AXRow})
 29
 30{AXRole: AXStaticText AXValue: Title} (parent: {#r0c1 AXRole: AXCell})
 31
 32{#r0c2 AXRole: AXCell} (parent: {#r0 AXRole: AXRow})
 33
 34{AXRole: AXStaticText AXValue: Year} (parent: {#r0c2 AXRole: AXCell})
 35
 36{#r1 AXRole: AXRow} (parent: {#table AXRole: AXTable})
 37
 38{#r1c0 AXRole: AXCell} (parent: {#r1 AXRole: AXRow})
 39
 40{AXRole: AXStaticText AXValue: Stephen Hawking} (parent: {#r1c0 AXRole: AXCell})
 41
 42{#r1c1 AXRole: AXCell} (parent: {#r1 AXRole: AXRow})
 43
 44{AXRole: AXStaticText AXValue: A Brief History of Time} (parent: {#r1c1 AXRole: AXCell})
 45
 46{#r1c2 AXRole: AXCell} (parent: {#r1 AXRole: AXRow})
 47
 48{AXRole: AXStaticText AXValue: 1988} (parent: {#r1c2 AXRole: AXCell})
 49
 50{#r2 AXRole: AXRow} (parent: {#table AXRole: AXTable})
 51
 52{#r2c0 AXRole: AXCell} (parent: {#r2 AXRole: AXRow})
 53
 54{AXRole: AXStaticText AXValue: Carl Sagan} (parent: {#r2c0 AXRole: AXCell})
 55
 56{#r2c1 AXRole: AXCell} (parent: {#r2 AXRole: AXRow})
 57
 58{AXRole: AXStaticText AXValue: Cosmos} (parent: {#r2c1 AXRole: AXCell})
 59
 60{#r2c2 AXRole: AXCell} (parent: {#r2 AXRole: AXRow})
 61
 62{AXRole: AXStaticText AXValue: 1980} (parent: {#r2c2 AXRole: AXCell})
 63
 64{#r3 AXRole: AXRow} (parent: {#table AXRole: AXTable})
 65
 66{#r3c0 AXRole: AXCell} (parent: {#r3 AXRole: AXRow})
 67
 68{AXRole: AXStaticText AXValue: Will Gater} (parent: {#r3c0 AXRole: AXCell})
 69
 70{#r3c1 AXRole: AXCell} (parent: {#r3 AXRole: AXRow})
 71
 72{AXRole: AXStaticText AXValue: The Mysteries of the Universe} (parent: {#r3c1 AXRole: AXCell})
 73
 74{#r3c2 AXRole: AXCell} (parent: {#r3 AXRole: AXRow})
 75
 76{AXRole: AXStaticText AXValue: 2020} (parent: {#r3c2 AXRole: AXCell})
 77
 78PASS successfullyParsed is true
 79
 80TEST COMPLETE
 81This is a table caption
 82Author
 83Title
 84Year
 85Stephen Hawking
 86A Brief History of Time
 871988
 88Carl Sagan
 89Cosmos
 901980
 91Will Gater
 92The Mysteries of the Universe
 932020

LayoutTests/accessibility/table-display-flex.html

 1<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
 2<html>
 3<head>
 4<script src="../resources/accessibility-helper.js"></script>
 5<script src="../resources/js-test.js"></script>
 6<style>
 7table, tr, td, th {
 8 display: flex;
 9}
 10</style>
 11</head>
 12<body role="group" id="body">
 13
 14<table id="table">
 15<caption>This is a table caption</caption>
 16<thead>
 17 <tr id="r0">
 18 <th id="r0c0">Author</th>
 19 <th id="r0c1">Title</th>
 20 <th id="r0c2">Year</th>
 21 </tr>
 22</thead>
 23<tbody>
 24 <tr id="r1">
 25 <td id="r1c0">Stephen Hawking</td>
 26 <td id="r1c1">A Brief History of Time</td>
 27 <td id="r1c2">1988</td>
 28 </tr>
 29 <tr id="r2">
 30 <td id="r2c0">Carl Sagan</td>
 31 <td id="r2c1">Cosmos</td>
 32 <td id="r2c2">1980</td>
 33 </tr>
 34 <tr id="r3">
 35 <td id="r3c0">Will Gater</td>
 36 <td id="r3c1">The Mysteries of the Universe</td>
 37 <td id="r3c2">2020</td>
 38 </tr>
 39</tbody>
 40</table>
 41
 42<script>
 43var output = "This test ensures that a table with display:flex components is accessible.\n\n";
 44
 45if (window.accessibilityController) {
 46 var table = accessibilityController.accessibleElementById("table");
 47 output += expect("table.rowCount", "4");
 48 output += expect("table.columnCount", "3");
 49
 50 for (let row = 0; row < 4; row++) {
 51 for (let column = 0; column < 3; column++)
 52 output += expect(`table.cellForColumnAndRow(${column}, ${row}).domIdentifier`, `"r${row}c${column}"`);
 53 }
 54
 55 output += `\nPerforming search traversal of body.\n`;
 56 function elementDescription(axElement) {
 57 if (!axElement)
 58 return "null";
 59
 60 const role = axElement.role;
 61 const id = axElement.domIdentifier;
 62 let result = `${id ? `#${id} ` : ""}${role}`;
 63 if (role.includes("StaticText"))
 64 result += ` ${accessibilityController.platformName === "ios" ? axElement.description : axElement.stringValue}`;
 65 return result;
 66 }
 67
 68 const container = accessibilityController.accessibleElementById("body");
 69 let searchResult = null;
 70 while (true) {
 71 searchResult = container.uiElementForSearchPredicate(searchResult, true, "AXAnyTypeSearchKey", "", false);
 72 if (!searchResult)
 73 break;
 74 const parentOutput = accessibilityController.platformName === "ios" ? "" : ` (parent: {${elementDescription(searchResult.parentElement())}})`;
 75 output += `\n{${elementDescription(searchResult)}}${parentOutput}\n`;
 76 }
 77 debug(output);
 78}
 79</script>
 80</body>
 81</html>
 82

LayoutTests/accessibility/table-display-grid-expected.txt

 1This test ensures that a table with display:grid components is accessible.
 2
 3PASS: table.rowCount === 4
 4PASS: table.columnCount === 3
 5PASS: table.cellForColumnAndRow(0, 0).domIdentifier === "r0c0"
 6PASS: table.cellForColumnAndRow(1, 0).domIdentifier === "r0c1"
 7PASS: table.cellForColumnAndRow(2, 0).domIdentifier === "r0c2"
 8PASS: table.cellForColumnAndRow(0, 1).domIdentifier === "r1c0"
 9PASS: table.cellForColumnAndRow(1, 1).domIdentifier === "r1c1"
 10PASS: table.cellForColumnAndRow(2, 1).domIdentifier === "r1c2"
 11PASS: table.cellForColumnAndRow(0, 2).domIdentifier === "r2c0"
 12PASS: table.cellForColumnAndRow(1, 2).domIdentifier === "r2c1"
 13PASS: table.cellForColumnAndRow(2, 2).domIdentifier === "r2c2"
 14PASS: table.cellForColumnAndRow(0, 3).domIdentifier === "r3c0"
 15PASS: table.cellForColumnAndRow(1, 3).domIdentifier === "r3c1"
 16PASS: table.cellForColumnAndRow(2, 3).domIdentifier === "r3c2"
 17
 18Performing search traversal of body.
 19
 20{#table AXRole: AXTable} (parent: {#body AXRole: AXGroup})
 21
 22{#r0 AXRole: AXRow} (parent: {#table AXRole: AXTable})
 23
 24{#r0c0 AXRole: AXCell} (parent: {#r0 AXRole: AXRow})
 25
 26{AXRole: AXStaticText AXValue: Author} (parent: {#r0c0 AXRole: AXCell})
 27
 28{#r0c1 AXRole: AXCell} (parent: {#r0 AXRole: AXRow})
 29
 30{AXRole: AXStaticText AXValue: Title} (parent: {#r0c1 AXRole: AXCell})
 31
 32{#r0c2 AXRole: AXCell} (parent: {#r0 AXRole: AXRow})
 33
 34{AXRole: AXStaticText AXValue: Year} (parent: {#r0c2 AXRole: AXCell})
 35
 36{#r1 AXRole: AXRow} (parent: {#table AXRole: AXTable})
 37
 38{#r1c0 AXRole: AXCell} (parent: {#r1 AXRole: AXRow})
 39
 40{AXRole: AXStaticText AXValue: Stephen Hawking} (parent: {#r1c0 AXRole: AXCell})
 41
 42{#r1c1 AXRole: AXCell} (parent: {#r1 AXRole: AXRow})
 43
 44{AXRole: AXStaticText AXValue: A Brief History of Time} (parent: {#r1c1 AXRole: AXCell})
 45
 46{#r1c2 AXRole: AXCell} (parent: {#r1 AXRole: AXRow})
 47
 48{AXRole: AXStaticText AXValue: 1988} (parent: {#r1c2 AXRole: AXCell})
 49
 50{#r2 AXRole: AXRow} (parent: {#table AXRole: AXTable})
 51
 52{#r2c0 AXRole: AXCell} (parent: {#r2 AXRole: AXRow})
 53
 54{AXRole: AXStaticText AXValue: Carl Sagan} (parent: {#r2c0 AXRole: AXCell})
 55
 56{#r2c1 AXRole: AXCell} (parent: {#r2 AXRole: AXRow})
 57
 58{AXRole: AXStaticText AXValue: Cosmos} (parent: {#r2c1 AXRole: AXCell})
 59
 60{#r2c2 AXRole: AXCell} (parent: {#r2 AXRole: AXRow})
 61
 62{AXRole: AXStaticText AXValue: 1980} (parent: {#r2c2 AXRole: AXCell})
 63
 64{#r3 AXRole: AXRow} (parent: {#table AXRole: AXTable})
 65
 66{#r3c0 AXRole: AXCell} (parent: {#r3 AXRole: AXRow})
 67
 68{AXRole: AXStaticText AXValue: Will Gater} (parent: {#r3c0 AXRole: AXCell})
 69
 70{#r3c1 AXRole: AXCell} (parent: {#r3 AXRole: AXRow})
 71
 72{AXRole: AXStaticText AXValue: The Mysteries of the Universe} (parent: {#r3c1 AXRole: AXCell})
 73
 74{#r3c2 AXRole: AXCell} (parent: {#r3 AXRole: AXRow})
 75
 76{AXRole: AXStaticText AXValue: 2020} (parent: {#r3c2 AXRole: AXCell})
 77
 78PASS successfullyParsed is true
 79
 80TEST COMPLETE
 81This is a table caption
 82Author
 83Title
 84Year
 85Stephen Hawking
 86A Brief History of Time
 871988
 88Carl Sagan
 89Cosmos
 901980
 91Will Gater
 92The Mysteries of the Universe
 932020

LayoutTests/accessibility/table-display-grid.html

 1<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
 2<html>
 3<head>
 4<script src="../resources/accessibility-helper.js"></script>
 5<script src="../resources/js-test.js"></script>
 6<style>
 7table, tr, td, th {
 8 display: grid;
 9}
 10</style>
 11</head>
 12<body role="group" id="body">
 13
 14<table id="table">
 15<caption>This is a table caption</caption>
 16<thead>
 17 <tr id="r0">
 18 <th id="r0c0">Author</th>
 19 <th id="r0c1">Title</th>
 20 <th id="r0c2">Year</th>
 21 </tr>
 22</thead>
 23<tbody>
 24 <tr id="r1">
 25 <td id="r1c0">Stephen Hawking</td>
 26 <td id="r1c1">A Brief History of Time</td>
 27 <td id="r1c2">1988</td>
 28 </tr>
 29 <tr id="r2">
 30 <td id="r2c0">Carl Sagan</td>
 31 <td id="r2c1">Cosmos</td>
 32 <td id="r2c2">1980</td>
 33 </tr>
 34 <tr id="r3">
 35 <td id="r3c0">Will Gater</td>
 36 <td id="r3c1">The Mysteries of the Universe</td>
 37 <td id="r3c2">2020</td>
 38 </tr>
 39</tbody>
 40</table>
 41
 42<script>
 43var output = "This test ensures that a table with display:grid components is accessible.\n\n";
 44
 45if (window.accessibilityController) {
 46 var table = accessibilityController.accessibleElementById("table");
 47 output += expect("table.rowCount", "4");
 48 output += expect("table.columnCount", "3");
 49
 50 for (let row = 0; row < 4; row++) {
 51 for (let column = 0; column < 3; column++)
 52 output += expect(`table.cellForColumnAndRow(${column}, ${row}).domIdentifier`, `"r${row}c${column}"`);
 53 }
 54
 55 output += `\nPerforming search traversal of body.\n`;
 56 function elementDescription(axElement) {
 57 if (!axElement)
 58 return "null";
 59
 60 const role = axElement.role;
 61 const id = axElement.domIdentifier;
 62 let result = `${id ? `#${id} ` : ""}${role}`;
 63 if (role.includes("StaticText"))
 64 result += ` ${accessibilityController.platformName === "ios" ? axElement.description : axElement.stringValue}`;
 65 return result;
 66 }
 67
 68 const container = accessibilityController.accessibleElementById("body");
 69 let searchResult = null;
 70 while (true) {
 71 searchResult = container.uiElementForSearchPredicate(searchResult, true, "AXAnyTypeSearchKey", "", false);
 72 if (!searchResult)
 73 break;
 74 const parentOutput = accessibilityController.platformName === "ios" ? "" : ` (parent: {${elementDescription(searchResult.parentElement())}})`;
 75 output += `\n{${elementDescription(searchResult)}}${parentOutput}\n`;
 76 }
 77 debug(output);
 78}
 79</script>
 80</body>
 81</html>
 82

LayoutTests/accessibility/table-display-inline-block-expected.txt

 1This test ensures that a table with display:inline-block components is accessible.
 2
 3PASS: table.rowCount === 4
 4PASS: table.columnCount === 3
 5PASS: table.cellForColumnAndRow(0, 0).domIdentifier === "r0c0"
 6PASS: table.cellForColumnAndRow(1, 0).domIdentifier === "r0c1"
 7PASS: table.cellForColumnAndRow(2, 0).domIdentifier === "r0c2"
 8PASS: table.cellForColumnAndRow(0, 1).domIdentifier === "r1c0"
 9PASS: table.cellForColumnAndRow(1, 1).domIdentifier === "r1c1"
 10PASS: table.cellForColumnAndRow(2, 1).domIdentifier === "r1c2"
 11PASS: table.cellForColumnAndRow(0, 2).domIdentifier === "r2c0"
 12PASS: table.cellForColumnAndRow(1, 2).domIdentifier === "r2c1"
 13PASS: table.cellForColumnAndRow(2, 2).domIdentifier === "r2c2"
 14PASS: table.cellForColumnAndRow(0, 3).domIdentifier === "r3c0"
 15PASS: table.cellForColumnAndRow(1, 3).domIdentifier === "r3c1"
 16PASS: table.cellForColumnAndRow(2, 3).domIdentifier === "r3c2"
 17
 18Performing search traversal of body.
 19
 20{#table AXRole: AXTable} (parent: {#body AXRole: AXGroup})
 21
 22{#r0 AXRole: AXRow} (parent: {#table AXRole: AXTable})
 23
 24{#r0c0 AXRole: AXCell} (parent: {#r0 AXRole: AXRow})
 25
 26{AXRole: AXStaticText AXValue: Author} (parent: {#r0c0 AXRole: AXCell})
 27
 28{#r0c1 AXRole: AXCell} (parent: {#r0 AXRole: AXRow})
 29
 30{AXRole: AXStaticText AXValue: Title} (parent: {#r0c1 AXRole: AXCell})
 31
 32{#r0c2 AXRole: AXCell} (parent: {#r0 AXRole: AXRow})
 33
 34{AXRole: AXStaticText AXValue: Year} (parent: {#r0c2 AXRole: AXCell})
 35
 36{#r1 AXRole: AXRow} (parent: {#table AXRole: AXTable})
 37
 38{#r1c0 AXRole: AXCell} (parent: {#r1 AXRole: AXRow})
 39
 40{AXRole: AXStaticText AXValue: Stephen Hawking} (parent: {#r1c0 AXRole: AXCell})
 41
 42{#r1c1 AXRole: AXCell} (parent: {#r1 AXRole: AXRow})
 43
 44{AXRole: AXStaticText AXValue: A Brief History of Time} (parent: {#r1c1 AXRole: AXCell})
 45
 46{#r1c2 AXRole: AXCell} (parent: {#r1 AXRole: AXRow})
 47
 48{AXRole: AXStaticText AXValue: 1988} (parent: {#r1c2 AXRole: AXCell})
 49
 50{#r2 AXRole: AXRow} (parent: {#table AXRole: AXTable})
 51
 52{#r2c0 AXRole: AXCell} (parent: {#r2 AXRole: AXRow})
 53
 54{AXRole: AXStaticText AXValue: Carl Sagan} (parent: {#r2c0 AXRole: AXCell})
 55
 56{#r2c1 AXRole: AXCell} (parent: {#r2 AXRole: AXRow})
 57
 58{AXRole: AXStaticText AXValue: Cosmos} (parent: {#r2c1 AXRole: AXCell})
 59
 60{#r2c2 AXRole: AXCell} (parent: {#r2 AXRole: AXRow})
 61
 62{AXRole: AXStaticText AXValue: 1980} (parent: {#r2c2 AXRole: AXCell})
 63
 64{#r3 AXRole: AXRow} (parent: {#table AXRole: AXTable})
 65
 66{#r3c0 AXRole: AXCell} (parent: {#r3 AXRole: AXRow})
 67
 68{AXRole: AXStaticText AXValue: Will Gater} (parent: {#r3c0 AXRole: AXCell})
 69
 70{#r3c1 AXRole: AXCell} (parent: {#r3 AXRole: AXRow})
 71
 72{AXRole: AXStaticText AXValue: The Mysteries of the Universe} (parent: {#r3c1 AXRole: AXCell})
 73
 74{#r3c2 AXRole: AXCell} (parent: {#r3 AXRole: AXRow})
 75
 76{AXRole: AXStaticText AXValue: 2020} (parent: {#r3c2 AXRole: AXCell})
 77
 78PASS successfullyParsed is true
 79
 80TEST COMPLETE
 81This is a table caption
 82Author Title Year Stephen Hawking A Brief History of Time 1988 Carl Sagan Cosmos 1980 Will Gater The Mysteries of the Universe 2020

LayoutTests/accessibility/table-display-inline-block.html

 1<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
 2<html>
 3<head>
 4<script src="../resources/accessibility-helper.js"></script>
 5<script src="../resources/js-test.js"></script>
 6<style>
 7table, tr, td, th {
 8 display: inline-block;
 9}
 10</style>
 11</head>
 12<body role="group" id="body">
 13
 14<table id="table">
 15<caption>This is a table caption</caption>
 16<thead>
 17 <tr id="r0">
 18 <th id="r0c0">Author</th>
 19 <th id="r0c1">Title</th>
 20 <th id="r0c2">Year</th>
 21 </tr>
 22</thead>
 23<tbody>
 24 <tr id="r1">
 25 <td id="r1c0">Stephen Hawking</td>
 26 <td id="r1c1">A Brief History of Time</td>
 27 <td id="r1c2">1988</td>
 28 </tr>
 29 <tr id="r2">
 30 <td id="r2c0">Carl Sagan</td>
 31 <td id="r2c1">Cosmos</td>
 32 <td id="r2c2">1980</td>
 33 </tr>
 34 <tr id="r3">
 35 <td id="r3c0">Will Gater</td>
 36 <td id="r3c1">The Mysteries of the Universe</td>
 37 <td id="r3c2">2020</td>
 38 </tr>
 39</tbody>
 40</table>
 41
 42<script>
 43var output = "This test ensures that a table with display:inline-block components is accessible.\n\n";
 44
 45if (window.accessibilityController) {
 46 var table = accessibilityController.accessibleElementById("table");
 47 output += expect("table.rowCount", "4");
 48 output += expect("table.columnCount", "3");
 49
 50 for (let row = 0; row < 4; row++) {
 51 for (let column = 0; column < 3; column++)
 52 output += expect(`table.cellForColumnAndRow(${column}, ${row}).domIdentifier`, `"r${row}c${column}"`);
 53 }
 54
 55 output += `\nPerforming search traversal of body.\n`;
 56 function elementDescription(axElement) {
 57 if (!axElement)
 58 return "null";
 59
 60 const role = axElement.role;
 61 const id = axElement.domIdentifier;
 62 let result = `${id ? `#${id} ` : ""}${role}`;
 63 if (role.includes("StaticText"))
 64 result += ` ${accessibilityController.platformName === "ios" ? axElement.description : axElement.stringValue}`;
 65 return result;
 66 }
 67
 68 const container = accessibilityController.accessibleElementById("body");
 69 let searchResult = null;
 70 while (true) {
 71 searchResult = container.uiElementForSearchPredicate(searchResult, true, "AXAnyTypeSearchKey", "", false);
 72 if (!searchResult)
 73 break;
 74 const parentOutput = accessibilityController.platformName === "ios" ? "" : ` (parent: {${elementDescription(searchResult.parentElement())}})`;
 75 output += `\n{${elementDescription(searchResult)}}${parentOutput}\n`;
 76 }
 77 debug(output);
 78}
 79</script>
 80</body>
 81</html>
 82

LayoutTests/platform/glib/accessibility/list-detection-expected.txt

@@PASS axElement.role == 'AXRole: AXList' is true
5656
5757
5858Inline list elements with an aria role should be a list
59 PASS axElement.role == 'AXRole: AXList' is false
 59PASS axElement.role == 'AXRole: AXList' is true
6060
6161
6262PASS successfullyParsed is true

LayoutTests/platform/ios/TestExpectations

@@accessibility/slider-with-lost-renderer.html [ Pass ]
22052205accessibility/spinbutton-increment-decrement.html [ Pass ]
22062206accessibility/display-contents/text-under-element.html [ Pass ]
22072207accessibility/text-updates-after-dynamic-change.html [ Pass ]
 2208accessibility/table-display-block.html [ Pass ]
 2209accessibility/table-display-flex.html [ Pass ]
 2210accessibility/table-display-grid.html [ Pass ]
 2211accessibility/table-display-inline-block.html [ Pass ]
22082212accessibility/url-test.html [ Pass ]
22092213accessibility/video-element-url-attribute.html [ Pass ]
22102214accessibility/visible-character-range-basic.html [ Pass ]

LayoutTests/platform/ios/accessibility/display-contents/table-expected.txt

@@Performing search traversal of body.
4141
4242{StaticText AXLabel: 2020}
4343
44 {Table}
45 
4644PASS successfullyParsed is true
4745
4846TEST COMPLETE

LayoutTests/platform/ios/accessibility/table-display-block-expected.txt

 1This test ensures that a table with display:block components is accessible.
 2
 3PASS: table.rowCount === 4
 4PASS: table.columnCount === 3
 5PASS: table.cellForColumnAndRow(0, 0).domIdentifier === "r0c0"
 6PASS: table.cellForColumnAndRow(1, 0).domIdentifier === "r0c1"
 7PASS: table.cellForColumnAndRow(2, 0).domIdentifier === "r0c2"
 8PASS: table.cellForColumnAndRow(0, 1).domIdentifier === "r1c0"
 9PASS: table.cellForColumnAndRow(1, 1).domIdentifier === "r1c1"
 10PASS: table.cellForColumnAndRow(2, 1).domIdentifier === "r1c2"
 11PASS: table.cellForColumnAndRow(0, 2).domIdentifier === "r2c0"
 12PASS: table.cellForColumnAndRow(1, 2).domIdentifier === "r2c1"
 13PASS: table.cellForColumnAndRow(2, 2).domIdentifier === "r2c2"
 14PASS: table.cellForColumnAndRow(0, 3).domIdentifier === "r3c0"
 15PASS: table.cellForColumnAndRow(1, 3).domIdentifier === "r3c1"
 16PASS: table.cellForColumnAndRow(2, 3).domIdentifier === "r3c2"
 17
 18Performing search traversal of body.
 19
 20{StaticText AXLabel: Author}
 21
 22{StaticText AXLabel: Title}
 23
 24{StaticText AXLabel: Year}
 25
 26{StaticText AXLabel: Stephen Hawking}
 27
 28{StaticText AXLabel: A Brief History of Time}
 29
 30{StaticText AXLabel: 1988}
 31
 32{StaticText AXLabel: Carl Sagan}
 33
 34{StaticText AXLabel: Cosmos}
 35
 36{StaticText AXLabel: 1980}
 37
 38{StaticText AXLabel: Will Gater}
 39
 40{StaticText AXLabel: The Mysteries of the Universe}
 41
 42{StaticText AXLabel: 2020}
 43
 44PASS successfullyParsed is true
 45
 46TEST COMPLETE
 47This is a table caption
 48Author
 49Title
 50Year
 51Stephen Hawking
 52A Brief History of Time
 531988
 54Carl Sagan
 55Cosmos
 561980
 57Will Gater
 58The Mysteries of the Universe
 592020

LayoutTests/platform/ios/accessibility/table-display-flex-expected.txt

 1This test ensures that a table with display:flex components is accessible.
 2
 3PASS: table.rowCount === 4
 4PASS: table.columnCount === 3
 5PASS: table.cellForColumnAndRow(0, 0).domIdentifier === "r0c0"
 6PASS: table.cellForColumnAndRow(1, 0).domIdentifier === "r0c1"
 7PASS: table.cellForColumnAndRow(2, 0).domIdentifier === "r0c2"
 8PASS: table.cellForColumnAndRow(0, 1).domIdentifier === "r1c0"
 9PASS: table.cellForColumnAndRow(1, 1).domIdentifier === "r1c1"
 10PASS: table.cellForColumnAndRow(2, 1).domIdentifier === "r1c2"
 11PASS: table.cellForColumnAndRow(0, 2).domIdentifier === "r2c0"
 12PASS: table.cellForColumnAndRow(1, 2).domIdentifier === "r2c1"
 13PASS: table.cellForColumnAndRow(2, 2).domIdentifier === "r2c2"
 14PASS: table.cellForColumnAndRow(0, 3).domIdentifier === "r3c0"
 15PASS: table.cellForColumnAndRow(1, 3).domIdentifier === "r3c1"
 16PASS: table.cellForColumnAndRow(2, 3).domIdentifier === "r3c2"
 17
 18Performing search traversal of body.
 19
 20{StaticText AXLabel: Author}
 21
 22{StaticText AXLabel: Title}
 23
 24{StaticText AXLabel: Year}
 25
 26{StaticText AXLabel: Stephen Hawking}
 27
 28{StaticText AXLabel: A Brief History of Time}
 29
 30{StaticText AXLabel: 1988}
 31
 32{StaticText AXLabel: Carl Sagan}
 33
 34{StaticText AXLabel: Cosmos}
 35
 36{StaticText AXLabel: 1980}
 37
 38{StaticText AXLabel: Will Gater}
 39
 40{StaticText AXLabel: The Mysteries of the Universe}
 41
 42{StaticText AXLabel: 2020}
 43
 44PASS successfullyParsed is true
 45
 46TEST COMPLETE
 47This is a table caption
 48Author
 49Title
 50Year
 51Stephen Hawking
 52A Brief History of Time
 531988
 54Carl Sagan
 55Cosmos
 561980
 57Will Gater
 58The Mysteries of the Universe
 592020

LayoutTests/platform/ios/accessibility/table-display-grid-expected.txt

 1This test ensures that a table with display:grid components is accessible.
 2
 3PASS: table.rowCount === 4
 4PASS: table.columnCount === 3
 5PASS: table.cellForColumnAndRow(0, 0).domIdentifier === "r0c0"
 6PASS: table.cellForColumnAndRow(1, 0).domIdentifier === "r0c1"
 7PASS: table.cellForColumnAndRow(2, 0).domIdentifier === "r0c2"
 8PASS: table.cellForColumnAndRow(0, 1).domIdentifier === "r1c0"
 9PASS: table.cellForColumnAndRow(1, 1).domIdentifier === "r1c1"
 10PASS: table.cellForColumnAndRow(2, 1).domIdentifier === "r1c2"
 11PASS: table.cellForColumnAndRow(0, 2).domIdentifier === "r2c0"
 12PASS: table.cellForColumnAndRow(1, 2).domIdentifier === "r2c1"
 13PASS: table.cellForColumnAndRow(2, 2).domIdentifier === "r2c2"
 14PASS: table.cellForColumnAndRow(0, 3).domIdentifier === "r3c0"
 15PASS: table.cellForColumnAndRow(1, 3).domIdentifier === "r3c1"
 16PASS: table.cellForColumnAndRow(2, 3).domIdentifier === "r3c2"
 17
 18Performing search traversal of body.
 19
 20{StaticText AXLabel: Author}
 21
 22{StaticText AXLabel: Title}
 23
 24{StaticText AXLabel: Year}
 25
 26{StaticText AXLabel: Stephen Hawking}
 27
 28{StaticText AXLabel: A Brief History of Time}
 29
 30{StaticText AXLabel: 1988}
 31
 32{StaticText AXLabel: Carl Sagan}
 33
 34{StaticText AXLabel: Cosmos}
 35
 36{StaticText AXLabel: 1980}
 37
 38{StaticText AXLabel: Will Gater}
 39
 40{StaticText AXLabel: The Mysteries of the Universe}
 41
 42{StaticText AXLabel: 2020}
 43
 44PASS successfullyParsed is true
 45
 46TEST COMPLETE
 47This is a table caption
 48Author
 49Title
 50Year
 51Stephen Hawking
 52A Brief History of Time
 531988
 54Carl Sagan
 55Cosmos
 561980
 57Will Gater
 58The Mysteries of the Universe
 592020

LayoutTests/platform/ios/accessibility/table-display-inline-block-expected.txt

 1This test ensures that a table with display:inline-block components is accessible.
 2
 3PASS: table.rowCount === 4
 4PASS: table.columnCount === 3
 5PASS: table.cellForColumnAndRow(0, 0).domIdentifier === "r0c0"
 6PASS: table.cellForColumnAndRow(1, 0).domIdentifier === "r0c1"
 7PASS: table.cellForColumnAndRow(2, 0).domIdentifier === "r0c2"
 8PASS: table.cellForColumnAndRow(0, 1).domIdentifier === "r1c0"
 9PASS: table.cellForColumnAndRow(1, 1).domIdentifier === "r1c1"
 10PASS: table.cellForColumnAndRow(2, 1).domIdentifier === "r1c2"
 11PASS: table.cellForColumnAndRow(0, 2).domIdentifier === "r2c0"
 12PASS: table.cellForColumnAndRow(1, 2).domIdentifier === "r2c1"
 13PASS: table.cellForColumnAndRow(2, 2).domIdentifier === "r2c2"
 14PASS: table.cellForColumnAndRow(0, 3).domIdentifier === "r3c0"
 15PASS: table.cellForColumnAndRow(1, 3).domIdentifier === "r3c1"
 16PASS: table.cellForColumnAndRow(2, 3).domIdentifier === "r3c2"
 17
 18Performing search traversal of body.
 19
 20{StaticText AXLabel: Author}
 21
 22{StaticText AXLabel: Title}
 23
 24{StaticText AXLabel: Year}
 25
 26{StaticText AXLabel: Stephen Hawking}
 27
 28{StaticText AXLabel: A Brief History of Time}
 29
 30{StaticText AXLabel: 1988}
 31
 32{StaticText AXLabel: Carl Sagan}
 33
 34{StaticText AXLabel: Cosmos}
 35
 36{StaticText AXLabel: 1980}
 37
 38{StaticText AXLabel: Will Gater}
 39
 40{StaticText AXLabel: The Mysteries of the Universe}
 41
 42{StaticText AXLabel: 2020}
 43
 44PASS successfullyParsed is true
 45
 46TEST COMPLETE
 47This is a table caption
 48Author Title Year Stephen Hawking A Brief History of Time 1988 Carl Sagan Cosmos 1980 Will Gater The Mysteries of the Universe 2020

LayoutTests/platform/mac/accessibility/generated-content-with-display-table-crash-expected.txt

@@AXRole: AXWebArea AXValue:
77 AXRole: AXStaticText AXValue: foo
88 AXRole: AXStaticText AXValue: !
99 AXRole: AXStaticText AXValue: bar
10  AXRole: AXGroup AXValue:
11  AXRole: AXStaticText AXValue: !
 10 AXRole: AXStaticText AXValue: !
1211 AXRole: AXGroup AXValue:
1312 AXRole: AXStaticText AXValue: baz
1413 AXRole: AXGroup AXValue: