diff --git a/app/assets/javascripts/editor/editor.js.erb b/app/assets/javascripts/editor/editor.js.erb
index 2c0696e4..2e64ab8e 100644
--- a/app/assets/javascripts/editor/editor.js.erb
+++ b/app/assets/javascripts/editor/editor.js.erb
@@ -106,9 +106,12 @@ var CodeOceanEditor = {
},
showOutput: function (event) {
- event.preventDefault();
- this.showOutputBar();
- $('body').scrollTo($(event.target).attr('href'));
+ const target = $(event.target).attr('href');
+ if (target !== "#") {
+ event.preventDefault();
+ this.showOutputBar();
+ $('body').scrollTo($(event.target).attr('href'));
+ }
},
renderProgressBar: function (score, maximum_score) {
@@ -472,15 +475,58 @@ var CodeOceanEditor = {
if (errorMessagesToShow.length > 1) {
// delete all current elements
targetNode.text('');
- // create a new list and appand each element
+ // create a new list and append each element
const ul = document.createElement("ul");
ul.setAttribute('class', 'error_messages_list');
- errorMessagesToShow.forEach(function (item) {
- var li = document.createElement("li");
- var text = $.parseHTML(item);
- $(li).append(text);
- ul.append(li);
- })
+
+ // Extract detailed linter results
+ if (result.file_role === 'teacher_defined_linter') {
+ const detailed_linter_results = result.detailed_linter_results;
+ const severity_groups = detailed_linter_results.reduce(function(map, obj) {
+ map[obj.severity] = map[obj.severity] || []
+ map[obj.severity].push(obj);
+ return map;
+ }, {});
+
+ for (let severity in severity_groups) {
+ if (!severity_groups.hasOwnProperty(severity)) {
+ continue;
+ }
+ const linter_results = severity_groups[severity]
+
+ const li = document.createElement("li");
+ const text = $.parseHTML(`${severity}:`);
+ $(li).append(text);
+ ul.append(li);
+
+ const sub_ul = document.createElement("ul");
+ sub_ul.setAttribute('class', 'error_messages_list');
+ for (let check_run of linter_results) {
+ const sub_li = document.createElement("li");
+
+ let scope = '';
+ if (check_run.scope) {
+ scope = `, ${check_run.scope}()`;
+ }
+ const context = `${check_run.file_name}: ${check_run.line}${scope}`;
+ const line_link = `${context}`;
+ const message = `${check_run.name}: ${check_run.result} (${line_link})`;
+ const sub_text = $.parseHTML(message);
+ $(sub_li).append(sub_text).on("click", "a", this.jumpToSourceLine.bind(this));
+ sub_ul.append(sub_li);
+ }
+ li.append(sub_ul);
+ }
+
+ // Just show standard results for normal test results
+ } else {
+ errorMessagesToShow.forEach(function (item) {
+ var li = document.createElement("li");
+ var text = $.parseHTML(item);
+ $(li).append(text);
+ ul.append(li);
+ })
+ }
targetNode.append(ul);
} else {
targetNode.html(errorMessagesToShow.join(''));