@lvce-editor/menu-worker 2.0.0 → 2.2.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.
Files changed (2) hide show
  1. package/dist/menuWorkerMain.js +375 -209
  2. package/package.json +1 -1
@@ -411,6 +411,100 @@ const IpcChildWithModuleWorkerAndMessagePort$1 = {
411
411
  listen: listen$6,
412
412
  wrap: wrap$e
413
413
  };
414
+ const addListener = (emitter, type, callback) => {
415
+ if ('addEventListener' in emitter) {
416
+ emitter.addEventListener(type, callback);
417
+ } else {
418
+ emitter.on(type, callback);
419
+ }
420
+ };
421
+ const removeListener = (emitter, type, callback) => {
422
+ if ('removeEventListener' in emitter) {
423
+ emitter.removeEventListener(type, callback);
424
+ } else {
425
+ emitter.off(type, callback);
426
+ }
427
+ };
428
+ const getFirstEvent = (eventEmitter, eventMap) => {
429
+ const {
430
+ resolve,
431
+ promise
432
+ } = Promise.withResolvers();
433
+ const listenerMap = Object.create(null);
434
+ const cleanup = value => {
435
+ for (const event of Object.keys(eventMap)) {
436
+ removeListener(eventEmitter, event, listenerMap[event]);
437
+ }
438
+ resolve(value);
439
+ };
440
+ for (const [event, type] of Object.entries(eventMap)) {
441
+ const listener = event => {
442
+ cleanup({
443
+ type,
444
+ event
445
+ });
446
+ };
447
+ addListener(eventEmitter, event, listener);
448
+ listenerMap[event] = listener;
449
+ }
450
+ return promise;
451
+ };
452
+ const Message$1 = 3;
453
+ const create$5$1 = async ({
454
+ messagePort,
455
+ isMessagePortOpen
456
+ }) => {
457
+ if (!isMessagePort(messagePort)) {
458
+ throw new IpcError('port must be of type MessagePort');
459
+ }
460
+ if (isMessagePortOpen) {
461
+ return messagePort;
462
+ }
463
+ const eventPromise = getFirstEvent(messagePort, {
464
+ message: Message$1
465
+ });
466
+ messagePort.start();
467
+ const {
468
+ type,
469
+ event
470
+ } = await eventPromise;
471
+ if (type !== Message$1) {
472
+ throw new IpcError('Failed to wait for ipc message');
473
+ }
474
+ if (event.data !== readyMessage) {
475
+ throw new IpcError('unexpected first message');
476
+ }
477
+ return messagePort;
478
+ };
479
+ const signal$1 = messagePort => {
480
+ messagePort.start();
481
+ };
482
+ class IpcParentWithMessagePort extends Ipc {
483
+ getData = getData$2;
484
+ send(message) {
485
+ this._rawIpc.postMessage(message);
486
+ }
487
+ sendAndTransfer(message) {
488
+ const transfer = getTransferrables(message);
489
+ this._rawIpc.postMessage(message, transfer);
490
+ }
491
+ dispose() {
492
+ this._rawIpc.close();
493
+ }
494
+ onMessage(callback) {
495
+ this._rawIpc.addEventListener('message', callback);
496
+ }
497
+ onClose(callback) {}
498
+ }
499
+ const wrap$5 = messagePort => {
500
+ return new IpcParentWithMessagePort(messagePort);
501
+ };
502
+ const IpcParentWithMessagePort$1 = {
503
+ __proto__: null,
504
+ create: create$5$1,
505
+ signal: signal$1,
506
+ wrap: wrap$5
507
+ };
414
508
 
415
509
  const Two = '2.0';
416
510
  const create$4 = (method, params) => {
@@ -421,7 +515,7 @@ const create$4 = (method, params) => {
421
515
  };
422
516
  };
423
517
  const callbacks = Object.create(null);
