@xbrowser/cli 1.9.9 → 1.11.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (27) hide show
  1. package/dist/{anti-bot-DR56Y63V.js → anti-bot-GTTYNEFB.js} +1 -1
  2. package/dist/{browser-FFYPFTBV.js → browser-Q5APBNF6.js} +1 -1
  3. package/dist/{browser-YCO4GJMZ.js → browser-V3JIWSTR.js} +2 -2
  4. package/dist/{browser-RHWUAMTB.js → browser-XNU7JQYC.js} +3 -2
  5. package/dist/{cdp-driver-J3YQ4LJV.js → cdp-driver-GD6YBBGE.js} +1 -1
  6. package/dist/cdp-driver-VEK6BNN6.js +49 -0
  7. package/dist/{cdp-driver-2T4P4ZE2.js → cdp-driver-XFTTZI5O.js} +436 -56
  8. package/dist/chunk-3FWLW7FS.js +106 -0
  9. package/dist/chunk-7OFM755Z.js +3509 -0
  10. package/dist/{chunk-5UGR6MUK.js → chunk-HBHOKZPN.js} +51 -16
  11. package/dist/{chunk-6OZWKXSW.js → chunk-HVPUVVSA.js} +72 -15
  12. package/dist/{chunk-GUTBIYFW.js → chunk-JEDP4PJW.js} +507 -70
  13. package/dist/{chunk-INTQPBYF.js → chunk-JKVUFP3G.js} +6 -2
  14. package/dist/{chunk-4452SPFI.js → chunk-NODRQGOK.js} +51 -16
  15. package/dist/{chunk-YMUSHPU4.js → chunk-WHPBNUKB.js} +35 -1
  16. package/dist/{chunk-RZM5CNIY.js → chunk-XKQVUFUS.js} +72 -15
  17. package/dist/{chunk-RRBXV7KE.js → chunk-XQ4HRPDJ.js} +384 -102
  18. package/dist/cli.js +79 -29
  19. package/dist/{daemon-client-GKEPT4NY.js → daemon-client-MMDRYCF5.js} +35 -1
  20. package/dist/{daemon-client-O6BYVRXV.js → daemon-client-Y2YSZCGK.js} +1 -1
  21. package/dist/daemon-main.js +103 -32
  22. package/dist/index.d.ts +8 -0
  23. package/dist/index.js +94 -31
  24. package/dist/{session-recorder-H3KEYU26.js → session-recorder-3BEVWHOK.js} +1 -1
  25. package/dist/{session-recorder-QRZMKFVL.js → session-recorder-SLDBENVF.js} +1 -1
  26. package/dist/{session-replayer-LJUC4TI7.js → session-replayer-WIUYVN5J.js} +90 -2
  27. package/package.json +1 -1
