(() => {
if (window.__drissionRecInstalled) return;
window.__drissionRecInstalled = true;
const esc = (s) =>
window.CSS && CSS.escape ? CSS.escape(s) : String(s).replace(/[^a-zA-Z0-9_-]/g, "\\$&");
const uniqIn = (doc, sel) => {
try {
return doc.querySelectorAll(sel).length === 1;
} catch (e) {
return false;
}
};
function selectorForIn(el, doc) {
if (el.id && uniqIn(doc, "#" + esc(el.id))) return "#" + el.id;
const nm = el.getAttribute && el.getAttribute("name");
if (nm && uniqIn(doc, el.tagName.toLowerCase() + '[name="' + nm + '"]')) return "@name:" + nm;
const parts = [];
let cur = el;
while (cur && cur.nodeType === 1 && cur !== doc.documentElement) {
if (cur.id && uniqIn(doc, "#" + esc(cur.id))) {
parts.unshift("#" + cur.id);
break;
}
let sel = cur.tagName.toLowerCase();
const par = cur.parentElement;
if (par) {
const same = Array.prototype.filter.call(par.children, (c) => c.tagName === cur.tagName);
if (same.length > 1) sel += ":nth-of-type(" + (same.indexOf(cur) + 1) + ")";
}
parts.unshift(sel);
cur = cur.parentElement;
}
return "css:" + parts.join(" > ");
}
const selectorFor = (el) => selectorForIn(el, document);
const frameSelector = () => {
try {
const fe = window.frameElement;
return fe ? selectorForIn(fe, fe.ownerDocument) : null;
} catch (e) {
return null; }
};
const send = (a) => {
try {
const f = frameSelector();
if (f) a.frame = f;
if (window.__drission_record) window.__drission_record(JSON.stringify(a));
} catch (e) {}
};
const isTextInput = (el) => {
if (el.tagName === "TEXTAREA") return true;
if (el.tagName !== "INPUT") return false;
const t = (el.getAttribute("type") || "text").toLowerCase();
return ["text", "password", "email", "search", "tel", "url", "number"].includes(t);
};
let dndFrom = null;
let down = null;
let suppressClickUntil = 0;
document.addEventListener(
"click",
(e) => {
if (Date.now() < suppressClickUntil) return; const el = e.target;
if (!el || el.nodeType !== 1) return;
const tag = el.tagName.toLowerCase();
if (tag === "select") return;
if (isTextInput(el)) return;
if (tag === "input") {
const t = (el.getAttribute("type") || "text").toLowerCase();
if (t === "checkbox" || t === "radio") return;
}
send({ type: "click", selector: selectorFor(el), tag: tag });
},
true
);
document.addEventListener(
"change",
(e) => {
const el = e.target;
if (!el || el.nodeType !== 1) return;
const tag = el.tagName.toLowerCase();
if (tag === "select") {
send({ type: "select", selector: selectorFor(el), value: el.value });
return;
}
if (tag === "input") {
const t = (el.getAttribute("type") || "text").toLowerCase();
if (t === "checkbox" || t === "radio") {
send({ type: "check", selector: selectorFor(el), checked: !!el.checked });
return;
}
}
if (isTextInput(el)) {
send({ type: "fill", selector: selectorFor(el), value: el.value != null ? String(el.value) : "" });
}
},
true
);
document.addEventListener(
"keydown",
(e) => {
if (e.key !== "Enter") return;
const el = e.target;
if (!el || el.nodeType !== 1) return;
if (isTextInput(el)) send({ type: "press", selector: selectorFor(el), key: "Enter" });
},
true
);
const hoverable = (el) => {
const tag = el.tagName.toLowerCase();
if (["a", "button", "summary"].includes(tag)) return true;
const role = (el.getAttribute("role") || "").toLowerCase();
if (["button", "menuitem", "tab", "link"].includes(role)) return true;
if (el.hasAttribute("aria-haspopup") || el.hasAttribute("onmouseenter") || el.hasAttribute("onmouseover"))
return true;
try {
return window.getComputedStyle(el).cursor === "pointer";
} catch (e) {
return false;
}
};
let hoverTimer = null;
let hoverEl = null;
let lastHover = null;
document.addEventListener(
"mouseover",
(e) => {
hoverEl = e.target;
if (hoverTimer) clearTimeout(hoverTimer);
hoverTimer = setTimeout(() => {
const el = hoverEl;
if (!el || el.nodeType !== 1) return;
if (!hoverable(el)) return;
const sel = selectorFor(el);
if (sel === lastHover) return;
lastHover = sel;
send({ type: "hover", selector: sel });
}, 250);
},
true
);
document.addEventListener(
"dragstart",
(e) => {
if (e.target && e.target.nodeType === 1) dndFrom = selectorFor(e.target);
},
true
);
document.addEventListener(
"drop",
(e) => {
if (dndFrom && e.target && e.target.nodeType === 1) {
send({ type: "drag", from: dndFrom, to: selectorFor(e.target) });
}
dndFrom = null;
},
true
);
document.addEventListener(
"mousedown",
(e) => {
if (e.button !== 0 || !e.target || e.target.nodeType !== 1) {
down = null;
return;
}
down = { el: e.target, x: e.clientX, y: e.clientY };
},
true
);
document.addEventListener(
"mouseup",
(e) => {
if (!down || !e.target || e.target.nodeType !== 1) {
down = null;
return;
}
const dist = Math.hypot(e.clientX - down.x, e.clientY - down.y);
const up = e.target;
if (dist > 12 && up !== down.el) {
send({ type: "drag", from: selectorFor(down.el), to: selectorFor(up) });
suppressClickUntil = Date.now() + 150; }
down = null;
},
true
);
})();