Skip to content

Commit

Permalink
Always init tutor links
Browse files Browse the repository at this point in the history
  • Loading branch information
jorg-vr committed Oct 19, 2023
1 parent 95c31e7 commit dfd9b11
Show file tree
Hide file tree
Showing 6 changed files with 116 additions and 107 deletions.
69 changes: 69 additions & 0 deletions app/assets/javascripts/file_viewer.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
import { showInfoModal } from "./modal";
import { fetch } from "utilities";
import { html } from "lit";

Check warning on line 3 in app/assets/javascripts/file_viewer.ts

View check run for this annotation

Codecov / codecov/patch

app/assets/javascripts/file_viewer.ts#L1-L3

Added lines #L1 - L3 were not covered by tests

function showInlineFile(name: string, content: string): void {
showInfoModal(name, html`<div class='code'>${content}</div>`);

Check warning on line 6 in app/assets/javascripts/file_viewer.ts

View check run for this annotation

Codecov / codecov/patch

app/assets/javascripts/file_viewer.ts#L5-L6

Added lines #L5 - L6 were not covered by tests
}

function showRealFile(name: string, activityPath: string, filePath: string): void {
const path = activityPath + "/" + filePath;
const random = Math.floor(Math.random() * 10000 + 1);
showInfoModal(

Check warning on line 12 in app/assets/javascripts/file_viewer.ts

View check run for this annotation

Codecov / codecov/patch

app/assets/javascripts/file_viewer.ts#L9-L12

Added lines #L9 - L12 were not covered by tests
html`${name} <a href='${path}' title='Download' download><i class='mdi mdi-download'></i></a>`,
html`<div class='code' id='file-${random}'>Loading...</div>`
);

fetch(path, {

Check warning on line 17 in app/assets/javascripts/file_viewer.ts

View check run for this annotation

Codecov / codecov/patch

app/assets/javascripts/file_viewer.ts#L17

Added line #L17 was not covered by tests
method: "GET"
}).then(response => {

Check warning on line 19 in app/assets/javascripts/file_viewer.ts

View check run for this annotation

Codecov / codecov/patch

app/assets/javascripts/file_viewer.ts#L19

Added line #L19 was not covered by tests
if (response.ok) {
response.text().then(data => {
let lines = data.split("\n");
const maxLines = 99;

Check warning on line 23 in app/assets/javascripts/file_viewer.ts

View check run for this annotation

Codecov / codecov/patch

app/assets/javascripts/file_viewer.ts#L21-L23

Added lines #L21 - L23 were not covered by tests
if (lines.length > maxLines) {
lines = lines.slice(0, maxLines);
lines.push("...");

Check warning on line 26 in app/assets/javascripts/file_viewer.ts

View check run for this annotation

Codecov / codecov/patch

app/assets/javascripts/file_viewer.ts#L25-L26

Added lines #L25 - L26 were not covered by tests
}

const table = document.createElement("table");
table.className = "external-file";
for (let i = 0; i < lines.length; i++) {
const tr = document.createElement("tr");

Check warning on line 32 in app/assets/javascripts/file_viewer.ts

View check run for this annotation

Codecov / codecov/patch

app/assets/javascripts/file_viewer.ts#L29-L32

Added lines #L29 - L32 were not covered by tests

const number = document.createElement("td");
number.className = "line-nr";

Check warning on line 35 in app/assets/javascripts/file_viewer.ts

View check run for this annotation

Codecov / codecov/patch

app/assets/javascripts/file_viewer.ts#L34-L35

Added lines #L34 - L35 were not covered by tests
number.textContent = (i === maxLines) ? "" : (i + 1).toString();
tr.appendChild(number);

Check warning on line 37 in app/assets/javascripts/file_viewer.ts

View check run for this annotation

Codecov / codecov/patch

app/assets/javascripts/file_viewer.ts#L37

Added line #L37 was not covered by tests

const line = document.createElement("td");
line.className = "line";

Check warning on line 40 in app/assets/javascripts/file_viewer.ts

View check run for this annotation

Codecov / codecov/patch

app/assets/javascripts/file_viewer.ts#L39-L40

Added lines #L39 - L40 were not covered by tests
// textContent is safe, html is not executed
line.textContent = lines[i];
tr.appendChild(line);
table.appendChild(tr);

Check warning on line 44 in app/assets/javascripts/file_viewer.ts

View check run for this annotation

Codecov / codecov/patch

app/assets/javascripts/file_viewer.ts#L42-L44

Added lines #L42 - L44 were not covered by tests
}
const fileView = document.getElementById(`file-${random}`);
fileView.innerHTML = "";
fileView.appendChild(table);

Check warning on line 48 in app/assets/javascripts/file_viewer.ts

View check run for this annotation

Codecov / codecov/patch

app/assets/javascripts/file_viewer.ts#L46-L48

Added lines #L46 - L48 were not covered by tests
});
}
});
}
export function initFileViewers(activityPath: string): void {
document.querySelectorAll("a.file-link").forEach(l => l.addEventListener("click", e => {
const link = e.currentTarget as HTMLLinkElement;
const fileName = link.innerText;
const tc = link.closest(".testcase.contains-file") as HTMLDivElement;

Check warning on line 57 in app/assets/javascripts/file_viewer.ts

View check run for this annotation

Codecov / codecov/patch

app/assets/javascripts/file_viewer.ts#L53-L57

Added lines #L53 - L57 were not covered by tests
if (tc === null) {
return;

Check warning on line 59 in app/assets/javascripts/file_viewer.ts

View check run for this annotation

Codecov / codecov/patch

app/assets/javascripts/file_viewer.ts#L59

Added line #L59 was not covered by tests
}
const files = JSON.parse(tc.dataset.files);
const file = files[fileName];

Check warning on line 62 in app/assets/javascripts/file_viewer.ts

View check run for this annotation

Codecov / codecov/patch

app/assets/javascripts/file_viewer.ts#L61-L62

Added lines #L61 - L62 were not covered by tests
if (file.location === "inline") {
showInlineFile(fileName, file.content);

Check warning on line 64 in app/assets/javascripts/file_viewer.ts

View check run for this annotation

Codecov / codecov/patch

app/assets/javascripts/file_viewer.ts#L64

Added line #L64 was not covered by tests
} else if (file.location === "href") {
showRealFile(fileName, activityPath, file.content);

Check warning on line 66 in app/assets/javascripts/file_viewer.ts

View check run for this annotation

Codecov / codecov/patch

app/assets/javascripts/file_viewer.ts#L66

Added line #L66 was not covered by tests
}
}));
}
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
import fscreen from "fscreen";
import { showInfoModal } from "./modal";
import { fetch } from "utilities";
import { html } from "lit";
import { showInfoModal } from "modal";
import { html } from "lit/development";

