@lvce-editor/problems-view 1.0.0 → 1.2.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,54 @@ 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 focusIndex = (state, index) => {
1081
+ return {
1082
+ ...state,
1083
+ focusedIndex: index
1084
+ };
1085
+ };
1086
+
1087
+ const None = 'none';
1088
+ const Tree$1 = 'tree';
1089
+ const TreeItem$1 = 'treeitem';
1090
+ const AriaRoles = {
1091
+ __proto__: null,
1092
+ None,
1093
+ Tree: Tree$1,
1094
+ TreeItem: TreeItem$1
1095
+ };
929
1096
  const Space = 9;
930
1097
  const PageUp = 10;
931
1098
  const PageDown = 11;
@@ -947,6 +1114,31 @@ const KeyCode = {
947
1114
  Space,
948
1115
  UpArrow
949
1116
  };
1117
+ const mergeClassNames = (...classNames) => {
1118
+ return classNames.filter(Boolean).join(' ');
1119
+ };
1120
+ const Button = 1;
1121
+ const Div = 4;
1122
+ const Input = 6;
1123
+ const Span = 8;
1124
+ const Text = 12;
1125
+ const Img = 17;
1126
+ const A = 53;
1127
+ const VirtualDomElements = {
1128
+ __proto__: null,
1129
+ A,
1130
+ Button,
1131
+ Div,
1132
+ Img,
1133
+ Input,
1134
+ Span};
1135
+ const text = data => {
1136
+ return {
1137
+ type: Text,
1138
+ text: data,
1139
+ childCount: 0
1140
+ };
1141
+ };
950
1142
 
951
1143
  const FocusProblems = 19;
952
1144
 
@@ -999,6 +1191,8 @@ const getKeyBindings = () => {
999
1191
  };
1000
1192
 
1001
1193
  const Item = 0;
1194
+ const Expanded = 1;
1195
+ const Collapsed = 2;
1002
1196
 
