axe-core 4.10.1 → 4.10.2-canary.71cbd90

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -14,7 +14,7 @@ Axe is an accessibility testing engine for websites and other HTML-based user in
14
14
 
15
15
  ## The Accessibility Rules
16
16
 
17
- Axe-core has different types of rules, for WCAG 2.0, 2.1, 2.2 on level A, AA and AAA as well as a number of best practices that help you identify common accessibility practices like ensuring every page has an `h1` heading, and to help you avoid "gotchas" in ARIA like where an ARIA attribute you used will get ignored. The complete list of rules, grouped WCAG level and best practice, can found in [doc/rule-descriptions.md](./doc/rule-descriptions.md).
17
+ Axe-core has different types of rules, for WCAG 2.0, 2.1, 2.2 on level A, AA and AAA as well as a number of best practices that help you identify common accessibility practices like ensuring every page has an `h1` heading, and to help you avoid "gotchas" in ARIA like where an ARIA attribute you used will get ignored. The complete list of rules, grouped WCAG level and best practice, can be found in [doc/rule-descriptions.md](./doc/rule-descriptions.md).
18
18
 
19
19
  With axe-core, you can find **on average 57% of WCAG issues automatically**. Additionally, axe-core will return elements as "incomplete" where axe-core could not be certain, and manual review is needed.
20
20
 
@@ -65,7 +65,7 @@ Axe was built to reflect how web development actually works. It works with all m
65
65
  - It's actively supported by [Deque Systems](https://www.deque.com), a major accessibility vendor.
66
66
  - It integrates with your existing functional/acceptance automated tests.
67
67
  - It automatically determines which rules to run based on the evaluation context.
68
- - Axe supports in-memory fixtures, static fixtures, integration tests and iframes of infinite depth.
68
+ - Axe supports in-memory fixtures, static fixtures, integration tests, and iframes of infinite depth.
69
69
  - Axe is highly configurable.
70
70
 
71
71
  ## Supported Browsers
