Skip to content

Commit

Permalink
Merge pull request #4879 from dodona-edu/chore/remove-jquery
Browse files Browse the repository at this point in the history
Remove JQuery
  • Loading branch information
jorg-vr authored Aug 14, 2023
2 parents 23268d8 + 78e05bc commit 8ca05cf
Show file tree
Hide file tree
Showing 25 changed files with 71 additions and 78 deletions.
9 changes: 8 additions & 1 deletion app/assets/javascripts/submission.ts
Original file line number Diff line number Diff line change
Expand Up @@ -120,4 +120,11 @@ function initSubmissionHistory(id: string): void {
element.scrollIntoView({ block: "center", inline: "nearest" });
}

export { initSubmissionShow, initSubmissionHistory, initCorrectSubmissionToNextLink };
function showLastTab(): void {
const tab = document.querySelector(".nav.nav-tabs li:last-child a");
if (tab) {
new bootstrap.Tab(tab).show();
}
}

export { initSubmissionShow, initSubmissionHistory, initCorrectSubmissionToNextLink, showLastTab };
34 changes: 26 additions & 8 deletions app/assets/javascripts/utilities.ts
Original file line number Diff line number Diff line change
Expand Up @@ -221,15 +221,32 @@ function getParentByClassName(element: Element, classNames: string): Element {
*/
function setHTMLExecuteScripts(el: Element, html: string): void {
el.innerHTML = html;
Array.from(el.querySelectorAll("script")).forEach(oldScriptEl => {
const newScriptEl = document.createElement("script");
Array.from(oldScriptEl.attributes).forEach(attr => {
newScriptEl.setAttribute(attr.name, attr.value);
});
const scriptText = document.createTextNode(oldScriptEl.innerHTML);
newScriptEl.appendChild(scriptText);
oldScriptEl.parentNode.replaceChild(newScriptEl, oldScriptEl);
executeScripts(el as HTMLElement);
}

function replaceHTMLExecuteScripts(el: Element, html: string): void {
const nodes = Array.from(new DOMParser().parseFromString(html, "text/html").body.childNodes);
el.replaceWith(...nodes);
nodes.filter(a => a instanceof HTMLElement || a instanceof HTMLScriptElement)
.forEach(executeScripts);
}

function executeScripts(el: HTMLElement | HTMLScriptElement): void {
if (el instanceof HTMLScriptElement) {
executeScript(el);
return;
}
Array.from(el.querySelectorAll("script")).forEach(executeScript);
}

function executeScript(oldScriptEl: HTMLScriptElement): void {
const newScriptEl = document.createElement("script");
Array.from(oldScriptEl.attributes).forEach(attr => {
newScriptEl.setAttribute(attr.name, attr.value);
});
const scriptText = document.createTextNode(oldScriptEl.innerHTML);
newScriptEl.appendChild(scriptText);
oldScriptEl.parentNode.replaceChild(newScriptEl, oldScriptEl);
}

export {
Expand All @@ -251,4 +268,5 @@ export {
ready,
getParentByClassName,
setHTMLExecuteScripts,
replaceHTMLExecuteScripts,
};
2 changes: 1 addition & 1 deletion app/helpers/renderers/pythia_renderer.rb
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ def tutor_init
@builder.script do
escaped = escape_javascript(@code.strip)
@builder << 'dodona.ready.then(function() {'
@builder << "$('#tutor').appendTo('body');"
@builder << "document.body.append(document.getElementById('tutor'));"
@builder << "var code = \"#{escaped}\";"
@builder << "dodona.initPythiaSubmissionShow(code, '#{activity_path(nil, @exercise)}');});"
end
Expand Down
12 changes: 3 additions & 9 deletions app/javascript/packs/application_pack.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,6 @@ import { start as startRails } from "@rails/ujs";

startRails();

import jQuery from "jquery";

// jQuery aliases
window.jQuery = jQuery;
window.jquery = jQuery;
window.$ = jQuery;

import { I18n } from "i18n/i18n";
window.I18n = new I18n();

Expand All @@ -32,14 +25,14 @@ window.bootstrap = bootstrap;
import { Drawer } from "drawer";
import { Toast } from "toast";
import { Notification } from "notification";
import { checkTimeZone, checkIframe, initTooltips, ready, setHTMLExecuteScripts } from "utilities.ts";
import { checkTimeZone, checkIframe, initTooltips, ready, setHTMLExecuteScripts, replaceHTMLExecuteScripts } from "utilities.ts";
import { initClipboard } from "copy";
import { FaviconManager } from "favicon";
import { themeState } from "state/Theme";
import "components/saved_annotations/saved_annotation_list";
import "components/progress_bar";
import "components/theme_picker";
import { userState } from "../../assets/javascripts/state/Users";
import { userState } from "state/Users";

// Initialize clipboard.js
initClipboard();
Expand All @@ -60,6 +53,7 @@ dodona.Notification = Notification;
dodona.initTooltips = initTooltips;
dodona.checkIframe = checkIframe;
dodona.setHTMLExecuteScripts = setHTMLExecuteScripts;
dodona.replaceHTMLExecuteScripts = replaceHTMLExecuteScripts;
dodona.setTheme = theme => themeState.selectedTheme = theme;
dodona.setUserId = userId => userState.id = userId;
dodona.ready = ready;
Expand Down
7 changes: 0 additions & 7 deletions app/javascript/packs/frame.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,6 @@
import "core-js/stable";
import "regenerator-runtime/runtime";

import jQuery from "jquery";

// jQuery aliases
window.jQuery = jQuery;
window.jquery = jQuery;
window.$ = jQuery;

// bootstrap
import { Alert, Button, Collapse, Dropdown, Modal, Popover, Tab, Tooltip } from "bootstrap";
const bootstrap = { Alert, Button, Collapse, Dropdown, Modal, Popover, Tab, Tooltip };
Expand Down
3 changes: 2 additions & 1 deletion app/javascript/packs/submission.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { initSubmissionShow, initCorrectSubmissionToNextLink, initSubmissionHistory } from "submission.ts";
import { initSubmissionShow, initCorrectSubmissionToNextLink, initSubmissionHistory, showLastTab } from "submission.ts";
import { initMathJax } from "exercise.ts";
import { attachClipboard } from "copy";
import { evaluationState } from "state/Evaluations";
Expand All @@ -13,3 +13,4 @@ window.dodona.initCorrectSubmissionToNextLink = initCorrectSubmissionToNextLink;
window.dodona.initSubmissionHistory = initSubmissionHistory;
window.dodona.setEvaluationId = id => evaluationState.id = id;
window.dodona.setAnnotationVisibility = visibility => annotationState.visibility = visibility;
window.dodona.showLastTab = showLastTab;
2 changes: 1 addition & 1 deletion app/views/application/_token_field.js.erb
Original file line number Diff line number Diff line change
@@ -1 +1 @@
$('#<%= container_name.to_s %>').html('<%= escape_javascript render(partial: 'application/token_field', formats: [:html], locals: { name: name, value: value, reset_url: reset_url }) %>');
dodona.setHTMLExecuteScripts(document.querySelector('#<%= container_name.to_s %>'), '<%= escape_javascript render(partial: 'application/token_field', formats: [:html], locals: { name: name, value: value, reset_url: reset_url }) %>');
2 changes: 1 addition & 1 deletion app/views/course_members/index.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@
{
icon: 'palette-swatch',
text: t(".edit_all_labels"),
js: '$("#labelsUploadModal").modal("show")',
js: 'bootstrap.Modal.getOrCreateInstance(document.querySelector("#labelsUploadModal")).show()',
type: 'enrolled'
}
],
Expand Down
2 changes: 1 addition & 1 deletion app/views/courses/_not_a_member_dialog.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,6 @@
</div>
<script type="text/javascript">
dodona.ready.then(function(){
$('#ltiModal').modal('show');
bootstrap.Modal.getOrCreateInstance(document.querySelector('#ltiModal')).show();
});
</script>
2 changes: 1 addition & 1 deletion app/views/courses/_reload_users.js.erb
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,5 @@
new dodona.Toast("<%= toast %>");
<% end %>
<% count = @course.pending_members.count %>
$("#pending-count").text('<%= count if count.nonzero? %>');
document.getElementById("pending-count").innerText = "<%= count if count.nonzero? %>";
dodona.search.search();
1 change: 0 additions & 1 deletion app/views/courses/show.js.erb

This file was deleted.

4 changes: 2 additions & 2 deletions app/views/evaluations/add_user.js.erb
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,5 @@ const row = document.querySelector("#user-row-<%= @user.id %>");
row.innerHTML = "<%= escape_javascript(render 'evaluations/member_row', course_membership: @course_membership, user: @user, confirm: false) %>";
row.classList.add("table-active");
dodona.initCheckbox(row);
$('#users-count-wrapper').html("<%= t('evaluations.edit_users.users_selected_html', count: @evaluation.users.count) %>")
$('#short-users-count-wrapper').text("<%= t('evaluations.edit_users.short_users_selected', count: @evaluation.users.count) %>")
dodona.setHTMLExecuteScripts(document.querySelector('#users-count-wrapper'), "<%= t('evaluations.edit_users.users_selected_html', count: @evaluation.users.count) %>")
document.querySelector('#short-users-count-wrapper').innerText = "<%= t('evaluations.edit_users.short_users_selected', count: @evaluation.users.count) %>";
2 changes: 1 addition & 1 deletion app/views/evaluations/create.js.erb
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
$("#info-panel .answer").text("<%= l @evaluation.deadline, format: :long %>");
document.querySelector("#info-panel .answer").innerText = "<%= l @evaluation.deadline, format: :long %>";
dodona.setHTMLExecuteScripts(document.querySelector("#users-step-wrapper"), "<%= raw escape_javascript(render partial: 'add_users') %>");
window.dodona.initTooltips();
window.dodona.toUsersStep();
Expand Down
4 changes: 2 additions & 2 deletions app/views/evaluations/refresh_users.js.erb
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
window.dodona.search.search();
$('#users-count-wrapper').html("<%= t('evaluations.edit_users.users_selected_html', count: @evaluation.users.count) %>")
$('#short-users-count-wrapper').text("<%= t('evaluations.edit_users.short_users_selected', count: @evaluation.users.count) %>")
dodona.setHTMLExecuteScripts(document.querySelector('#users-count-wrapper'), "<%= t('evaluations.edit_users.users_selected_html', count: @evaluation.users.count) %>")
document.querySelector('#short-users-count-wrapper').innerText = "<%= t('evaluations.edit_users.short_users_selected', count: @evaluation.users.count) %>";
4 changes: 2 additions & 2 deletions app/views/evaluations/remove_user.js.erb
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,5 @@ const row = document.querySelector("#user-row-<%= @user.id %>");
row.innerHTML = "<%= escape_javascript(render 'evaluations/member_row', course_membership: @course_membership, user: @user, confirm: false) %>";
row.classList.remove("table-active");
dodona.initCheckbox(row);
$('#users-count-wrapper').html("<%= t('evaluations.edit_users.users_selected_html', count: @evaluation.users.count) %>")
$('#short-users-count-wrapper').text("<%= t('evaluations.edit_users.short_users_selected', count: @evaluation.users.count) %>")
dodona.setHTMLExecuteScripts(document.querySelector('#users-count-wrapper'), "<%= t('evaluations.edit_users.users_selected_html', count: @evaluation.users.count) %>")
document.querySelector('#short-users-count-wrapper').innerText = "<%= t('evaluations.edit_users.short_users_selected', count: @evaluation.users.count) %>";
2 changes: 1 addition & 1 deletion app/views/feedbacks/show.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@
dodona.ready.then(function () {
window.dodona.setEvaluationId(<%= @feedback.evaluation.id %>);
window.dodona.setAnnotationVisibility("important");
$(".nav.nav-tabs li:last-child a").tab("show");
window.dodona.showLastTab();
});
</script>
<% end %>
2 changes: 1 addition & 1 deletion app/views/score_items/add_all.js.erb
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
$("#add-score-item-to-all").modal("hide");
bootstrap.Modal.getOrCreateInstance(document.querySelector("#add-score-item-to-all")).hide();
dodona.setHTMLExecuteScripts(document.querySelector("#items-step"), "<%= raw escape_javascript(render partial: 'evaluations/score_items') %>");
9 changes: 5 additions & 4 deletions app/views/score_items/index.js.erb
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
<%# Refreshes the score items for one exercise. %>
modal = $(".modal-<%= evaluation_exercise.id %>");
if (modal.is(":visible")) {
modal.on("hidden.bs.modal", () => {
vissibleModal = document.querySelector(".modal-<%= evaluation_exercise.id %>.show")
if (vissibleModal){
vissibleModal.addEventListener("hidden.bs.modal", () => {
dodona.setHTMLExecuteScripts(document.querySelector("#card-<%= evaluation_exercise.id %>"), "<%= escape_javascript(render 'score_items/exercise', evaluation_exercise: evaluation_exercise, new: new) %>");
}).modal("hide");
}, { once: true });
bootstrap.Modal.getOrCreateInstance(vissibleModal).hide();
} else {
dodona.setHTMLExecuteScripts(document.querySelector("#card-<%= evaluation_exercise.id %>"), "<%= escape_javascript(render 'score_items/exercise', evaluation_exercise: evaluation_exercise, new: new) %>");
}
Expand Down
12 changes: 6 additions & 6 deletions app/views/scores/show.js.erb
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
<%# This does two steps: replace the HTML of the score, and then notify the action class. %>
<%# The index is set with JS once known. %>
$("#<%= @score.score_item.id %>-score-form-wrapper")
.replaceWith("<%= escape_javascript(render 'feedbacks/score_actions', score: @score, score_item: @score.score_item, index: @order) %>");
$(".user-feedback-row")
.html("<%= escape_javascript(render 'feedbacks/user_feedback_row', current_feedback: @feedback) %>");
$(".progress-row")
.html("<%= escape_javascript(render 'feedbacks/progress_row', metadata: @feedback.evaluation_exercise.metadata) %>");
dodona.replaceHTMLExecuteScripts(document.getElementById("<%= @score.score_item.id %>-score-form-wrapper"),
"<%= escape_javascript(render 'feedbacks/score_actions', score: @score, score_item: @score.score_item, index: @order) %>");
dodona.setHTMLExecuteScripts(document.querySelector(".user-feedback-row"),
"<%= escape_javascript(render 'feedbacks/user_feedback_row', current_feedback: @feedback) %>");
dodona.setHTMLExecuteScripts(document.querySelector(".progress-row"),
"<%= escape_javascript(render 'feedbacks/progress_row', metadata: @feedback.evaluation_exercise.metadata) %>");
window.dodona.feedbackActions.initScoreForm("<%= @score.score_item.id %>");
window.dodona.feedbackActions.setTotal("<%= format_score @total %>", <%= @feedback.completed %>);
2 changes: 1 addition & 1 deletion app/views/series/mass_rejudge.js.erb
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
$(".btn-group.open").removeClass("open");
document.querySelector(".btn-group.open").classList.remove("open");
new dodona.Toast("<%= I18n.t('submissions.index.reevaluating_submissions', count: @submissions.length) %>");
2 changes: 1 addition & 1 deletion app/views/series/show.js.erb
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,5 @@
loaded: true,
user: @user,
} %>
$("#series-card-<%= @series.id %>").replaceWith("<%= escape_javascript series_card %>");
dodona.replaceHTMLExecuteScripts(document.getElementById("series-card-<%= @series.id %>"), "<%= escape_javascript series_card %>");
dodona.ready.then(dodona.initTooltips)
2 changes: 1 addition & 1 deletion app/views/submissions/show.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
can't generically handle code tabs, except for selecting the last
tab. %>
if (window.location.hash === "#code") {
$(".nav.nav-tabs li:last-child a").tab("show");
window.dodona.showLastTab();
}
});
</script>
Expand Down
2 changes: 0 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@
"@rails/activestorage": "^7.0.6",
"@rails/ujs": "^7.0.6",
"@types/d3": "^7.4.0",
"@types/jquery": "^3.5.16",
"babel-loader": "^9.1.3",
"babel-plugin-macros": "^3.1.0",
"bootstrap": "5.3.1",
Expand All @@ -36,7 +35,6 @@
"fscreen": "^1.2.0",
"glightbox": "^3.2.0",
"iframe-resizer": "^4.3.6",
"jquery": "^3.7.0",
"lit": "2.8.0",
"node-polyglot": "^2.5.0",
"sass": "^1.64.2",
Expand Down
9 changes: 4 additions & 5 deletions test/javascript/setup-jest.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
import * as jQuery from "jquery";

declare let window: any;
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
declare let global: any;
window.$ = window.jQuery = jQuery;
global.$ = global.jQuery = jQuery;

// Mocking the I18N calls. The key itself will be returned as value.
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
global.I18n = {
t: t => t,
formatNumber: n => n.toString(),
Expand Down
17 changes: 0 additions & 17 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -1991,13 +1991,6 @@
jest-matcher-utils "^27.0.0"
pretty-format "^27.0.0"

"@types/jquery@^3.5.16":
version "3.5.16"
resolved "https://registry.yarnpkg.com/@types/jquery/-/jquery-3.5.16.tgz#632131baf30951915b0317d48c98e9890bdf051d"
integrity sha512-bsI7y4ZgeMkmpG9OM710RRzDFp+w4P1RGiIt30C1mSBT+ExCleeh4HObwgArnDFELmRrOpXgSYN9VF1hj+f1lw==
dependencies:
"@types/sizzle" "*"

"@types/json-schema@*", "@types/json-schema@^7.0.8", "@types/json-schema@^7.0.9":
version "7.0.11"
resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.11.tgz#d421b6c527a3037f7c84433fd2c4229e016863d3"
Expand Down Expand Up @@ -2043,11 +2036,6 @@
resolved "https://registry.yarnpkg.com/@types/serviceworker/-/serviceworker-0.0.72.tgz#d4f9f02ab8bc03a9a8075b05ffe0671da1285991"
integrity sha512-RL8/s2CAx+DLmTp00xzzFMiSChkDZD0UgqTwcYYsGdbYWEc0zoBDpJ4lr7gq67S1F3N8QC8EajSzS/5sIkJAcQ==

"@types/sizzle@*":
version "2.3.3"
resolved "https://registry.yarnpkg.com/@types/sizzle/-/sizzle-2.3.3.tgz#ff5e2f1902969d305225a047c8a0fd5c915cebef"
integrity sha512-JYM8x9EGF163bEyhdJBpR2QX1R5naCJHC8ucJylJ3w9/CVBaskdQ8WqBf8MmQrd1kRvp/a4TS8HJ+bxzR7ZJYQ==

"@types/stack-utils@^2.0.0":
version "2.0.1"
resolved "https://registry.yarnpkg.com/@types/stack-utils/-/stack-utils-2.0.1.tgz#20f18294f797f2209b5f65c8e3b5c8e8261d127c"
Expand Down Expand Up @@ -5551,11 +5539,6 @@ jest@^26.6.3:
import-local "^3.0.2"
jest-cli "^26.6.3"

jquery@^3.7.0:
version "3.7.0"
resolved "https://registry.yarnpkg.com/jquery/-/jquery-3.7.0.tgz#fe2c01a05da500709006d8790fe21c8a39d75612"
integrity sha512-umpJ0/k8X0MvD1ds0P9SfowREz2LenHsQaxSohMZ5OMNEU2r0tf8pdeEFTHMFxWVxKNyU9rTtK3CWzUCTKJUeQ==

js-levenshtein-esm@^1.2.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/js-levenshtein-esm/-/js-levenshtein-esm-1.2.0.tgz#96532c34e0c90df198c9419963c64ca3cf43ae92"
Expand Down

0 comments on commit 8ca05cf

Please sign in to comment.