浏览代码

Make errors clickable

Sebastien Lebreton 5 年之前
父节点
当前提交
792b204276
共有 3 个文件被更改,包括 51 次插入17 次删除
  1. 3 0
      Playground/css/index.css
  2. 6 3
      Playground/js/monacoCreator.js
  3. 42 14
      Playground/js/utils.js

+ 3 - 0
Playground/css/index.css

@@ -621,6 +621,9 @@ body {
     border-radius: 5px;
     color:white;
 }
+#errorZone #gotoLocation {
+    cursor: pointer;
+}
 #errorZone button {
     position:absolute;
     top : 3px;

+ 6 - 3
Playground/js/monacoCreator.js

@@ -169,10 +169,13 @@ class MonacoCreator {
 
             diagnostics.forEach(function(diagset) {
                 if (diagset.length) {
-                    var diagnostic = diagset[0];
-                    var position = model.getPositionAt(diagnostic.start);
+                    const diagnostic = diagset[0];
+                    const position = model.getPositionAt(diagnostic.start);
                     
-                    throw new Error(`Line ${position.lineNumber}:${position.column} - ${diagnostic.messageText}`);
+                    const error = new EvalError(diagnostic.messageText);
+                    error.lineNumber = position.lineNumber;
+                    error.columnNumber = position.column;
+                    throw error;
                 }
             });
 

+ 42 - 14
Playground/js/utils.js

@@ -18,29 +18,42 @@ class Utils {
         this.setToMultipleID('safemodeToggle', 'innerHTML', 'Safe mode <i class="fa fa-check-square" aria-hidden="true"></i>');
     };
 
+    toLocationError(errorMessage, errorEvent) {
+        // Do we have any location info?
+        if (errorEvent.hasOwnProperty('lineNumber') && errorEvent.hasOwnProperty('columnNumber'))
+            return errorEvent;
+
+        // Else try to parse the stack to retrieve location...
+        var regEx = /\(.+:(\d+):(\d+)\)\n/g;
+        var match = regEx.exec(errorEvent.stack);
+        if (match) {
+            var error = new EvalError(errorMessage);
+            error.lineNumber = match[1];
+            error.columnNumber = match[2];
+            return error;
+        }
+
+        // Not an error with proper location
+        return null;        
+    }
+
     /**
      * Used to show error messages
      * @param {String} errorMessage 
      * @param {String} errorEvent 
      */
     showError(errorMessage, errorEvent) {
-        var errorContent =
-            '<div class="alert alert-error"><button type="button" class="close" data-dismiss="alert">&times;</button>';
-        if (errorEvent) {
-            var regEx = /\(.+:(\d+):(\d+)\)\n/g;
-
-            var match = regEx.exec(errorEvent.stack);
-            if (match) {
-                errorContent += "Line ";
-                var lineNumber = match[1];
-                var columnNumber = match[2];
+        let errorContent = '<div class="alert alert-error"><button type="button" class="close" data-dismiss="alert">&times;</button>';
 
-                errorContent += lineNumber + ':' + columnNumber + ' - ';
-            }
+        const locationError = this.toLocationError(errorMessage, errorEvent);
+        if (locationError == null) {
+            // use a regular message
+            errorContent += `${errorMessage}</div>`;
+        } else {
+            // we have location information
+            errorContent += `<span id="gotoLocation">Line ${locationError.lineNumber} : ${locationError.columnNumber} - ${errorMessage}</span></div>`;
         }
 
-        errorContent += errorMessage + '</div>';
-
         document.getElementById("errorZone").style.display = 'block';
         document.getElementById("errorZone").innerHTML = errorContent;
 
@@ -48,6 +61,21 @@ class Utils {
         document.getElementById("errorZone").querySelector('.close').addEventListener('click', function () {
             document.getElementById("errorZone").style.display = 'none';
         });
+
+        // Go To Location
+        const gotoLocation = document.getElementById("gotoLocation");
+        const jsEditor = this.parent.monacoCreator.jsEditor;
+        if (gotoLocation) {
+            gotoLocation.addEventListener('click', function () {
+                const position = { 
+                    lineNumber: Number(locationError.lineNumber), 
+                    column: Number(locationError.columnNumber)
+                };
+
+                jsEditor.revealPositionInCenter(position, monaco.editor.ScrollType.Smooth);
+                jsEditor.setPosition(position);
+            });
+        }
     };
 
     /**