package/axe.d.ts CHANGED
@@ -342,6 +342,9 @@ declare namespace axe {
342
342
  interface DqElement extends SerialDqElement {
343
343
  element: Element;
344
344
  toJSON(): SerialDqElement;
345
+ }
346
+ interface DqElementConstructor {
347
+ new (elm: Element, options?: { absolutePaths?: boolean }): DqElement;
345
348
  mergeSpecs(
346
349
  childSpec: SerialDqElement,
347
350
  parentSpec: SerialDqElement
@@ -405,6 +408,24 @@ declare namespace axe {
405
408
  boundingClientRect: DOMRect;
406
409
  }
407
410
 
411
+ interface CustomNodeSerializer<T = SerialDqElement> {
412
+ toSpec: (dqElm: DqElement) => T;
413
+ mergeSpecs: (nodeSpec: T, parentFrameSpec: T) => T;
414
+ }
415
+
416
+ interface NodeSerializer {
417
+ update: <T>(serializer: CustomNodeSerializer<T>) => void;
418
+ toSpec: (node: Element | VirtualNode) => SerialDqElement;
419
+ dqElmToSpec: (
420
+ dqElm: DqElement | SerialDqElement,
421
+ options?: RunOptions
422
+ ) => SerialDqElement;
423
+ mergeSpecs: (
424
+ nodeSpec: SerialDqElement,
425
+ parentFrameSpec: SerialDqElement
426
+ ) => SerialDqElement;
427
+ }
428
+
408
429
  interface Utils {
409
430
  getFrameContexts: (
410
431
  context?: ElementContext,
@@ -423,15 +444,13 @@ declare namespace axe {
423
444
  selector: unknown
424
445
  ) => selector is LabelledShadowDomSelector;
425
446
 
426
- DqElement: new (
427
- elm: Element,
428
- options?: { absolutePaths?: boolean }
429
- ) => DqElement;
447
+ DqElement: DqElementConstructor;
430
448
  uuid: (
431
449
  options?: { random?: Uint8Array | Array<number> },
432
450
  buf?: Uint8Array | Array<number>,
433
451
  offset?: number
434
452
  ) => string | Uint8Array | Array<number>;
453
+ nodeSerializer: NodeSerializer;
435
454
  }
436
455
 
437
456
  interface Aria {
package/axe.js CHANGED
@@ -1,4 +1,4 @@
1
- /*! axe v4.10.1
1
+ /*! axe v4.10.2-canary.71cbd90
2
2
  * Copyright (c) 2015 - 2024 Deque Systems, Inc.
3
3
  *
4
4
  * Your use of this Source Code Form is subject to the terms of the Mozilla Public
@@ -22,7 +22,7 @@
22
22
  }, _typeof(o);
23
23
  }
24
24
  var axe = axe || {};
25
- axe.version = '4.10.1';
25
+ axe.version = '4.10.2-canary.71cbd90';
26
26
  if (typeof define === 'function' && define.amd) {
27
27
  define('axe-core', [], function() {
28
28
  return axe;
@@ -6943,6 +6943,9 @@
6943
6943
  parseStylesheet: function parseStylesheet() {
6944
6944
  return parse_stylesheet_default;
6945
6945
  },
6946
+ parseTabindex: function parseTabindex() {
6947
+ return parse_tabindex_default;
6948
+ },
6946
6949
  performanceTimer: function performanceTimer() {
6947
6950
  return performance_timer_default;
6948
6951
  },
@@ -7625,7 +7628,7 @@
7625
7628
  var parentElement = node.parentElement;
7626
7629
  var parentNode = node.parentNode;
7627
7630
  var nthChild = '';
7628
- if (nodeName2 !== 'head' && nodeName2 !== 'body' && parentNode.children.length > 1) {
7631
+ if (nodeName2 !== 'head' && nodeName2 !== 'body' && (parentNode === null || parentNode === void 0 ? void 0 : parentNode.children.length) > 1) {
7629
7632
  var index = Array.prototype.indexOf.call(parentNode.children, node) + 1;
7630
7633
  nthChild = ':nth-child('.concat(index, ')');
7631
7634
  }
@@ -10299,9 +10302,8 @@
10299
10302
  var nodeAndDescendents = query_selector_all_default(virtualNode, '*');
10300
10303
  var tabbableElements = nodeAndDescendents.filter(function(vNode) {
10301
10304
  var isFocusable2 = vNode.isFocusable;
10302
- var tabIndex = vNode.actualNode.getAttribute('tabindex');
10303
- tabIndex = tabIndex && !isNaN(parseInt(tabIndex, 10)) ? parseInt(tabIndex) : null;
10304
- return tabIndex ? isFocusable2 && tabIndex >= 0 : isFocusable2;
10305
+ var tabIndex = parse_tabindex_default(vNode.actualNode.getAttribute('tabindex'));
10306
+ return tabIndex !== null ? isFocusable2 && tabIndex >= 0 : isFocusable2;
10305
10307
  });
10306
10308
  return tabbableElements;
10307
10309
  }
@@ -10344,18 +10346,15 @@
10344
10346
  } else if (is_natively_focusable_default(vNode)) {
10345
10347
  return true;
10346
10348
  }
10347
- var tabindex = vNode.attr('tabindex');
10348
- if (tabindex && !isNaN(parseInt(tabindex, 10))) {
10349
- return true;
10350
- }
10351
- return false;
10349
+ var tabindex = parse_tabindex_default(vNode.attr('tabindex'));
10350
+ return tabindex !== null;
10352
10351
  }
10353
10352
  function _isInTabOrder(el) {
10354
10353
  var _nodeLookup6 = _nodeLookup(el), vNode = _nodeLookup6.vNode;
10355
10354
  if (vNode.props.nodeType !== 1) {
10356
10355
  return false;
10357
10356
  }
10358
- var tabindex = parseInt(vNode.attr('tabindex', 10));
10357
+ var tabindex = parse_tabindex_default(vNode.attr('tabindex'));
10359
10358
  if (tabindex <= -1) {
10360
10359
  return false;
10361
10360
  }
@@ -13893,7 +13892,7 @@
13893
13892
  });
13894
13893
  }
13895
13894
  function insertedIntoFocusOrder(el) {
13896
- var tabIndex = parseInt(el.getAttribute('tabindex'), 10);
13895
+ var tabIndex = parse_tabindex_default(el.getAttribute('tabindex'));
13897
13896
  return tabIndex > -1 && _isFocusable(el) && !is_natively_focusable_default(el);
13898
13897
  }
13899
13898
  var inserted_into_focus_order_default = insertedIntoFocusOrder;
@@ -18616,12 +18615,8 @@
18616
18615
  };
18617
18616
  }
18618
18617
  function frameFocusable(frame) {
18619
- var tabIndex = frame.getAttribute('tabindex');
18620
- if (!tabIndex) {
18621
- return true;
18622
- }
18623
- var _int = parseInt(tabIndex, 10);
18624
- return isNaN(_int) || _int >= 0;
18618
+ var tabIndex = parse_tabindex_default(frame.getAttribute('tabindex'));
18619
+ return tabIndex === null || tabIndex >= 0;
18625
18620
  }
18626
18621
  function getBoundingSize(domNode) {
18627
18622
  var width = parseInt(domNode.getAttribute('width'), 10);
@@ -19196,6 +19191,17 @@
19196
19191
  });
19197
19192
  }
19198
19193
  var parse_crossorigin_stylesheet_default = parseCrossOriginStylesheet;
19194
+ function parseTabindex(value) {
19195
+ if (typeof value !== 'string') {
19196
+ return null;
19197
+ }
19198
+ var match = value.trim().match(/^([-+]?\d+)/);
19199
+ if (match) {
19200
+ return Number(match[1]);
19201
+ }
19202
+ return null;
19203
+ }
19204
+ var parse_tabindex_default = parseTabindex;
19199
19205
  var performanceTimer = function() {
19200
19206
  function now() {
19201
19207
  if (window.performance && window.performance) {
@@ -20505,54 +20511,6 @@
20505
20511
  return out ? true : void 0;
20506
20512
  }
20507
20513
  var th_has_data_cells_evaluate_default = thHasDataCellsEvaluate;
20508
- function tdHeadersAttrEvaluate(node) {
20509
- var cells = [];
20510
- var reviewCells = [];
20511
- var badCells = [];
20512
- for (var rowIndex = 0; rowIndex < node.rows.length; rowIndex++) {
20513
- var row = node.rows[rowIndex];
20514
- for (var cellIndex = 0; cellIndex < row.cells.length; cellIndex++) {
20515
- cells.push(row.cells[cellIndex]);
20516
- }
20517
- }
20518
- var ids = cells.filter(function(cell) {
20519
- return cell.getAttribute('id');
20520
- }).map(function(cell) {
20521
- return cell.getAttribute('id');
20522
- });
20523
- cells.forEach(function(cell) {
20524
- var isSelf = false;
20525
- var notOfTable = false;
20526
- if (!cell.hasAttribute('headers') || !_isVisibleToScreenReaders(cell)) {
20527
- return;
20528
- }
20529
- var headersAttr = cell.getAttribute('headers').trim();
20530
- if (!headersAttr) {
20531
- return reviewCells.push(cell);
20532
- }
20533
- var headers = token_list_default(headersAttr);
20534
- if (headers.length !== 0) {
20535
- if (cell.getAttribute('id')) {
20536
- isSelf = headers.indexOf(cell.getAttribute('id').trim()) !== -1;
20537
- }
20538
- notOfTable = headers.some(function(header) {
20539
- return !ids.includes(header);
20540
- });
20541
- if (isSelf || notOfTable) {
20542
- badCells.push(cell);
20543
- }
20544
- }
20545
- });
20546
- if (badCells.length > 0) {
20547
- this.relatedNodes(badCells);
20548
- return false;
20549
- }
20550
- if (reviewCells.length) {
20551
- this.relatedNodes(reviewCells);
20552
- return void 0;
20553
- }
20554
- return true;
20555
- }
20556
20514
  var aria_exports = {};
20557
20515
  __export(aria_exports, {
20558
20516
  allowedAttr: function allowedAttr() {
@@ -22774,6 +22732,66 @@
22774
22732
  return !!attrDefinition;
22775
22733
  }
22776
22734
  var validate_attr_default = validateAttr;
22735
+ var messageKeys = [ 'cell-header-not-in-table', 'cell-header-not-th', 'header-refs-self', 'empty-hdrs' ];
22736
+ var notInTable = messageKeys[0], notTh = messageKeys[1], selfRef = messageKeys[2], emptyHdrs = messageKeys[3];
22737
+ function tdHeadersAttrEvaluate(node) {
22738
+ var cells = [];
22739
+ var cellRoleById = {};
22740
+ for (var rowIndex = 0; rowIndex < node.rows.length; rowIndex++) {
22741
+ var row = node.rows[rowIndex];
22742
+ for (var cellIndex = 0; cellIndex < row.cells.length; cellIndex++) {
22743
+ var cell = row.cells[cellIndex];
22744
+ cells.push(cell);
22745
+ var cellId = cell.getAttribute('id');
22746
+ if (cellId) {
22747
+ cellRoleById[cellId] = get_role_default(cell);
22748
+ }
22749
+ }
22750
+ }
22751
+ var badCells = _defineProperty(_defineProperty(_defineProperty(_defineProperty({}, selfRef, new Set()), notInTable, new Set()), notTh, new Set()), emptyHdrs, new Set());
22752
+ cells.forEach(function(cell) {
22753
+ if (!cell.hasAttribute('headers') || !_isVisibleToScreenReaders(cell)) {
22754
+ return;
22755
+ }
22756
+ var headersAttr = cell.getAttribute('headers').trim();
22757
+ if (!headersAttr) {
22758
+ badCells[emptyHdrs].add(cell);
22759
+ return;
22760
+ }
22761
+ var cellId = cell.getAttribute('id');
22762
+ var headers = token_list_default(headersAttr);
22763
+ headers.forEach(function(headerId) {
22764
+ if (cellId && headerId === cellId) {
22765
+ badCells[selfRef].add(cell);
22766
+ } else if (!cellRoleById[headerId]) {
22767
+ badCells[notInTable].add(cell);
22768
+ } else if (![ 'columnheader', 'rowheader' ].includes(cellRoleById[headerId])) {
22769
+ badCells[notTh].add(cell);
22770
+ }
22771
+ });
22772
+ });
22773
+ var _iterator15 = _createForOfIteratorHelper(messageKeys), _step15;
22774
+ try {
22775
+ for (_iterator15.s(); !(_step15 = _iterator15.n()).done; ) {
22776
+ var messageKey = _step15.value;
22777
+ if (badCells[messageKey].size > 0) {
22778
+ this.relatedNodes(_toConsumableArray(badCells[messageKey]));
22779
+ if (messageKey === emptyHdrs) {
22780
+ return void 0;
22781
+ }
22782
+ this.data({
22783
+ messageKey: messageKey
22784
+ });
22785
+ return false;
22786
+ }
22787
+ }
22788
+ } catch (err) {
22789
+ _iterator15.e(err);
22790
+ } finally {
22791
+ _iterator15.f();
22792
+ }
22793
+ return true;
22794
+ }
22777
22795
  function tdHasHeaderEvaluate(node) {
22778
22796
  var badCells = [];
22779
22797
  var cells = get_all_cells_default(node);
@@ -23162,19 +23180,19 @@
23162
23180
  return;
23163
23181
  }
23164
23182
  var frameAncestry = r.node.ancestry.slice(0, -1);
23165
- var _iterator15 = _createForOfIteratorHelper(iframeResults), _step15;
23183
+ var _iterator16 = _createForOfIteratorHelper(iframeResults), _step16;
23166
23184
  try {
23167
- for (_iterator15.s(); !(_step15 = _iterator15.n()).done; ) {
23168
- var iframeResult = _step15.value;
23185
+ for (_iterator16.s(); !(_step16 = _iterator16.n()).done; ) {
23186
+ var iframeResult = _step16.value;
23169
23187
  if (_matchAncestry(frameAncestry, iframeResult.node.ancestry)) {
23170
23188
  r.result = iframeResult.result;
23171
23189
  break;
23172
23190
  }
23173
23191
  }
23174
23192
  } catch (err) {
23175
- _iterator15.e(err);
23193
+ _iterator16.e(err);
23176
23194
  } finally {
23177
- _iterator15.f();
23195
+ _iterator16.f();
23178
23196
  }
23179
23197
  });
23180
23198
  iframeResults.forEach(function(r) {
@@ -23661,11 +23679,11 @@
23661
23679
  }
23662
23680
  function getShadowColorsMap(parsedShadows) {
23663
23681
  var colorMap = {};
23664
- var _iterator16 = _createForOfIteratorHelper(parsedShadows), _step16;
23682
+ var _iterator17 = _createForOfIteratorHelper(parsedShadows), _step17;
23665
23683
  try {
23666
- for (_iterator16.s(); !(_step16 = _iterator16.n()).done; ) {
23684
+ for (_iterator17.s(); !(_step17 = _iterator17.n()).done; ) {
23667
23685
  var _colorMap$colorStr;
23668
- var _step16$value = _step16.value, colorStr = _step16$value.colorStr, pixels = _step16$value.pixels;
23686
+ var _step17$value = _step17.value, colorStr = _step17$value.colorStr, pixels = _step17$value.pixels;
23669
23687
  (_colorMap$colorStr = colorMap[colorStr]) !== null && _colorMap$colorStr !== void 0 ? _colorMap$colorStr : colorMap[colorStr] = {
23670
23688
  top: [],
23671
23689
  right: [],
@@ -23686,9 +23704,9 @@
23686
23704
  }
23687
23705
  }
23688
23706
  } catch (err) {
23689
- _iterator16.e(err);
23707
+ _iterator17.e(err);
23690
23708
  } finally {
23691
- _iterator16.f();
23709
+ _iterator17.f();
23692
23710
  }
23693
23711
  return colorMap;
23694
23712
  }
@@ -23765,10 +23783,10 @@
23765
23783
  assert_default(isNaN(fontSize) === false, 'Unable to determine font-size value '.concat(fontSizeStr));
23766
23784
  var thinShadows = [];
23767
23785
  var shadows = _parseTextShadows(textShadow);
23768
- var _iterator17 = _createForOfIteratorHelper(shadows), _step17;
23786
+ var _iterator18 = _createForOfIteratorHelper(shadows), _step18;
23769
23787
  try {
23770
- for (_iterator17.s(); !(_step17 = _iterator17.n()).done; ) {
23771
- var shadow = _step17.value;
23788
+ for (_iterator18.s(); !(_step18 = _iterator18.n()).done; ) {
23789
+ var shadow = _step18.value;
23772
23790
  var colorStr = shadow.colorStr || style.getPropertyValue('color');
23773
23791
  var _shadow$pixels = _slicedToArray(shadow.pixels, 3), offsetX = _shadow$pixels[0], offsetY = _shadow$pixels[1], _shadow$pixels$ = _shadow$pixels[2], blurRadius = _shadow$pixels$ === void 0 ? 0 : _shadow$pixels$;
23774
23792
  if (maxRatio && blurRadius >= fontSize * maxRatio) {
@@ -23801,9 +23819,9 @@
23801
23819
  shadowColors.push(_color3);
23802
23820
  }
23803
23821
  } catch (err) {
23804
- _iterator17.e(err);
23822
+ _iterator18.e(err);
23805
23823
  } finally {
23806
- _iterator17.f();
23824
+ _iterator18.f();
23807
23825
  }
23808
23826
  if (thinShadows.length > 0) {
23809
23827
  var strokeColors = _getStrokeColorsFromShadows(thinShadows, {
@@ -24131,11 +24149,11 @@
24131
24149
  return fgColor;
24132
24150
  }
24133
24151
  function findNodeInContexts(contexts, node) {
24134
- var _iterator18 = _createForOfIteratorHelper(contexts), _step18;
24152
+ var _iterator19 = _createForOfIteratorHelper(contexts), _step19;
24135
24153
  try {
24136
- for (_iterator18.s(); !(_step18 = _iterator18.n()).done; ) {
24154
+ for (_iterator19.s(); !(_step19 = _iterator19.n()).done; ) {
24137
24155
  var _context$vNode;
24138
- var context = _step18.value;
24156
+ var context = _step19.value;
24139
24157
  if (((_context$vNode = context.vNode) === null || _context$vNode === void 0 ? void 0 : _context$vNode.actualNode) === node) {
24140
24158
  return context;
24141
24159
  }
@@ -24145,9 +24163,9 @@
24145
24163
  }
24146
24164
  }
24147
24165
  } catch (err) {
24148
- _iterator18.e(err);
24166
+ _iterator19.e(err);
24149
24167
  } finally {
24150
- _iterator18.f();
24168
+ _iterator19.f();
24151
24169
  }
24152
24170
  }
24153
24171
  function hasValidContrastRatio(bg, fg, fontSize, isBold) {
@@ -24491,10 +24509,10 @@
24491
24509
  function filterByElmsOverlap(vNode, nearbyElms) {
24492
24510
  var fullyObscuringElms = [];
24493
24511
  var partialObscuringElms = [];
24494
- var _iterator19 = _createForOfIteratorHelper(nearbyElms), _step19;
24512
+ var _iterator20 = _createForOfIteratorHelper(nearbyElms), _step20;
24495
24513
  try {
24496
- for (_iterator19.s(); !(_step19 = _iterator19.n()).done; ) {
24497
- var vNeighbor = _step19.value;
24514
+ for (_iterator20.s(); !(_step20 = _iterator20.n()).done; ) {
24515
+ var vNeighbor = _step20.value;
24498
24516
  if (!isDescendantNotInTabOrder2(vNode, vNeighbor) && _hasVisualOverlap(vNode, vNeighbor) && getCssPointerEvents(vNeighbor) !== 'none') {
24499
24517
  if (isEnclosedRect2(vNode, vNeighbor)) {
24500
24518
  fullyObscuringElms.push(vNeighbor);
@@ -24504,9 +24522,9 @@
24504
24522
  }
24505
24523
  }
24506
24524
  } catch (err) {
24507
- _iterator19.e(err);
24525
+ _iterator20.e(err);
24508
24526
  } finally {
24509
- _iterator19.f();
24527
+ _iterator20.f();
24510
24528
  }
24511
24529
  return {
24512
24530
  fullyObscuringElms: fullyObscuringElms,
@@ -24579,10 +24597,10 @@
24579
24597
  }
24580
24598
  var closeNeighbors = [];
24581
24599
  var closestOffset = minOffset;
24582
- var _iterator20 = _createForOfIteratorHelper(_findNearbyElms(vNode, minOffset)), _step20;
24600
+ var _iterator21 = _createForOfIteratorHelper(_findNearbyElms(vNode, minOffset)), _step21;
24583
24601
  try {
24584
- for (_iterator20.s(); !(_step20 = _iterator20.n()).done; ) {
24585
- var vNeighbor = _step20.value;
24602
+ for (_iterator21.s(); !(_step21 = _iterator21.n()).done; ) {
24603
+ var vNeighbor = _step21.value;
24586
24604
  if (get_role_type_default(vNeighbor) !== 'widget' || !_isFocusable(vNeighbor)) {
24587
24605
  continue;
24588
24606
  }
@@ -24611,9 +24629,9 @@
24611
24629
  closeNeighbors.push(vNeighbor);
24612
24630
  }
24613
24631
  } catch (err) {
24614
- _iterator20.e(err);
24632
+ _iterator21.e(err);
24615
24633
  } finally {
24616
- _iterator20.f();
24634
+ _iterator21.f();
24617
24635
  }
24618
24636
  if (closeNeighbors.length === 0) {
24619
24637
  this.data({
@@ -25422,8 +25440,8 @@
25422
25440
  }
25423
25441
  var alt_space_value_evaluate_default = altSpaceValueEvaluate;
25424
25442
  function tabindexEvaluate(node, options, virtualNode) {
25425
- var tabIndex = parseInt(virtualNode.attr('tabindex'), 10);
25426
- return isNaN(tabIndex) ? true : tabIndex <= 0;
25443
+ var tabIndex = parse_tabindex_default(virtualNode.attr('tabindex'));
25444
+ return tabIndex === null || tabIndex <= 0;
25427
25445
  }
25428
25446
  var tabindex_evaluate_default = tabindexEvaluate;
25429
25447
  function noFocusableContentEvaluate(node, options, virtualNode) {
@@ -25467,8 +25485,8 @@
25467
25485
  return retVal;
25468
25486
  }
25469
25487
  function usesUnreliableHidingStrategy(vNode) {
25470
- var tabIndex = parseInt(vNode.attr('tabindex'), 10);
25471
- return !isNaN(tabIndex) && tabIndex < 0;
25488
+ var tabIndex = parse_tabindex_default(vNode.attr('tabindex'));
25489
+ return tabIndex !== null && tabIndex < 0;
25472
25490
  }
25473
25491
  function landmarkIsTopLevelEvaluate(node) {
25474
25492
  var landmarks = get_aria_roles_by_type_default('landmark');
@@ -25540,9 +25558,7 @@
25540
25558
  }
25541
25559
  var focusable_not_tabbable_evaluate_default = focusableNotTabbableEvaluate;
25542
25560
  function focusableNoNameEvaluate(node, options, virtualNode) {
25543
- var tabIndex = virtualNode.attr('tabindex');
25544
- var inFocusOrder = _isFocusable(virtualNode) && tabIndex > -1;
25545
- if (!inFocusOrder) {
25561
+ if (!_isInTabOrder(virtualNode)) {
25546
25562
  return false;
25547
25563
  }
25548
25564
  try {
@@ -26817,18 +26833,18 @@
26817
26833
  if (Array.isArray(options[role])) {
26818
26834
  allowed = unique_array_default(options[role].concat(allowed));
26819
26835
  }
26820
- var _iterator21 = _createForOfIteratorHelper(virtualNode.attrNames), _step21;
26836
+ var _iterator22 = _createForOfIteratorHelper(virtualNode.attrNames), _step22;
26821
26837
  try {
26822
- for (_iterator21.s(); !(_step21 = _iterator21.n()).done; ) {
26823
- var attrName = _step21.value;
26838
+ for (_iterator22.s(); !(_step22 = _iterator22.n()).done; ) {
26839
+ var attrName = _step22.value;
26824
26840
  if (validate_attr_default(attrName) && !allowed.includes(attrName) && !ignoredAttrs(attrName, virtualNode.attr(attrName), virtualNode)) {
26825
26841
  invalid.push(attrName);
26826
26842
  }
26827
26843
  }
26828
26844
  } catch (err) {
26829
- _iterator21.e(err);
26845
+ _iterator22.e(err);
26830
26846
  } finally {
26831
- _iterator21.f();
26847
+ _iterator22.f();
26832
26848
  }
26833
26849
  if (!invalid.length) {
26834
26850
  return true;
@@ -27007,8 +27023,8 @@
27007
27023
  }
27008
27024
  var no_role_matches_default = noRoleMatches;
27009
27025
  function noNegativeTabindexMatches(node, virtualNode) {
27010
- var tabindex = parseInt(virtualNode.attr('tabindex'), 10);
27011
- return isNaN(tabindex) || tabindex >= 0;
27026
+ var tabindex = parse_tabindex_default(virtualNode.attr('tabindex'));
27027
+ return tabindex === null || tabindex >= 0;
27012
27028
  }
27013
27029
  var no_negative_tabindex_matches_default = noNegativeTabindexMatches;
27014
27030
  function noNamingMethodMatches(node, virtualNode) {
@@ -27338,14 +27354,14 @@
27338
27354
  return false;
27339
27355
  }
27340
27356
  var role = virtualNode.attr('role');
27341
- var tabIndex = virtualNode.attr('tabindex');
27342
- if (tabIndex === '-1' && role) {
27357
+ var tabIndex = parse_tabindex_default(virtualNode.attr('tabindex'));
27358
+ if (tabIndex < 0 && role) {
27343
27359
  var roleDef = standards_default.ariaRoles[role];
27344
27360
  if (roleDef === void 0 || roleDef.type !== 'widget') {
27345
27361
  return false;
27346
27362
  }
27347
27363
  }
27348
- if (tabIndex === '-1' && virtualNode.actualNode && !_isVisibleOnScreen(virtualNode) && !_isVisibleToScreenReaders(virtualNode)) {
27364
+ if (tabIndex < 0 && virtualNode.actualNode && !_isVisibleOnScreen(virtualNode) && !_isVisibleToScreenReaders(virtualNode)) {
27349
27365
  return false;
27350
27366
  }
27351
27367
  return true;
@@ -27836,16 +27852,18 @@
27836
27852
  });
27837
27853
  });
27838
27854
  });
27839
- q.defer(function(res) {
27840
- return setTimeout(res, 0);
27841
- });
27842
- if (options.performanceTimer) {
27843
- this._logRulePerformance();
27844
- }
27845
27855
  q.then(function() {
27846
- return resolve(ruleResult);
27856
+ if (options.performanceTimer) {
27857
+ _this9._logRulePerformance();
27858
+ }
27859
+ setTimeout(function() {
27860
+ resolve(ruleResult);
27861
+ }, 0);
27847
27862
  })['catch'](function(error) {
27848
- return reject(error);
27863
+ if (options.performanceTimer) {
27864
+ _this9._logRulePerformance();
27865
+ }
27866
+ reject(error);
27849
27867
  });
27850
27868
  };
27851
27869
  Rule.prototype.runSync = function runSync2(context) {
@@ -28188,10 +28206,10 @@
28188
28206
  value: function setAllowedOrigins(allowedOrigins) {
28189
28207
  var defaultOrigin = getDefaultOrigin();
28190
28208
  this.allowedOrigins = [];
28191
- var _iterator22 = _createForOfIteratorHelper(allowedOrigins), _step22;
28209
+ var _iterator23 = _createForOfIteratorHelper(allowedOrigins), _step23;
28192
28210
  try {
28193
- for (_iterator22.s(); !(_step22 = _iterator22.n()).done; ) {
28194
- var origin = _step22.value;
28211
+ for (_iterator23.s(); !(_step23 = _iterator23.n()).done; ) {
28212
+ var origin = _step23.value;
28195
28213
  if (origin === constants_default.allOrigins) {
28196
28214
  this.allowedOrigins = [ '*' ];
28197
28215
  return;
@@ -28202,9 +28220,9 @@
28202
28220
  }
28203
28221
  }
28204
28222
  } catch (err) {
28205
- _iterator22.e(err);
28223
+ _iterator23.e(err);
28206
28224
  } finally {
28207
- _iterator22.f();
28225
+ _iterator23.f();
28208
28226
  }
28209
28227
  }
28210
28228
  }, {
@@ -28994,10 +29012,10 @@
28994
29012
  }
28995
29013
  function setFrameSpec(partialResults) {
28996
29014
  var frameStack = [];
28997
- var _iterator23 = _createForOfIteratorHelper(partialResults), _step23;
29015
+ var _iterator24 = _createForOfIteratorHelper(partialResults), _step24;
28998
29016
  try {
28999
- for (_iterator23.s(); !(_step23 = _iterator23.n()).done; ) {
29000
- var partialResult = _step23.value;
29017
+ for (_iterator24.s(); !(_step24 = _iterator24.n()).done; ) {
29018
+ var partialResult = _step24.value;
29001
29019
  var frameSpec = frameStack.shift();
29002
29020
  if (!partialResult) {
29003
29021
  continue;
@@ -29007,9 +29025,9 @@
29007
29025
  frameStack.unshift.apply(frameStack, _toConsumableArray(frameSpecs));
29008
29026
  }
29009
29027
  } catch (err) {
29010
- _iterator23.e(err);
29028
+ _iterator24.e(err);
29011
29029
  } finally {
29012
- _iterator23.f();
29030
+ _iterator24.f();
29013
29031
  }
29014
29032
  }
29015
29033
  function getMergedFrameSpecs(_ref149) {
@@ -29614,8 +29632,8 @@
29614
29632
  help: 'Non-empty <td> elements in larger <table> must have an associated table header'
29615
29633
  },
29616
29634
  'td-headers-attr': {
29617
- description: 'Ensure that each cell in a table that uses the headers attribute refers only to other cells in that table',
29618
- help: 'Table cells that use the headers attribute must only refer to cells in the same table'
29635
+ description: 'Ensure that each cell in a table that uses the headers attribute refers only to other <th> elements in that table',
29636
+ help: 'Table cell headers attributes must refer to other <th> elements in the same table'
29619
29637
  },
29620
29638
  'th-has-data-cells': {
29621
29639
  description: 'Ensure that <th> elements and elements with role=columnheader/rowheader have data cells they describe',
@@ -30655,9 +30673,13 @@
30655
30673
  'td-headers-attr': {
30656
30674
  impact: 'serious',
30657
30675
  messages: {
30658
- pass: 'The headers attribute is exclusively used to refer to other cells in the table',
30676
+ pass: 'The headers attribute is exclusively used to refer to other header cells in the table',
30659
30677
  incomplete: 'The headers attribute is empty',
30660
- fail: 'The headers attribute is not exclusively used to refer to other cells in the table'
30678
+ fail: {
30679
+ 'cell-header-not-in-table': 'The headers attribute is not exclusively used to refer to other header cells in the table',
30680
+ 'cell-header-not-th': 'The headers attribute must refer to header cells, not data cells',
30681
+ 'header-refs-self': 'The element with headers attribute refers to itself'
30682
+ }
30661
30683
  }
30662
30684
  },
30663
30685
  'th-has-data-cells': {