page-no-duplicate-evaluate.js 1.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142
  1. import cache from '../../core/base/cache';
  2. import { querySelectorAllFilter } from '../../core/utils';
  3. import { isVisible, findUpVirtual } from '../../commons/dom';
  4. function pageNoDuplicateEvaluate(node, options, virtualNode) {
  5. if (!options || !options.selector || typeof options.selector !== 'string') {
  6. throw new TypeError(
  7. 'page-no-duplicate requires options.selector to be a string'
  8. );
  9. }
  10. // only look at the first node and it's related nodes
  11. const key = 'page-no-duplicate;' + options.selector;
  12. if (cache.get(key)) {
  13. this.data('ignored');
  14. return;
  15. }
  16. cache.set(key, true);
  17. let elms = querySelectorAllFilter(axe._tree[0], options.selector, elm =>
  18. isVisible(elm.actualNode)
  19. );
  20. // Filter elements that, within certain contexts, don't map their role.
  21. // e.g. a <footer> inside a <main> is not a banner, but in the <body> context it is
  22. if (typeof options.nativeScopeFilter === 'string') {
  23. elms = elms.filter(elm => {
  24. return (
  25. elm.actualNode.hasAttribute('role') ||
  26. !findUpVirtual(elm, options.nativeScopeFilter)
  27. );
  28. });
  29. }
  30. this.relatedNodes(
  31. elms.filter(elm => elm !== virtualNode).map(elm => elm.actualNode)
  32. );
  33. return elms.length <= 1;
  34. }
  35. export default pageNoDuplicateEvaluate;