@lvce-editor/problems-view 1.25.3 → 1.26.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.
@@ -3,29 +3,87 @@ const toCommandId = key => {
3
3
  return key.slice(dotIndex + 1);
4
4
  };
5
5
  const create$a = () => {
6
+ const commandQueues = new Map();
7
+ const generations = Object.create(null);
6
8
  const states = Object.create(null);
7
9
  const commandMapRef = {};
10
+ const getGeneration = uid => generations[uid] || 0;
11
+ const isCurrentGeneration = (uid, generation) => {
12
+ return states[uid] !== undefined && getGeneration(uid) === generation;
13
+ };
14
+ const updateState = (uid, generation, fallbackState, updater) => {
15
+ if (!isCurrentGeneration(uid, generation)) {
16
+ return Promise.resolve(fallbackState);
17
+ }
18
+ const current = states[uid];
19
+ const updatedState = updater(current.newState);
20
+ if (updatedState !== current.newState) {
21
+ states[uid] = {
22
+ newState: updatedState,
23
+ oldState: current.oldState,
24
+ scheduledState: updatedState
25
+ };
26
+ }
27
+ return Promise.resolve(updatedState);
28
+ };
29
+ const createAsyncCommandContext = (uid, generation) => {
30
+ let latestState = states[uid].newState;
31
+ return {
32
+ getState: () => {
33
+ if (isCurrentGeneration(uid, generation)) {
34
+ latestState = states[uid].newState;
35
+ }
36
+ return latestState;
37
+ },
38
+ updateState: async updater => {
39
+ latestState = await updateState(uid, generation, latestState, updater);
40
+ return latestState;
41
+ }
42
+ };
43
+ };
44
+ const enqueueCommand = async (uid, command) => {
45
+ const previous = commandQueues.get(uid) || Promise.resolve();
46
+ const run = async () => {
47
+ try {
48
+ await previous;
49
+ } catch {
50
+ // The previous caller receives its error; later commands must still run.
51
+ }
52
+ await command();
53
+ };
54
+ const current = run();
55
+ commandQueues.set(uid, current);
56
+ try {
57
+ await current;
58
+ } finally {
59
+ if (commandQueues.get(uid) === current) {
60
+ commandQueues.delete(uid);
61
+ }
62
+ }
63
+ };
8
64
  return {
9
65
  clear() {
66
+ commandQueues.clear();
10
67
  for (const key of Object.keys(states)) {
11
68
  delete states[key];
12
69
  }
13
70
  },
14
71
  diff(uid, modules, numbers) {
15
72
  const {
16
- newState,
17
- oldState
73
+ oldState,
74
+ scheduledState
18
75
  } = states[uid];
19
76
  const diffResult = [];
20
77
  for (let i = 0; i < modules.length; i++) {
21
78
  const fn = modules[i];
22
- if (!fn(oldState, newState)) {
79
+ if (!fn(oldState, scheduledState)) {
23
80
  diffResult.push(numbers[i]);
24
81
  }
25
82
  }
26
83
  return diffResult;
27
84
  },
28
85
  dispose(uid) {
86
+ commandQueues.delete(uid);
29
87
  delete states[uid];
30
88
  },
31
89
  get(uid) {
@@ -37,21 +95,33 @@ const create$a = () => {
37
95
  return ids;
38
96
  },
39
97
  getKeys() {
40
- return Object.keys(states).map(key => {
41
- return Number.parseFloat(key);
42
- });
98
+ return Object.keys(states).map(Number);
43
99
  },
44
100
  registerCommands(commandMap) {
45
101
  Object.assign(commandMapRef, commandMap);
46
102
  },
47
- set(uid, oldState, newState) {
103
+ set(uid, oldState, newState, scheduledState) {
104
+ const current = states[uid];
105
+ if (!current || oldState === newState && newState !== current.newState) {
106
+ generations[uid] = getGeneration(uid) + 1;
107
+ }
48
108
  states[uid] = {
49
109
  newState,
50
- oldState
110
+ oldState,
111
+ scheduledState: scheduledState ?? newState
51
112
  };
52
113
  },
114
+ wrapAsyncCommand(fn) {
115
+ const wrapped = async (uid, ...args) => {
116
+ const generation = getGeneration(uid);
117
+ const context = createAsyncCommandContext(uid, generation);
118
+ await fn(context, ...args);
119
+ };
120
+ return wrapped;
121
+ },
53
122
  wrapCommand(fn) {
54
123
  const wrapped = async (uid, ...args) => {
124
+ const generation = getGeneration(uid);
55
125
  const {
56
126
  newState,
57
127
  oldState
@@ -60,6 +130,9 @@ const create$a = () => {
60
130
  if (oldState === newerState || newState === newerState) {
61
131
  return;
62
132
  }
133
+ if (!isCurrentGeneration(uid, generation)) {
134
+ return;
135
+ }
63
136
  const latestOld = states[uid];
64
137
  const latestNew = {
65
138
  ...latestOld.newState,
@@ -67,7 +140,8 @@ const create$a = () => {
67
140
  };
68
141
  states[uid] = {
69
142
  newState: latestNew,
70
- oldState: latestOld.oldState
143
+ oldState: latestOld.oldState,
144
+ scheduledState: latestNew
71
145
  };
72
146
  };
73
147
  return wrapped;
@@ -83,6 +157,7 @@ const create$a = () => {
83
157
  },
84
158
  wrapLoadContent(fn) {
85
159
  const wrapped = async (uid, ...args) => {
160
+ const generation = getGeneration(uid);
86
161
  const {
87
162
  newState,
88
163
  oldState
@@ -97,6 +172,11 @@ const create$a = () => {
97
172
  error
98
173
  };
99
174
  }
175
+ if (!isCurrentGeneration(uid, generation)) {
176
+ return {
177
+ error
178
+ };
179
+ }
100
180
  const latestOld = states[uid];
101
181
  const latestNew = {
102
182
  ...latestOld.newState,
@@ -104,13 +184,59 @@ const create$a = () => {
104
184
  };
105
185
  states[uid] = {
106
186
  newState: latestNew,
107
- oldState: latestOld.oldState
187
+ oldState: latestOld.oldState,
188
+ scheduledState: latestNew
108
189
  };
109
190
  return {
110
191
  error
111
192
  };
112
193
  };
113
194
  return wrapped;
195
+ },
196
+ wrapSerialAsyncCommand(fn) {
197
+ const wrapped = async (uid, ...args) => {
198
+ await enqueueCommand(uid, async () => {
199
+ if (!states[uid]) {
200
+ return;
201
+ }
202
+ const generation = getGeneration(uid);
203
+ const context = createAsyncCommandContext(uid, generation);
204
+ await fn(context, ...args);
205
+ });
206
+ };
207
+ return wrapped;
208
+ },
209
+ wrapSerialCommand(fn) {
210
+ const wrapped = async (uid, ...args) => {
211
+ await enqueueCommand(uid, async () => {
212
+ if (!states[uid]) {
213
+ return;
214
+ }
215
+ const generation = getGeneration(uid);
216
+ const {
217
+ newState,
218
+ oldState
219
+ } = states[uid];
220
+ const newerState = await fn(newState, ...args);
221
+ if (oldState === newerState || newState === newerState) {
222
+ return;
223
+ }
224
+ if (!isCurrentGeneration(uid, generation)) {
225
+ return;
226
+ }
227
+ const latestOld = states[uid];
228
+ const latestNew = {
229
+ ...latestOld.newState,
230
+ ...newerState
231
+ };
232
+ states[uid] = {
233
+ newState: latestNew,
234
+ oldState: latestOld.oldState,
235
+ scheduledState: latestNew
236
+ };
237
+ });
238
+ };
239
+ return wrapped;
114
240
  }
115
241
  };
116
242
  };
@@ -183,7 +309,7 @@ class AssertionError extends Error {
183
309
  const Object$1 = 1;
184
310
  const Number$1 = 2;
185
311
  const Array$1 = 3;
186
- const String = 4;
312
+ const String$1 = 4;
187
313
  const Boolean$1 = 5;
188
314
  const Function = 6;
189
315
  const Null = 7;
@@ -195,7 +321,7 @@ const getType = value => {
195
321
  case 'function':
196
322
  return Function;
197
323
  case 'string':
198
- return String;
324
+ return String$1;
199
325
  case 'object':
200
326
  if (value === null) {
201
327
  return Null;
@@ -224,7 +350,7 @@ const array = value => {
224
350
  };
225
351
  const string = value => {
226
352
  const type = getType(value);
227
- if (type !== String) {
353
+ if (type !== String$1) {
228
354
  throw new AssertionError('expected value to be of type string');
229
355
  }
230
356
  };
@@ -271,7 +397,6 @@ const walkValue = (value, transferrables, isTransferrable) => {
271
397
  for (const property of Object.values(value)) {
272
398
  walkValue(property, transferrables, isTransferrable);
273
399
  }
274
- return;
275
400
  }
276
401
  };
277
402
  const getTransferrables = value => {
@@ -425,7 +550,14 @@ class IpcError extends VError {
425
550
  const cause = new Error(message);
426
551
  // @ts-ignore
427
552
  cause.code = code;
428
- cause.stack = stack;
553
+ if (stack) {
554
+ Object.defineProperty(cause, 'stack', {
555
+ configurable: true,
556
+ enumerable: false,
557
+ value: stack,
558
+ writable: true
559
+ });
560
+ }
429
561
  super(cause, betterMessage);
430
562
  } else {
431
563
  super(betterMessage);
@@ -712,7 +844,10 @@ const constructError = (message, type, name) => {
712
844
  if (ErrorConstructor === Error) {
713
845
  const error = new Error(message);
714
846
  if (name && name !== 'VError') {
715
- error.name = name;
847
+ Object.defineProperty(error, 'name', {
848
+ configurable: true,
849
+ value: name
850
+ });
716
851
  }
717
852
  return error;
718
853
  }
@@ -729,8 +864,10 @@ const getCurrentStack = () => {
729
864
  const currentStack = joinLines(splitLines(new Error().stack || '').slice(stackLinesToSkip));
730
865
  return currentStack;
731
866
  };
732
- const getNewLineIndex = (string, startIndex = undefined) => {
733
- return string.indexOf(NewLine, startIndex);
867
+ const getNewLineIndex = (string, startIndex) => {
868
+ {
869
+ return string.indexOf(NewLine);
870
+ }
734
871
  };
735
872
  const getParentStack = error => {
736
873
  let parentStack = error.stack || error.data || error.message || '';
@@ -741,55 +878,91 @@ const getParentStack = error => {
741
878
  };
742
879
  const MethodNotFound = -32601;
743
880
  const Custom = -32001;
881
+ const setStack = (error, stack) => {
882
+ const descriptor = Object.getOwnPropertyDescriptor(error, 'stack');
883
+ if (descriptor) {
884
+ if (!descriptor.configurable && !descriptor.writable) {
885
+ return;
886
+ }
887
+ if (!descriptor.configurable && descriptor.writable) {
888
+ error.stack = stack;
889
+ return;
890
+ }
891
+ }
892
+ Object.defineProperty(error, 'stack', {
893
+ configurable: true,
894
+ value: stack,
895
+ writable: true
896
+ });
897
+ };
898
+ const restoreExistingError = (error, currentStack) => {
899
+ if (typeof error.stack === 'string') {
900
+ setStack(error, `${error.stack}${NewLine}${currentStack}`);
901
+ }
902
+ return error;
903
+ };
904
+ const restoreMethodNotFoundError = (error, currentStack) => {
905
+ const restoredError = new JsonRpcError(error.message);
906
+ const parentStack = getParentStack(error);
907
+ setStack(restoredError, `${parentStack}${NewLine}${currentStack}`);
908
+ return restoredError;
909
+ };
910
+ const restoreStackFromData = (restoredError, error, currentStack) => {
911
+ if (error.data.stack && error.data.type && error.message) {
912
+ setStack(restoredError, `${error.data.type}: ${error.message}${NewLine}${error.data.stack}${NewLine}${currentStack}`);
913
+ return;
914
+ }
915
+ if (error.data.stack) {
916
+ setStack(restoredError, error.data.stack);
917
+ }
918
+ };
919
+ const applyDataProperties = (restoredError, error) => {
920
+ restoreStackFromData(restoredError, error, getCurrentStack());
921
+ if (error.data.codeFrame) {
922
+ // @ts-ignore
923
+ restoredError.codeFrame = error.data.codeFrame;
924
+ }
925
+ if (error.data.code) {
926
+ // @ts-ignore
927
+ restoredError.code = error.data.code;
928
+ }
929
+ if (error.data.type) {
930
+ // @ts-ignore
931
+ restoredError.name = error.data.type;
932
+ }
933
+ };
934
+ const applyDirectProperties = (restoredError, error) => {
935
+ if (error.stack) {
936
+ const lowerStack = restoredError.stack || '';
937
+ const indexNewLine = getNewLineIndex(lowerStack);
938
+ const parentStack = getParentStack(error);
939
+ // @ts-ignore
940
+ setStack(restoredError, `${parentStack}${lowerStack.slice(indexNewLine)}`);
941
+ }
942
+ if (error.codeFrame) {
943
+ // @ts-ignore
944
+ restoredError.codeFrame = error.codeFrame;
945
+ }
946
+ };
947
+ const restoreMessageError = (error, _currentStack) => {
948
+ const restoredError = constructError(error.message, error.type, error.name);
949
+ if (error.data) {
950
+ applyDataProperties(restoredError, error);
951
+ } else {
952
+ applyDirectProperties(restoredError, error);
953
+ }
954
+ return restoredError;
955
+ };
744
956
  const restoreJsonRpcError = error => {
745
957
  const currentStack = getCurrentStack();
746
958
  if (error && error instanceof Error) {
747
- if (typeof error.stack === 'string') {
748
- error.stack = error.stack + NewLine + currentStack;
749
- }
750
- return error;
959
+ return restoreExistingError(error, currentStack);
751
960
  }
752
961
  if (error && error.code && error.code === MethodNotFound) {
753
- const restoredError = new JsonRpcError(error.message);
754
- const parentStack = getParentStack(error);
755
- restoredError.stack = parentStack + NewLine + currentStack;
756
- return restoredError;
962
+ return restoreMethodNotFoundError(error, currentStack);
757
963
  }
758
964
  if (error && error.message) {
759
- const restoredError = constructError(error.message, error.type, error.name);
760
- if (error.data) {
761
- if (error.data.stack && error.data.type && error.message) {
762
- restoredError.stack = error.data.type + ': ' + error.message + NewLine + error.data.stack + NewLine + currentStack;
763
- } else if (error.data.stack) {
764
- restoredError.stack = error.data.stack;
765
- }
766
- if (error.data.codeFrame) {
767
- // @ts-ignore
768
- restoredError.codeFrame = error.data.codeFrame;
769
- }
770
- if (error.data.code) {
771
- // @ts-ignore
772
- restoredError.code = error.data.code;
773
- }
774
- if (error.data.type) {
775
- // @ts-ignore
776
- restoredError.name = error.data.type;
777
- }
778
- } else {
779
- if (error.stack) {
780
- const lowerStack = restoredError.stack || '';
781
- // @ts-ignore
782
- const indexNewLine = getNewLineIndex(lowerStack);
783
- const parentStack = getParentStack(error);
784
- // @ts-ignore
785
- restoredError.stack = parentStack + lowerStack.slice(indexNewLine);
786
- }
787
- if (error.codeFrame) {
788
- // @ts-ignore
789
- restoredError.codeFrame = error.codeFrame;
790
- }
791
- }
792
- return restoredError;
965
+ return restoreMessageError(error);
793
966
  }
794
967
  if (typeof error === 'string') {
795
968
  return new Error(`JsonRpc Error: ${error}`);
@@ -1254,13 +1427,178 @@ const ToolBar = 'toolbar';
1254
1427
  const Tree = 'tree';
1255
1428
  const TreeItem = 'treeitem';
1256
1429
 
1430
+ const Audio = 0;
1257
1431
  const Button$1 = 1;
1432
+ const Col = 2;
1433
+ const ColGroup = 3;
1258
1434
  const Div = 4;
1435
+ const H1 = 5;
1259
1436
  const Input = 6;
1437
+ const Kbd = 7;
1260
1438
  const Span = 8;
1439
+ const Table$1 = 9;
1440
+ const TBody = 10;
1441
+ const Td = 11;
1261
1442
  const Text = 12;
1443
+ const Th = 13;
1444
+ const THead = 14;
1445
+ const Tr = 15;
1446
+ const I = 16;
1262
1447
  const Img = 17;
1448
+ const Root = 0;
1449
+ const Ins = 20;
1450
+ const Del = 21;
1451
+ const H2 = 22;
1452
+ const H3 = 23;
1453
+ const H4 = 24;
1454
+ const H5 = 25;
1455
+ const H6 = 26;
1456
+ const Article = 27;
1457
+ const Aside = 28;
1458
+ const Footer = 29;
1459
+ const Header = 30;
1460
+ const Nav = 40;
1461
+ const Section = 41;
1462
+ const Search = 42;
1463
+ const Dd = 43;
1464
+ const Dl = 44;
1465
+ const Figcaption = 45;
1466
+ const Figure = 46;
1467
+ const Hr = 47;
1468
+ const Li = 48;
1469
+ const Ol = 49;
1470
+ const P = 50;
1471
+ const Pre = 51;
1263
1472
  const A = 53;
1473
+ const Abbr = 54;
1474
+ const Br = 55;
1475
+ const Cite = 56;
1476
+ const Data = 57;
1477
+ const Time = 58;
1478
+ const Tfoot = 59;
1479
+ const Ul = 60;
1480
+ const Video = 61;
1481
+ const TextArea = 62;
1482
+ const Select = 63;
1483
+ const Option = 64;
1484
+ const Code$1 = 65;
1485
+ const Label$1 = 66;
1486
+ const Dt = 67;
1487
+ const Iframe = 68;
1488
+ const Main = 69;
1489
+ const Strong = 70;
1490
+ const Em = 71;
1491
+ const Style = 72;
1492
+ const Html = 73;
1493
+ const Head = 74;
1494
+ const Title = 75;
1495
+ const Meta = 76;
1496
+ const Canvas = 77;
1497
+ const Form = 78;
1498
+ const BlockQuote = 79;
1499
+ const Quote = 80;
1500
+ const Circle = 81;
1501
+ const Defs = 82;
1502
+ const Ellipse = 83;
1503
+ const G = 84;
1504
+ const Line = 85;
1505
+ const Path = 86;
1506
+ const Polygon = 87;
1507
+ const Polyline = 88;
1508
+ const Rect = 89;
1509
+ const Svg = 90;
1510
+ const Use = 91;
1511
+ const Reference = 100;
1512
+
1513
+ const VirtualDomElements = {
1514
+ __proto__: null,
1515
+ A,
1516
+ Abbr,
1517
+ Article,
1518
+ Aside,
1519
+ Audio,
1520
+ BlockQuote,
1521
+ Br,
1522
+ Button: Button$1,
1523
+ Canvas,
1524
+ Circle,
1525
+ Cite,
1526
+ Code: Code$1,
1527
+ Col,
1528
+ ColGroup,
1529
+ Data,
1530
+ Dd,
1531
+ Defs,
1532
+ Del,
1533
+ Div,
1534
+ Dl,
1535
+ Dt,
1536
+ Ellipse,
1537
+ Em,
1538
+ Figcaption,
1539
+ Figure,
1540
+ Footer,
1541
+ Form,
1542
+ G,
1543
+ H1,
1544
+ H2,
1545
+ H3,
1546
+ H4,
1547
+ H5,
1548
+ H6,
1549
+ Head,
1550
+ Header,
1551
+ Hr,
1552
+ Html,
1553
+ I,
1554
+ Iframe,
1555
+ Img,
1556
+ Input,
1557
+ Ins,
1558
+ Kbd,
1559
+ Label: Label$1,
1560
+ Li,
1561
+ Line,
1562
+ Main,
1563
+ Meta,
1564
+ Nav,
1565
+ Ol,
1566
+ Option,
1567
+ P,
1568
+ Path,
1569
+ Polygon,
1570
+ Polyline,
1571
+ Pre,
1572
+ Quote,
1573
+ Rect,
1574
+ Reference,
1575
+ Root,
1576
+ Search,
1577
+ Section,
1578
+ Select,
1579
+ Span,
1580
+ Strong,
1581
+ Style,
1582
+ Svg,
1583
+ TBody,
1584
+ THead,
1585
+ Table: Table$1,
1586
+ Td,
1587
+ Text,
1588
+ TextArea,
1589
+ Tfoot,
1590
+ Th,
1591
+ Time,
1592
+ Title,
1593
+ Tr,
1594
+ Ul,
1595
+ Use,
1596
+ Video
1597
+ };
1598
+
1599
+ const ClientY = 'event.clientY';
1600
+ const DeltaMode = 'event.deltaMode';
1601
+ const DeltaY = 'event.deltaY';
1264
1602
 
1265
1603
  const Space = 9;
1266
1604
  const PageUp = 10;
@@ -1378,17 +1716,23 @@ const create = (id, uri, x, y, width, height, workspaceUri) => {
1378
1716
  const state = {
1379
1717
  activeUri: '',
1380
1718
  collapsedUris: [],
1719
+ deltaY: 0,
1381
1720
  filteredProblems: [],
1382
1721
  filterValue: '',
1722
+ finalDeltaY: 0,
1383
1723
  focusedIndex: -2,
1724
+ handleOffset: 0,
1384
1725
  height,
1385
1726
  inputSource: User,
1386
1727
  itemHeight: 22,
1387
1728
  listItems: [],
1388
1729
  maxLineY: 0,
1389
1730
  message: '',
1731
+ minimumSliderSize: 20,
1390
1732
  minLineY: 0,
1391
1733
  problems: [],
1734
+ scrollBarActive: false,
1735
+ scrollBarHeight: 0,
1392
1736
  showErrors: true,
1393
1737
  showInfos: true,
1394
1738
  showWarnings: true,
@@ -1404,15 +1748,26 @@ const create = (id, uri, x, y, width, height, workspaceUri) => {
1404
1748
  };
1405
1749
 
1406
1750
  const isEqual$2 = (oldState, newState) => {
1407
- return oldState.collapsedUris === newState.collapsedUris && oldState.filterValue === newState.filterValue && oldState.problems === newState.problems;
1751
+ return oldState.collapsedUris === newState.collapsedUris && oldState.deltaY === newState.deltaY && oldState.filterValue === newState.filterValue && oldState.finalDeltaY === newState.finalDeltaY && oldState.height === newState.height && oldState.itemHeight === newState.itemHeight && oldState.maxLineY === newState.maxLineY && oldState.minLineY === newState.minLineY && oldState.problems === newState.problems && oldState.scrollBarHeight === newState.scrollBarHeight && oldState.viewMode === newState.viewMode && oldState.width === newState.width;
1408
1752
  };
1409
1753
 
1410
1754
  const isEqual$1 = (oldState, newState) => {
1411
1755
  return newState.inputSource === User || oldState.filterValue === newState.filterValue;
1412
1756
  };
1413
1757
 
1758
+ const haveSameCollapsedUris = (oldState, newState) => {
1759
+ const oldCollapsedUris = oldState.collapsedUris;
1760
+ const newCollapsedUris = newState.collapsedUris;
1761
+ if (oldCollapsedUris === newCollapsedUris) {
1762
+ return true;
1763
+ }
1764
+ if (!oldCollapsedUris || !newCollapsedUris) {
1765
+ return false;
1766
+ }
1767
+ return oldCollapsedUris.length === newCollapsedUris.length && oldCollapsedUris.every((uri, index) => uri === newCollapsedUris[index]);
1768
+ };
1414
1769
  const isEqual = (oldState, newState) => {
1415
- return oldState.activeUri === newState.activeUri && oldState.problems === newState.problems && oldState.filterValue === newState.filterValue && oldState.message === newState.message && oldState.viewMode === newState.viewMode;
1770
+ return oldState.activeUri === newState.activeUri && haveSameCollapsedUris(oldState, newState) && oldState.focusedIndex === newState.focusedIndex && oldState.height === newState.height && oldState.maxLineY === newState.maxLineY && oldState.minLineY === newState.minLineY && oldState.problems === newState.problems && oldState.filterValue === newState.filterValue && oldState.message === newState.message && oldState.scrollBarActive === newState.scrollBarActive && oldState.scrollBarHeight === newState.scrollBarHeight && oldState.width === newState.width && oldState.viewMode === newState.viewMode;
1416
1771
  };
1417
1772
 
1418
1773
  const RenderItems = 1;
@@ -1433,12 +1788,132 @@ const diff = (oldState, newState) => {
1433
1788
  return diffResult;
1434
1789
  };
1435
1790
 
1791
+ const FilterHeight = 24;
1792
+ const TableHeaderHeight = 22;
1793
+ const getListTopOffset = (width, smallWidthBreakPoint, viewMode) => {
1794
+ const filterHeight = viewMode !== None && width <= smallWidthBreakPoint ? FilterHeight : 0;
1795
+ const tableHeaderHeight = viewMode === Table ? TableHeaderHeight : 0;
1796
+ return filterHeight + tableHeaderHeight;
1797
+ };
1798
+ const getListHeight = (height, width, smallWidthBreakPoint, viewMode) => {
1799
+ return Math.max(height - getListTopOffset(width, smallWidthBreakPoint, viewMode), 0);
1800
+ };
1801
+
1802
+ const getNumberOfVisibleItems = (listHeight, itemHeight) => {
1803
+ if (listHeight <= 0 || itemHeight <= 0) {
1804
+ return 0;
1805
+ }
1806
+ return Math.ceil(listHeight / itemHeight) + 1;
1807
+ };
1808
+
1809
+ const getScrollBarSize = (size, contentSize, minimumSliderSize) => {
1810
+ if (size <= 0 || size >= contentSize) {
1811
+ return 0;
1812
+ }
1813
+ return Math.min(Math.max(Math.round(size ** 2 / contentSize), minimumSliderSize), size);
1814
+ };
1815
+
1816
+ const matchesFilterValue = (string, filterValueLower) => {
1817
+ if (filterValueLower) {
1818
+ return string.toLowerCase().indexOf(filterValueLower);
1819
+ }
1820
+ return 0;
1821
+ };
1822
+
1823
+ const Item = 0;
1824
+ const Expanded = 1;
1825
+ const Collapsed = 2;
1826
+
1827
+ const getListItemType = (listItemType, isCollapsed) => {
1828
+ if (listItemType === Item) {
1829
+ return Item;
1830
+ }
1831
+ if (isCollapsed) {
1832
+ return Collapsed;
1833
+ }
1834
+ return Expanded;
1835
+ };
1836
+ const filterProblems = (problems, collapsedUris, filterValue) => {
1837
+ const filterValueLower = filterValue.toLowerCase();
1838
+ const filtered = [];
1839
+ for (const problem of problems) {
1840
+ const uriMatchIndex = matchesFilterValue(problem.uri, filterValueLower);
1841
+ const sourceMatchIndex = matchesFilterValue(problem.source, filterValueLower);
1842
+ const messageMatchIndex = matchesFilterValue(problem.message, filterValueLower);
1843
+ if (uriMatchIndex === -1 && sourceMatchIndex === -1 && messageMatchIndex === -1) {
1844
+ continue;
1845
+ }
1846
+ const isCollapsed = collapsedUris.includes(problem.uri);
1847
+ if (isCollapsed && problem.listItemType === Item) {
1848
+ continue;
1849
+ }
1850
+ filtered.push({
1851
+ ...problem,
1852
+ isCollapsed,
1853
+ listItemType: getListItemType(problem.listItemType, isCollapsed),
1854
+ messageMatchIndex,
1855
+ sourceMatchIndex,
1856
+ uriMatchIndex
1857
+ });
1858
+ }
1859
+ return filtered;
1860
+ };
1861
+
1862
+ const getVisibleProblemCount = (problems, collapsedUris, filterValue, viewMode) => {
1863
+ const filtered = filterProblems(problems, collapsedUris, filterValue);
1864
+ if (viewMode !== Table) {
1865
+ return filtered.length;
1866
+ }
1867
+ let count = 0;
1868
+ for (const problem of filtered) {
1869
+ if (problem.message) {
1870
+ count++;
1871
+ }
1872
+ }
1873
+ return count;
1874
+ };
1875
+
1876
+ const updateVirtualList = (state, newDeltaY) => {
1877
+ const {
1878
+ collapsedUris,
1879
+ deltaY: currentDeltaY,
1880
+ filterValue,
1881
+ height,
1882
+ itemHeight,
1883
+ minimumSliderSize,
1884
+ problems,
1885
+ smallWidthBreakPoint,
1886
+ viewMode,
1887
+ width
1888
+ } = state;
1889
+ const itemCount = getVisibleProblemCount(problems, collapsedUris, filterValue, viewMode);
1890
+ const listHeight = getListHeight(height, width, smallWidthBreakPoint, viewMode);
1891
+ const contentHeight = itemCount * itemHeight;
1892
+ const finalDeltaY = Math.max(contentHeight - listHeight, 0);
1893
+ const requestedDeltaY = newDeltaY ?? currentDeltaY;
1894
+ const deltaY = Math.min(Math.max(Number.isFinite(requestedDeltaY) ? requestedDeltaY : 0, 0), finalDeltaY);
1895
+ const minLineY = itemHeight > 0 ? Math.floor(deltaY / itemHeight) : 0;
1896
+ const visibleCount = getNumberOfVisibleItems(listHeight, itemHeight);
1897
+ const maxLineY = Math.min(minLineY + visibleCount, itemCount);
1898
+ const scrollBarHeight = getScrollBarSize(listHeight, contentHeight, minimumSliderSize);
1899
+ return {
1900
+ ...state,
1901
+ deltaY,
1902
+ finalDeltaY,
1903
+ maxLineY,
1904
+ minLineY,
1905
+ scrollBarHeight
1906
+ };
1907
+ };
1908
+
1436
1909
  const diff2 = uid => {
1437
1910
  const {
1438
1911
  newState,
1439
1912
  oldState
1440
1913
  } = get(uid);
1441
- const diffResult = diff(oldState, newState);
1914
+ const updatedState = updateVirtualList(newState);
1915
+ set(uid, oldState, updatedState);
1916
+ const diffResult = diff(oldState, updatedState);
1442
1917
  return diffResult;
1443
1918
  };
1444
1919
 
@@ -1461,6 +1936,8 @@ const text = data => {
1461
1936
  };
1462
1937
  };
1463
1938
 
1939
+ new Set(Object.values(VirtualDomElements));
1940
+
1464
1941
  const FocusProblems = 19;
1465
1942
 
1466
1943
  const getKeyBindings = () => {
@@ -1512,15 +1989,15 @@ const getKeyBindings = () => {
1512
1989
  };
1513
1990
 
1514
1991
  const emptyObject = {};
1515
- const RE_PLACEHOLDER = /\{(PH\d+)\}/g;
1516
1992
  const i18nString = (key, placeholders = emptyObject) => {
1517
1993
  if (placeholders === emptyObject) {
1518
1994
  return key;
1519
1995
  }
1520
- const replacer = (match, rest) => {
1521
- return placeholders[rest];
1522
- };
1523
- return key.replaceAll(RE_PLACEHOLDER, replacer);
1996
+ let result = key;
1997
+ for (const [placeholder, replacement] of Object.entries(placeholders)) {
1998
+ result = result.split(`{${placeholder}}`).join(String(replacement));
1999
+ }
2000
+ return result;
1524
2001
  };
1525
2002
 
1526
2003
  const ClearFilters = 'Clear Filters';
@@ -1646,10 +2123,6 @@ const {
1646
2123
  getProblems: getProblems$1,
1647
2124
  getUri} = EditorWorker;
1648
2125
 
1649
- const Item = 0;
1650
- const Expanded = 1;
1651
- const Collapsed = 2;
1652
-
1653
2126
  const toProblem = (diagnostic, index) => {
1654
2127
  const {
1655
2128
  code,
@@ -1881,19 +2354,27 @@ const getListIndex = (eventX, eventY, x, y, deltaY, itemHeight) => {
1881
2354
 
1882
2355
  const handleClickAt = (state, eventX, eventY) => {
1883
2356
  const {
2357
+ collapsedUris,
2358
+ deltaY,
2359
+ filterValue,
1884
2360
  itemHeight,
1885
2361
  problems,
2362
+ smallWidthBreakPoint,
2363
+ viewMode,
2364
+ width,
1886
2365
  x,
1887
2366
  y
1888
2367
  } = state;
1889
2368
 
1890
2369
  // TODO use functional focus rendering
1891
2370
  // Focus.setFocus(FocusKey.Problems)
1892
- if (problems.length === 0) {
2371
+ const problemCount = getVisibleProblemCount(problems, collapsedUris, filterValue, viewMode);
2372
+ if (problemCount === 0) {
1893
2373
  return focusIndex(state, -1);
1894
2374
  }
1895
- const index = getListIndex(eventX, eventY, x, y, 0, itemHeight);
1896
- if (index > problems.length) {
2375
+ const listTopOffset = getListTopOffset(width, smallWidthBreakPoint, viewMode);
2376
+ const index = getListIndex(eventX, eventY, x, y + listTopOffset, deltaY, itemHeight);
2377
+ if (index < 0 || index >= problemCount) {
1897
2378
  return focusIndex(state, -1);
1898
2379
  }
1899
2380
  return {
@@ -1948,6 +2429,109 @@ const handleIconThemeChange = state => {
1948
2429
  };
1949
2430
  };
1950
2431
 
2432
+ const handleScrollBarCaptureLost = state => {
2433
+ return {
2434
+ ...state,
2435
+ scrollBarActive: false
2436
+ };
2437
+ };
2438
+
2439
+ const getNewDeltaYPercent = (height, scrollBarHeight, relativeY) => {
2440
+ const halfScrollBarHeight = scrollBarHeight / 2;
2441
+ if (relativeY <= halfScrollBarHeight) {
2442
+ return {
2443
+ handleOffset: Math.max(relativeY, 0),
2444
+ percent: 0
2445
+ };
2446
+ }
2447
+ if (relativeY <= height - halfScrollBarHeight) {
2448
+ return {
2449
+ handleOffset: halfScrollBarHeight,
2450
+ percent: (relativeY - halfScrollBarHeight) / (height - scrollBarHeight)
2451
+ };
2452
+ }
2453
+ return {
2454
+ handleOffset: Math.min(scrollBarHeight - height + relativeY, scrollBarHeight),
2455
+ percent: 1
2456
+ };
2457
+ };
2458
+
2459
+ const getScrollBarTop = (height, finalDeltaY, deltaY, scrollBarHeight) => {
2460
+ if (finalDeltaY <= 0 || !Number.isFinite(finalDeltaY)) {
2461
+ return 0;
2462
+ }
2463
+ const scrollBarTop = Math.round(deltaY / finalDeltaY * (height - scrollBarHeight));
2464
+ return Number.isFinite(scrollBarTop) ? scrollBarTop : 0;
2465
+ };
2466
+
2467
+ const setDeltaY = (state, deltaY) => {
2468
+ return updateVirtualList(state, deltaY);
2469
+ };
2470
+
2471
+ const handleScrollBarClick = (state, eventY) => {
2472
+ const {
2473
+ deltaY,
2474
+ finalDeltaY,
2475
+ height,
2476
+ scrollBarHeight,
2477
+ smallWidthBreakPoint,
2478
+ viewMode,
2479
+ width,
2480
+ y
2481
+ } = state;
2482
+ const listTopOffset = getListTopOffset(width, smallWidthBreakPoint, viewMode);
2483
+ const listHeight = getListHeight(height, width, smallWidthBreakPoint, viewMode);
2484
+ const relativeY = eventY - y - listTopOffset;
2485
+ const scrollBarTop = getScrollBarTop(listHeight, finalDeltaY, deltaY, scrollBarHeight);
2486
+ const offsetInThumb = relativeY - scrollBarTop;
2487
+ if (offsetInThumb >= 0 && offsetInThumb < scrollBarHeight) {
2488
+ return {
2489
+ ...state,
2490
+ handleOffset: offsetInThumb,
2491
+ scrollBarActive: true
2492
+ };
2493
+ }
2494
+ const {
2495
+ handleOffset,
2496
+ percent
2497
+ } = getNewDeltaYPercent(listHeight, scrollBarHeight, relativeY);
2498
+ return {
2499
+ ...setDeltaY(state, percent * finalDeltaY),
2500
+ handleOffset,
2501
+ scrollBarActive: true
2502
+ };
2503
+ };
2504
+
2505
+ const handleScrollBarMove = (state, eventY) => {
2506
+ const {
2507
+ finalDeltaY,
2508
+ handleOffset,
2509
+ height,
2510
+ scrollBarActive,
2511
+ scrollBarHeight,
2512
+ smallWidthBreakPoint,
2513
+ viewMode,
2514
+ width,
2515
+ y
2516
+ } = state;
2517
+ if (!scrollBarActive) {
2518
+ return state;
2519
+ }
2520
+ const listTopOffset = getListTopOffset(width, smallWidthBreakPoint, viewMode);
2521
+ const listHeight = getListHeight(height, width, smallWidthBreakPoint, viewMode);
2522
+ const availableTrackHeight = listHeight - scrollBarHeight;
2523
+ const relativeY = eventY - y - listTopOffset - handleOffset;
2524
+ const percent = availableTrackHeight <= 0 ? 0 : relativeY / availableTrackHeight;
2525
+ return setDeltaY(state, percent * finalDeltaY);
2526
+ };
2527
+
2528
+ const handleWheel = (state, deltaMode, deltaY) => {
2529
+ const {
2530
+ deltaY: currentDeltaY
2531
+ } = state;
2532
+ return setDeltaY(state, currentDeltaY + deltaY);
2533
+ };
2534
+
1951
2535
  const initialize = async () => {
1952
2536
  // function is not needed anymore
1953
2537
  };
@@ -2045,48 +2629,6 @@ const getUniqueIndents = problems => {
2045
2629
  return uniqueIndents;
2046
2630
  };
2047
2631
 
2048
- const matchesFilterValue = (string, filterValueLower) => {
2049
- if (filterValueLower) {
2050
- return string.toLowerCase().indexOf(filterValueLower);
2051
- }
2052
- return 0;
2053
- };
2054
-
2055
- const getListItemType = (listItemType, isCollapsed) => {
2056
- if (listItemType === Item) {
2057
- return Item;
2058
- }
2059
- if (isCollapsed) {
2060
- return Collapsed;
2061
- }
2062
- return Expanded;
2063
- };
2064
- const filterProblems = (problems, collapsedUris, filterValue) => {
2065
- const filterValueLower = filterValue.toLowerCase();
2066
- const filtered = [];
2067
- for (const problem of problems) {
2068
- const uriMatchIndex = matchesFilterValue(problem.uri, filterValueLower);
2069
- const sourceMatchIndex = matchesFilterValue(problem.source, filterValueLower);
2070
- const messageMatchIndex = matchesFilterValue(problem.message, filterValueLower);
2071
- if (uriMatchIndex === -1 && sourceMatchIndex === -1 && messageMatchIndex === -1) {
2072
- continue;
2073
- }
2074
- const isCollapsed = collapsedUris.includes(problem.uri);
2075
- if (isCollapsed && problem.listItemType === Item) {
2076
- continue;
2077
- }
2078
- filtered.push({
2079
- ...problem,
2080
- isCollapsed,
2081
- listItemType: getListItemType(problem.listItemType, isCollapsed),
2082
- messageMatchIndex,
2083
- sourceMatchIndex,
2084
- uriMatchIndex
2085
- });
2086
- }
2087
- return filtered;
2088
- };
2089
-
2090
2632
  const getFileNameIcon = file => {
2091
2633
  return '';
2092
2634
  };
@@ -2098,7 +2640,7 @@ const getIcon = uri => {
2098
2640
  return getFileNameIcon();
2099
2641
  };
2100
2642
 
2101
- const getVisibleProblems = (problems, collapsedUris, focusedIndex, filterValue) => {
2643
+ const getVisibleProblems = (problems, collapsedUris, focusedIndex, filterValue, minLineY = 0, maxLineY = Infinity, viewMode = List) => {
2102
2644
  array(problems);
2103
2645
  array(collapsedUris);
2104
2646
  number(focusedIndex);
@@ -2106,8 +2648,10 @@ const getVisibleProblems = (problems, collapsedUris, focusedIndex, filterValue)
2106
2648
  const visibleItems = [];
2107
2649
  const filterValueLength = filterValue.length;
2108
2650
  const filtered = filterProblems(problems, collapsedUris, filterValue);
2109
- for (let i = 0; i < filtered.length; i++) {
2110
- const problem = filtered[i];
2651
+ const displayProblems = viewMode === Table ? filtered.filter(problem => problem.message) : filtered;
2652
+ const finalLineY = Math.min(maxLineY, displayProblems.length);
2653
+ for (let i = minLineY; i < finalLineY; i++) {
2654
+ const problem = displayProblems[i];
2111
2655
  visibleItems.push({
2112
2656
  ...problem,
2113
2657
  filterValueLength,
@@ -2122,14 +2666,62 @@ const getVisibleProblems = (problems, collapsedUris, focusedIndex, filterValue)
2122
2666
  const renderCss = (oldState, newState) => {
2123
2667
  const {
2124
2668
  collapsedUris,
2669
+ deltaY,
2125
2670
  filterValue,
2671
+ finalDeltaY,
2126
2672
  focusedIndex,
2673
+ height,
2674
+ itemHeight,
2675
+ maxLineY,
2676
+ minLineY,
2127
2677
  problems,
2128
- uid
2678
+ scrollBarHeight,
2679
+ smallWidthBreakPoint,
2680
+ uid,
2681
+ viewMode,
2682
+ width
2129
2683
  } = newState;
2130
- const visibleProblems = getVisibleProblems(problems, collapsedUris, focusedIndex, filterValue);
2684
+ const visibleProblems = getVisibleProblems(problems, collapsedUris, focusedIndex, filterValue, minLineY, maxLineY, viewMode);
2131
2685
  const uniqueIndents = getUniqueIndents(visibleProblems);
2132
- const css = uniqueIndents.map(getIndentRule).join('\n');
2686
+ const listHeight = getListHeight(height, width, smallWidthBreakPoint, viewMode);
2687
+ const scrollBarTop = getScrollBarTop(listHeight, finalDeltaY, deltaY, scrollBarHeight);
2688
+ const itemOffset = itemHeight > 0 ? -(deltaY % itemHeight) : 0;
2689
+ const rules = [`.Problems {
2690
+ display: flex;
2691
+ flex-direction: column;
2692
+ overflow: hidden;
2693
+ position: relative;
2694
+ }
2695
+ .ProblemsContent {
2696
+ flex: 1;
2697
+ min-height: 0;
2698
+ overflow: hidden;
2699
+ position: relative;
2700
+ }
2701
+ .ProblemsList {
2702
+ contain: strict;
2703
+ height: 100%;
2704
+ overflow: hidden;
2705
+ width: 100%;
2706
+ }
2707
+ .ProblemsTableBody {
2708
+ overflow: hidden;
2709
+ }
2710
+ .ProblemsTableRow {
2711
+ height: ${itemHeight}px;
2712
+ }
2713
+ .ProblemsContentTable > .ScrollBar {
2714
+ top: 22px;
2715
+ }
2716
+ .Problems .ScrollBarThumb {
2717
+ height: ${scrollBarHeight}px;
2718
+ translate: 0 ${scrollBarTop}px;
2719
+ }
2720
+ .ProblemsList > .Problem:first-child,
2721
+ .ProblemsTableBody > .ProblemsTableRow:first-child {
2722
+ margin-top: ${itemOffset}px;
2723
+ }`, ...uniqueIndents.map(getIndentRule)];
2724
+ const css = rules.join('\n');
2133
2725
  return [SetCss, uid, css];
2134
2726
  };
2135
2727
 
@@ -2157,7 +2749,10 @@ const MessageAction = 'MessageAction';
2157
2749
  const Problem = 'Problem';
2158
2750
  const ProblemAt = 'ProblemAt';
2159
2751
  const ProblemBadge = 'ProblemBadge';
2752
+ const ProblemLabel = 'ProblemLabel';
2160
2753
  const Problems = 'Problems';
2754
+ const ProblemsContent = 'ProblemsContent';
2755
+ const ProblemsContentTable = 'ProblemsContentTable';
2161
2756
  const ProblemSelected = 'ProblemSelected';
2162
2757
  const ProblemsErrorIcon = 'ProblemsErrorIcon';
2163
2758
  const ProblemsIcon = 'ProblemsIcon';
@@ -2169,6 +2764,10 @@ const ProblemsTableRow = 'ProblemsTableRow';
2169
2764
  const ProblemsTableRowItem = 'ProblemsTableRowItem';
2170
2765
  const ProblemsTableRowOdd = 'ProblemsTableRowOdd';
2171
2766
  const ProblemsWarningIcon = 'ProblemsWarningIcon';
2767
+ const ScrollBar = 'ScrollBar';
2768
+ const ScrollBarSmall = 'ScrollBarSmall';
2769
+ const ScrollBarThumb = 'ScrollBarThumb';
2770
+ const ScrollBarThumbActive = 'ScrollBarThumbActive';
2172
2771
  const Viewlet = 'Viewlet';
2173
2772
 
2174
2773
  const HandleBlur = 1;
@@ -2177,6 +2776,10 @@ const HandleContextMenu = 3;
2177
2776
  const HandleFilterInput = 4;
2178
2777
  const HandlePointerDown = 5;
2179
2778
  const HandleClickMoreFilters = 6;
2779
+ const HandleWheel = 7;
2780
+ const HandleScrollBarMove = 8;
2781
+ const HandleScrollBarPointerCaptureLost = 9;
2782
+ const HandleScrollBarPointerDown = 10;
2180
2783
 
2181
2784
  const getIconVirtualDom = (icon, type = Div) => {
2182
2785
  return {
@@ -2306,19 +2909,21 @@ const getFileIconVirtualDom = icon => {
2306
2909
 
2307
2910
  const Warning = 'warning';
2308
2911
 
2912
+ const warningIconNode = {
2913
+ childCount: 0,
2914
+ className: mergeClassNames(ProblemsIcon, ProblemsWarningIcon),
2915
+ type: Div
2916
+ };
2917
+ const errorIconNode = {
2918
+ childCount: 0,
2919
+ className: mergeClassNames(ProblemsIcon, ProblemsErrorIcon),
2920
+ type: Div
2921
+ };
2309
2922
  const getProblemsIconVirtualDom = type => {
2310
2923
  if (type === Warning) {
2311
- return {
2312
- childCount: 0,
2313
- className: mergeClassNames(ProblemsIcon, ProblemsWarningIcon),
2314
- type: Div
2315
- };
2924
+ return warningIconNode;
2316
2925
  }
2317
- return {
2318
- childCount: 0,
2319
- className: mergeClassNames(ProblemsIcon, ProblemsErrorIcon),
2320
- type: Div
2321
- };
2926
+ return errorIconNode;
2322
2927
  };
2323
2928
 
2324
2929
  // TODO compute detail message in getVisibleProblems
@@ -2396,7 +3001,7 @@ const getProblemVirtualDom = problem => {
2396
3001
  const lineColumn = atLineColumn(rowIndex, columnIndex);
2397
3002
  const label = {
2398
3003
  childCount: 1,
2399
- className: Label,
3004
+ className: ProblemLabel,
2400
3005
  type: Div
2401
3006
  };
2402
3007
  /**
@@ -2532,14 +3137,14 @@ const messageNode = {
2532
3137
  className: Message,
2533
3138
  type: Div
2534
3139
  };
2535
- const getProblemsVirtualDom$1 = (viewMode, problems, filterValue, message) => {
2536
- if (problems.length === 0 && message) {
3140
+ const getProblemsVirtualDom$1 = (viewMode, problems, filterValue, message, problemCount = problems.length) => {
3141
+ if (problemCount === 0 && message) {
2537
3142
  return [messageNode, text(message)];
2538
3143
  }
2539
- if (problems.length === 0 && filterValue) {
3144
+ if (problemCount === 0 && filterValue) {
2540
3145
  return getNoResultsWithFilterVirtualDom();
2541
3146
  }
2542
- if (problems.length === 0) {
3147
+ if (problemCount === 0) {
2543
3148
  return getProblemsNoProblemsFoundVirtualDom();
2544
3149
  }
2545
3150
  if (viewMode === Table) {
@@ -2548,9 +3153,26 @@ const getProblemsVirtualDom$1 = (viewMode, problems, filterValue, message) => {
2548
3153
  return getProblemsListVirtualDom(problems);
2549
3154
  };
2550
3155
 
3156
+ const scrollBarNode = {
3157
+ childCount: 1,
3158
+ className: mergeClassNames(ScrollBar, ScrollBarSmall),
3159
+ onPointerDown: HandleScrollBarPointerDown,
3160
+ type: Div
3161
+ };
3162
+ const getScrollBarVirtualDom = (scrollBarHeight, scrollBarActive) => {
3163
+ if (scrollBarHeight <= 0) {
3164
+ return [];
3165
+ }
3166
+ return [scrollBarNode, {
3167
+ childCount: 0,
3168
+ className: mergeClassNames(ScrollBarThumb, scrollBarActive ? ScrollBarThumbActive : ''),
3169
+ type: Div
3170
+ }];
3171
+ };
3172
+
2551
3173
  const Focusable = 0;
2552
3174
 
2553
- const getProblemsVirtualDom = (activeUri, viewMode, problems, filterValue, isSmall, message) => {
3175
+ const getProblemsVirtualDom = (activeUri, viewMode, problems, filterValue, isSmall, message, scrollBarHeight = 0, scrollBarActive = false, problemCount = problems.length) => {
2554
3176
  const baseDom = {
2555
3177
  childCount: isSmall ? 2 : 1,
2556
3178
  className: mergeClassNames(Viewlet, Problems),
@@ -2558,6 +3180,7 @@ const getProblemsVirtualDom = (activeUri, viewMode, problems, filterValue, isSma
2558
3180
  onBlur: HandleBlur,
2559
3181
  onContextMenu: HandleContextMenu,
2560
3182
  onPointerDown: HandlePointerDown,
3183
+ onWheel: HandleWheel,
2561
3184
  tabIndex: Focusable,
2562
3185
  type: Div
2563
3186
  };
@@ -2565,8 +3188,15 @@ const getProblemsVirtualDom = (activeUri, viewMode, problems, filterValue, isSma
2565
3188
  badgeText: '',
2566
3189
  command: HandleFilterInput,
2567
3190
  placeholder: filter()}) : [];
2568
- const itemsDom = getProblemsVirtualDom$1(viewMode, problems, filterValue, message);
2569
- return [baseDom, ...filterDom, ...itemsDom];
3191
+ const itemsDom = getProblemsVirtualDom$1(viewMode, problems, filterValue, message, problemCount);
3192
+ const scrollBarDom = getScrollBarVirtualDom(scrollBarHeight, scrollBarActive);
3193
+ const contentClassName = viewMode === Table ? mergeClassNames(ProblemsContent, ProblemsContentTable) : ProblemsContent;
3194
+ const contentDom = {
3195
+ childCount: scrollBarDom.length > 0 ? 2 : 1,
3196
+ className: contentClassName,
3197
+ type: Div
3198
+ };
3199
+ return [baseDom, ...filterDom, contentDom, ...itemsDom, ...scrollBarDom];
2570
3200
  };
2571
3201
 
2572
3202
  const renderItems = (oldState, newState) => {
@@ -2575,15 +3205,20 @@ const renderItems = (oldState, newState) => {
2575
3205
  collapsedUris,
2576
3206
  filterValue,
2577
3207
  focusedIndex,
3208
+ maxLineY,
2578
3209
  message,
3210
+ minLineY,
2579
3211
  problems,
3212
+ scrollBarActive,
3213
+ scrollBarHeight,
2580
3214
  smallWidthBreakPoint,
2581
3215
  viewMode,
2582
3216
  width
2583
3217
  } = newState;
2584
- const visible = getVisibleProblems(problems, collapsedUris, focusedIndex, filterValue);
3218
+ const problemCount = getVisibleProblemCount(problems, collapsedUris, filterValue, viewMode);
3219
+ const visible = getVisibleProblems(problems, collapsedUris, focusedIndex, filterValue, minLineY, maxLineY, viewMode);
2585
3220
  const isSmall = width <= smallWidthBreakPoint;
2586
- const dom = getProblemsVirtualDom(activeUri, viewMode, visible, filterValue, isSmall, message);
3221
+ const dom = getProblemsVirtualDom(activeUri, viewMode, visible, filterValue, isSmall, message, scrollBarHeight, scrollBarActive, problemCount);
2587
3222
  return ['Viewlet.setDom2', dom];
2588
3223
  };
2589
3224
 
@@ -2650,7 +3285,7 @@ const getActions = state => {
2650
3285
  viewMode,
2651
3286
  width
2652
3287
  } = state;
2653
- const visibleCount = getVisibleProblems(problems, collapsedUris, focusedIndex, filterValue).length;
3288
+ const visibleCount = getVisibleProblems(problems, collapsedUris, focusedIndex, filterValue, 0, Infinity, viewMode).length;
2654
3289
  const problemsCount = problems.length;
2655
3290
  const isSmall = width <= smallWidthBreakPoint;
2656
3291
  const actions = [];
@@ -2717,6 +3352,21 @@ const renderEventListeners = () => {
2717
3352
  }, {
2718
3353
  name: HandleClickMoreFilters,
2719
3354
  params: ['handleClickMoreFilters']
3355
+ }, {
3356
+ name: HandleWheel,
3357
+ params: ['handleWheel', DeltaMode, DeltaY],
3358
+ passive: true
3359
+ }, {
3360
+ name: HandleScrollBarPointerDown,
3361
+ params: ['handleScrollBarClick', ClientY],
3362
+ preventDefault: true,
3363
+ trackPointerEvents: [HandleScrollBarMove, HandleScrollBarPointerCaptureLost]
3364
+ }, {
3365
+ name: HandleScrollBarMove,
3366
+ params: ['handleScrollBarMove', ClientY]
3367
+ }, {
3368
+ name: HandleScrollBarPointerCaptureLost,
3369
+ params: ['handleScrollBarCaptureLost']
2720
3370
  }];
2721
3371
  };
2722
3372
 
@@ -2773,6 +3423,10 @@ const commandMap = {
2773
3423
  'Problems.handleContextMenu': wrapCommand(handleContextMenu),
2774
3424
  'Problems.handleFilterInput': wrapCommand(handleFilterInput),
2775
3425
  'Problems.handleIconThemeChange': wrapCommand(handleIconThemeChange),
3426
+ 'Problems.handleScrollBarCaptureLost': wrapCommand(handleScrollBarCaptureLost),
3427
+ 'Problems.handleScrollBarClick': wrapCommand(handleScrollBarClick),
3428
+ 'Problems.handleScrollBarMove': wrapCommand(handleScrollBarMove),
3429
+ 'Problems.handleWheel': wrapCommand(handleWheel),
2776
3430
  'Problems.initialize': initialize,
2777
3431
  'Problems.loadContent': wrapCommand(loadContent),
2778
3432
  'Problems.render2': render2,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lvce-editor/problems-view",
3
- "version": "1.25.3",
3
+ "version": "1.26.0",
4
4
  "description": "Problems View Worker",
5
5
  "repository": {
6
6
  "type": "git",