@lvce-editor/title-bar-worker 2.4.0 → 2.5.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.
@@ -61,7 +61,7 @@ class AssertionError extends Error {
61
61
  }
62
62
  }
63
63
  const Object$1 = 1;
64
- const Number = 2;
64
+ const Number$1 = 2;
65
65
  const Array$1 = 3;
66
66
  const String = 4;
67
67
  const Boolean$1 = 5;
@@ -71,7 +71,7 @@ const Unknown$1 = 8;
71
71
  const getType = value => {
72
72
  switch (typeof value) {
73
73
  case 'number':
74
- return Number;
74
+ return Number$1;
75
75
  case 'function':
76
76
  return Function;
77
77
  case 'string':
@@ -98,7 +98,7 @@ const object = value => {
98
98
  };
99
99
  const number = value => {
100
100
  const type = getType(value);
101
- if (type !== Number) {
101
+ if (type !== Number$1) {
102
102
  throw new AssertionError('expected value to be of type number');
103
103
  }
104
104
  };
@@ -108,18 +108,6 @@ const array = value => {
108
108
  throw new AssertionError('expected value to be of type array');
109
109
  }
110
110
  };
111
- const string = value => {
112
- const type = getType(value);
113
- if (type !== String) {
114
- throw new AssertionError('expected value to be of type string');
115
- }
116
- };
117
- const boolean = value => {
118
- const type = getType(value);
119
- if (type !== Boolean$1) {
120
- throw new AssertionError('expected value to be of type boolean');
121
- }
122
- };
123
111
 
124
112
  const isMessagePort = value => {
125
113
  return value && value instanceof MessagePort;
@@ -903,6 +891,109 @@ const WebWorkerRpcClient = {
903
891
  __proto__: null,
904
892
  create: create$3
905
893
  };
894
+ const createMockRpc = ({
895
+ commandMap
896
+ }) => {
897
+ const invocations = [];
898
+ const invoke = (method, ...params) => {
899
+ invocations.push([method, ...params]);
900
+ const command = commandMap[method];
901
+ if (!command) {
902
+ throw new Error(`command ${method} not found`);
903
+ }
904
+ return command(...params);
905
+ };
906
+ const mockRpc = {
907
+ invoke,
908
+ invokeAndTransfer: invoke,
909
+ invocations
910
+ };
911
+ return mockRpc;
912
+ };
913
+
914
+ const toCommandId = key => {
915
+ const dotIndex = key.indexOf('.');
916
+ return key.slice(dotIndex + 1);
917
+ };
918
+ const create$2 = () => {
919
+ const states = Object.create(null);
920
+ const commandMapRef = {};
921
+ return {
922
+ get(uid) {
923
+ return states[uid];
924
+ },
925
+ set(uid, oldState, newState) {
926
+ states[uid] = {
927
+ oldState,
928
+ newState
929
+ };
930
+ },
931
+ dispose(uid) {
932
+ delete states[uid];
933
+ },
934
+ getKeys() {
935
+ return Object.keys(states).map(key => {
936
+ return Number.parseInt(key);
937
+ });
938
+ },
939
+ clear() {
940
+ for (const key of Object.keys(states)) {
941
+ delete states[key];
942
+ }
943
+ },
944
+ wrapCommand(fn) {
945
+ const wrapped = async (uid, ...args) => {
946
+ const {
947
+ newState
948
+ } = states[uid];
949
+ const newerState = await fn(newState, ...args);
950
+ if (newState === newerState) {
951
+ return;
952
+ }
953
+ const latest = states[uid];
954
+ states[uid] = {
955
+ oldState: latest.oldState,
956
+ newState: newerState
957
+ };
958
+ };
959
+ return wrapped;
960
+ },
961
+ wrapGetter(fn) {
962
+ const wrapped = (uid, ...args) => {
963
+ const {
964
+ newState
965
+ } = states[uid];
966
+ return fn(newState, ...args);
967
+ };
968
+ return wrapped;
969
+ },
970
+ diff(uid, modules, numbers) {
971
+ const {
972
+ oldState,
973
+ newState
974
+ } = states[uid];
975
+ const diffResult = [];
976
+ for (let i = 0; i < modules.length; i++) {
977
+ const fn = modules[i];
978
+ if (!fn(oldState, newState)) {
979
+ diffResult.push(numbers[i]);
980
+ }
981
+ }
982
+ return diffResult;
983
+ },
984
+ getCommandIds() {
985
+ const keys = Object.keys(commandMapRef);
986
+ const ids = keys.map(toCommandId);
987
+ return ids;
988
+ },
989
+ registerCommands(commandMap) {
990
+ Object.assign(commandMapRef, commandMap);
991
+ }
992
+ };
993
+ };
994
+ const terminate = () => {
995
+ globalThis.close();
996
+ };
906
997
 
907
998
  const RenderEntries = 1;
908
999
  const RenderFocusedIndex = 2;
@@ -937,24 +1028,10 @@ const diff = (oldState, newState) => {
937
1028
  return diffResult;
938
1029
  };
939
1030
 
940
- const create$2 = () => {
941
- const states = Object.create(null);
942
- return {
943
- get(uid) {
944
- return states[uid];
945
- },
946
- set(uid, oldState, newState) {
947
- states[uid] = {
948
- oldState,
949
- newState
950
- };
951
- }
952
- };
953
- };
954
-
955
1031
  const {
956
1032
  get: get$1,
957
- set: set$3
1033
+ set: set$3,
1034
+ wrapCommand
958
1035
  } = create$2();
959
1036
 
960
1037
  const diff2 = uid => {
@@ -971,7 +1048,12 @@ const getCommandIds = () => {
971
1048
  return commandsIds;
972
1049
  };
973
1050
 
1051
+ const Button = 1;
1052
+ const Div = 4;
1053
+ const Span = 8;
974
1054
  const Text = 12;
1055
+ const I = 16;
1056
+ const Img = 17;
975
1057
 
976
1058
  const Escape$2 = 8;
977
1059
  const Space$2 = 9;
@@ -992,6 +1074,10 @@ const mergeClassNames = (...classNames) => {
992
1074
  return classNames.filter(Boolean).join(' ');
993
1075
  };
994
1076
 
1077
+ const px = value => {
1078
+ return `${value}px`;
1079
+ };
1080
+
995
1081
  const text = data => {
996
1082
  return {
997
1083
  type: Text,
@@ -1459,6 +1545,11 @@ const sendMessagePortToMarkdownWorker = async (port, rpcId) => {
1459
1545
  // @ts-ignore
1460
1546
  await invokeAndTransfer('SendMessagePortToExtensionHostWorker.sendMessagePortToMarkdownWorker', port, command, rpcId);
1461
1547
  };
1548
+ const sendMessagePortToIconThemeWorker = async (port, rpcId) => {
1549
+ const command = 'IconTheme.handleMessagePort';
1550
+ // @ts-ignore
1551
+ await invokeAndTransfer('SendMessagePortToExtensionHostWorker.sendMessagePortToIconThemeWorker', port, command, rpcId);
1552
+ };
1462
1553
  const sendMessagePortToFileSystemWorker = async (port, rpcId) => {
1463
1554
  const command = 'FileSystem.handleMessagePort';
1464
1555
  // @ts-ignore
@@ -1658,6 +1749,13 @@ const getLogsDir = async () => {
1658
1749
  // @ts-ignore
1659
1750
  return invoke$1('PlatformPaths.getLogsDir');
1660
1751
  };
1752
+ const registerMockRpc = commandMap => {
1753
+ const mockRpc = createMockRpc({
1754
+ commandMap
1755
+ });
1756
+ set$1(mockRpc);
1757
+ return mockRpc;
1758
+ };
1661
1759
 
1662
1760
  const RendererWorker = {
1663
1761
  __proto__: null,
@@ -1707,6 +1805,7 @@ const RendererWorker = {
1707
1805
  openUrl,
1708
1806
  openWidget,
1709
1807
  readFile,
1808
+ registerMockRpc,
1710
1809
  registerWebViewInterceptor,
1711
1810
  renderMarkdown,
1712
1811
  rerenderEditor,
@@ -1717,6 +1816,7 @@ const RendererWorker = {
1717
1816
  sendMessagePortToErrorWorker,
1718
1817
  sendMessagePortToExtensionHostWorker,
1719
1818
  sendMessagePortToFileSystemWorker,
1819
+ sendMessagePortToIconThemeWorker,
1720
1820
  sendMessagePortToMarkdownWorker,
1721
1821
  sendMessagePortToRendererProcess,
1722
1822
  sendMessagePortToSearchProcess,
@@ -2099,12 +2199,6 @@ const MenuItemCheckBox = 'menuitemcheckbox';
2099
2199
  const None = 'none';
2100
2200
  const Separator = 'separator';
2101
2201
 
2102
- const Button = 1;
2103
- const Div = 4;
2104
- const I = 16;
2105
- const Img = 17;
2106
- const Span = 8;
2107
-
2108
2202
  const getIconVirtualDom = (icon, type = Div) => {
2109
2203
  return {
2110
2204
  type,
@@ -2140,12 +2234,13 @@ const getTitleBarButtonsVirtualDom = buttons => {
2140
2234
  return dom;
2141
2235
  };
2142
2236
 
2237
+ const parentNode = {
2238
+ type: Div,
2239
+ className: mergeClassNames(Viewlet, TitleBarIcon),
2240
+ childCount: 1
2241
+ };
2143
2242
  const getTitleBarIconVirtualDom = iconSrc => {
2144
- return [{
2145
- type: Div,
2146
- className: mergeClassNames(Viewlet, TitleBarIcon),
2147
- childCount: 1
2148
- }, {
2243
+ return [parentNode, {
2149
2244
  type: Img,
2150
2245
  className: TitleBarIconIcon,
2151
2246
  src: iconSrc,
@@ -2154,16 +2249,16 @@ const getTitleBarIconVirtualDom = iconSrc => {
2154
2249
  }];
2155
2250
  };
2156
2251
 
2157
- const HandleClick = 'handleClick';
2158
- const HandleClickMinimize = 'handleClickMinimize';
2159
- const HandleClickToggleClose = 'handleClickToggleClose';
2160
- const HandleClickToggleMaximize = 'handleClickToggleMaximize';
2161
- const HandleFocusIn = 'handleFocusIn';
2162
- const HandleFocusOut = 'handleFocusOut';
2163
- const HandlePointerOut = 'handlePointerOut';
2164
- const HandlePointerOver = 'handlePointerOver';
2165
- const HandleMenuClick = 'handleMenuClick';
2166
- const HandleMenuMouseOver = 'handleMenuMouseOver';
2252
+ const HandleClick = 1;
2253
+ const HandleClickMinimize = 2;
2254
+ const HandleClickToggleClose = 3;
2255
+ const HandleClickToggleMaximize = 4;
2256
+ const HandleFocusIn = 5;
2257
+ const HandleFocusOut = 6;
2258
+ const HandlePointerOut = 7;
2259
+ const HandlePointerOver = 8;
2260
+ const HandleMenuClick = 9;
2261
+ const HandleMenuMouseOver = 10;
2167
2262
 
2168
2263
  const getItemVirtualDom = item => {
2169
2264
  // @ts-ignore
@@ -2173,6 +2268,7 @@ const getItemVirtualDom = item => {
2173
2268
  isOpen,
2174
2269
  isFocused
2175
2270
  } = item;
2271
+ // TODO avoid mutation
2176
2272
  const dom = [];
2177
2273
  dom.push({
2178
2274
  type: Div,
@@ -2252,7 +2348,8 @@ const handleClickToggleMaximize = async state => {
2252
2348
  return state;
2253
2349
  };
2254
2350
 
2255
- const handleClick$1 = (state, className) => {
2351
+ // TODO use button name property
2352
+ const handleClick$1 = async (state, className) => {
2256
2353
  if (className.includes('Minimize')) {
2257
2354
  return handleClickMinimize(state);
2258
2355
  }
@@ -2487,7 +2584,7 @@ const handlePointerOut = (state, clientX, clientY) => {
2487
2584
  if (index === -1) {
2488
2585
  return state;
2489
2586
  }
2490
- return handleMouseOut(state, index);
2587
+ return handleMouseOut(state);
2491
2588
  };
2492
2589
 
2493
2590
  const handleMouseOverMenuClosed = (state, index) => {
@@ -2511,74 +2608,46 @@ const handlePointerOver = (state, clientX, clientY) => {
2511
2608
  return handleMouseOver(state, index);
2512
2609
  };
2513
2610
 
2514
- const getFontString = (fontWeight, fontSize, fontFamily) => {
2515
- return `${fontWeight} ${fontSize}px ${fontFamily}`;
2516
- };
2517
-
2518
- const createTextMeasureContext = () => {
2611
+ const createTextMeasureContext = (letterSpacing, font) => {
2519
2612
  const canvas = new OffscreenCanvas(0, 0);
2520
2613
  const ctx = canvas.getContext('2d');
2521
2614
  if (!ctx) {
2522
2615
  throw new Error('Failed to get canvas context 2d');
2523
2616
  }
2617
+ ctx.letterSpacing = letterSpacing;
2618
+ ctx.font = font;
2524
2619
  return ctx;
2525
2620
  };
2526
2621
 
2527
- const state = {
2528
- ctx: undefined
2529
- };
2530
- const getOrCreate = createCtx => {
2531
- if (state.ctx) {
2532
- return state.ctx;
2533
- }
2534
- state.ctx = createCtx();
2535
- return state.ctx;
2536
- };
2537
-
2538
- const getContext = () => {
2539
- const ctx = getOrCreate(createTextMeasureContext);
2540
- return ctx;
2541
- };
2542
-
2543
- const px = value => {
2544
- return `${value}px`;
2622
+ const getFontString = (fontWeight, fontSize, fontFamily) => {
2623
+ return `${fontWeight} ${fontSize}px ${fontFamily}`;
2545
2624
  };
2546
2625
 
2547
- const getLetterSpacingString = letterSpacing => {
2548
- return px(letterSpacing);
2549
- };
2550
- const measureTextWidth = (text, fontWeight, fontSize, fontFamily, letterSpacing, isMonoSpaceFont, charWidth) => {
2551
- string(text);
2552
- number(fontWeight);
2553
- number(fontSize);
2554
- string(fontFamily);
2555
- boolean(isMonoSpaceFont);
2556
- number(charWidth);
2626
+ const measureTextWidths = (texts, fontWeight, fontSize, fontFamily, letterSpacing) => {
2557
2627
  if (typeof letterSpacing !== 'number') {
2558
2628
  throw new TypeError('letterSpacing must be of type number');
2559
2629
  }
2560
- const letterSpacingString = getLetterSpacingString(letterSpacing);
2630
+ const letterSpacingString = px(letterSpacing);
2561
2631
  const fontString = getFontString(fontWeight, fontSize, fontFamily);
2562
- const ctx = getContext();
2563
- ctx.letterSpacing = letterSpacingString;
2564
- ctx.font = fontString;
2565
- const metrics = ctx.measureText(text);
2566
- const {
2567
- width
2568
- } = metrics;
2569
- return width;
2570
- };
2571
-
2572
- const measureTitleBarEntryWidth = (label, fontWeight, fontSize, fontFamily, letterSpacing) => {
2573
- const isMonospaceFont = false;
2574
- const charWidth = 0;
2575
- return measureTextWidth(label, fontWeight, fontSize, fontFamily, letterSpacing, isMonospaceFont, charWidth);
2632
+ const ctx = createTextMeasureContext(letterSpacingString, fontString);
2633
+ const widths = [];
2634
+ for (const text of texts) {
2635
+ const metrics = ctx.measureText(text);
2636
+ const {
2637
+ width
2638
+ } = metrics;
2639
+ widths.push(width);
2640
+ }
2641
+ return widths;
2576
2642
  };
2577
2643
 
2578
2644
  const addWidths = (entries, labelPadding, fontWeight, fontSize, fontFamily, letterSpacing) => {
2645
+ const labels = entries.map(entry => entry.label);
2646
+ const widths = measureTextWidths(labels, fontWeight, fontSize, fontFamily, letterSpacing);
2579
2647
  const withWidths = [];
2580
- for (const entry of entries) {
2581
- const textWidth = measureTitleBarEntryWidth(entry.label, fontWeight, fontSize, fontFamily, letterSpacing);
2648
+ for (let i = 0; i < entries.length; i++) {
2649
+ const entry = entries[i];
2650
+ const textWidth = widths[i];
2582
2651
  const width = textWidth + labelPadding * 2;
2583
2652
  withWidths.push({
2584
2653
  ...entry,
@@ -2966,16 +3035,20 @@ const parseKey = rawKey => {
2966
3035
  };
2967
3036
  };
2968
3037
 
3038
+ const classNameFocused = mergeClassNames(MenuItem$1, MenuItemFocused);
3039
+ const getMenuItemClassName = isFocused => {
3040
+ if (isFocused) {
3041
+ return classNameFocused;
3042
+ }
3043
+ return MenuItem$1;
3044
+ };
2969
3045
  const getMenuItemDefaultDom = menuItem => {
2970
3046
  const {
2971
3047
  label,
2972
3048
  isFocused,
2973
3049
  key
2974
3050
  } = menuItem;
2975
- let className = MenuItem$1;
2976
- if (isFocused) {
2977
- className += ' ' + MenuItemFocused;
2978
- }
3051
+ const className = getMenuItemClassName(isFocused);
2979
3052
  const dom = [];
2980
3053
  dom.push({
2981
3054
  type: Div,
@@ -3240,10 +3313,6 @@ const saveState = uid => {
3240
3313
  };
3241
3314
  };
3242
3315
 
3243
- const terminate = () => {
3244
- globalThis.close();
3245
- };
3246
-
3247
3316
  const create = (id, uri, x, y, width, height) => {
3248
3317
  const state = {
3249
3318
  uid: id,
@@ -3260,7 +3329,8 @@ const create = (id, uri, x, y, width, height) => {
3260
3329
  x,
3261
3330
  y,
3262
3331
  width,
3263
- height
3332
+ height,
3333
+ iconWidth: 30
3264
3334
  };
3265
3335
  set$3(id, state, state);
3266
3336
  return state;
@@ -3377,10 +3447,7 @@ const handleFocusOut = async state => {
3377
3447
  return state;
3378
3448
  };
3379
3449
 
3380
- /**
3381
- * @param {boolean} focus
3382
- */
3383
- const openMenu = (state, focus) => {
3450
+ const openMenu = async (state, focus) => {
3384
3451
  const {
3385
3452
  focusedIndex
3386
3453
  } = state;
@@ -3738,7 +3805,7 @@ const handleMenuMouseOver = async (state, level, index) => {
3738
3805
  };
3739
3806
  };
3740
3807
 
3741
- const toggleMenu = state => {
3808
+ const toggleMenu = async state => {
3742
3809
  const {
3743
3810
  isMenuOpen
3744
3811
  } = state;
@@ -3748,21 +3815,6 @@ const toggleMenu = state => {
3748
3815
  return openMenu(state, /* focus */false);
3749
3816
  };
3750
3817
 
3751
- const wrapCommand = fn => {
3752
- const wrapped = async (uid, ...args) => {
3753
- const {
3754
- newState
3755
- } = get$1(uid);
3756
- const newerState = await fn(newState, ...args);
3757
- if (newState === newerState) {
3758
- return;
3759
- }
3760
- const latest = get$1(uid);
3761
- set$3(uid, latest.oldState, newerState);
3762
- };
3763
- return wrapped;
3764
- };
3765
-
3766
3818
  const commandMap = {
3767
3819
  'TitleBar.getButtonsVirtualDom': getTitleBarButtonsVirtualDom,
3768
3820
  'TitleBar.getIconVirtualDom': getTitleBarIconVirtualDom,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lvce-editor/title-bar-worker",
3
- "version": "2.4.0",
3
+ "version": "2.5.0",
4
4
  "description": "Title Bar Worker",
5
5
  "repository": {
6
6
  "type": "git",
@@ -9,5 +9,8 @@
9
9
  "license": "MIT",
10
10
  "author": "Lvce Editor",
11
11
  "type": "module",
12
- "main": "dist/titleBarWorkerMain.js"
12
+ "main": "dist/titleBarWorkerMain.js",
13
+ "dependencies": {
14
+ "@lvce-editor/viewlet-registry": "^1.4.0"
15
+ }
13
16
  }