Get rid of :has selector (closes #586)

This commit is contained in:
Kamran Ahmed
2026-06-24 09:01:00 +01:00
parent f7b7760506
commit b5105a9225
3 changed files with 67 additions and 1 deletions
+1 -1
View File
@@ -136,7 +136,7 @@
}
/* Disable the scrolling of parent element if it has an active element*/
:not(body):has(> .driver-active-element) {
.driver-active-element-parent {
overflow: hidden !important;
}
+14
View File
@@ -156,6 +156,10 @@ function transferHighlight(toElement: Element, toStep: DriveStep) {
renderPopover(toElement, toStep);
}
document.querySelectorAll(".driver-active-element-parent").forEach(element => {
element.classList.remove("driver-active-element-parent");
});
fromElement.classList.remove("driver-active-element", "driver-no-interaction");
fromElement.removeAttribute("aria-haspopup");
fromElement.removeAttribute("aria-expanded");
@@ -166,6 +170,11 @@ function transferHighlight(toElement: Element, toStep: DriveStep) {
toElement.classList.add("driver-no-interaction");
}
const toParent = toElement.parentElement;
if (toParent && toParent !== document.body) {
toParent.classList.add("driver-active-element-parent");
}
toElement.classList.add("driver-active-element");
toElement.setAttribute("aria-haspopup", "dialog");
toElement.setAttribute("aria-expanded", "true");
@@ -175,6 +184,11 @@ function transferHighlight(toElement: Element, toStep: DriveStep) {
export function destroyHighlight() {
document.getElementById("driver-dummy-element")?.remove();
document.querySelectorAll(".driver-active-element").forEach(element => {
const parent = element.parentElement;
if (parent && parent !== document.body) {
parent.classList.remove("driver-active-element-parent");
}
element.classList.remove("driver-active-element", "driver-no-interaction");
element.removeAttribute("aria-haspopup");
element.removeAttribute("aria-expanded");
+52
View File
@@ -0,0 +1,52 @@
import { describe, expect, it } from "vitest";
import { createDriver, navButton, useDriverHarness } from "./utils";
useDriverHarness();
const PARENT_CLASS = "driver-active-element-parent";
const NESTED_HTML = `
<div id="container-a"><button id="child-a" type="button">A</button></div>
<div id="container-b"><button id="child-b" type="button">B</button></div>
<button id="top-level" type="button">Top</button>
`;
describe("active element parent", () => {
it("locks scrolling on the highlighted element's parent", () => {
document.body.innerHTML = NESTED_HTML;
const d = createDriver({ animate: false, steps: [{ element: "#child-a" }] });
d.drive();
expect(document.getElementById("container-a")?.classList.contains(PARENT_CLASS)).toBe(true);
});
it("moves the lock to the new parent when highlighting a different branch", () => {
document.body.innerHTML = NESTED_HTML;
const d = createDriver({
animate: false,
steps: [{ element: "#child-a" }, { element: "#child-b" }],
});
d.drive();
navButton("next")?.click();
expect(document.getElementById("container-a")?.classList.contains(PARENT_CLASS)).toBe(false);
expect(document.getElementById("container-b")?.classList.contains(PARENT_CLASS)).toBe(true);
});
it("never locks the body element", () => {
document.body.innerHTML = NESTED_HTML;
const d = createDriver({ animate: false, steps: [{ element: "#top-level" }] });
d.drive();
expect(document.body.classList.contains(PARENT_CLASS)).toBe(false);
});
it("releases the lock when the tour is destroyed", () => {
document.body.innerHTML = NESTED_HTML;
const d = createDriver({ animate: false, steps: [{ element: "#child-a" }] });
d.drive();
d.destroy();
expect(document.getElementById("container-a")?.classList.contains(PARENT_CLASS)).toBe(false);
});
});