diff --git a/lib/commons/table/get-headers.js b/lib/commons/table/get-headers.js
index e7d2131c1d..a3540dff9f 100644
--- a/lib/commons/table/get-headers.js
+++ b/lib/commons/table/get-headers.js
@@ -20,7 +20,14 @@ function traverseForHeaders(headerType, position, tableGrid) {
// adjust position by rowspan and colspan
// subtract 1 from col/rowspan to make them 0 indexed
const colspan = startCell.colSpan - 1;
- const rowspan = startCell.rowSpan - 1;
+
+ // ie11 returns 1 as the rowspan value even if it's set to 0
+ const rowspanAttr = startCell.getAttribute('rowspan');
+ const rowspanValue =
+ parseInt(rowspanAttr) === 0 || startCell.rowspan === 0
+ ? tableGrid.length
+ : startCell.rowSpan;
+ const rowspan = rowspanValue - 1;
const rowStart = position.y + rowspan;
const colStart = position.x + colspan;
diff --git a/lib/commons/table/to-grid.js b/lib/commons/table/to-grid.js
index 484226e0bd..0463c491cf 100644
--- a/lib/commons/table/to-grid.js
+++ b/lib/commons/table/to-grid.js
@@ -19,7 +19,18 @@ function toGrid(node) {
for (var j = 0, cellLength = cells.length; j < cellLength; j++) {
for (var colSpan = 0; colSpan < cells[j].colSpan; colSpan++) {
- for (var rowSpan = 0; rowSpan < cells[j].rowSpan; rowSpan++) {
+ // if [the rowSpan] value is set to 0, it extends until the
+ // end of the table section
+ // @see https://developer.mozilla.org/en-US/docs/Web/HTML/Element/td#attr-rowspan
+
+ // ie11 returns 1 as the rowspan value even if it's set to 0
+ const rowspanAttr = cells[j].getAttribute('rowspan');
+ const rowspanValue =
+ parseInt(rowspanAttr) === 0 || cells[j].rowspan === 0
+ ? rows.length
+ : cells[j].rowSpan;
+
+ for (var rowSpan = 0; rowSpan < rowspanValue; rowSpan++) {
table[i + rowSpan] = table[i + rowSpan] || [];
while (table[i + rowSpan][columnIndex]) {
columnIndex++;
diff --git a/test/commons/table/get-headers.js b/test/commons/table/get-headers.js
index e7d44cd4c2..9bea2bc19e 100644
--- a/test/commons/table/get-headers.js
+++ b/test/commons/table/get-headers.js
@@ -107,6 +107,22 @@ describe('table.getHeaders', function() {
]);
});
+ it('should handle rowspan=0', function() {
+ fixture.innerHTML =
+ '
';
+
+ var target = $id('target');
+
+ axe.testUtils.flatTreeSetup(fixture.firstChild);
+ assert.deepEqual(axe.commons.table.getHeaders(target), [
+ $id('t1'),
+ $id('t2')
+ ]);
+ });
+
it('should handle headers attribute', function() {
fixture.innerHTML =
'' +
diff --git a/test/commons/table/to-grid.js b/test/commons/table/to-grid.js
index 18849b2e9e..38b78640f2 100644
--- a/test/commons/table/to-grid.js
+++ b/test/commons/table/to-grid.js
@@ -70,6 +70,21 @@ describe('table.toGrid', function() {
]);
});
+ it('should handle rowspan=0', function() {
+ fixture.innerHTML =
+ '' +
+ '2 | ok | |
' +
+ '4 | 5 |
' +
+ '
';
+
+ var target = fixture.querySelector('table');
+
+ assert.deepEqual(axe.commons.table.toGrid(target), [
+ [$id('t1'), $id('t2'), $id('t3')],
+ [$id('t4'), $id('t2'), $id('t5')]
+ ]);
+ });
+
it('should insert an empty array for empty rows', function() {
fixture.innerHTML =
'';