@@ -0,0 +1,106 @@
1
+ // src/cdp-driver/selector-utils.ts
2
+ function queryJS(selector) {
3
+ return `(${deepQueryIIFE})( ${JSON.stringify(queryMainJS(selector))} )`;
4
+ }
5
+ var deepQueryIIFE = `(function(mainExpr) {
6
+ const run = (root) => {
7
+ try { return new Function('document', 'return (' + mainExpr + ')')(root); }
8
+ catch (e) { return null; }
9
+ };
10
+ const scanRoot = (root) => {
11
+ const direct = run(root);
12
+ if (direct) return direct;
13
+ let all;
14
+ try { all = root.querySelectorAll('*'); } catch (e) { return null; }
15
+ for (const el of all) {
16
+ if (el.shadowRoot) {
17
+ const r = scanRoot(el.shadowRoot);
18
+ if (r) return r;
19
+ }
20
+ if (el.tagName === 'IFRAME') {
21
+ let inner = null;
22
+ try { inner = el.contentDocument; } catch (e) { /* cross-origin */ }
23
+ if (inner) {
24
+ const r = scanRoot(inner);
25
+ if (r) return r;
26
+ }
27
+ }
28
+ }
29
+ return null;
30
+ };
31
+ return scanRoot(document);
32
+ })`;
33
+ function queryMainJS(selector) {
34
+ if (selector.startsWith("xpath=")) {
35
+ const xpath = JSON.stringify(selector.slice(6));
36
+ return `document.evaluate(${xpath}, document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue`;
37
+ }
38
+ if (selector.startsWith("text=")) {
39
+ const raw = selector.slice(5);
40
+ const exact = raw.startsWith('"') && raw.endsWith('"');
41
+ const text = exact ? raw.slice(1, -1) : raw;
42
+ return `(() => {
43
+ const target = ${JSON.stringify(text)};
44
+ const exact = ${exact};
45
+ // Match on OWN text nodes (not strict leaf elements): search-result
46
+ // titles mix text with inline highlight <em> marks \u2014 a strict leaf filter
47
+ // finds nothing there (real-world juejin). Own-text keeps the match
48
+ // precise (descendant-only text doesn't count) while tolerating markup.
49
+ const ownText = (e) => Array.prototype.filter.call(e.childNodes, (n) => n.nodeType === 3)
50
+ .map((n) => n.textContent).join('').trim();
51
+ const els = [...document.querySelectorAll('*')].filter(e => {
52
+ if (e.offsetParent === null && e.tagName !== 'BODY') return false;
53
+ const t = ownText(e);
54
+ if (!t) return false;
55
+ return exact ? t === target : t.toLowerCase().includes(target.toLowerCase());
56
+ });
57
+ // Rank instead of raw DOM order: exact text beats substring, interactive
58
+ // elements (button/a/[onclick]/inputs) beat prose. Prevents matching a
59
+ // description paragraph that merely MENTIONS the target label
60
+ // (rec-duel d06: header text "\u76EE\u6807\u9879\u300C\u7B2C 87 \u53F7\u300D" hijacked text=\u7B2C 87 \u53F7).
61
+ const isInteractive = (e) => {
62
+ const tag = e.tagName;
63
+ return tag === 'BUTTON' || tag === 'A' || tag === 'INPUT' || tag === 'SELECT'
64
+ || e.hasAttribute('onclick') || e.getAttribute('role') === 'button';
65
+ };
66
+ els.sort((a, b) => {
67
+ const ta = ownText(a), tb = ownText(b);
68
+ const ea = ta === target ? 0 : 1, eb = tb === target ? 0 : 1;
69
+ if (ea !== eb) return ea - eb;
70
+ const ia = isInteractive(a) ? 0 : 1, ib = isInteractive(b) ? 0 : 1;
71
+ if (ia !== ib) return ia - ib;
72
+ return 0; // stable \u2014 preserve DOM order
73
+ });
74
+ return els[0] || null;
75
+ })()`;
76
+ }
77
+ if (selector.startsWith("popup-text=")) {
78
+ const text = selector.slice("popup-text=".length);
79
+ return `(() => {
80
+ const target = ${JSON.stringify(text)};
81
+ const els = [...document.querySelectorAll('*')].filter(e => {
82
+ if (e.children.length > 0) return false;
83
+ if (e.offsetParent === null) return false;
84
+ if ((e.textContent || '').trim() !== target) return false;
85
+ return true;
86
+ });
87
+ return els[0] || null;
88
+ })()`;
89
+ }
90
+ return `document.querySelector(${JSON.stringify(selector)})`;
91
+ }
92
+ function queryAllJS(selector) {
93
+ if (selector.startsWith("xpath=")) {
94
+ const xpath = JSON.stringify(selector.slice(6));
95
+ return `(() => { const it = document.evaluate(${xpath}, document, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null); const r=[]; for(let i=0;i<it.snapshotLength;i++) r.push(it.snapshotItem(i)); return r; })()`;
96
+ }
97
+ if (selector.startsWith("text=") || selector.startsWith("popup-text=")) {
98
+ return `(() => { const el = ${queryJS(selector)}; return el ? [el] : []; })()`;
99
+ }
100
+ return `document.querySelectorAll(${JSON.stringify(selector)})`;
101
+ }
102
+
103
+ export {
104
+ queryJS,
105
+ queryAllJS
106
+ };