@lvce-editor/find-widget-worker 3.1.0 → 3.3.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.
- package/dist/findWidgetWorkerMain.js +196 -46
- package/package.json +1 -1
|
@@ -374,7 +374,7 @@ const callbacks = Object.create(null);
|
|
|
374
374
|
const get$2 = id => {
|
|
375
375
|
return callbacks[id];
|
|
376
376
|
};
|
|
377
|
-
const remove = id => {
|
|
377
|
+
const remove$1 = id => {
|
|
378
378
|
delete callbacks[id];
|
|
379
379
|
};
|
|
380
380
|
class JsonRpcError extends Error {
|
|
@@ -527,7 +527,7 @@ const resolve = (id, response) => {
|
|
|
527
527
|
return;
|
|
528
528
|
}
|
|
529
529
|
fn(response);
|
|
530
|
-
remove(id);
|
|
530
|
+
remove$1(id);
|
|
531
531
|
};
|
|
532
532
|
const E_COMMAND_NOT_FOUND = 'E_COMMAND_NOT_FOUND';
|
|
533
533
|
const getErrorType = prettyError => {
|
|
@@ -834,6 +834,34 @@ const WebWorkerRpcClient = {
|
|
|
834
834
|
__proto__: null,
|
|
835
835
|
create: create$1$1
|
|
836
836
|
};
|
|
837
|
+
const createMockRpc = ({
|
|
838
|
+
commandMap
|
|
839
|
+
}) => {
|
|
840
|
+
const invocations = [];
|
|
841
|
+
const invoke = (method, ...params) => {
|
|
842
|
+
invocations.push([method, ...params]);
|
|
843
|
+
const command = commandMap[method];
|
|
844
|
+
if (!command) {
|
|
845
|
+
throw new Error(`command ${method} not found`);
|
|
846
|
+
}
|
|
847
|
+
return command(...params);
|
|
848
|
+
};
|
|
849
|
+
const mockRpc = {
|
|
850
|
+
invocations,
|
|
851
|
+
invoke,
|
|
852
|
+
invokeAndTransfer: invoke
|
|
853
|
+
};
|
|
854
|
+
return mockRpc;
|
|
855
|
+
};
|
|
856
|
+
|
|
857
|
+
const CheckBox = 'checkbox';
|
|
858
|
+
const Group = 'group';
|
|
859
|
+
const None = 'none';
|
|
860
|
+
|
|
861
|
+
const Button = 1;
|
|
862
|
+
const Div = 4;
|
|
863
|
+
const Text = 12;
|
|
864
|
+
const TextArea = 62;
|
|
837
865
|
|
|
838
866
|
const ClientX = 'event.clientX';
|
|
839
867
|
const ClientY = 'event.clientY';
|
|
@@ -887,7 +915,11 @@ const set$2 = (id, rpc) => {
|
|
|
887
915
|
const get$1 = id => {
|
|
888
916
|
return rpcs[id];
|
|
889
917
|
};
|
|
918
|
+
const remove = id => {
|
|
919
|
+
delete rpcs[id];
|
|
920
|
+
};
|
|
890
921
|
|
|
922
|
+
/* eslint-disable @typescript-eslint/explicit-function-return-type */
|
|
891
923
|
const create$2 = rpcId => {
|
|
892
924
|
return {
|
|
893
925
|
async dispose() {
|
|
@@ -906,6 +938,18 @@ const create$2 = rpcId => {
|
|
|
906
938
|
// @ts-ignore
|
|
907
939
|
return rpc.invokeAndTransfer(method, ...params);
|
|
908
940
|
},
|
|
941
|
+
registerMockRpc(commandMap) {
|
|
942
|
+
const mockRpc = createMockRpc({
|
|
943
|
+
commandMap
|
|
944
|
+
});
|
|
945
|
+
set$2(rpcId, mockRpc);
|
|
946
|
+
// @ts-ignore
|
|
947
|
+
mockRpc[Symbol.dispose] = () => {
|
|
948
|
+
remove(rpcId);
|
|
949
|
+
};
|
|
950
|
+
// @ts-ignore
|
|
951
|
+
return mockRpc;
|
|
952
|
+
},
|
|
909
953
|
set(rpc) {
|
|
910
954
|
set$2(rpcId, rpc);
|
|
911
955
|
}
|
|
@@ -1181,16 +1225,16 @@ const focusIndex = async (state, index) => {
|
|
|
1181
1225
|
const {
|
|
1182
1226
|
editorUid,
|
|
1183
1227
|
matches,
|
|
1184
|
-
matchIndex
|
|
1185
|
-
value
|
|
1228
|
+
matchIndex
|
|
1186
1229
|
} = state;
|
|
1187
1230
|
if (index === matchIndex) {
|
|
1188
1231
|
return state;
|
|
1189
1232
|
}
|
|
1190
1233
|
// // TODO find next match and highlight it
|
|
1191
|
-
const matchRowIndex = matches[index *
|
|
1192
|
-
const matchColumnIndex = matches[index *
|
|
1193
|
-
const
|
|
1234
|
+
const matchRowIndex = matches[index * 3];
|
|
1235
|
+
const matchColumnIndex = matches[index * 3 + 1];
|
|
1236
|
+
const matchLength = matches[index * 3 + 2];
|
|
1237
|
+
const newSelections = new Uint32Array([matchRowIndex, matchColumnIndex, matchRowIndex, matchColumnIndex + matchLength]);
|
|
1194
1238
|
await setSelections(editorUid, newSelections);
|
|
1195
1239
|
return {
|
|
1196
1240
|
...state,
|
|
@@ -1287,17 +1331,18 @@ const findRegexMatches = (lines, regex) => {
|
|
|
1287
1331
|
if (!lastMatch) {
|
|
1288
1332
|
break;
|
|
1289
1333
|
}
|
|
1290
|
-
matches.push(i, lastMatch.index);
|
|
1334
|
+
matches.push(i, lastMatch.index, lastMatch[0].length);
|
|
1291
1335
|
} while (true);
|
|
1292
1336
|
}
|
|
1293
1337
|
return new Uint32Array(matches);
|
|
1294
1338
|
};
|
|
1295
1339
|
|
|
1340
|
+
const emptyMatches$1 = new Uint32Array([]);
|
|
1296
1341
|
const findMatches = (lines, searchString, options) => {
|
|
1297
1342
|
if (searchString.length === 0) {
|
|
1298
1343
|
return {
|
|
1299
1344
|
error: '',
|
|
1300
|
-
matches:
|
|
1345
|
+
matches: emptyMatches$1
|
|
1301
1346
|
};
|
|
1302
1347
|
}
|
|
1303
1348
|
const {
|
|
@@ -1307,7 +1352,7 @@ const findMatches = (lines, searchString, options) => {
|
|
|
1307
1352
|
if (error) {
|
|
1308
1353
|
return {
|
|
1309
1354
|
error,
|
|
1310
|
-
matches:
|
|
1355
|
+
matches: emptyMatches$1
|
|
1311
1356
|
};
|
|
1312
1357
|
}
|
|
1313
1358
|
const matches = findRegexMatches(lines, regex);
|
|
@@ -1318,7 +1363,7 @@ const findMatches = (lines, searchString, options) => {
|
|
|
1318
1363
|
};
|
|
1319
1364
|
|
|
1320
1365
|
const getMatchCount = matches => {
|
|
1321
|
-
return matches.length /
|
|
1366
|
+
return matches.length / 3;
|
|
1322
1367
|
};
|
|
1323
1368
|
|
|
1324
1369
|
const measureTextHeight = (value, lineHeight) => {
|
|
@@ -1459,6 +1504,47 @@ const applyEdits = async (editorId, edits) => {
|
|
|
1459
1504
|
await invoke('Editor.applyDocumentEdits', editorId, edits);
|
|
1460
1505
|
};
|
|
1461
1506
|
|
|
1507
|
+
/**
|
|
1508
|
+
* Apply regex replacement with back-reference substitution ($1, $2, etc.)
|
|
1509
|
+
*/
|
|
1510
|
+
const applyRegexReplacement = (originalText, regex, replacement) => {
|
|
1511
|
+
// Create a non-global version of the regex to get capture groups
|
|
1512
|
+
const flags = regex.flags.replace('g', '');
|
|
1513
|
+
const nonGlobalRegex = new RegExp(regex.source, flags);
|
|
1514
|
+
const match = nonGlobalRegex.exec(originalText);
|
|
1515
|
+
if (!match) {
|
|
1516
|
+
return replacement;
|
|
1517
|
+
}
|
|
1518
|
+
|
|
1519
|
+
// Replace $n back-references with captured groups
|
|
1520
|
+
let result = replacement;
|
|
1521
|
+
|
|
1522
|
+
// Handle $& (entire match)
|
|
1523
|
+
result = result.replaceAll('$&', match[0]);
|
|
1524
|
+
|
|
1525
|
+
// Handle $` (text before match) - in this context it's empty since we're matching the whole text
|
|
1526
|
+
result = result.replaceAll('$`', '');
|
|
1527
|
+
|
|
1528
|
+
// Handle $' (text after match) - in this context it's empty since we're matching the whole text
|
|
1529
|
+
result = result.replaceAll("$'", '');
|
|
1530
|
+
|
|
1531
|
+
// Handle $$ (literal $)
|
|
1532
|
+
result = result.replaceAll('$$', '\u0000DOLLAR\u0000');
|
|
1533
|
+
|
|
1534
|
+
// Handle $n and $nn (numbered capture groups)
|
|
1535
|
+
result = result.replaceAll(/\$(\d{1,2})/g, (_match, groupNumber) => {
|
|
1536
|
+
const index = Number.parseInt(groupNumber, 10);
|
|
1537
|
+
if (index < match.length) {
|
|
1538
|
+
return match[index] ?? '';
|
|
1539
|
+
}
|
|
1540
|
+
return `$${groupNumber}`;
|
|
1541
|
+
});
|
|
1542
|
+
|
|
1543
|
+
// Restore literal $
|
|
1544
|
+
result = result.replaceAll('\u0000DOLLAR\u0000', '$');
|
|
1545
|
+
return result;
|
|
1546
|
+
};
|
|
1547
|
+
|
|
1462
1548
|
/**
|
|
1463
1549
|
* Preserves the case pattern of the original text when replacing.
|
|
1464
1550
|
* Supports uppercase, lowercase, PascalCase, and camelCase patterns.
|
|
@@ -1498,24 +1584,47 @@ const preserveCase$1 = (originalText, replacementText) => {
|
|
|
1498
1584
|
return replacementText;
|
|
1499
1585
|
};
|
|
1500
1586
|
|
|
1501
|
-
const getEdits = (matches, value, replacement, startIndex, replaceAll, lines, preserveCaseOption = false) => {
|
|
1587
|
+
const getEdits = (matches, value, replacement, startIndex, replaceAll, lines, preserveCaseOption = false, options) => {
|
|
1502
1588
|
if (value.length === 0 || matches.length === 0) {
|
|
1503
1589
|
return [];
|
|
1504
1590
|
}
|
|
1505
1591
|
const edits = [];
|
|
1506
|
-
const totalMatches = Math.floor(matches.length /
|
|
1592
|
+
const totalMatches = Math.floor(matches.length / 3);
|
|
1507
1593
|
const fromIndex = replaceAll ? 0 : Math.max(0, startIndex);
|
|
1508
1594
|
const toIndex = replaceAll ? totalMatches : Math.min(totalMatches, fromIndex + 1);
|
|
1595
|
+
|
|
1596
|
+
// Build regex once if using regular expressions
|
|
1597
|
+
let regex;
|
|
1598
|
+
if (options?.useRegularExpression) {
|
|
1599
|
+
const {
|
|
1600
|
+
error,
|
|
1601
|
+
regex: builtRegex
|
|
1602
|
+
} = buildRegex(value, options);
|
|
1603
|
+
if (!error) {
|
|
1604
|
+
regex = builtRegex;
|
|
1605
|
+
}
|
|
1606
|
+
}
|
|
1509
1607
|
for (let i = fromIndex; i < toIndex; i++) {
|
|
1510
|
-
const rowIndex = matches[i *
|
|
1511
|
-
const startColumnIndex = matches[i *
|
|
1512
|
-
const
|
|
1608
|
+
const rowIndex = matches[i * 3];
|
|
1609
|
+
const startColumnIndex = matches[i * 3 + 1];
|
|
1610
|
+
const matchLength = matches[i * 3 + 2];
|
|
1611
|
+
const endColumnIndex = startColumnIndex + matchLength;
|
|
1513
1612
|
|
|
1514
1613
|
// Get the original text that was matched
|
|
1515
1614
|
const originalText = lines[rowIndex].slice(startColumnIndex, endColumnIndex);
|
|
1516
1615
|
|
|
1616
|
+
// Apply regex replacement with back-references if enabled
|
|
1617
|
+
let finalReplacement;
|
|
1618
|
+
if (options?.useRegularExpression && regex) {
|
|
1619
|
+
finalReplacement = applyRegexReplacement(originalText, regex, replacement);
|
|
1620
|
+
} else {
|
|
1621
|
+
finalReplacement = replacement;
|
|
1622
|
+
}
|
|
1623
|
+
|
|
1517
1624
|
// Apply case preservation if enabled
|
|
1518
|
-
|
|
1625
|
+
if (preserveCaseOption) {
|
|
1626
|
+
finalReplacement = preserveCase$1(originalText, finalReplacement);
|
|
1627
|
+
}
|
|
1519
1628
|
|
|
1520
1629
|
// Convert row/column positions to character offsets
|
|
1521
1630
|
let startOffset = 0;
|
|
@@ -1538,39 +1647,86 @@ const getEdits = (matches, value, replacement, startIndex, replaceAll, lines, pr
|
|
|
1538
1647
|
return edits;
|
|
1539
1648
|
};
|
|
1540
1649
|
|
|
1650
|
+
const getLines = async editorUid => {
|
|
1651
|
+
const lines = await getLines$1(editorUid);
|
|
1652
|
+
return lines;
|
|
1653
|
+
};
|
|
1654
|
+
|
|
1655
|
+
const updateAfterReplace = async (state, matchIndex) => {
|
|
1656
|
+
const {
|
|
1657
|
+
editorUid,
|
|
1658
|
+
matchCase,
|
|
1659
|
+
matchWholeWord,
|
|
1660
|
+
useRegularExpression,
|
|
1661
|
+
value
|
|
1662
|
+
} = state;
|
|
1663
|
+
const options = {
|
|
1664
|
+
matchCase,
|
|
1665
|
+
matchWholeWord,
|
|
1666
|
+
useRegularExpression
|
|
1667
|
+
};
|
|
1668
|
+
const newLines = await getLines(editorUid);
|
|
1669
|
+
const {
|
|
1670
|
+
error,
|
|
1671
|
+
matches: newMatches
|
|
1672
|
+
} = findMatches(newLines, value, options);
|
|
1673
|
+
const newMatchCount = getMatchCount(newMatches);
|
|
1674
|
+
|
|
1675
|
+
// Keep matchIndex in bounds, or reset to 0 if no matches remain
|
|
1676
|
+
const newMatchIndex = newMatchCount === 0 ? 0 : Math.min(matchIndex, newMatchCount - 1);
|
|
1677
|
+
return {
|
|
1678
|
+
...state,
|
|
1679
|
+
inputErrorMessage: error,
|
|
1680
|
+
lines: newLines,
|
|
1681
|
+
matchCount: newMatchCount,
|
|
1682
|
+
matches: newMatches,
|
|
1683
|
+
matchIndex: newMatchIndex
|
|
1684
|
+
};
|
|
1685
|
+
};
|
|
1686
|
+
|
|
1541
1687
|
const replace$1 = async state => {
|
|
1542
1688
|
const {
|
|
1543
1689
|
editorUid,
|
|
1544
1690
|
lines,
|
|
1691
|
+
matchCase,
|
|
1545
1692
|
matches,
|
|
1546
1693
|
matchIndex,
|
|
1694
|
+
matchWholeWord,
|
|
1547
1695
|
preserveCase,
|
|
1548
1696
|
replacement,
|
|
1697
|
+
useRegularExpression,
|
|
1549
1698
|
value
|
|
1550
1699
|
} = state;
|
|
1551
|
-
const
|
|
1552
|
-
|
|
1553
|
-
|
|
1554
|
-
|
|
1555
|
-
return {
|
|
1556
|
-
...state
|
|
1700
|
+
const options = {
|
|
1701
|
+
matchCase,
|
|
1702
|
+
matchWholeWord,
|
|
1703
|
+
useRegularExpression
|
|
1557
1704
|
};
|
|
1705
|
+
const edits = getEdits(matches, value, replacement, matchIndex, false, lines, preserveCase, options);
|
|
1706
|
+
await applyEdits(editorUid, edits);
|
|
1707
|
+
return updateAfterReplace(state, matchIndex);
|
|
1558
1708
|
};
|
|
1559
1709
|
|
|
1560
|
-
const replaceAll$1 = state => {
|
|
1710
|
+
const replaceAll$1 = async state => {
|
|
1561
1711
|
const {
|
|
1562
1712
|
editorUid,
|
|
1563
1713
|
lines,
|
|
1714
|
+
matchCase,
|
|
1564
1715
|
matches,
|
|
1716
|
+
matchWholeWord,
|
|
1565
1717
|
preserveCase,
|
|
1566
1718
|
replacement,
|
|
1719
|
+
useRegularExpression,
|
|
1567
1720
|
value
|
|
1568
1721
|
} = state;
|
|
1569
|
-
const
|
|
1570
|
-
|
|
1571
|
-
|
|
1572
|
-
|
|
1722
|
+
const options = {
|
|
1723
|
+
matchCase,
|
|
1724
|
+
matchWholeWord,
|
|
1725
|
+
useRegularExpression
|
|
1573
1726
|
};
|
|
1727
|
+
const edits = getEdits(matches, value, replacement, 0, true, lines, preserveCase, options);
|
|
1728
|
+
await applyEdits(editorUid, edits);
|
|
1729
|
+
return updateAfterReplace(state, 0);
|
|
1574
1730
|
};
|
|
1575
1731
|
|
|
1576
1732
|
const getClickHandler = name => {
|
|
@@ -1605,7 +1761,7 @@ const handleFindWidgetFocus = (state, focusKey) => {
|
|
|
1605
1761
|
const {
|
|
1606
1762
|
focus
|
|
1607
1763
|
} = state;
|
|
1608
|
-
if (focus === focusKey) {
|
|
1764
|
+
if (!focusKey || focus === focusKey) {
|
|
1609
1765
|
return state;
|
|
1610
1766
|
}
|
|
1611
1767
|
return {
|
|
@@ -1619,6 +1775,7 @@ const handleFindFocus = state => {
|
|
|
1619
1775
|
return handleFindWidgetFocus(state, FindWidget$1);
|
|
1620
1776
|
};
|
|
1621
1777
|
|
|
1778
|
+
// TODO maybe use one handleFocus function with a name parameter
|
|
1622
1779
|
const handleReplaceFocus = state => {
|
|
1623
1780
|
return handleFindWidgetFocus(state, FocusFindWidgetReplace);
|
|
1624
1781
|
};
|
|
@@ -1822,6 +1979,10 @@ const getKeyBindings = () => {
|
|
|
1822
1979
|
command: 'FindWidget.focusPreviousMatchButton',
|
|
1823
1980
|
key: Tab,
|
|
1824
1981
|
when: FocusFindWidgetReplace$1
|
|
1982
|
+
}, {
|
|
1983
|
+
command: 'FindWidget.replace',
|
|
1984
|
+
key: Enter,
|
|
1985
|
+
when: FocusFindWidgetReplace$1
|
|
1825
1986
|
}, {
|
|
1826
1987
|
command: 'FindWidget.replaceAll',
|
|
1827
1988
|
key: Alt | CtrlCmd | Enter,
|
|
@@ -1910,12 +2071,10 @@ const getFindWidgetPosition = (editorX, editorY, editorWidth) => {
|
|
|
1910
2071
|
};
|
|
1911
2072
|
};
|
|
1912
2073
|
|
|
1913
|
-
const getLines = async editorUid => {
|
|
1914
|
-
const lines = await getLines$1(editorUid);
|
|
1915
|
-
return lines;
|
|
1916
|
-
};
|
|
1917
|
-
|
|
1918
2074
|
const getSelectedText = (lines, selections) => {
|
|
2075
|
+
if (selections.length === 0) {
|
|
2076
|
+
return '';
|
|
2077
|
+
}
|
|
1919
2078
|
const startRowIndex = selections[0];
|
|
1920
2079
|
const startColumnIndex = selections[1];
|
|
1921
2080
|
const endColumnIndex = selections[3];
|
|
@@ -2198,24 +2357,15 @@ const getFindWidgetButtonsEnabled = (matchCount, value) => {
|
|
|
2198
2357
|
};
|
|
2199
2358
|
};
|
|
2200
2359
|
|
|
2201
|
-
const CheckBox = 'checkbox';
|
|
2202
|
-
const Group = 'group';
|
|
2203
|
-
const None = 'none';
|
|
2204
|
-
|
|
2205
|
-
const Button = 1;
|
|
2206
|
-
const Div = 4;
|
|
2207
|
-
const Text = 12;
|
|
2208
|
-
const TextArea = 62;
|
|
2209
|
-
|
|
2210
2360
|
const mergeClassNames = (...classNames) => {
|
|
2211
2361
|
return classNames.filter(Boolean).join(' ');
|
|
2212
2362
|
};
|
|
2213
2363
|
|
|
2214
2364
|
const text = data => {
|
|
2215
2365
|
return {
|
|
2216
|
-
|
|
2366
|
+
childCount: 0,
|
|
2217
2367
|
text: data,
|
|
2218
|
-
|
|
2368
|
+
type: Text
|
|
2219
2369
|
};
|
|
2220
2370
|
};
|
|
2221
2371
|
|
|
@@ -2514,7 +2664,7 @@ const getEventListeners = (uid, widgetId) => {
|
|
|
2514
2664
|
params: ['executeWidgetCommand', 'FindWidget', 'FindWidget.handleBlur', 0, widgetId]
|
|
2515
2665
|
}, {
|
|
2516
2666
|
name: HandleReplaceInput,
|
|
2517
|
-
params: ['executeWidgetCommand', 'FindWidget', 'FindWidget.handleReplaceInput', 0, widgetId]
|
|
2667
|
+
params: ['executeWidgetCommand', 'FindWidget', 'FindWidget.handleReplaceInput', 0, widgetId, TargetValue]
|
|
2518
2668
|
}, {
|
|
2519
2669
|
name: HandleReplaceFocus,
|
|
2520
2670
|
params: ['executeWidgetCommand', 'FindWidget', 'FindWidget.handleReplaceFocus', 0, widgetId]
|