Răsfoiți Sursa

feat: support error message display

田丰 10 luni în urmă
părinte
comite
7906fb1212

+ 5 - 1
packages/semi-foundation/jsonViewer/jsonViewer.scss

@@ -196,5 +196,9 @@ $module: #{$prefix}-json-viewer;
         cursor: pointer;
     }
 
-
+    &-error {
+        text-decoration: underline wavy var(--semi-color-danger);
+        text-decoration-thickness: 1px;
+        text-underline-position: under;
+    }
 }

+ 1 - 1
packages/semi-json-viewer-core/src/service/parse.ts

@@ -251,7 +251,7 @@ export function parseJson(jsonModel: JSONModel) {
         skipUntil: Json.SyntaxKind[] = []
     ): T | undefined {
         let start = scanner.getTokenOffset();
-        let end = scanner.getPosition() + scanner.getTokenLength();
+        let end = scanner.getTokenOffset() + scanner.getTokenLength();
         if (start === end && start > 0) {
             start--;
             while (start > 0 && /\s/.test(text.charAt(start))) {

+ 41 - 0
packages/semi-json-viewer-core/src/view/error/errorWidget.ts

@@ -0,0 +1,41 @@
+import { Diagnostic } from '../../service/jsonTypes';
+import { Emitter, getEmitter } from '../../common/emitter';
+import { View } from '../view';
+import { GlobalEvents } from '../../common/emitterEvents';
+
+export class ErrorWidget {
+    private _view: View;
+    private emitter: Emitter<GlobalEvents> = getEmitter();
+    constructor(view: View) {
+        this._view = view;
+        this._attachEventListeners();
+    }
+
+    private _attachEventListeners() {
+        this.emitter.on('problemsChanged', (result: any) => {
+            this.renderErrorLine(result.problems);
+        });
+    }
+
+    private renderErrorLine(problems: Diagnostic[]) {
+        problems.forEach((problem: Diagnostic) => {
+            const { start, end } = problem.range;
+            const errMessage = problem.message;
+            this.findDomByPos(start, end, errMessage);
+        });
+    }
+
+    private findDomByPos(start: { lineNumber: number; column: number }, end: { lineNumber: number; column: number }, errMessage: string) {
+        const line = this._view.getLineElement(start.lineNumber);
+        if (!line) return;
+        let offset = 1;
+        for (let i = 0; i < line.children.length; i++) {
+            const child = line.children[i];
+            offset += child.textContent?.length || 0;
+            if (offset > start.column && offset <= end.column) {
+                const className = 'semi-json-viewer-error';
+                child.classList.add(className);
+            }
+        }
+    }
+}

+ 3 - 0
packages/semi-json-viewer-core/src/view/view.ts

@@ -15,6 +15,7 @@ import { ScalingCellSizeAndPositionManager } from './virtualized/ScalingCellSize
 import { CompleteWidget } from './complete/completeWidget';
 import { HoverWidget } from './hover/hoverWidget';
 import { GlobalEvents } from '../common/emitterEvents';
+import { ErrorWidget } from './error/errorWidget';
 //TODO 实现ViewModel抽离代码
 
 /**
@@ -45,6 +46,7 @@ export class View {
     private _foldWidget: FoldWidget;
     private _completeWidget: CompleteWidget;
     private _hoverWidget: HoverWidget;
+    private _errorWidget: ErrorWidget;
     private _jsonWorkerManager: JsonWorkerManager = getJsonWorkerManager();
     private _tokenizationJsonModelPart: TokenizationJsonModelPart;
     private _scalingCellSizeAndPositionManager: ScalingCellSizeAndPositionManager;
@@ -79,6 +81,7 @@ export class View {
         this._editWidget = new EditWidget(this, this._jsonModel, this._selectionModel, this._foldingModel);
         this._completeWidget = new CompleteWidget(this, this._jsonModel, this._selectionModel);
         this._hoverWidget = new HoverWidget(this);
+        this._errorWidget = new ErrorWidget(this);
 
         this._tokenizationJsonModelPart = new TokenizationJsonModelPart(this._jsonModel);