@lvce-editor/problems-view 1.0.0 → 1.1.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.
@@ -54,6 +54,61 @@ class VError extends Error {
54
54
  }
55
55
  }
56
56
 
57
+ class AssertionError extends Error {
58
+ constructor(message) {
59
+ super(message);
60
+ this.name = 'AssertionError';
61
+ }
62
+ }
63
+ const Object$1 = 1;
64
+ const Number$1 = 2;
65
+ const Array$1 = 3;
66
+ const String = 4;
67
+ const Boolean$1 = 5;
68
+ const Function = 6;
69
+ const Null = 7;
70
+ const Unknown = 8;
71
+ const getType = value => {
72
+ switch (typeof value) {
73
+ case 'number':
74
+ return Number$1;
75
+ case 'function':
76
+ return Function;
77
+ case 'string':
78
+ return String;
79
+ case 'object':
80
+ if (value === null) {
81
+ return Null;
82
+ }
83
+ if (Array.isArray(value)) {
84
+ return Array$1;
85
+ }
86
+ return Object$1;
87
+ case 'boolean':
88
+ return Boolean$1;
89
+ default:
90
+ return Unknown;
91
+ }
92
+ };
93
+ const number = value => {
94
+ const type = getType(value);
95
+ if (type !== Number$1) {
96
+ throw new AssertionError('expected value to be of type number');
97
+ }
98
+ };
99
+ const array = value => {
100
+ const type = getType(value);
101
+ if (type !== Array$1) {
102
+ throw new AssertionError('expected value to be of type array');
103
+ }
104
+ };
105
+ const string = value => {
106
+ const type = getType(value);
107
+ if (type !== String) {
108
+ throw new AssertionError('expected value to be of type string');
109
+ }
110
+ };
111
+
57
112
  const isMessagePort = value => {
58
113
  return value && value instanceof MessagePort;
59
114
  };
@@ -381,7 +436,7 @@ const callbacks = Object.create(null);
381
436
  const set$2 = (id, fn) => {
382
437
  callbacks[id] = fn;
383
438
  };