424
- const set$4 = (id, fn) => {
518
+ const set$5 = (id, fn) => {
425
519
  callbacks[id] = fn;
426
520
  };
427
521
  const get$3 = id => {
@@ -431,16 +525,16 @@ const remove = id => {
431
525
  delete callbacks[id];
432
526
  };
433
527
  let id$a = 0;
434
- const create$3 = () => {
528
+ const create$3$1 = () => {
435
529
  return ++id$a;
436
530
  };
437
531
  const registerPromise = () => {
438
- const id = create$3();
532
+ const id = create$3$1();
439
533
  const {
440
534
  resolve,
441
535
  promise
442
536
  } = Promise.withResolvers();
443
- set$4(id, resolve);
537
+ set$5(id, resolve);
444
538
  return {
445
539
  id,
446
540
  promise
@@ -668,7 +762,7 @@ const getErrorResponse = (id, error, preparePrettyError, logError) => {
668
762
  const errorProperty = getErrorProperty(error, prettyError);
669
763
  return create$1$1(id, errorProperty);
670
764
  };
671
- const create$5 = (message, result) => {
765
+ const create$6 = (message, result) => {
672
766
  return {
673
767
  jsonrpc: Two,
674
768
  id: message.id,
@@ -677,7 +771,7 @@ const create$5 = (message, result) => {
677
771
  };
678
772
  const getSuccessResponse = (message, result) => {
679
773
  const resultProperty = result ?? null;
680
- return create$5(message, resultProperty);
774
+ return create$6(message, resultProperty);
681
775
  };
682
776
  const getErrorResponseSimple = (id, error) => {
683
777
  return {
@@ -781,11 +875,11 @@ const invokeHelper = async (ipc, method, params, useSendAndTransfer) => {
781
875
  const responseMessage = await promise;
782
876
  return unwrapJsonRpcResult(responseMessage);
783
877
  };
784
- const send = (transport, method, ...params) => {
878
+ const send$1 = (transport, method, ...params) => {
785
879
  const message = create$4(method, params);
786
880
  transport.send(message);
787
881
  };
788
- const invoke$3 = (ipc, method, ...params) => {
882
+ const invoke$4 = (ipc, method, ...params) => {
789
883
  return invokeHelper(ipc, method, params, false);
790
884
  };
791
885
  const invokeAndTransfer$1 = (ipc, method, ...params) => {
@@ -821,10 +915,10 @@ const createRpc = ipc => {
821
915
  * @deprecated
822
916
  */
823
917
  send(method, ...params) {
824
- send(ipc, method, ...params);
918
+ send$1(ipc, method, ...params);
825
919
  },
826
920
  invoke(method, ...params) {
827
- return invoke$3(ipc, method, ...params);
921
+ return invoke$4(ipc, method, ...params);
828
922
  },
829
923
  invokeAndTransfer(method, ...params) {
830
924
  return invokeAndTransfer$1(ipc, method, ...params);
@@ -865,6 +959,40 @@ const listen$1 = async (module, options) => {
865
959
  const ipc = module.wrap(rawIpc);
866
960
  return ipc;
867
961
  };
962
+ const create$5 = async ({
963
+ commandMap,
964
+ messagePort
965
+ }) => {
966
+ // TODO create a commandMap per rpc instance
967
+ register(commandMap);
968
+ const rawIpc = await IpcParentWithMessagePort$1.create({
969
+ messagePort,
970
+ isMessagePortOpen: true
971
+ });
972
+ const ipc = IpcParentWithMessagePort$1.wrap(rawIpc);
973
+ handleIpc(ipc);
974
+ const rpc = createRpc(ipc);
975
+ messagePort.start();
976
+ return rpc;
977
+ };
978
+ const create$3 = async ({
979
+ commandMap,
980
+ send
981
+ }) => {
982
+ const {
983
+ port1,
984
+ port2
985
+ } = new MessageChannel();
986
+ await send(port1);
987
+ return create$5({
988
+ commandMap,
989
+ messagePort: port2
990
+ });
991
+ };
992
+ const TransferMessagePortRpcParent = {
993
+ __proto__: null,
994
+ create: create$3
995
+ };
868
996
  const create$2 = async ({
869
997
  commandMap
870
998
  }) => {
@@ -901,6 +1029,10 @@ const createMockRpc = ({
901
1029
 
902
1030
  const Text = 12;
903
1031
 
1032
+ const Button = 'event.button';
1033
+ const ClientX = 'event.clientX';
1034
+ const ClientY = 'event.clientY';
1035
+
904
1036
  const Backspace$1 = 1;
905
1037
  const Tab$1 = 2;
906
1038
  const Enter$1 = 3;
@@ -1167,6 +1299,8 @@ const getKeyCodeString = keyCode => {
1167
1299
  }
1168
1300
  };
1169
1301
 
1302
+ const Script = 2;
1303
+
1170
1304
  const CtrlCmd = 1 << 11 >>> 0;
1171
1305
  const Shift = 1 << 10 >>> 0;
1172
1306
 
@@ -1190,10 +1324,13 @@ const parseKey = rawKey => {
1190
1324
  };
1191
1325
 
1192
1326
  const DebugWorker = 55;
1327
+ const RendererProcess = 1670;
1193
1328
  const RendererWorker$1 = 1;
1194
1329
 
1330
+ const FocusSelector = 'Viewlet.focusSelector';
1331
+
1195
1332
  const rpcs = Object.create(null);
1196
- const set$3 = (id, rpc) => {
1333
+ const set$4 = (id, rpc) => {
1197
1334
  rpcs[id] = rpc;
1198
1335
  };
1199
1336
  const get$2 = id => {
@@ -1215,7 +1352,7 @@ const create$1 = rpcId => {
1215
1352
  return rpc.invokeAndTransfer(method, ...params);
1216
1353
  },
1217
1354
  set(rpc) {
1218
- set$3(rpcId, rpc);
1355
+ set$4(rpcId, rpc);
1219
1356
  },
1220
1357
  async dispose() {
1221
1358
  const rpc = get$2(rpcId);
@@ -1224,6 +1361,10 @@ const create$1 = rpcId => {
1224
1361
  };
1225
1362
  };
1226
1363
 
1364
+ const {
1365
+ invoke: invoke$3,
1366
+ set: set$3} = create$1(RendererProcess);
1367
+
1227
1368
  const {
1228
1369
  invoke: invoke$2,
1229
1370
  invokeAndTransfer,
@@ -1239,6 +1380,14 @@ const getFilePathElectron = async file => {
1239
1380
  const showContextMenu = async (x, y, id, ...args) => {
1240
1381
  return invoke$2('ContextMenu.show', x, y, id, ...args);
1241
1382
  };
1383
+ const showContextMenu2 = async (uid, menuId, x, y, args) => {
1384
+ number(uid);
1385
+ number(menuId);
1386
+ number(x);
1387
+ number(y);
1388
+ // @ts-ignore
1389
+ await invoke$2('ContextMenu.show2', uid, menuId, x, y, args);
1390
+ };
1242
1391
  const getElectronVersion = async () => {
1243
1392
  return invoke$2('Process.getElectronVersion');
1244
1393
  };
@@ -1354,6 +1503,9 @@ const getKeyBindings$1 = async () => {
1354
1503
  const writeClipBoardText = async text => {
1355
1504
  await invoke$2('ClipBoard.writeText', /* text */text);
1356
1505
  };
1506
+ const readClipBoardText = async () => {
1507
+ return invoke$2('ClipBoard.readText');
1508
+ };
1357
1509
  const writeClipBoardImage = async blob => {
1358
1510
  // @ts-ignore
1359
1511
  await invoke$2('ClipBoard.writeImage', /* text */blob);
@@ -1397,6 +1549,16 @@ const sendMessagePortToRendererProcess = async port => {
1397
1549
  // @ts-ignore
1398
1550
  await invokeAndTransfer('SendMessagePortToExtensionHostWorker.sendMessagePortToRendererProcess', port, command, DebugWorker);
1399
1551
  };
1552
+ const sendMessagePortToTextMeasurementWorker = async port => {
1553
+ const command = 'TextMeasurement.handleMessagePort';
1554
+ // @ts-ignore
1555
+ await invokeAndTransfer('SendMessagePortToExtensionHostWorker.sendMessagePortToTextMeasurementWorker', port, command, 0);
1556
+ };
1557
+ const sendMessagePortToSourceControlWorker = async port => {
1558
+ const command = 'SourceControl.handleMessagePort';
1559
+ // @ts-ignore
1560
+ await invokeAndTransfer('SendMessagePortToExtensionHostWorker.sendMessagePortToSourceControlWorker', port, command, 0);
1561
+ };
1400
1562
  const getPreference = async key => {
1401
1563
  return await invoke$2('Preferences.get', key);
1402
1564
  };
@@ -1468,7 +1630,7 @@ const openExtensionSearch = async () => {
1468
1630
  };
1469
1631
  const setExtensionsSearchValue = async searchValue => {
1470
1632
  // @ts-ignore
1471
- return invoke$2('Extensions.handleInput', searchValue);
1633
+ return invoke$2('Extensions.handleInput', searchValue, Script);
1472
1634
  };
1473
1635
  const openExternal = async uri => {
1474
1636
  // @ts-ignore
@@ -1545,6 +1707,7 @@ const RendererWorker = {
1545
1707
  openUri,
1546
1708
  openUrl,
1547
1709
  openWidget,
1710
+ readClipBoardText,
1548
1711
  readFile,
1549
1712
  registerMockRpc,
1550
1713
  registerWebViewInterceptor,
@@ -1561,7 +1724,9 @@ const RendererWorker = {
1561
1724
  sendMessagePortToMarkdownWorker,
1562
1725
  sendMessagePortToRendererProcess,
1563
1726
  sendMessagePortToSearchProcess,
1727
+ sendMessagePortToSourceControlWorker,
1564
1728
  sendMessagePortToSyntaxHighlightingWorker,
1729
+ sendMessagePortToTextMeasurementWorker,
1565
1730
  set: set$2,
1566
1731
  setAdditionalFocus,
1567
1732
  setColorTheme,
@@ -1570,6 +1735,7 @@ const RendererWorker = {
1570
1735
  setWebViewPort,
1571
1736
  setWorkspacePath,
1572
1737
  showContextMenu,
1738
+ showContextMenu2,
1573
1739
  showErrorDialog,
1574
1740
  showMessageBox,
1575
1741
  showSaveFilePicker,
@@ -1579,6 +1745,122 @@ const RendererWorker = {
1579
1745
  writeClipBoardText
1580
1746
  };
1581
1747
 
1748
+ /* eslint-disable @typescript-eslint/prefer-readonly-parameter-types */
1749
+ // TODO lazyload menuEntries and use Command.execute (maybe)
1750
+
1751
+ // TODO difference between focusing with mouse or keyboard
1752
+ // with mouse -> open submenu
1753
+ // with keyboard -> don't open submenu, only focus
1754
+
1755
+ // TODO this code seems a bit too complicated, maybe it can be simplified
1756
+
1757
+ const state$1 = {
1758
+ menus: [],
1759
+ latestTimeStamp: 0};
1760
+ const addMenuInternal = menu => {
1761
+ if (state$1.menus.length > 5) {
1762
+ throw new Error('too many menus');
1763
+ }
1764
+ state$1.menus.push(menu);
1765
+ return menu;
1766
+ };
1767
+ const getCount = () => {
1768
+ return state$1.menus.length;
1769
+ };
1770
+ const reset = () => {
1771
+ state$1.menus = [];
1772
+ };
1773
+ const get$1 = index => {
1774
+ return state$1.menus[index];
1775
+ };
1776
+ const set$1 = menus => {
1777
+ state$1.menus = menus;
1778
+ };
1779
+ const getAll = () => {
1780
+ return state$1.menus;
1781
+ };
1782
+ const setTimestamp = timestamp => {
1783
+ state$1.latestTimeStamp = timestamp;
1784
+ };
1785
+ const getLatestTimestamp = () => {
1786
+ return state$1.latestTimeStamp;
1787
+ };
1788
+
1789
+ const closeSubMenu = async () => {
1790
+ const menus = getAll();
1791
+ const parentMenu = menus.at(-1);
1792
+ // @ts-ignore
1793
+ await invoke$3(/* Menu.hideSubMenu */7903, /* parentIndex */parentMenu.focusedIndex);
1794
+ };
1795
+
1796
+ const Separator$1 = 1;
1797
+ const None = 0;
1798
+ const SubMenu = 4;
1799
+ const Checked = 2;
1800
+ const Unchecked = 3;
1801
+ const Disabled = 5;
1802
+ const RestoreFocus = 6;
1803
+ const Ignore = 7;
1804
+
1805
+ // TODO lazyload menuEntries and use Command.execute (maybe)
1806
+ const CONTEXT_MENU_WIDTH$1 = 250;
1807
+
1808
+ // TODO difference between focusing with mouse or keyboard
1809
+ // with mouse -> open submenu
1810
+ // with keyboard -> don't open submenu, only focus
1811
+
1812
+ // TODO this code seems a bit too complicated, maybe it can be simplified
1813
+
1814
+ // TODO handle printable letter and focus item that starts with that letter
1815
+
1816
+ // TODO pageup / pagedown keys
1817
+
1818
+ // TODO more tests
1819
+
1820
+ const CONTEXT_MENU_ITEM_HEIGHT$1 = 26;
1821
+ const CONTEXT_MENU_SEPARATOR_HEIGHT$1 = 11;
1822
+ const CONTEXT_MENU_PADDING$1 = 8;
1823
+ const getMenuHeight$1 = items => {
1824
+ let height = CONTEXT_MENU_PADDING$1;
1825
+ for (const item of items) {
1826
+ switch (item.flags) {
1827
+ case Separator$1:
1828
+ height += CONTEXT_MENU_SEPARATOR_HEIGHT$1;
1829
+ break;
1830
+ default:
1831
+ height += CONTEXT_MENU_ITEM_HEIGHT$1;
1832
+ break;
1833
+ }
1834
+ }
1835
+ return height;
1836
+ };
1837
+ const getMenuBounds = (x, y, items) => {
1838
+ const menuWidth = CONTEXT_MENU_WIDTH$1;
1839
+ const menuHeight = getMenuHeight$1(items);
1840
+ const layoutState = {
1841
+ points: [0, 0]
1842
+ };
1843
+ const windowWidth = layoutState.points[0];
1844
+ const windowHeight = layoutState.points[1];
1845
+ // TODO maybe only send labels and keybindings to ui (id not needed on ui)
1846
+ // TODO what about separators?
1847
+
1848
+ if (x + menuWidth > windowWidth) {
1849
+ x -= menuWidth;
1850
+ x = Math.max(x, 0);
1851
+ }
1852
+ if (y + menuHeight > windowHeight) {
1853
+ y -= menuHeight;
1854
+ y = Math.max(y, 0);
1855
+ }
1856
+ return {
1857
+ x,
1858
+ y,
1859
+ width: menuWidth,
1860
+ height: menuHeight
1861
+ };
1862
+ };
1863
+
1582
1864
  const matchesArgs = (a, b) => {
1583
1865
  if (!a && !b) {
1584
1866
  return true;
@@ -1615,7 +1897,7 @@ const invoke$1 = async (method, ...params) => {
1615
1897
  await invoke$2('WebView.compatRendererProcessInvoke', method, ...params);
1616
1898
  };
1617
1899
 
1618
- const state$1 = {
1900
+ const state = {
1619
1901
  /**
1620
1902
  * @type {any}
1621
1903
  */
@@ -1698,19 +1980,10 @@ const Terminal$1 = 14;
1698
1980
  const TitleBar = 15;
1699
1981
  const View$1 = 16;
1700
1982
 
1701
- const Separator$1 = 1;
1702
- const None = 0;
1703
- const SubMenu = 4;
1704
- const Checked = 2;
1705
- const Unchecked = 3;
1706
- const Disabled = 5;
1707
- const RestoreFocus = 6;
1708
- const Ignore = 7;
1709
-
1710
1983
  const menuEntrySeparator = {
1711
1984
  id: 'separator',
1712
1985
  label: '',
1713
- flags: Separator$1,
1986
+ flags: Separator$2,
1714
1987
  command: ''
1715
1988
  };
1716
1989
 
@@ -2193,7 +2466,7 @@ const getMenuEntries2 = async (uid, menuId, ...args) => {
2193
2466
  };
2194
2467
 
2195
2468
  const addKeyBindings = menuEntries => {
2196
- const keyBindings = state$1.matchingKeyBindings;
2469
+ const keyBindings = state.matchingKeyBindings;
2197
2470
  const newMenuEntries = [];
2198
2471
  for (const menuEntry of menuEntries) {
2199
2472
  const keyBinding = getCommandKeyBinding(keyBindings, menuEntry.command, menuEntry.args);
@@ -2449,72 +2722,56 @@ const getVisible = (items, focusedIndex, expanded, level) => {
2449
2722
  return visibleItems;
2450
2723
  };
2451
2724
 
2452
- /* eslint-disable @typescript-eslint/prefer-readonly-parameter-types */
2453
- // TODO lazyload menuEntries and use Command.execute (maybe)
2454
-
2455
- // TODO difference between focusing with mouse or keyboard
2456
- // with mouse -> open submenu
2457
- // with keyboard -> don't open submenu, only focus
2458
-
2459
- // TODO this code seems a bit too complicated, maybe it can be simplified
2460
-
2461
- const state = {
2462
- menus: [],
2463
- latestTimeStamp: 0};
2464
- const addMenuInternal = menu => {
2465
- if (state.menus.length > 5) {
2466
- throw new Error('too many menus');
2467
- }
2468
- state.menus.push(menu);
2469
- return menu;
2470
- };
2471
- const getCount = () => {
2472
- return state.menus.length;
2473
- };
2474
- const reset = () => {
2475
- state.menus = [];
2476
- };
2477
- const get$1 = index => {
2478
- return state.menus[index];
2479
- };
2480
- const set$1 = menus => {
2481
- state.menus = menus;
2482
- };
2483
- const getAll = () => {
2484
- return state.menus;
2485
- };
2486
- const setTimestamp = timestamp => {
2487
- state.latestTimeStamp = timestamp;
2488
- };
2489
- const getLatestTimestamp = () => {
2490
- return state.latestTimeStamp;
2725
+ const CONTEXT_MENU_WIDTH = 250;
2726
+ const getMenuWidth = () => {
2727
+ return CONTEXT_MENU_WIDTH;
2491
2728
  };
2492
2729
 
2493
2730
  // TODO lazyload menuEntries and use Command.execute (maybe)
2494
- const CONTEXT_MENU_ITEM_HEIGHT$2 = 26;
2495
- const CONTEXT_MENU_SEPARATOR_HEIGHT$2 = 11;
2496
- const CONTEXT_MENU_PADDING$2 = 8;
2497
- const getMenuHeight$2 = items => {
2498
- let height = CONTEXT_MENU_PADDING$2;
2731
+ const CONTEXT_MENU_ITEM_HEIGHT = 26;
2732
+ const CONTEXT_MENU_SEPARATOR_HEIGHT = 11;
2733
+ const CONTEXT_MENU_PADDING = 8;
2734
+ const getMenuHeight = items => {
2735
+ let height = CONTEXT_MENU_PADDING;
2499
2736
  for (const item of items) {
2500
2737
  switch (item.flags) {
2501
2738
  case Separator$1:
2502
- height += CONTEXT_MENU_SEPARATOR_HEIGHT$2;
2739
+ height += CONTEXT_MENU_SEPARATOR_HEIGHT;
2503
2740
  break;
2504
2741
  default:
2505
- height += CONTEXT_MENU_ITEM_HEIGHT$2;
2742
+ height += CONTEXT_MENU_ITEM_HEIGHT;
2506
2743
  break;
2507
2744
  }
2508
2745
  }
2509
2746
  return height;
2510
2747
  };
2511
2748
 
2749
+ const getMenuHideCommands = async (restoreFocus = true) => {
2750
+ if (getCount() === 0) {
2751
+ return {
2752
+ newMenus: [],
2753
+ commands: []
2754
+ };
2755
+ }
2756
+ reset();
2757
+ return {
2758
+ commands: [/* Menu.hide */'Menu.hide', /* restoreFocus */restoreFocus],
2759
+ newMenus: []
2760
+ };
2761
+ };
2762
+
2763
+ const hide = async (restoreFocus = true) => {
2764
+ const {
2765
+ commands
2766
+ } = await getMenuHideCommands(restoreFocus);
2767
+ if (commands.length > 0) {
2768
+ // @ts-ignore
2769
+ await invoke$3(...commands);
2770
+ }
2771
+ };
2772
+
2512
2773
  // TODO lazyload menuEntries and use Command.execute (maybe)
2513
2774
  const MENU_WIDTH = 150;
2514
- const CONTEXT_MENU_WIDTH$1 = 250;
2515
- const getMenuWidth = () => {
2516
- return CONTEXT_MENU_WIDTH$1;
2517
- };
2518
2775
 
2519
2776
  // TODO difference between focusing with mouse or keyboard
2520
2777
  // with mouse -> open submenu
@@ -2526,50 +2783,9 @@ const getMenuWidth = () => {
2526
2783
 
2527
2784
  // TODO more tests
2528
2785
 
2529
- const CONTEXT_MENU_ITEM_HEIGHT$1 = 26;
2530
- const CONTEXT_MENU_SEPARATOR_HEIGHT$1 = 11;
2531
- const CONTEXT_MENU_PADDING$1 = 8;
2532
- const getMenuHeight$1 = items => {
2533
- let height = CONTEXT_MENU_PADDING$1;
2534
- for (const item of items) {
2535
- switch (item.flags) {
2536
- case Separator$1:
2537
- height += CONTEXT_MENU_SEPARATOR_HEIGHT$1;
2538
- break;
2539
- default:
2540
- height += CONTEXT_MENU_ITEM_HEIGHT$1;
2541
- break;
2542
- }
2543
- }
2544
- return height;
2545
- };
2546
- const getMenuBounds$1 = (x, y, items) => {
2547
- const menuWidth = CONTEXT_MENU_WIDTH$1;
2548
- const menuHeight = getMenuHeight$1(items);
2549
- const layoutState = {
2550
- points: [0, 0]
2551
- };
2552
- const windowWidth = layoutState.points[0];
2553
- const windowHeight = layoutState.points[1];
2554
- // TODO maybe only send labels and keybindings to ui (id not needed on ui)
2555
- // TODO what about separators?
2556
-
2557
- if (x + menuWidth > windowWidth) {
2558
- x -= menuWidth;
2559
- }
2560
- if (y + menuHeight > windowHeight) {
2561
- y -= menuHeight;
2562
- }
2563
- return {
2564
- x,
2565
- y,
2566
- width: menuWidth,
2567
- height: menuHeight
2568
- };
2569
- };
2570
2786
  const show$2 = async (x, y, id, mouseBlocking = false, ...args) => {
2571
2787
  const items = await getMenuEntriesWithKeyBindings(id, ...args);
2572
- const bounds = getMenuBounds$1(x, y, items);
2788
+ const bounds = getMenuBounds(x, y, items);
2573
2789
  const menu = addMenuInternal({
2574
2790
  id,
2575
2791
  items,
@@ -2584,7 +2800,7 @@ const show$2 = async (x, y, id, mouseBlocking = false, ...args) => {
2584
2800
  };
2585
2801
  const show2$2 = async (uid, menuId, x, y, mouseBlocking = false, ...args) => {
2586
2802
  const items = await getMenuEntriesWithKeyBindings2(uid, menuId, ...args);
2587
- const bounds = getMenuBounds$1(x, y, items);
2803
+ const bounds = getMenuBounds(x, y, items);
2588
2804
  const menu = addMenuInternal({
2589
2805
  id: menuId,
2590
2806
  items,
@@ -2597,17 +2813,10 @@ const show2$2 = async (uid, menuId, x, y, mouseBlocking = false, ...args) => {
2597
2813
  const dom = getMenuVirtualDom(visible).slice(1);
2598
2814
  await invoke$1(/* Menu.show */'Menu.showMenu', /* x */bounds.x, /* y */bounds.y, /* width */bounds.width, /* height */bounds.height, /* items */menu.items, /* level */menu.level, /* parentIndex */-1, /* dom */dom, /* mouseBlocking */mouseBlocking);
2599
2815
  };
2600
- const hide$1 = async (restoreFocus = true) => {
2601
- if (getCount() === 0) {
2602
- return;
2603
- }
2604
- reset();
2605
- await invoke$1(/* Menu.hide */'Menu.hide', /* restoreFocus */restoreFocus);
2606
- };
2607
2816
 
2608
2817
  const show$1 = async (x, y, id, ...args) => {
2609
2818
  // @ts-ignore
2610
- await hide$1();
2819
+ await hide();
2611
2820
  // TODO handle error
2612
2821
  // TODO race condition
2613
2822
  await show$2(x, y, id, /* mouseBlocking */true, ...args);
@@ -2616,7 +2825,7 @@ const show$1 = async (x, y, id, ...args) => {
2616
2825
  };
2617
2826
  const show2$1 = async (uid, menuId, x, y, ...args) => {
2618
2827
  // @ts-ignore
2619
- await hide$1();
2828
+ await hide();
2620
2829
  // TODO handle error
2621
2830
  // TODO race condition
2622
2831
  await show2$2(uid, menuId, x, y, /* mouseBlocking */true, ...args);
@@ -2645,7 +2854,7 @@ const show2 = async (uid, menuId, x, y, ...args) => {
2645
2854
  number(menuId);
2646
2855
  number(x);
2647
2856
  number(y);
2648
- const module = getModule();
2857
+ const module = await getModule();
2649
2858
  // @ts-ignore
2650
2859
  return module.show2(uid, menuId, x, y, ...args);
2651
2860
  };
@@ -2858,20 +3067,6 @@ const getKeyBindings = () => {
2858
3067
  }];
2859
3068
  };
2860
3069
 
2861
- const getMenuHideCommands = async (restoreFocus = true) => {
2862
- if (getCount() === 0) {
2863
- return {
2864
- newMenus: [],
2865
- commands: []
2866
- };
2867
- }
2868
- reset();
2869
- return {
2870
- commands: [/* Menu.hide */'Menu.hide', /* restoreFocus */restoreFocus],
2871
- newMenus: []
2872
- };
2873
- };
2874
-
2875
3070
  const menus = [MenuEntriesEdit, MenuEntriesFile, MenuEntriesGo, MenuEntriesHelp, MenuEntriesRun, MenuEntriesSelection, MenuEntriesTerminal, MenuEntriesTitleBar, MenuEntriesView, MenuEntriesOpenRecent];
2876
3071
 
2877
3072
  const getMenuIds = () => {
@@ -2886,7 +3081,6 @@ const getMenuEntries = (id, platform) => {
2886
3081
  };
2887
3082
 
2888
3083
  // TODO lazyload menuEntries and use Command.execute (maybe)
2889
- const CONTEXT_MENU_WIDTH = 250;
2890
3084
 
2891
3085
  // TODO difference between focusing with mouse or keyboard
2892
3086
  // with mouse -> open submenu
@@ -2900,49 +3094,6 @@ const CONTEXT_MENU_WIDTH = 250;
2900
3094
 
2901
3095
  // TODO more tests
2902
3096
 
2903
- const CONTEXT_MENU_ITEM_HEIGHT = 26;
2904
- const CONTEXT_MENU_SEPARATOR_HEIGHT = 11;
2905
- const CONTEXT_MENU_PADDING = 8;
2906
- const getMenuHeight = items => {
2907
- let height = CONTEXT_MENU_PADDING;
2908
- for (const item of items) {
2909
- switch (item.flags) {
2910
- case Separator$1:
2911
- height += CONTEXT_MENU_SEPARATOR_HEIGHT;
2912
- break;
2913
- default:
2914
- height += CONTEXT_MENU_ITEM_HEIGHT;
2915
- break;
2916
- }
2917
- }
2918
- return height;
2919
- };
2920
- const getMenuBounds = (x, y, items) => {
2921
- const menuWidth = CONTEXT_MENU_WIDTH;
2922
- const menuHeight = getMenuHeight(items);
2923
- const layoutState = {
2924
- points: [0, 0]
2925
- };
2926
- const windowWidth = layoutState.points[0];
2927
- const windowHeight = layoutState.points[1];
2928
- // TODO maybe only send labels and keybindings to ui (id not needed on ui)
2929
- // TODO what about separators?
2930
-
2931
- if (x + menuWidth > windowWidth) {
2932
- x -= menuWidth;
2933
- x = Math.max(x, 0);
2934
- }
2935
- if (y + menuHeight > windowHeight) {
2936
- y -= menuHeight;
2937
- y = Math.max(y, 0);
2938
- }
2939
- return {
2940
- x,
2941
- y,
2942
- width: menuWidth,
2943
- height: menuHeight
2944
- };
2945
- };
2946
3097
  const getMenuShowCommands = async (items, menuId, x, y, mouseBlocking = false) => {
2947
3098
  const bounds = getMenuBounds(x, y, items);
2948
3099
  const menu = addMenuInternal({
@@ -2976,6 +3127,12 @@ const hideSubMenus = async level => {
2976
3127
  }
2977
3128
  };
2978
3129
 
3130
+ /* eslint-disable @typescript-eslint/no-implied-eval */
3131
+ const MENU_DELAY_TRIANGLE = 300;
3132
+ const resolveAfterTimeout = fn => {
3133
+ setTimeout(fn, MENU_DELAY_TRIANGLE);
3134
+ };
3135
+
2979
3136
  const showSubMenuAtEnter = async (level, index, enterX, enterY) => {
2980
3137
  // TODO delete old menus
2981
3138
  set$1(getAll().slice(0, level + 1));
@@ -2993,7 +3150,7 @@ const showSubMenuAtEnter = async (level, index, enterX, enterY) => {
2993
3150
  enterY
2994
3151
  });
2995
3152
  const width = getMenuWidth();
2996
- const height = getMenuHeight$2(subMenuItems);
3153
+ const height = getMenuHeight(subMenuItems);
2997
3154
  const visible = getVisible(subMenu.items, -1, false, subMenu.level);
2998
3155
  const dom = getMenuVirtualDom(visible).slice(1);
2999
3156
  return {
@@ -3005,11 +3162,6 @@ const showSubMenu = async (level, index) => {
3005
3162
  return showSubMenuAtEnter(level, index, -1, -1);
3006
3163
  };
3007
3164
 
3008
- /* eslint-disable @typescript-eslint/no-implied-eval */
3009
- const MENU_DELAY_TRIANGLE = 300;
3010
- const resolveAfterTimeout = fn => {
3011
- setTimeout(fn, MENU_DELAY_TRIANGLE);
3012
- };
3013
3165
  const handleMouseEnter = async (level, index, enterX, enterY, enterTimeStamp) => {
3014
3166
  setTimestamp(enterTimeStamp);
3015
3167
  if (level >= getCount()) {
@@ -3065,7 +3217,7 @@ const renderFocusedIndex = (oldState, newState) => {
3065
3217
  if (newState.focusedIndex === -1) {
3066
3218
  return [];
3067
3219
  }
3068
- return ['Viewlet.focusSelector', '.ViewletTitleBarMenuBar'];
3220
+ return [FocusSelector, '.ViewletTitleBarMenuBar'];
3069
3221
  };
3070
3222
 
3071
3223
  const SetMenus = 'setMenus';
@@ -3144,19 +3296,19 @@ const renderEventListeners = () => {
3144
3296
  params: ['handleFocus']
3145
3297
  }, {
3146
3298
  name: HandleMenuClick,
3147
- params: ['handleMenuClick', 'event.clientX', 'event.clientY']
3299
+ params: ['handleMenuClick', ClientX, ClientY]
3148
3300
  }, {
3149
3301
  name: HandleMenuMouseOver,
3150
- params: ['handleMenuMouseOver', 'event.clientX', 'event.clientY']
3302
+ params: ['handleMenuMouseOver', ClientX, ClientY]
3151
3303
  }, {
3152
3304
  name: HandleClick,
3153
- params: ['handleClickAt', 'event.button', 'event.clientX', 'event.clientY']
3305
+ params: ['handleClickAt', Button, ClientX, ClientY]
3154
3306
  }, {
3155
3307
  name: HandlePointerOut,
3156
- params: ['handlePointerOut', 'event.clientX', 'event.clientY']
3308
+ params: ['handlePointerOut', ClientX, ClientY]
3157
3309
  }, {
3158
3310
  name: HandlePointerOver,
3159
- params: ['handlePointerOver', 'event.clientX', 'event.clientY']
3311
+ params: ['handlePointerOver', ClientX, ClientY]
3160
3312
  }];
3161
3313
  };
3162
3314
 
@@ -3173,16 +3325,6 @@ const executeMenuItemCommand = async item => {
3173
3325
  await invoke(item.command, ...(item.args || []));
3174
3326
  };
3175
3327
 
3176
- const hide = async (restoreFocus = true) => {
3177
- const {
3178
- commands
3179
- } = await getMenuHideCommands(restoreFocus);
3180
- if (commands.length > 0) {
3181
- // @ts-ignore
3182
- await invoke$2(...commands);
3183
- }
3184
- };
3185
-
3186
3328
  const selectIndexNone = async (menu, item) => {
3187
3329
  await Promise.all([hide(/* restoreFocus */false), executeMenuItemCommand(item)]);
3188
3330
  };
@@ -3251,12 +3393,13 @@ const wrapCommand = fn => {
3251
3393
  };
3252
3394
 
3253
3395
  const commandMap = {
3396
+ 'Menu.closeSubMenu': closeSubMenu,
3254
3397
  'Menu.diff2': diff2,
3255
- 'Menu.focusPrevious': focusPrevious,
3256
3398
  'Menu.focusFirst': focusFirst,
3257
3399
  'Menu.focusIndex': focusIndex,
3258
3400
  'Menu.focusLast': focusLast,
3259
3401
  'Menu.focusNext': focusNext,
3402
+ 'Menu.focusPrevious': focusPrevious,
3260
3403
  'Menu.getCommands': getCommandIds,
3261
3404
  'Menu.getHideCommands': getMenuHideCommands,
3262
3405
  'Menu.getKeyBindings': getKeyBindings,
@@ -3267,22 +3410,45 @@ const commandMap = {
3267
3410
  'Menu.handleContextMenu': handleContextMenu,
3268
3411
  'Menu.handleMouseEnter': handleMouseEnter,
3269
3412
  'Menu.handleMouseLeave': handleMouseLeave,
3413
+ 'Menu.hide': hide,
3270
3414
  'Menu.hideSubMenus': hideSubMenus,
3271
3415
  'Menu.loadContent': wrapCommand(loadContent),
3272
3416
  'Menu.render2': render2,
3273
3417
  'Menu.renderEventListeners': renderEventListeners,
3274
3418
  'Menu.saveState': saveState,
3419
+ 'Menu.selectIndex': selectIndex,
3275
3420
  'Menu.selectItem': selectItem,
3276
3421
  'Menu.show': show,
3277
3422
  'Menu.show2': show2,
3278
3423
  'Menu.showSubMenu': showSubMenu
3279
3424
  };
3280
3425
 
3426
+ const send = port => {
3427
+ return sendMessagePortToRendererProcess(port);
3428
+ };
3429
+ const createRendererProcessRpc = async () => {
3430
+ try {
3431
+ const rpc = await TransferMessagePortRpcParent.create({
3432
+ commandMap: {},
3433
+ send
3434
+ });
3435
+ return rpc;
3436
+ } catch (error) {
3437
+ throw new VError(error, `Failed to create renderer process rpc`);
3438
+ }
3439
+ };
3440
+
3441
+ const initializeRendererProcess = async () => {
3442
+ const rpc = await createRendererProcessRpc();
3443
+ set$3(rpc);
3444
+ };
3445
+
3281
3446
  const listen = async () => {
3282
3447
  const rpc = await WebWorkerRpcClient.create({
3283
3448
  commandMap: commandMap
3284
3449
  });
3285
3450
  set$2(rpc);
3451
+ await initializeRendererProcess();
3286
3452
  };
3287
3453
 
3288
3454
  const main = async () => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lvce-editor/menu-worker",
3
- "version": "2.0.0",
3
+ "version": "2.2.0",
4
4
  "description": "Menu Worker",
5
5
  "repository": {
6
6
  "type": "git",