1003
1197
  const getArrowLeftNewFocusedIndex = (problems, collapsedUris, focusedIndex) => {
1004
1198
  for (let i = focusedIndex; i >= 0; i--) {
@@ -1069,63 +1263,621 @@ const initialize = async () => {
1069
1263
  // TODO create connection to editor worker
1070
1264
  };
1071
1265
 
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
1266
+ const Chevron = 'Chevron';
1267
+ const FileIcon = 'FileIcon';
1268
+ const Filter$3 = 'Filter';
1269
+ const Highlight = 'Highlight';
1270
+ const IconButton = 'IconButton';
1271
+ const InputBox = 'InputBox';
1272
+ const Label = 'Label';
1273
+ const LabelDetail = 'LabelDetail';
1274
+ const Message$1 = 'Message';
1275
+ const MessageAction = 'MessageAction';
1276
+ const Problem = 'Problem';
1277
+ const ProblemAt = 'ProblemAt';
1278
+ const ProblemBadge = 'ProblemBadge';
1279
+ const Problems = 'Problems';
1280
+ const ProblemSelected = 'ProblemSelected';
1281
+ const ProblemsErrorIcon = 'ProblemsErrorIcon';
1282
+ const ProblemsIcon = 'ProblemsIcon';
1283
+ const ProblemsList = 'ProblemsList';
1284
+ const ProblemsTable = 'ProblemsTable';
1285
+ const ProblemsTableBody = 'ProblemsTableBody';
1286
+ const ProblemsTableHeader = 'ProblemsTableHeader';
1287
+ const ProblemsTableRow = 'ProblemsTableRow';
1288
+ const ProblemsTableRowItem = 'ProblemsTableRowItem';
1289
+ const ProblemsTableRowOdd = 'ProblemsTableRowOdd';
1290
+ const ProblemsWarningIcon = 'ProblemsWarningIcon';
1291
+ const Viewlet = 'Viewlet';
1292
+
1293
+ const HandleBlur = 'handleBlur';
1294
+ const HandleClearFilterClick = 'handleClearFilterClick';
1295
+ const HandleContextMenu = 'handleContextMenu';
1296
+ const HandleFilterInput = 'handleFilterInput';
1297
+ const HandlePointerDown = 'handlePointerDown';
1298
+
1299
+ const getIconVirtualDom = (icon, type = VirtualDomElements.Div) => {
1300
+ return {
1301
+ type,
1302
+ className: `MaskIcon MaskIcon${icon}`,
1303
+ role: AriaRoles.None,
1304
+ childCount: 0
1305
+ };
1079
1306
  };
1080
1307
 
1081
- const rpcs = Object.create(null);
1082
- const set$g = (id, rpc) => {
1083
- rpcs[id] = rpc;
1308
+ const getActionButtonVirtualDom = action => {
1309
+ const {
1310
+ id,
1311
+ icon,
1312
+ command
1313
+ } = action;
1314
+ return [{
1315
+ type: VirtualDomElements.Button,
1316
+ className: IconButton,
1317
+ title: id,
1318
+ 'data-command': command,
1319
+ childCount: 1
1320
+ }, getIconVirtualDom(icon)];
1084
1321
  };
1085
- const get = id => {
1086
- return rpcs[id];
1322
+
1323
+ const Filter$2 = 'filter';
1324
+
1325
+ const Filter$1 = 'Filter';
1326
+
1327
+ const getProblemsFilterVirtualDom = action => {
1328
+ // TODO avoid mutation
1329
+ const dom = [];
1330
+ dom.push({
1331
+ type: VirtualDomElements.Div,
1332
+ className: Filter$3,
1333
+ childCount: 1
1334
+ }, {
1335
+ type: VirtualDomElements.Input,
1336
+ className: InputBox,
1337
+ spellcheck: false,
1338
+ autocapitalize: 'off',
1339
+ autocorrect: 'off',
1340
+ placeholder: action.placeholder,
1341
+ onInput: action.command,
1342
+ name: Filter$2,
1343
+ value: action.value
1344
+ });
1345
+ // @ts-ignore
1346
+ dom[0].childCount++;
1347
+ dom.push(...getActionButtonVirtualDom({
1348
+ id: 'more filters',
1349
+ icon: Filter$1,
1350
+ command: 'more filters'
1351
+ }));
1352
+ return dom;
1087
1353
  };
1088
1354
 
1089
- /* eslint-disable @typescript-eslint/explicit-function-return-type */
1355
+ const getBadgeVirtualDom = (className, count) => {
1356
+ return [{
1357
+ type: VirtualDomElements.Div,
1358
+ className: `Badge ${className}`,
1359
+ childCount: 1
1360
+ }, text(`${count}`)];
1361
+ };
1090
1362
 
1091
- const create = rpcId => {
1363
+ const getChevronDownVirtualDom = (extraClassName = '') => {
1092
1364
  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();
1365
+ type: VirtualDomElements.Div,
1366
+ className: `${Chevron} MaskIconChevronDown ${extraClassName}`,
1367
+ childCount: 0
1368
+ };
1369
+ };
1370
+ const getChevronRightVirtualDom = (extraClassName = '') => {
1371
+ return {
1372
+ type: VirtualDomElements.Div,
1373
+ className: `${Chevron} MaskIconChevronRight ${extraClassName}`,
1374
+ childCount: 0
1375
+ };
1376
+ };
1377
+
1378
+ const getFileIconVirtualDom = icon => {
1379
+ return {
1380
+ type: VirtualDomElements.Img,
1381
+ className: FileIcon,
1382
+ src: icon,
1383
+ role: AriaRoles.None,
1384
+ childCount: 0
1385
+ };
1386
+ };
1387
+
1388
+ const Warning = 'warning';
1389
+
1390
+ const getProblemsIconVirtualDom = type => {
1391
+ // TODO use mergeclassnames
1392
+ if (type === Warning) {
1393
+ return {
1394
+ type: VirtualDomElements.Div,
1395
+ className: `${ProblemsIcon} ${ProblemsWarningIcon}`,
1396
+ childCount: 0
1397
+ };
1398
+ }
1399
+ return {
1400
+ type: VirtualDomElements.Div,
1401
+ className: `${ProblemsIcon} ${ProblemsErrorIcon}`,
1402
+ childCount: 0
1403
+ };
1404
+ };
1405
+
1406
+ // TODO compute detail message in getVisibleProblems
1407
+ const getProblemSourceDetail = (source, code) => {
1408
+ let message = '';
1409
+ if (source) {
1410
+ message += `${source}`;
1411
+ }
1412
+ if (code) {
1413
+ message += `(${code})`;
1414
+ }
1415
+ message += ' ';
1416
+ return message;
1417
+ };
1418
+
1419
+ const defaultIndent = 1;
1420
+ const getTreeItemIndent = depth => {
1421
+ return `${depth * defaultIndent}rem`;
1422
+ };
1423
+
1424
+ const emptyObject = {};
1425
+ const RE_PLACEHOLDER = /\{(PH\d+)\}/g;
1426
+ const i18nString = (key, placeholders = emptyObject) => {
1427
+ if (placeholders === emptyObject) {
1428
+ return key;
1429
+ }
1430
+ const replacer = (match, rest) => {
1431
+ return placeholders[rest];
1432
+ };
1433
+ return key.replaceAll(RE_PLACEHOLDER, replacer);
1434
+ };
1435
+
1436
+ const ClearFilters = 'Clear Filters';
1437
+ const Code = 'Code';
1438
+ const File = 'File';
1439
+ const Filter = 'Filter';
1440
+ const LineColumn = '[Ln {PH1}, Col {PH2}]';
1441
+ const Message = 'Message';
1442
+ const NoProblemsDetected = 'No problems have been detected in the workspace.';
1443
+ const NoResultsFoundWithProvidedFilterCriteria = 'No results found with provided filter criteria.';
1444
+ const Source = 'Source';
1445
+
1446
+ const noProblemsDetected = () => {
1447
+ return i18nString(NoProblemsDetected);
1448
+ };
1449
+ const atLineColumn = (line, column) => {
1450
+ return i18nString(LineColumn, {
1451
+ PH1: line,
1452
+ PH2: column
1453
+ });
1454
+ };
1455
+ const clearFilter = () => {
1456
+ return i18nString(ClearFilters);
1457
+ };
1458
+ const code = () => {
1459
+ return i18nString(Code);
1460
+ };
1461
+ const message = () => {
1462
+ return i18nString(Message);
1463
+ };
1464
+ const file = () => {
1465
+ return i18nString(File);
1466
+ };
1467
+ const filter = () => {
1468
+ return i18nString(Filter);
1469
+ };
1470
+ const source = () => {
1471
+ return i18nString(Source);
1472
+ };
1473
+ const noResultsFoundWithProvidedFilterCriteria = () => {
1474
+ return i18nString(NoResultsFoundWithProvidedFilterCriteria);
1475
+ };
1476
+
1477
+ const getProblemVirtualDom = problem => {
1478
+ const {
1479
+ message,
1480
+ rowIndex,
1481
+ columnIndex,
1482
+ isActive,
1483
+ uri,
1484
+ icon,
1485
+ source,
1486
+ relativePath,
1487
+ messageMatchIndex,
1488
+ filterValueLength,
1489
+ code,
1490
+ type,
1491
+ posInSet,
1492
+ setSize,
1493
+ level,
1494
+ listItemType,
1495
+ isCollapsed
1496
+ } = problem;
1497
+ let className = Problem;
1498
+ if (isActive) {
1499
+ className += ' ' + ProblemSelected;
1500
+ }
1501
+ if (listItemType === Expanded || listItemType === Collapsed) {
1502
+ return [{
1503
+ type: VirtualDomElements.Div,
1504
+ className,
1505
+ childCount: 5,
1506
+ paddingLeft: getTreeItemIndent(1),
1507
+ ariaPosInSet: posInSet,
1508
+ ariaSetSize: setSize,
1509
+ ariaLevel: level,
1510
+ ariaExpanded: !isCollapsed,
1511
+ ariaSelected: isActive,
1512
+ role: AriaRoles.TreeItem
1513
+ }, listItemType === Collapsed ? getChevronRightVirtualDom() : getChevronDownVirtualDom(), getFileIconVirtualDom(icon), text(uri), {
1514
+ type: VirtualDomElements.Div,
1515
+ className: LabelDetail,
1516
+ childCount: 1
1517
+ }, text(relativePath), ...getBadgeVirtualDom(ProblemBadge, problem.count)];
1518
+ }
1519
+ const lineColumn = atLineColumn(rowIndex, columnIndex);
1520
+ const label = {
1521
+ type: VirtualDomElements.Div,
1522
+ className: Label,
1523
+ childCount: 1
1524
+ };
1525
+ /**
1526
+ * @type {any}
1527
+ */
1528
+ const dom = [{
1529
+ type: VirtualDomElements.Div,
1530
+ className,
1531
+ childCount: 3,
1532
+ paddingLeft: getTreeItemIndent(2),
1533
+ ariaPosInSet: posInSet,
1534
+ ariaSetSize: setSize,
1535
+ ariaLevel: level,
1536
+ ariaSelected: isActive,
1537
+ role: AriaRoles.TreeItem
1538
+ }, getProblemsIconVirtualDom(type), label];
1539
+ if (filterValueLength) {
1540
+ const before = message.slice(0, messageMatchIndex);
1541
+ const middle = message.slice(messageMatchIndex, messageMatchIndex + filterValueLength);
1542
+ const after = message.slice(messageMatchIndex + filterValueLength);
1543
+ label.childCount += 2;
1544
+ dom.push(text(before), {
1545
+ type: VirtualDomElements.Div,
1546
+ className: Highlight,
1547
+ childCount: 1
1548
+ }, text(middle), text(after));
1549
+ } else {
1550
+ dom.push(text(message));
1551
+ }
1552
+ dom.push({
1553
+ type: VirtualDomElements.Span,
1554
+ className: ProblemAt,
1555
+ childCount: 2
1556
+ }, text(getProblemSourceDetail(source, code)), text(lineColumn));
1557
+ return dom;
1558
+ };
1559
+
1560
+ const getProblemsListVirtualDom = problems => {
1561
+ const dom = [{
1562
+ type: VirtualDomElements.Div,
1563
+ className: ProblemsList,
1564
+ childCount: problems.length,
1565
+ role: AriaRoles.Tree,
1566
+ ariaLabel: 'Problems Tree' // TODO use i18n string
1567
+ }, ...problems.flatMap(getProblemVirtualDom)];
1568
+ return dom;
1569
+ };
1570
+
1571
+ const getProblemsNoProblemsFoundVirtualDom = filterValue => {
1572
+ // TODO avoid mutation
1573
+ const dom = [];
1574
+ dom.push({
1575
+ type: VirtualDomElements.Div,
1576
+ className: Message$1,
1577
+ childCount: 1
1578
+ });
1579
+ if (filterValue) {
1580
+ dom[0].childCount += 2;
1581
+ dom.push({
1582
+ type: VirtualDomElements.Span,
1583
+ childCount: 1
1584
+ }, text(noResultsFoundWithProvidedFilterCriteria()), {
1585
+ type: VirtualDomElements.A,
1586
+ className: MessageAction,
1587
+ childCount: 1,
1588
+ onClick: HandleClearFilterClick
1589
+ }, text(clearFilter()), text('.'));
1590
+ } else {
1591
+ dom.push(text(noProblemsDetected()));
1592
+ }
1593
+ return dom;
1594
+ };
1595
+
1596
+ const getClassName = isEven => {
1597
+ if (isEven) {
1598
+ return ProblemsTableRow;
1599
+ }
1600
+ return mergeClassNames(ProblemsTableRow, ProblemsTableRowOdd);
1601
+ };
1602
+ const getProblemsTableRowVirtualDom = problem => {
1603
+ const {
1604
+ code,
1605
+ source,
1606
+ uri,
1607
+ message,
1608
+ isEven,
1609
+ type
1610
+ } = problem;
1611
+ // TODO problems are grouped by uri, depending
1612
+ // on which renderer is used the data needs to look different
1613
+ if (!message) {
1614
+ return [];
1615
+ }
1616
+ const dom = [{
1617
+ type: VirtualDomElements.Div,
1618
+ className: getClassName(isEven),
1619
+ childCount: 5
1620
+ }, {
1621
+ type: VirtualDomElements.Div,
1622
+ className: ProblemsTableRowItem,
1623
+ childCount: 1
1624
+ }, getProblemsIconVirtualDom(type), {
1625
+ type: VirtualDomElements.Div,
1626
+ className: ProblemsTableRowItem,
1627
+ childCount: 1
1628
+ }, text(getProblemSourceDetail(source, code)), {
1629
+ type: VirtualDomElements.Div,
1630
+ className: ProblemsTableRowItem,
1631
+ childCount: 1
1632
+ }, text(message), {
1633
+ type: VirtualDomElements.Div,
1634
+ className: ProblemsTableRowItem,
1635
+ childCount: 1
1636
+ }, text(uri), {
1637
+ type: VirtualDomElements.Div,
1638
+ className: ProblemsTableRowItem,
1639
+ childCount: 1
1640
+ }, text(source)];
1641
+ return dom;
1642
+ };
1643
+
1644
+ const getProblemsTableBodyVirtualDom = problems => {
1645
+ const dom = [{
1646
+ type: VirtualDomElements.Div,
1647
+ className: ProblemsTableBody,
1648
+ childCount: problems.length
1649
+ }, ...problems.flatMap(getProblemsTableRowVirtualDom)];
1650
+ return dom;
1651
+ };
1652
+
1653
+ const getProblemsTableHeaderVirtualDom = () => {
1654
+ const textCode = code();
1655
+ const textSource = source();
1656
+ const textMessage = message();
1657
+ const textFile = file();
1658
+ const dom = [{
1659
+ type: VirtualDomElements.Div,
1660
+ className: ProblemsTableHeader,
1661
+ childCount: 1
1662
+ }, {
1663
+ type: VirtualDomElements.Div,
1664
+ className: ProblemsTableRow,
1665
+ childCount: 5
1666
+ }, {
1667
+ type: VirtualDomElements.Div,
1668
+ className: ProblemsTableRowItem,
1669
+ childCount: 0
1670
+ }, {
1671
+ type: VirtualDomElements.Div,
1672
+ className: ProblemsTableRowItem,
1673
+ childCount: 1
1674
+ }, text(textCode), {
1675
+ type: VirtualDomElements.Div,
1676
+ className: ProblemsTableRowItem,
1677
+ childCount: 1
1678
+ }, text(textMessage), {
1679
+ type: VirtualDomElements.Div,
1680
+ className: ProblemsTableRowItem,
1681
+ childCount: 1
1682
+ }, text(textFile), {
1683
+ type: VirtualDomElements.Div,
1684
+ className: ProblemsTableRowItem,
1685
+ childCount: 1
1686
+ }, text(textSource)];
1687
+ return dom;
1688
+ };
1689
+
1690
+ const getProblemsTableVirtualDom = problems => {
1691
+ const dom = [{
1692
+ type: VirtualDomElements.Div,
1693
+ className: ProblemsTable,
1694
+ childCount: 2
1695
+ }, ...getProblemsTableHeaderVirtualDom(), ...getProblemsTableBodyVirtualDom(problems)];
1696
+ return dom;
1697
+ };
1698
+
1699
+ const getProblemsVirtualDom$1 = (viewMode, problems, filterValue) => {
1700
+ if (problems.length === 0) {
1701
+ return getProblemsNoProblemsFoundVirtualDom(filterValue);
1702
+ }
1703
+ if (viewMode === Table) {
1704
+ return getProblemsTableVirtualDom(problems);
1705
+ }
1706
+ const dom = getProblemsListVirtualDom(problems);
1707
+ return dom;
1708
+ };
1709
+
1710
+ const getProblemsVirtualDom = (viewMode, problems, filterValue, isSmall) => {
1711
+ // TODO avoid mutation
1712
+ const dom = [];
1713
+ dom.push({
1714
+ type: VirtualDomElements.Div,
1715
+ className: mergeClassNames(Viewlet, Problems),
1716
+ tabIndex: 0,
1717
+ onPointerDown: HandlePointerDown,
1718
+ onContextMenu: HandleContextMenu,
1719
+ onBlur: HandleBlur,
1720
+ childCount: 1
1721
+ });
1722
+ if (isSmall) {
1723
+ dom[0].childCount++;
1724
+ dom.push(...getProblemsFilterVirtualDom({
1725
+ command: HandleFilterInput,
1726
+ placeholder: filter(),
1727
+ value: ''
1728
+ }));
1729
+ }
1730
+ dom.push(...getProblemsVirtualDom$1(viewMode, problems, filterValue));
1731
+ return dom;
1732
+ };
1733
+
1734
+ const matchesFilterValue = (string, filterValueLower) => {
1735
+ if (filterValueLower) {
1736
+ return string.toLowerCase().indexOf(filterValueLower);
1737
+ }
1738
+ return 0;
1739
+ };
1740
+ const getListItemType = (listItemType, isCollapsed) => {
1741
+ if (listItemType === Item) {
1742
+ return Item;
1743
+ }
1744
+ if (isCollapsed) {
1745
+ return Collapsed;
1746
+ }
1747
+ return Expanded;
1748
+ };
1749
+ const filterProblems = (problems, collapsedUris, filterValue) => {
1750
+ const filterValueLower = filterValue.toLowerCase();
1751
+ const filtered = [];
1752
+ for (const problem of problems) {
1753
+ const uriMatchIndex = matchesFilterValue(problem.uri, filterValueLower);
1754
+ const sourceMatchIndex = matchesFilterValue(problem.source, filterValueLower);
1755
+ const messageMatchIndex = matchesFilterValue(problem.message, filterValueLower);
1756
+ if (uriMatchIndex === -1 && sourceMatchIndex === -1 && messageMatchIndex === -1) {
1757
+ continue;
1758
+ }
1759
+ const isCollapsed = collapsedUris.includes(problem.uri);
1760
+ if (isCollapsed && problem.listItemType === Item) {
1761
+ continue;
1111
1762
  }
1763
+ filtered.push({
1764
+ ...problem,
1765
+ uriMatchIndex,
1766
+ sourceMatchIndex,
1767
+ messageMatchIndex,
1768
+ listItemType: getListItemType(problem.listItemType, isCollapsed),
1769
+ isCollapsed
1770
+ });
1771
+ }
1772
+ return filtered;
1773
+ };
1774
+
1775
+ const getFileNameIcon = file => {
1776
+ return '';
1777
+ };
1778
+
1779
+ const getIcon = uri => {
1780
+ if (!uri) {
1781
+ return '';
1782
+ }
1783
+ return getFileNameIcon();
1784
+ };
1785
+ const getVisibleProblems = (problems, collapsedUris, focusedIndex, filterValue) => {
1786
+ array(problems);
1787
+ array(collapsedUris);
1788
+ number(focusedIndex);
1789
+ string(filterValue);
1790
+ const visibleItems = [];
1791
+ const filterValueLength = filterValue.length;
1792
+ const filtered = filterProblems(problems, collapsedUris, filterValue);
1793
+ for (let i = 0; i < filtered.length; i++) {
1794
+ const problem = filtered[i];
1795
+ visibleItems.push({
1796
+ ...problem,
1797
+ isEven: i % 2 === 0,
1798
+ isActive: i === focusedIndex,
1799
+ icon: getIcon(problem.uri),
1800
+ filterValueLength
1801
+ });
1802
+ }
1803
+ return visibleItems;
1804
+ };
1805
+
1806
+ const renderItems = (oldState, newState) => {
1807
+ const visible = getVisibleProblems(newState.problems, newState.collapsedUris, newState.focusedIndex, newState.filterValue);
1808
+ const isSmall = newState.width <= newState.smallWidthBreakPoint;
1809
+ const dom = getProblemsVirtualDom(newState.viewMode, visible, newState.filterValue, isSmall);
1810
+ return ['Viewlet.setDom2', dom];
1811
+ };
1812
+
1813
+ const getRenderer = diffType => {
1814
+ switch (diffType) {
1815
+ case RenderItems:
1816
+ return renderItems;
1817
+ default:
1818
+ throw new Error('unknown renderer');
1819
+ }
1820
+ };
1821
+
1822
+ const applyRender = (oldState, newState, diffResult) => {
1823
+ const commands = [];
1824
+ for (const item of diffResult) {
1825
+ const fn = getRenderer(item);
1826
+ commands.push(fn(oldState, newState));
1827
+ }
1828
+ return commands;
1829
+ };
1830
+
1831
+ const render2 = (uid, diffResult) => {
1832
+ const {
1833
+ oldState,
1834
+ newState
1835
+ } = get(uid);
1836
+ set(uid, newState, newState);
1837
+ const commands = applyRender(oldState, newState, diffResult);
1838
+ return commands;
1839
+ };
1840
+
1841
+ const resize = (state, dimensions) => {
1842
+ return {
1843
+ ...state,
1844
+ ...dimensions
1112
1845
  };
1113
1846
  };
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
1847
 
1121
- const {
1122
- set} = RendererWorker;
1848
+ const saveState = state => {
1849
+ const {
1850
+ viewMode,
1851
+ filterValue,
1852
+ collapsedUris
1853
+ } = state;
1854
+ return {
1855
+ viewMode,
1856
+ filterValue,
1857
+ collapsedUris
1858
+ };
1859
+ };
1860
+
1861
+ const commandMap = {
1862
+ 'Problems.copyMessage': copyMessage,
1863
+ 'Problems.create': create,
1864
+ 'Problems.diff2': diff2,
1865
+ 'Problems.focusIndex': focusIndex,
1866
+ 'Problems.getKeyBindings': getKeyBindings,
1867
+ 'Problems.handleArrowLeft': wrapCommand(handleArrowLeft),
1868
+ 'Problems.handleArrowRight': wrapCommand(handleArrowRight),
1869
+ 'Problems.initialize': initialize,
1870
+ 'Problems.render2': render2,
1871
+ 'Problems.resize': resize,
1872
+ 'Problems.saveState': saveState,
1873
+ 'Problems.terminate': terminate
1874
+ };
1123
1875
 
1124
1876
  const listen = async () => {
1125
1877
  const rpc = await WebWorkerRpcClient.create({
1126
1878
  commandMap: commandMap
1127
1879
  });
1128
- set(rpc);
1880
+ set$1(rpc);
1129
1881
  };
1130
1882
 
1131
1883
  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.2.0",
4
4
  "description": "Problems View Worker",
5
5
  "repository": {
6
6
  "type": "git",