feat: 开发采集插件
This commit is contained in:
@@ -0,0 +1,59 @@
|
||||
/**
|
||||
* DOM 工具 - 等待元素、Shadow DOM 穿透
|
||||
* 从 docs/extension/plan.md §6.5 移植
|
||||
*/
|
||||
|
||||
/**
|
||||
* 等待任一选择器出现(MutationObserver + 超时)
|
||||
*/
|
||||
export function waitForAny(
|
||||
selectors: string[],
|
||||
timeoutMs = 10_000
|
||||
): Promise<Element | null> {
|
||||
const hit = () => selectors.map(s => document.querySelector(s)).find(Boolean) ?? null;
|
||||
|
||||
const found = hit();
|
||||
if (found) return Promise.resolve(found);
|
||||
|
||||
return new Promise((resolve) => {
|
||||
const timer = setTimeout(() => {
|
||||
observer.disconnect();
|
||||
resolve(null); // 超时返回 null
|
||||
}, timeoutMs);
|
||||
|
||||
const observer = new MutationObserver(() => {
|
||||
const el = hit();
|
||||
if (el) {
|
||||
clearTimeout(timer);
|
||||
observer.disconnect();
|
||||
resolve(el);
|
||||
}
|
||||
});
|
||||
|
||||
observer.observe(document.documentElement, { childList: true, subtree: true });
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 穿透 Shadow DOM 查询元素
|
||||
* 1688 部分组件用了 Web Components
|
||||
*/
|
||||
export function queryAllDeep(selectors: string[]): Element[] {
|
||||
const out: Element[] = [];
|
||||
for (const sel of selectors) {
|
||||
let nodes: NodeListOf<Element>;
|
||||
try {
|
||||
nodes = document.querySelectorAll(sel);
|
||||
} catch {
|
||||
continue; // 选择器写错不能拖垮整个扫描
|
||||
}
|
||||
nodes.forEach(el => {
|
||||
if (el.shadowRoot) {
|
||||
out.push(...Array.from(el.shadowRoot.querySelectorAll('img, video')));
|
||||
} else {
|
||||
out.push(el);
|
||||
}
|
||||
});
|
||||
}
|
||||
return out;
|
||||
}
|
||||
Reference in New Issue
Block a user