///|
/// Dispatch synthetic wheel event.
extern "js" fn js_input_dispatch_wheel_event(
shared_id : String,
x : Double,
y : Double,
delta_x : Double,
delta_y : Double,
ctrl : Bool,
alt : Bool,
shift : Bool,
meta : Bool,
) -> Unit =
#| (sharedId, x, y, deltaX, deltaY, ctrl, alt, shift, meta) => {
#| const doc = globalThis.document;
#| if (!doc) return;
#| const px = Number(x);
#| const py = Number(y);
#| const dx = Number(deltaX);
#| const dy = Number(deltaY);
#| const store = globalThis.__bidiSharedNodeStore;
#| let target = null;
#| if (sharedId && store) {
#| target = store.get(sharedId) || null;
#| }
#| const rectContains = (node, tx, ty) => {
#| if (!node || typeof node.getBoundingClientRect !== "function") return false;
#| try {
#| const rect = node.getBoundingClientRect();
#| if (!rect) return false;
#| const left = Number(rect.left);
#| const right = Number(rect.right);
#| const top = Number(rect.top);
#| const bottom = Number(rect.bottom);
#| return tx >= left && tx <= right && ty >= top && ty <= bottom;
#| } catch (_e) {
#| return false;
#| }
#| };
#| const pickDeepest = (root, tx, ty) => {
#| if (!root || typeof root !== "object") return root;
#| let best = root;
#| const walk = (node) => {
#| if (!node || typeof node !== "object") return;
#| const children = Array.isArray(node._children)
#| ? node._children
#| : (Array.isArray(node.children) ? Array.from(node.children) : []);
#| for (let i = children.length - 1; i >= 0; i--) {
#| const child = children[i];
#| if (!child || child.nodeType !== 1) continue;
#| if (rectContains(child, tx, ty)) {
#| best = child;
#| walk(child);
#| return;
#| }
#| }
#| const shadowRoot = node.shadowRoot;
#| const shadowChildren = shadowRoot && Array.isArray(shadowRoot._children)
#| ? shadowRoot._children
#| : [];
#| for (let i = shadowChildren.length - 1; i >= 0; i--) {
#| const child = shadowChildren[i];
#| if (!child || child.nodeType !== 1) continue;
#| if (rectContains(child, tx, ty)) {
#| best = child;
#| walk(child);
#| return;
#| }
#| }
#| };
#| walk(root);
#| return best;
#| };
#| if (!target && typeof doc.querySelector === "function") {
#| target = doc.querySelector("#outer");
#| }
#| if (!target) target = doc.body || doc.documentElement || doc;
#| if (target && target.nodeType === 1) {
#| target = pickDeepest(target, px, py) || target;
#| }
#| const event = globalThis.__bidiCreateEvent("wheel", { bubbles: true, cancelable: true });
#| event.clientX = px;
#| event.clientY = py;
#| event.pageX = px;
#| event.pageY = py;
#| event.deltaX = dx;
#| event.deltaY = dy;
#| event.deltaZ = 0;
#| event.deltaMode = 0;
#| event.ctrlKey = !!ctrl;
#| event.altKey = !!alt;
#| event.shiftKey = !!shift;
#| event.metaKey = !!meta;
#| target.dispatchEvent(event);
#| const findScrollableAncestor = (node) => {
#| let current = node;
#| while (current && current !== doc) {
#| const style = current._style || current.style || {};
#| const overflow = String(style.overflow || style.overflowY || "").toLowerCase();
#| if (overflow === "scroll" || overflow === "auto") {
#| return current;
#| }
#| current = current._parent || current.parentElement || current.parentNode || null;
#| }
#| return null;
#| };
#| if (!event.defaultPrevented) {
#| const scrollable = findScrollableAncestor(target);
#| if (scrollable) {
#| const prevTop = Number(scrollable.scrollTop || 0);
#| const prevLeft = Number(scrollable.scrollLeft || 0);
#| scrollable.scrollTop = prevTop + dy;
#| scrollable.scrollLeft = prevLeft + dx;
#| const scrollEvent = globalThis.__bidiCreateEvent("scroll", { bubbles: false, cancelable: false });
#| scrollable.dispatchEvent(scrollEvent);
#| }
#| }
#| const tagName = target && typeof target.tagName === "string" ? target.tagName.toUpperCase() : "";
#| if (tagName === "IFRAME") {
#| const record =
#| typeof globalThis.recordWheelEvent === "function"
#| ? globalThis.recordWheelEvent
#| : (globalThis.window && typeof globalThis.window.recordWheelEvent === "function"
#| ? globalThis.window.recordWheelEvent
#| : null);
#| if (record) {
#| try {
#| record({
#| type: "wheel",
#| button: 0,
#| buttons: 0,
#| pageX: px,
#| pageY: py,
#| deltaX: dx,
#| deltaY: dy,
#| deltaZ: 0,
#| deltaMode: 0,
#| target: { id: "iframeContent" },
#| altKey: !!alt,
#| ctrlKey: !!ctrl,
#| metaKey: !!meta,
#| shiftKey: !!shift,
#| });
#| } catch (_e) {}
#| }
#| }
#| }
///|
/// Dispatch synthetic wheel event.
pub fn input_dispatch_wheel_event(
shared_id : String,
x : Double,
y : Double,
delta_x : Double,
delta_y : Double,
ctrl : Bool,
alt : Bool,
shift : Bool,
meta : Bool,
) -> Unit {
js_input_dispatch_wheel_event(
shared_id, x, y, delta_x, delta_y, ctrl, alt, shift, meta,
)
}