@lvce-editor/menu-worker 1.6.0 → 2.0.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.
@@ -421,10 +421,10 @@ const create$4 = (method, params) => {
421
421
  };
422
422
  };
423
423
  const callbacks = Object.create(null);
424
- const set$3 = (id, fn) => {
424
+ const set$4 = (id, fn) => {
425
425
  callbacks[id] = fn;
426
426
  };
427
- const get$2 = id => {
427
+ const get$3 = id => {
428
428
  return callbacks[id];
429
429
  };
430
430
  const remove = id => {
@@ -440,7 +440,7 @@ const registerPromise = () => {
440
440
  resolve,
441
441
  promise
442
442
  } = Promise.withResolvers();
443
- set$3(id, resolve);
443
+ set$4(id, resolve);
444
444
  return {
445
445
  id,
446
446
  promise
@@ -601,14 +601,14 @@ const unwrapJsonRpcResult = responseMessage => {
601
601
  }
602
602
  throw new JsonRpcError('unexpected response message');
603
603
  };
604
- const warn = (...args) => {
604
+ const warn$1 = (...args) => {
605
605
  console.warn(...args);
606
606
  };
607
607
  const resolve = (id, response) => {
608
- const fn = get$2(id);
608
+ const fn = get$3(id);
609
609
  if (!fn) {
610
610
  console.log(response);
611
- warn(`callback ${id} may already be disposed`);
611
+ warn$1(`callback ${id} may already be disposed`);
612
612
  return;
613
613
  }
614
614
  fn(response);
@@ -785,10 +785,10 @@ const send = (transport, method, ...params) => {
785
785
  const message = create$4(method, params);
786
786
  transport.send(message);
787
787
  };
788
- const invoke$2 = (ipc, method, ...params) => {
788
+ const invoke$3 = (ipc, method, ...params) => {
789
789
  return invokeHelper(ipc, method, params, false);
790
790
  };
791
- const invokeAndTransfer = (ipc, method, ...params) => {
791
+ const invokeAndTransfer$1 = (ipc, method, ...params) => {
792
792
  return invokeHelper(ipc, method, params, true);
793
793
  };
794
794
 
@@ -824,10 +824,10 @@ const createRpc = ipc => {
824
824
  send(ipc, method, ...params);
825
825
  },
826
826
  invoke(method, ...params) {
827
- return invoke$2(ipc, method, ...params);
827
+ return invoke$3(ipc, method, ...params);
828
828
  },
829
829
  invokeAndTransfer(method, ...params) {
830
- return invokeAndTransfer(ipc, method, ...params);
830
+ return invokeAndTransfer$1(ipc, method, ...params);
831
831
  },
832
832
  async dispose() {
833
833
  await ipc?.dispose();
@@ -879,6 +879,25 @@ const WebWorkerRpcClient = {
879
879
  __proto__: null,
880
880
  create: create$2
881
881
  };
882
+ const createMockRpc = ({
883
+ commandMap
884
+ }) => {
885
+ const invocations = [];
886
+ const invoke = (method, ...params) => {
887
+ invocations.push([method, ...params]);
888
+ const command = commandMap[method];
889
+ if (!command) {
890
+ throw new Error(`command ${method} not found`);
891
+ }
892
+ return command(...params);
893
+ };
894
+ const mockRpc = {
895
+ invoke,
896
+ invokeAndTransfer: invoke,
897
+ invocations
898
+ };
899
+ return mockRpc;
900
+ };
882
901
 
883
902
  const Text = 12;
884
903
 
@@ -1151,6 +1170,13 @@ const getKeyCodeString = keyCode => {
1151
1170
  const CtrlCmd = 1 << 11 >>> 0;
1152
1171
  const Shift = 1 << 10 >>> 0;
1153
1172
 
1173
+ const Separator$2 = 1;
1174
+ const None$1 = 0;
1175
+ const SubMenu$1 = 4;
1176
+ const Disabled$1 = 5;
1177
+ const RestoreFocus$1 = 6;
1178
+ const Ignore$1 = 7;
1179
+
1154
1180
  const parseKey = rawKey => {
1155
1181
  const isCtrl = Boolean(rawKey & CtrlCmd);
1156
1182
  const isShift = Boolean(rawKey & Shift);
@@ -1163,13 +1189,14 @@ const parseKey = rawKey => {
1163
1189
  };
1164
1190
  };
1165
1191
 
1166
- const RendererWorker = 1;
1192
+ const DebugWorker = 55;
1193
+ const RendererWorker$1 = 1;
1167
1194
 
1168
1195
  const rpcs = Object.create(null);
1169
- const set$2 = (id, rpc) => {
1196
+ const set$3 = (id, rpc) => {
1170
1197
  rpcs[id] = rpc;
1171
1198
  };
1172
- const get$1 = id => {
1199
+ const get$2 = id => {
1173
1200
  return rpcs[id];
1174
1201
  };
1175
1202
 
@@ -1177,29 +1204,380 @@ const create$1 = rpcId => {
1177
1204
  return {
1178
1205
  // @ts-ignore
1179
1206
  invoke(method, ...params) {
1180
- const rpc = get$1(rpcId);
1207
+ const rpc = get$2(rpcId);
1181
1208
  // @ts-ignore
1182
1209
  return rpc.invoke(method, ...params);
1183
1210
  },
1184
1211
  // @ts-ignore
1185
1212
  invokeAndTransfer(method, ...params) {
1186
- const rpc = get$1(rpcId);
1213
+ const rpc = get$2(rpcId);
1187
1214
  // @ts-ignore
1188
1215
  return rpc.invokeAndTransfer(method, ...params);
1189
1216
  },
1190
1217
  set(rpc) {
1191
- set$2(rpcId, rpc);
1218
+ set$3(rpcId, rpc);
1192
1219
  },
1193
1220
  async dispose() {
1194
- const rpc = get$1(rpcId);
1221
+ const rpc = get$2(rpcId);
1195
1222
  await rpc.dispose();
1196
1223
  }
1197
1224
  };
1198
1225
  };
1199
1226
 
1200
1227
  const {
1201
- invoke: invoke$1,
1202
- set: set$1} = create$1(RendererWorker);
1228
+ invoke: invoke$2,
1229
+ invokeAndTransfer,
1230
+ set: set$2,
1231
+ dispose
1232
+ } = create$1(RendererWorker$1);
1233
+ const searchFileHtml = async uri => {
1234
+ return invoke$2('ExtensionHost.searchFileWithHtml', uri);
1235
+ };
1236
+ const getFilePathElectron = async file => {
1237
+ return invoke$2('FileSystemHandle.getFilePathElectron', file);
1238
+ };
1239
+ const showContextMenu = async (x, y, id, ...args) => {
1240
+ return invoke$2('ContextMenu.show', x, y, id, ...args);
1241
+ };
1242
+ const getElectronVersion = async () => {
1243
+ return invoke$2('Process.getElectronVersion');
1244
+ };
1245
+ const applyBulkReplacement = async bulkEdits => {
1246
+ await invoke$2('BulkReplacement.applyBulkReplacement', bulkEdits);
1247
+ };
1248
+ const setColorTheme = async id => {
1249
+ // @ts-ignore
1250
+ return invoke$2(/* ColorTheme.setColorTheme */'ColorTheme.setColorTheme', /* colorThemeId */id);
1251
+ };
1252
+ const getNodeVersion = async () => {
1253
+ return invoke$2('Process.getNodeVersion');
1254
+ };
1255
+ const getChromeVersion = async () => {
1256
+ return invoke$2('Process.getChromeVersion');
1257
+ };
1258
+ const getV8Version = async () => {
1259
+ return invoke$2('Process.getV8Version');
1260
+ };
1261
+ const getFileHandles = async fileIds => {
1262
+ const files = await invoke$2('FileSystemHandle.getFileHandles', fileIds);
1263
+ return files;
1264
+ };
1265
+ const setWorkspacePath = async path => {
1266
+ await invoke$2('Workspace.setPath', path);
1267
+ };
1268
+ const registerWebViewInterceptor = async (id, port) => {
1269
+ await invokeAndTransfer('WebView.registerInterceptor', id, port);
1270
+ };
1271
+ const unregisterWebViewInterceptor = async id => {
1272
+ await invoke$2('WebView.unregisterInterceptor', id);
1273
+ };
1274
+ const sendMessagePortToEditorWorker = async (port, rpcId) => {
1275
+ const command = 'HandleMessagePort.handleMessagePort';
1276
+ // @ts-ignore
1277
+ await invokeAndTransfer('SendMessagePortToExtensionHostWorker.sendMessagePortToEditorWorker', port, command, rpcId);
1278
+ };
1279
+ const sendMessagePortToErrorWorker = async (port, rpcId) => {
1280
+ const command = 'Errors.handleMessagePort';
1281
+ // @ts-ignore
1282
+ await invokeAndTransfer('SendMessagePortToExtensionHostWorker.sendMessagePortToErrorWorker', port, command, rpcId);
1283
+ };
1284
+ const sendMessagePortToMarkdownWorker = async (port, rpcId) => {
1285
+ const command = 'Markdown.handleMessagePort';
1286
+ // @ts-ignore
1287
+ await invokeAndTransfer('SendMessagePortToExtensionHostWorker.sendMessagePortToMarkdownWorker', port, command, rpcId);
1288
+ };
1289
+ const sendMessagePortToIconThemeWorker = async (port, rpcId) => {
1290
+ const command = 'IconTheme.handleMessagePort';
1291
+ // @ts-ignore
1292
+ await invokeAndTransfer('SendMessagePortToExtensionHostWorker.sendMessagePortToIconThemeWorker', port, command, rpcId);
1293
+ };
1294
+ const sendMessagePortToFileSystemWorker = async (port, rpcId) => {
1295
+ const command = 'FileSystem.handleMessagePort';
1296
+ // @ts-ignore
1297
+ await invokeAndTransfer('SendMessagePortToExtensionHostWorker.sendMessagePortToFileSystemWorker', port, command, rpcId);
1298
+ };
1299
+ const readFile = async uri => {
1300
+ return invoke$2('FileSystem.readFile', uri);
1301
+ };
1302
+ const getWebViewSecret = async key => {
1303
+ // @ts-ignore
1304
+ return invoke$2('WebView.getSecret', key);
1305
+ };
1306
+ const setWebViewPort = async (uid, port, origin, portType) => {
1307
+ return invokeAndTransfer('WebView.setPort', uid, port, origin, portType);
1308
+ };
1309
+ const setFocus = key => {
1310
+ return invoke$2('Focus.setFocus', key);
1311
+ };
1312
+ const getFileIcon = async options => {
1313
+ return invoke$2('IconTheme.getFileIcon', options);
1314
+ };
1315
+ const getColorThemeNames = async () => {
1316
+ return invoke$2('ColorTheme.getColorThemeNames');
1317
+ };
1318
+ const disableExtension = async id => {
1319
+ // @ts-ignore
1320
+ return invoke$2('ExtensionManagement.disable', id);
1321
+ };
1322
+ const enableExtension = async id => {
1323
+ // @ts-ignore
1324
+ return invoke$2('ExtensionManagement.enable', id);
1325
+ };
1326
+ const handleDebugChange = async params => {
1327
+ // @ts-ignore
1328
+ return invoke$2('Run And Debug.handleChange', params);
1329
+ };
1330
+ const getFolderIcon = async options => {
1331
+ return invoke$2('IconTheme.getFolderIcon', options);
1332
+ };
1333
+ const closeWidget = async widgetId => {
1334
+ return invoke$2('Viewlet.closeWidget', widgetId);
1335
+ };
1336
+ const sendMessagePortToExtensionHostWorker = async (port, rpcId = 0) => {
1337
+ const command = 'HandleMessagePort.handleMessagePort2';
1338
+ await invokeAndTransfer('SendMessagePortToExtensionHostWorker.sendMessagePortToExtensionHostWorker', port, command, rpcId);
1339
+ };
1340
+ const sendMessagePortToSearchProcess = async port => {
1341
+ await invokeAndTransfer('SendMessagePortToElectron.sendMessagePortToElectron', port, 'HandleMessagePortForSearchProcess.handleMessagePortForSearchProcess');
1342
+ };
1343
+ const confirm = async (message, options) => {
1344
+ // @ts-ignore
1345
+ const result = await invoke$2('ConfirmPrompt.prompt', message, options);
1346
+ return result;
1347
+ };
1348
+ const getRecentlyOpened$1 = async () => {
1349
+ return invoke$2(/* RecentlyOpened.getRecentlyOpened */'RecentlyOpened.getRecentlyOpened');
1350
+ };
1351
+ const getKeyBindings$1 = async () => {
1352
+ return invoke$2('KeyBindingsInitial.getKeyBindings');
1353
+ };
1354
+ const writeClipBoardText = async text => {
1355
+ await invoke$2('ClipBoard.writeText', /* text */text);
1356
+ };
1357
+ const writeClipBoardImage = async blob => {
1358
+ // @ts-ignore
1359
+ await invoke$2('ClipBoard.writeImage', /* text */blob);
1360
+ };
1361
+ const searchFileMemory = async uri => {
1362
+ // @ts-ignore
1363
+ return invoke$2('ExtensionHost.searchFileWithMemory', uri);
1364
+ };
1365
+ const searchFileFetch = async uri => {
1366
+ return invoke$2('ExtensionHost.searchFileWithFetch', uri);
1367
+ };
1368
+ const showMessageBox = async options => {
1369
+ return invoke$2('ElectronDialog.showMessageBox', options);
1370
+ };
1371
+ const handleDebugResumed = async params => {
1372
+ await invoke$2('Run And Debug.handleResumed', params);
1373
+ };
1374
+ const openWidget = async name => {
1375
+ await invoke$2('Viewlet.openWidget', name);
1376
+ };
1377
+ const getIcons = async requests => {
1378
+ const icons = await invoke$2('IconTheme.getIcons', requests);
1379
+ return icons;
1380
+ };
1381
+ const activateByEvent = event => {
1382
+ return invoke$2('ExtensionHostManagement.activateByEvent', event);
1383
+ };
1384
+ const setAdditionalFocus = focusKey => {
1385
+ // @ts-ignore
1386
+ return invoke$2('Focus.setAdditionalFocus', focusKey);
1387
+ };
1388
+ const getActiveEditorId = () => {
1389
+ // @ts-ignore
1390
+ return invoke$2('GetActiveEditor.getActiveEditorId');
1391
+ };
1392
+ const getWorkspacePath = () => {
1393
+ return invoke$2('Workspace.getPath');
1394
+ };
1395
+ const sendMessagePortToRendererProcess = async port => {
1396
+ const command = 'HandleMessagePort.handleMessagePort';
1397
+ // @ts-ignore
1398
+ await invokeAndTransfer('SendMessagePortToExtensionHostWorker.sendMessagePortToRendererProcess', port, command, DebugWorker);
1399
+ };
1400
+ const getPreference = async key => {
1401
+ return await invoke$2('Preferences.get', key);
1402
+ };
1403
+ const getAllExtensions = async () => {
1404
+ return invoke$2('ExtensionManagement.getAllExtensions');
1405
+ };
1406
+ const rerenderEditor = async key => {
1407
+ // @ts-ignore
1408
+ return invoke$2('Editor.rerender', key);
1409
+ };
1410
+ const handleDebugPaused = async params => {
1411
+ await invoke$2('Run And Debug.handlePaused', params);
1412
+ };
1413
+ const openUri = async (uri, focus, options) => {
1414
+ await invoke$2('Main.openUri', uri, focus, options);
1415
+ };
1416
+ const sendMessagePortToSyntaxHighlightingWorker = async port => {
1417
+ await invokeAndTransfer(
1418
+ // @ts-ignore
1419
+ 'SendMessagePortToSyntaxHighlightingWorker.sendMessagePortToSyntaxHighlightingWorker', port, 'HandleMessagePort.handleMessagePort2');
1420
+ };
1421
+ const handleDebugScriptParsed = async script => {
1422
+ await invoke$2('Run And Debug.handleScriptParsed', script);
1423
+ };
1424
+ const getWindowId = async () => {
1425
+ return invoke$2('GetWindowId.getWindowId');
1426
+ };
1427
+ const getBlob = async uri => {
1428
+ // @ts-ignore
1429
+ return invoke$2('FileSystem.getBlob', uri);
1430
+ };
1431
+ const getExtensionCommands = async () => {
1432
+ return invoke$2('ExtensionHost.getCommands');
1433
+ };
1434
+ const showErrorDialog = async errorInfo => {
1435
+ // @ts-ignore
1436
+ await invoke$2('ErrorHandling.showErrorDialog', errorInfo);
1437
+ };
1438
+ const getFolderSize = async uri => {
1439
+ // @ts-ignore
1440
+ return await invoke$2('FileSystem.getFolderSize', uri);
1441
+ };
1442
+ const getExtension = async id => {
1443
+ // @ts-ignore
1444
+ return invoke$2('ExtensionManagement.getExtension', id);
1445
+ };
1446
+ const getMarkdownDom = async html => {
1447
+ // @ts-ignore
1448
+ return invoke$2('Markdown.getVirtualDom', html);
1449
+ };
1450
+ const renderMarkdown = async (markdown, options) => {
1451
+ // @ts-ignore
1452
+ return invoke$2('Markdown.renderMarkdown', markdown, options);
1453
+ };
1454
+ const openNativeFolder = async uri => {
1455
+ // @ts-ignore
1456
+ await invoke$2('OpenNativeFolder.openNativeFolder', uri);
1457
+ };
1458
+ const uninstallExtension = async id => {
1459
+ return invoke$2('ExtensionManagement.uninstall', id);
1460
+ };
1461
+ const installExtension = async id => {
1462
+ // @ts-ignore
1463
+ return invoke$2('ExtensionManagement.install', id);
1464
+ };
1465
+ const openExtensionSearch = async () => {
1466
+ // @ts-ignore
1467
+ return invoke$2('SideBar.openViewlet', 'Extensions');
1468
+ };
1469
+ const setExtensionsSearchValue = async searchValue => {
1470
+ // @ts-ignore
1471
+ return invoke$2('Extensions.handleInput', searchValue);
1472
+ };
1473
+ const openExternal = async uri => {
1474
+ // @ts-ignore
1475
+ await invoke$2('Open.openExternal', uri);
1476
+ };
1477
+ const openUrl = async uri => {
1478
+ // @ts-ignore
1479
+ await invoke$2('Open.openUrl', uri);
1480
+ };
1481
+ const getAllPreferences = async () => {
1482
+ // @ts-ignore
1483
+ return invoke$2('Preferences.getAll');
1484
+ };
1485
+ const showSaveFilePicker = async () => {
1486
+ // @ts-ignore
1487
+ return invoke$2('FilePicker.showSaveFilePicker');
1488
+ };
1489
+ const getLogsDir = async () => {
1490
+ // @ts-ignore
1491
+ return invoke$2('PlatformPaths.getLogsDir');
1492
+ };
1493
+ const registerMockRpc = commandMap => {
1494
+ const mockRpc = createMockRpc({
1495
+ commandMap
1496
+ });
1497
+ set$2(mockRpc);
1498
+ return mockRpc;
1499
+ };
1500
+
1501
+ const RendererWorker = {
1502
+ __proto__: null,
1503
+ activateByEvent,
1504
+ applyBulkReplacement,
1505
+ closeWidget,
1506
+ confirm,
1507
+ disableExtension,
1508
+ dispose,
1509
+ enableExtension,
1510
+ getActiveEditorId,
1511
+ getAllExtensions,
1512
+ getAllPreferences,
1513
+ getBlob,
1514
+ getChromeVersion,
1515
+ getColorThemeNames,
1516
+ getElectronVersion,
1517
+ getExtension,
1518
+ getExtensionCommands,
1519
+ getFileHandles,
1520
+ getFileIcon,
1521
+ getFilePathElectron,
1522
+ getFolderIcon,
1523
+ getFolderSize,
1524
+ getIcons,
1525
+ getKeyBindings: getKeyBindings$1,
1526
+ getLogsDir,
1527
+ getMarkdownDom,
1528
+ getNodeVersion,
1529
+ getPreference,
1530
+ getRecentlyOpened: getRecentlyOpened$1,
1531
+ getV8Version,
1532
+ getWebViewSecret,
1533
+ getWindowId,
1534
+ getWorkspacePath,
1535
+ handleDebugChange,
1536
+ handleDebugPaused,
1537
+ handleDebugResumed,
1538
+ handleDebugScriptParsed,
1539
+ installExtension,
1540
+ invoke: invoke$2,
1541
+ invokeAndTransfer,
1542
+ openExtensionSearch,
1543
+ openExternal,
1544
+ openNativeFolder,
1545
+ openUri,
1546
+ openUrl,
1547
+ openWidget,
1548
+ readFile,
1549
+ registerMockRpc,
1550
+ registerWebViewInterceptor,
1551
+ renderMarkdown,
1552
+ rerenderEditor,
1553
+ searchFileFetch,
1554
+ searchFileHtml,
1555
+ searchFileMemory,
1556
+ sendMessagePortToEditorWorker,
1557
+ sendMessagePortToErrorWorker,
1558
+ sendMessagePortToExtensionHostWorker,
1559
+ sendMessagePortToFileSystemWorker,
1560
+ sendMessagePortToIconThemeWorker,
1561
+ sendMessagePortToMarkdownWorker,
1562
+ sendMessagePortToRendererProcess,
1563
+ sendMessagePortToSearchProcess,
1564
+ sendMessagePortToSyntaxHighlightingWorker,
1565
+ set: set$2,
1566
+ setAdditionalFocus,
1567
+ setColorTheme,
1568
+ setExtensionsSearchValue,
1569
+ setFocus,
1570
+ setWebViewPort,
1571
+ setWorkspacePath,
1572
+ showContextMenu,
1573
+ showErrorDialog,
1574
+ showMessageBox,
1575
+ showSaveFilePicker,
1576
+ uninstallExtension,
1577
+ unregisterWebViewInterceptor,
1578
+ writeClipBoardImage,
1579
+ writeClipBoardText
1580
+ };
1203
1581
 
1204
1582
  const matchesArgs = (a, b) => {
1205
1583
  if (!a && !b) {
@@ -1227,8 +1605,14 @@ const getCommandKeyBinding = (keyBindings, command, args) => {
1227
1605
  return undefined;
1228
1606
  };
1229
1607
 
1230
- const invoke = async (method, ...params) => {
1231
- // TODO
1608
+ /* eslint-disable no-console */
1609
+ const warn = (...args) => {
1610
+ console.warn(...args);
1611
+ };
1612
+
1613
+ const invoke$1 = async (method, ...params) => {
1614
+ // @ts-ignore
1615
+ await invoke$2('WebView.compatRendererProcessInvoke', method, ...params);
1232
1616
  };
1233
1617
 
1234
1618
  const state$1 = {
@@ -1540,7 +1924,7 @@ const MenuEntriesHelp = {
1540
1924
  };
1541
1925
 
1542
1926
  const getRecentlyOpened = () => {
1543
- return invoke$1(/* RecentlyOpened.getRecentlyOpened */'RecentlyOpened.getRecentlyOpened');
1927
+ return invoke$2(/* RecentlyOpened.getRecentlyOpened */'RecentlyOpened.getRecentlyOpened');
1544
1928
  };
1545
1929
 
1546
1930
  const File = 'file://';
@@ -1799,33 +2183,13 @@ const menus$1 = [MenuEntriesEdit, MenuEntriesFile, MenuEntriesGo, MenuEntriesHel
1799
2183
  const getMenus = () => {
1800
2184
  return menus$1;
1801
2185
  };
1802
- const getModule$1 = id => {
1803
- for (const module of menus$1) {
1804
- if (module.id === id) {
1805
- return module;
1806
- }
1807
- }
1808
- return undefined;
1809
- };
1810
2186
  const getMenuEntries$1 = async (id, ...args) => {
1811
- try {
1812
- const module = getModule$1(id);
1813
- // @ts-ignore
1814
- const inject = module.inject || [];
1815
- // @ts-ignore
1816
- return module.getMenuEntries(...args);
1817
- } catch (error) {
1818
- throw new VError(error, `Failed to load menu entries for id ${id}`);
1819
- }
2187
+ // @ts-ignore
2188
+ return invoke$2('Menu.getMenuEntries', id, ...args);
1820
2189
  };
1821
2190
  const getMenuEntries2 = async (uid, menuId, ...args) => {
1822
- try {
1823
- const module = await getModule$1(menuId);
1824
- // @ts-ignore
1825
- return module.getMenuEntries(uid, ...args);
1826
- } catch (error) {
1827
- throw new VError(error, `Failed to load menu entries for id ${menuId}`);
1828
- }
2191
+ // @ts-ignore
2192
+ return invoke$2('Menu.getMenuEntries2', uid, menuId, ...args);
1829
2193
  };
1830
2194
 
1831
2195
  const addKeyBindings = menuEntries => {
@@ -2095,7 +2459,8 @@ const getVisible = (items, focusedIndex, expanded, level) => {
2095
2459
  // TODO this code seems a bit too complicated, maybe it can be simplified
2096
2460
 
2097
2461
  const state = {
2098
- menus: []};
2462
+ menus: [],
2463
+ latestTimeStamp: 0};
2099
2464
  const addMenuInternal = menu => {
2100
2465
  if (state.menus.length > 5) {
2101
2466
  throw new Error('too many menus');
@@ -2109,12 +2474,51 @@ const getCount = () => {
2109
2474
  const reset = () => {
2110
2475
  state.menus = [];
2111
2476
  };
2477
+ const get$1 = index => {
2478
+ return state.menus[index];
2479
+ };
2480
+ const set$1 = menus => {
2481
+ state.menus = menus;
2482
+ };
2112
2483
  const getAll = () => {
2113
2484
  return state.menus;
2114
2485
  };
2486
+ const setTimestamp = timestamp => {
2487
+ state.latestTimeStamp = timestamp;
2488
+ };
2489
+ const getLatestTimestamp = () => {
2490
+ return state.latestTimeStamp;
2491
+ };
2492
+
2493
+ // 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;
2499
+ for (const item of items) {
2500
+ switch (item.flags) {
2501
+ case Separator$1:
2502
+ height += CONTEXT_MENU_SEPARATOR_HEIGHT$2;
2503
+ break;
2504
+ default:
2505
+ height += CONTEXT_MENU_ITEM_HEIGHT$2;
2506
+ break;
2507
+ }
2508
+ }
2509
+ return height;
2510
+ };
2115
2511
 
2116
2512
  // TODO lazyload menuEntries and use Command.execute (maybe)
2513
+ const MENU_WIDTH = 150;
2117
2514
  const CONTEXT_MENU_WIDTH$1 = 250;
2515
+ const getMenuWidth = () => {
2516
+ return CONTEXT_MENU_WIDTH$1;
2517
+ };
2518
+
2519
+ // TODO difference between focusing with mouse or keyboard
2520
+ // with mouse -> open submenu
2521
+ // with keyboard -> don't open submenu, only focus
2118
2522
 
2119
2523
  // TODO handle printable letter and focus item that starts with that letter
2120
2524
 
@@ -2176,7 +2580,7 @@ const show$2 = async (x, y, id, mouseBlocking = false, ...args) => {
2176
2580
  });
2177
2581
  const visible = getVisible(menu.items, -1, false, menu.level);
2178
2582
  const dom = getMenuVirtualDom(visible).slice(1);
2179
- await invoke(/* 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);
2583
+ 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);
2180
2584
  };
2181
2585
  const show2$2 = async (uid, menuId, x, y, mouseBlocking = false, ...args) => {
2182
2586
  const items = await getMenuEntriesWithKeyBindings2(uid, menuId, ...args);
@@ -2191,19 +2595,19 @@ const show2$2 = async (uid, menuId, x, y, mouseBlocking = false, ...args) => {
2191
2595
  });
2192
2596
  const visible = getVisible(menu.items, -1, false, menu.level);
2193
2597
  const dom = getMenuVirtualDom(visible).slice(1);
2194
- await invoke(/* 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);
2598
+ 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);
2195
2599
  };
2196
- const hide = async (restoreFocus = true) => {
2600
+ const hide$1 = async (restoreFocus = true) => {
2197
2601
  if (getCount() === 0) {
2198
2602
  return;
2199
2603
  }
2200
2604
  reset();
2201
- await invoke(/* Menu.hide */'Menu.hide', /* restoreFocus */restoreFocus);
2605
+ await invoke$1(/* Menu.hide */'Menu.hide', /* restoreFocus */restoreFocus);
2202
2606
  };
2203
2607
 
2204
2608
  const show$1 = async (x, y, id, ...args) => {
2205
2609
  // @ts-ignore
2206
- await hide();
2610
+ await hide$1();
2207
2611
  // TODO handle error
2208
2612
  // TODO race condition
2209
2613
  await show$2(x, y, id, /* mouseBlocking */true, ...args);
@@ -2212,7 +2616,7 @@ const show$1 = async (x, y, id, ...args) => {
2212
2616
  };
2213
2617
  const show2$1 = async (uid, menuId, x, y, ...args) => {
2214
2618
  // @ts-ignore
2215
- await hide();
2619
+ await hide$1();
2216
2620
  // TODO handle error
2217
2621
  // TODO race condition
2218
2622
  await show2$2(uid, menuId, x, y, /* mouseBlocking */true, ...args);
@@ -2307,6 +2711,109 @@ const diff2 = uid => {
2307
2711
  return diff(oldState, newState);
2308
2712
  };
2309
2713
 
2714
+ const canBeFocused = item => {
2715
+ switch (item.flags) {
2716
+ case Separator$2:
2717
+ case Disabled$1:
2718
+ return false;
2719
+ default:
2720
+ return true;
2721
+ }
2722
+ };
2723
+
2724
+ const focusIndex = async (menu, index) => {
2725
+ if (menu.items.length === 0) {
2726
+ return;
2727
+ }
2728
+ const oldFocusedIndex = menu.focusedIndex;
2729
+ menu.focusedIndex = index;
2730
+ return {
2731
+ commands: [/* Menu.focusIndex */'Menu.focusIndex', /* level */menu.level, /* oldFocusedIndex */oldFocusedIndex, /* newFocusedIndex */index],
2732
+ menus: getAll()
2733
+ };
2734
+ };
2735
+
2736
+ const getCurrentMenu = () => {
2737
+ if (getCount() === 0) {
2738
+ warn('menu not available');
2739
+ }
2740
+ return getAll().at(-1);
2741
+ };
2742
+ const getIndexToFocusNextStartingAt = (items, startIndex) => {
2743
+ for (let i = startIndex; i < startIndex + items.length; i++) {
2744
+ const index = i % items.length;
2745
+ const item = items[index];
2746
+ if (canBeFocused(item)) {
2747
+ return index;
2748
+ }
2749
+ }
2750
+ return -1;
2751
+ };
2752
+ const getIndexToFocusFirst = items => {
2753
+ return getIndexToFocusNextStartingAt(items, 0);
2754
+ };
2755
+ const focusFirst = async () => {
2756
+ const menu = getCurrentMenu();
2757
+ if (getCount() === 0) {
2758
+ return;
2759
+ }
2760
+ const indexToFocus = getIndexToFocusFirst(menu.items);
2761
+ await focusIndex(menu, indexToFocus);
2762
+ };
2763
+
2764
+ const getIndexToFocusPreviousStartingAt$1 = (items, startIndex) => {
2765
+ for (let i = startIndex; i > startIndex - items.length; i--) {
2766
+ const index = (i + items.length) % items.length;
2767
+ const item = items[index];
2768
+ if (canBeFocused(item)) {
2769
+ return index;
2770
+ }
2771
+ }
2772
+ return -1;
2773
+ };
2774
+ const focusLast = async () => {
2775
+ const menu = getCurrentMenu();
2776
+ const indexToFocus = getIndexToFocusPreviousStartingAt$1(menu.items, menu.items.length - 1);
2777
+ await focusIndex(menu, indexToFocus);
2778
+ };
2779
+
2780
+ const getIndexToFocusNext = menu => {
2781
+ const startIndex = menu.focusedIndex + 1;
2782
+ return getIndexToFocusNextStartingAt(menu.items, startIndex);
2783
+ };
2784
+ const focusNext = async () => {
2785
+ const menu = getCurrentMenu();
2786
+ if (menu.items.length === 0) {
2787
+ return;
2788
+ }
2789
+ const indexToFocus = getIndexToFocusNext(menu);
2790
+ await focusIndex(menu, indexToFocus);
2791
+ };
2792
+
2793
+ // TODO this code seems a bit too complicated, maybe it can be simplified
2794
+ const getIndexToFocusPreviousStartingAt = (items, startIndex) => {
2795
+ for (let i = startIndex; i > startIndex - items.length; i--) {
2796
+ const index = (i + items.length) % items.length;
2797
+ const item = items[index];
2798
+ if (canBeFocused(item)) {
2799
+ return index;
2800
+ }
2801
+ }
2802
+ return -1;
2803
+ };
2804
+ const getIndexToFocusPrevious = menu => {
2805
+ const startIndex = menu.focusedIndex === -1 ? menu.items.length - 1 : menu.focusedIndex - 1;
2806
+ return getIndexToFocusPreviousStartingAt(menu.items, startIndex);
2807
+ };
2808
+ const focusPrevious = async () => {
2809
+ const menu = getCurrentMenu();
2810
+ if (menu.items.length === 0) {
2811
+ return;
2812
+ }
2813
+ const indexToFocus = getIndexToFocusPrevious(menu);
2814
+ await focusIndex(menu, indexToFocus);
2815
+ };
2816
+
2310
2817
  const commandsIds = ['closeMenu', 'handleClickAt', 'focus', 'focusFirst', 'focusIndex', 'focusLast', 'focusNext', 'focusPrevious', 'handleClick', 'handleFocus', 'handleFocusOut', 'handleKeyArrowDown', 'handleKeyArrowLeft', 'handleKeyArrowRight', 'handleKeyArrowUp', 'handleKeyEnd', 'handleKeyEnter', 'handleKeyEscape', 'handleKeyHome', 'handleKeySpace', 'handleMenuClick', 'handleMenuMouseOver', 'handleMouseOut', 'handleMouseOver', 'handlePointerOver', 'handlePointerOut', 'toggleIndex', 'toggleMenu'];
2311
2818
 
2312
2819
  const getCommandIds = () => {
@@ -2423,9 +2930,11 @@ const getMenuBounds = (x, y, items) => {
2423
2930
 
2424
2931
  if (x + menuWidth > windowWidth) {
2425
2932
  x -= menuWidth;
2933
+ x = Math.max(x, 0);
2426
2934
  }
2427
2935
  if (y + menuHeight > windowHeight) {
2428
2936
  y -= menuHeight;
2937
+ y = Math.max(y, 0);
2429
2938
  }
2430
2939
  return {
2431
2940
  x,
@@ -2457,6 +2966,95 @@ const handleContextMenu = state => {
2457
2966
  return state;
2458
2967
  };
2459
2968
 
2969
+ const hideSubMenus = async level => {
2970
+ if (level < getCount()) {
2971
+ set$1(getAll().slice(0, level + 1));
2972
+ return {
2973
+ commands: [/* Menu.hideSubMenu */'Menu.hideSubMenu', /* level */level + 1],
2974
+ menus: getAll()
2975
+ };
2976
+ }
2977
+ };
2978
+
2979
+ const showSubMenuAtEnter = async (level, index, enterX, enterY) => {
2980
+ // TODO delete old menus
2981
+ set$1(getAll().slice(0, level + 1));
2982
+ const parentMenu = get$1(level);
2983
+ const item = parentMenu.items[index];
2984
+ const subMenuItems = await getMenuEntries$1(item.id);
2985
+ const subMenu = addMenuInternal({
2986
+ id: item.id,
2987
+ items: subMenuItems,
2988
+ focusedIndex: -1,
2989
+ level: getCount(),
2990
+ y: parentMenu.y + index * 25,
2991
+ x: parentMenu.x + MENU_WIDTH,
2992
+ enterX,
2993
+ enterY
2994
+ });
2995
+ const width = getMenuWidth();
2996
+ const height = getMenuHeight$2(subMenuItems);
2997
+ const visible = getVisible(subMenu.items, -1, false, subMenu.level);
2998
+ const dom = getMenuVirtualDom(visible).slice(1);
2999
+ return {
3000
+ commands: [/* Menu.showMenu */'Menu.showMenu', /* x */subMenu.x, /* y */subMenu.y, /* width */width, /* height */height, /* items */subMenu.items, /* level */subMenu.level, /* parentIndex */index, /* dom */dom],
3001
+ menus: getAll()
3002
+ };
3003
+ };
3004
+ const showSubMenu = async (level, index) => {
3005
+ return showSubMenuAtEnter(level, index, -1, -1);
3006
+ };
3007
+
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
+ const handleMouseEnter = async (level, index, enterX, enterY, enterTimeStamp) => {
3014
+ setTimestamp(enterTimeStamp);
3015
+ if (level >= getCount()) {
3016
+ return;
3017
+ }
3018
+ const menu = get$1(level);
3019
+ if (menu.focusedIndex === index) {
3020
+ return;
3021
+ }
3022
+ if (level < getCount() - 1) {
3023
+ const subMenu = get$1(level + 1);
3024
+ const subMenuEnterX = subMenu.enterX;
3025
+ // TODO should check for triangle position here
3026
+ if (enterX >= subMenuEnterX) {
3027
+ await new Promise(resolveAfterTimeout);
3028
+ if (getLatestTimestamp() !== enterTimeStamp) {
3029
+ return;
3030
+ }
3031
+ }
3032
+ }
3033
+ const item = menu.items[index];
3034
+ await focusIndex(menu, index);
3035
+ switch (item.flags) {
3036
+ case /* SubMenu */4:
3037
+ await showSubMenuAtEnter(menu.level, index, enterX, enterY);
3038
+ break;
3039
+ default:
3040
+ await hideSubMenus(menu.level);
3041
+ break;
3042
+ }
3043
+ };
3044
+
3045
+ const handleMouseLeave = async () => {
3046
+ const menu = get$1(0);
3047
+ if (menu.items.length === 0) {
3048
+ return;
3049
+ }
3050
+ const oldFocusedIndex = menu.focusedIndex;
3051
+ menu.focusedIndex = -1;
3052
+ return {
3053
+ commands: [/* Menu.focusIndex */'Menu.focusIndex', /* level */menu.level, /* oldFocusedIndex */oldFocusedIndex, /* newFocusedIndex */-1],
3054
+ menus: getAll()
3055
+ };
3056
+ };
3057
+
2460
3058
  const loadContent = async (state, titleBarEntries) => {
2461
3059
  return {
2462
3060
  ...state
@@ -2568,6 +3166,75 @@ const saveState = uid => {
2568
3166
  };
2569
3167
  };
2570
3168
 
3169
+ const {
3170
+ invoke} = RendererWorker;
3171
+
3172
+ const executeMenuItemCommand = async item => {
3173
+ await invoke(item.command, ...(item.args || []));
3174
+ };
3175
+
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
+ const selectIndexNone = async (menu, item) => {
3187
+ await Promise.all([hide(/* restoreFocus */false), executeMenuItemCommand(item)]);
3188
+ };
3189
+ const selectIndexRestoreFocus = async (menu, item) => {
3190
+ await Promise.all([hide(/* restoreFocus */true), executeMenuItemCommand(item)]);
3191
+ };
3192
+ const selectIndexSubMenu = async (menu, item, index) => {
3193
+ if (menu.focusedIndex === index) {
3194
+ return;
3195
+ }
3196
+ await showSubMenu(menu.level, menu.focusedIndex);
3197
+ };
3198
+ const selectIndexDefault = async () => {};
3199
+ const selectIndexIgnore = async (menu, item) => {
3200
+ await executeMenuItemCommand(item);
3201
+ };
3202
+ const getSelectIndexFunction = flags => {
3203
+ switch (flags) {
3204
+ case None$1:
3205
+ return selectIndexNone;
3206
+ case SubMenu$1:
3207
+ return selectIndexSubMenu;
3208
+ case RestoreFocus$1:
3209
+ return selectIndexRestoreFocus;
3210
+ case Ignore$1:
3211
+ return selectIndexIgnore;
3212
+ default:
3213
+ return selectIndexDefault;
3214
+ }
3215
+ };
3216
+ const selectIndex = async (level, index) => {
3217
+ const menu = get$1(level);
3218
+ // TODO avoid assignment
3219
+ menu.focusedIndex = index;
3220
+ const item = menu.items[menu.focusedIndex];
3221
+ const fn = getSelectIndexFunction(item.flags);
3222
+ await fn(menu, item, index);
3223
+ };
3224
+
3225
+ const selectItem = async text => {
3226
+ for (let level = 0; level < getCount(); level++) {
3227
+ const menu = get$1(level);
3228
+ for (let i = 0; i < menu.items.length; i++) {
3229
+ const item = menu.items[i];
3230
+ if (item.label === text) {
3231
+ return selectIndex(level, i);
3232
+ }
3233
+ }
3234
+ }
3235
+ throw new Error(`menu item not found: ${text}`);
3236
+ };
3237
+
2571
3238
  const wrapCommand = fn => {
2572
3239
  const wrapped = async (uid, ...args) => {
2573
3240
  const {
@@ -2584,28 +3251,38 @@ const wrapCommand = fn => {
2584
3251
  };
2585
3252
 
2586
3253
  const commandMap = {
2587
- 'Menu.getMenuEntries': getMenuEntries,
2588
- 'Menu.getMenuIds': getMenuIds,
2589
- 'Menu.handleContextMenu': handleContextMenu,
2590
- 'Menu.renderEventListeners': renderEventListeners,
2591
3254
  'Menu.diff2': diff2,
3255
+ 'Menu.focusPrevious': focusPrevious,
3256
+ 'Menu.focusFirst': focusFirst,
3257
+ 'Menu.focusIndex': focusIndex,
3258
+ 'Menu.focusLast': focusLast,
3259
+ 'Menu.focusNext': focusNext,
2592
3260
  'Menu.getCommands': getCommandIds,
3261
+ 'Menu.getHideCommands': getMenuHideCommands,
2593
3262
  'Menu.getKeyBindings': getKeyBindings,
3263
+ 'Menu.getMenuEntries': getMenuEntries,
3264
+ 'Menu.getMenuIds': getMenuIds,
2594
3265
  'Menu.getMenus': getMenus,
3266
+ 'Menu.getShowCommands': getMenuShowCommands,
3267
+ 'Menu.handleContextMenu': handleContextMenu,
3268
+ 'Menu.handleMouseEnter': handleMouseEnter,
3269
+ 'Menu.handleMouseLeave': handleMouseLeave,
3270
+ 'Menu.hideSubMenus': hideSubMenus,
2595
3271
  'Menu.loadContent': wrapCommand(loadContent),
2596
3272
  'Menu.render2': render2,
3273
+ 'Menu.renderEventListeners': renderEventListeners,
2597
3274
  'Menu.saveState': saveState,
3275
+ 'Menu.selectItem': selectItem,
2598
3276
  'Menu.show': show,
2599
3277
  'Menu.show2': show2,
2600
- 'Menu.getShowCommands': getMenuShowCommands,
2601
- 'Menu.getHideCommands': getMenuHideCommands
3278
+ 'Menu.showSubMenu': showSubMenu
2602
3279
  };
2603
3280
 
2604
3281
  const listen = async () => {
2605
3282
  const rpc = await WebWorkerRpcClient.create({
2606
3283
  commandMap: commandMap
2607
3284
  });
2608
- set$1(rpc);
3285
+ set$2(rpc);
2609
3286
  };
2610
3287
 
2611
3288
  const main = async () => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lvce-editor/menu-worker",
3
- "version": "1.6.0",
3
+ "version": "2.0.0",
4
4
  "description": "Menu Worker",
5
5
  "repository": {
6
6
  "type": "git",