@lvce-editor/find-widget-worker 1.13.0 → 1.15.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.
@@ -977,7 +977,8 @@ const create$1 = (uid, x, y, width, height, parentUid) => {
977
977
  editorY: y,
978
978
  editorWidth: width,
979
979
  editorHeight: height,
980
- inputSource: 0
980
+ inputSource: 0,
981
+ preserveCase: false
981
982
  };
982
983
  set$3(uid, state, state);
983
984
  return state;
@@ -1010,6 +1011,11 @@ const RenderContent = 13;
1010
1011
  const RenderFocusContext = 14;
1011
1012
  const RenderFocus = 15;
1012
1013
  const RenderValue = 16;
1014
+ const RenderReplaceValue = 17;
1015
+
1016
+ const CheckBox = 'checkbox';
1017
+ const Group = 'group';
1018
+ const None = 'none';
1013
1019
 
1014
1020
  const Button = 1;
1015
1021
  const Div = 4;
@@ -1286,17 +1292,21 @@ const handleBlur = async state => {
1286
1292
  };
1287
1293
  };
1288
1294
 
1289
- const close$1 = async state => {
1290
- const {
1291
- editorUid
1292
- } = state;
1295
+ const escapeRegExpCharacters = value => {
1293
1296
  // @ts-ignore
1294
- await invoke('Editor.closeFind2', editorUid);
1295
- return state;
1297
+ return RegExp.escape(value);
1296
1298
  };
1297
1299
 
1298
- const handleClickClose = state => {
1299
- return close$1(state);
1300
+ const buildRegex = (searchString, options) => {
1301
+ const {
1302
+ matchCase,
1303
+ useRegularExpression,
1304
+ matchWholeWord
1305
+ } = options;
1306
+ const flags = matchCase ? 'g' : 'gi';
1307
+ const pattern = useRegularExpression ? searchString : escapeRegExpCharacters(searchString);
1308
+ const wrapped = matchWholeWord ? `\\b(?:${pattern})\\b` : pattern;
1309
+ return new RegExp(wrapped, flags);
1300
1310
  };
1301
1311
 
1302
1312
  const findRegexMatches = (lines, regex) => {
@@ -1321,22 +1331,11 @@ const findRegexMatches = (lines, regex) => {
1321
1331
  return new Uint32Array(matches);
1322
1332
  };
1323
1333
 
1324
- const escapeRegExpCharacters = value => {
1325
- // @ts-ignore
1326
- return RegExp.escape(value);
1327
- };
1328
-
1329
- const regexFlags = 'gi';
1330
- const getSearchRegex = searchString => {
1331
- const escaped = escapeRegExpCharacters(searchString);
1332
- return new RegExp(escaped, regexFlags);
1333
- };
1334
-
1335
- const findMatchesCaseInsensitive = (lines, searchString) => {
1334
+ const findMatches = (lines, searchString, options) => {
1336
1335
  if (searchString.length === 0) {
1337
1336
  return new Uint32Array([]);
1338
1337
  }
1339
- const regex = getSearchRegex(searchString);
1338
+ const regex = buildRegex(searchString, options);
1340
1339
  return findRegexMatches(lines, regex);
1341
1340
  };
1342
1341
 
@@ -1346,9 +1345,17 @@ const getMatchCount = matches => {
1346
1345
 
1347
1346
  const refresh$1 = (state, value, inputSource) => {
1348
1347
  const {
1349
- lines
1348
+ lines,
1349
+ matchCase,
1350
+ useRegularExpression,
1351
+ matchWholeWord
1350
1352
  } = state;
1351
- const matches = findMatchesCaseInsensitive(lines, value);
1353
+ const options = {
1354
+ matchCase,
1355
+ useRegularExpression,
1356
+ matchWholeWord
1357
+ };
1358
+ const matches = findMatches(lines, value, options);
1352
1359
  const matchCount = getMatchCount(matches);
1353
1360
  return {
1354
1361
  ...state,
@@ -1364,6 +1371,165 @@ const refresh = (state, value = state.value, inputSource = User) => {
1364
1371
  return refresh$1(state, value, inputSource);
1365
1372
  };
1366
1373
 
1374
+ const toggleMatchCase = state => {
1375
+ const {
1376
+ matchCase
1377
+ } = state;
1378
+ const newState = {
1379
+ ...state,
1380
+ matchCase: !matchCase
1381
+ };
1382
+ return refresh(newState, newState.value, User);
1383
+ };
1384
+
1385
+ const toggleMatchWholeWord = state => {
1386
+ const {
1387
+ matchWholeWord
1388
+ } = state;
1389
+ const newState = {
1390
+ ...state,
1391
+ matchWholeWord: !matchWholeWord
1392
+ };
1393
+ return refresh(newState, newState.value, User);
1394
+ };
1395
+
1396
+ const togglePreserveCase = state => {
1397
+ const {
1398
+ preserveCase
1399
+ } = state;
1400
+ // TODO update search results
1401
+ return {
1402
+ ...state,
1403
+ preserveCase: !preserveCase
1404
+ };
1405
+ };
1406
+
1407
+ const toggleUseRegularExpression = state => {
1408
+ const {
1409
+ useRegularExpression
1410
+ } = state;
1411
+ const newState = {
1412
+ ...state,
1413
+ useRegularExpression: !useRegularExpression
1414
+ };
1415
+ return refresh(newState, newState.value, User);
1416
+ };
1417
+
1418
+ const Close$2 = 'Close';
1419
+ const FocusNext = 'FocusNext';
1420
+ const FocusPrevious = 'FocusPrevious';
1421
+ const MatchCase$1 = 'MatchCase';
1422
+ const MatchWholeWord$1 = 'MatchWholeWord';
1423
+ const PreserveCase = 'PreserveCase';
1424
+ const Replace$2 = 'Replace';
1425
+ const ReplaceAll$2 = 'ReplaceAll';
1426
+ const ReplaceValue = 'replace-value';
1427
+ const SearchValue = 'search-value';
1428
+ const ToggleReplace = 'ToggleReplace';
1429
+ const UseRegularExpression$1 = 'UseRegularExpression';
1430
+
1431
+ const applyEdits = async (editorId, edits) => {
1432
+ // @ts-ignore
1433
+ await invoke('Editor.applyDocumentEdits', editorId, edits);
1434
+ };
1435
+
1436
+ const getEdits = (matches, value, replacement, startIndex, replaceAll) => {
1437
+ if (value.length === 0 || matches.length === 0) {
1438
+ return [];
1439
+ }
1440
+ const edits = [];
1441
+ const totalMatches = Math.floor(matches.length / 2);
1442
+ const fromIndex = replaceAll ? 0 : Math.max(0, startIndex);
1443
+ const toIndex = replaceAll ? totalMatches : Math.min(totalMatches, fromIndex + 1);
1444
+ for (let i = fromIndex; i < toIndex; i++) {
1445
+ const rowIndex = matches[i * 2];
1446
+ const startColumnIndex = matches[i * 2 + 1];
1447
+ const endColumnIndex = startColumnIndex + value.length;
1448
+ edits.push({
1449
+ start: {
1450
+ rowIndex,
1451
+ columnIndex: startColumnIndex
1452
+ },
1453
+ end: {
1454
+ rowIndex,
1455
+ columnIndex: endColumnIndex
1456
+ },
1457
+ inserted: [replacement],
1458
+ deleted: [value],
1459
+ origin: 'find-widget.replace'
1460
+ });
1461
+ }
1462
+ return edits;
1463
+ };
1464
+
1465
+ const replace$1 = async state => {
1466
+ const {
1467
+ matches,
1468
+ value,
1469
+ replacement,
1470
+ matchIndex,
1471
+ editorUid
1472
+ } = state;
1473
+ const edits = getEdits(matches, value, replacement, matchIndex, false);
1474
+ await applyEdits(editorUid, edits);
1475
+ // TODO ask editor worker to apply edit
1476
+ // TODO ask editor worker for new lines?
1477
+ return {
1478
+ ...state
1479
+ };
1480
+ };
1481
+
1482
+ const replaceAll$1 = state => {
1483
+ const {
1484
+ matches,
1485
+ value,
1486
+ replacement,
1487
+ editorUid
1488
+ } = state;
1489
+ const edits = getEdits(matches, value, replacement, 0, true);
1490
+ void applyEdits(editorUid, edits);
1491
+ return {
1492
+ ...state
1493
+ };
1494
+ };
1495
+
1496
+ const getClickHandler = name => {
1497
+ switch (name) {
1498
+ case Replace$2:
1499
+ return replace$1;
1500
+ case ReplaceAll$2:
1501
+ return replaceAll$1;
1502
+ case MatchCase$1:
1503
+ return toggleMatchCase;
1504
+ case MatchWholeWord$1:
1505
+ return toggleMatchWholeWord;
1506
+ case UseRegularExpression$1:
1507
+ return toggleUseRegularExpression;
1508
+ case PreserveCase:
1509
+ return togglePreserveCase;
1510
+ default:
1511
+ throw new Error(`unexpected click`);
1512
+ }
1513
+ };
1514
+
1515
+ const handleClickButton = async (state, name) => {
1516
+ const fn = getClickHandler(name);
1517
+ return fn(state);
1518
+ };
1519
+
1520
+ const close$1 = async state => {
1521
+ const {
1522
+ editorUid
1523
+ } = state;
1524
+ // @ts-ignore
1525
+ await invoke('Editor.closeFind2', editorUid);
1526
+ return state;
1527
+ };
1528
+
1529
+ const handleClickClose = state => {
1530
+ return close$1(state);
1531
+ };
1532
+
1367
1533
  const handleInput = (state, value, inputSource = User) => {
1368
1534
  return refresh(state, value, inputSource);
1369
1535
  };
@@ -1388,6 +1554,28 @@ const toggleReplace = state => {
1388
1554
  };
1389
1555
  };
1390
1556
 
1557
+ const handleReplaceInput = (state, value, inputSource = User) => {
1558
+ return {
1559
+ ...state,
1560
+ replacement: value,
1561
+ inputSource
1562
+ };
1563
+ };
1564
+
1565
+ const regexFlags = 'gi';
1566
+ const getSearchRegex = searchString => {
1567
+ const escaped = escapeRegExpCharacters(searchString);
1568
+ return new RegExp(escaped, regexFlags);
1569
+ };
1570
+
1571
+ const findMatchesCaseInsensitive = (lines, searchString) => {
1572
+ if (searchString.length === 0) {
1573
+ return new Uint32Array([]);
1574
+ }
1575
+ const regex = getSearchRegex(searchString);
1576
+ return findRegexMatches(lines, regex);
1577
+ };
1578
+
1391
1579
  const getFindWidgetPosition = (editorX, editorY, editorWidth) => {
1392
1580
  const width = 300;
1393
1581
  const height = 30;
@@ -1492,6 +1680,7 @@ const HandleClickPreviousMatch = 'handleClickPreviousMatch';
1492
1680
  const HandleClickReplace = 'handleClickReplace';
1493
1681
  const HandleClickToggleReplace = 'handleClickToggleReplace';
1494
1682
  const HandleClickReplaceAll = 'handleClickReplaceAll';
1683
+ const HandleClickButton = 'handleClickButton';
1495
1684
  const HandleFocus = 'handleFocus';
1496
1685
  const HandleInput = 'handleInput';
1497
1686
  const HandleReplaceFocus = 'handleReplaceFocus';
@@ -1513,12 +1702,12 @@ const i18nString = (key, placeholders = emptyObject) => {
1513
1702
 
1514
1703
  const MatchOf = '{PH1} of {PH2}';
1515
1704
  const NoResults = 'No Results';
1516
- const Close$2 = 'Close';
1705
+ const Close$1 = 'Close';
1517
1706
  const PreviousMatch = 'Previous Match';
1518
1707
  const NextMatch = 'Next Match';
1519
1708
  const Find$1 = 'Find';
1520
- const Replace$2 = 'Replace';
1521
- const ReplaceAll$2 = 'Replace All';
1709
+ const Replace$1 = 'Replace';
1710
+ const ReplaceAll$1 = 'Replace All';
1522
1711
 
1523
1712
  const noResults = () => {
1524
1713
  return i18nString(NoResults);
@@ -1536,32 +1725,26 @@ const nextMatch = () => {
1536
1725
  return i18nString(NextMatch);
1537
1726
  };
1538
1727
  const close = () => {
1539
- return i18nString(Close$2);
1728
+ return i18nString(Close$1);
1540
1729
  };
1541
1730
  const find = () => {
1542
1731
  return i18nString(Find$1);
1543
1732
  };
1544
1733
  const replace = () => {
1545
- return i18nString(Replace$2);
1734
+ return i18nString(Replace$1);
1546
1735
  };
1547
1736
  const replaceAll = () => {
1548
- return i18nString(ReplaceAll$2);
1737
+ return i18nString(ReplaceAll$1);
1549
1738
  };
1550
1739
 
1740
+ const MatchCase = 'CaseSensitive';
1741
+ const UseRegularExpression = 'Regex';
1742
+ const MatchWholeWord = 'WholeWord';
1551
1743
  const ArrowDown = 'ArrowDown';
1552
1744
  const ArrowUp = 'ArrowUp';
1553
- const Close$1 = 'Close';
1554
- const Replace$1 = 'Replace';
1555
- const ReplaceAll$1 = 'ReplaceAll';
1556
-
1557
- const ToggleReplace = 'ToggleReplace';
1558
- const SearchValue = 'search-value';
1559
- const ReplaceValue = 'replace-value';
1560
- const ReplaceAll = 'ReplaceAll';
1561
1745
  const Close = 'Close';
1562
- const FocusNext = 'FocusNext';
1563
- const FocusPrevious = 'FocusPrevious';
1564
1746
  const Replace = 'Replace';
1747
+ const ReplaceAll = 'ReplaceAll';
1565
1748
 
1566
1749
  const getFindWidgetButtons = (findButtonsEnabled, replaceButtonsEnabled) => {
1567
1750
  const findButtons = [{
@@ -1578,23 +1761,23 @@ const getFindWidgetButtons = (findButtonsEnabled, replaceButtonsEnabled) => {
1578
1761
  name: FocusNext
1579
1762
  }, {
1580
1763
  label: close(),
1581
- icon: Close$1,
1764
+ icon: Close,
1582
1765
  disabled: false,
1583
1766
  onClick: HandleClickClose,
1584
- name: Close
1767
+ name: Close$2
1585
1768
  }];
1586
1769
  const replaceButtons = [{
1587
1770
  label: replace(),
1588
- icon: Replace$1,
1771
+ icon: Replace,
1589
1772
  disabled: !replaceButtonsEnabled,
1590
1773
  onClick: HandleClickReplace,
1591
- name: Replace
1774
+ name: Replace$2
1592
1775
  }, {
1593
1776
  label: replaceAll(),
1594
- icon: ReplaceAll$1,
1777
+ icon: ReplaceAll,
1595
1778
  disabled: !replaceButtonsEnabled,
1596
1779
  onClick: HandleClickReplaceAll,
1597
- name: ReplaceAll
1780
+ name: ReplaceAll$2
1598
1781
  }];
1599
1782
  return {
1600
1783
  findButtons,
@@ -1623,10 +1806,6 @@ const text = data => {
1623
1806
  };
1624
1807
  };
1625
1808
 
1626
- const CheckBox = 'checkbox';
1627
- const Group = 'group';
1628
- const None = 'none';
1629
-
1630
1809
  const FindWidgetFind = 'FindWidgetFind';
1631
1810
  const FindWidgetMatchCount = 'FindWidgetMatchCount';
1632
1811
  const FindWidgetMatchCountEmpty = 'FindWidgetMatchCountEmpty';
@@ -1645,6 +1824,25 @@ const ViewletFind = 'ViewletFind';
1645
1824
  const FindWidget = 'FindWidget';
1646
1825
  const ViewletFindWidget = 'ViewletFindWidget';
1647
1826
 
1827
+ const getFindButtons = () => {
1828
+ return [{
1829
+ checked: false,
1830
+ icon: MatchCase,
1831
+ title: 'Match Case',
1832
+ name: MatchCase$1
1833
+ }, {
1834
+ checked: false,
1835
+ icon: MatchWholeWord,
1836
+ title: 'Match Whole Word',
1837
+ name: MatchWholeWord$1
1838
+ }, {
1839
+ checked: false,
1840
+ icon: UseRegularExpression,
1841
+ title: 'Use Regular Expression',
1842
+ name: UseRegularExpression$1
1843
+ }];
1844
+ };
1845
+
1648
1846
  const getFindMatchCountClassName = (matchCount, value) => {
1649
1847
  if (value && matchCount === 0) {
1650
1848
  return mergeClassNames(FindWidgetMatchCount, FindWidgetMatchCountEmpty);
@@ -1701,7 +1899,7 @@ const getSearchFieldButtonVirtualDom = button => {
1701
1899
  childCount: 1
1702
1900
  }, {
1703
1901
  type: Div,
1704
- className: mergeClassNames(MaskIcon, icon),
1902
+ className: mergeClassNames(MaskIcon, `MaskIcon${icon}`),
1705
1903
  childCount: 0
1706
1904
  }];
1707
1905
  };
@@ -1741,7 +1939,7 @@ const getFindWidgetFindVirtualDom = (matchCountText, buttons, matchCount, value)
1741
1939
  className: FindWidgetFind,
1742
1940
  childCount: 5
1743
1941
  });
1744
- dom.push(...getSearchFieldVirtualDom('search-value', find(), HandleInput, [], [], HandleFocus));
1942
+ dom.push(...getSearchFieldVirtualDom(SearchValue, find(), HandleInput, getFindButtons(), [], HandleFocus));
1745
1943
  const findClassName = getFindMatchCountClassName(matchCount, value);
1746
1944
  dom.push({
1747
1945
  type: Div,
@@ -1867,6 +2065,9 @@ const getEventListeners = (uid, widgetId) => {
1867
2065
  }, {
1868
2066
  name: HandleClickReplaceAll,
1869
2067
  params: ['executeWidgetCommand', 'FindWidget', 'FindWidget.handleClickReplaceAll', 0, widgetId]
2068
+ }, {
2069
+ name: HandleClickButton,
2070
+ params: ['executeWidgetCommand', 'FindWidget', 'FindWidget.handleClickButton', 0, widgetId, `event.target.name`]
1870
2071
  }];
1871
2072
  };
1872
2073
 
@@ -1893,6 +2094,14 @@ const renderFocusContext = (oldState, newState) => {
1893
2094
  return [/* method */SetFocusContext, FocusFindWidget];
1894
2095
  };
1895
2096
 
2097
+ const renderReplaceValue = (oldState, newState) => {
2098
+ const {
2099
+ uid,
2100
+ replacement
2101
+ } = newState;
2102
+ return [SetValueByName, uid, Replace$2, replacement];
2103
+ };
2104
+
1896
2105
  const renderUid = (oldState, newState) => {
1897
2106
  const {
1898
2107
  uid,
@@ -1925,6 +2134,8 @@ const getRenderer = diffType => {
1925
2134
  return renderFocus;
1926
2135
  case RenderValue:
1927
2136
  return renderValue;
2137
+ case RenderReplaceValue:
2138
+ return renderReplaceValue;
1928
2139
  default:
1929
2140
  throw new Error('unknown renderer');
1930
2141
  }
@@ -1957,6 +2168,7 @@ const commandMap = {
1957
2168
  'FindWidget.focusFirst': wrapCommand(focusFirst),
1958
2169
  'FindWidget.focusIndex': wrapCommand(focusIndex),
1959
2170
  'FindWidget.focusLast': wrapCommand(focusLast),
2171
+ 'FindWidget.toggleMatchCase': wrapCommand(toggleMatchCase),
1960
2172
  'FindWidget.focusNext': wrapCommand(focusNext),
1961
2173
  'FindWidget.focusPrevious': wrapCommand(focusPrevious),
1962
2174
  'FindWidget.focusReplace': wrapCommand(focusReplace),
@@ -1965,11 +2177,16 @@ const commandMap = {
1965
2177
  'FindWidget.handleBlur': wrapCommand(handleBlur),
1966
2178
  'FindWidget.handleClickClose': wrapCommand(handleClickClose),
1967
2179
  'FindWidget.handleInput': wrapCommand(handleInput),
2180
+ 'FindWidget.handleReplaceInput': wrapCommand(handleReplaceInput),
1968
2181
  'FindWidget.loadContent': wrapCommand(loadContent),
1969
2182
  'FindWidget.preventDefaultBrowserFind': wrapCommand(preventDefaultBrowserFind),
1970
2183
  'FindWidget.render2': render2,
1971
2184
  'FindWidget.terminate': terminate,
1972
- 'FindWidget.toggleReplace': wrapCommand(toggleReplace)
2185
+ 'FindWidget.toggleReplace': wrapCommand(toggleReplace),
2186
+ 'FindWidget.replace': wrapCommand(replace$1),
2187
+ 'FindWidget.replaceAll': wrapCommand(replaceAll$1),
2188
+ 'FindWidget.handleClickButton': wrapCommand(handleClickButton),
2189
+ 'FindWidget.toggleUseRegularExpression': wrapCommand(toggleUseRegularExpression)
1973
2190
  };
1974
2191
 
1975
2192
  const listen = async () => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lvce-editor/find-widget-worker",
3
- "version": "1.13.0",
3
+ "version": "1.15.0",
4
4
  "description": "Web Worker for the find widget in Lvce Editor",
5
5
  "repository": {
6
6
  "type": "git",