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 = $(' ');
- btn.addClass('btn btn-sm btn-primary ordo-admonition-btn').attr('data-toggle', 'button');
-
- /* Make sure that the magic happens when the DOM sub-structure
- of a given admonition cell has been fully loaded */
-
- cell.element.ready(function() {
- if (params.enableModeToggle) {
- btn.addClass('active').attr('aria-pressed', true);
- cell.element.find('div.ordo-admonition-controls').nextAll().show();
- btn.text('Close');
- } else {
- btn.attr('aria-pressed', false);
- cell.element.find('div.ordo-admonition-controls').nextAll().hide();
- btn.text('Open');
- }
- });
+ console.debug("toggleOpenButton");
+ console.debug(cell);
+
+ if (cell.metadata.ordo !== undefined &&
+ cell.metadata.ordo.admonition !== undefined &&
+ cell.metadata.ordo.admonition) {
+
+ var ordoDiv = $('
')
+ .addClass("text-center")
+ .addClass('ordo-admonition-controls');
+
+ var btn = $(' ')
+ .addClass('btn btn-sm btn-primary ordo-admonition-btn')
+ .attr('data-toggle', 'button');
+
+
+ /*
+ Make sure that the magic happens when the DOM sub-structure
+ of a given admonition cell has been fully loaded
+ */
+
+ cell.element.ready(function() {
+ if (params.enableModeToggle) {
+ btn.addClass('active').attr('aria-pressed', true);
+ cell.element.find('div.ordo-admonition-controls').nextAll().show();
+ btn.text('Close');
+ } else {
+ btn.attr('aria-pressed', false);
+ cell.element.find('div.ordo-admonition-controls').nextAll().hide();
+ btn.text('Open');
+ }
+ });
- btn.click(function() { onClickAdmonitionButton(cell,$(this)) });
- console.debug("PREPENDING", localDiv);
- cell.element.prepend(localDiv.append(btn));
- } else {
- console.debug("NOT PREPENDING");
- cell.element.find('div.ordo-admonition-controls').remove();
- }
- }
+ btn.click(function() { onClickAdmonitionButton(cell,$(this)) });
+
+ cell.element.prepend(ordoDiv.append(btn));
+ } else {
+ cell.element.find('div.ordo-admonition-controls').remove();
+ }
+ };
+
+
+ /**
+ * Creates and adds the ordo cell toolbar to the given cell
+ * @param {*} div
+ * @param {*} cell
+ * @param {*} celltoolbar
+ */
var createCellToolbar = function (div, cell, celltoolbar) {
- var localDiv = $('
').addClass('ordo-celltoolbar');
+ var ordoDiv = $('
').addClass('ordo-celltoolbar');
- /* Authoring */
- if (cell.cell_type === null) {
- events.on('create.Cell', (event, data) => {
- events.off(event);
- createCellToolbar(div, cell, celltoolbar)
- });
- } else {
+ /* Authoring */
+ if (cell.cell_type === null) {
+
+ events.on('create.Cell', (event, _) => {
+ events.off(event);
+ createCellToolbar(div, cell, celltoolbar);
+ });
- if (cell.cell_type === 'code') {
- var editSolBtn = $(' ').addClass('btn btn-sm btn-secondary').text('Edit solutions').click((evt) => onEditSol(cell));
- var editSuccBtn = $(' ').addClass('btn btn-sm btn-secondary').text('Edit success message').click((evt) => onEditSuccMsg(cell));
- var editFailBtn = $(' ').addClass('btn btn-sm btn-secondary').text('Edit failure message').click((evt) => onEditFailMsg(cell));;
- var authGrp = $('
').addClass('btn-group').
- attr('role', 'group').
- attr('aria-label', 'Buttons for authoring cell solutions');
- authGrp.append(editSolBtn).append(editSuccBtn).append(editFailBtn);
- localDiv.append(authGrp);
- }
+ } else {
+ if (cell.cell_type === 'code') {
+ var editSolBtn = $(' ')
+ .addClass('btn btn-sm btn-secondary')
+ .text('Edit solutions')
+ .click((evt) => onEditSol(cell));
+
+ var editSuccBtn = $(' ')
+ .addClass('btn btn-sm btn-secondary')
+ .text('Edit success message')
+ .click((evt) => onEditSuccMsg(cell));
+
+ var editFailBtn = $(' ')
+ .addClass('btn btn-sm btn-secondary')
+ .text('Edit failure message')
+ .click((evt) => onEditFailMsg(cell));;
+
+
+ var authGrp = $('
')
+ .addClass('btn-group')
+ .attr('role', 'group')
+ .attr('aria-label', 'Buttons for authoring cell solutions');
+
- /* Admonition */
- var adm = $(' ');
+ authGrp.append(editSolBtn).append(editSuccBtn).append(editFailBtn);
+
+ ordoDiv.append(authGrp);
+ }
- adm.addClass('btn btn-sm btn-secondary').attr('data-toggle', 'button').attr('aria-pressed', false)
- .text('Make admonition');
- if (cell.metadata.ordo !== undefined &&
- cell.metadata.ordo.admonition !== undefined &&
- cell.metadata.ordo.admonition) {
- adm.addClass('active').attr('aria-pressed', true);
- }
-
- adm.click(() => {
-
- if (cell.metadata.ordo === undefined) {
- cell.metadata.ordo = {};
- }
-
- if (cell.metadata.ordo.admonition === undefined) {
- cell.metadata.ordo.admonition = true;
- cell.element.addClass('ordo-admonition-on');
- } else {
- delete cell.metadata.ordo.admonition;
- cell.element.removeClass('ordo-admonition-on');
- }
- toggleOpenButton(cell);
-
- });
+ /* Admonition */
+ var adm = $(' ')
+ .addClass('btn btn-sm btn-secondary')
+ .attr('data-toggle', 'button')
+ .attr('aria-pressed', false)
+ .text('Make admonition');
- $(div).append(localDiv.append(adm));
- }
+ if (cell.metadata.ordo !== undefined &&
+ cell.metadata.ordo.admonition !== undefined &&
+ cell.metadata.ordo.admonition) {
+ adm.addClass('active').attr('aria-pressed', true);
+ }
+
+
+ adm.click(() => {
+
+ if (cell.metadata.ordo === undefined) {
+ cell.metadata.ordo = {};
+ }
+
+ if (cell.metadata.ordo.admonition === undefined) {
+ cell.metadata.ordo.admonition = true;
+ cell.element.addClass('ordo-admonition-on');
+ } else {
+ delete cell.metadata.ordo.admonition;
+ cell.element.removeClass('ordo-admonition-on');
+ }
+
+ toggleOpenButton(cell);
+
+ });
+
+
+ $(div).append(ordoDiv.append(adm));
+ }
};
+
+ /**
+ * Adds ordo UI to all cells
+ */
var initializeCells = function() {
- console.log(Jupyter.notebook.get_cells());
- Jupyter.notebook.get_cells().forEach(function (cell, idx, cells) {
- console.debug("initializeCells");
- console.debug(cell.metadata);
- toggleOpenButton(cell);
- });
-
- /* handle copy/ cut & paste of cells */
- events.on('create.Cell', (event, data) => {
- var cell = data.cell;
- /* Metadata might not be available upon create.Cell, so we
- * have to defer ... */
- events.one('set_dirty.Notebook', (event, data) => {
- toggleOpenButton(cell);
- });
- });
- }
+
+ Jupyter.notebook.get_cells().forEach(function (cell, idx, cells) {
+ console.debug("initializeCells");
+ console.debug(cell.metadata);
+
+ toggleOpenButton(cell);
+ });
+ };
+
/**
- * reads configuration properties containing default feedback responses for the plugin
+ * reads and sets configuration properties, which contains the default messages
+ * for failure and success
*/
var readConfig = function() {
-
- $.extend(true, params, Jupyter.notebook.config.data.ordo);
- console.debug(params);
-
- /* FIXME: for the time being, set old variables */
- defaultFailure = params['defaultFailure'];
- defaultSuccess = params['defaultSuccess'];
-
+
+ $.extend(true, params, Jupyter.notebook.config.data.ordo);
+ console.debug(params);
+
+ /* FIXME: for the time being, set old variables */
+ defaultFailure = params['defaultFailure'];
+ defaultSuccess = params['defaultSuccess'];
};
-
+
+
+ /**
+ * Sends python code to the kernel for excecution and returns the result
+ * @param {*} python
+ * @returns {*} The result of the excecution
+ */
var executePython = function(python) {
- console.debug("define: ", python);
-
- return (new Promise((resolve, reject) => {
- console.debug("1. executePython: " + python);
- Jupyter.notebook.kernel.execute(python, {
- iopub: { output: (msg) => {
- console.debug("CALLBACK: ", msg);
- /* TODO: Fix for error cases, check for status == error etc. */
- if (msg.msg_type === 'execute_result') {
- console.debug("CALLBACK (result): ", solutionToString(msg.content.data));
- resolve(msg.content.data)
- }
- }}}, { silent: false });
- })).then((result) => { console.debug("2. executePython" + result); return result; });
- }
+ console.debug("define: ", python);
+
+ result = new Promise((resolve, reject) => {
+ console.debug("Promise Python:", python);
+
+ Jupyter.notebook.kernel.execute(
+ python, {
+ iopub: {
+ output: (msg) => {
+ console.debug("CALLBACK: ", msg);
+
+ /* TODO: Fix for error cases, check for status == error etc. */
+ if (msg.msg_type === 'execute_result') {
+ console.debug("CALLBACK (result): ", solutionToString(msg.content.data));
+
+ resolve(msg.content.data);
+ }
+ }
+ }
+ },
+ {silent: false}
+ );
+ }).then((result) => {
+ console.debug("Promise result ", result);
+
+ return result;
+ });
+
+ return result;
+ };
var getOutput = function(obj) {
@@ -362,144 +440,137 @@ define([
}
/**
- * Capture output_appended.OutputArea event for the result value
- * Capture finished_execute.CodeCell event for the data value
- * check for a solution in cell metadata
- * if exists:
- * check only one area appended (ends recursion)
- * if true:
- * check result against solution
- * if result correct:
- * append the success message
- * if result incorrect:
- * append the failure message
+ * executes the solution upon the event finished_execute.CodeCell and appends the result
+ * to the output area called
+ * @param {object} evt the event finished_execute.CodeCell. not used withing the function
+ * @param {object} obj an objectwhich provides access to the cell via property cell
*/
-
var onCodeCellExecuted = async function(evt, obj) {
-
- var solution = obj.cell.metadata.ordo_solution;
- var feedback;
- if (solution !== undefined) {
- var res;
- var output = getOutput(obj);
-
- console.debug("OUTPUT", output);
-
- 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;
- }
-
- if (output === undefined) {
- /* We have a solution, but a required output is missing */
- var channel = obj.cell.metadata.ordo_channel || "result";
- console.debug("[ordo] missing output, but required", solution)
- feedback = " " +
- "× " +
- "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 = " " +
+ "× " +
+ "Well Done! That was the correct response. " +
+ "
";
+
+ return feedback;
+ }
+
+ if (success_msg == undefined && defaultSuccess) {
+ feedback = " " +
+ "× " +
+ defaultSuccess +
+ "
"
+
+ return feedback;
+ }
+
+ feedback = " " +
+ "× " +
+ success_msg +
+ "
"
+
+ return feedback;
+ }
+
+
+ /*
+ Solution was wrong.
+ */
+
+ if (failure_msg == undefined) {
+ feedback = " " +
+ "× " +
+ "Oh no! That wasn't quite right. " +
+ "
"
+
+ return feedback;
+ }
+
+ if (failure_msg == undefined && defaultFailure) {
+ feedback = " " +
+ "× " +
+ defaultFailure +
+ "
"
+
+ return feedback;
+ }
+
+ feedback = "" +
+ "× " +
+ failure_msg +
+ "
"
+
+ 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 = " " +
- "× " +
- "Well Done! That was the correct response. " +
- "
"
- } else if (success_msg == undefined && defaultSuccess) {
- feedback = " " +
- "× " +
- defaultSuccess +
- "
"
- } else {
- feedback = " " +
- "× " +
- success_msg +
- "
"
- }
- } else {
- if (failure_msg == undefined) {
- feedback = " " +
- "× " +
- "Oh no! That wasn't quite right. " +
- "
"
- } else if (failure_msg == undefined && defaultFailure) {
- feedback = " " +
- "× " +
- defaultFailure +
- "
"
- } else {
- feedback = "" +
- "× " +
- failure_msg +
- "
"
- }
- }
- 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 solution ");
- $(".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 = "" +
- "
× " +
- "
Expected solution is (on "+ channel + "
): " + solution + " "
- 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 solution ");
+
+
+ $(".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 = "" +
+ "× " +
+ " Expected solution is: " + solution + "
";
+
+ 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 =
- "" +
- " Solution " +
- " Message " +
- " Message " +
- "
";
-
- /**
- * html for the input box to create a feedback message
- */
- var makeMessageInputArea = function() {
- var styles= [
- 'bold',
- 'plain text',
- 'html'
- ]
-
- $sel = $(' ', {
- 'class': "form-control",
- 'id': "styling",
- 'title': 'Select the styling for the following text'
- })
- $.each(styles, function(index, type) {
- $sel.append("" + type + " ")
- })
-
- var inputArea = $('
', {
- 'class': 'inputArea'
- }).append(
- $('
', {
- 'title': 'Message Input Area'
- }).append(
- $('', {
- 'class': "form-inline"
- }).append($sel)
- .append(
- $('', {
- 'class': 'form-control',
- 'id': 'message_text_area',
- 'rows': '2',
- 'style': 'width:70%',
- 'title': 'Input text here!'
- }))
- .append(
- $(' ', {
- 'class': 'btn btn-default add-field',
- 'title': 'Add another field'
- }).append(
- $(' ', {
- 'class': 'fa fa-plus'
- })
- )
- )
- .append($('
', {
- 'class': 'form-text text-muted',
- 'text': 'When html is selected, users may format their message using html as desired.'
- }))
- )
- )
- return inputArea;
- }
+
+ /**
+ * html for the feedback buttons on a cell
+ */
+ var ordoEditButtons =
+ "" +
+ " Solution " +
+ " Message " +
+ " Message " +
+ "
";
- /**
- * html for the input form to create a solution
- */
+
+ /**
+ * Assembles the html for the input box and returns it
+ * @returns {String} inputArea the html for the input box as a string
+ */
+ var makeMessageInputArea = function() {
+ var styles= [
+ 'bold',
+ 'plain text',
+ 'html'
+ ];
+
+ $sel = $(' ', {
+ 'class': "form-control",
+ 'id': "styling",
+ 'title': 'Select the styling for the following text'
+ });
+
+ $.each(styles, function(index, type) {
+ $sel.append("" + type + " ")
+ });
+
+
+
+ var inputArea =
+ $('
', {'class': 'inputArea'}).append(
+ $('
', {'title': 'Message Input Area'}).append(
+ $('', {'class': "form-inline"}).append($sel).append(
+ $('', {
+ 'class': 'form-control',
+ 'id': 'message_text_area',
+ 'rows': '2',
+ 'style': 'width:70%',
+ 'title': 'Input text here!'})).append(
+ $(' ', {
+ 'class': 'btn btn-default add-field',
+ 'title': 'Add another field'}).append(
+ $(' ', {
+ 'class': 'fa fa-plus'}))).append(
+ $('
', {
+ 'class': 'form-text text-muted',
+ 'text': 'When html is selected, users may format their message using html as desired.'
+ }))
+ )
+ );
+
+ return inputArea;
+ };
+
+
+
+ /**
+ * Assembles HTML for the create a solution input form and returns it as a string
+ * @param {Object} cell The jupyter notebooks cell object
+ * @returns {String} inputArea The create a solution input form HTML as a string
+ */
var makeSolutionInputArea = function(cell) {
- solution = cell.metadata.ordo_solution;
- channel = cell.metadata.ordo_channel;
- console.debug("makeSolutionInputArea", solution, channel);
-
- var output_types = [
- 'text/plain',
- 'text/html',
- 'text/markdown',
- 'text/latex',
- 'image/svg+xml',
- 'image/png',
- 'image/jpeg',
- 'application/javascript',
- 'application/pdf',
- 'python'
- ]
-
- $sel = $(' ', {
- 'class': "form-control solution_type",
- 'id': "output_type",
- 'title': 'Select the output type'
- })
-
- $.each(output_types, function(index, type) {
- opt = $("" + type + " ");
- if (solution !== undefined && solution[type] !== undefined) {
- console.log(type, solution[type]);
- opt.attr('selected', true);
- }
- $sel.append(opt);
- })
-
- var inputArea = $('
', {
- 'title': 'Solution Input Area'
- }).append(
- $('', {
- 'class': "form-inline"
- }).append($sel)
- .append('' +
- ' ' +
- 'result ' +
- '
' +
- '' +
- ' '+
- 'stdout '+
- '
'+
- ''+
- ' ' +
- 'stderr '+
- '
')
- .append($('', {
- 'class': 'form-control solution_text_area',
- 'id': 'solution_text_area',
- 'rows': '2',
- 'style': 'width:65%',
- 'title': 'Input text here!'
- })).append(
- $(' ', {
- 'class': 'fa fa-plus'
- })
- )
- )
-
- if (solution !== undefined) {
- $('#solution_text_area', inputArea).val(solutionToString(solution));
- }
-
- if (channel !== undefined) {
- $('input[name="channelOptions"]:checked', inputArea).prop('checked', false);
- $('input[name="channelOptions"][value="' + channel + '"]', inputArea).prop('checked', true);
- }
-
- return inputArea;
- }
-
- var ordo_exts = function() {
- return Jupyter.notebook.config.loaded.then(readConfig).then(initialize).catch(function on_error (reason) {
- console.error('Error:', reason);
+ console.debug("makeSolutionInputArea", cell.metadata.ordo_solution);
+
+ var output_types = [
+ 'text/plain',
+ 'text/html',
+ 'text/markdown',
+ 'text/latex',
+ 'image/svg+xml',
+ 'image/png',
+ 'image/jpeg',
+ 'application/javascript',
+ 'application/pdf',
+ 'python'
+ ];
+
+ $sel = $(' ', {
+ 'class': "form-control solution_type",
+ 'id': "output_type",
+ 'title': 'Select the output type'
});
- }
+
+ $.each(output_types, function(index, type) {
+ opt = $("" + type + " ");
+
+ if (cell.metadata.ordo_solution !== undefined && cell.metadata.ordo_solution[type] !== undefined) {
+ console.log(type, cell.metadata.ordo_solution[type]);
+ opt.attr('selected', true);
+ }
+
+ $sel.append(opt);
+ })
+
+
+ var inputArea = $('
', {
+ 'title': 'Solution Input Area'
+ }).append(
+ $('', {
+ 'class': "form-inline"
+ }).append($sel).append(
+ $('', {
+ 'class': 'form-control solution_text_area',
+ 'id': 'solution_text_area',
+ 'rows': '2',
+ 'style': 'width:65%',
+ 'title': 'Input text here!'
+ })).append(
+ $(' ', {
+ 'class': 'btn btn-default',
+ 'title': 'Add another field'
+ }).append(
+ $(' ', {
+ 'class': 'fa fa-plus'
+ })
+ )
+ )
+ );
+
+
+ if (cell.metadata.ordo_solution !== undefined) {
+ $('#solution_text_area', inputArea).val(solutionToString(cell.metadata.ordo_solution));
+ }
+
+ return inputArea;
+ };
+
+
+ var ordo_exts = function() {
+ return Jupyter.notebook.config.loaded
+ .then(readConfig)
+ .then(initialize)
+ .catch(function on_error(reason) {
+ console.error('Error:', reason);
+ });
+ };
+
return {
- load_ipython_extension: ordo_exts
+ load_ipython_extension: ordo_exts
}
});