From f2b6c9dfd27a3c460318eede9c3e1998b5f80418 Mon Sep 17 00:00:00 2001 From: liuguiyuan <875079152@qq.com> Date: Tue, 31 Mar 2026 00:57:44 +0800 Subject: [PATCH 1/3] fix: use hasAttribute with known aria list for interactive candidate detection Replace broken el.hasAttribute("aria-") with a curated list of 27 aria attributes checked via hasAttribute. Each check is O(1). WAI-ARIA 1.2 defines ~50 aria attributes total per MDN. Of these ~27 appear on interactive elements such as buttons, inputs, sliders, and dialogs. The remaining ~20 are structural container attributes like aria-live, aria-colcount, and aria-rowspan that only appear on non-interactive containers. Checking them would not change results. --- .../page-controller/src/dom/dom_tree/index.js | 39 ++++++++++++++++++- 1 file changed, 38 insertions(+), 1 deletion(-) diff --git a/packages/page-controller/src/dom/dom_tree/index.js b/packages/page-controller/src/dom/dom_tree/index.js index 782ad58..9166612 100644 --- a/packages/page-controller/src/dom/dom_tree/index.js +++ b/packages/page-controller/src/dom/dom_tree/index.js @@ -1143,6 +1143,43 @@ export default ( * @param {HTMLElement} element - The element to check. * @returns {boolean} Whether the element is an interactive candidate. */ + const INTERACTIVE_ARIA_ATTRS = [ + 'aria-label', + 'aria-labelledby', + 'aria-describedby', + 'aria-expanded', + 'aria-checked', + 'aria-selected', + 'aria-pressed', + 'aria-hidden', + 'aria-haspopup', + 'aria-controls', + 'aria-owns', + 'aria-current', + 'aria-disabled', + 'aria-live', + 'aria-modal', + 'aria-activedescendant', + 'aria-valuenow', + 'aria-valuetext', + 'aria-valuemax', + 'aria-valuemin', + 'aria-autocomplete', + 'aria-invalid', + 'aria-required', + 'aria-level', + 'aria-sort', + 'aria-orientation', + 'aria-multiline', + ] + + function hasAriaAttribute(el) { + for (let i = 0; i < INTERACTIVE_ARIA_ATTRS.length; i++) { + if (el.hasAttribute(INTERACTIVE_ARIA_ATTRS[i])) return true + } + return false + } + function isInteractiveCandidate(element) { if (!element || element.nodeType !== Node.ELEMENT_NODE) return false @@ -1167,7 +1204,7 @@ export default ( element.hasAttribute('onclick') || element.hasAttribute('role') || element.hasAttribute('tabindex') || - element.hasAttribute('aria-') || + hasAriaAttribute(element) || element.hasAttribute('data-action') || element.getAttribute('contenteditable') === 'true' From 3efef0ec42c9210c22a18a0ee32656328c1759d3 Mon Sep 17 00:00:00 2001 From: Simon <10131203+gaomeng1900@users.noreply.github.com> Date: Thu, 2 Apr 2026 17:33:27 +0800 Subject: [PATCH 2/3] fix(controller): clean up `INTERACTIVE_ARIA_ATTRS` --- .../page-controller/src/dom/dom_tree/index.js | 18 ++---------------- 1 file changed, 2 insertions(+), 16 deletions(-) diff --git a/packages/page-controller/src/dom/dom_tree/index.js b/packages/page-controller/src/dom/dom_tree/index.js index 9166612..ccfdd1b 100644 --- a/packages/page-controller/src/dom/dom_tree/index.js +++ b/packages/page-controller/src/dom/dom_tree/index.js @@ -1144,36 +1144,22 @@ export default ( * @returns {boolean} Whether the element is an interactive candidate. */ const INTERACTIVE_ARIA_ATTRS = [ - 'aria-label', - 'aria-labelledby', - 'aria-describedby', 'aria-expanded', 'aria-checked', 'aria-selected', 'aria-pressed', - 'aria-hidden', 'aria-haspopup', 'aria-controls', 'aria-owns', - 'aria-current', - 'aria-disabled', - 'aria-live', - 'aria-modal', 'aria-activedescendant', 'aria-valuenow', 'aria-valuetext', 'aria-valuemax', 'aria-valuemin', 'aria-autocomplete', - 'aria-invalid', - 'aria-required', - 'aria-level', - 'aria-sort', - 'aria-orientation', - 'aria-multiline', ] - function hasAriaAttribute(el) { + function hasInteractiveAria(el) { for (let i = 0; i < INTERACTIVE_ARIA_ATTRS.length; i++) { if (el.hasAttribute(INTERACTIVE_ARIA_ATTRS[i])) return true } @@ -1204,7 +1190,7 @@ export default ( element.hasAttribute('onclick') || element.hasAttribute('role') || element.hasAttribute('tabindex') || - hasAriaAttribute(element) || + hasInteractiveAria(element) || element.hasAttribute('data-action') || element.getAttribute('contenteditable') === 'true' From bde630f55dee1c90828c81d9942e0ab5980d57e6 Mon Sep 17 00:00:00 2001 From: Simon <10131203+gaomeng1900@users.noreply.github.com> Date: Thu, 2 Apr 2026 17:38:02 +0800 Subject: [PATCH 3/3] chore(controller): add @edit mark --- packages/page-controller/src/dom/dom_tree/index.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/packages/page-controller/src/dom/dom_tree/index.js b/packages/page-controller/src/dom/dom_tree/index.js index ccfdd1b..5f57ff7 100644 --- a/packages/page-controller/src/dom/dom_tree/index.js +++ b/packages/page-controller/src/dom/dom_tree/index.js @@ -18,6 +18,7 @@ * @edit improve `sampleRect`, filter out rects with 0 area * @edit exclude aria-hidden elements * @edit make sure attributes exist for interactive candidates. + * @edit fix "aria-*" attributes check */ export default ( @@ -1143,6 +1144,8 @@ export default ( * @param {HTMLElement} element - The element to check. * @returns {boolean} Whether the element is an interactive candidate. */ + + // @edit fix "aria-*" attributes check const INTERACTIVE_ARIA_ATTRS = [ 'aria-expanded', 'aria-checked',