Check warning on line 4 in app/assets/javascripts/tutor.ts

View check run for this annotation

Codecov / codecov/patch

app/assets/javascripts/tutor.ts#L3-L4

Added lines #L3 - L4 were not covered by tests

function initPythiaSubmissionShow(submissionCode: string, activityPath: string): void {
export function initTutor(submissionCode: string): void {

Check warning on line 6 in app/assets/javascripts/tutor.ts

View check run for this annotation

Codecov / codecov/patch

app/assets/javascripts/tutor.ts#L6

Added line #L6 was not covered by tests
function init(): void {
initTutorLinks();
initFileViewers(activityPath);
if (document.querySelectorAll(".tutormodal").length == 1) {
initFullScreen();
} else {
Expand Down Expand Up @@ -52,73 +51,6 @@ function initPythiaSubmissionShow(submissionCode: string, activityPath: string):
}));
}

function initFileViewers(activityPath: string): void {
document.querySelectorAll("a.file-link").forEach(l => l.addEventListener("click", e => {
const link = e.currentTarget as HTMLLinkElement;
const fileName = link.innerText;
const tc = link.closest(".testcase.contains-file") as HTMLDivElement;
if (tc === null) {
return;
}
const files = JSON.parse(tc.dataset.files);
const file = files[fileName];
if (file.location === "inline") {
showInlineFile(fileName, file.content);
} else if (file.location === "href") {
showRealFile(fileName, activityPath, file.content);
}
}));
}

function showInlineFile(name: string, content: string): void {
showInfoModal(name, html`<div class='code'>${content}</div>`);
}

function showRealFile(name: string, activityPath: string, filePath: string): void {
const path = activityPath + "/" + filePath;
const random = Math.floor(Math.random() * 10000 + 1);
showInfoModal(
html`${name} <a href='${path}' title='Download' download><i class='mdi mdi-download'></i></a>`,
html`<div class='code' id='file-${random}'>Loading...</div>`
);

fetch(path, {
method: "GET"
}).then(response => {
if (response.ok) {
response.text().then(data => {
let lines = data.split("\n");
const maxLines = 99;
if (lines.length > maxLines) {
lines = lines.slice(0, maxLines);
lines.push("...");
}

const table = document.createElement("table");
table.className = "external-file";
for (let i = 0; i < lines.length; i++) {
const tr = document.createElement("tr");

const number = document.createElement("td");
number.className = "line-nr";
number.textContent = (i === maxLines) ? "" : (i + 1).toString();
tr.appendChild(number);

const line = document.createElement("td");
line.className = "line";
// textContent is safe, html is not executed
line.textContent = lines[i];
tr.appendChild(line);
table.appendChild(tr);
}
const fileView = document.getElementById(`file-${random}`);
fileView.innerHTML = "";
fileView.appendChild(table);
});
}
});
}

function initFullScreen(): void {
fscreen.addEventListener("fullscreenchange", resizeFullScreen);

Expand Down Expand Up @@ -220,5 +152,3 @@ function initPythiaSubmissionShow(submissionCode: string, activityPath: string):

init();
}

