donobu 5.52.2 → 5.52.3
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.
|
@@ -933,24 +933,22 @@ class PageInspector {
|
|
|
933
933
|
if (document.scrollingElement) {
|
|
934
934
|
maybeAddScrollable(document.scrollingElement);
|
|
935
935
|
}
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
// Skip if this element already carries a value (e.g. assigned via <label>)
|
|
946
|
-
return;
|
|
936
|
+
/**
|
|
937
|
+
* Run the visibility / enabled / top-most checks on a single element and,
|
|
938
|
+
* if they pass, assign it the next interactable number. Returns `true` if
|
|
939
|
+
* the element (or, via the <label htmlFor> mapping, its associated control)
|
|
940
|
+
* was attributed.
|
|
941
|
+
*/
|
|
942
|
+
function tryAttributeElement(element) {
|
|
943
|
+
if (element.hasAttribute(interactableAttribute)) {
|
|
944
|
+
return false;
|
|
947
945
|
}
|
|
948
946
|
const rect = element.getBoundingClientRect();
|
|
949
947
|
const style = window.getComputedStyle(element);
|
|
950
948
|
const visible = isElementVisible(rect, style) && isElementMoreThanHalfInViewport(rect);
|
|
951
949
|
const enabled = isElementEnabled(element, style);
|
|
952
950
|
if (!visible || !enabled) {
|
|
953
|
-
return;
|
|
951
|
+
return false;
|
|
954
952
|
}
|
|
955
953
|
// Check a few probe points to make sure the element is top-most
|
|
956
954
|
for (const pt of getPointsToCheck(rect)) {
|
|
@@ -959,9 +957,9 @@ class PageInspector {
|
|
|
959
957
|
if (elToCheck === element) {
|
|
960
958
|
element.setAttribute(interactableAttribute, offset.toString());
|
|
961
959
|
offset++;
|
|
962
|
-
return; // this element done
|
|
960
|
+
return true; // this element done
|
|
963
961
|
}
|
|
964
|
-
// Handle <label> -> control mapping
|
|
962
|
+
// Handle <label> -> control mapping (explicit `for`/`htmlFor`)
|
|
965
963
|
if (elToCheck.tagName.toLowerCase() === 'label' &&
|
|
966
964
|
elToCheck.htmlFor) {
|
|
967
965
|
const forId = elToCheck.htmlFor;
|
|
@@ -972,11 +970,41 @@ class PageInspector {
|
|
|
972
970
|
control.setAttribute(interactableAttribute, offset.toString());
|
|
973
971
|
offset++;
|
|
974
972
|
}
|
|
975
|
-
return;
|
|
973
|
+
return true;
|
|
976
974
|
}
|
|
977
975
|
elToCheck = elToCheck.parentElement;
|
|
978
976
|
}
|
|
979
977
|
}
|
|
978
|
+
return false;
|
|
979
|
+
}
|
|
980
|
+
// 2) Iterate and assign numbers
|
|
981
|
+
uniqueElements.forEach((element) => {
|
|
982
|
+
if (element === document.scrollingElement) {
|
|
983
|
+
// Special-case: always keep the root scrolling element
|
|
984
|
+
element.setAttribute(interactableAttribute, offset.toString());
|
|
985
|
+
offset++;
|
|
986
|
+
return; // skip the usual checks
|
|
987
|
+
}
|
|
988
|
+
else if (element.hasAttribute(interactableAttribute)) {
|
|
989
|
+
// Skip if this element already carries a value (e.g. assigned via <label>)
|
|
990
|
+
return;
|
|
991
|
+
}
|
|
992
|
+
if (tryAttributeElement(element)) {
|
|
993
|
+
return;
|
|
994
|
+
}
|
|
995
|
+
// Fallback: the element is a visually-hidden native control (e.g. a 0x0,
|
|
996
|
+
// opacity-0, pointer-events:none <input>) wrapped in a styled <label>.
|
|
997
|
+
// This is the standard pattern for Ant Design Segmented/Radio/Checkbox/
|
|
998
|
+
// Switch and many other component libraries: the native input is hidden
|
|
999
|
+
// and the surrounding <label> is the real clickable surface. Since the
|
|
1000
|
+
// hidden control fails the visibility/enabled checks above, attribute the
|
|
1001
|
+
// wrapping <label> instead so the toggle is still annotated.
|
|
1002
|
+
const wrappingLabel = element.closest('label');
|
|
1003
|
+
if (wrappingLabel &&
|
|
1004
|
+
wrappingLabel !== element &&
|
|
1005
|
+
!wrappingLabel.hasAttribute(interactableAttribute)) {
|
|
1006
|
+
tryAttributeElement(wrappingLabel);
|
|
1007
|
+
}
|
|
980
1008
|
});
|
|
981
1009
|
return offset;
|
|
982
1010
|
}
|
|
@@ -933,24 +933,22 @@ class PageInspector {
|
|
|
933
933
|
if (document.scrollingElement) {
|
|
934
934
|
maybeAddScrollable(document.scrollingElement);
|
|
935
935
|
}
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
// Skip if this element already carries a value (e.g. assigned via <label>)
|
|
946
|
-
return;
|
|
936
|
+
/**
|
|
937
|
+
* Run the visibility / enabled / top-most checks on a single element and,
|
|
938
|
+
* if they pass, assign it the next interactable number. Returns `true` if
|
|
939
|
+
* the element (or, via the <label htmlFor> mapping, its associated control)
|
|
940
|
+
* was attributed.
|
|
941
|
+
*/
|
|
942
|
+
function tryAttributeElement(element) {
|
|
943
|
+
if (element.hasAttribute(interactableAttribute)) {
|
|
944
|
+
return false;
|
|
947
945
|
}
|
|
948
946
|
const rect = element.getBoundingClientRect();
|
|
949
947
|
const style = window.getComputedStyle(element);
|
|
950
948
|
const visible = isElementVisible(rect, style) && isElementMoreThanHalfInViewport(rect);
|
|
951
949
|
const enabled = isElementEnabled(element, style);
|
|
952
950
|
if (!visible || !enabled) {
|
|
953
|
-
return;
|
|
951
|
+
return false;
|
|
954
952
|
}
|
|
955
953
|
// Check a few probe points to make sure the element is top-most
|
|
956
954
|
for (const pt of getPointsToCheck(rect)) {
|
|
@@ -959,9 +957,9 @@ class PageInspector {
|
|
|
959
957
|
if (elToCheck === element) {
|
|
960
958
|
element.setAttribute(interactableAttribute, offset.toString());
|
|
961
959
|
offset++;
|
|
962
|
-
return; // this element done
|
|
960
|
+
return true; // this element done
|
|
963
961
|
}
|
|
964
|
-
// Handle <label> -> control mapping
|
|
962
|
+
// Handle <label> -> control mapping (explicit `for`/`htmlFor`)
|
|
965
963
|
if (elToCheck.tagName.toLowerCase() === 'label' &&
|
|
966
964
|
elToCheck.htmlFor) {
|
|
967
965
|
const forId = elToCheck.htmlFor;
|
|
@@ -972,11 +970,41 @@ class PageInspector {
|
|
|
972
970
|
control.setAttribute(interactableAttribute, offset.toString());
|
|
973
971
|
offset++;
|
|
974
972
|
}
|
|
975
|
-
return;
|
|
973
|
+
return true;
|
|
976
974
|
}
|
|
977
975
|
elToCheck = elToCheck.parentElement;
|
|
978
976
|
}
|
|
979
977
|
}
|
|
978
|
+
return false;
|
|
979
|
+
}
|
|
980
|
+
// 2) Iterate and assign numbers
|
|
981
|
+
uniqueElements.forEach((element) => {
|
|
982
|
+
if (element === document.scrollingElement) {
|
|
983
|
+
// Special-case: always keep the root scrolling element
|
|
984
|
+
element.setAttribute(interactableAttribute, offset.toString());
|
|
985
|
+
offset++;
|
|
986
|
+
return; // skip the usual checks
|
|
987
|
+
}
|
|
988
|
+
else if (element.hasAttribute(interactableAttribute)) {
|
|
989
|
+
// Skip if this element already carries a value (e.g. assigned via <label>)
|
|
990
|
+
return;
|
|
991
|
+
}
|
|
992
|
+
if (tryAttributeElement(element)) {
|
|
993
|
+
return;
|
|
994
|
+
}
|
|
995
|
+
// Fallback: the element is a visually-hidden native control (e.g. a 0x0,
|
|
996
|
+
// opacity-0, pointer-events:none <input>) wrapped in a styled <label>.
|
|
997
|
+
// This is the standard pattern for Ant Design Segmented/Radio/Checkbox/
|
|
998
|
+
// Switch and many other component libraries: the native input is hidden
|
|
999
|
+
// and the surrounding <label> is the real clickable surface. Since the
|
|
1000
|
+
// hidden control fails the visibility/enabled checks above, attribute the
|
|
1001
|
+
// wrapping <label> instead so the toggle is still annotated.
|
|
1002
|
+
const wrappingLabel = element.closest('label');
|
|
1003
|
+
if (wrappingLabel &&
|
|
1004
|
+
wrappingLabel !== element &&
|
|
1005
|
+
!wrappingLabel.hasAttribute(interactableAttribute)) {
|
|
1006
|
+
tryAttributeElement(wrappingLabel);
|
|
1007
|
+
}
|
|
980
1008
|
});
|
|
981
1009
|
return offset;
|
|
982
1010
|
}
|