@douyinfe/semi-json-viewer-core 2.95.1 → 2.96.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.
Files changed (2) hide show
  1. package/lib/index.js +153 -31
  2. package/package.json +2 -2
package/lib/index.js CHANGED
@@ -363,45 +363,157 @@ var SelectionModel = class {
363
363
  toViewPosition() {
364
364
  const selection = window.getSelection();
365
365
  if (!selection) return;
366
- const range = new Range();
367
366
  if (this.isSelectedAll) {
368
- range.setStartBefore(this._view.scrollDom.firstChild);
369
- range.setEndAfter(this._view.scrollDom.lastChild);
367
+ const firstChild = this._view.scrollDom.firstChild;
368
+ const lastChild = this._view.scrollDom.lastChild;
369
+ if (!firstChild || !lastChild) {
370
+ selection.removeAllRanges();
371
+ return;
372
+ }
373
+ const range2 = new Range();
374
+ range2.setStartBefore(firstChild);
375
+ range2.setEndAfter(lastChild);
370
376
  selection.removeAllRanges();
371
- selection.addRange(range);
377
+ selection.addRange(range2);
378
+ return;
379
+ }
380
+ if (!this.isCollapsed) {
381
+ this._restoreMultiSelection(selection);
372
382
  return;
373
383
  }
374
384
  const row = this._jsonModel.lastChangeBufferPos.lineNumber;
375
385
  const col = this._jsonModel.lastChangeBufferPos.column - 1;
376
- if (this.isSelecting) {
386
+ const firstVisibleLineElement = this._view.scrollDom.firstElementChild;
387
+ const lastVisibleLineElement = this._view.scrollDom.lastElementChild;
388
+ if (!firstVisibleLineElement || !lastVisibleLineElement) {
389
+ selection.removeAllRanges();
390
+ return;
377
391
  }
378
392
  const lineElement = this._view.getLineElement(row);
379
- if (!lineElement) return;
380
- if (col === 0) {
381
- range.setStart(lineElement, 0);
382
- range.setEnd(lineElement, 0);
393
+ const range = new Range();
394
+ if (!lineElement) {
395
+ const firstVisibleLineNumber = Number(firstVisibleLineElement.dataset.lineNumber || 0);
396
+ const lastVisibleLineNumber = Number(lastVisibleLineElement.dataset.lineNumber || 0);
397
+ if (row < firstVisibleLineNumber) {
398
+ range.setStartBefore(firstVisibleLineElement);
399
+ range.setEndBefore(firstVisibleLineElement);
400
+ } else if (row > lastVisibleLineNumber) {
401
+ range.setStartAfter(lastVisibleLineElement);
402
+ range.setEndAfter(lastVisibleLineElement);
403
+ } else {
404
+ selection.removeAllRanges();
405
+ return;
406
+ }
383
407
  } else {
384
- const walker = document.createTreeWalker(
385
- lineElement,
386
- NodeFilter.SHOW_TEXT,
387
- null
388
- );
389
- let node = walker.nextNode();
390
- let currentOffset = 0;
391
- while (node) {
392
- const nodeLength = node.length;
393
- if (currentOffset + nodeLength >= col) {
394
- range.setStart(node, col - currentOffset);
395
- range.setEnd(node, col - currentOffset);
396
- break;
408
+ const position = this._findPositionInLine(lineElement, col);
409
+ if (position) {
410
+ range.setStart(position.node, position.offset);
411
+ range.setEnd(position.node, position.offset);
412
+ } else {
413
+ range.setStart(lineElement, 0);
414
+ range.setEnd(lineElement, 0);
415
+ }
416
+ }
417
+ selection.removeAllRanges();
418
+ selection.addRange(range);
419
+ }
420
+ /**
421
+ * Restore multi-selection (non-collapsed selection) after DOM re-render
422
+ */
423
+ _restoreMultiSelection(selection) {
424
+ var _a2;
425
+ const firstVisibleLineElement = this._view.scrollDom.firstElementChild;
426
+ const lastVisibleLineElement = this._view.scrollDom.lastElementChild;
427
+ if (!firstVisibleLineElement || !lastVisibleLineElement) {
428
+ selection.removeAllRanges();
429
+ return;
430
+ }
431
+ const startLineElement = this._view.getLineElement(this.startRow);
432
+ const endLineElement = this._view.getLineElement(this.endRow);
433
+ const firstVisibleLineNumber = Number(firstVisibleLineElement.dataset.lineNumber || 0);
434
+ const lastVisibleLineNumber = Number(lastVisibleLineElement.dataset.lineNumber || 0);
435
+ const isSelectionAboveViewport = this.endRow < firstVisibleLineNumber;
436
+ const isSelectionBelowViewport = this.startRow > lastVisibleLineNumber;
437
+ if (isSelectionAboveViewport) {
438
+ const range2 = new Range();
439
+ range2.setStartBefore(firstVisibleLineElement);
440
+ range2.setEndBefore(firstVisibleLineElement);
441
+ selection.removeAllRanges();
442
+ selection.addRange(range2);
443
+ return;
444
+ }
445
+ if (isSelectionBelowViewport) {
446
+ const range2 = new Range();
447
+ range2.setStartAfter(lastVisibleLineElement);
448
+ range2.setEndAfter(lastVisibleLineElement);
449
+ selection.removeAllRanges();
450
+ selection.addRange(range2);
451
+ return;
452
+ }
453
+ const range = new Range();
454
+ if (startLineElement) {
455
+ const startPos = this._findPositionInLine(startLineElement, this.startCol - 1);
456
+ if (startPos) {
457
+ range.setStart(startPos.node, startPos.offset);
458
+ } else {
459
+ range.setStart(startLineElement, 0);
460
+ }
461
+ } else {
462
+ range.setStartBefore(firstVisibleLineElement);
463
+ }
464
+ if (endLineElement) {
465
+ const endPos = this._findPositionInLine(endLineElement, this.endCol - 1);
466
+ if (endPos) {
467
+ range.setEnd(endPos.node, endPos.offset);
468
+ } else {
469
+ const lastChild = endLineElement.lastChild;
470
+ if (lastChild) {
471
+ if (lastChild.nodeType === Node.TEXT_NODE) {
472
+ range.setEnd(lastChild, ((_a2 = lastChild.textContent) == null ? void 0 : _a2.length) || 0);
473
+ } else {
474
+ range.setEnd(endLineElement, endLineElement.childNodes.length);
475
+ }
397
476
  }
398
- currentOffset += nodeLength;
399
- node = walker.nextNode();
400
477
  }
478
+ } else {
479
+ range.setEndAfter(lastVisibleLineElement);
401
480
  }
402
481
  selection.removeAllRanges();
403
482
  selection.addRange(range);
404
483
  }
484
+ /**
485
+ * Find the text node and offset for a given column position in a line element
486
+ */
487
+ _findPositionInLine(lineElement, col) {
488
+ if (col === 0) {
489
+ const walker2 = document.createTreeWalker(lineElement, NodeFilter.SHOW_TEXT, null);
490
+ const firstNode = walker2.nextNode();
491
+ if (firstNode) {
492
+ return { node: firstNode, offset: 0 };
493
+ }
494
+ return null;
495
+ }
496
+ const walker = document.createTreeWalker(lineElement, NodeFilter.SHOW_TEXT, null);
497
+ let node = walker.nextNode();
498
+ let currentOffset = 0;
499
+ while (node) {
500
+ const nodeLength = node.length;
501
+ if (currentOffset + nodeLength >= col) {
502
+ return { node, offset: col - currentOffset };
503
+ }
504
+ currentOffset += nodeLength;
505
+ node = walker.nextNode();
506
+ }
507
+ walker.currentNode = lineElement;
508
+ let lastNode = null;
509
+ while (walker.nextNode()) {
510
+ lastNode = walker.currentNode;
511
+ }
512
+ if (lastNode) {
513
+ return { node: lastNode, offset: lastNode.length };
514
+ }
515
+ return null;
516
+ }
405
517
  toLastPosition() {
406
518
  this.isCollapsed = true;
407
519
  this.isSelectedAll = false;
@@ -2878,6 +2990,9 @@ var CompletionItem;
2878
2990
  })(CompletionItem || (CompletionItem = {}));
2879
2991
 
2880
2992
  // src/service/parse.ts
2993
+ function getNodeValue2(node) {
2994
+ return Json.getNodeValue(node);
2995
+ }
2881
2996
  function getNodePath2(node) {
2882
2997
  return Json.getNodePath(node);
2883
2998
  }
@@ -4434,11 +4549,11 @@ var View = class {
4434
4549
  container.appendChild(highlightedSpan);
4435
4550
  } else {
4436
4551
  if (((_a2 = this._options) == null ? void 0 : _a2.readOnly) && this._tryApplyCustomRender(token.scopes, content)) {
4437
- const offset = this._jsonModel.getOffsetAt(lineNumber, (start + end) / 2);
4552
+ const offset = this._jsonModel.getOffsetAt(lineNumber, start + 1);
4438
4553
  const node = (_b = this._root) == null ? void 0 : _b.getNodeFromOffset(offset);
4439
- const path = getNodePath2(node);
4554
+ const path = node ? getNodePath2(node) : [];
4440
4555
  const pathChain = getPathChain(path);
4441
- const customElement = this._renderCustomToken(content, this._customRenderRule, token, pathChain);
4556
+ const customElement = this._renderCustomToken(content, this._customRenderRule, token, pathChain, node);
4442
4557
  if (customElement instanceof HTMLElement) {
4443
4558
  container.appendChild(customElement);
4444
4559
  continue;
@@ -4502,10 +4617,10 @@ var View = class {
4502
4617
  }
4503
4618
  return false;
4504
4619
  }
4505
- isMatch(content, pathChain, rule) {
4620
+ isMatch(content, typedValue, pathChain, tokenType, rule) {
4506
4621
  const match = rule.match;
4507
4622
  if (typeof match === "function") {
4508
- return match(content, pathChain);
4623
+ return match(typedValue, pathChain, tokenType);
4509
4624
  } else if (typeof match === "string") {
4510
4625
  return match === content;
4511
4626
  } else if (match instanceof RegExp) {
@@ -4513,10 +4628,17 @@ var View = class {
4513
4628
  }
4514
4629
  return false;
4515
4630
  }
4516
- _renderCustomToken(content, rule, token, pathChain) {
4631
+ _renderCustomToken(content, rule, token, pathChain, node) {
4517
4632
  const realContent = content.replace(/^"|"$/g, "");
4633
+ const tokenType = token.scopes === TOKEN_PROPERTY_NAME ? "key" : "value";
4634
+ let typedValue = realContent;
4635
+ if (token.scopes === TOKEN_VALUE_NUMBER || token.scopes === TOKEN_VALUE_BOOLEAN || token.scopes === TOKEN_VALUE_NULL) {
4636
+ if (node) {
4637
+ typedValue = getNodeValue2(node);
4638
+ }
4639
+ }
4518
4640
  for (const item of rule) {
4519
- if (this.isMatch(realContent, pathChain, item)) {
4641
+ if (this.isMatch(realContent, typedValue, pathChain, tokenType, item)) {
4520
4642
  const element = item.render(content);
4521
4643
  return element;
4522
4644
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@douyinfe/semi-json-viewer-core",
3
- "version": "2.95.1",
3
+ "version": "2.96.0",
4
4
  "description": "",
5
5
  "main": "lib/index.js",
6
6
  "module": "lib/index.js",
@@ -53,5 +53,5 @@
53
53
  ],
54
54
  "author": "",
55
55
  "license": "MIT",
56
- "gitHead": "2a3f86116f503105a95f32045127b82a4f03c08d"
56
+ "gitHead": "25977da675cef6d8dd70e92531b2441030991952"
57
57
  }