export { initPythiaSubmissionShow };
33 changes: 33 additions & 0 deletions app/helpers/renderers/feedback_table_renderer.rb
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ def initialize(submission, user)

def parse
if @result.present?
tutor_init
@builder.div(class: 'feedback-table', 'data-exercise_id': @exercise.id) do
if @result[:messages].present?
@builder.div(class: 'feedback-table-messages') do
Expand Down Expand Up @@ -408,4 +409,36 @@ def safe(html)
sanitize html
end
end

def tutor_init
# Initialize tutor javascript
@builder.script do
escaped = escape_javascript(@code.strip)
@builder << 'dodona.ready.then(function() {'
@builder << "document.body.append(document.getElementById('tutor'));"
@builder << "dodona.initTutor(\"#{escaped}\");});"
end

# Tutor HTML
@builder.div(id: 'tutor', class: 'tutormodal') do
@builder.div(id: 'info-modal', class: 'modal fade', 'data-backdrop': true, tabindex: -1) do
@builder.div(class: 'modal-dialog modal-xl modal-fullscreen-lg-down tutor') do
@builder.div(class: 'modal-content') do
@builder.div(class: 'modal-header') do
@builder.h4(class: 'modal-title') {}
@builder.div(class: 'icons') do
@builder.button(id: 'fullscreen-button', type: 'button', class: 'btn btn-icon') do
@builder.i('', class: 'mdi mdi-fullscreen')
end
@builder.button(type: 'button', class: 'btn btn-icon', 'data-bs-dismiss': 'modal') do
@builder.i('', class: 'mdi mdi-close')
end
end
end
@builder.div(class: 'modal-body') {}
end
end
end
end
end
end
33 changes: 4 additions & 29 deletions app/helpers/renderers/pythia_renderer.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ class PythiaRenderer < FeedbackTableRenderer
include ActionView::Helpers::JavaScriptHelper

def parse
tutor_init
file_viewer_init
super
end

Expand Down Expand Up @@ -74,36 +74,11 @@ def testcase(tc)

## custom methods

def tutor_init
# Initialize tutor javascript
def file_viewer_init
# Initialize file viewers
@builder.script do
escaped = escape_javascript(@code.strip)
@builder << 'dodona.ready.then(function() {'
@builder << "document.body.append(document.getElementById('tutor'));"
@builder << "var code = \"#{escaped}\";"
@builder << "dodona.initPythiaSubmissionShow(code, '#{activity_path(nil, @exercise)}');});"
end

# Tutor HTML
@builder.div(id: 'tutor', class: 'tutormodal') do
@builder.div(id: 'info-modal', class: 'modal fade', 'data-backdrop': true, tabindex: -1) do
@builder.div(class: 'modal-dialog modal-xl modal-fullscreen-lg-down tutor') do
@builder.div(class: 'modal-content') do
@builder.div(class: 'modal-header') do
@builder.h4(class: 'modal-title') {}
@builder.div(class: 'icons') do
@builder.button(id: 'fullscreen-button', type: 'button', class: 'btn btn-icon') do
@builder.i('', class: 'mdi mdi-fullscreen')
end
@builder.button(type: 'button', class: 'btn btn-icon', 'data-bs-dismiss': 'modal') do
@builder.i('', class: 'mdi mdi-close')
end
end
end
@builder.div(class: 'modal-body') {}
end
end
end
@builder << "dodona.initFileViewers('#{activity_path(nil, @exercise)}');});"
end
end

Expand Down
7 changes: 2 additions & 5 deletions app/javascript/packs/pythia_submission.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,3 @@
import { initPythiaSubmissionShow } from "pythia_submission.ts";
import { initFileViewers } from "file_viewer";

window.dodona.initPythiaSubmissionShow = initPythiaSubmissionShow;

// will automatically bind to window.iFrameResize()
require("iframe-resizer"); // eslint-disable-line no-undef
window.dodona.initFileViewers = initFileViewers;
5 changes: 5 additions & 0 deletions app/javascript/packs/submission.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { attachClipboard } from "copy";
import { evaluationState } from "state/Evaluations";
import codeListing from "code_listing";
import { annotationState } from "state/Annotations";
import { initTutor } from "tutor";

window.dodona.initSubmissionShow = initSubmissionShow;
window.dodona.codeListing = codeListing;
Expand All @@ -14,3 +15,7 @@ window.dodona.initSubmissionHistory = initSubmissionHistory;
window.dodona.setEvaluationId = id => evaluationState.id = id;
window.dodona.setAnnotationVisibility = visibility => annotationState.visibility = visibility;
window.dodona.showLastTab = showLastTab;
window.dodona.initTutor = initTutor;

// will automatically bind to window.iFrameResize()
require("iframe-resizer"); // eslint-disable-line no-undef

0 comments on commit dfd9b11

Please sign in to comment.