diff --git a/ordo/ordo.js b/ordo/ordo.js index be9c6a6..8b2cf47 100644 --- a/ordo/ordo.js +++ b/ordo/ordo.js @@ -16,8 +16,6 @@ define([ console.debug("...Ordo loaded... grading capabilities initiated"); - var CellToolbar = celltoolbar.CellToolbar; - var defaultSuccess = ""; var defaultFailure = ""; @@ -47,7 +45,7 @@ define([ 'edit_mode.Cell', 'edit_mode.Notebook', 'execute.CodeCell', - 'finished_execute.CodeCell', + 'finished_execute.CodeCell', 'execution_request.Kernel', 'expand_pager', 'file_load_failed.Editor', @@ -115,19 +113,23 @@ define([ 'unregistered_preset.CellToolbar', ]; - + events.on(all_events.join(' '), function (evt, data) { console.debug('[evt]', evt.type, (new Date()).toISOString(), data); }); var params = { defaultSuccess : "", - defaultFailure : "", - enableModeToggle : true + defaultFailure : "", + enableModeToggle : true }; - + + + /** + * Does all the init work of ordo + */ var initialize = function () { - + $('') .attr({ rel: 'stylesheet', @@ -136,193 +138,269 @@ define([ }) .appendTo('head'); - events.on("notebook_loaded.Notebook", function() { - initializeCells() - }); + + events.on("notebook_loaded.Notebook", function() { + initializeCells() + }); + + + if (Jupyter.notebook !== undefined && Jupyter.notebook._fully_loaded) { initializeCells(); } - - - ordoFeedback(); - makeOutputButton(); - showSolutionButton(); - editMetadataButtons(); - - /* The default is feedback mode ... */ - $('.command_mode').addClass('ordo_feedback_mode'); - - if (params.enableModeToggle) { - - /* TODO: Remove toggle button, eventually */ - - ordoEditFeedbackToggle(); - - CellToolbar.register_callback('create_tutorial.toolbar', createCellToolbar); - - var preset = [ - 'create_tutorial.toolbar' - ]; - - CellToolbar.register_preset('Create Tutorial', preset, Jupyter.notebook); - } + + + ordoFeedback(); + makeOutputButton(); + showSolutionButton(); + editMetadataButtons(); + + + /* The default is feedback mode ... */ + $('.command_mode').addClass('ordo_feedback_mode'); + + if (params.enableModeToggle) { + + /* TODO: Remove toggle button, eventually */ + + ordoEditFeedbackToggle(); + + celltoolbar.CellToolbar.register_callback('create_tutorial.toolbar', createCellToolbar); + + var preset = ['create_tutorial.toolbar']; + + celltoolbar.CellToolbar.register_preset('Create Tutorial', preset, Jupyter.notebook); + } }; + + + /** + * Toggles the admonition div between the states open and close + * @param {object} cell Jupyter notebooks' cell object + * @param {object} btn A JQuery object that represents a HTML button + */ var onClickAdmonitionButton = function(cell, btn) { - if (btn.hasClass('active')) { - console.debug("Close ..."); - cell.element.find('div.ordo-admonition-controls').nextAll().hide(); - btn.text('Open'); - } else { - cell.element.find('div.ordo-admonition-controls').nextAll().show() - btn.text('Close'); - } - console.debug(btn); + console.debug(btn); + + if (btn.hasClass('active')) { + console.debug("Close ..."); + + cell.element.find('div.ordo-admonition-controls').nextAll().hide(); + btn.text('Open'); + } else { + console.debug("Open ..."); + + cell.element.find('div.ordo-admonition-controls').nextAll().show(); + btn.text('Close'); + } }; + + + /** + * Creates and appends the ordo div with tits button to the given cell + * @param {object} cell Jupyter notebooks' cell object + */ var toggleOpenButton = function(cell) { - console.debug("toggleOpenButton"); - console.debug(cell, cell.metadata /*, cell.metadata.ordo.admonition, cell.metadata.ordo.admonition*/); - if (cell.metadata.ordo !== undefined && - cell.metadata.ordo.admonition !== undefined && - cell.metadata.ordo.admonition) { - var localDiv = $('
').addClass("text-center").addClass('ordo-admonition-controls'); - var btn = $(' " + - "Oh no! There is no output available on " + channel + "" + - "
" - } else { - - console.debug("ordo feedback ?", obj.cell.element.find('.output_area')); - - feedback = ordoFeedbackMessage(equals(res, output), - obj.cell.metadata.ordo_success, - obj.cell.metadata.ordo_failure); - - - /* if (obj.cell.metadata.ordo_verify === undefined) { - var res; - if (solution['python'] !== undefined) { - console.debug("executePython AWAIT ", solution); - - res = await executePython(solution["python"]).then((result) => { console.debug("3. executePython", result); return result }) - obj.cell.metadata.ordo_solution = {...obj.cell.metadata.ordo_solution, ...res}; - - - } else { - res = solution; - } - console.debug("executePython SOL xxxxx: ", res, output); - feedback = ordoFeedbackMessage(equals(res, output), - obj.cell.metadata.ordo_success, - obj.cell.metadata.ordo_failure); - } else { - if(solution['python'] !== undefined) { - console.debug("executePython AWAIT ", solution); - - solution = await executePython(solution["python"]).then((result) => console.debug("3. executePython2" + result)) - } - - console.debug("executePython SOL 2 ", solution); - feedback = obj.cell.metadata.ordo_verify(output, - obj.cell.metadata.ordo_success, - obj.cell.metadata.ordo_failure); - } - */ - } - obj.cell.output_area.append_output({ - "output_type" : "display_data", - "data" : { - "text/html": feedback - }, - "metadata" : {} - }); - } + + outputs = obj.cell.output_area.outputs; + solution = obj.cell.metadata.ordo_solution; + + if (solution !== undefined) { + console.debug("ordo feedback ?", obj.cell.element.find('.output_area')); + + if (obj.cell.metadata.ordo_verify === undefined) { + var res; + + if (solution['python'] !== undefined) { + console.debug("executePython AWAIT ", solution); + + res = await executePython(solution["python"]).then((result) => { console.debug("3. executePython", result); return result }) + obj.cell.metadata.ordo_solution = {...obj.cell.metadata.ordo_solution, ...res}; + + + } else { + res = solution; + } + + console.debug("executePython SOL xxxxx: ", res, outputs, outputs[outputs.length-1]); + feedback = ordoFeedbackMessage( + equals(res, outputs[outputs.length-1].data), + obj.cell.metadata.ordo_success, + obj.cell.metadata.ordo_failure); + } else { + if(solution['python'] != undefined) { + console.debug("executePython AWAIT ", solution); + + solution = await executePython(solution["python"]).then((result) => console.debug("3. executePython2" + result)) + } + + console.debug("executePython SOL 2 ", solution); + feedback = obj.cell.metadata.ordo_verify( + outputs[outputs.length-1].data, + obj.cell.metadata.ordo_success, + obj.cell.metadata.ordo_failure); + } + + obj.cell.output_area.append_output({ + "output_type" : "display_data", + "data" : { + "text/html": feedback + }, + "metadata" : {} + }); + } }; + /** + * registers function onCodeCellExecuted to event finished_execute.CodeCell. This function is hence + * called after the current code cell is executed + */ var ordoFeedback = function () { - events.on('finished_execute.CodeCell', onCodeCellExecuted); - } + events.on('finished_execute.CodeCell', onCodeCellExecuted); + }; + + + /** + * returns the feedback div. + * @param {boolean} correct - indicates if the solution was correct or not + * @param {string} success_msg - the success message for the current cell, if defined + * @param {string} failure_msg - the failure message for the current cell, if defined + * @returns {string} the feedback div container as a string + */ + var ordoFeedbackMessage = function(correct, success_msg, failure_msg) { + if(correct) { + if (success_msg == undefined && defaultSuccess == "") { + feedback = ""; + + return feedback; + } + + if (success_msg == undefined && defaultSuccess) { + feedback = "" + + return feedback; + } + + feedback = "" + + return feedback; + } + + + /* + Solution was wrong. + */ + + if (failure_msg == undefined) { + feedback = "" + + return feedback; + } + + if (failure_msg == undefined && defaultFailure) { + feedback = "" + + return feedback; + } + + feedback = "" + + return feedback; + }; - /** - * returns the div containing the - * @param {boolean} correct - if the submitted solutions was correct or not - * @param {string} success_msg - the success message for the current cell, if defined - * @param {string} failure_msg - the failure message for the current cell, if defined - */ - var ordoFeedbackMessage = function(correct,success_msg,failure_msg) { - if(correct) { - if (success_msg == undefined && defaultSuccess == "") { - feedback = "" - } else if (success_msg == undefined && defaultSuccess) { - feedback = "" - } else { - feedback = "" - } - } else { - if (failure_msg == undefined) { - feedback = "" - } else if (failure_msg == undefined && defaultFailure) { - feedback = "" - } else { - feedback = "" - } - } - return feedback; - } /** * tests two metadata objects for equality @@ -524,523 +595,545 @@ define([ if(typeof(obj1[p]) == undefined) return false; } return true; - } - /** - * Capture select cell event for the cell data - * check cell type is code - * if true: - * check the cell is the same as the formerly selected cell - * if true: - * return with no action - * if false: - * Remove the button from the formerly selected cell - * check if the cell has been run already - * if true: - * append a button for the user to click which will: - * make ordo_solution = output_area.outputs[0] - */ - var makeOutputButton = function () { - var currCell = undefined; - events.on('select.Cell', function(event, data) { - newCell = data.cell; - if(newCell == currCell){ - return; - } else if($('.ordo_edit_mode').length == 0) { - return; - } else { - $(".show-ordo-solution").remove(); - $(".make-ordo-solution").remove(); - currCell = newCell; - if(currCell.cell_type == "code") { - if(currCell.output_area.outputs.length > 0){ - if(currCell.output_area.outputs[0].output_type == "execute_result") { - $(".selected .output_area") - .first() - .append(""); - $(".make-ordo-solution").on("click", function() { - console.debug("updated metadata"); - currCell.metadata.ordo_solution = currCell.output_area.outputs[0].data; - }); - } - } - } - } - }); - } + }; - /** - * @param {Object} solution - - * returns the correct solution in the appropriate format - */ - var solutionToString = function (solution) { - var outStr = ""; - console.debug(solution) - for (var key in solution) { - switch (key){ - case 'text/html': - outStr = solution[key]; - break; - case 'text/plain': - outStr = solution[key]; - break; - case 'python': - outStr = solution[key]; - break; - default: - outStr = 'N/A'; - } - } - console.debug(outStr); - return outStr; - } - var solutionToString = function (solution) { - var outStr = ""; - var mimeTypes = Object.keys(solution); - console.debug("mimeTypes", mimeTypes); - /* TODO: change to "text/x-..." later */ - if (mimeTypes.includes("python")) { - outStr = solution["python"]; - } else { - for (var mt of mimeTypes) { - console.debug("mt", mt); - switch (mt) { - case "text/html": - outStr = solution[mt]; - break; - case "text/plain": - outStr = solution[mt]; - break; - default: - outStr = null; - } - } - } - console.debug(outStr); - return outStr; - } + /** + * Capture select cell event for the cell data + * check cell type is code + * if true: + * check the cell is the same as the formerly selected cell + * if true: + * return with no action + * if false: + * Remove the button from the formerly selected cell + * check if the cell has been run already + * if true: + * append a button for the user to click which will: + * make ordo_solution = output_area.outputs[0] + */ + var makeOutputButton = function () { - /** - * - * creates a button to show the current solution to the user - */ - var showSolutionButton = function () { - var currCell = undefined; - events.on('select.Cell', function(event, data) { - newCell = data.cell; - if(newCell == currCell){ - return; - } else if($('.ordo_feedback_mode').length == 0) { - return; - } else { - $(".show-ordo-solution").remove(); - currCell = newCell; - if(currCell.cell_type === "code" && currCell.metadata && currCell.metadata.ordo_solution) { - if(currCell.output_area.outputs.length > 0) { - console.debug("Show solution button"); - console.debug(currCell.output_area.outputs[0].output_type); - if(["execute_result", "stream"].includes(currCell.output_area.outputs[0].output_type)) { - $(".selected .input") - .after("
"); - $(".show-ordo-solution").one("click", function() { - //currCell.metadata.ordo_solution = currCell.output_area.outputs[0].data; - // solution = solutionToString(currCell.metadata.ordo_solution) - console.debug(currCell.metadata.ordo_solution); - - /* TODO: - * - Improve retrieval here based on a parametric solutionToString - * - Make sure that we escape text/plain content here, as feedback requires markup! - */ - - solution = currCell.metadata.ordo_solution['text/plain'] - var channel = currCell.metadata.ordo_channel || "result"; - console.debug("Current solution => " + solution); - feedback = "" - currCell.output_area.append_output({ - "output_type" : "display_data", - "data" : { - "text/html": feedback - }, - "metadata" : {} - }); - }); - } - } - } - } - }); - } + events.on('select.Cell', function(event, data) { + newCell = data.cell; + + if(data.cell == undefined) { + return; + } + + if($('.ordo_edit_mode').length == 0) { + return; + } + + + $(".show-ordo-solution").remove(); + $(".make-ordo-solution").remove(); + + if(data.cell.cell_type == "code") { + if(data.cell.output_area.outputs.length > 0){ + if(data.cell.output_area.outputs[0].output_type == "execute_result") { + $(".selected .output_area") + .first() + .append(""); + + + $(".make-ordo-solution").on("click", function() { + console.debug("updated metadata"); + data.cell.metadata.ordo_solution = data.cell.output_area.outputs[0].data; + }); + } + } + } + }); + }; + + /** + * returns the solution as a string for display purposes. this is used when the user clicks on + * Edit Solutions + * @param {Object} solution + * @returns {String} solution + */ + var solutionToString = function(solution) { + + /* TODO: change to "text/x-..." later */ + var acceptedMimeTypes = ["python", "text/html", "text/plain"]; + + + var mimeTypes = Object.keys(solution); + console.debug("mimeTypes", mimeTypes); + + + for(acceptedMimeType in acceptedMimeTypes) { + if (mimeTypes.includes(acceptedMimeType)) { + outStr = solution[acceptedMimeType]; + console.debug(outStr); + return outStr; + } + } + + return null; + }; + + + /** + * + * creates and appends a button to show the current solution to the user. + */ + var showSolutionButton = function () { + + events.on('select.Cell', function(event, data) { + + if(data.cell == undefined){ + return; + } + + if($('.ordo_feedback_mode').length == 0) { + return; + } + + + $(".show-ordo-solution").remove(); + + + if(data.cell.cell_type === "code" && data.cell.metadata && data.cell.metadata.ordo_solution) { + + if(data.cell.output_area.outputs.length > 0) { + console.debug("Show solution button"); + console.debug(data.cell.output_area.outputs[0].output_type); + + if(["execute_result", "stream"].includes(data.cell.output_area.outputs[0].output_type)) { + $(".selected .input") + .after("
"); + + $(".show-ordo-solution").one("click", function() { + console.debug(data.cell.metadata.ordo_solution); + + /* TODO: + * - Improve retrieval here based on a parametric solutionToString + * - Make sure that we escape text/plain content here, as feedback requires markup! + */ + + solution = data.cell.metadata.ordo_solution['text/plain']; + console.debug("Current solution => " + solution); + + feedback = ""; + + currCell.output_area.append_output({ + "output_type" : "display_data", + "data" : { + "text/html": feedback + }, + "metadata" : {} + }); + }); + } + } + } + }); + }; + + /** - * sets the solution for the current cell to be the solution for all cells in the notebook - */ - var allOutputsButton = function() { - var myFunc = function () { - cells = Jupyter.notebook.get_cells(); - for(i=0;i < cells.length;i++) { - if(cells[i].cell_type == "code") { - if(cells[i].output_area != undefined) { - if(cells[i].output_area.outputs.length > 0) { - if(cells[i].output_area.outputs[0].output_type == "execute_result") { - cells[i].metadata.ordo_solution = cells[i].output_area.outputs[0].data - console.debug("updated metadata"); - } - } - } - } - } - }; - var action = { - icon: 'fa-lightbulb-o', - help: 'Make all outputs solutions', - help_index: 'zz', - handler: myFunc - }; - var prefix = 'allOutputsButton'; - var action_name = 'show-button'; - var full_action_name = Jupyter.actions.register(action, action_name,prefix); - if($("[data-jupyter-action*='allOutputsButton']").length == 0) { - Jupyter.toolbar.add_buttons_group([full_action_name]); - } - } + * Sets the solution of each cell to the output of the cell. + */ + var allOutputsButton = function() { - /** - * toggles the cell mode between editing/creating solutions and giving feedback - */ - var ordoEditFeedbackToggle = function() { - var editMode = function() { - $('.command_mode').removeClass('ordo_feedback_mode'); - $('.command_mode').addClass('ordo_edit_mode'); - $("[data-jupyter-action*='feedbackToggle']").removeClass('active'); - $("[data-jupyter-action*='editModeToggle']").addClass('active'); - makeOutputButton(); - allOutputsButton(); - }; - var eMaction = { - icon: 'fa-pencil', - help: 'Enter ordo-edit mode', - help_index: 'zy', - handler: editMode - }; - var eMprefix = 'editModeToggle'; - var eMaction_name = 'EnterEditMode'; - var eM_action_name = Jupyter.actions.register(eMaction, eMaction_name, eMprefix); - - var feedbackMode = function() { - $('.command_mode').removeClass('ordo_edit_mode'); - $('.command_mode').addClass('ordo_feedback_mode'); - $("[data-jupyter-action*='editModeToggle']").removeClass('active'); - $("[data-jupyter-action*='feedbackToggle']").addClass('active'); - $("[data-jupyter-action*='allOutputsButton']").remove(); - $(".make-ordo-solution").remove(); - $(".ordo-user-input").remove(); - }; - var fMaction = { - icon: 'fa-check', - help: 'Enter feedback-only mode', - help_index: 'zx', - handler: feedbackMode - }; - var fMprefix = 'feedbackToggle'; - var fMaction_name = 'EnterFeedbackMode'; - var fM_action_name = Jupyter.actions.register(fMaction, fMaction_name, fMprefix); - - /* Jupyter.toolbar.add_buttons_group([fM_action_name,eM_action_name]) */ - var eMaction = { - icon: 'fa-pencil', - help: 'Enter ordo-edit mode', - help_index: 'zy', - handler: editMode - }; - var eMprefix = 'editModeToggle'; - var eMaction_name = 'EnterEditMode'; - var eM_action_name = Jupyter.actions.register(eMaction, eMaction_name, eMprefix); - - var toggleAdmonitions = function() { - var r = $("[data-jupyter-action*='toggleAdmonitions']").toggleClass('active'); - console.debug("toggleAdmonitions 'em!!!!"); - - Jupyter.notebook.get_cells(). - forEach(function (cell, idx, cells) { - var elem; - if (r.hasClass('active')) { - elem = cell.element.find("div.ordo-admonition-controls button.ordo-admonition-btn.active"); - } else { - elem = cell.element.find("div.ordo-admonition-controls :not(button.ordo-admonition-btn.active)"); - } - - if (elem.length > 0) { - onClickAdmonitionButton(cell, elem); - elem.toggleClass("active"); - } - }); - }; + var setAllCellOutputsAsCellSolutions = function () { - var admAction = { - icon: 'fa-window-close-o', - help: 'Open/ close all admonitions cells', - help_index: 'zz', - handler: toggleAdmonitions - }; + for(i=0; i < Jupyter.notebook.get_cells().length; i++) { - var admPrefix = 'toggleAdmonitions'; - var admAction_name = 'OpenCloseAdmonitions'; - var adm_action_name = Jupyter.actions.register(admAction, admAction_name, admPrefix); - - Jupyter.toolbar.add_buttons_group([fM_action_name,eM_action_name,adm_action_name]) + if(cells[i].cell_type == "code") { + + if(cells[i].output_area != undefined) { - $("[data-jupyter-action*='feedbackToggle']").addClass('active'); + if(cells[i].output_area.outputs.length > 0) { - } + if(cells[i].output_area.outputs[0].output_type == "execute_result") { + cells[i].metadata.ordo_solution = cells[i].output_area.outputs[0].data; + console.debug("updated metadata"); + } + } + } + } + } + }; + + + var action = { + icon: 'fa-lightbulb-o', + help: 'Make all outputs solutions', + help_index: 'zz', + handler: setAllCellOutputsAsCellSolutions + }; + + + var prefix = 'allOutputsButton'; + var action_name = 'show-button'; + var full_action_name = Jupyter.actions.register(action, action_name, prefix); + + + if($("[data-jupyter-action*='allOutputsButton']").length == 0) { + Jupyter.toolbar.add_buttons_group([full_action_name]); + } + }; + + + + /** + * toggles the cell mode between editing/creating solutions and giving feedback + */ + var ordoEditFeedbackToggle = function() { + var editMode = function() { + $('.command_mode').removeClass('ordo_feedback_mode'); + $('.command_mode').addClass('ordo_edit_mode'); + $("[data-jupyter-action*='feedbackToggle']").removeClass('active'); + $("[data-jupyter-action*='editModeToggle']").addClass('active'); + makeOutputButton(); + allOutputsButton(); + }; + + var eMaction = { + icon: 'fa-pencil', + help: 'Enter ordo-edit mode', + help_index: 'zy', + handler: editMode + }; + + + var eMprefix = 'editModeToggle'; + var eMaction_name = 'EnterEditMode'; + var eM_action_name = Jupyter.actions.register(eMaction, eMaction_name, eMprefix); + + + + + var feedbackMode = function() { + $('.command_mode').removeClass('ordo_edit_mode'); + $('.command_mode').addClass('ordo_feedback_mode'); + $("[data-jupyter-action*='editModeToggle']").removeClass('active'); + $("[data-jupyter-action*='feedbackToggle']").addClass('active'); + $("[data-jupyter-action*='allOutputsButton']").remove(); + $(".make-ordo-solution").remove(); + $(".ordo-user-input").remove(); + }; + + + var fMaction = { + icon: 'fa-check', + help: 'Enter feedback-only mode', + help_index: 'zx', + handler: feedbackMode + }; + + + var fMprefix = 'feedbackToggle'; + var fMaction_name = 'EnterFeedbackMode'; + var fM_action_name = Jupyter.actions.register(fMaction, fMaction_name, fMprefix); + + + + var toggleAdmonitions = function() { + var r = $("[data-jupyter-action*='toggleAdmonitions']").toggleClass('active'); + console.debug("toggleAdmonitions 'em!!!!"); + + Jupyter.notebook.get_cells().forEach(function (cell, idx, cells) { + + if (r.hasClass('active')) { + var elem = cell.element.find("div.ordo-admonition-controls button.ordo-admonition-btn.active"); + } else { + var elem = cell.element.find("div.ordo-admonition-controls :not(button.ordo-admonition-btn.active)"); + } + + if (elem.length > 0) { + onClickAdmonitionButton(cell, elem); + elem.toggleClass("active"); + } + }); + }; + + var admAction = { + icon: 'fa-window-close-o', + help: 'Open/ close all admonitions cells', + help_index: 'zz', + handler: toggleAdmonitions + }; + + var admPrefix = 'toggleAdmonitions'; + var admAction_name = 'OpenCloseAdmonitions'; + var adm_action_name = Jupyter.actions.register(admAction, admAction_name, admPrefix); + + Jupyter.toolbar.add_buttons_group([fM_action_name, eM_action_name, adm_action_name]); + + $("[data-jupyter-action*='feedbackToggle']").addClass('active'); + }; + + + /** + * Invokes the edit solution modal for a given cell + * @param {object} A jupyter notebook cell object + */ var onEditSol = function(cell) { - dialog.modal({ - 'title': 'Edit Solutions', - 'body': makeSolutionInputArea(cell), - 'buttons': { - 'Cancel': {}, - 'Save New Solution': { - 'id': 'save-solution-btn', - 'class': 'btn-primary', - 'click': function() { - sol = {} - sol[$('#output_type').val()] = $('#solution_text_area').val() - cell.metadata.ordo_solution = sol - cell.metadata.ordo_channel = $('input[name="channelOptions"]:checked').val(); - } - }, - }, - 'keyboard_manager': Jupyter.notebook.keyboard_manager, - 'notebook': Jupyter.notebook - }) + dialog.modal({ + 'title': 'Edit Solutions', + 'body': makeSolutionInputArea(cell), + 'buttons': { + 'Cancel': {}, + 'Save New Solution': { + 'id': 'save-solution-btn', + 'class': 'btn-primary', + 'click': function() { + sol = {}; + sol[$('#output_type').val()] = $('#solution_text_area').val(); + cell.metadata.ordo_solution = sol; + } + }, + }, + 'keyboard_manager': Jupyter.notebook.keyboard_manager, + 'notebook': Jupyter.notebook + }); }; + + + /** + * Invokes the edit success message modal for a given cell + * @param {object} A jupyter notebook cell object + */ var onEditSuccMsg = function(cell) { - dialog.modal({ - 'title': 'Edit Success Messages', - 'body': makeMessageInputArea(cell), - 'buttons': { - 'Cancel': {}, - 'Save New Message': { - 'id': 'save-success-msg-btn', - 'class': 'btn-primary', - 'click': function() { - if($('#styling').val() == "bold") { - sol = "" + $('#message_text_area').val() + "" - } else { - sol = $('#message_text_area').val() - } - cell.metadata.ordo_success = sol - } - }, - }, - 'keyboard_manager': Jupyter.notebook.keyboard_manager, - 'notebook': Jupyter.notebook - }) + dialog.modal({ + 'title': 'Edit Success Messages', + 'body': makeMessageInputArea(cell), + 'buttons': { + 'Cancel': {}, + 'Save New Message': { + 'id': 'save-success-msg-btn', + 'class': 'btn-primary', + 'click': function() { + if($('#styling').val() == "bold") { + sol = "" + $('#message_text_area').val() + ""; + } else { + sol = $('#message_text_area').val(); + } + + cell.metadata.ordo_success = sol; + } + }, + }, + 'keyboard_manager': Jupyter.notebook.keyboard_manager, + 'notebook': Jupyter.notebook + }) }; + + + /** + * Invokes the edit fail message modal for a given cell + * @param {object} A jupyter notebook cell object + */ var onEditFailMsg = function(cell) { - dialog.modal({ - 'title': 'Edit Failure Message', - 'body': makeMessageInputArea(cell), - 'buttons': { - 'Cancel': {}, - 'Save New Message': { - 'id': 'save-failure-msg-btn', - 'class': 'btn-primary', - 'click': function() { - if($('#styling').val() == "bold") { - sol = "" + $('#message_text_area').val() + "" - } else { - sol = $('#message_text_area').val() - } - cell.metadata.ordo_failure = sol - } - }, - }, - 'keyboard_manager': Jupyter.notebook.keyboard_manager, - 'notebook': Jupyter.notebook - }) - } + dialog.modal({ + 'title': 'Edit Failure Message', + 'body': makeMessageInputArea(cell), + 'buttons': { + 'Cancel': {}, + 'Save New Message': { + 'id': 'save-failure-msg-btn', + 'class': 'btn-primary', + 'click': function() { + if($('#styling').val() == "bold") { + sol = "" + $('#message_text_area').val() + ""; + } else { + sol = $('#message_text_area').val(); + } + + cell.metadata.ordo_failure = sol; + } + }, + }, + 'keyboard_manager': Jupyter.notebook.keyboard_manager, + 'notebook': Jupyter.notebook + }) + }; /** * creates the buttons and handles the functionality related to editing a solution */ var editMetadataButtons = function() { - var currCell = undefined; - events.on('select.Cell', function(event, data) { - newCell = data.cell; - if(newCell == currCell){ - return; - } else if($('.ordo_edit_mode').length == 0) { - return; - } else { - $(".ordo-user-input").remove(); - currCell = newCell; - if(currCell.cell_type == "code") { - $(".selected > .output_wrapper .output").append(ordoEditButtons); - $(".ordo-add-solution").on('click', (evt) => onEditSol(currCell)); - $(".ordo-add-success-msg").on('click', (evt) => onEditSuccMsg(currCell)); - $(".ordo-add-failure-msg").on('click', (evt) => onFailureSuccMsg(currCell)); - } - } - }); - } + + events.on('select.Cell', function(event, data) { + + if(data.cell == undefined){ + return; + } + + if($('.ordo_edit_mode').length == 0) { + return; + } + + + + $(".ordo-user-input").remove(); + + if(data.cell.cell_type == "code") { + $(".selected > .output_wrapper .output").append(ordoEditButtons); + $(".ordo-add-solution").on('click', (evt) => onEditSol(data.cell)); + $(".ordo-add-success-msg").on('click', (evt) => onEditSuccMsg(data.cell)); + $(".ordo-add-failure-msg").on('click', (evt) => onFailureSuccMsg(data.cell)); + } + + }); + }; - /** - * html for the feedback buttons on a cell - */ - var ordoEditButtons = - "
" + - "" + - "" + - "" + - "
"; - - /** - * html for the input box to create a feedback message - */ - var makeMessageInputArea = function() { - var styles= [ - 'bold', - 'plain text', - 'html' - ] - - $sel = $('