Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion lib/rules/bypass.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"id": "bypass",
"impact": "serious",
"selector": "html",
"selector": "html:not(html *)",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think this will work in IE 11. In that the not pseudo-selector only supports basic entry like :not(html), it doesn't support complex or list selectors that I'm aware of. This should be validated before merge, as it could break existing checks being ran in the wild.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Doesn't matter. These don't actually get executed. Axe parses them and walks the tree with them.

@straker did you perf test this? This seems like an awfully slow selector.

Copy link
Contributor Author

@straker straker Jan 5, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This isn't slow at all. The way the QSA code works is it matches each expression in turn. So it starts by matching all html elements on the page (an O(1) operation), then it runs the :not operator which is also a quick match using the matchesExpression logic on any found nodes. This barely adds any time to the selection, and testing this out didn't result in any difference in timings.

On https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/Your_first_WebExtension (size of the page does not matter for matching tag selectors), current axe-core average of five runs is 235.76ms. Using this code average of five runs is 220.52ms. This isn't a time savings it's just the variability of the runs. 15ms of time difference is not significant.

"pageLevel": true,
"matches": "bypass-matches",
"reviewOnFail": true,
Expand Down
2 changes: 1 addition & 1 deletion lib/rules/css-orientation-lock.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"id": "css-orientation-lock",
"impact": "serious",
"selector": "html",
"selector": "html:not(html *)",
"tags": [
"cat.structure",
"wcag134",
Expand Down
2 changes: 1 addition & 1 deletion lib/rules/document-title.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"id": "document-title",
"impact": "serious",
"selector": "html",
"selector": "html:not(html *)",
"matches": "is-initiator-matches",
"tags": [
"cat.text-alternatives",
Expand Down
2 changes: 1 addition & 1 deletion lib/rules/frame-focusable-content.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"id": "frame-focusable-content",
"impact": "serious",
"selector": "html",
"selector": "html:not(html *)",
"matches": "frame-focusable-content-matches",
"tags": [
"cat.keyboard",
Expand Down
2 changes: 1 addition & 1 deletion lib/rules/frame-tested.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"id": "frame-tested",
"impact": "critical",
"selector": "html, frame, iframe",
"selector": "html:not(html *), frame, iframe",
"tags": ["cat.structure", "best-practice", "review-item"],
"metadata": {
"description": "Ensure <iframe> and <frame> elements contain the axe-core script",
Expand Down
2 changes: 1 addition & 1 deletion lib/rules/html-has-lang.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"id": "html-has-lang",
"impact": "serious",
"selector": "html",
"selector": "html:not(html *)",
"matches": "is-initiator-matches",
"tags": [
"cat.language",
Expand Down
2 changes: 1 addition & 1 deletion lib/rules/html-lang-valid.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"id": "html-lang-valid",
"impact": "serious",
"selector": "html[lang]:not([lang=\"\"]), html[xml\\:lang]:not([xml\\:lang=\"\"])",
"selector": "html[lang]:not([lang=\"\"]):not(html *), html[xml\\:lang]:not([xml\\:lang=\"\"]):not(html *)",
"tags": [
"cat.language",
"wcag2a",
Expand Down
2 changes: 1 addition & 1 deletion lib/rules/html-xml-lang-mismatch.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"id": "html-xml-lang-mismatch",
"impact": "moderate",
"selector": "html[lang][xml\\:lang]",
"selector": "html[lang][xml\\:lang]:not(html *)",
"matches": "xml-lang-mismatch-matches",
"tags": [
"cat.language",
Expand Down
2 changes: 1 addition & 1 deletion lib/rules/landmark-one-main.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"id": "landmark-one-main",
"impact": "moderate",
"selector": "html",
"selector": "html:not(html *)",
"tags": ["cat.semantics", "best-practice"],
"metadata": {
"description": "Ensure the document has a main landmark",
Expand Down
2 changes: 1 addition & 1 deletion lib/rules/page-has-heading-one.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"id": "page-has-heading-one",
"impact": "moderate",
"selector": "html",
"selector": "html:not(html *)",
"tags": ["cat.semantics", "best-practice"],
"metadata": {
"description": "Ensure that the page, or at least one of its frames contains a level-one heading",
Expand Down
7 changes: 7 additions & 0 deletions test/integration/full/bypass/header1.html
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,13 @@
<h2>This header will make the test pass.</h2>
<a href="http://www.deque.com">stuff</a>
<div id="mocha"></div>
<div id="additional"></div>
<script>
// only way to get a 2nd html element on the page is to create it with createElement
// if you try to do it through the html parser it won't work
var root = document.createElement('html');
document.getElementById('additional').append(root);
</script>
<script src="/test/testutils.js"></script>
<script src="pass-tests.js"></script>
<script src="/test/integration/adapter.js"></script>
Expand Down
2 changes: 1 addition & 1 deletion test/integration/full/bypass/pass-tests.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ describe('bypass aria header test ' + window.location.pathname, function () {
});

it('should find html', function () {
assert.deepEqual(results.passes[0].nodes[0].target, ['html']);
assert.isTrue(results.passes[0].nodes[0].target[0].startsWith('html'));
});
});
});
7 changes: 7 additions & 0 deletions test/integration/full/css-orientation-lock/passes.html
Original file line number Diff line number Diff line change
Expand Up @@ -26,5 +26,12 @@
<script src="/test/testutils.js"></script>
<script src="passes.js"></script>
<script src="/test/integration/adapter.js"></script>
<div id="additional"></div>
<script>
// only way to get a 2nd html element on the page is to create it with createElement
// if you try to do it through the html parser it won't work
var root = document.createElement('html');
document.getElementById('additional').append(root);
</script>
</body>
</html>
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,13 @@
<body>
<iframe id="frame1" src="frames/level1.html"></iframe>
<div id="mocha"></div>
<div id="additional"></div>
<script>
// only way to get a 2nd html element on the page is to create it with createElement
// if you try to do it through the html parser it won't work
var root = document.createElement('html');
document.getElementById('additional').append(root);
</script>
<script src="/test/testutils.js"></script>
<script src="document-title-pass.js"></script>
<script src="/test/integration/adapter.js"></script>
Expand Down
7 changes: 7 additions & 0 deletions test/integration/full/frame-tested/frame-tested-pass.html
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,13 @@
<body>
<iframe id="pass" src="frames/with-axe.html"></iframe>
<div id="mocha"></div>
<div id="additional"></div>
<script>
// only way to get a 2nd html element on the page is to create it with createElement
// if you try to do it through the html parser it won't work
var root = document.createElement('html');
document.getElementById('additional').append(root);
</script>
<script src="/test/testutils.js"></script>
<script src="frame-tested-pass.js"></script>
<script src="/test/integration/adapter.js"></script>
Expand Down
7 changes: 7 additions & 0 deletions test/integration/full/html-has-lang/html-has-lang-pass.html
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,13 @@
-->
<iframe id="frame1" src="frames/level1.html"></iframe>
<div id="mocha"></div>
<div id="additional"></div>
<script>
// only way to get a 2nd html element on the page is to create it with createElement
// if you try to do it through the html parser it won't work
var root = document.createElement('html');
document.getElementById('additional').append(root);
</script>
<script src="/test/testutils.js"></script>
<script src="html-has-lang-pass.js"></script>
<script src="/test/integration/adapter.js"></script>
Expand Down
7 changes: 7 additions & 0 deletions test/integration/full/html-lang-valid/html-lang-valid.html
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,13 @@
<body>
<iframe id="frame1" src="frames/level1.html"></iframe>
<div id="mocha"></div>
<div id="additional"></div>
<script>
// only way to get a 2nd html element on the page is to create it with createElement
// if you try to do it through the html parser it won't work
var root = document.createElement('html');
document.getElementById('additional').append(root);
</script>
<script src="/test/testutils.js"></script>
<script src="html-lang-valid.js"></script>
<script src="/test/integration/adapter.js"></script>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,13 @@
<p>No main content</p>
<iframe id="frame1" src="frames/level1.html"></iframe>
<div id="mocha"></div>
<div id="additional"></div>
<script>
// only way to get a 2nd html element on the page is to create it with createElement
// if you try to do it through the html parser it won't work
var root = document.createElement('html');
document.getElementById('additional').append(root);
</script>
<script src="/test/testutils.js"></script>
<script src="landmark-one-main-pass1.js"></script>
<script src="/test/integration/adapter.js"></script>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,13 @@
<p>No h1 content</p>
<iframe id="frame1" src="frames/level1.html"></iframe>
<div id="mocha"></div>
<div id="additional"></div>
<script>
// only way to get a 2nd html element on the page is to create it with createElement
// if you try to do it through the html parser it won't work
var root = document.createElement('html');
document.getElementById('additional').append(root);
</script>
<script src="/test/testutils.js"></script>
<script src="page-has-heading-one-pass1.js"></script>
<script src="/test/integration/adapter.js"></script>
Expand Down