@lvce-editor/main-area-worker 8.12.0 → 8.14.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.
@@ -88,7 +88,13 @@ const terminate = () => {
88
88
  };
89
89
 
90
90
  const getGroupIndexById = (state, groupId) => {
91
- return state.layout.groups.findIndex(group => group.id === groupId);
91
+ const {
92
+ layout
93
+ } = state;
94
+ const {
95
+ groups
96
+ } = layout;
97
+ return groups.findIndex(group => group.id === groupId);
92
98
  };
93
99
 
94
100
  const redistributeSizesWithRounding = groups => {
@@ -181,7 +187,13 @@ const closeTab = (state, groupId, tabId) => {
181
187
  };
182
188
 
183
189
  const getFocusedGroup = state => {
184
- return state.layout.groups.find(group => group.focused);
190
+ const {
191
+ layout
192
+ } = state;
193
+ const {
194
+ groups
195
+ } = layout;
196
+ return groups.find(group => group.focused);
185
197
  };
186
198
 
187
199
  const closeActiveEditor = state => {
@@ -273,9 +285,12 @@ const getGroupById = (state, groupId) => {
273
285
  };
274
286
 
275
287
  const closeTabsRight = (state, groupId) => {
288
+ const {
289
+ layout
290
+ } = state;
276
291
  const {
277
292
  groups
278
- } = state.layout;
293
+ } = layout;
279
294
  const group = getGroupById(state, groupId);
280
295
  if (!group) {
281
296
  return state;
@@ -1666,6 +1681,7 @@ const copyPath$1 = async (state, path) => {
1666
1681
 
1667
1682
  const copyRelativePath$1 = async (state, path) => {
1668
1683
  string(path);
1684
+ // TODO use clipboard worker
1669
1685
  const relativePath = await invoke('Workspace.pathBaseName', path);
1670
1686
  await invoke('ClipBoard.writeText', relativePath);
1671
1687
  return state;
@@ -1707,7 +1723,7 @@ const create$2 = (uid, uri, x, y, width, height, platform, assetDir, tabHeight =
1707
1723
  };
1708
1724
 
1709
1725
  const isEqual$1 = (oldState, newState) => {
1710
- return oldState.width === newState.width && oldState.height === newState.height;
1726
+ return false;
1711
1727
  };
1712
1728
 
1713
1729
  const isEqual = (oldState, newState) => {
@@ -2287,10 +2303,13 @@ const closeEditorGroup$1 = (state, groupId) => {
2287
2303
  if (Number.isNaN(groupId)) {
2288
2304
  return state;
2289
2305
  }
2306
+ const {
2307
+ layout
2308
+ } = state;
2290
2309
  const {
2291
2310
  activeGroupId,
2292
2311
  groups
2293
- } = state.layout;
2312
+ } = layout;
2294
2313
  const groupIndex = getGroupIndexById(state, groupId);
2295
2314
  if (groupIndex === -1 || groups.length <= 1) {
2296
2315
  return state;
@@ -2338,6 +2357,11 @@ const handleClickTogglePreview = async state => {
2338
2357
  return state;
2339
2358
  };
2340
2359
 
2360
+ const CloseGroup = 'close-group';
2361
+ const RetryOpen = 'retry-open';
2362
+ const SplitRight = 'split-right';
2363
+ const TogglePreview$1 = 'toggle-preview';
2364
+
2341
2365
  const getBasename$1 = uri => {
2342
2366
  const lastSlashIndex = uri.lastIndexOf('/');
2343
2367
  if (lastSlashIndex === -1) {
@@ -2376,6 +2400,7 @@ const createEmptyGroup = (state, uri, requestId) => {
2376
2400
  icon: '',
2377
2401
  id: tabId,
2378
2402
  isDirty: false,
2403
+ isPreview: false,
2379
2404
  language: '',
2380
2405
  loadingState: 'loading',
2381
2406
  title,
@@ -2400,8 +2425,12 @@ const createEmptyGroup = (state, uri, requestId) => {
2400
2425
  };
2401
2426
 
2402
2427
  const openTab = (state, groupId, tab) => {
2403
- const newTab = 'id' in tab && tab.id !== undefined ? tab : {
2428
+ const normalizedTab = {
2404
2429
  ...tab,
2430
+ isPreview: tab.isPreview ?? false
2431
+ };
2432
+ const newTab = 'id' in normalizedTab && normalizedTab.id !== undefined ? normalizedTab : {
2433
+ ...normalizedTab,
2405
2434
  id: create$1()
2406
2435
  };
2407
2436
  const {
@@ -2459,6 +2488,7 @@ const ensureActiveGroup = (state, uri) => {
2459
2488
  icon: '',
2460
2489
  id: tabId,
2461
2490
  isDirty: false,
2491
+ isPreview: false,
2462
2492
  language: '',
2463
2493
  loadingState: 'loading',
2464
2494
  title,
@@ -2912,28 +2942,35 @@ const splitEditorGroup$1 = (state, groupId, direction) => {
2912
2942
  };
2913
2943
 
2914
2944
  const handleClickAction = async (state, action, rawGroupId) => {
2945
+ const {
2946
+ layout
2947
+ } = state;
2948
+ const {
2949
+ activeGroupId,
2950
+ groups
2951
+ } = layout;
2915
2952
  if (!action) {
2916
2953
  return state;
2917
2954
  }
2918
- if (state.layout.activeGroupId === undefined) {
2955
+ if (activeGroupId === undefined) {
2919
2956
  return state;
2920
2957
  }
2921
- const activeGroup = getActiveGroup(state.layout.groups, state.layout.activeGroupId);
2958
+ const activeGroup = getActiveGroup(groups, activeGroupId);
2922
2959
  if (!activeGroup) {
2923
2960
  return state;
2924
2961
  }
2925
2962
  switch (action) {
2926
- case 'close-group':
2963
+ case CloseGroup:
2927
2964
  if (rawGroupId) {
2928
2965
  const groupId = Number.parseInt(rawGroupId, 10);
2929
2966
  return closeEditorGroup$1(state, groupId);
2930
2967
  }
2931
2968
  return state;
2932
- case 'retry-open':
2969
+ case RetryOpen:
2933
2970
  return retryOpen(state);
2934
- case 'split-right':
2971
+ case SplitRight:
2935
2972
  return splitEditorGroup$1(state, activeGroup.id, Right);
2936
- case 'toggle-preview':
2973
+ case TogglePreview$1:
2937
2974
  return handleClickTogglePreview(state);
2938
2975
  default:
2939
2976
  return state;
@@ -3072,6 +3109,7 @@ const newFile = async state => {
3072
3109
  icon: '',
3073
3110
  id: tabId,
3074
3111
  isDirty: false,
3112
+ isPreview: false,
3075
3113
  language: 'plaintext',
3076
3114
  loadingState: 'loading',
3077
3115
  title: 'Untitled',
@@ -3249,16 +3287,27 @@ const handleSashPointerDown = async (state, sashId, clientX, clientY) => {
3249
3287
  };
3250
3288
  };
3251
3289
 
3252
- const MIN_GROUP_SIZE = 10;
3290
+ const MIN_GROUP_WIDTH_PX = 250;
3253
3291
  const clamp = (value, min, max) => {
3254
3292
  return Math.min(max, Math.max(min, value));
3255
3293
  };
3256
3294
  const round = value => {
3257
3295
  return Math.round(value * 100) / 100;
3258
3296
  };
3297
+ const getMinGroupSizePercent = axisSize => {
3298
+ if (!axisSize) {
3299
+ return 10;
3300
+ }
3301
+ const minPercent = MIN_GROUP_WIDTH_PX / axisSize * 100;
3302
+ // Ensure minimum is at least 10%, matching the CSS 250px constraint on typical widths
3303
+ return Math.max(minPercent, 10);
3304
+ };
3259
3305
  const handleSashPointerMove = async (state, clientX, clientY) => {
3260
3306
  const {
3261
- sashDrag
3307
+ height,
3308
+ layout,
3309
+ sashDrag,
3310
+ width
3262
3311
  } = state;
3263
3312
  if (!sashDrag) {
3264
3313
  return state;
@@ -3266,16 +3315,26 @@ const handleSashPointerMove = async (state, clientX, clientY) => {
3266
3315
  if (!Number.isFinite(clientX) || !Number.isFinite(clientY)) {
3267
3316
  return state;
3268
3317
  }
3269
- const axisSize = state.layout.direction === 'horizontal' ? state.width : state.height;
3318
+ const {
3319
+ direction,
3320
+ groups
3321
+ } = layout;
3322
+ const axisSize = direction === 'horizontal' ? width : height;
3270
3323
  if (!axisSize) {
3271
3324
  return state;
3272
3325
  }
3273
- const deltaPx = state.layout.direction === 'horizontal' ? clientX - sashDrag.startClientX : clientY - sashDrag.startClientY;
3326
+ const deltaPx = direction === 'horizontal' ? clientX - sashDrag.startClientX : clientY - sashDrag.startClientY;
3274
3327
  const deltaPercent = deltaPx / axisSize * 100;
3275
3328
  const totalResizableSize = sashDrag.beforeSize + sashDrag.afterSize;
3276
- const beforeSize = clamp(sashDrag.beforeSize + deltaPercent, MIN_GROUP_SIZE, totalResizableSize - MIN_GROUP_SIZE);
3329
+ let minGroupSize = getMinGroupSizePercent(axisSize);
3330
+
3331
+ // If the minimum size makes it impossible to fit two groups, relax the constraint
3332
+ if (2 * minGroupSize > totalResizableSize) {
3333
+ minGroupSize = totalResizableSize / 2;
3334
+ }
3335
+ const beforeSize = clamp(sashDrag.beforeSize + deltaPercent, minGroupSize, totalResizableSize - minGroupSize);
3277
3336
  const afterSize = totalResizableSize - beforeSize;
3278
- const groups = state.layout.groups.map(group => {
3337
+ const newGroups = groups.map(group => {
3279
3338
  if (group.id === sashDrag.beforeGroupId) {
3280
3339
  return {
3281
3340
  ...group,
@@ -3293,8 +3352,8 @@ const handleSashPointerMove = async (state, clientX, clientY) => {
3293
3352
  return {
3294
3353
  ...state,
3295
3354
  layout: {
3296
- ...state.layout,
3297
- groups
3355
+ ...layout,
3356
+ groups: newGroups
3298
3357
  }
3299
3358
  };
3300
3359
  };
@@ -3408,10 +3467,13 @@ const handleUriChange = async (state, oldUri, newUri) => {
3408
3467
  };
3409
3468
 
3410
3469
  const handleWorkspaceChange = state => {
3470
+ const {
3471
+ layout
3472
+ } = state;
3411
3473
  return {
3412
3474
  ...state,
3413
3475
  layout: {
3414
- ...state.layout,
3476
+ ...layout,
3415
3477
  activeGroupId: undefined,
3416
3478
  groups: []
3417
3479
  }
@@ -3441,7 +3503,7 @@ const initialize = async () => {
3441
3503
  };
3442
3504
 
3443
3505
  const isValidTab = tab => {
3444
- return tab && typeof tab.id === 'number' && typeof tab.title === 'string' && typeof tab.isDirty === 'boolean' && typeof tab.editorUid === 'number' && typeof tab.icon === 'string' && (tab.editorType === 'text' || tab.editorType === 'custom');
3506
+ return tab && typeof tab.id === 'number' && typeof tab.title === 'string' && typeof tab.isDirty === 'boolean' && typeof tab.isPreview === 'boolean' && typeof tab.editorUid === 'number' && typeof tab.icon === 'string' && (tab.editorType === 'text' || tab.editorType === 'custom');
3445
3507
  };
3446
3508
 
3447
3509
  const isValidEditorGroup = group => {
@@ -3478,23 +3540,31 @@ const tryRestoreLayout = savedState => {
3478
3540
  const {
3479
3541
  layout
3480
3542
  } = savedState;
3481
- if (!isValidMainAreaLayout(layout)) {
3543
+ if (!layout || typeof layout !== 'object') {
3544
+ return undefined;
3545
+ }
3546
+ const rawLayout = layout;
3547
+ if (!Array.isArray(rawLayout.groups)) {
3482
3548
  return undefined;
3483
3549
  }
3484
3550
 
3485
3551
  // Normalize all tabs to have editorUid: -1 so SelectTab will create viewlets
3486
3552
  // Mark all restored tabs as not dirty
3487
3553
  const normalizedLayout = {
3488
- ...layout,
3489
- groups: layout.groups.map(group => ({
3554
+ ...rawLayout,
3555
+ groups: rawLayout.groups.map(group => ({
3490
3556
  ...group,
3491
- tabs: group.tabs.map(tab => ({
3557
+ tabs: Array.isArray(group?.tabs) ? group.tabs.map(tab => ({
3492
3558
  ...tab,
3493
3559
  editorUid: -1,
3494
- isDirty: false
3495
- }))
3560
+ isDirty: false,
3561
+ isPreview: typeof tab?.isPreview === 'boolean' ? tab.isPreview : false
3562
+ })) : []
3496
3563
  }))
3497
3564
  };
3565
+ if (!isValidMainAreaLayout(normalizedLayout)) {
3566
+ return undefined;
3567
+ }
3498
3568
  return normalizedLayout;
3499
3569
  };
3500
3570
 
@@ -3514,7 +3584,10 @@ const createViewlets = async (layout, viewletModuleIds, bounds) => {
3514
3584
  const getViewletModuleIds = async layout => {
3515
3585
  const viewletModuleIds = {};
3516
3586
  for (const group of layout.groups) {
3517
- const activeTab = group.tabs.find(tab => tab.id === group.activeTabId);
3587
+ const {
3588
+ tabs
3589
+ } = group;
3590
+ const activeTab = tabs.find(tab => tab.id === group.activeTabId);
3518
3591
  if (activeTab && activeTab.uri) {
3519
3592
  const viewletModuleId = await getViewletModuleId(activeTab.uri);
3520
3593
  if (viewletModuleId) {
@@ -3780,6 +3853,28 @@ const getMenuEntries = async (state, props) => {
3780
3853
  }
3781
3854
  };
3782
3855
 
3856
+ const openUris = async (state, uris) => {
3857
+ if (uris.length === 0) {
3858
+ return state;
3859
+ }
3860
+ if (uris.length === 1) {
3861
+ return openUri(state, uris[0]);
3862
+ }
3863
+ let currentState = await openUri(state, uris[0]);
3864
+ const firstTab = findTabByUri(currentState, uris[0]);
3865
+ for (const uri of uris.slice(1)) {
3866
+ const existingTab = findTabByUri(currentState, uri);
3867
+ if (existingTab) {
3868
+ continue;
3869
+ }
3870
+ currentState = ensureActiveGroup(currentState, uri);
3871
+ }
3872
+ if (!firstTab) {
3873
+ return currentState;
3874
+ }
3875
+ return switchTab(currentState, firstTab.groupId, firstTab.tab.id);
3876
+ };
3877
+
3783
3878
  const refresh = state => {
3784
3879
  return {
3785
3880
  ...state
@@ -3789,26 +3884,9 @@ const refresh = state => {
3789
3884
  const getCss = () => {
3790
3885
  const rules = [`.MainArea {
3791
3886
  }`, `.editor-groups-container {
3792
- position: relative;
3793
- }`, `.Sash {
3794
- position: absolute;
3795
- z-index: 1;
3796
- }`, `.SashVertical {
3797
- top: 0;
3798
- bottom: 0;
3799
- width: 0;
3800
- cursor: col-resize;
3801
- }`, `.SashVertical:hover {
3802
- width: 4px;
3803
- margin-left: -2px;
3804
- }`, `.SashHorizontal {
3805
- left: 0;
3806
- right: 0;
3807
- height: 0;
3808
- cursor: row-resize;
3809
- }`, `.SashHorizontal:hover {
3810
- height: 4px;
3811
- margin-top: -2px;
3887
+ overflow: auto;
3888
+ }`, `.EditorGroup {
3889
+ min-width: 250px;
3812
3890
  }`];
3813
3891
  const css = rules.join('\n');
3814
3892
  return css;
@@ -4149,7 +4227,8 @@ const renderError = errorMessage => {
4149
4227
  }, text(`Error: ${errorMessage}`), {
4150
4228
  childCount: 1,
4151
4229
  className: `${Button} ${ButtonSecondary}`,
4152
- 'data-action': 'retry-open',
4230
+ 'data-action': RetryOpen,
4231
+ name: RetryOpen,
4153
4232
  onClick: HandleClickAction,
4154
4233
  type: Button$2
4155
4234
  }, text('Retry')];
@@ -4293,9 +4372,9 @@ const renderEditorGroupActions = (group, groupIndex, splitButtonEnabled) => {
4293
4372
  ariaLabel: 'Preview',
4294
4373
  childCount: 1,
4295
4374
  className: IconButton,
4296
- 'data-action': 'toggle-preview',
4375
+ 'data-action': TogglePreview$1,
4297
4376
  'data-groupId': String(group.id),
4298
- name: 'toggle-preview',
4377
+ name: TogglePreview$1,
4299
4378
  onClick: HandleClickAction,
4300
4379
  title: togglePreview(),
4301
4380
  type: Button$2
@@ -4309,8 +4388,9 @@ const renderEditorGroupActions = (group, groupIndex, splitButtonEnabled) => {
4309
4388
  buttons.push({
4310
4389
  childCount: 1,
4311
4390
  className: EditorGroupActionButton + ' ' + SplitEditorGroupButton,
4312
- 'data-action': 'split-right',
4391
+ 'data-action': SplitRight,
4313
4392
  'data-groupId': String(group.id),
4393
+ name: SplitRight,
4314
4394
  onClick: HandleClickAction,
4315
4395
  title: splitEditorGroup(),
4316
4396
  type: Button$2
@@ -4343,20 +4423,32 @@ const renderEmptyGroupCloseButton = (group, groupIndex) => {
4343
4423
  childCount: 1,
4344
4424
  className: EmptyGroupCloseButton,
4345
4425
  'data-groupId': String(group.id),
4346
- name: 'close-group',
4426
+ name: CloseGroup,
4347
4427
  onClick: HandleClickAction,
4348
4428
  title: closeEditorGroup(),
4349
4429
  type: Button$2
4350
4430
  }, text('✕')];
4351
4431
  };
4352
4432
 
4353
- const renderEmptyEditorGroup = (group, groupIndex, style) => {
4433
+ const renderWaterMark = () => {
4354
4434
  return [{
4355
4435
  childCount: 1,
4436
+ className: 'WaterMarkWrapper',
4437
+ type: Div
4438
+ }, {
4439
+ childCount: 0,
4440
+ className: 'WaterMark',
4441
+ type: Div
4442
+ }];
4443
+ };
4444
+
4445
+ const renderEmptyEditorGroup = (group, groupIndex, style) => {
4446
+ return [{
4447
+ childCount: 2,
4356
4448
  className: EditorGroup,
4357
4449
  style,
4358
4450
  type: Div
4359
- }, ...renderEmptyGroupCloseButton(group)];
4451
+ }, ...renderEmptyGroupCloseButton(group), ...renderWaterMark()];
4360
4452
  };
4361
4453
 
4362
4454
  const renderEditorGroup = (group, groupIndex, splitButtonEnabled = false, sizeProperty = 'width') => {
@@ -4379,10 +4471,13 @@ const renderEditorGroup = (group, groupIndex, splitButtonEnabled = false, sizePr
4379
4471
  }, ...renderEditor(activeTab)];
4380
4472
  };
4381
4473
 
4474
+ const getSashClassName = direction => {
4475
+ return direction === 'horizontal' ? 'Sash SashVertical' : 'Sash SashHorizontal';
4476
+ };
4382
4477
  const renderSash = (direction, sashId, style) => {
4383
4478
  return [{
4384
4479
  childCount: 0,
4385
- className: direction === 'horizontal' ? 'Sash SashVertical' : 'Sash SashHorizontal',
4480
+ className: getSashClassName(direction),
4386
4481
  'data-sashId': sashId,
4387
4482
  onPointerDown: HandleSashPointerDown,
4388
4483
  style,
@@ -4412,6 +4507,7 @@ const getMainAreaVirtualDom = (layout, splitButtonEnabled = false) => {
4412
4507
  const directionClassName = isSplit ? direction === 'horizontal' ? EditorGroupsVertical : EditorGroupsHorizontal : '';
4413
4508
  const editorGroupsContainerClassName = directionClassName ? `${EDITOR_GROUPS_CONTAINER} ${directionClassName}` : EDITOR_GROUPS_CONTAINER;
4414
4509
  let sashOffset = 0;
4510
+ let childCount = 0;
4415
4511
  for (let i = 0; i < groups.length; i++) {
4416
4512
  sashOffset += groups[i].size;
4417
4513
  if (i > 0) {
@@ -4421,15 +4517,17 @@ const getMainAreaVirtualDom = (layout, splitButtonEnabled = false) => {
4421
4517
  const sashId = create(beforeGroupId, afterGroupId);
4422
4518
  const style = direction === 'horizontal' ? `left:${sashOffset - groups[i].size}%;` : `top:${sashOffset - groups[i].size}%;`;
4423
4519
  children.push(...renderSash(direction, sashId, style));
4520
+ childCount++;
4424
4521
  }
4425
4522
  children.push(...renderEditorGroup(groups[i], i, splitButtonEnabled, sizeProperty));
4523
+ childCount++;
4426
4524
  }
4427
4525
  return [{
4428
4526
  childCount: 1,
4429
4527
  className: Main,
4430
4528
  type: Div
4431
4529
  }, {
4432
- childCount: children.length,
4530
+ childCount,
4433
4531
  className: editorGroupsContainerClassName,
4434
4532
  role: None$1,
4435
4533
  type: Div
@@ -4685,6 +4783,7 @@ const commandMap = {
4685
4783
  'MainArea.loadContent': wrapCommand(loadContent),
4686
4784
  'MainArea.newFile': wrapCommand(newFile),
4687
4785
  'MainArea.openUri': wrapCommand(openUri),
4786
+ 'MainArea.openUris': wrapCommand(openUris),
4688
4787
  'MainArea.refresh': wrapCommand(refresh),
4689
4788
  'MainArea.render2': render2,
4690
4789
  'MainArea.renderEventListeners': renderEventListeners,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lvce-editor/main-area-worker",
3
- "version": "8.12.0",
3
+ "version": "8.14.0",
4
4
  "description": "Main Area Worker",
5
5
  "repository": {
6
6
  "type": "git",