|
@@ -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);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|