haltija 1.1.3 → 1.1.4
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.
- package/apps/desktop/package.json +1 -1
- package/apps/desktop/resources/component.js +97 -17
- package/bin/tosijs-dev.mjs +0 -0
- package/dist/component.js +97 -17
- package/dist/index.js +18 -10
- package/dist/server.js +18 -10
- package/package.json +1 -1
|
@@ -36,7 +36,57 @@
|
|
|
36
36
|
});
|
|
37
37
|
|
|
38
38
|
// src/version.ts
|
|
39
|
-
var VERSION = "1.1.
|
|
39
|
+
var VERSION = "1.1.4";
|
|
40
|
+
|
|
41
|
+
// src/text-selector.ts
|
|
42
|
+
var TEXT_PSEUDO_RE = /:(?:text-is|has-text|text)\(/;
|
|
43
|
+
function parseTextSelector(selector) {
|
|
44
|
+
const match = selector.match(/:(?:text-is|has-text|text)\(/);
|
|
45
|
+
if (!match || match.index === undefined)
|
|
46
|
+
return null;
|
|
47
|
+
const pseudoStart = match.index;
|
|
48
|
+
const pseudoName = match[0].slice(1, -1);
|
|
49
|
+
let depth = 1;
|
|
50
|
+
let i = pseudoStart + match[0].length;
|
|
51
|
+
while (i < selector.length && depth > 0) {
|
|
52
|
+
if (selector[i] === "(")
|
|
53
|
+
depth++;
|
|
54
|
+
else if (selector[i] === ")")
|
|
55
|
+
depth--;
|
|
56
|
+
i++;
|
|
57
|
+
}
|
|
58
|
+
if (depth !== 0)
|
|
59
|
+
return null;
|
|
60
|
+
const rawArg = selector.slice(pseudoStart + match[0].length, i - 1).trim();
|
|
61
|
+
const baseSelector = (selector.slice(0, pseudoStart) + selector.slice(i)).trim() || "*";
|
|
62
|
+
const regexMatch = rawArg.match(/^\/(.+)\/([gimsuy]*)$/);
|
|
63
|
+
if (regexMatch) {
|
|
64
|
+
try {
|
|
65
|
+
return {
|
|
66
|
+
baseSelector,
|
|
67
|
+
pseudoType: pseudoName,
|
|
68
|
+
searchRegex: new RegExp(regexMatch[1], regexMatch[2])
|
|
69
|
+
};
|
|
70
|
+
} catch {}
|
|
71
|
+
}
|
|
72
|
+
const unquoted = rawArg.startsWith('"') && rawArg.endsWith('"') || rawArg.startsWith("'") && rawArg.endsWith("'") ? rawArg.slice(1, -1) : rawArg;
|
|
73
|
+
return {
|
|
74
|
+
baseSelector,
|
|
75
|
+
pseudoType: pseudoName,
|
|
76
|
+
searchText: unquoted.toLowerCase()
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
function textMatches(elementText, parsed) {
|
|
80
|
+
const text = elementText.trim();
|
|
81
|
+
if (parsed.searchRegex) {
|
|
82
|
+
return parsed.searchRegex.test(text);
|
|
83
|
+
}
|
|
84
|
+
const lower = text.toLowerCase();
|
|
85
|
+
if (parsed.pseudoType === "text-is") {
|
|
86
|
+
return lower === parsed.searchText;
|
|
87
|
+
}
|
|
88
|
+
return lower.includes(parsed.searchText);
|
|
89
|
+
}
|
|
40
90
|
|
|
41
91
|
// src/component.ts
|
|
42
92
|
var VERSION2 = VERSION;
|
|
@@ -299,7 +349,7 @@
|
|
|
299
349
|
const allSimilar = document.querySelectorAll(selector);
|
|
300
350
|
const matchingText = Array.from(allSimilar).filter((e) => e.innerText?.trim() === text);
|
|
301
351
|
if (matchingText.length === 1) {
|
|
302
|
-
return `${tag}:
|
|
352
|
+
return `${tag}:text-is("${text}")`;
|
|
303
353
|
}
|
|
304
354
|
}
|
|
305
355
|
}
|
|
@@ -325,6 +375,34 @@
|
|
|
325
375
|
}
|
|
326
376
|
return getSelector(el);
|
|
327
377
|
}
|
|
378
|
+
function elementTextMatches(el, parsed) {
|
|
379
|
+
const text = el.innerText ?? "";
|
|
380
|
+
return textMatches(text, parsed);
|
|
381
|
+
}
|
|
382
|
+
function resolveSelector(selector) {
|
|
383
|
+
if (!TEXT_PSEUDO_RE.test(selector)) {
|
|
384
|
+
return document.querySelector(selector);
|
|
385
|
+
}
|
|
386
|
+
const parsed = parseTextSelector(selector);
|
|
387
|
+
if (!parsed)
|
|
388
|
+
return document.querySelector(selector);
|
|
389
|
+
const candidates = document.querySelectorAll(parsed.baseSelector);
|
|
390
|
+
for (const el of candidates) {
|
|
391
|
+
if (elementTextMatches(el, parsed))
|
|
392
|
+
return el;
|
|
393
|
+
}
|
|
394
|
+
return null;
|
|
395
|
+
}
|
|
396
|
+
function resolveSelectorAll(selector) {
|
|
397
|
+
if (!TEXT_PSEUDO_RE.test(selector)) {
|
|
398
|
+
return Array.from(document.querySelectorAll(selector));
|
|
399
|
+
}
|
|
400
|
+
const parsed = parseTextSelector(selector);
|
|
401
|
+
if (!parsed)
|
|
402
|
+
return Array.from(document.querySelectorAll(selector));
|
|
403
|
+
const candidates = document.querySelectorAll(parsed.baseSelector);
|
|
404
|
+
return Array.from(candidates).filter((el) => elementTextMatches(el, parsed));
|
|
405
|
+
}
|
|
328
406
|
function extractElement(el) {
|
|
329
407
|
const rect = el.getBoundingClientRect();
|
|
330
408
|
const attrs = {};
|
|
@@ -4905,10 +4983,10 @@ ${elementSummary}${moreText}`;
|
|
|
4905
4983
|
const req = payload2;
|
|
4906
4984
|
try {
|
|
4907
4985
|
if (req.all) {
|
|
4908
|
-
const elements =
|
|
4909
|
-
this.respond(msg2.id, true,
|
|
4986
|
+
const elements = resolveSelectorAll(req.selector);
|
|
4987
|
+
this.respond(msg2.id, true, elements.map(extractElement));
|
|
4910
4988
|
} else {
|
|
4911
|
-
const el =
|
|
4989
|
+
const el = resolveSelector(req.selector);
|
|
4912
4990
|
this.respond(msg2.id, true, el ? extractElement(el) : null);
|
|
4913
4991
|
}
|
|
4914
4992
|
} catch (err) {
|
|
@@ -4916,7 +4994,7 @@ ${elementSummary}${moreText}`;
|
|
|
4916
4994
|
}
|
|
4917
4995
|
} else if (action2 === "inspect") {
|
|
4918
4996
|
try {
|
|
4919
|
-
const el =
|
|
4997
|
+
const el = resolveSelector(payload2.selector);
|
|
4920
4998
|
if (!el) {
|
|
4921
4999
|
this.respond(msg2.id, false, null, `Element not found: ${payload2.selector}`);
|
|
4922
5000
|
return;
|
|
@@ -4931,19 +5009,19 @@ ${elementSummary}${moreText}`;
|
|
|
4931
5009
|
}
|
|
4932
5010
|
} else if (action2 === "inspectAll") {
|
|
4933
5011
|
try {
|
|
4934
|
-
const elements =
|
|
5012
|
+
const elements = resolveSelectorAll(payload2.selector);
|
|
4935
5013
|
const opts = {
|
|
4936
5014
|
fullStyles: payload2.fullStyles,
|
|
4937
5015
|
matchedRules: payload2.matchedRules
|
|
4938
5016
|
};
|
|
4939
|
-
const results =
|
|
5017
|
+
const results = elements.slice(0, payload2.limit || 10).map((el) => inspectElement(el, opts));
|
|
4940
5018
|
this.respond(msg2.id, true, results);
|
|
4941
5019
|
} catch (err) {
|
|
4942
5020
|
this.respond(msg2.id, false, null, err.message);
|
|
4943
5021
|
}
|
|
4944
5022
|
} else if (action2 === "highlight") {
|
|
4945
5023
|
try {
|
|
4946
|
-
const el =
|
|
5024
|
+
const el = resolveSelector(payload2.selector);
|
|
4947
5025
|
if (!el) {
|
|
4948
5026
|
this.respond(msg2.id, false, null, `Element not found: ${payload2.selector}`);
|
|
4949
5027
|
return;
|
|
@@ -4963,7 +5041,7 @@ ${elementSummary}${moreText}`;
|
|
|
4963
5041
|
} else if (action2 === "tree") {
|
|
4964
5042
|
try {
|
|
4965
5043
|
const request = payload2;
|
|
4966
|
-
const el =
|
|
5044
|
+
const el = resolveSelector(request.selector);
|
|
4967
5045
|
if (!el) {
|
|
4968
5046
|
this.respond(msg2.id, false, null, `Element not found: ${request.selector}`);
|
|
4969
5047
|
return;
|
|
@@ -5108,7 +5186,7 @@ ${elementSummary}${moreText}`;
|
|
|
5108
5186
|
}
|
|
5109
5187
|
const html2canvas = window.html2canvas;
|
|
5110
5188
|
if (html2canvas) {
|
|
5111
|
-
const target = payload2?.selector ?
|
|
5189
|
+
const target = payload2?.selector ? resolveSelector(payload2.selector) : document.body;
|
|
5112
5190
|
if (!target) {
|
|
5113
5191
|
this.respond(msg2.id, false, null, `Element not found: ${payload2?.selector}`);
|
|
5114
5192
|
return;
|
|
@@ -5262,7 +5340,7 @@ ${elementSummary}${moreText}`;
|
|
|
5262
5340
|
return;
|
|
5263
5341
|
}
|
|
5264
5342
|
} else if (selector) {
|
|
5265
|
-
el =
|
|
5343
|
+
el = resolveSelector(selector);
|
|
5266
5344
|
targetDesc = selector;
|
|
5267
5345
|
}
|
|
5268
5346
|
if (!el) {
|
|
@@ -5614,7 +5692,7 @@ ${elementSummary}${moreText}`;
|
|
|
5614
5692
|
return;
|
|
5615
5693
|
}
|
|
5616
5694
|
} else if (payload2.selector) {
|
|
5617
|
-
el =
|
|
5695
|
+
el = resolveSelector(payload2.selector);
|
|
5618
5696
|
targetDesc = payload2.selector;
|
|
5619
5697
|
}
|
|
5620
5698
|
if (!el) {
|
|
@@ -5689,7 +5767,7 @@ ${elementSummary}${moreText}`;
|
|
|
5689
5767
|
return;
|
|
5690
5768
|
}
|
|
5691
5769
|
} else if (selector) {
|
|
5692
|
-
target =
|
|
5770
|
+
target = resolveSelector(selector);
|
|
5693
5771
|
targetDesc = selector;
|
|
5694
5772
|
if (!target) {
|
|
5695
5773
|
this.respond(responseId, false, null, `Element not found: ${selector}`);
|
|
@@ -6095,7 +6173,7 @@ ${elementSummary}${moreText}`;
|
|
|
6095
6173
|
startMutationWatch(config) {
|
|
6096
6174
|
this.stopMutationWatch();
|
|
6097
6175
|
this.mutationConfig = config;
|
|
6098
|
-
const root = config.root ?
|
|
6176
|
+
const root = config.root ? resolveSelector(config.root) : document.body;
|
|
6099
6177
|
if (!root) {
|
|
6100
6178
|
this.send("mutations", "error", {
|
|
6101
6179
|
error: `Root element not found: ${config.root}`
|
|
@@ -6369,7 +6447,7 @@ ${elementSummary}${moreText}`;
|
|
|
6369
6447
|
this.send("mutations", "batch", batch);
|
|
6370
6448
|
}
|
|
6371
6449
|
watchEvents(req, watchId) {
|
|
6372
|
-
const target = req.selector ?
|
|
6450
|
+
const target = req.selector ? resolveSelector(req.selector) : document;
|
|
6373
6451
|
if (!target) {
|
|
6374
6452
|
this.respond(watchId, false, null, `Element not found: ${req.selector}`);
|
|
6375
6453
|
return;
|
|
@@ -6444,7 +6522,7 @@ ${elementSummary}${moreText}`;
|
|
|
6444
6522
|
this.eventWatchers.clear();
|
|
6445
6523
|
}
|
|
6446
6524
|
dispatchSyntheticEvent(req, responseId) {
|
|
6447
|
-
const el =
|
|
6525
|
+
const el = resolveSelector(req.selector);
|
|
6448
6526
|
if (!el) {
|
|
6449
6527
|
this.respond(responseId, false, null, `Element not found: ${req.selector}`);
|
|
6450
6528
|
return;
|
|
@@ -6588,6 +6666,8 @@ ${elementSummary}${moreText}`;
|
|
|
6588
6666
|
}
|
|
6589
6667
|
customElements.define(TAG_NAME, DevChannel);
|
|
6590
6668
|
currentTagName = TAG_NAME;
|
|
6669
|
+
window.__haltija_resolveSelector = resolveSelector;
|
|
6670
|
+
window.__haltija_resolveSelectorAll = resolveSelectorAll;
|
|
6591
6671
|
}
|
|
6592
6672
|
registerDevChannel();
|
|
6593
6673
|
var WIDGET_ID = "haltija-widget";
|
package/bin/tosijs-dev.mjs
CHANGED
|
File without changes
|
package/dist/component.js
CHANGED
|
@@ -36,7 +36,57 @@
|
|
|
36
36
|
});
|
|
37
37
|
|
|
38
38
|
// src/version.ts
|
|
39
|
-
var VERSION = "1.1.
|
|
39
|
+
var VERSION = "1.1.4";
|
|
40
|
+
|
|
41
|
+
// src/text-selector.ts
|
|
42
|
+
var TEXT_PSEUDO_RE = /:(?:text-is|has-text|text)\(/;
|
|
43
|
+
function parseTextSelector(selector) {
|
|
44
|
+
const match = selector.match(/:(?:text-is|has-text|text)\(/);
|
|
45
|
+
if (!match || match.index === undefined)
|
|
46
|
+
return null;
|
|
47
|
+
const pseudoStart = match.index;
|
|
48
|
+
const pseudoName = match[0].slice(1, -1);
|
|
49
|
+
let depth = 1;
|
|
50
|
+
let i = pseudoStart + match[0].length;
|
|
51
|
+
while (i < selector.length && depth > 0) {
|
|
52
|
+
if (selector[i] === "(")
|
|
53
|
+
depth++;
|
|
54
|
+
else if (selector[i] === ")")
|
|
55
|
+
depth--;
|
|
56
|
+
i++;
|
|
57
|
+
}
|
|
58
|
+
if (depth !== 0)
|
|
59
|
+
return null;
|
|
60
|
+
const rawArg = selector.slice(pseudoStart + match[0].length, i - 1).trim();
|
|
61
|
+
const baseSelector = (selector.slice(0, pseudoStart) + selector.slice(i)).trim() || "*";
|
|
62
|
+
const regexMatch = rawArg.match(/^\/(.+)\/([gimsuy]*)$/);
|
|
63
|
+
if (regexMatch) {
|
|
64
|
+
try {
|
|
65
|
+
return {
|
|
66
|
+
baseSelector,
|
|
67
|
+
pseudoType: pseudoName,
|
|
68
|
+
searchRegex: new RegExp(regexMatch[1], regexMatch[2])
|
|
69
|
+
};
|
|
70
|
+
} catch {}
|
|
71
|
+
}
|
|
72
|
+
const unquoted = rawArg.startsWith('"') && rawArg.endsWith('"') || rawArg.startsWith("'") && rawArg.endsWith("'") ? rawArg.slice(1, -1) : rawArg;
|
|
73
|
+
return {
|
|
74
|
+
baseSelector,
|
|
75
|
+
pseudoType: pseudoName,
|
|
76
|
+
searchText: unquoted.toLowerCase()
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
function textMatches(elementText, parsed) {
|
|
80
|
+
const text = elementText.trim();
|
|
81
|
+
if (parsed.searchRegex) {
|
|
82
|
+
return parsed.searchRegex.test(text);
|
|
83
|
+
}
|
|
84
|
+
const lower = text.toLowerCase();
|
|
85
|
+
if (parsed.pseudoType === "text-is") {
|
|
86
|
+
return lower === parsed.searchText;
|
|
87
|
+
}
|
|
88
|
+
return lower.includes(parsed.searchText);
|
|
89
|
+
}
|
|
40
90
|
|
|
41
91
|
// src/component.ts
|
|
42
92
|
var VERSION2 = VERSION;
|
|
@@ -299,7 +349,7 @@
|
|
|
299
349
|
const allSimilar = document.querySelectorAll(selector);
|
|
300
350
|
const matchingText = Array.from(allSimilar).filter((e) => e.innerText?.trim() === text);
|
|
301
351
|
if (matchingText.length === 1) {
|
|
302
|
-
return `${tag}:
|
|
352
|
+
return `${tag}:text-is("${text}")`;
|
|
303
353
|
}
|
|
304
354
|
}
|
|
305
355
|
}
|
|
@@ -325,6 +375,34 @@
|
|
|
325
375
|
}
|
|
326
376
|
return getSelector(el);
|
|
327
377
|
}
|
|
378
|
+
function elementTextMatches(el, parsed) {
|
|
379
|
+
const text = el.innerText ?? "";
|
|
380
|
+
return textMatches(text, parsed);
|
|
381
|
+
}
|
|
382
|
+
function resolveSelector(selector) {
|
|
383
|
+
if (!TEXT_PSEUDO_RE.test(selector)) {
|
|
384
|
+
return document.querySelector(selector);
|
|
385
|
+
}
|
|
386
|
+
const parsed = parseTextSelector(selector);
|
|
387
|
+
if (!parsed)
|
|
388
|
+
return document.querySelector(selector);
|
|
389
|
+
const candidates = document.querySelectorAll(parsed.baseSelector);
|
|
390
|
+
for (const el of candidates) {
|
|
391
|
+
if (elementTextMatches(el, parsed))
|
|
392
|
+
return el;
|
|
393
|
+
}
|
|
394
|
+
return null;
|
|
395
|
+
}
|
|
396
|
+
function resolveSelectorAll(selector) {
|
|
397
|
+
if (!TEXT_PSEUDO_RE.test(selector)) {
|
|
398
|
+
return Array.from(document.querySelectorAll(selector));
|
|
399
|
+
}
|
|
400
|
+
const parsed = parseTextSelector(selector);
|
|
401
|
+
if (!parsed)
|
|
402
|
+
return Array.from(document.querySelectorAll(selector));
|
|
403
|
+
const candidates = document.querySelectorAll(parsed.baseSelector);
|
|
404
|
+
return Array.from(candidates).filter((el) => elementTextMatches(el, parsed));
|
|
405
|
+
}
|
|
328
406
|
function extractElement(el) {
|
|
329
407
|
const rect = el.getBoundingClientRect();
|
|
330
408
|
const attrs = {};
|
|
@@ -4905,10 +4983,10 @@ ${elementSummary}${moreText}`;
|
|
|
4905
4983
|
const req = payload2;
|
|
4906
4984
|
try {
|
|
4907
4985
|
if (req.all) {
|
|
4908
|
-
const elements =
|
|
4909
|
-
this.respond(msg2.id, true,
|
|
4986
|
+
const elements = resolveSelectorAll(req.selector);
|
|
4987
|
+
this.respond(msg2.id, true, elements.map(extractElement));
|
|
4910
4988
|
} else {
|
|
4911
|
-
const el =
|
|
4989
|
+
const el = resolveSelector(req.selector);
|
|
4912
4990
|
this.respond(msg2.id, true, el ? extractElement(el) : null);
|
|
4913
4991
|
}
|
|
4914
4992
|
} catch (err) {
|
|
@@ -4916,7 +4994,7 @@ ${elementSummary}${moreText}`;
|
|
|
4916
4994
|
}
|
|
4917
4995
|
} else if (action2 === "inspect") {
|
|
4918
4996
|
try {
|
|
4919
|
-
const el =
|
|
4997
|
+
const el = resolveSelector(payload2.selector);
|
|
4920
4998
|
if (!el) {
|
|
4921
4999
|
this.respond(msg2.id, false, null, `Element not found: ${payload2.selector}`);
|
|
4922
5000
|
return;
|
|
@@ -4931,19 +5009,19 @@ ${elementSummary}${moreText}`;
|
|
|
4931
5009
|
}
|
|
4932
5010
|
} else if (action2 === "inspectAll") {
|
|
4933
5011
|
try {
|
|
4934
|
-
const elements =
|
|
5012
|
+
const elements = resolveSelectorAll(payload2.selector);
|
|
4935
5013
|
const opts = {
|
|
4936
5014
|
fullStyles: payload2.fullStyles,
|
|
4937
5015
|
matchedRules: payload2.matchedRules
|
|
4938
5016
|
};
|
|
4939
|
-
const results =
|
|
5017
|
+
const results = elements.slice(0, payload2.limit || 10).map((el) => inspectElement(el, opts));
|
|
4940
5018
|
this.respond(msg2.id, true, results);
|
|
4941
5019
|
} catch (err) {
|
|
4942
5020
|
this.respond(msg2.id, false, null, err.message);
|
|
4943
5021
|
}
|
|
4944
5022
|
} else if (action2 === "highlight") {
|
|
4945
5023
|
try {
|
|
4946
|
-
const el =
|
|
5024
|
+
const el = resolveSelector(payload2.selector);
|
|
4947
5025
|
if (!el) {
|
|
4948
5026
|
this.respond(msg2.id, false, null, `Element not found: ${payload2.selector}`);
|
|
4949
5027
|
return;
|
|
@@ -4963,7 +5041,7 @@ ${elementSummary}${moreText}`;
|
|
|
4963
5041
|
} else if (action2 === "tree") {
|
|
4964
5042
|
try {
|
|
4965
5043
|
const request = payload2;
|
|
4966
|
-
const el =
|
|
5044
|
+
const el = resolveSelector(request.selector);
|
|
4967
5045
|
if (!el) {
|
|
4968
5046
|
this.respond(msg2.id, false, null, `Element not found: ${request.selector}`);
|
|
4969
5047
|
return;
|
|
@@ -5108,7 +5186,7 @@ ${elementSummary}${moreText}`;
|
|
|
5108
5186
|
}
|
|
5109
5187
|
const html2canvas = window.html2canvas;
|
|
5110
5188
|
if (html2canvas) {
|
|
5111
|
-
const target = payload2?.selector ?
|
|
5189
|
+
const target = payload2?.selector ? resolveSelector(payload2.selector) : document.body;
|
|
5112
5190
|
if (!target) {
|
|
5113
5191
|
this.respond(msg2.id, false, null, `Element not found: ${payload2?.selector}`);
|
|
5114
5192
|
return;
|
|
@@ -5262,7 +5340,7 @@ ${elementSummary}${moreText}`;
|
|
|
5262
5340
|
return;
|
|
5263
5341
|
}
|
|
5264
5342
|
} else if (selector) {
|
|
5265
|
-
el =
|
|
5343
|
+
el = resolveSelector(selector);
|
|
5266
5344
|
targetDesc = selector;
|
|
5267
5345
|
}
|
|
5268
5346
|
if (!el) {
|
|
@@ -5614,7 +5692,7 @@ ${elementSummary}${moreText}`;
|
|
|
5614
5692
|
return;
|
|
5615
5693
|
}
|
|
5616
5694
|
} else if (payload2.selector) {
|
|
5617
|
-
el =
|
|
5695
|
+
el = resolveSelector(payload2.selector);
|
|
5618
5696
|
targetDesc = payload2.selector;
|
|
5619
5697
|
}
|
|
5620
5698
|
if (!el) {
|
|
@@ -5689,7 +5767,7 @@ ${elementSummary}${moreText}`;
|
|
|
5689
5767
|
return;
|
|
5690
5768
|
}
|
|
5691
5769
|
} else if (selector) {
|
|
5692
|
-
target =
|
|
5770
|
+
target = resolveSelector(selector);
|
|
5693
5771
|
targetDesc = selector;
|
|
5694
5772
|
if (!target) {
|
|
5695
5773
|
this.respond(responseId, false, null, `Element not found: ${selector}`);
|
|
@@ -6095,7 +6173,7 @@ ${elementSummary}${moreText}`;
|
|
|
6095
6173
|
startMutationWatch(config) {
|
|
6096
6174
|
this.stopMutationWatch();
|
|
6097
6175
|
this.mutationConfig = config;
|
|
6098
|
-
const root = config.root ?
|
|
6176
|
+
const root = config.root ? resolveSelector(config.root) : document.body;
|
|
6099
6177
|
if (!root) {
|
|
6100
6178
|
this.send("mutations", "error", {
|
|
6101
6179
|
error: `Root element not found: ${config.root}`
|
|
@@ -6369,7 +6447,7 @@ ${elementSummary}${moreText}`;
|
|
|
6369
6447
|
this.send("mutations", "batch", batch);
|
|
6370
6448
|
}
|
|
6371
6449
|
watchEvents(req, watchId) {
|
|
6372
|
-
const target = req.selector ?
|
|
6450
|
+
const target = req.selector ? resolveSelector(req.selector) : document;
|
|
6373
6451
|
if (!target) {
|
|
6374
6452
|
this.respond(watchId, false, null, `Element not found: ${req.selector}`);
|
|
6375
6453
|
return;
|
|
@@ -6444,7 +6522,7 @@ ${elementSummary}${moreText}`;
|
|
|
6444
6522
|
this.eventWatchers.clear();
|
|
6445
6523
|
}
|
|
6446
6524
|
dispatchSyntheticEvent(req, responseId) {
|
|
6447
|
-
const el =
|
|
6525
|
+
const el = resolveSelector(req.selector);
|
|
6448
6526
|
if (!el) {
|
|
6449
6527
|
this.respond(responseId, false, null, `Element not found: ${req.selector}`);
|
|
6450
6528
|
return;
|
|
@@ -6588,6 +6666,8 @@ ${elementSummary}${moreText}`;
|
|
|
6588
6666
|
}
|
|
6589
6667
|
customElements.define(TAG_NAME, DevChannel);
|
|
6590
6668
|
currentTagName = TAG_NAME;
|
|
6669
|
+
window.__haltija_resolveSelector = resolveSelector;
|
|
6670
|
+
window.__haltija_resolveSelectorAll = resolveSelectorAll;
|
|
6591
6671
|
}
|
|
6592
6672
|
registerDevChannel();
|
|
6593
6673
|
var WIDGET_ID = "haltija-widget";
|
package/dist/index.js
CHANGED
|
@@ -685,7 +685,7 @@ var injectorCode = `
|
|
|
685
685
|
`;
|
|
686
686
|
|
|
687
687
|
// src/version.ts
|
|
688
|
-
var VERSION = "1.1.
|
|
688
|
+
var VERSION = "1.1.4";
|
|
689
689
|
|
|
690
690
|
// src/embedded-assets.ts
|
|
691
691
|
var APP_MD = `# Haltija App
|
|
@@ -5391,6 +5391,13 @@ function registerHandler(endpoint2, handler) {
|
|
|
5391
5391
|
handlers.set(endpoint2.path, handler);
|
|
5392
5392
|
}
|
|
5393
5393
|
var sleep = (ms) => new Promise((r) => setTimeout(r, ms));
|
|
5394
|
+
function qs(selector) {
|
|
5395
|
+
const s = JSON.stringify(selector);
|
|
5396
|
+
return `(window.__haltija_resolveSelector || document.querySelector.bind(document))(${s})`;
|
|
5397
|
+
}
|
|
5398
|
+
function qsVisible(selector) {
|
|
5399
|
+
return `(function(){var el=${qs(selector)};return !!el && el.offsetParent !== null})()`;
|
|
5400
|
+
}
|
|
5394
5401
|
var SNAPSHOT_CODE = `(function() {
|
|
5395
5402
|
const snapshot = { elements: {}, focused: null, scrollY: window.scrollY, scrollX: window.scrollX };
|
|
5396
5403
|
|
|
@@ -5576,7 +5583,7 @@ registerHandler(click, async (body, ctx) => {
|
|
|
5576
5583
|
if (autoWait) {
|
|
5577
5584
|
const startTime = Date.now();
|
|
5578
5585
|
const pollInterval = 100;
|
|
5579
|
-
const checkCode =
|
|
5586
|
+
const checkCode = qsVisible(selector);
|
|
5580
5587
|
while (Date.now() - startTime < timeout) {
|
|
5581
5588
|
const checkResponse = await ctx.requestFromBrowser("eval", "exec", { code: checkCode }, 5000, windowId);
|
|
5582
5589
|
if (checkResponse.success && checkResponse.data === true) {
|
|
@@ -5621,13 +5628,14 @@ registerHandler(fetchUrl, async (body, ctx) => {
|
|
|
5621
5628
|
registerHandler(call, async (body, ctx) => {
|
|
5622
5629
|
const windowId = body.window || ctx.targetWindowId;
|
|
5623
5630
|
const selector = JSON.stringify(body.selector);
|
|
5631
|
+
const resolveExpr = `(window.__haltija_resolveSelector || document.querySelector.bind(document))(${selector})`;
|
|
5624
5632
|
const method = body.method;
|
|
5625
5633
|
const args = body.args;
|
|
5626
5634
|
let code;
|
|
5627
5635
|
if (args !== undefined) {
|
|
5628
5636
|
const argsJson = JSON.stringify(args);
|
|
5629
5637
|
code = `(function() {
|
|
5630
|
-
const el =
|
|
5638
|
+
const el = ${resolveExpr};
|
|
5631
5639
|
if (!el) return { success: false, error: 'Element not found: ${body.selector.replace(/'/g, "\\'")}' };
|
|
5632
5640
|
if (typeof el[${JSON.stringify(method)}] !== 'function') {
|
|
5633
5641
|
return { success: false, error: 'Method not found: ${method}' };
|
|
@@ -5641,7 +5649,7 @@ registerHandler(call, async (body, ctx) => {
|
|
|
5641
5649
|
})()`;
|
|
5642
5650
|
} else {
|
|
5643
5651
|
code = `(function() {
|
|
5644
|
-
const el =
|
|
5652
|
+
const el = ${resolveExpr};
|
|
5645
5653
|
if (!el) return { success: false, error: 'Element not found: ${body.selector.replace(/'/g, "\\'")}' };
|
|
5646
5654
|
try {
|
|
5647
5655
|
const value = el[${JSON.stringify(method)}];
|
|
@@ -5665,7 +5673,7 @@ registerHandler(drag, async (body, ctx) => {
|
|
|
5665
5673
|
const steps = Math.max(5, Math.floor(duration / 16));
|
|
5666
5674
|
const windowId = body.window || ctx.targetWindowId;
|
|
5667
5675
|
await ctx.requestFromBrowser("eval", "exec", {
|
|
5668
|
-
code:
|
|
5676
|
+
code: `${qs(selector)}?.scrollIntoView({behavior: "smooth", block: "center"})`
|
|
5669
5677
|
}, 5000, windowId);
|
|
5670
5678
|
await sleep(100);
|
|
5671
5679
|
const inspectResponse = await ctx.requestFromBrowser("dom", "inspect", { selector }, 5000, windowId);
|
|
@@ -5711,7 +5719,7 @@ registerHandler(type, async (body, ctx) => {
|
|
|
5711
5719
|
if (autoWait && body.selector) {
|
|
5712
5720
|
const startTime = Date.now();
|
|
5713
5721
|
const pollInterval = 100;
|
|
5714
|
-
const checkCode =
|
|
5722
|
+
const checkCode = qsVisible(body.selector);
|
|
5715
5723
|
while (Date.now() - startTime < waitTimeout) {
|
|
5716
5724
|
const checkResponse = await ctx.requestFromBrowser("eval", "exec", { code: checkCode }, 5000, windowId);
|
|
5717
5725
|
if (checkResponse.success && checkResponse.data === true) {
|
|
@@ -5786,7 +5794,7 @@ registerHandler(inspectAll, async (body, ctx) => {
|
|
|
5786
5794
|
registerHandler(highlight, async (body, ctx) => {
|
|
5787
5795
|
const windowId = body.window || ctx.targetWindowId;
|
|
5788
5796
|
await ctx.requestFromBrowser("eval", "exec", {
|
|
5789
|
-
code:
|
|
5797
|
+
code: `${qs(body.selector)}?.scrollIntoView({behavior: "smooth", block: "center"})`
|
|
5790
5798
|
}, 5000, windowId);
|
|
5791
5799
|
await sleep(100);
|
|
5792
5800
|
const response = await ctx.requestFromBrowser("dom", "highlight", {
|
|
@@ -5958,7 +5966,7 @@ registerHandler(wait, async (body, ctx) => {
|
|
|
5958
5966
|
const startTime = Date.now();
|
|
5959
5967
|
if (body.forElement) {
|
|
5960
5968
|
const selector = body.forElement;
|
|
5961
|
-
const checkCode = hidden ?
|
|
5969
|
+
const checkCode = hidden ? `(function(){var el=${qs(selector)};return !el || el.offsetParent === null})()` : qsVisible(selector);
|
|
5962
5970
|
while (Date.now() - startTime < timeout) {
|
|
5963
5971
|
const checkResponse = await ctx.requestFromBrowser("eval", "exec", { code: checkCode }, 5000, windowId);
|
|
5964
5972
|
if (checkResponse.success && checkResponse.data === true) {
|
|
@@ -6055,7 +6063,7 @@ registerHandler(formData, async (body, ctx) => {
|
|
|
6055
6063
|
const includeHidden = body.includeHidden ?? false;
|
|
6056
6064
|
const selector = body.selector || "form";
|
|
6057
6065
|
const formCode = `(function() {
|
|
6058
|
-
const form = document.querySelector(${JSON.stringify(selector)});
|
|
6066
|
+
const form = (window.__haltija_resolveSelector || document.querySelector.bind(document))(${JSON.stringify(selector)});
|
|
6059
6067
|
if (!form) return { success: false, error: 'Form not found: ${selector.replace(/'/g, "\\'")}' };
|
|
6060
6068
|
|
|
6061
6069
|
const fields = {};
|
|
@@ -6175,7 +6183,7 @@ registerHandler(scroll, async (body, ctx) => {
|
|
|
6175
6183
|
if (body.selector) {
|
|
6176
6184
|
const code = `
|
|
6177
6185
|
(async () => {
|
|
6178
|
-
const el = document.querySelector(${JSON.stringify(body.selector)});
|
|
6186
|
+
const el = (window.__haltija_resolveSelector || document.querySelector.bind(document))(${JSON.stringify(body.selector)});
|
|
6179
6187
|
if (!el) return { success: false, error: 'Element not found' };
|
|
6180
6188
|
const rect = el.getBoundingClientRect();
|
|
6181
6189
|
const blockAlign = ${JSON.stringify(block)};
|
package/dist/server.js
CHANGED
|
@@ -685,7 +685,7 @@ var injectorCode = `
|
|
|
685
685
|
`;
|
|
686
686
|
|
|
687
687
|
// src/version.ts
|
|
688
|
-
var VERSION = "1.1.
|
|
688
|
+
var VERSION = "1.1.4";
|
|
689
689
|
|
|
690
690
|
// src/embedded-assets.ts
|
|
691
691
|
var APP_MD = `# Haltija App
|
|
@@ -5391,6 +5391,13 @@ function registerHandler(endpoint2, handler) {
|
|
|
5391
5391
|
handlers.set(endpoint2.path, handler);
|
|
5392
5392
|
}
|
|
5393
5393
|
var sleep = (ms) => new Promise((r) => setTimeout(r, ms));
|
|
5394
|
+
function qs(selector) {
|
|
5395
|
+
const s = JSON.stringify(selector);
|
|
5396
|
+
return `(window.__haltija_resolveSelector || document.querySelector.bind(document))(${s})`;
|
|
5397
|
+
}
|
|
5398
|
+
function qsVisible(selector) {
|
|
5399
|
+
return `(function(){var el=${qs(selector)};return !!el && el.offsetParent !== null})()`;
|
|
5400
|
+
}
|
|
5394
5401
|
var SNAPSHOT_CODE = `(function() {
|
|
5395
5402
|
const snapshot = { elements: {}, focused: null, scrollY: window.scrollY, scrollX: window.scrollX };
|
|
5396
5403
|
|
|
@@ -5576,7 +5583,7 @@ registerHandler(click, async (body, ctx) => {
|
|
|
5576
5583
|
if (autoWait) {
|
|
5577
5584
|
const startTime = Date.now();
|
|
5578
5585
|
const pollInterval = 100;
|
|
5579
|
-
const checkCode =
|
|
5586
|
+
const checkCode = qsVisible(selector);
|
|
5580
5587
|
while (Date.now() - startTime < timeout) {
|
|
5581
5588
|
const checkResponse = await ctx.requestFromBrowser("eval", "exec", { code: checkCode }, 5000, windowId);
|
|
5582
5589
|
if (checkResponse.success && checkResponse.data === true) {
|
|
@@ -5621,13 +5628,14 @@ registerHandler(fetchUrl, async (body, ctx) => {
|
|
|
5621
5628
|
registerHandler(call, async (body, ctx) => {
|
|
5622
5629
|
const windowId = body.window || ctx.targetWindowId;
|
|
5623
5630
|
const selector = JSON.stringify(body.selector);
|
|
5631
|
+
const resolveExpr = `(window.__haltija_resolveSelector || document.querySelector.bind(document))(${selector})`;
|
|
5624
5632
|
const method = body.method;
|
|
5625
5633
|
const args = body.args;
|
|
5626
5634
|
let code;
|
|
5627
5635
|
if (args !== undefined) {
|
|
5628
5636
|
const argsJson = JSON.stringify(args);
|
|
5629
5637
|
code = `(function() {
|
|
5630
|
-
const el =
|
|
5638
|
+
const el = ${resolveExpr};
|
|
5631
5639
|
if (!el) return { success: false, error: 'Element not found: ${body.selector.replace(/'/g, "\\'")}' };
|
|
5632
5640
|
if (typeof el[${JSON.stringify(method)}] !== 'function') {
|
|
5633
5641
|
return { success: false, error: 'Method not found: ${method}' };
|
|
@@ -5641,7 +5649,7 @@ registerHandler(call, async (body, ctx) => {
|
|
|
5641
5649
|
})()`;
|
|
5642
5650
|
} else {
|
|
5643
5651
|
code = `(function() {
|
|
5644
|
-
const el =
|
|
5652
|
+
const el = ${resolveExpr};
|
|
5645
5653
|
if (!el) return { success: false, error: 'Element not found: ${body.selector.replace(/'/g, "\\'")}' };
|
|
5646
5654
|
try {
|
|
5647
5655
|
const value = el[${JSON.stringify(method)}];
|
|
@@ -5665,7 +5673,7 @@ registerHandler(drag, async (body, ctx) => {
|
|
|
5665
5673
|
const steps = Math.max(5, Math.floor(duration / 16));
|
|
5666
5674
|
const windowId = body.window || ctx.targetWindowId;
|
|
5667
5675
|
await ctx.requestFromBrowser("eval", "exec", {
|
|
5668
|
-
code:
|
|
5676
|
+
code: `${qs(selector)}?.scrollIntoView({behavior: "smooth", block: "center"})`
|
|
5669
5677
|
}, 5000, windowId);
|
|
5670
5678
|
await sleep(100);
|
|
5671
5679
|
const inspectResponse = await ctx.requestFromBrowser("dom", "inspect", { selector }, 5000, windowId);
|
|
@@ -5711,7 +5719,7 @@ registerHandler(type, async (body, ctx) => {
|
|
|
5711
5719
|
if (autoWait && body.selector) {
|
|
5712
5720
|
const startTime = Date.now();
|
|
5713
5721
|
const pollInterval = 100;
|
|
5714
|
-
const checkCode =
|
|
5722
|
+
const checkCode = qsVisible(body.selector);
|
|
5715
5723
|
while (Date.now() - startTime < waitTimeout) {
|
|
5716
5724
|
const checkResponse = await ctx.requestFromBrowser("eval", "exec", { code: checkCode }, 5000, windowId);
|
|
5717
5725
|
if (checkResponse.success && checkResponse.data === true) {
|
|
@@ -5786,7 +5794,7 @@ registerHandler(inspectAll, async (body, ctx) => {
|
|
|
5786
5794
|
registerHandler(highlight, async (body, ctx) => {
|
|
5787
5795
|
const windowId = body.window || ctx.targetWindowId;
|
|
5788
5796
|
await ctx.requestFromBrowser("eval", "exec", {
|
|
5789
|
-
code:
|
|
5797
|
+
code: `${qs(body.selector)}?.scrollIntoView({behavior: "smooth", block: "center"})`
|
|
5790
5798
|
}, 5000, windowId);
|
|
5791
5799
|
await sleep(100);
|
|
5792
5800
|
const response = await ctx.requestFromBrowser("dom", "highlight", {
|
|
@@ -5958,7 +5966,7 @@ registerHandler(wait, async (body, ctx) => {
|
|
|
5958
5966
|
const startTime = Date.now();
|
|
5959
5967
|
if (body.forElement) {
|
|
5960
5968
|
const selector = body.forElement;
|
|
5961
|
-
const checkCode = hidden ?
|
|
5969
|
+
const checkCode = hidden ? `(function(){var el=${qs(selector)};return !el || el.offsetParent === null})()` : qsVisible(selector);
|
|
5962
5970
|
while (Date.now() - startTime < timeout) {
|
|
5963
5971
|
const checkResponse = await ctx.requestFromBrowser("eval", "exec", { code: checkCode }, 5000, windowId);
|
|
5964
5972
|
if (checkResponse.success && checkResponse.data === true) {
|
|
@@ -6055,7 +6063,7 @@ registerHandler(formData, async (body, ctx) => {
|
|
|
6055
6063
|
const includeHidden = body.includeHidden ?? false;
|
|
6056
6064
|
const selector = body.selector || "form";
|
|
6057
6065
|
const formCode = `(function() {
|
|
6058
|
-
const form = document.querySelector(${JSON.stringify(selector)});
|
|
6066
|
+
const form = (window.__haltija_resolveSelector || document.querySelector.bind(document))(${JSON.stringify(selector)});
|
|
6059
6067
|
if (!form) return { success: false, error: 'Form not found: ${selector.replace(/'/g, "\\'")}' };
|
|
6060
6068
|
|
|
6061
6069
|
const fields = {};
|
|
@@ -6175,7 +6183,7 @@ registerHandler(scroll, async (body, ctx) => {
|
|
|
6175
6183
|
if (body.selector) {
|
|
6176
6184
|
const code = `
|
|
6177
6185
|
(async () => {
|
|
6178
|
-
const el = document.querySelector(${JSON.stringify(body.selector)});
|
|
6186
|
+
const el = (window.__haltija_resolveSelector || document.querySelector.bind(document))(${JSON.stringify(body.selector)});
|
|
6179
6187
|
if (!el) return { success: false, error: 'Element not found' };
|
|
6180
6188
|
const rect = el.getBoundingClientRect();
|
|
6181
6189
|
const blockAlign = ${JSON.stringify(block)};
|