384
- const get$1 = id => {
439
+ const get$2 = id => {
385
440
  return callbacks[id];
386
441
  };
387
442
  const remove = id => {
@@ -561,7 +616,7 @@ const warn = (...args) => {
561
616
  console.warn(...args);
562
617
  };
563
618
  const resolve = (id, response) => {
564
- const fn = get$1(id);
619
+ const fn = get$2(id);
565
620
  if (!fn) {
566
621
  console.log(response);
567
622
  warn(`callback ${id} may already be disposed`);
@@ -892,16 +947,83 @@ const terminate = () => {
892
947
  globalThis.close();
893
948
  };
894
949
 
895
- const User = 1;
950
+ const rpcs = Object.create(null);
951
+ const set$g = (id, rpc) => {
952
+ rpcs[id] = rpc;
953
+ };
954
+ const get$1 = id => {
955
+ return rpcs[id];
956
+ };
957
+
958
+ /* eslint-disable @typescript-eslint/explicit-function-return-type */
959
+
960
+ const create$1 = rpcId => {
961
+ return {
962
+ // @ts-ignore
963
+ invoke(method, ...params) {
964
+ const rpc = get$1(rpcId);
965
+ // @ts-ignore
966
+ return rpc.invoke(method, ...params);
967
+ },
968
+ // @ts-ignore
969
+ invokeAndTransfer(method, ...params) {
970
+ const rpc = get$1(rpcId);
971
+ // @ts-ignore
972
+ return rpc.invokeAndTransfer(method, ...params);
973
+ },
974
+ set(rpc) {
975
+ set$g(rpcId, rpc);
976
+ },
977
+ async dispose() {
978
+ const rpc = get$1(rpcId);
979
+ await rpc.dispose();
980
+ }
981
+ };
982
+ };
983
+ const RendererWorker$1 = 1;
984
+ const {
985
+ invoke: invoke$3,
986
+ set: set$3} = create$1(RendererWorker$1);
987
+ const writeClipBoardText$1 = async text => {
988
+ await invoke$3('ClipBoard.writeText', /* text */text);
989
+ };
990
+ const RendererWorker = {
991
+ __proto__: null,
992
+ set: set$3,
993
+ writeClipBoardText: writeClipBoardText$1
994
+ };
896
995
 
897
996
  const {
898
997
  set: set$1,
998
+ writeClipBoardText
999
+ } = RendererWorker;
1000
+
1001
+ const writeText = async text => {
1002
+ await writeClipBoardText(text);
1003
+ };
1004
+
1005
+ const copyMessage = async state => {
1006
+ const {
1007
+ problems,
1008
+ focusedIndex
1009
+ } = state;
1010
+ const problem = problems[focusedIndex];
1011
+ await writeText(problem.message);
1012
+ return state;
1013
+ };
1014
+
1015
+ const User = 1;
1016
+
1017
+ const {
1018
+ get,
1019
+ set,
899
1020
  wrapCommand
900
1021
  } = create$2();
901
1022
 
902
- const None = 0;
1023
+ const None$1 = 0;
1024
+ const Table = 1;
903
1025
 
904
- const create$1 = (id, uri, x, y, width, height, args, parentUid) => {
1026
+ const create = (id, uri, x, y, width, height, args, parentUid) => {
905
1027
  const state = {
906
1028
  uid: id,
907
1029
  parentUid,
@@ -914,7 +1036,7 @@ const create$1 = (id, uri, x, y, width, height, args, parentUid) => {
914
1036
  width,
915
1037
  height,
916
1038
  filterValue: '',
917
- viewMode: None,
1039
+ viewMode: None$1,
918
1040
  inputSource: User,
919
1041
  minLineY: 0,
920
1042
  maxLineY: 0,
@@ -923,9 +1045,47 @@ const create$1 = (id, uri, x, y, width, height, args, parentUid) => {
923
1045
  smallWidthBreakPoint: 650,
924
1046
  filteredProblems: []
925
1047
  };
926
- set$1(id, state, state);
1048
+ set(id, state, state);
1049
+ };
1050
+
1051
+ const isEqual = (oldState, newState) => {
1052
+ return oldState.problems === newState.problems;
1053
+ };
1054
+
1055
+ const RenderItems = 1;
1056
+
1057
+ const modules = [isEqual];
1058
+ const numbers = [RenderItems];
1059
+
1060
+ const diff = (oldState, newState) => {
1061
+ const diffResult = [];
1062
+ for (let i = 0; i < modules.length; i++) {
1063
+ const fn = modules[i];
1064
+ if (!fn(oldState, newState)) {
1065
+ diffResult.push(numbers[i]);
1066
+ }
1067
+ }
1068
+ return diffResult;
1069
+ };
1070
+
1071
+ const diff2 = uid => {
1072
+ const {
1073
+ oldState,
1074
+ newState
1075
+ } = get(uid);
1076
+ const diffResult = diff(oldState, newState);
1077
+ return diffResult;
927
1078
  };
928
1079
 
1080
+ const None = 'none';
1081
+ const Tree$1 = 'tree';
1082
+ const TreeItem$1 = 'treeitem';
1083
+ const AriaRoles = {
1084
+ __proto__: null,
1085
+ None,
1086
+ Tree: Tree$1,
1087
+ TreeItem: TreeItem$1
1088
+ };
929
1089
  const Space = 9;
930
1090
  const PageUp = 10;
931
1091
  const PageDown = 11;
@@ -947,6 +1107,31 @@ const KeyCode = {
947
1107
  Space,
948
1108
  UpArrow
949
1109
  };
1110
+ const mergeClassNames = (...classNames) => {
1111
+ return classNames.filter(Boolean).join(' ');
1112
+ };
1113
+ const Button = 1;
1114
+ const Div = 4;
1115
+ const Input = 6;
1116
+ const Span = 8;
1117
+ const Text = 12;
1118
+ const Img = 17;
1119
+ const A = 53;
1120
+ const VirtualDomElements = {
1121
+ __proto__: null,
1122
+ A,
1123
+ Button,
1124
+ Div,
1125
+ Img,
1126
+ Input,
1127
+ Span};
1128
+ const text = data => {
1129
+ return {
1130
+ type: Text,
1131
+ text: data,
1132
+ childCount: 0
1133
+ };
1134
+ };
950
1135
 
951
1136
  const FocusProblems = 19;
952
1137
 
@@ -999,6 +1184,8 @@ const getKeyBindings = () => {
999
1184
  };
1000
1185
 
1001
1186
  const Item = 0;
1187
+ const Expanded = 1;
1188
+ const Collapsed = 2;
1002
1189
 
1003
1190
  const getArrowLeftNewFocusedIndex = (problems, collapsedUris, focusedIndex) => {
1004
1191
  for (let i = focusedIndex; i >= 0; i--) {
@@ -1069,63 +1256,612 @@ const initialize = async () => {
1069
1256
  // TODO create connection to editor worker
1070
1257
  };
1071
1258
 
1072
- const commandMap = {
1073
- 'Problems.handleArrowLeft': wrapCommand(handleArrowLeft),
1074
- 'Problems.handleArrowRight': wrapCommand(handleArrowRight),
1075
- 'Problems.create': create$1,
1076
- 'Problems.getKeyBindings': getKeyBindings,
1077
- 'Problems.terminate': terminate,
1078
- 'Problems.initialize': initialize
1259
+ const Chevron = 'Chevron';
1260
+ const FileIcon = 'FileIcon';
1261
+ const Filter$3 = 'Filter';
1262
+ const Highlight = 'Highlight';
1263
+ const IconButton = 'IconButton';
1264
+ const InputBox = 'InputBox';
1265
+ const Label = 'Label';
1266
+ const LabelDetail = 'LabelDetail';
1267
+ const Message$1 = 'Message';
1268
+ const MessageAction = 'MessageAction';
1269
+ const Problem = 'Problem';
1270
+ const ProblemAt = 'ProblemAt';
1271
+ const ProblemBadge = 'ProblemBadge';
1272
+ const Problems = 'Problems';
1273
+ const ProblemSelected = 'ProblemSelected';
1274
+ const ProblemsErrorIcon = 'ProblemsErrorIcon';
1275
+ const ProblemsIcon = 'ProblemsIcon';
1276
+ const ProblemsList = 'ProblemsList';
1277
+ const ProblemsTable = 'ProblemsTable';
1278
+ const ProblemsTableBody = 'ProblemsTableBody';
1279
+ const ProblemsTableHeader = 'ProblemsTableHeader';
1280
+ const ProblemsTableRow = 'ProblemsTableRow';
1281
+ const ProblemsTableRowItem = 'ProblemsTableRowItem';
1282
+ const ProblemsTableRowOdd = 'ProblemsTableRowOdd';
1283
+ const ProblemsWarningIcon = 'ProblemsWarningIcon';
1284
+ const Viewlet = 'Viewlet';
1285
+
1286
+ const HandleBlur = 'handleBlur';
1287
+ const HandleClearFilterClick = 'handleClearFilterClick';
1288
+ const HandleContextMenu = 'handleContextMenu';
1289
+ const HandleFilterInput = 'handleFilterInput';
1290
+ const HandlePointerDown = 'handlePointerDown';
1291
+
1292
+ const getIconVirtualDom = (icon, type = VirtualDomElements.Div) => {
1293
+ return {
1294
+ type,
1295
+ className: `MaskIcon MaskIcon${icon}`,
1296
+ role: AriaRoles.None,
1297
+ childCount: 0
1298
+ };
1079
1299
  };
1080
1300
 
1081
- const rpcs = Object.create(null);
1082
- const set$g = (id, rpc) => {
1083
- rpcs[id] = rpc;
1301
+ const getActionButtonVirtualDom = action => {
1302
+ const {
1303
+ id,
1304
+ icon,
1305
+ command
1306
+ } = action;
1307
+ return [{
1308
+ type: VirtualDomElements.Button,
1309
+ className: IconButton,
1310
+ title: id,
1311
+ 'data-command': command,
1312
+ childCount: 1
1313
+ }, getIconVirtualDom(icon)];
1084
1314
  };
1085
- const get = id => {
1086
- return rpcs[id];
1315
+
1316
+ const Filter$2 = 'filter';
1317
+
1318
+ const Filter$1 = 'Filter';
1319
+
1320
+ const getProblemsFilterVirtualDom = action => {
1321
+ // TODO avoid mutation
1322
+ const dom = [];
1323
+ dom.push({
1324
+ type: VirtualDomElements.Div,
1325
+ className: Filter$3,
1326
+ childCount: 1
1327
+ }, {
1328
+ type: VirtualDomElements.Input,
1329
+ className: InputBox,
1330
+ spellcheck: false,
1331
+ autocapitalize: 'off',
1332
+ autocorrect: 'off',
1333
+ placeholder: action.placeholder,
1334
+ onInput: action.command,
1335
+ name: Filter$2,
1336
+ value: action.value
1337
+ });
1338
+ // @ts-ignore
1339
+ dom[0].childCount++;
1340
+ dom.push(...getActionButtonVirtualDom({
1341
+ id: 'more filters',
1342
+ icon: Filter$1,
1343
+ command: 'more filters'
1344
+ }));
1345
+ return dom;
1087
1346
  };
1088
1347
 
1089
- /* eslint-disable @typescript-eslint/explicit-function-return-type */
1348
+ const getBadgeVirtualDom = (className, count) => {
1349
+ return [{
1350
+ type: VirtualDomElements.Div,
1351
+ className: `Badge ${className}`,
1352
+ childCount: 1
1353
+ }, text(`${count}`)];
1354
+ };
1090
1355
 
1091
- const create = rpcId => {
1356
+ const getChevronDownVirtualDom = (extraClassName = '') => {
1092
1357
  return {
1093
- // @ts-ignore
1094
- invoke(method, ...params) {
1095
- const rpc = get(rpcId);
1096
- // @ts-ignore
1097
- return rpc.invoke(method, ...params);
1098
- },
1099
- // @ts-ignore
1100
- invokeAndTransfer(method, ...params) {
1101
- const rpc = get(rpcId);
1102
- // @ts-ignore
1103
- return rpc.invokeAndTransfer(method, ...params);
1104
- },
1105
- set(rpc) {
1106
- set$g(rpcId, rpc);
1107
- },
1108
- async dispose() {
1109
- const rpc = get(rpcId);
1110
- await rpc.dispose();
1358
+ type: VirtualDomElements.Div,
1359
+ className: `${Chevron} MaskIconChevronDown ${extraClassName}`,
1360
+ childCount: 0
1361
+ };
1362
+ };
1363
+ const getChevronRightVirtualDom = (extraClassName = '') => {
1364
+ return {
1365
+ type: VirtualDomElements.Div,
1366
+ className: `${Chevron} MaskIconChevronRight ${extraClassName}`,
1367
+ childCount: 0
1368
+ };
1369
+ };
1370
+
1371
+ const getFileIconVirtualDom = icon => {
1372
+ return {
1373
+ type: VirtualDomElements.Img,
1374
+ className: FileIcon,
1375
+ src: icon,
1376
+ role: AriaRoles.None,
1377
+ childCount: 0
1378
+ };
1379
+ };
1380
+
1381
+ const Warning = 'warning';
1382
+
1383
+ const getProblemsIconVirtualDom = type => {
1384
+ // TODO use mergeclassnames
1385
+ if (type === Warning) {
1386
+ return {
1387
+ type: VirtualDomElements.Div,
1388
+ className: `${ProblemsIcon} ${ProblemsWarningIcon}`,
1389
+ childCount: 0
1390
+ };
1391
+ }
1392
+ return {
1393
+ type: VirtualDomElements.Div,
1394
+ className: `${ProblemsIcon} ${ProblemsErrorIcon}`,
1395
+ childCount: 0
1396
+ };
1397
+ };
1398
+
1399
+ // TODO compute detail message in getVisibleProblems
1400
+ const getProblemSourceDetail = (source, code) => {
1401
+ let message = '';
1402
+ if (source) {
1403
+ message += `${source}`;
1404
+ }
1405
+ if (code) {
1406
+ message += `(${code})`;
1407
+ }
1408
+ message += ' ';
1409
+ return message;
1410
+ };
1411
+
1412
+ const defaultIndent = 1;
1413
+ const getTreeItemIndent = depth => {
1414
+ return `${depth * defaultIndent}rem`;
1415
+ };
1416
+
1417
+ const emptyObject = {};
1418
+ const RE_PLACEHOLDER = /\{(PH\d+)\}/g;
1419
+ const i18nString = (key, placeholders = emptyObject) => {
1420
+ if (placeholders === emptyObject) {
1421
+ return key;
1422
+ }
1423
+ const replacer = (match, rest) => {
1424
+ return placeholders[rest];
1425
+ };
1426
+ return key.replaceAll(RE_PLACEHOLDER, replacer);
1427
+ };
1428
+
1429
+ const ClearFilters = 'Clear Filters';
1430
+ const Code = 'Code';
1431
+ const File = 'File';
1432
+ const Filter = 'Filter';
1433
+ const LineColumn = '[Ln {PH1}, Col {PH2}]';
1434
+ const Message = 'Message';
1435
+ const NoProblemsDetected = 'No problems have been detected in the workspace.';
1436
+ const NoResultsFoundWithProvidedFilterCriteria = 'No results found with provided filter criteria.';
1437
+ const Source = 'Source';
1438
+
1439
+ const noProblemsDetected = () => {
1440
+ return i18nString(NoProblemsDetected);
1441
+ };
1442
+ const atLineColumn = (line, column) => {
1443
+ return i18nString(LineColumn, {
1444
+ PH1: line,
1445
+ PH2: column
1446
+ });
1447
+ };
1448
+ const clearFilter = () => {
1449
+ return i18nString(ClearFilters);
1450
+ };
1451
+ const code = () => {
1452
+ return i18nString(Code);
1453
+ };
1454
+ const message = () => {
1455
+ return i18nString(Message);
1456
+ };
1457
+ const file = () => {
1458
+ return i18nString(File);
1459
+ };
1460
+ const filter = () => {
1461
+ return i18nString(Filter);
1462
+ };
1463
+ const source = () => {
1464
+ return i18nString(Source);
1465
+ };
1466
+ const noResultsFoundWithProvidedFilterCriteria = () => {
1467
+ return i18nString(NoResultsFoundWithProvidedFilterCriteria);
1468
+ };
1469
+
1470
+ const getProblemVirtualDom = problem => {
1471
+ const {
1472
+ message,
1473
+ rowIndex,
1474
+ columnIndex,
1475
+ isActive,
1476
+ uri,
1477
+ icon,
1478
+ source,
1479
+ relativePath,
1480
+ messageMatchIndex,
1481
+ filterValueLength,
1482
+ code,
1483
+ type,
1484
+ posInSet,
1485
+ setSize,
1486
+ level,
1487
+ listItemType,
1488
+ isCollapsed
1489
+ } = problem;
1490
+ let className = Problem;
1491
+ if (isActive) {
1492
+ className += ' ' + ProblemSelected;
1493
+ }
1494
+ if (listItemType === Expanded || listItemType === Collapsed) {
1495
+ return [{
1496
+ type: VirtualDomElements.Div,
1497
+ className,
1498
+ childCount: 5,
1499
+ paddingLeft: getTreeItemIndent(1),
1500
+ ariaPosInSet: posInSet,
1501
+ ariaSetSize: setSize,
1502
+ ariaLevel: level,
1503
+ ariaExpanded: !isCollapsed,
1504
+ ariaSelected: isActive,
1505
+ role: AriaRoles.TreeItem
1506
+ }, listItemType === Collapsed ? getChevronRightVirtualDom() : getChevronDownVirtualDom(), getFileIconVirtualDom(icon), text(uri), {
1507
+ type: VirtualDomElements.Div,
1508
+ className: LabelDetail,
1509
+ childCount: 1
1510
+ }, text(relativePath), ...getBadgeVirtualDom(ProblemBadge, problem.count)];
1511
+ }
1512
+ const lineColumn = atLineColumn(rowIndex, columnIndex);
1513
+ const label = {
1514
+ type: VirtualDomElements.Div,
1515
+ className: Label,
1516
+ childCount: 1
1517
+ };
1518
+ /**
1519
+ * @type {any}
1520
+ */
1521
+ const dom = [{
1522
+ type: VirtualDomElements.Div,
1523
+ className,
1524
+ childCount: 3,
1525
+ paddingLeft: getTreeItemIndent(2),
1526
+ ariaPosInSet: posInSet,
1527
+ ariaSetSize: setSize,
1528
+ ariaLevel: level,
1529
+ ariaSelected: isActive,
1530
+ role: AriaRoles.TreeItem
1531
+ }, getProblemsIconVirtualDom(type), label];
1532
+ if (filterValueLength) {
1533
+ const before = message.slice(0, messageMatchIndex);
1534
+ const middle = message.slice(messageMatchIndex, messageMatchIndex + filterValueLength);
1535
+ const after = message.slice(messageMatchIndex + filterValueLength);
1536
+ label.childCount += 2;
1537
+ dom.push(text(before), {
1538
+ type: VirtualDomElements.Div,
1539
+ className: Highlight,
1540
+ childCount: 1
1541
+ }, text(middle), text(after));
1542
+ } else {
1543
+ dom.push(text(message));
1544
+ }
1545
+ dom.push({
1546
+ type: VirtualDomElements.Span,
1547
+ className: ProblemAt,
1548
+ childCount: 2
1549
+ }, text(getProblemSourceDetail(source, code)), text(lineColumn));
1550
+ return dom;
1551
+ };
1552
+
1553
+ const getProblemsListVirtualDom = problems => {
1554
+ const dom = [{
1555
+ type: VirtualDomElements.Div,
1556
+ className: ProblemsList,
1557
+ childCount: problems.length,
1558
+ role: AriaRoles.Tree,
1559
+ ariaLabel: 'Problems Tree' // TODO use i18n string
1560
+ }, ...problems.flatMap(getProblemVirtualDom)];
1561
+ return dom;
1562
+ };
1563
+
1564
+ const getProblemsNoProblemsFoundVirtualDom = filterValue => {
1565
+ // TODO avoid mutation
1566
+ const dom = [];
1567
+ dom.push({
1568
+ type: VirtualDomElements.Div,
1569
+ className: Message$1,
1570
+ childCount: 1
1571
+ });
1572
+ if (filterValue) {
1573
+ dom[0].childCount += 2;
1574
+ dom.push({
1575
+ type: VirtualDomElements.Span,
1576
+ childCount: 1
1577
+ }, text(noResultsFoundWithProvidedFilterCriteria()), {
1578
+ type: VirtualDomElements.A,
1579
+ className: MessageAction,
1580
+ childCount: 1,
1581
+ onClick: HandleClearFilterClick
1582
+ }, text(clearFilter()), text('.'));
1583
+ } else {
1584
+ dom.push(text(noProblemsDetected()));
1585
+ }
1586
+ return dom;
1587
+ };
1588
+
1589
+ const getClassName = isEven => {
1590
+ if (isEven) {
1591
+ return ProblemsTableRow;
1592
+ }
1593
+ return mergeClassNames(ProblemsTableRow, ProblemsTableRowOdd);
1594
+ };
1595
+ const getProblemsTableRowVirtualDom = problem => {
1596
+ const {
1597
+ code,
1598
+ source,
1599
+ uri,
1600
+ message,
1601
+ isEven,
1602
+ type
1603
+ } = problem;
1604
+ // TODO problems are grouped by uri, depending
1605
+ // on which renderer is used the data needs to look different
1606
+ if (!message) {
1607
+ return [];
1608
+ }
1609
+ const dom = [{
1610
+ type: VirtualDomElements.Div,
1611
+ className: getClassName(isEven),
1612
+ childCount: 5
1613
+ }, {
1614
+ type: VirtualDomElements.Div,
1615
+ className: ProblemsTableRowItem,
1616
+ childCount: 1
1617
+ }, getProblemsIconVirtualDom(type), {
1618
+ type: VirtualDomElements.Div,
1619
+ className: ProblemsTableRowItem,
1620
+ childCount: 1
1621
+ }, text(getProblemSourceDetail(source, code)), {
1622
+ type: VirtualDomElements.Div,
1623
+ className: ProblemsTableRowItem,
1624
+ childCount: 1
1625
+ }, text(message), {
1626
+ type: VirtualDomElements.Div,
1627
+ className: ProblemsTableRowItem,
1628
+ childCount: 1
1629
+ }, text(uri), {
1630
+ type: VirtualDomElements.Div,
1631
+ className: ProblemsTableRowItem,
1632
+ childCount: 1
1633
+ }, text(source)];
1634
+ return dom;
1635
+ };
1636
+
1637
+ const getProblemsTableBodyVirtualDom = problems => {
1638
+ const dom = [{
1639
+ type: VirtualDomElements.Div,
1640
+ className: ProblemsTableBody,
1641
+ childCount: problems.length
1642
+ }, ...problems.flatMap(getProblemsTableRowVirtualDom)];
1643
+ return dom;
1644
+ };
1645
+
1646
+ const getProblemsTableHeaderVirtualDom = () => {
1647
+ const textCode = code();
1648
+ const textSource = source();
1649
+ const textMessage = message();
1650
+ const textFile = file();
1651
+ const dom = [{
1652
+ type: VirtualDomElements.Div,
1653
+ className: ProblemsTableHeader,
1654
+ childCount: 1
1655
+ }, {
1656
+ type: VirtualDomElements.Div,
1657
+ className: ProblemsTableRow,
1658
+ childCount: 5
1659
+ }, {
1660
+ type: VirtualDomElements.Div,
1661
+ className: ProblemsTableRowItem,
1662
+ childCount: 0
1663
+ }, {
1664
+ type: VirtualDomElements.Div,
1665
+ className: ProblemsTableRowItem,
1666
+ childCount: 1
1667
+ }, text(textCode), {
1668
+ type: VirtualDomElements.Div,
1669
+ className: ProblemsTableRowItem,
1670
+ childCount: 1
1671
+ }, text(textMessage), {
1672
+ type: VirtualDomElements.Div,
1673
+ className: ProblemsTableRowItem,
1674
+ childCount: 1
1675
+ }, text(textFile), {
1676
+ type: VirtualDomElements.Div,
1677
+ className: ProblemsTableRowItem,
1678
+ childCount: 1
1679
+ }, text(textSource)];
1680
+ return dom;
1681
+ };
1682
+
1683
+ const getProblemsTableVirtualDom = problems => {
1684
+ const dom = [{
1685
+ type: VirtualDomElements.Div,
1686
+ className: ProblemsTable,
1687
+ childCount: 2
1688
+ }, ...getProblemsTableHeaderVirtualDom(), ...getProblemsTableBodyVirtualDom(problems)];
1689
+ return dom;
1690
+ };
1691
+
1692
+ const getProblemsVirtualDom$1 = (viewMode, problems, filterValue) => {
1693
+ if (problems.length === 0) {
1694
+ return getProblemsNoProblemsFoundVirtualDom(filterValue);
1695
+ }
1696
+ if (viewMode === Table) {
1697
+ return getProblemsTableVirtualDom(problems);
1698
+ }
1699
+ const dom = getProblemsListVirtualDom(problems);
1700
+ return dom;
1701
+ };
1702
+
1703
+ const getProblemsVirtualDom = (viewMode, problems, filterValue, isSmall) => {
1704
+ // TODO avoid mutation
1705
+ const dom = [];
1706
+ dom.push({
1707
+ type: VirtualDomElements.Div,
1708
+ className: mergeClassNames(Viewlet, Problems),
1709
+ tabIndex: 0,
1710
+ onPointerDown: HandlePointerDown,
1711
+ onContextMenu: HandleContextMenu,
1712
+ onBlur: HandleBlur,
1713
+ childCount: 1
1714
+ });
1715
+ if (isSmall) {
1716
+ dom[0].childCount++;
1717
+ dom.push(...getProblemsFilterVirtualDom({
1718
+ command: HandleFilterInput,
1719
+ placeholder: filter(),
1720
+ value: ''
1721
+ }));
1722
+ }
1723
+ dom.push(...getProblemsVirtualDom$1(viewMode, problems, filterValue));
1724
+ return dom;
1725
+ };
1726
+
1727
+ const matchesFilterValue = (string, filterValueLower) => {
1728
+ if (filterValueLower) {
1729
+ return string.toLowerCase().indexOf(filterValueLower);
1730
+ }
1731
+ return 0;
1732
+ };
1733
+ const getListItemType = (listItemType, isCollapsed) => {
1734
+ if (listItemType === Item) {
1735
+ return Item;
1736
+ }
1737
+ if (isCollapsed) {
1738
+ return Collapsed;
1739
+ }
1740
+ return Expanded;
1741
+ };
1742
+ const filterProblems = (problems, collapsedUris, filterValue) => {
1743
+ const filterValueLower = filterValue.toLowerCase();
1744
+ const filtered = [];
1745
+ for (const problem of problems) {
1746
+ const uriMatchIndex = matchesFilterValue(problem.uri, filterValueLower);
1747
+ const sourceMatchIndex = matchesFilterValue(problem.source, filterValueLower);
1748
+ const messageMatchIndex = matchesFilterValue(problem.message, filterValueLower);
1749
+ if (uriMatchIndex === -1 && sourceMatchIndex === -1 && messageMatchIndex === -1) {
1750
+ continue;
1111
1751
  }
1752
+ const isCollapsed = collapsedUris.includes(problem.uri);
1753
+ if (isCollapsed && problem.listItemType === Item) {
1754
+ continue;
1755
+ }
1756
+ filtered.push({
1757
+ ...problem,
1758
+ uriMatchIndex,
1759
+ sourceMatchIndex,
1760
+ messageMatchIndex,
1761
+ listItemType: getListItemType(problem.listItemType, isCollapsed),
1762
+ isCollapsed
1763
+ });
1764
+ }
1765
+ return filtered;
1766
+ };
1767
+
1768
+ const getFileNameIcon = file => {
1769
+ return '';
1770
+ };
1771
+
1772
+ const getIcon = uri => {
1773
+ if (!uri) {
1774
+ return '';
1775
+ }
1776
+ return getFileNameIcon();
1777
+ };
1778
+ const getVisibleProblems = (problems, collapsedUris, focusedIndex, filterValue) => {
1779
+ array(problems);
1780
+ array(collapsedUris);
1781
+ number(focusedIndex);
1782
+ string(filterValue);
1783
+ const visibleItems = [];
1784
+ const filterValueLength = filterValue.length;
1785
+ const filtered = filterProblems(problems, collapsedUris, filterValue);
1786
+ for (let i = 0; i < filtered.length; i++) {
1787
+ const problem = filtered[i];
1788
+ visibleItems.push({
1789
+ ...problem,
1790
+ isEven: i % 2 === 0,
1791
+ isActive: i === focusedIndex,
1792
+ icon: getIcon(problem.uri),
1793
+ filterValueLength
1794
+ });
1795
+ }
1796
+ return visibleItems;
1797
+ };
1798
+
1799
+ const renderItems = (oldState, newState) => {
1800
+ const visible = getVisibleProblems(newState.problems, newState.collapsedUris, newState.focusedIndex, newState.filterValue);
1801
+ const isSmall = newState.width <= newState.smallWidthBreakPoint;
1802
+ const dom = getProblemsVirtualDom(newState.viewMode, visible, newState.filterValue, isSmall);
1803
+ return ['Viewlet.setDom2', dom];
1804
+ };
1805
+
1806
+ const getRenderer = diffType => {
1807
+ switch (diffType) {
1808
+ case RenderItems:
1809
+ return renderItems;
1810
+ default:
1811
+ throw new Error('unknown renderer');
1812
+ }
1813
+ };
1814
+
1815
+ const applyRender = (oldState, newState, diffResult) => {
1816
+ const commands = [];
1817
+ for (const item of diffResult) {
1818
+ const fn = getRenderer(item);
1819
+ commands.push(fn(oldState, newState));
1820
+ }
1821
+ return commands;
1822
+ };
1823
+
1824
+ const render2 = (uid, diffResult) => {
1825
+ const {
1826
+ oldState,
1827
+ newState
1828
+ } = get(uid);
1829
+ set(uid, newState, newState);
1830
+ const commands = applyRender(oldState, newState, diffResult);
1831
+ return commands;
1832
+ };
1833
+
1834
+ const saveState = state => {
1835
+ const {
1836
+ viewMode,
1837
+ filterValue,
1838
+ collapsedUris
1839
+ } = state;
1840
+ return {
1841
+ viewMode,
1842
+ filterValue,
1843
+ collapsedUris
1112
1844
  };
1113
1845
  };
1114
- const RendererWorker$1 = 1;
1115
- const {
1116
- set: set$3} = create(RendererWorker$1);
1117
- const RendererWorker = {
1118
- __proto__: null,
1119
- set: set$3};
1120
1846
 
1121
- const {
1122
- set} = RendererWorker;
1847
+ const commandMap = {
1848
+ 'Problems.create': create,
1849
+ 'Problems.diff2': diff2,
1850
+ 'Problems.getKeyBindings': getKeyBindings,
1851
+ 'Problems.handleArrowLeft': wrapCommand(handleArrowLeft),
1852
+ 'Problems.handleArrowRight': wrapCommand(handleArrowRight),
1853
+ 'Problems.initialize': initialize,
1854
+ 'Problems.render2': render2,
1855
+ 'Problems.saveState': saveState,
1856
+ 'Problems.terminate': terminate,
1857
+ 'Problems.copyMessage': copyMessage
1858
+ };
1123
1859
 
1124
1860
  const listen = async () => {
1125
1861
  const rpc = await WebWorkerRpcClient.create({
1126
1862
  commandMap: commandMap
1127
1863
  });
1128
- set(rpc);
1864
+ set$1(rpc);
1129
1865
  };
1130
1866
 
1131
1867
  const main = async () => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lvce-editor/problems-view",
3
- "version": "1.0.0",
3
+ "version": "1.1.0",
4
4
  "description": "Problems View Worker",
5
5
  "repository": {
6
6
  "type": "git",