83 lines
3.0 KiB
TypeScript
83 lines
3.0 KiB
TypeScript
// @ts-nocheck
|
|
import { executeScript, getActiveTab, isScriptableUrl } from '../core';
|
|
import { contentDispatch } from './injected';
|
|
export async function domOp(funcName, args) {
|
|
const tab = await getActiveTab();
|
|
if (!isScriptableUrl(tab.url)) {
|
|
throw new Error(`Cannot run DOM commands on ${tab.url} — navigate to a regular web page first`);
|
|
}
|
|
const results = await executeScript({
|
|
target: { tabId: tab.id },
|
|
func: contentDispatch,
|
|
args: [funcName, args],
|
|
});
|
|
return results[0]?.result;
|
|
}
|
|
|
|
export async function domEval({ code, tabId } = {}) {
|
|
const tab = tabId ? await chrome.tabs.get(tabId) : await getActiveTab();
|
|
if (!isScriptableUrl(tab.url)) {
|
|
throw new Error(`Cannot run DOM commands on ${tab.url} — navigate to a regular web page first`);
|
|
}
|
|
const results = await executeScript({
|
|
target: { tabId: tab.id },
|
|
world: "MAIN",
|
|
func: (c) => (0, eval)(c),
|
|
args: [code],
|
|
});
|
|
return results[0]?.result ?? null;
|
|
}
|
|
|
|
export async function domWaitFor({ selector, timeout = 10000, visible = false, hidden = false, tabId } = {}) {
|
|
const tab = tabId ? await chrome.tabs.get(tabId) : await getActiveTab();
|
|
if (!isScriptableUrl(tab.url)) {
|
|
throw new Error(`Cannot run DOM commands on ${tab.url} — navigate to a regular web page first`);
|
|
}
|
|
const deadline = Date.now() + timeout;
|
|
while (Date.now() < deadline) {
|
|
const results = await executeScript({
|
|
target: { tabId: tab.id },
|
|
func: (sel, vis, hid) => {
|
|
const el = document.querySelector(sel);
|
|
if (hid) return !el || el.offsetParent === null;
|
|
if (!el) return false;
|
|
if (vis) {
|
|
const r = el.getBoundingClientRect();
|
|
return r.width > 0 && r.height > 0;
|
|
}
|
|
return true;
|
|
},
|
|
args: [selector, visible, hidden],
|
|
});
|
|
if (results[0]?.result) return { selector, found: !hidden };
|
|
await new Promise(r => setTimeout(r, 200));
|
|
}
|
|
throw new Error(`Selector '${selector}' condition not met within ${timeout}ms`);
|
|
}
|
|
|
|
export async function domPoll({ selector, pattern, attr, timeout = 30000, interval = 500, tabId } = {}) {
|
|
const tab = tabId ? await chrome.tabs.get(tabId) : await getActiveTab();
|
|
if (!isScriptableUrl(tab.url)) {
|
|
throw new Error(`Cannot run DOM commands on ${tab.url} — navigate to a regular web page first`);
|
|
}
|
|
const deadline = Date.now() + timeout;
|
|
const regex = new RegExp(pattern);
|
|
while (Date.now() < deadline) {
|
|
const results = await executeScript({
|
|
target: { tabId: tab.id },
|
|
func: (sel, a) => {
|
|
const el = document.querySelector(sel);
|
|
if (!el) return null;
|
|
if (a) return el.getAttribute(a) ?? el[a] ?? null;
|
|
return el.value !== undefined ? el.value : el.textContent.trim();
|
|
},
|
|
args: [selector, attr || null],
|
|
});
|
|
const value = results[0]?.result;
|
|
if (value != null && regex.test(String(value))) return { selector, value, pattern };
|
|
await new Promise(r => setTimeout(r, interval));
|
|
}
|
|
throw new Error(`Selector '${selector}' did not match '${pattern}' within ${timeout}ms`);
|
|
}
|
|
|