@quanta-intellect/vessel-browser 0.1.84 → 0.1.88
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 +8 -0
- package/out/main/index.js +183 -117
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -182,6 +182,14 @@ The packaged AppImage path:
|
|
|
182
182
|
- uses the packaged Vessel app icon and metadata
|
|
183
183
|
- is the recommended path for early adopters who just want to run Vessel
|
|
184
184
|
|
|
185
|
+
Windows packaged releases:
|
|
186
|
+
|
|
187
|
+
- use the `Vessel-<version>-x64-setup.exe` NSIS installer
|
|
188
|
+
- can be installed over an existing Vessel install when upgrading
|
|
189
|
+
- preserve Vessel app data during the normal upgrade path
|
|
190
|
+
|
|
191
|
+
You do not need to uninstall Vessel before installing a newer Windows release. Uninstall first only if you are recovering from a broken install or intentionally removing local Vessel data.
|
|
192
|
+
|
|
185
193
|
After install:
|
|
186
194
|
|
|
187
195
|
```bash
|
package/out/main/index.js
CHANGED
|
@@ -616,7 +616,7 @@ class Tab {
|
|
|
616
616
|
var el = document.elementFromPoint(${x}, ${y});
|
|
617
617
|
while (el) {
|
|
618
618
|
if (el.hasAttribute && el.hasAttribute('data-vessel-highlight')) {
|
|
619
|
-
return el.textContent || '';
|
|
619
|
+
return el.getAttribute('data-vessel-highlight-text') || el.textContent || '';
|
|
620
620
|
}
|
|
621
621
|
el = el.parentElement;
|
|
622
622
|
}
|
|
@@ -931,6 +931,7 @@ class Tab {
|
|
|
931
931
|
mark.style.setProperty('background', 'rgba(240, 198, 54, 0.3)', 'important');
|
|
932
932
|
mark.style.setProperty('border-bottom-color', '#f0c636', 'important');
|
|
933
933
|
mark.setAttribute('data-vessel-highlight', 'true');
|
|
934
|
+
mark.setAttribute('data-vessel-highlight-text', text);
|
|
934
935
|
range.surroundContents(mark);
|
|
935
936
|
} else {
|
|
936
937
|
// For cross-node selections, extract and wrap in a mark
|
|
@@ -939,6 +940,7 @@ class Tab {
|
|
|
939
940
|
mark.style.setProperty('background', 'rgba(240, 198, 54, 0.3)', 'important');
|
|
940
941
|
mark.style.setProperty('border-bottom-color', '#f0c636', 'important');
|
|
941
942
|
mark.setAttribute('data-vessel-highlight', 'true');
|
|
943
|
+
mark.setAttribute('data-vessel-highlight-text', text);
|
|
942
944
|
var contents = range.extractContents();
|
|
943
945
|
mark.appendChild(contents);
|
|
944
946
|
range.insertNode(mark);
|
|
@@ -1215,6 +1217,134 @@ for (var cr = 0; cr < contentRoots.length; cr++) {
|
|
|
1215
1217
|
if (contentRoot) break;
|
|
1216
1218
|
}`;
|
|
1217
1219
|
const NAV_ANCESTORS_JS = `var NAV_ANCESTORS = 'nav, aside, footer, header, [role="navigation"], [role="complementary"], .sidebar, .navbox, .infobox, figcaption, .thumbcaption, .mw-jump-link';`;
|
|
1220
|
+
const TEXT_MATCH_HELPERS_JS = `
|
|
1221
|
+
function normalizeHighlightSearchText(value) {
|
|
1222
|
+
return String(value || '').replace(/\\s+/g, ' ').trim().toLowerCase();
|
|
1223
|
+
}
|
|
1224
|
+
|
|
1225
|
+
function isHighlightableTextNode(n) {
|
|
1226
|
+
var p = n.parentElement;
|
|
1227
|
+
if (!p) return false;
|
|
1228
|
+
if (SKIP_TAGS[p.tagName]) return false;
|
|
1229
|
+
if (p.closest('[data-vessel-highlight]')) return false;
|
|
1230
|
+
if (p.closest(NAV_ANCESTORS)) return false;
|
|
1231
|
+
var style = window.getComputedStyle(p);
|
|
1232
|
+
if (style.display === 'none' || style.visibility === 'hidden' || style.opacity === '0') return false;
|
|
1233
|
+
if (p.offsetWidth === 0 && p.offsetHeight === 0) return false;
|
|
1234
|
+
return true;
|
|
1235
|
+
}
|
|
1236
|
+
|
|
1237
|
+
function collectTextRangeMatches(root, searchText, limit) {
|
|
1238
|
+
var normalizedSearch = normalizeHighlightSearchText(searchText);
|
|
1239
|
+
if (!root || !normalizedSearch) return [];
|
|
1240
|
+
var normalized = '';
|
|
1241
|
+
var map = [];
|
|
1242
|
+
var w = document.createTreeWalker(root, NodeFilter.SHOW_TEXT, {
|
|
1243
|
+
acceptNode: function(n) {
|
|
1244
|
+
return isHighlightableTextNode(n)
|
|
1245
|
+
? NodeFilter.FILTER_ACCEPT
|
|
1246
|
+
: NodeFilter.FILTER_REJECT;
|
|
1247
|
+
}
|
|
1248
|
+
});
|
|
1249
|
+
var n;
|
|
1250
|
+
while ((n = w.nextNode())) {
|
|
1251
|
+
var text = n.textContent || '';
|
|
1252
|
+
for (var i = 0; i < text.length; i++) {
|
|
1253
|
+
var ch = text.charAt(i);
|
|
1254
|
+
if (/\\s/.test(ch)) {
|
|
1255
|
+
if (normalized.length === 0 || normalized.charAt(normalized.length - 1) === ' ') {
|
|
1256
|
+
continue;
|
|
1257
|
+
}
|
|
1258
|
+
normalized += ' ';
|
|
1259
|
+
} else {
|
|
1260
|
+
normalized += ch.toLowerCase();
|
|
1261
|
+
}
|
|
1262
|
+
map.push({ node: n, offset: i });
|
|
1263
|
+
}
|
|
1264
|
+
}
|
|
1265
|
+
var matches = [];
|
|
1266
|
+
var from = 0;
|
|
1267
|
+
while (matches.length < limit) {
|
|
1268
|
+
var idx = normalized.indexOf(normalizedSearch, from);
|
|
1269
|
+
if (idx === -1) break;
|
|
1270
|
+
var start = map[idx];
|
|
1271
|
+
var end = map[idx + normalizedSearch.length - 1];
|
|
1272
|
+
if (start && end) {
|
|
1273
|
+
matches.push({
|
|
1274
|
+
startNode: start.node,
|
|
1275
|
+
startOffset: start.offset,
|
|
1276
|
+
endNode: end.node,
|
|
1277
|
+
endOffset: end.offset + 1,
|
|
1278
|
+
});
|
|
1279
|
+
}
|
|
1280
|
+
from = idx + Math.max(1, normalizedSearch.length);
|
|
1281
|
+
}
|
|
1282
|
+
return matches;
|
|
1283
|
+
}
|
|
1284
|
+
|
|
1285
|
+
function collectTextSegmentsForMatch(match) {
|
|
1286
|
+
var segments = [];
|
|
1287
|
+
var inRange = false;
|
|
1288
|
+
var w = document.createTreeWalker(document.body, NodeFilter.SHOW_TEXT, {
|
|
1289
|
+
acceptNode: function(n) {
|
|
1290
|
+
return isHighlightableTextNode(n) || n === match.startNode || n === match.endNode
|
|
1291
|
+
? NodeFilter.FILTER_ACCEPT
|
|
1292
|
+
: NodeFilter.FILTER_REJECT;
|
|
1293
|
+
}
|
|
1294
|
+
});
|
|
1295
|
+
var n;
|
|
1296
|
+
while ((n = w.nextNode())) {
|
|
1297
|
+
if (n === match.startNode) inRange = true;
|
|
1298
|
+
if (!inRange) continue;
|
|
1299
|
+
segments.push({
|
|
1300
|
+
node: n,
|
|
1301
|
+
start: n === match.startNode ? match.startOffset : 0,
|
|
1302
|
+
end: n === match.endNode ? match.endOffset : (n.textContent || '').length,
|
|
1303
|
+
});
|
|
1304
|
+
if (n === match.endNode) break;
|
|
1305
|
+
}
|
|
1306
|
+
return segments;
|
|
1307
|
+
}
|
|
1308
|
+
|
|
1309
|
+
function markTextSegment(segment, solidColor, bgColor, fullText) {
|
|
1310
|
+
if (!segment.node || segment.end <= segment.start) return null;
|
|
1311
|
+
var parent = segment.node.parentNode;
|
|
1312
|
+
if (!parent) return null;
|
|
1313
|
+
var text = segment.node.textContent || '';
|
|
1314
|
+
var selected = text.slice(segment.start, segment.end);
|
|
1315
|
+
if (!selected) return null;
|
|
1316
|
+
var mark = document.createElement('mark');
|
|
1317
|
+
mark.className = '__vessel-highlight-text';
|
|
1318
|
+
mark.style.setProperty('background', bgColor, 'important');
|
|
1319
|
+
mark.style.setProperty('border-bottom-color', solidColor, 'important');
|
|
1320
|
+
mark.setAttribute('data-vessel-highlight', 'true');
|
|
1321
|
+
if (fullText) {
|
|
1322
|
+
mark.setAttribute('data-vessel-highlight-text', fullText);
|
|
1323
|
+
}
|
|
1324
|
+
mark.textContent = selected;
|
|
1325
|
+
if (segment.start > 0) {
|
|
1326
|
+
parent.insertBefore(document.createTextNode(text.slice(0, segment.start)), segment.node);
|
|
1327
|
+
}
|
|
1328
|
+
parent.insertBefore(mark, segment.node);
|
|
1329
|
+
if (segment.end < text.length) {
|
|
1330
|
+
parent.insertBefore(document.createTextNode(text.slice(segment.end)), segment.node);
|
|
1331
|
+
}
|
|
1332
|
+
parent.removeChild(segment.node);
|
|
1333
|
+
return mark;
|
|
1334
|
+
}
|
|
1335
|
+
|
|
1336
|
+
function applyTextRangeMatch(match, solidColor, bgColor, fullText) {
|
|
1337
|
+
var segments = collectTextSegmentsForMatch(match);
|
|
1338
|
+
var marks = [];
|
|
1339
|
+
for (var i = segments.length - 1; i >= 0; i--) {
|
|
1340
|
+
try {
|
|
1341
|
+
var mark = markTextSegment(segments[i], solidColor, bgColor, fullText);
|
|
1342
|
+
if (mark) marks.unshift(mark);
|
|
1343
|
+
} catch (_e) {}
|
|
1344
|
+
}
|
|
1345
|
+
return marks;
|
|
1346
|
+
}
|
|
1347
|
+
`;
|
|
1218
1348
|
const HIGHLIGHT_COLORS = {
|
|
1219
1349
|
yellow: {
|
|
1220
1350
|
solid: "#f0c636",
|
|
@@ -1299,8 +1429,7 @@ const VESSEL_HIGHLIGHT_CSS = `
|
|
|
1299
1429
|
opacity: 1;
|
|
1300
1430
|
}
|
|
1301
1431
|
`;
|
|
1302
|
-
async function
|
|
1303
|
-
const c = resolveColor(color);
|
|
1432
|
+
async function ensureHighlightStyles(wc) {
|
|
1304
1433
|
await wc.executeJavaScript(`
|
|
1305
1434
|
(function() {
|
|
1306
1435
|
if (!document.getElementById('__vessel-highlight-styles')) {
|
|
@@ -1309,6 +1438,14 @@ async function highlightOnPage(wc, resolvedSelector, text, label, durationMs, co
|
|
|
1309
1438
|
s.textContent = ${JSON.stringify(VESSEL_HIGHLIGHT_CSS)};
|
|
1310
1439
|
document.head.appendChild(s);
|
|
1311
1440
|
}
|
|
1441
|
+
})()
|
|
1442
|
+
`);
|
|
1443
|
+
}
|
|
1444
|
+
async function highlightOnPage(wc, resolvedSelector, text, label, durationMs, color) {
|
|
1445
|
+
const c = resolveColor(color);
|
|
1446
|
+
await ensureHighlightStyles(wc);
|
|
1447
|
+
await wc.executeJavaScript(`
|
|
1448
|
+
(function() {
|
|
1312
1449
|
if (!window.__vesselHighlightLabelManager) {
|
|
1313
1450
|
var overlap = function(a, b) {
|
|
1314
1451
|
return a.left < b.right && a.right > b.left && a.top < b.bottom && a.bottom > b.top;
|
|
@@ -1438,7 +1575,6 @@ async function highlightOnPage(wc, resolvedSelector, text, label, durationMs, co
|
|
|
1438
1575
|
return wc.executeJavaScript(`
|
|
1439
1576
|
(function() {
|
|
1440
1577
|
var searchText = (${JSON.stringify(text)} || '').trim();
|
|
1441
|
-
var foldedSearchText = searchText.toLowerCase();
|
|
1442
1578
|
var solidColor = ${JSON.stringify(c.solid)};
|
|
1443
1579
|
var bgColor = ${JSON.stringify(c.bg)};
|
|
1444
1580
|
var labelBg = ${JSON.stringify(c.label)};
|
|
@@ -1450,60 +1586,22 @@ async function highlightOnPage(wc, resolvedSelector, text, label, durationMs, co
|
|
|
1450
1586
|
${SKIP_TAGS_JS}
|
|
1451
1587
|
${CONTENT_ROOTS_JS}
|
|
1452
1588
|
${NAV_ANCESTORS_JS}
|
|
1453
|
-
|
|
1454
|
-
function collectMatches(root, limit) {
|
|
1455
|
-
var matches = [];
|
|
1456
|
-
var w = document.createTreeWalker(root, NodeFilter.SHOW_TEXT, {
|
|
1457
|
-
acceptNode: function(n) {
|
|
1458
|
-
var p = n.parentElement;
|
|
1459
|
-
if (!p) return NodeFilter.FILTER_REJECT;
|
|
1460
|
-
if (SKIP_TAGS[p.tagName]) return NodeFilter.FILTER_REJECT;
|
|
1461
|
-
if (p.closest('[data-vessel-highlight]')) return NodeFilter.FILTER_REJECT;
|
|
1462
|
-
if (p.closest(NAV_ANCESTORS)) return NodeFilter.FILTER_REJECT;
|
|
1463
|
-
var style = window.getComputedStyle(p);
|
|
1464
|
-
if (style.display === 'none' || style.visibility === 'hidden' || style.opacity === '0') return NodeFilter.FILTER_REJECT;
|
|
1465
|
-
if (p.offsetWidth === 0 && p.offsetHeight === 0) return NodeFilter.FILTER_REJECT;
|
|
1466
|
-
return NodeFilter.FILTER_ACCEPT;
|
|
1467
|
-
}
|
|
1468
|
-
});
|
|
1469
|
-
var n;
|
|
1470
|
-
while ((n = w.nextNode())) {
|
|
1471
|
-
var haystack = n.textContent || '';
|
|
1472
|
-
var idx = haystack.indexOf(searchText);
|
|
1473
|
-
if (idx === -1 && foldedSearchText) {
|
|
1474
|
-
idx = haystack.toLowerCase().indexOf(foldedSearchText);
|
|
1475
|
-
}
|
|
1476
|
-
if (idx !== -1) {
|
|
1477
|
-
matches.push({ node: n, idx: idx });
|
|
1478
|
-
if (matches.length >= limit) break;
|
|
1479
|
-
}
|
|
1480
|
-
}
|
|
1481
|
-
return matches;
|
|
1482
|
-
}
|
|
1589
|
+
${TEXT_MATCH_HELPERS_JS}
|
|
1483
1590
|
|
|
1484
1591
|
// First try: match inside main content area (skip nav/sidebar/captions)
|
|
1485
|
-
var
|
|
1592
|
+
var textMatches = contentRoot ? collectTextRangeMatches(contentRoot, searchText, 20) : [];
|
|
1486
1593
|
// Fallback: if no matches in content area, search the whole body
|
|
1487
|
-
if (
|
|
1488
|
-
|
|
1594
|
+
if (textMatches.length === 0) {
|
|
1595
|
+
textMatches = collectTextRangeMatches(document.body, searchText, 20);
|
|
1489
1596
|
}
|
|
1490
1597
|
var count = 0;
|
|
1491
1598
|
var firstMark = null;
|
|
1492
|
-
for (var i =
|
|
1493
|
-
var
|
|
1494
|
-
|
|
1495
|
-
|
|
1496
|
-
range.setStart(match.node, match.idx);
|
|
1497
|
-
range.setEnd(match.node, match.idx + searchText.length);
|
|
1498
|
-
var mark = document.createElement('mark');
|
|
1499
|
-
mark.className = '__vessel-highlight-text';
|
|
1500
|
-
mark.style.setProperty('background', bgColor, 'important');
|
|
1501
|
-
mark.style.setProperty('border-bottom-color', solidColor, 'important');
|
|
1502
|
-
mark.setAttribute('data-vessel-highlight', 'true');
|
|
1503
|
-
range.surroundContents(mark);
|
|
1504
|
-
if (!firstMark) firstMark = mark;
|
|
1599
|
+
for (var i = textMatches.length - 1; i >= 0; i--) {
|
|
1600
|
+
var marks = applyTextRangeMatch(textMatches[i], solidColor, bgColor, searchText);
|
|
1601
|
+
if (marks.length > 0) {
|
|
1602
|
+
firstMark = marks[0];
|
|
1505
1603
|
count++;
|
|
1506
|
-
}
|
|
1604
|
+
}
|
|
1507
1605
|
}
|
|
1508
1606
|
if (count === 0) return 'Text not found: ' + searchText.slice(0, 80);
|
|
1509
1607
|
if (firstMark) firstMark.scrollIntoView({ behavior: 'smooth', block: 'center' });
|
|
@@ -1552,72 +1650,26 @@ async function highlightBatchOnPage(wc, entries) {
|
|
|
1552
1650
|
color: resolveColor(e.color)
|
|
1553
1651
|
}));
|
|
1554
1652
|
if (serialized.length === 0) return;
|
|
1653
|
+
await ensureHighlightStyles(wc);
|
|
1555
1654
|
await wc.executeJavaScript(`
|
|
1556
1655
|
(function() {
|
|
1557
|
-
if (!document.getElementById('__vessel-highlight-styles')) {
|
|
1558
|
-
var s = document.createElement('style');
|
|
1559
|
-
s.id = '__vessel-highlight-styles';
|
|
1560
|
-
s.textContent = ${JSON.stringify(VESSEL_HIGHLIGHT_CSS)};
|
|
1561
|
-
document.head.appendChild(s);
|
|
1562
|
-
}
|
|
1563
1656
|
var entries = ${JSON.stringify(serialized)};
|
|
1564
1657
|
${SKIP_TAGS_JS}
|
|
1565
1658
|
${CONTENT_ROOTS_JS}
|
|
1566
1659
|
${NAV_ANCESTORS_JS}
|
|
1567
|
-
|
|
1568
|
-
function collectMatches(root, searchText, foldedSearchText, limit) {
|
|
1569
|
-
var matches = [];
|
|
1570
|
-
var w = document.createTreeWalker(root, NodeFilter.SHOW_TEXT, {
|
|
1571
|
-
acceptNode: function(n) {
|
|
1572
|
-
var p = n.parentElement;
|
|
1573
|
-
if (!p) return NodeFilter.FILTER_REJECT;
|
|
1574
|
-
if (SKIP_TAGS[p.tagName]) return NodeFilter.FILTER_REJECT;
|
|
1575
|
-
if (p.closest('[data-vessel-highlight]')) return NodeFilter.FILTER_REJECT;
|
|
1576
|
-
if (p.closest(NAV_ANCESTORS)) return NodeFilter.FILTER_REJECT;
|
|
1577
|
-
var style = window.getComputedStyle(p);
|
|
1578
|
-
if (style.display === 'none' || style.visibility === 'hidden' || style.opacity === '0') return NodeFilter.FILTER_REJECT;
|
|
1579
|
-
if (p.offsetWidth === 0 && p.offsetHeight === 0) return NodeFilter.FILTER_REJECT;
|
|
1580
|
-
return NodeFilter.FILTER_ACCEPT;
|
|
1581
|
-
}
|
|
1582
|
-
});
|
|
1583
|
-
var n;
|
|
1584
|
-
while ((n = w.nextNode())) {
|
|
1585
|
-
var haystack = n.textContent || '';
|
|
1586
|
-
var idx = haystack.indexOf(searchText);
|
|
1587
|
-
if (idx === -1 && foldedSearchText) {
|
|
1588
|
-
idx = haystack.toLowerCase().indexOf(foldedSearchText);
|
|
1589
|
-
}
|
|
1590
|
-
if (idx !== -1) {
|
|
1591
|
-
matches.push({ node: n, idx: idx });
|
|
1592
|
-
if (matches.length >= limit) break;
|
|
1593
|
-
}
|
|
1594
|
-
}
|
|
1595
|
-
return matches;
|
|
1596
|
-
}
|
|
1660
|
+
${TEXT_MATCH_HELPERS_JS}
|
|
1597
1661
|
|
|
1598
1662
|
for (var e = 0; e < entries.length; e++) {
|
|
1599
1663
|
var entry = entries[e];
|
|
1600
1664
|
var c = entry.color;
|
|
1601
1665
|
if (entry.text) {
|
|
1602
1666
|
var searchText = (entry.text || '').trim();
|
|
1603
|
-
var
|
|
1604
|
-
|
|
1605
|
-
|
|
1606
|
-
textNodes = collectMatches(document.body, searchText, foldedSearchText, 20);
|
|
1667
|
+
var textMatches = contentRoot ? collectTextRangeMatches(contentRoot, searchText, 20) : [];
|
|
1668
|
+
if (textMatches.length === 0) {
|
|
1669
|
+
textMatches = collectTextRangeMatches(document.body, searchText, 20);
|
|
1607
1670
|
}
|
|
1608
|
-
for (var i =
|
|
1609
|
-
|
|
1610
|
-
var match = textNodes[i];
|
|
1611
|
-
var range = document.createRange();
|
|
1612
|
-
range.setStart(match.node, match.idx);
|
|
1613
|
-
range.setEnd(match.node, match.idx + searchText.length);
|
|
1614
|
-
var mark = document.createElement('mark');
|
|
1615
|
-
mark.className = '__vessel-highlight-text';
|
|
1616
|
-
mark.style.setProperty('background', c.bg, 'important');
|
|
1617
|
-
mark.style.setProperty('border-bottom-color', c.solid, 'important');
|
|
1618
|
-
mark.setAttribute('data-vessel-highlight', 'true');
|
|
1619
|
-
range.surroundContents(mark);
|
|
1620
|
-
} catch (_e) {}
|
|
1671
|
+
for (var i = textMatches.length - 1; i >= 0; i--) {
|
|
1672
|
+
applyTextRangeMatch(textMatches[i], c.solid, c.bg, searchText);
|
|
1621
1673
|
}
|
|
1622
1674
|
} else if (entry.selector) {
|
|
1623
1675
|
try {
|
|
@@ -1704,6 +1756,8 @@ async function clearAllHighlightElements(wc) {
|
|
|
1704
1756
|
el.style.removeProperty('outline');
|
|
1705
1757
|
el.style.removeProperty('outline-offset');
|
|
1706
1758
|
});
|
|
1759
|
+
var style = document.getElementById('__vessel-highlight-styles');
|
|
1760
|
+
if (style) style.remove();
|
|
1707
1761
|
return true;
|
|
1708
1762
|
})()
|
|
1709
1763
|
`);
|
|
@@ -3210,7 +3264,8 @@ class TabManager {
|
|
|
3210
3264
|
`(function() {
|
|
3211
3265
|
var marks = document.querySelectorAll('mark.__vessel-highlight-text[data-vessel-highlight]');
|
|
3212
3266
|
marks.forEach(function(m) {
|
|
3213
|
-
|
|
3267
|
+
var highlightText = m.getAttribute('data-vessel-highlight-text') || m.textContent;
|
|
3268
|
+
if (highlightText === ${JSON.stringify(text)}) {
|
|
3214
3269
|
var parent = m.parentNode;
|
|
3215
3270
|
while (m.firstChild) parent.insertBefore(m.firstChild, m);
|
|
3216
3271
|
m.remove();
|
|
@@ -12311,7 +12366,10 @@ async function captureLiveHighlightSnapshot(wc, savedHighlights = []) {
|
|
|
12311
12366
|
const pageHighlights = Array.from(
|
|
12312
12367
|
document.querySelectorAll("mark.__vessel-highlight-text[data-vessel-highlight]")
|
|
12313
12368
|
).map((mark) => {
|
|
12314
|
-
const text =
|
|
12369
|
+
const text =
|
|
12370
|
+
mark.getAttribute("data-vessel-highlight-text")?.trim() ||
|
|
12371
|
+
mark.textContent?.trim() ||
|
|
12372
|
+
"";
|
|
12315
12373
|
const style = window.getComputedStyle(mark);
|
|
12316
12374
|
return {
|
|
12317
12375
|
text,
|
|
@@ -12347,20 +12405,28 @@ function formatLiveSelectionSection(snapshot) {
|
|
|
12347
12405
|
const sections = [];
|
|
12348
12406
|
if (snapshot.activeSelection) {
|
|
12349
12407
|
const preview = snapshot.activeSelection.length > 400 ? `${snapshot.activeSelection.slice(0, 397)}...` : snapshot.activeSelection;
|
|
12350
|
-
sections.push(
|
|
12351
|
-
|
|
12408
|
+
sections.push(
|
|
12409
|
+
`## Active User Selection
|
|
12410
|
+
The user currently has this text selected on screen:
|
|
12411
|
+
- "${preview}"`
|
|
12412
|
+
);
|
|
12352
12413
|
}
|
|
12353
|
-
|
|
12354
|
-
(highlight) =>
|
|
12355
|
-
);
|
|
12356
|
-
if (unsavedHighlights.length > 0) {
|
|
12357
|
-
const lines = unsavedHighlights.map((highlight) => {
|
|
12414
|
+
if (snapshot.pageHighlights.length > 0) {
|
|
12415
|
+
const lines = snapshot.pageHighlights.map((highlight) => {
|
|
12358
12416
|
const preview = highlight.text.length > 180 ? `${highlight.text.slice(0, 177)}...` : highlight.text;
|
|
12359
|
-
const
|
|
12360
|
-
|
|
12417
|
+
const details = [
|
|
12418
|
+
highlight.persisted ? "saved" : "visible only",
|
|
12419
|
+
highlight.color ? `color: ${highlight.color}` : ""
|
|
12420
|
+
].filter(Boolean);
|
|
12421
|
+
return `- "${preview}"${details.length ? ` (${details.join(", ")})` : ""}`;
|
|
12361
12422
|
});
|
|
12362
|
-
sections.push(
|
|
12363
|
-
|
|
12423
|
+
sections.push(
|
|
12424
|
+
[
|
|
12425
|
+
"## Visible Highlights On Screen",
|
|
12426
|
+
"These are the highlighted passages currently visible in the page. Treat this as authoritative before searching or inspecting:",
|
|
12427
|
+
lines.join("\n")
|
|
12428
|
+
].join("\n")
|
|
12429
|
+
);
|
|
12364
12430
|
}
|
|
12365
12431
|
return sections.length > 0 ? sections.join("\n\n") : null;
|
|
12366
12432
|
}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@quanta-intellect/vessel-browser",
|
|
3
3
|
"mcpName": "io.github.unmodeled-tyler/vessel-browser",
|
|
4
|
-
"version": "0.1.
|
|
4
|
+
"version": "0.1.88",
|
|
5
5
|
"description": "AI-native web browser runtime for autonomous agents with human supervision",
|
|
6
6
|
"main": "./out/main/index.js",
|
|
7
7
|
"bin": {
|