@quanta-intellect/vessel-browser 0.1.11 → 0.1.12
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 +6 -3
- package/out/main/index.js +2214 -431
- package/out/preload/content-script.js +61 -17
- package/out/preload/index.js +20 -0
- package/out/renderer/assets/{index-DOCQcMR5.css → index-DMd-y6tm.css} +95 -0
- package/out/renderer/assets/{index-BUYEjb3N.js → index-Do3B3G1W.js} +234 -122
- package/out/renderer/index.html +2 -2
- package/package.json +1 -1
|
@@ -2128,33 +2128,76 @@ const elementSelectors = {};
|
|
|
2128
2128
|
let indexedElements = /* @__PURE__ */ new WeakMap();
|
|
2129
2129
|
const indexedElementRefs = {};
|
|
2130
2130
|
let activeOverlays = [];
|
|
2131
|
-
|
|
2132
|
-
|
|
2133
|
-
|
|
2134
|
-
|
|
2135
|
-
const MAX_DEPTH = 3;
|
|
2131
|
+
const MAX_SHADOW_HOSTS = 150;
|
|
2132
|
+
const MAX_SHADOW_DEPTH = 5;
|
|
2133
|
+
const MAX_WALK_ELEMENTS = 1e4;
|
|
2134
|
+
function collectShadowRoots(root) {
|
|
2136
2135
|
const shadowRoots = [];
|
|
2137
|
-
|
|
2138
|
-
|
|
2139
|
-
|
|
2140
|
-
|
|
2141
|
-
|
|
2136
|
+
let walked = 0;
|
|
2137
|
+
const walk = (node, depth) => {
|
|
2138
|
+
if (depth > MAX_SHADOW_DEPTH || shadowRoots.length >= MAX_SHADOW_HOSTS) return;
|
|
2139
|
+
const tw = document.createTreeWalker(node, NodeFilter.SHOW_ELEMENT);
|
|
2140
|
+
let el = tw.nextNode();
|
|
2141
|
+
while (el && walked < MAX_WALK_ELEMENTS && shadowRoots.length < MAX_SHADOW_HOSTS) {
|
|
2142
|
+
walked++;
|
|
2142
2143
|
if (el.shadowRoot) {
|
|
2143
2144
|
shadowRoots.push(el.shadowRoot);
|
|
2144
|
-
|
|
2145
|
-
}
|
|
2146
|
-
if (el.children.length > 0 && el.children.length < 200) {
|
|
2147
|
-
findShadowRoots(el, depth);
|
|
2145
|
+
walk(el.shadowRoot, depth + 1);
|
|
2148
2146
|
}
|
|
2147
|
+
el = tw.nextNode();
|
|
2149
2148
|
}
|
|
2150
2149
|
};
|
|
2151
|
-
|
|
2152
|
-
|
|
2150
|
+
walk(root, 0);
|
|
2151
|
+
return shadowRoots;
|
|
2152
|
+
}
|
|
2153
|
+
function deepQuerySelectorAll(selector, root = document) {
|
|
2154
|
+
const results = [];
|
|
2155
|
+
root.querySelectorAll(selector).forEach((el) => results.push(el));
|
|
2156
|
+
for (const sr of collectShadowRoots(root)) {
|
|
2153
2157
|
sr.querySelectorAll(selector).forEach((el) => results.push(el));
|
|
2154
2158
|
}
|
|
2155
2159
|
return results;
|
|
2156
2160
|
}
|
|
2161
|
+
function isInShadowDom(el) {
|
|
2162
|
+
return el.getRootNode() instanceof ShadowRoot;
|
|
2163
|
+
}
|
|
2164
|
+
function generateShadowPiercingSelector(el) {
|
|
2165
|
+
const segments = [];
|
|
2166
|
+
let current = el;
|
|
2167
|
+
while (current) {
|
|
2168
|
+
const rootNode = current.getRootNode();
|
|
2169
|
+
const innerSel = generateStableSelector(current);
|
|
2170
|
+
if (rootNode instanceof ShadowRoot) {
|
|
2171
|
+
segments.unshift(innerSel);
|
|
2172
|
+
current = rootNode.host;
|
|
2173
|
+
} else {
|
|
2174
|
+
segments.unshift(innerSel);
|
|
2175
|
+
break;
|
|
2176
|
+
}
|
|
2177
|
+
}
|
|
2178
|
+
if (segments.length <= 1) return null;
|
|
2179
|
+
return segments.join(" >>> ");
|
|
2180
|
+
}
|
|
2181
|
+
function resolveShadowSelector(selectorPath) {
|
|
2182
|
+
const segments = selectorPath.split(" >>> ").map((s) => s.trim());
|
|
2183
|
+
let scope = document;
|
|
2184
|
+
for (let i = 0; i < segments.length; i++) {
|
|
2185
|
+
const el = scope.querySelector(segments[i]);
|
|
2186
|
+
if (!el) return null;
|
|
2187
|
+
if (i < segments.length - 1) {
|
|
2188
|
+
if (!el.shadowRoot) return null;
|
|
2189
|
+
scope = el.shadowRoot;
|
|
2190
|
+
} else {
|
|
2191
|
+
return el;
|
|
2192
|
+
}
|
|
2193
|
+
}
|
|
2194
|
+
return null;
|
|
2195
|
+
}
|
|
2157
2196
|
function generateSelector(el) {
|
|
2197
|
+
if (isInShadowDom(el)) {
|
|
2198
|
+
const shadowPath = generateShadowPiercingSelector(el);
|
|
2199
|
+
if (shadowPath) return shadowPath;
|
|
2200
|
+
}
|
|
2158
2201
|
return generateStableSelector(el);
|
|
2159
2202
|
}
|
|
2160
2203
|
function assignIndex(el) {
|
|
@@ -2672,7 +2715,7 @@ function extractLandmarks() {
|
|
|
2672
2715
|
"dialog, [role='dialog'], [role='alertdialog']"
|
|
2673
2716
|
];
|
|
2674
2717
|
selectors.forEach((selector) => {
|
|
2675
|
-
|
|
2718
|
+
deepQuerySelectorAll(selector).forEach((el) => {
|
|
2676
2719
|
const tag = el.tagName.toLowerCase();
|
|
2677
2720
|
const role = el.getAttribute("role") || (tag === "header" ? "banner" : tag === "nav" ? "navigation" : tag === "main" ? "main" : tag === "aside" ? "complementary" : tag === "footer" ? "contentinfo" : tag === "article" ? "article" : tag === "section" ? "region" : tag === "dialog" ? "dialog" : "generic");
|
|
2678
2721
|
landmarks.push({
|
|
@@ -2896,6 +2939,7 @@ electron.contextBridge.exposeInMainWorld("__vessel", {
|
|
|
2896
2939
|
extractContent: vesselExtractContent,
|
|
2897
2940
|
getElementSelector: resolveElementSelector,
|
|
2898
2941
|
interactByIndex,
|
|
2942
|
+
resolveShadowSelector,
|
|
2899
2943
|
notifyHighlightSelection: (text) => {
|
|
2900
2944
|
if (typeof text === "string" && text.trim()) {
|
|
2901
2945
|
electron.ipcRenderer.send("vessel:highlight-selection", text.trim());
|
package/out/preload/index.js
CHANGED
|
@@ -35,6 +35,7 @@ const Channels = {
|
|
|
35
35
|
SIDEBAR_RESIZE: "ui:sidebar-resize",
|
|
36
36
|
SIDEBAR_RESIZE_START: "ui:sidebar-resize-start",
|
|
37
37
|
SIDEBAR_RESIZE_COMMIT: "ui:sidebar-resize-commit",
|
|
38
|
+
SIDEBAR_CONTEXT_MENU: "ui:sidebar-context-menu",
|
|
38
39
|
FOCUS_MODE_TOGGLE: "ui:focus-mode-toggle",
|
|
39
40
|
SETTINGS_VISIBILITY: "ui:settings-visibility",
|
|
40
41
|
// Settings
|
|
@@ -53,6 +54,11 @@ const Channels = {
|
|
|
53
54
|
// Highlights
|
|
54
55
|
HIGHLIGHT_CAPTURE: "highlights:capture",
|
|
55
56
|
HIGHLIGHT_CAPTURE_RESULT: "highlights:capture-result",
|
|
57
|
+
HIGHLIGHT_NAV_COUNT: "highlights:nav-count",
|
|
58
|
+
HIGHLIGHT_NAV_SCROLL: "highlights:nav-scroll",
|
|
59
|
+
HIGHLIGHT_NAV_REMOVE: "highlights:nav-remove",
|
|
60
|
+
HIGHLIGHT_NAV_CLEAR: "highlights:nav-clear",
|
|
61
|
+
SIDEBAR_HIGHLIGHT_ACTION: "highlights:sidebar-action",
|
|
56
62
|
// DevTools panel
|
|
57
63
|
DEVTOOLS_PANEL_TOGGLE: "devtools-panel:toggle",
|
|
58
64
|
DEVTOOLS_PANEL_STATE: "devtools-panel:state",
|
|
@@ -120,6 +126,15 @@ const api = {
|
|
|
120
126
|
const handler = (_, result) => cb(result);
|
|
121
127
|
electron.ipcRenderer.on(Channels.HIGHLIGHT_CAPTURE_RESULT, handler);
|
|
122
128
|
return () => electron.ipcRenderer.removeListener(Channels.HIGHLIGHT_CAPTURE_RESULT, handler);
|
|
129
|
+
},
|
|
130
|
+
getCount: () => electron.ipcRenderer.invoke(Channels.HIGHLIGHT_NAV_COUNT),
|
|
131
|
+
scrollTo: (index) => electron.ipcRenderer.invoke(Channels.HIGHLIGHT_NAV_SCROLL, index),
|
|
132
|
+
remove: (index) => electron.ipcRenderer.invoke(Channels.HIGHLIGHT_NAV_REMOVE, index),
|
|
133
|
+
clearAll: () => electron.ipcRenderer.invoke(Channels.HIGHLIGHT_NAV_CLEAR),
|
|
134
|
+
onSidebarAction: (cb) => {
|
|
135
|
+
const handler = (_, action) => cb(action);
|
|
136
|
+
electron.ipcRenderer.on(Channels.SIDEBAR_HIGHLIGHT_ACTION, handler);
|
|
137
|
+
return () => electron.ipcRenderer.removeListener(Channels.SIDEBAR_HIGHLIGHT_ACTION, handler);
|
|
123
138
|
}
|
|
124
139
|
},
|
|
125
140
|
ui: {
|
|
@@ -127,6 +142,11 @@ const api = {
|
|
|
127
142
|
startSidebarResize: () => electron.ipcRenderer.invoke(Channels.SIDEBAR_RESIZE_START),
|
|
128
143
|
resizeSidebar: (width) => electron.ipcRenderer.invoke(Channels.SIDEBAR_RESIZE, width),
|
|
129
144
|
commitSidebarResize: () => electron.ipcRenderer.invoke(Channels.SIDEBAR_RESIZE_COMMIT),
|
|
145
|
+
onSidebarContextMenu: (cb) => {
|
|
146
|
+
const handler = (_, position) => cb(position);
|
|
147
|
+
electron.ipcRenderer.on(Channels.SIDEBAR_CONTEXT_MENU, handler);
|
|
148
|
+
return () => electron.ipcRenderer.removeListener(Channels.SIDEBAR_CONTEXT_MENU, handler);
|
|
149
|
+
},
|
|
130
150
|
toggleFocusMode: () => electron.ipcRenderer.invoke(Channels.FOCUS_MODE_TOGGLE),
|
|
131
151
|
setSettingsVisibility: (open) => electron.ipcRenderer.invoke(Channels.SETTINGS_VISIBILITY, open)
|
|
132
152
|
},
|
|
@@ -2533,6 +2533,101 @@
|
|
|
2533
2533
|
border-color: var(--border-visible);
|
|
2534
2534
|
}
|
|
2535
2535
|
|
|
2536
|
+
/* ═══════════════════════════════════════
|
|
2537
|
+
Highlight navigation bar
|
|
2538
|
+
═══════════════════════════════════════ */
|
|
2539
|
+
|
|
2540
|
+
.highlight-nav {
|
|
2541
|
+
display: flex;
|
|
2542
|
+
align-items: center;
|
|
2543
|
+
justify-content: flex-end;
|
|
2544
|
+
gap: 2px;
|
|
2545
|
+
padding: 4px 14px;
|
|
2546
|
+
flex-shrink: 0;
|
|
2547
|
+
}
|
|
2548
|
+
|
|
2549
|
+
.highlight-nav-btn {
|
|
2550
|
+
display: inline-flex;
|
|
2551
|
+
align-items: center;
|
|
2552
|
+
justify-content: center;
|
|
2553
|
+
width: 24px;
|
|
2554
|
+
height: 24px;
|
|
2555
|
+
padding: 0;
|
|
2556
|
+
color: var(--text-muted);
|
|
2557
|
+
background: transparent;
|
|
2558
|
+
border: 1px solid transparent;
|
|
2559
|
+
border-radius: var(--radius-sm);
|
|
2560
|
+
cursor: pointer;
|
|
2561
|
+
transition: color var(--duration-fast) var(--ease-in-out),
|
|
2562
|
+
background var(--duration-fast) var(--ease-in-out);
|
|
2563
|
+
}
|
|
2564
|
+
|
|
2565
|
+
.highlight-nav-btn:hover:not(:disabled) {
|
|
2566
|
+
color: var(--text-primary);
|
|
2567
|
+
background: var(--bg-tertiary);
|
|
2568
|
+
}
|
|
2569
|
+
|
|
2570
|
+
.highlight-nav-btn:disabled {
|
|
2571
|
+
opacity: 0.3;
|
|
2572
|
+
cursor: default;
|
|
2573
|
+
}
|
|
2574
|
+
|
|
2575
|
+
.highlight-nav-label {
|
|
2576
|
+
display: inline-flex;
|
|
2577
|
+
align-items: center;
|
|
2578
|
+
gap: 5px;
|
|
2579
|
+
padding: 3px 10px;
|
|
2580
|
+
font-size: 11px;
|
|
2581
|
+
font-weight: 500;
|
|
2582
|
+
color: rgba(196, 160, 90, 0.85);
|
|
2583
|
+
background: rgba(196, 160, 90, 0.08);
|
|
2584
|
+
border: 1px solid rgba(196, 160, 90, 0.2);
|
|
2585
|
+
border-radius: var(--radius-md);
|
|
2586
|
+
cursor: pointer;
|
|
2587
|
+
transition: background var(--duration-fast) var(--ease-in-out),
|
|
2588
|
+
border-color var(--duration-fast) var(--ease-in-out);
|
|
2589
|
+
white-space: nowrap;
|
|
2590
|
+
}
|
|
2591
|
+
|
|
2592
|
+
.highlight-nav-label:hover {
|
|
2593
|
+
background: rgba(196, 160, 90, 0.14);
|
|
2594
|
+
border-color: rgba(196, 160, 90, 0.35);
|
|
2595
|
+
}
|
|
2596
|
+
|
|
2597
|
+
.hl-context-menu {
|
|
2598
|
+
position: fixed;
|
|
2599
|
+
z-index: 9999;
|
|
2600
|
+
min-width: 160px;
|
|
2601
|
+
padding: 4px 0;
|
|
2602
|
+
background: var(--bg-secondary);
|
|
2603
|
+
border: 1px solid var(--border-visible);
|
|
2604
|
+
border-radius: var(--radius-md);
|
|
2605
|
+
box-shadow: 0 4px 16px rgba(0, 0, 0, 0.4);
|
|
2606
|
+
}
|
|
2607
|
+
|
|
2608
|
+
.hl-context-item {
|
|
2609
|
+
display: block;
|
|
2610
|
+
width: 100%;
|
|
2611
|
+
padding: 6px 12px;
|
|
2612
|
+
font-size: 11.5px;
|
|
2613
|
+
color: var(--text-secondary);
|
|
2614
|
+
background: transparent;
|
|
2615
|
+
border: none;
|
|
2616
|
+
cursor: pointer;
|
|
2617
|
+
text-align: left;
|
|
2618
|
+
transition: background var(--duration-fast) var(--ease-in-out);
|
|
2619
|
+
}
|
|
2620
|
+
|
|
2621
|
+
.hl-context-item:hover {
|
|
2622
|
+
background: rgba(255, 255, 255, 0.06);
|
|
2623
|
+
color: var(--text-primary);
|
|
2624
|
+
}
|
|
2625
|
+
|
|
2626
|
+
.hl-context-danger:hover {
|
|
2627
|
+
color: #e06060;
|
|
2628
|
+
background: rgba(224, 96, 96, 0.08);
|
|
2629
|
+
}
|
|
2630
|
+
|
|
2536
2631
|
.sidebar-input-area {
|
|
2537
2632
|
display: flex;
|
|
2538
2633
|
gap: 6px;
|