Some checks are pending
Tests & Quality Checks / Test on Python 3.11 (push) Waiting to run
Tests & Quality Checks / Test on Python 3.12 (push) Waiting to run
Tests & Quality Checks / Test on Python 3.11-1 (push) Waiting to run
Tests & Quality Checks / Test on Python 3.12-1 (push) Waiting to run
Tests & Quality Checks / Test on Python 3.10 (push) Waiting to run
Tests & Quality Checks / Test on Python 3.11-2 (push) Waiting to run
Tests & Quality Checks / Test on Python 3.12-2 (push) Waiting to run
Tests & Quality Checks / Build Artifacts (push) Blocked by required conditions
Tests & Quality Checks / Build Artifacts-1 (push) Blocked by required conditions
186 lines
5.4 KiB
JavaScript
186 lines
5.4 KiB
JavaScript
// Mouse Event Emulator for Qt WebEngineView
|
|
// Qt WebEngineView may not forward all mouse events to JavaScript properly
|
|
// This script uses polling with document.elementFromPoint() to detect hover changes
|
|
// and manually dispatches mouseover/mouseenter/mouseleave events.
|
|
// ALSO: Injects a CSS stylesheet that simulates :hover effects using classes
|
|
|
|
(function() {
|
|
try {
|
|
if (window.__mouse_emulator_injected) return;
|
|
window.__mouse_emulator_injected = true;
|
|
|
|
console.log("[MouseEventEmulator] Initialized - polling for hover state changes");
|
|
|
|
// ========================================================
|
|
// PART 1: Inject CSS stylesheet for hover simulation
|
|
// ========================================================
|
|
|
|
var style = document.createElement("style");
|
|
style.type = "text/css";
|
|
style.id = "__mouse_emulator_hover_styles";
|
|
style.innerHTML = `
|
|
/* Checkbox hover simulation */
|
|
input[type="checkbox"].__mouse_hover {
|
|
cursor: pointer;
|
|
}
|
|
|
|
/* Link hover simulation */
|
|
a.__mouse_hover {
|
|
text-decoration: underline;
|
|
}
|
|
`;
|
|
|
|
if (document.head) {
|
|
document.head.insertBefore(style, document.head.firstChild);
|
|
} else {
|
|
document.body.insertBefore(style, document.body.firstChild);
|
|
}
|
|
|
|
// ========================================================
|
|
// PART 2: Track hover state and apply hover class
|
|
// ========================================================
|
|
|
|
var lastElement = null;
|
|
var lastX = -1;
|
|
var lastY = -1;
|
|
|
|
// High-frequency polling to detect element changes at mouse position
|
|
var pollIntervalId = setInterval(function() {
|
|
if (!window.__lastMousePos) {
|
|
window.__lastMousePos = { x: 0, y: 0 };
|
|
}
|
|
|
|
var x = window.__lastMousePos.x;
|
|
var y = window.__lastMousePos.y;
|
|
|
|
lastX = x;
|
|
lastY = y;
|
|
|
|
var element = document.elementFromPoint(x, y);
|
|
|
|
if (!element || element === document || element.tagName === "HTML") {
|
|
if (lastElement && lastElement !== document) {
|
|
try {
|
|
lastElement.classList.remove("__mouse_hover");
|
|
var leaveEvent = new MouseEvent("mouseleave", {
|
|
bubbles: true,
|
|
cancelable: true,
|
|
view: window,
|
|
});
|
|
lastElement.dispatchEvent(leaveEvent);
|
|
} catch (err) {
|
|
console.warn("[MouseEventEmulator] Error in leave handler:", err);
|
|
}
|
|
lastElement = null;
|
|
}
|
|
return;
|
|
}
|
|
|
|
// Element changed
|
|
if (element !== lastElement) {
|
|
// Remove hover class from previous element
|
|
if (lastElement && lastElement !== document && lastElement !== element) {
|
|
try {
|
|
lastElement.classList.remove("__mouse_hover");
|
|
var leaveEvent = new MouseEvent("mouseleave", {
|
|
bubbles: true,
|
|
cancelable: true,
|
|
view: window,
|
|
clientX: x,
|
|
clientY: y,
|
|
});
|
|
lastElement.dispatchEvent(leaveEvent);
|
|
} catch (err) {
|
|
console.warn("[MouseEventEmulator] Error dispatching mouseleave:", err);
|
|
}
|
|
}
|
|
|
|
// Add hover class and dispatch events for new element
|
|
if (element) {
|
|
try {
|
|
element.classList.add("__mouse_hover");
|
|
|
|
var overEvent = new MouseEvent("mouseover", {
|
|
bubbles: true,
|
|
cancelable: true,
|
|
view: window,
|
|
clientX: x,
|
|
clientY: y,
|
|
});
|
|
element.dispatchEvent(overEvent);
|
|
|
|
var enterEvent = new MouseEvent("mouseenter", {
|
|
bubbles: false,
|
|
cancelable: true,
|
|
view: window,
|
|
clientX: x,
|
|
clientY: y,
|
|
});
|
|
element.dispatchEvent(enterEvent);
|
|
|
|
var moveEvent = new MouseEvent("mousemove", {
|
|
bubbles: true,
|
|
cancelable: true,
|
|
view: window,
|
|
clientX: x,
|
|
clientY: y,
|
|
});
|
|
element.dispatchEvent(moveEvent);
|
|
} catch (err) {
|
|
console.warn("[MouseEventEmulator] Error dispatching mouse events:", err);
|
|
}
|
|
}
|
|
|
|
lastElement = element;
|
|
}
|
|
}, 50);
|
|
|
|
// Track mouse position from all available events
|
|
document.addEventListener(
|
|
"mousemove",
|
|
function(e) {
|
|
window.__lastMousePos = { x: e.clientX, y: e.clientY };
|
|
},
|
|
true
|
|
);
|
|
|
|
document.addEventListener(
|
|
"mousedown",
|
|
function(e) {
|
|
window.__lastMousePos = { x: e.clientX, y: e.clientY };
|
|
},
|
|
true
|
|
);
|
|
|
|
document.addEventListener(
|
|
"mouseup",
|
|
function(e) {
|
|
window.__lastMousePos = { x: e.clientX, y: e.clientY };
|
|
},
|
|
true
|
|
);
|
|
|
|
document.addEventListener(
|
|
"mouseover",
|
|
function(e) {
|
|
window.__lastMousePos = { x: e.clientX, y: e.clientY };
|
|
},
|
|
true
|
|
);
|
|
|
|
document.addEventListener(
|
|
"mouseenter",
|
|
function(e) {
|
|
window.__lastMousePos = { x: e.clientX, y: e.clientY };
|
|
},
|
|
true
|
|
);
|
|
|
|
console.log("[MouseEventEmulator] Ready - polling enabled for hover state detection");
|
|
} catch (e) {
|
|
console.error("[MouseEventEmulator] FATAL ERROR:", e);
|
|
if (e.stack) {
|
|
console.error("[MouseEventEmulator] Stack:", e.stack);
|
|
}
|
|
}
|
|
})();
|