Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
60 commits
Select commit Hold shift + click to select a range
cda783b
ci: fix release script (#4984)
straker Jan 6, 2026
a167eb9
chore: merge master into develop (#4982)
WilcoFiers Jan 7, 2026
8541f2c
test: fix test:unit (#4989)
straker Jan 13, 2026
9e09139
feat(rules): deprecate landmark-complementary-is-top-level rules (#4992)
chutchins25 Jan 23, 2026
0489e30
fix(aria-valid-attr-value): handle multiple aria-errormessage IDs (#4…
JustasMonkev Jan 26, 2026
4ec5211
fix(scrollable-region-focusable): clarify the issue is in safari (#4995)
WilcoFiers Jan 29, 2026
c528814
chore: sync generated files (#5007)
straker Feb 3, 2026
835e930
ci: fix update-generated-files workflow (#5006)
straker Feb 3, 2026
5761cda
chore: bump globals from 16.5.0 to 17.1.0 (#5005)
dependabot[bot] Feb 3, 2026
c994928
chore: bump jquery from 3.7.1 to 4.0.0 (#5004)
dependabot[bot] Feb 3, 2026
838707a
fix(scrollable-region-focusable): do not fail scroll areas when all c…
straker Feb 5, 2026
b8e6a59
feat(core): expose normalizeRunOptions (#4998)
qazwsxedcrfvtgb1111 Feb 5, 2026
c395424
chore: bump the npm-low-risk group across 1 directory with 8 updates …
dependabot[bot] Feb 5, 2026
0d4e4e7
feat(new-rule): check that aria-tab have an accessible name (#5001)
chutchins25 Feb 16, 2026
0281fa1
fix(DqElement): avoid calling constructors with cloneNode (#5013)
WilcoFiers Feb 18, 2026
48ca955
fix(aria): prevent getOwnedVirtual from returning duplicate nodes (#4…
camiha Feb 18, 2026
a4b8091
fix(target-size): determine offset using clientRects if target is dis…
straker Feb 20, 2026
2067b87
fix(existing-rule): aria-busy now shows an error message for a use wi…
chutchins25 Mar 4, 2026
88c3676
test: fix chromedriver 146 failing to create session (#5026)
straker Mar 7, 2026
133e573
chore: bump jsdom from 27.4.0 to 28.1.0 (#5021)
dependabot[bot] Mar 13, 2026
5c1a55c
chore: bump the npm-low-risk group with 6 updates (#5020)
dependabot[bot] Mar 13, 2026
3af1fb7
chore: add CLAUDE.md and pull request checklist (#5035)
dylanb Mar 19, 2026
a8dd81b
fix(target-size): ignore widgets that are inline with other inline el…
straker Mar 26, 2026
c29b0af
chore: merge master into develop (#5051)
straker Mar 31, 2026
3c35b65
chore: bump actions/download-artifact from 7.0.0 to 8.0.1 (#5056)
dependabot[bot] Apr 1, 2026
b9ffe03
chore: bump actions/upload-artifact from 6.0.0 to 7.0.0 (#5054)
dependabot[bot] Apr 1, 2026
f2b8935
chore: bump the npm-low-risk group with 8 updates (#5053)
dependabot[bot] Apr 1, 2026
c6245e7
fix(aria-allowed-attr): restrict br and wbr elements to aria-hidden o…
nami8824 Apr 7, 2026
be3801e
refactor(frame-messenger): Guard against inherited properties as topi…
RinZ27 Apr 9, 2026
1229a6e
fix(target-size): ignore position: fixed elements that are offscreen …
straker Apr 10, 2026
b329a08
chore: merge master into develop (#5072)
straker Apr 16, 2026
1c15f82
feat(utils): add `getElementInternals` function (#5077)
straker Apr 22, 2026
d1fabaa
fix(utils/getAncestry): escape node name (#5079)
straker Apr 22, 2026
3e49812
chore: fix cherry-pick script buffer size error for large git logs (#…
straker Apr 23, 2026
ea7202c
fix(commons/text): exclude natively hidden elements from aria-labelle…
nami8824 Apr 23, 2026
7d5d363
chore: merge master into develop (#5084)
stephenmathieson Apr 28, 2026
b8e3646
ci(deploy): use gh cli to create github release (#5094)
Garbee May 6, 2026
57cb1ef
chore: code mod to refactor test dir (#5068)
WilcoFiers May 7, 2026
22eae72
chore(utils/is-valid-custom-element-name): helper function to determi…
straker May 7, 2026
417b48a
feat(aria-allowed/prohibited-attr, aria-required-parent/children): pa…
straker May 12, 2026
e1efff1
chore: bump the npm-low-risk group across 1 directory with 8 updates …
dependabot[bot] May 12, 2026
81e975d
chore: bump start-server-and-test from 2.1.5 to 3.0.2 (#5093)
dependabot[bot] May 12, 2026
e823ff1
chore: bump jsdom from 28.1.0 to 29.0.2 (#5092)
dependabot[bot] May 12, 2026
437f491
chore: bump actions/upload-artifact from 7.0.0 to 7.0.1 in the gha-lo…
dependabot[bot] May 12, 2026
3c336f7
chore: bump typescript from 5.9.3 to 6.0.3 (#5090)
dependabot[bot] May 13, 2026
8223c98
fix(aria-conditional-attr): add support for radio (#5100)
mehm8128 May 13, 2026
d423974
chore: add perf timing to runPartial (#5103)
straker May 14, 2026
3a012a1
fix(label-content-name-mismatch): match visible text with aria-label …
mehm8128 May 15, 2026
c61d58b
feat: add gather-internals.js external script (#5099)
straker May 19, 2026
63bab8f
feat(axe.externalAPIs): add public api for setting elementInternal da…
straker May 21, 2026
c2b5292
feat: expose axe.resetLocale() to restore the default locale (#5108)
zlayaAvocado May 21, 2026
c4f60ff
fix(helpUrl): ensure axe.configure always updates the help URLs (#5114)
WilcoFiers May 22, 2026
13005ed
fix(locale): ensure all subtags are correctly set (#5112)
WilcoFiers May 26, 2026
edc6ce2
fix(utils): update isShadowRoot to use spec-compliant custom element …
bwyard May 26, 2026
c01a37d
ci: ignore gather-internals.js from import deploy validation (#5110)
straker May 27, 2026
7d9d696
feat(list,listitem): support element internals role (#5119)
straker May 27, 2026
f12ef32
fix(utils): Add null check to parseCrossOriginStylesheet, closes #507…
dcbroad3 May 27, 2026
c621011
docs(check-options): fix duplicate "the" (passLength/failLength rows)…
adv0r May 28, 2026
75bf772
feat(getRules): include rule enabled state in returned objects (#5118)
pomerantsev May 29, 2026
1e9df5a
chore(release): 4.12.0
attest-team-ci Jun 1, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
37 changes: 37 additions & 0 deletions .github/bin/extract-release-notes.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
#!/usr/bin/env bash

set -eu -o pipefail

# Extracts the body of the most recent release section from CHANGELOG.md —
# everything between the latest version header and the previous one. The
# version header itself is not included. The result is written as a
# multiline `notes` step output to $GITHUB_OUTPUT when set (GitHub
# Actions), otherwise to stdout.
#
# The awk pattern /# \[?[0-9]/ matches version-header lines (`#`, space,
# optional `[`, digit), e.g. `### [4.11.4](...) (2026-04-23)`. The pattern
# is not anchored, so it matches the `# [4` substring inside `###`. On the
# first match it sets `found=1` and skips the line (so the header itself
# is not printed); on the next match (the previous release's header) it
# exits. `found{print}` prints every line in between.
#
# Walking through a typical CHANGELOG.md:
#
# Line v-header? found Action
# -------------------------------- --------- ------ -------
# # Changelog no 0 nothing
# All notable changes... no 0 nothing
# ### [4.11.4](...) (2026-04-23) yes 0 -> 1 skip
# (blank) no 1 print
# ### Bug Fixes no 1 print
# - **commons/text:** ... no 1 print
# - **utils/getAncestry:** ... no 1 print
# ### [4.11.3](...) (2026-04-13) yes 1 exit

repo_root="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"

{
echo 'notes<<EOF'
awk '/# \[?[0-9]/{if(found) exit; found=1; next} found{print}' "$repo_root/CHANGELOG.md"
echo 'EOF'
} >> "${GITHUB_OUTPUT:-/dev/stdout}"
29 changes: 28 additions & 1 deletion .github/bin/validate-package.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -210,7 +210,13 @@ defined files in the \`files\` array of \`package.json\`.
| File | Status | Version |\n|------|--------|--------|
`;

const importTargets = [...pkg.files.map(file => `${pkg.name}/${file}`)];
// these files are not part of the importable api
const nonImportableFiles = ['gather-internals.js'];
const importTargets = [
...pkg.files
.filter(file => !nonImportableFiles.includes(file))
.map(file => `${pkg.name}/${file}`)
];
let anyCaught = false;

console.log('Validating package files are importable:');
Expand Down Expand Up @@ -284,6 +290,27 @@ defined files in the \`files\` array of \`package.json\`.
}
}

// check that the non-importable files are parsable
for (const file of nonImportableFiles) {
const target = `${pkg.name}/${file}`;
try {
const resolved = import.meta.resolve(target);
if (resolved.includes('node_modules')) {
console.error(`✗ ${target} resolves to node_modules`);
summary += `| \`${target}\` | ✗ Resolves to node_modules |\n`;
exitCode++;
continue;
}
execSync(`node --check "${fileURLToPath(resolved)}"`, { stdio: 'pipe' });
console.info(`✓ ${target} (parse-only, browser-only)`);
summary += `| \`${target}\` | ✓ Parse OK (browser-only) | n/a |\n`;
} catch (error) {
console.error(`✗ ${target}: ${error.message}`);
summary += `| \`${target}\` | ✗ Parse failed (browser-only) | n/a |\n`;
exitCode++;
}
}

if (anyCaught) {
exitCode++;
}
Expand Down
19 changes: 11 additions & 8 deletions .github/workflows/deploy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -166,16 +166,19 @@ jobs:
contents: write # Required to create releases
steps:
- *checkout
- name: Install Release Helper
run: go install gopkg.in/aktau/github-release.v0@latest
- name: Download Release Script
run: curl https://raw.githubusercontent.com/dequelabs/attest-release-scripts/develop/src/node-github-release.sh -s -o ./node-github-release.sh
- name: Make Release Script Executable
run: chmod +x ./node-github-release.sh
- name: Extract release notes
id: release-notes
run: ./.github/bin/extract-release-notes.sh
- name: Create GitHub Release
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: ./node-github-release.sh
GH_TOKEN: ${{ github.token }}
VERSION: ${{ needs.prod-deploy.outputs.version }}
NOTES: ${{ steps.release-notes.outputs.notes }}
run: |
gh release create "v${VERSION}" \
--title "Release ${VERSION}" \
--target ${{ github.sha }} \
--notes "$NOTES"
validate-deploy:
name: Validate Deployment
needs: prod-deploy
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ jobs:
run: |
npm run prepare
npm run build
- uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
- uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: axe-core
path: axe.js
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ test/integration/*/index.html
# dist
axe.js
axe.*.js
/gather-internals.js

# generated src file
lib/core/base/metadata-function-map.js
Expand Down
36 changes: 36 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,42 @@

All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.

## [4.12.0](https://github.com/dequelabs/axe-core/compare/v4.11.4...v4.12.0) (2026-06-01)

### Features

- add gather-internals.js external script ([#5099](https://github.com/dequelabs/axe-core/issues/5099)) ([c61d58b](https://github.com/dequelabs/axe-core/commit/c61d58b40d87f81152526edcea67292aa7e3ae1d)), closes [#5080](https://github.com/dequelabs/axe-core/issues/5080)
- **aria-allowed/prohibited-attr, aria-required-parent/children:** partially support element internals role ([#5080](https://github.com/dequelabs/axe-core/issues/5080)) ([417b48a](https://github.com/dequelabs/axe-core/commit/417b48a0d60f0c01ce81e69cc50c2c59e45aa4de)), closes [#5039](https://github.com/dequelabs/axe-core/issues/5039) [#4259](https://github.com/dequelabs/axe-core/issues/4259)
- **axe.externalAPIs:** add public api for setting elementInternal data ([#5105](https://github.com/dequelabs/axe-core/issues/5105)) ([63bab8f](https://github.com/dequelabs/axe-core/commit/63bab8fec82817849a8e69b7cd00f1c1bf3ddf6e))
- **core:** expose normalizeRunOptions ([#4998](https://github.com/dequelabs/axe-core/issues/4998)) ([b8e6a59](https://github.com/dequelabs/axe-core/commit/b8e6a5943f3d7613e770f36dd15fdb27621ca18c))
- expose axe.resetLocale() to restore the default locale ([#5108](https://github.com/dequelabs/axe-core/issues/5108)) ([c2b5292](https://github.com/dequelabs/axe-core/commit/c2b5292397727e1f9d63ae1675db447a5cf58a23)), closes [#5107](https://github.com/dequelabs/axe-core/issues/5107)
- **getRules:** include rule enabled state in returned objects ([#5118](https://github.com/dequelabs/axe-core/issues/5118)) ([75bf772](https://github.com/dequelabs/axe-core/commit/75bf772d47ec1cc6027de55b47aaa63ffef171da)), closes [#5116](https://github.com/dequelabs/axe-core/issues/5116)
- **list,listitem:** support element internals role ([#5119](https://github.com/dequelabs/axe-core/issues/5119)) ([7d9d696](https://github.com/dequelabs/axe-core/commit/7d9d69678df257ee72b962d45371ae27e3aa82ca))
- **new-rule:** check that aria-tab have an accessible name ([#5001](https://github.com/dequelabs/axe-core/issues/5001)) ([0d4e4e7](https://github.com/dequelabs/axe-core/commit/0d4e4e70aa9f46519eb6000744e043c058fd994e)), closes [#4842](https://github.com/dequelabs/axe-core/issues/4842)
- **rules:** deprecate landmark-complementary-is-top-level rules ([#4992](https://github.com/dequelabs/axe-core/issues/4992)) ([9e09139](https://github.com/dequelabs/axe-core/commit/9e091391189dba452ea485275609120e1e6ae8ba)), closes [#4950](https://github.com/dequelabs/axe-core/issues/4950)
- **utils:** add `getElementInternals` function ([#5077](https://github.com/dequelabs/axe-core/issues/5077)) ([1c15f82](https://github.com/dequelabs/axe-core/commit/1c15f8224a184d3c0da95942e99d9d73ad5645c0))

### Bug Fixes

- **aria-allowed-attr:** restrict br and wbr elements to aria-hidden only ([#4974](https://github.com/dequelabs/axe-core/issues/4974)) ([c6245e7](https://github.com/dequelabs/axe-core/commit/c6245e7aee824434fcdae3c77c24365493dbe4be))
- **aria-conditional-attr:** add support for radio ([#5100](https://github.com/dequelabs/axe-core/issues/5100)) ([8223c98](https://github.com/dequelabs/axe-core/commit/8223c989ff4fd2b8002f4961a8ee005a371f39cc))
- **aria-valid-attr-value:** handle multiple aria-errormessage IDs ([#4973](https://github.com/dequelabs/axe-core/issues/4973)) ([0489e30](https://github.com/dequelabs/axe-core/commit/0489e30aad3d80790d8fb9cf5b1807d7c3a2179f))
- **aria:** prevent getOwnedVirtual from returning duplicate nodes ([#4987](https://github.com/dequelabs/axe-core/issues/4987)) ([48ca955](https://github.com/dequelabs/axe-core/commit/48ca9554e2f0400caeec55c09aa100cbb415422d)), closes [#4840](https://github.com/dequelabs/axe-core/issues/4840)
- **commons/text:** exclude natively hidden elements from aria-labelledby accessible name ([#5076](https://github.com/dequelabs/axe-core/issues/5076)) ([ea7202c](https://github.com/dequelabs/axe-core/commit/ea7202c6bf1a6166c878dbf19bb5454372b61fae)), closes [#4704](https://github.com/dequelabs/axe-core/issues/4704)
- **DqElement:** avoid calling constructors with cloneNode ([#5013](https://github.com/dequelabs/axe-core/issues/5013)) ([0281fa1](https://github.com/dequelabs/axe-core/commit/0281fa16f7110b793ac8b3b5b46f93e81be75ee4))
- **existing-rule:** aria-busy now shows an error message for a use with unallowed children ([#5017](https://github.com/dequelabs/axe-core/issues/5017)) ([2067b87](https://github.com/dequelabs/axe-core/commit/2067b87195552daa3065be7aca1aa2a02c135f28))
- **helpUrl:** ensure axe.configure always updates the help URLs ([#5114](https://github.com/dequelabs/axe-core/issues/5114)) ([c4f60ff](https://github.com/dequelabs/axe-core/commit/c4f60ffcd47eb64514e8cbafbc68ad357ce60e77))
- **label-content-name-mismatch:** match visible text with aria-label and exclude invisible text ([#5096](https://github.com/dequelabs/axe-core/issues/5096)) ([3a012a1](https://github.com/dequelabs/axe-core/commit/3a012a141f56b76d6a58fcfb01598ba45e91a442))
- **locale:** ensure all subtags are correctly set ([#5112](https://github.com/dequelabs/axe-core/issues/5112)) ([13005ed](https://github.com/dequelabs/axe-core/commit/13005eda098db154f3d78df3923ed85389344353))
- **scrollable-region-focusable:** clarify the issue is in safari ([#4995](https://github.com/dequelabs/axe-core/issues/4995)) ([4ec5211](https://github.com/dequelabs/axe-core/commit/4ec52112b67b1b44f82b3eade1825789ee8cb659)), closes [WebKit#190870](https://github.com/dequelabs/WebKit/issues/190870) [WebKit#277290](https://github.com/dequelabs/WebKit/issues/277290)
- **scrollable-region-focusable:** do not fail scroll areas when all content is visible without scrolling ([#4993](https://github.com/dequelabs/axe-core/issues/4993)) ([838707a](https://github.com/dequelabs/axe-core/commit/838707a8f224907042221bbf6fb28d6ad59d7cb0))
- **target-size:** determine offset using clientRects if target is display:inline ([#5012](https://github.com/dequelabs/axe-core/issues/5012)) ([a4b8091](https://github.com/dequelabs/axe-core/commit/a4b809183f43c4296a3ec57cd80d8a8f34743361))
- **target-size:** ignore position: fixed elements that are offscreen when page is scrolled ([#5066](https://github.com/dequelabs/axe-core/issues/5066)) ([1229a6e](https://github.com/dequelabs/axe-core/commit/1229a6e7162768a283f5e2307024dee0d0566452)), closes [#5065](https://github.com/dequelabs/axe-core/issues/5065)
- **target-size:** ignore widgets that are inline with other inline elements ([#5000](https://github.com/dequelabs/axe-core/issues/5000)) ([a8dd81b](https://github.com/dequelabs/axe-core/commit/a8dd81be759c670203784acf7b1894257df5457c))
- **utils/getAncestry:** escape node name ([#5079](https://github.com/dequelabs/axe-core/issues/5079)) ([d1fabaa](https://github.com/dequelabs/axe-core/commit/d1fabaad99b1b055b2436a0c3efc22cb66df3934)), closes [#5078](https://github.com/dequelabs/axe-core/issues/5078)
- **utils:** Add null check to parseCrossOriginStylesheet, closes [#5074](https://github.com/dequelabs/axe-core/issues/5074) ([#5075](https://github.com/dequelabs/axe-core/issues/5075)) ([f12ef32](https://github.com/dequelabs/axe-core/commit/f12ef32554deb116238ac29d854ad8e46baa9adb))
- **utils:** update isShadowRoot to use spec-compliant custom element regex ([#5059](https://github.com/dequelabs/axe-core/issues/5059)) ([edc6ce2](https://github.com/dequelabs/axe-core/commit/edc6ce2815b79a976bdb654bd8062f28132a3cdd)), closes [#5030](https://github.com/dequelabs/axe-core/issues/5030)

### [4.11.4](https://github.com/dequelabs/axe-core/compare/v4.11.3...v4.11.4) (2026-04-23)

### Bug Fixes
Expand Down
33 changes: 33 additions & 0 deletions Gruntfile.js
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,39 @@ module.exports = function (grunt) {
cwd: 'lib/core',
src: ['core.js'],
dest: 'tmp/core'
},
// build so we can test it by itself
{
expand: true,
cwd: 'lib/gather-internals',
src: ['walk-tree.js'],
dest: 'tmp/',
options: {
globalName: '_gatherInternals'
}
},
{
expand: true,
src: ['lib/gather-internals/main.js'],
dest: './',
options: {
outfile: 'gather-internals.js',
// esbuild doesn't support returning from an iife so we'll have to do a bit of a hack to make it work
// @see https://github.com/evanw/esbuild/issues/2277
banner: {
js: '(() => {'
},
footer: {
js: `return elementInternalsMap;
})();`
},
globalName: 'elementInternalsMap',
metafile: true
},
validateImports: {
max: 10,
maxSize: 4000
}
}
]
}
Expand Down
40 changes: 39 additions & 1 deletion axe.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,9 @@ declare namespace axe {
performanceTimer?: boolean;
pingWaitTime?: number;
}
interface NormalizedRunOptions extends RunOptions {
runOnly?: RunOnly;
}
interface PreloadOptions {
assets: string[];
timeout?: number;
Expand Down Expand Up @@ -331,7 +334,7 @@ declare namespace axe {
matches?: string | ((node: Element, virtualNode: VirtualNode) => boolean);
reviewOnFail?: boolean;
actIds?: string[];
metadata?: Omit<RuleMetadata, 'ruleId' | 'tags' | 'actIds'>;
metadata?: Omit<RuleMetadata, 'ruleId' | 'tags' | 'actIds' | 'enabled'>;
}
interface AxePlugin {
id: string;
Expand All @@ -349,6 +352,7 @@ declare namespace axe {
helpUrl: string;
tags: string[];
actIds?: string[];
enabled: boolean;
}
interface SerialDqElement {
source: string;
Expand Down Expand Up @@ -501,6 +505,7 @@ declare namespace axe {
offset?: number
) => string | Uint8Array | Array<number>;
nodeSerializer: NodeSerializer;
normalizeRunOptions: (options?: RunOptions) => NormalizedRunOptions;
}

interface Aria {
Expand Down Expand Up @@ -625,6 +630,14 @@ declare namespace axe {
*/
function reset(): void;

/**
* Restores the default locale that was active before any
* `axe.configure({ locale })` call. No-op if no non-default
* locale has ever been applied. Does not affect any other
* configuration.
*/
function resetLocale(): void;

/**
* Function to register a plugin configuration in document and its subframes
* @param {Object} plugin A plugin configuration object
Expand Down Expand Up @@ -670,6 +683,31 @@ declare namespace axe {
isDefault?: boolean
): void;

/**
* Run axe in the current window only
* @param {ElementContext} context Optional The `Context` specification object @see Context
* @param {RunOptions} options Optional Options passed into rules or checks, temporarily modifying them.
* @returns {Promise<PartialResult>} Partial result, for use in axe.finishRun.
*/
function externalAPIs(params?: {
elementInternalsTimeout?: number;
getElementInternals?: () => Promise<ElementInternalsMap>;
}): void;

type ElementInternalsMap = Array<{
ancestry: CrossTreeSelector;
internals: Record<string, InternalsData>;
}>;
type InternalsData = string | InternalsDataIdref | InternalsDataIdrefs;
type InternalsDataIdref = {
type: 'HTMLElement';
value: CrossTreeSelector;
};
type InternalsDataIdrefs = {
type: 'NodeList';
value: CrossTreeSelector[];
};

// axe.frameMessenger
type FrameMessenger = {
open: (topicHandler: TopicHandler) => Close | void;
Expand Down
2 changes: 1 addition & 1 deletion bower.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "axe-core",
"version": "4.11.4",
"version": "4.12.0",
"deprecated": true,
"contributors": [
{
Expand Down
26 changes: 24 additions & 2 deletions build/tasks/esbuild.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
const { build } = require('esbuild');
const path = require('path');
const assert = require('assert');

module.exports = function (grunt) {
grunt.registerMultiTask(
Expand All @@ -12,6 +13,7 @@ module.exports = function (grunt) {
files.forEach(file => {
const src = Array.isArray(file.src) ? file.src : [file.src];
const dest = file.dest;
const options = file.options || {};

src.forEach(entry => {
const name = path.basename(entry);
Expand All @@ -23,9 +25,29 @@ module.exports = function (grunt) {
entryPoints: [entry],
outfile: path.join(dest, name),
minify: false,
bundle: true
bundle: true,
...options
})
.then(done)
.then(result => {
if (options.metafile && file.validateImports) {
const { max, maxSize } = file.validateImports;
const { inputs } = result.metafile;
const entries = Object.entries(inputs);

assert(
entries.length <= max,
`${entry} imported too many files (max: ${max}): ${entries.length}`
);
for (const [key, value] of entries) {
assert(
value.bytes <= maxSize,
`${key} import size too large (max: ${maxSize}): ${value.bytes}`
);
}
}

done(result);
})
.catch(e => {
grunt.fail.fatal(e);
done();
Expand Down
Loading
Loading