diff --git a/app/assets/javascripts/bootstrap-dropdown-submenu.js b/app/assets/javascripts/bootstrap-dropdown-submenu.js index 10809c02..38ad3854 100644 --- a/app/assets/javascripts/bootstrap-dropdown-submenu.js +++ b/app/assets/javascripts/bootstrap-dropdown-submenu.js @@ -1,6 +1,6 @@ $(document).on('turbolinks:load', function() { - var subMenusSelector = 'ul.dropdown-menu [data-toggle=dropdown]'; + var subMenusSelector = 'ul.dropdown-menu [data-bs-toggle=dropdown]'; function openSubMenu(event) { if (this.pathname === '/') { diff --git a/app/assets/javascripts/codeharbor_link.js b/app/assets/javascripts/codeharbor_link.js index 4cd49ece..fdf42859 100644 --- a/app/assets/javascripts/codeharbor_link.js +++ b/app/assets/javascripts/codeharbor_link.js @@ -1,5 +1,5 @@ $(document).on('turbolinks:load', function() { - $('[data-toggle="tooltip"]').tooltip(); + $('[data-bs-toggle="tooltip"]').tooltip(); if($.isController('codeharbor_links')) { if ($('.edit_codeharbor_link, .new_codeharbor_link').isPresent()) { diff --git a/app/assets/javascripts/editor.js b/app/assets/javascripts/editor.js index 465e2f49..6dc79b7f 100644 --- a/app/assets/javascripts/editor.js +++ b/app/assets/javascripts/editor.js @@ -15,12 +15,9 @@ $(document).on('turbolinks:load', function(event) { ); if ($('#editor').isPresent() && CodeOceanEditor && event.originalEvent.data.url.includes("/implement")) { - if (CodeOceanEditor.isBrowserSupported()) { - $('#alert').hide(); - // This call will (amon other things) initializeEditors and load the content except for the last line - // It must not be called during page navigation. Otherwise, content will be duplicated! - // Search for insertLines and Turbolinks reload / cache control - CodeOceanEditor.initializeEverything(); - } + // This call will (amon other things) initializeEditors and load the content except for the last line + // It must not be called during page navigation. Otherwise, content will be duplicated! + // Search for insertLines and Turbolinks reload / cache control + CodeOceanEditor.initializeEverything(); } }); diff --git a/app/assets/javascripts/editor/editor.js.erb b/app/assets/javascripts/editor/editor.js.erb index b07341ae..d242e64b 100644 --- a/app/assets/javascripts/editor/editor.js.erb +++ b/app/assets/javascripts/editor/editor.js.erb @@ -78,7 +78,7 @@ var CodeOceanEditor = { if ($('#output-' + index).isPresent()) { return $('#output-' + index); } else { - var element = $('
').attr('id', 'output-' + index);
+            var element = $('
').attr('id', 'output-' + index);
             $('#output').append(element);
             return element;
         }
@@ -235,10 +235,20 @@ var CodeOceanEditor = {
         window.dispatchEvent(new Event('resize'));
     },
 
-    resizeParentOfAceEditor: function (element) {
+    resizeSidebars: function () {
+        $('#content-left-sidebar').height(this.calculateEditorHeight('#content-left-sidebar', false));
+        $('#content-right-sidebar').height(this.calculateEditorHeight('#content-right-sidebar', false));
+    },
+
+    calculateEditorHeight: function (element, considerStatusbar) {
+        let bottom = considerStatusbar ? ($('#statusbar').height() || 0) : 0;
         // calculate needed size: window height - position of top of ACE editor - height of autosave label below editor - 5 for bar margins
-        var windowHeight = window.innerHeight - $(element).offset().top - ($('#statusbar').height() || 0) - 5;
-        $(element).parent().height(windowHeight);
+        return window.innerHeight - $(element).offset().top - bottom - 5;
+    },
+
+    resizeParentOfAceEditor: function (element) {
+        const editorHeight = this.calculateEditorHeight(element, true);
+        $(element).parent().height(editorHeight);
     },
 
     initializeEditors: function (own_solution = false) {
@@ -259,6 +269,7 @@ var CodeOceanEditor = {
             // Resize frame on window size change
             $(window).resize(function () {
                 this.resizeParentOfAceEditor(element);
+                this.resizeSidebars();
             }.bind(this));
 
             var editor = ace.edit(element);
@@ -390,6 +401,7 @@ var CodeOceanEditor = {
             tipButton.on('click', this.handleSideBarToggle.bind(this));
         }
         $('#sidebar').on('transitionend', this.resizeAceEditors.bind(this));
+        $('#sidebar').on('transitionend', this.resizeSidebars.bind(this));
     },
 
     handleSideBarToggle: function () {
@@ -433,12 +445,12 @@ var CodeOceanEditor = {
         button.prop('disabled', true);
         button.on('click', function () {
             $('#rfc_intervention_text').hide()
-            $('#comment-modal').modal('show');
+            new bootstrap.Modal($('#comment-modal')).show();
         });
 
         $('#askForCommentsButton').on('click', this.requestComments.bind(this));
         $('#closeAskForCommentsButton').on('click', function () {
-            $('#comment-modal').modal('hide');
+            bootstrap.Modal.getInstance($('#comment-modal')).hide();
         });
 
         setTimeout(function () {
@@ -475,12 +487,6 @@ var CodeOceanEditor = {
         return this.isActiveFileExecutable() && ['teacher_defined_test', 'user_defined_test', 'teacher_defined_linter'].includes(this.active_frame.data('role'));
     },
 
-    isBrowserSupported: function () {
-        //  websockets are used for run, score and test
-        // Also exclude IE and IE 11
-        return Modernizr.websockets && window.navigator.userAgent.indexOf("MSIE") <= 0 && !navigator.userAgent.match(/Trident\/7\./);
-    },
-
     populateCard: function (card, result, index) {
         card.addClass(this.getCardClass(result));
         card.find('.card-title .filename').text(result.filename);
@@ -778,7 +784,7 @@ var CodeOceanEditor = {
         event.preventDefault();
         this.createSubmission('#create-file', null, function (response) {
             $('#code_ocean_file_context_id').val(response.id);
-            $('#modal-file').modal('show');
+            new bootstrap.Modal($('#modal-file')).show();
         }.bind(this));
     },
 
@@ -786,6 +792,7 @@ var CodeOceanEditor = {
         $('#toggle-sidebar-output').on('click', this.hideOutputBar.bind(this));
         $('#toggle-sidebar-output-collapsed').on('click', this.showOutputBar.bind(this));
         $('#output_sidebar').on('transitionend', this.resizeAceEditors.bind(this));
+        $('#output_sidebar').on('transitionend', this.resizeSidebars.bind(this));
     },
 
     showOutputBar: function () {
@@ -801,7 +808,7 @@ var CodeOceanEditor = {
     },
 
     initializeSideBarTooltips: function () {
-        $('[data-toggle="tooltip"]').tooltip()
+        $('[data-bs-toggle="tooltip"]').tooltip()
     },
 
     initializeDescriptionToggle: function () {
@@ -809,12 +816,13 @@ var CodeOceanEditor = {
         $('a#toggle').on('click', this.toggleDescriptionCard.bind(this));
     },
 
-    toggleDescriptionCard: function () {
+    toggleDescriptionCard: function (event) {
         $('#description-card').toggleClass('description-card-collapsed').toggleClass('description-card');
         $('#description-symbol').toggleClass('fa-chevron-down').toggleClass('fa-chevron-right');
         var toggle = $('a#toggle');
         toggle.text(toggle.text() == toggle.data('hide') ? toggle.data('show') : toggle.data('hide'));
         this.resizeAceEditors();
+        this.resizeSidebars();
         event.preventDefault();
     },
 
@@ -871,7 +879,7 @@ var CodeOceanEditor = {
                             if (editor.data('tips-interventions')) {
                                 const modal = $('#tips-intervention-modal');
                                 modal.find('.modal-footer').html(I18n.t("exercises.implement.intervention.explanation", {duration: Math.round(percentile75 / 60)}));
-                                modal.modal('show');
+                                new bootstrap.Modal(modal).show();
                                 $.ajax({
                                     data: {
                                         intervention_type: 'TipsIntervention'
@@ -883,7 +891,7 @@ var CodeOceanEditor = {
                             } else if (editor.data('break-interventions')) {
                                 const modal = $('#break-intervention-modal');
                                 modal.find('.modal-footer').html(I18n.t("exercises.implement.intervention.explanation", {duration: Math.round(percentile75 / 60)}));
-                                modal.modal('show');
+                                new bootstrap.Modal(modal).show();
                                 $.ajax({
                                     data: {
                                         intervention_type: 'BreakIntervention'
@@ -902,7 +910,7 @@ var CodeOceanEditor = {
                                     modal.on('hidden.bs.modal', function () {
                                         modal.find('.modal-footer').text('');
                                     });
-                                    modal.modal('show');
+                                    new bootstrap.Modal(modal).show();
                                     $.ajax({
                                         data: {
                                             intervention_type: 'QuestionIntervention'
@@ -945,7 +953,6 @@ var CodeOceanEditor = {
         CodeOceanEditor.editors = [];
         this.initializeRegexes();
         this.initializeCodePilot();
-        $('.score, #development-environment').show();
         this.configureEditors();
         this.initializeEditors();
         this.initializeEventHandlers();
@@ -961,6 +968,7 @@ var CodeOceanEditor = {
         this.renderScore();
         this.showFirstFile();
         this.resizeAceEditors();
+        this.resizeSidebars();
         this.initializeDeadlines();
         CodeOceanEditorTips.initializeEventHandlers();
 
diff --git a/app/assets/javascripts/editor/participantsupport.js.erb b/app/assets/javascripts/editor/participantsupport.js.erb
index 77d2138b..db801aeb 100644
--- a/app/assets/javascripts/editor/participantsupport.js.erb
+++ b/app/assets/javascripts/editor/participantsupport.js.erb
@@ -4,7 +4,7 @@ CodeOceanEditorFlowr = {
     '
' + '' + + body.append('' + '<%= I18n.t('exercises.implement.flowr.go_to_question') %>'); body.find('.btn').on('click', CodeOceanEditor.createEventHandler('editor_flowr_click_question', questionUrl)); @@ -112,7 +112,7 @@ CodeOceanEditorCodePilot = { QaApiOutputBuffer: {'stdout': '', 'stderr': ''}, initializeCodePilot: function () { - if ($('#questions-column').isPresent() && (typeof QaApi != 'undefined') && QaApi.isBrowserSupported()) { + if ($('#questions-column').isPresent() && (typeof QaApi != 'undefined')) { $('#editor-column').addClass('col-md-10').removeClass('col-md-12'); $('#questions-column').addClass('col-md-2'); @@ -161,7 +161,7 @@ CodeOceanEditorRequestForComments = { this.createSubmission($('#requestComments'), null, createRequestForComments.bind(this)); - $('#comment-modal').modal('hide'); + bootstrap.Modal.getInstance($('#comment-modal')).hide(); $('#question').val(''); // we disabled the button to prevent that the user spams RFCs, but decided against this now. //var button = $('#requestComments'); diff --git a/app/assets/javascripts/editor/turtle.js b/app/assets/javascripts/editor/turtle.js index e6463ee4..d388f375 100644 --- a/app/assets/javascripts/editor/turtle.js +++ b/app/assets/javascripts/editor/turtle.js @@ -37,15 +37,16 @@ CodeOceanEditorTurtle = { }, showCanvas: function () { - if ($('#turtlediv').isPresent() && this.turtlecanvas.hasClass('d-none')) { - this.turtlecanvas.removeClass('d-none'); + const turtlediv = $('#turtlediv'); + if (turtlediv.isPresent() && turtlediv.hasClass('d-none')) { + turtlediv.removeClass('d-none'); } }, hideCanvas: function () { - const turtlecanvas = $('#turtlecanvas'); - if ($('#turtlediv').isPresent() && !turtlecanvas.hasClass('d-none')) { - turtlecanvas.addClass('d-none'); + const turtlediv = $('#turtlediv'); + if (turtlediv.isPresent() && !turtlediv.hasClass('d-none')) { + turtlediv.addClass('d-none'); } } diff --git a/app/assets/javascripts/exercise_collections.js.erb b/app/assets/javascripts/exercise_collections.js.erb index 6c8602f7..d0aad22e 100644 --- a/app/assets/javascripts/exercise_collections.js.erb +++ b/app/assets/javascripts/exercise_collections.js.erb @@ -187,7 +187,7 @@ $(document).on('turbolinks:load', function() { for (var i = 0; i < selectedExercises.length; i++) { addExercise(selectedExercises[i].value, selectedExercises[i].label); } - $('#add-exercise-modal').modal('hide') + bootstrap.Modal.getInstance($('#add-exercise-modal')).hide(); updateExerciseList(); addExercisesForm.find('select').val('').trigger("chosen:updated"); }); diff --git a/app/assets/javascripts/exercises.js.erb b/app/assets/javascripts/exercises.js.erb index 9a5f0378..a91586dd 100644 --- a/app/assets/javascripts/exercises.js.erb +++ b/app/assets/javascripts/exercises.js.erb @@ -123,7 +123,7 @@ $(document).on('turbolinks:load', function () { var buildCheckboxes = function () { $('tbody tr').each(function (index, element) { var td = $('td.public', element); - var checkbox = $('', { + var checkbox = $('', { checked: td.data('value'), type: 'checkbox' }); @@ -225,9 +225,9 @@ $(document).on('turbolinks:load', function () { const tip = {id: id, title: title} const template = '
' + - '' + tip.title + - '' + - '' + + '' + tip.title + + '' + + '' + '
' + '
'; const tipList = $('#tip-list').append(template); @@ -243,7 +243,7 @@ $(document).on('turbolinks:load', function () { for (let i = 0; i < selectedTips.length; i++) { addTip(selectedTips[i].value, selectedTips[i].label); } - $('#add-tips-modal').modal('hide') + bootstrap.Modal.getInstance($('#add-tips-modal')).hide(); updateTipsJSON(); chosenInputTips.val('').trigger("chosen:updated"); }); @@ -328,10 +328,7 @@ $(document).on('turbolinks:load', function () { var observeExportButtons = function () { $('.export-start').on('click', function (e) { e.preventDefault(); - $('#export-modal').modal({ - height: 250 - }); - $('#export-modal').modal('show'); + new bootstrap.Modal($('#export-modal')).show(); exportExerciseStart($(this).data().exerciseId); }); $('body').on('click', '.export-retry-button', function () { @@ -382,7 +379,7 @@ $(document).on('turbolinks:load', function () { if (response.status == 'success') { $messageDiv.addClass('export-success'); setTimeout((function () { - $('#export-modal').modal('hide'); + bootstrap.Modal.getInstance($('#export-modal')).hide(); $messageDiv.html('').removeClass('export-success'); }), 3000); } else { @@ -396,7 +393,7 @@ $(document).on('turbolinks:load', function () { }; var overrideTextareaTabBehavior = function () { - $('.form-group textarea[name$="[content]"]').on('keydown', function (event) { + $('.mb-3 textarea[name$="[content]"]').on('keydown', function (event) { if (event.which === TAB_KEY_CODE) { event.preventDefault(); insertTabAtCursor($(this)); diff --git a/app/assets/javascripts/forms.js b/app/assets/javascripts/forms.js index 7e469455..2be40eba 100644 --- a/app/assets/javascripts/forms.js +++ b/app/assets/javascripts/forms.js @@ -9,7 +9,7 @@ $(document).on('turbolinks:load', function() { event.preventDefault(); if (!$(this).hasClass('disabled')) { - var parent = $(this).parents('.form-group'); + var parent = $(this).parents('.mb-3'); var original_input = parent.find('.original-input'); var alternative_input = parent.find('.alternative-input'); diff --git a/app/assets/javascripts/pagedown/markdown.editor.js.erb b/app/assets/javascripts/pagedown/markdown.editor.js.erb index 459d7cfa..8330a85c 100644 --- a/app/assets/javascripts/pagedown/markdown.editor.js.erb +++ b/app/assets/javascripts/pagedown/markdown.editor.js.erb @@ -1018,7 +1018,7 @@ text = 'http://' + text; } - $(dialog).modal('hide'); + bootstrap.Modal.getInstance($(dialog)).hide(); callback(text); return false; @@ -1032,7 +1032,7 @@ //