diff --git a/package-lock.json b/package-lock.json index 0e0a56833..aa315f782 100644 --- a/package-lock.json +++ b/package-lock.json @@ -15,7 +15,7 @@ "handsontable": "7.2.2", "jexcel": "^3.9.1", "jquery-ui": "1.10.4", - "micro-parsons": "https://github.com/amy21206/micro-parsons-element/releases/download/v0.1.3/micro-parsons-0.1.3.tgz", + "micro-parsons": "https://github.com/amy21206/micro-parsons-element/releases/download/v0.1.4/micro-parsons-0.1.4.tgz", "select2": "^4.1.0-rc.0", "sql.js": "1.5.0", "vega-embed": "3.14.0", @@ -2715,9 +2715,9 @@ } }, "node_modules/micro-parsons": { - "version": "0.1.3", - "resolved": "https://github.com/amy21206/micro-parsons-element/releases/download/v0.1.3/micro-parsons-0.1.3.tgz", - "integrity": "sha512-MkFh2oooq59u2+OwKUEokX3VtelYnEnmdoDj8yNDUiL/+TF6nlgzqmp13RPewFbYHosrA8kudikyEtsxVnilnw==", + "version": "0.1.4", + "resolved": "https://github.com/amy21206/micro-parsons-element/releases/download/v0.1.4/micro-parsons-0.1.4.tgz", + "integrity": "sha512-3hg55GJpg779Vhyzk2Ij3Jz/e6UKZGltwpA60EegQrT4C0XR1ioWBoZutNy2BZ5bR6LCC8RXCky4gF9qxl7/ew==", "license": "MIT", "dependencies": { "highlight.js": "^11.7.0", @@ -7844,8 +7844,8 @@ "dev": true }, "micro-parsons": { - "version": "https://github.com/amy21206/micro-parsons-element/releases/download/v0.1.3/micro-parsons-0.1.3.tgz", - "integrity": "sha512-MkFh2oooq59u2+OwKUEokX3VtelYnEnmdoDj8yNDUiL/+TF6nlgzqmp13RPewFbYHosrA8kudikyEtsxVnilnw==", + "version": "https://github.com/amy21206/micro-parsons-element/releases/download/v0.1.4/micro-parsons-0.1.4.tgz", + "integrity": "sha512-3hg55GJpg779Vhyzk2Ij3Jz/e6UKZGltwpA60EegQrT4C0XR1ioWBoZutNy2BZ5bR6LCC8RXCky4gF9qxl7/ew==", "requires": { "highlight.js": "^11.7.0", "sortablejs": "^1.14.0" diff --git a/package.json b/package.json index 0bbe8c470..952b4d372 100644 --- a/package.json +++ b/package.json @@ -36,7 +36,7 @@ "handsontable": "7.2.2", "jexcel": "^3.9.1", "jquery-ui": "1.10.4", - "micro-parsons": "https://github.com/amy21206/micro-parsons-element/releases/download/v0.1.3/micro-parsons-0.1.3.tgz", + "micro-parsons": "https://github.com/amy21206/micro-parsons-element/releases/download/v0.1.4/micro-parsons-0.1.4.tgz", "select2": "^4.1.0-rc.0", "sql.js": "1.5.0", "vega-embed": "3.14.0", diff --git a/runestone/hparsons/js/SQLFeedback.js b/runestone/hparsons/js/SQLFeedback.js index dcc683849..b77156c91 100644 --- a/runestone/hparsons/js/SQLFeedback.js +++ b/runestone/hparsons/js/SQLFeedback.js @@ -261,13 +261,10 @@ export default class SQLFeedback extends HParsonsFeedback { // adapted from activecode async buildProg() { // assemble code from prefix, suffix, and editor for running. - // TODO: fix or remove text entry + // TODO: automatically joins the text array with space. + // Should be joining without space when implementing regex. var prog; - if (this.hparsons.textentry) { - prog = this.hparsons.hparsonsInput.getCurrentInput(); - } else { - prog = this.hparsons.hparsonsInput.getParsonsTextArray().join(' ') + "\n"; - } + prog = this.hparsons.hparsonsInput.getParsonsTextArray().join(' ') + "\n"; return Promise.resolve(prog); } diff --git a/runestone/hparsons/js/hparsons.js b/runestone/hparsons/js/hparsons.js index ba67c502f..a78429307 100644 --- a/runestone/hparsons/js/hparsons.js +++ b/runestone/hparsons/js/hparsons.js @@ -28,6 +28,11 @@ export default class HParsons extends RunestoneBase { this.divid = opts.orig.id; this.containerDiv = opts.orig; this.useRunestoneServices = opts.useRunestoneServices; + + // Set the storageId (key for storing data) + var storageId = super.localStorageKey(); + this.storageId = storageId; + this.origElem = orig; this.origText = this.origElem.textContent; this.code = $(orig).text() || "\n\n\n\n\n"; @@ -71,6 +76,7 @@ export default class HParsons extends RunestoneBase { // initializing functionalities for different feedback this.feedbackController.init(); + this.checkServer('hparsons', true); } // copied from activecode, already modified to add parsons @@ -110,7 +116,6 @@ export default class HParsons extends RunestoneBase { this.feedbackController.createOutput(); } - // copied from activecode createControls() { var ctrlDiv = document.createElement("div"); $(ctrlDiv).addClass("hp_actions"); @@ -122,8 +127,10 @@ export default class HParsons extends RunestoneBase { ctrlDiv.appendChild(this.runButton); $(this.runButton).attr("type", "button"); $(this.runButton).text("Run"); + var that = this; this.runButton.onclick = () => { - this.feedbackController.runButtonHandler(); + that.feedbackController.runButtonHandler(); + that.setLocalStorage(); }; // Reset button @@ -134,8 +141,9 @@ export default class HParsons extends RunestoneBase { ctrlDiv.appendChild(resetBtn); this.resetButton = resetBtn; this.resetButton.onclick = () => { - this.hparsonsInput.resetInput(); - this.feedbackController.reset(); + that.hparsonsInput.resetInput(); + that.setLocalStorage(); + that.feedbackController.reset(); }; $(resetBtn).attr("type", "button"); @@ -143,6 +151,69 @@ export default class HParsons extends RunestoneBase { this.controlDiv = ctrlDiv; } + // Return previous answers in local storage + // + localData() { + var data = localStorage.getItem(this.storageId); + if (data !== null) { + if (data.charAt(0) == "{") { + data = JSON.parse(data); + } else { + data = {}; + } + } else { + data = {}; + } + return data; + } + // RunestoneBase: Sent when the server has data + restoreAnswers(serverData) { + // TODO: not tested with server data yet. + // Server side data should be: + /* + { + answer: Array, // list of answer block content + count: ?number // number of previous attempts if block-based feedback + } + */ + if (serverData.answer){ + this.hparsonsInput.restoreAnswer(serverData.answer); + } + if (serverData.count) { + this.feedbackController.checkCount = serverData.count; + } + } + // RunestoneBase: Load what is in local storage + checkLocalStorage() { + if (this.graderactive) { + // Zihan: I think this means the component is still loading? + return; + } + let localData = this.localData(); + if (localData.answer) { + this.hparsonsInput.restoreAnswer(localData.answer); + } + if (localData.count) { + this.feedbackController.checkCount = localData.count; + } + } + // RunestoneBase: Set the state of the problem in local storage + setLocalStorage(data) { + let currentState = {}; + if (data == undefined) { + currentState = { + answer: this.hparsonsInput.getParsonsTextArray() + } + if (this.isBlockGrading) { + // if this is block grading, add number of previous attempts too + currentState.count = this.feedbackController.checkCount; + } + } else { + currentState = data; + } + localStorage.setItem(this.storageId, JSON.stringify(currentState)); + } + logHorizontalParsonsEvent(hparsonsEvent) { let ev = { event: "hparsons",