@quanta-intellect/vessel-browser 0.1.35 → 0.1.45
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/README.md +27 -2
- package/out/main/index.js +2178 -347
- package/out/preload/content-script.js +27 -2
- package/out/renderer/assets/{index-IYqP5OYH.js → index-BC3sJqLj.js} +170 -135
- package/out/renderer/index.html +1 -1
- package/package.json +8 -7
|
@@ -3187,12 +3187,33 @@ function vesselExtractContent() {
|
|
|
3187
3187
|
function resolveElementSelector(index) {
|
|
3188
3188
|
return elementSelectors[index] || null;
|
|
3189
3189
|
}
|
|
3190
|
+
function resolveElementIndexBySelector(selector) {
|
|
3191
|
+
if (!selector || typeof selector !== "string") return null;
|
|
3192
|
+
let el = null;
|
|
3193
|
+
try {
|
|
3194
|
+
if (selector.includes(" >>> ")) {
|
|
3195
|
+
el = resolveShadowSelector(selector);
|
|
3196
|
+
} else {
|
|
3197
|
+
el = document.querySelector(selector);
|
|
3198
|
+
}
|
|
3199
|
+
} catch {
|
|
3200
|
+
return null;
|
|
3201
|
+
}
|
|
3202
|
+
if (!el) return null;
|
|
3203
|
+
const existing = indexedElements.get(el);
|
|
3204
|
+
return typeof existing === "number" ? existing : null;
|
|
3205
|
+
}
|
|
3190
3206
|
function interactByIndex(index, action, value) {
|
|
3191
3207
|
const el = indexedElementRefs[index];
|
|
3192
|
-
if (!el || !(el instanceof HTMLElement)) {
|
|
3208
|
+
if (!el || !(el instanceof HTMLElement) || !document.contains(el)) {
|
|
3193
3209
|
return "Error[stale-index]: Element not found — the page may have changed. Call read_page to refresh.";
|
|
3194
3210
|
}
|
|
3195
3211
|
if (action === "click") {
|
|
3212
|
+
el.scrollIntoView({ behavior: "instant", block: "center", inline: "center" });
|
|
3213
|
+
const rect = el.getBoundingClientRect();
|
|
3214
|
+
if (rect.width <= 0 || rect.height <= 0) {
|
|
3215
|
+
return "Error[hidden]: Element has no visible area. It may be inside a collapsed, lazy-loaded, or virtual-scroll section. Scroll toward it, then call read_page to refresh visible elements.";
|
|
3216
|
+
}
|
|
3196
3217
|
el.focus();
|
|
3197
3218
|
el.click();
|
|
3198
3219
|
if (el instanceof HTMLInputElement) {
|
|
@@ -3214,9 +3235,12 @@ function interactByIndex(index, action, value) {
|
|
|
3214
3235
|
}
|
|
3215
3236
|
return `${ariaChecked === "true" ? "Selected" : "Clicked"}: ${label}`;
|
|
3216
3237
|
}
|
|
3217
|
-
|
|
3238
|
+
const anchor = el instanceof HTMLAnchorElement ? el : el.closest("a[href]");
|
|
3239
|
+
const href = anchor instanceof HTMLAnchorElement ? anchor.href : null;
|
|
3240
|
+
return "Clicked: " + (el.getAttribute("aria-label") || el.textContent?.trim().slice(0, 60) || el.tagName.toLowerCase()) + (href ? "\nhref: " + href : "");
|
|
3218
3241
|
}
|
|
3219
3242
|
if (action === "focus") {
|
|
3243
|
+
el.scrollIntoView({ behavior: "instant", block: "center", inline: "center" });
|
|
3220
3244
|
el.focus();
|
|
3221
3245
|
return "Focused: " + (el.getAttribute("aria-label") || el.textContent?.trim().slice(0, 60) || el.tagName.toLowerCase());
|
|
3222
3246
|
}
|
|
@@ -3241,6 +3265,7 @@ function interactByIndex(index, action, value) {
|
|
|
3241
3265
|
electron.contextBridge.exposeInMainWorld("__vessel", {
|
|
3242
3266
|
extractContent: vesselExtractContent,
|
|
3243
3267
|
getElementSelector: resolveElementSelector,
|
|
3268
|
+
getElementIndexBySelector: resolveElementIndexBySelector,
|
|
3244
3269
|
interactByIndex,
|
|
3245
3270
|
resolveShadowSelector,
|
|
3246
3271
|
notifyHighlightSelection: (text) => {
|