feedback.js.html 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329
  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="utf-8">
  5. <title>JSDoc: Source: feedback.js</title>
  6. <script src="scripts/prettify/prettify.js"> </script>
  7. <script src="scripts/prettify/lang-css.js"> </script>
  8. <!--[if lt IE 9]>
  9. <script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script>
  10. <![endif]-->
  11. <link type="text/css" rel="stylesheet" href="styles/prettify-tomorrow.css">
  12. <link type="text/css" rel="stylesheet" href="styles/jsdoc-default.css">
  13. </head>
  14. <body>
  15. <div id="main">
  16. <h1 class="page-title">Source: feedback.js</h1>
  17. <section>
  18. <article>
  19. <pre class="prettyprint source linenums"><code>/**
  20. * An object that manages the feedback area, where users are told the state of their
  21. * program's execution and given guidance. Also manages the creation of the Trace Table.
  22. *
  23. * @constructor
  24. * @this {BlockPyFeedback}
  25. * @param {Object} main - The main BlockPy instance
  26. * @param {HTMLElement} tag - The HTML object this is attached to.
  27. */
  28. function BlockPyFeedback(main, tag) {
  29. this.main = main;
  30. this.tag = tag;
  31. this.body = this.tag.find('.blockpy-feedback-body');
  32. this.title = this.tag.find('.blockpy-feedback-title');
  33. this.original = this.tag.find('.blockpy-feedback-original');
  34. this.status = this.tag.find('.blockpy-feedback-status');
  35. this.trace = this.tag.find('.blockpy-feedback-trace');
  36. // Reload the tracetable on click
  37. this.trace.click(this.buildTraceTable.bind(this));
  38. this.original.hide();
  39. };
  40. /**
  41. * Reload the trace table, showing it if it was hidden and
  42. * resetting its position to the last step.
  43. */
  44. BlockPyFeedback.prototype.buildTraceTable = function() {
  45. var execution = this.main.model.execution;
  46. execution.show_trace(true);
  47. execution.trace_step(execution.last_step());
  48. this.main.components.server.logEvent('editor', 'trace')
  49. }
  50. /**
  51. * Raises a generic warning. This might not be used anymore.
  52. *
  53. * @param {String} html - Some HTML content to render to the user.
  54. */
  55. BlockPyFeedback.prototype.error = function(html) {
  56. this.tag.html(html);
  57. this.tag.removeClass("alert-success");
  58. this.tag.addClass("alert-warning");
  59. this.main.components.printer.print("Execution stopped - there was an error!");
  60. }
  61. /**
  62. * Clears any output currently in the feedback area. Also resets the printer and
  63. * any highlighted lines in the editor.
  64. */
  65. BlockPyFeedback.prototype.clear = function() {
  66. this.title.html("Ready");
  67. this.original.hide();
  68. this.body.html("Run your program to get feedback.");
  69. this.main.model.status.error("none");
  70. this.main.components.editor.unhighlightLines();
  71. this.main.components.printer.resetPrinter()
  72. };
  73. /**
  74. * Clears any errors from the editor area.
  75. */
  76. BlockPyFeedback.prototype.clearEditorErrors = function() {
  77. if (this.main.model.status.error() == "editor") {
  78. this.clear();
  79. }
  80. }
  81. /**
  82. * Show an error message related to a problem with the editor. This will appear in
  83. * the Feedback area, the Printer, and also log to the server. The relevant line of
  84. * code or block will also be highlighted.
  85. *
  86. * @param {String} original - HTML content that represents the original error message generated by the system.
  87. * @param {String} message - HTML content that is a hopefully friendlier message for the user explaining the error.
  88. * @param {number} line - What line the error occurred on.
  89. */
  90. BlockPyFeedback.prototype.editorError = function(original, message, line) {
  91. original = this.prettyPrintError(original);
  92. this.title.html("Editor Error");
  93. this.original.show().html(original);
  94. this.body.html(message);
  95. this.main.model.status.error("editor");
  96. this.main.components.editor.highlightError(line-1);
  97. //this.main.components.printer.print("Editor error - could not make blocks!");
  98. this.main.components.server.logEvent('feedback', "Editor Error", original+"\n|\n"+message);
  99. }
  100. /**
  101. * Mark this problem as completed for the student. This will appear in the Feedback area,
  102. * and will also unhighlight lines in the editor and log to the server.
  103. */
  104. BlockPyFeedback.prototype.complete = function() {
  105. this.title.html("Complete!");
  106. this.original.hide();
  107. this.body.html("Great work!");
  108. this.main.model.status.error("complete");
  109. this.main.components.editor.unhighlightLines();
  110. this.main.components.server.logEvent('feedback', "Success");
  111. }
  112. /**
  113. * Mark this problem as finished for the student. This will appear in the Feedback area,
  114. * and will also unhighlight lines in the editor and log to the server.
  115. */
  116. BlockPyFeedback.prototype.finished = function() {
  117. this.title.html("Ran");
  118. this.original.hide();
  119. this.body.html("Your program ran successfully, without any errors. However, this problem does not have a correct solution. When you are satisfied with your program, you may stop working.");
  120. this.main.model.status.error("no errors");
  121. this.main.components.editor.unhighlightLines();
  122. this.main.components.server.logEvent('feedback', "Finished");
  123. }
  124. /**
  125. * This notifies the student that their code ran without errors, but that there was no
  126. * Success raised by the Checker. This will appear in the Feedback area,
  127. * and will also unhighlight lines in the editor and log to the server.
  128. */
  129. BlockPyFeedback.prototype.noErrors = function() {
  130. this.title.html("Ran");
  131. this.original.hide();
  132. this.body.html("No errors reported. View your output on the left.");
  133. this.main.model.status.error("no errors");
  134. this.main.components.editor.unhighlightLines();
  135. this.main.components.server.logEvent('feedback', "No Errors", '');
  136. }
  137. /**
  138. * Show an error message related to syntax issue. This will appear in
  139. * the Feedback area, the Printer, and also log to the server. The relevant line of
  140. * code or block will also be highlighted.
  141. *
  142. * @param {String} original - HTML content that represents the original error message generated by the system.
  143. * @param {String} message - HTML content that is a hopefully friendlier message for the user explaining the error.
  144. * @param {number} line - What line the error occurred on.
  145. */
  146. BlockPyFeedback.prototype.syntaxError = function(original, message, line) {
  147. original = this.prettyPrintError(original);
  148. this.title.html("Syntax Error");
  149. this.original.show().html(original);
  150. this.body.html(message);
  151. this.main.model.status.error("syntax");
  152. this.main.components.editor.highlightError(line-1);
  153. this.main.components.printer.print("Execution stopped - there was an error!");
  154. this.main.components.server.logEvent('feedback', "Syntax Error", original+"\n|\n"+message);
  155. }
  156. /**
  157. * Show an error message related to semantic error with the program (e.g., unused variable).
  158. * This will appear in the Feedback area, the Printer, and also log to the server. The
  159. * relevant line of code or block will also be highlighted.
  160. *
  161. * @param {String} original - HTML content that represents the original error message generated by the system.
  162. * @param {String} message - HTML content that is a hopefully friendlier message for the user explaining the error.
  163. * @param {number} line - What line the error occurred on.
  164. */
  165. BlockPyFeedback.prototype.semanticError = function(name, message, line) {
  166. this.title.html(name);
  167. this.original.hide();
  168. this.body.html(message);
  169. this.main.model.status.error("semantic");
  170. if (line !== null) {
  171. this.main.components.editor.highlightError(line-1);
  172. }
  173. this.main.components.printer.print("Execution stopped - there was an error!");
  174. this.main.components.server.logEvent('feedback', "Semantic Error", name+"\n|\n"+message);
  175. }
  176. /**
  177. * Show an error message related to a serious internal BlockPy program. Under normal conditions,
  178. * this should never appear to a student. This will appear in
  179. * the Feedback area, the Printer, and also log to the server. The relevant line of
  180. * code or block will also be highlighted.
  181. *
  182. * @param {String} original - HTML content that represents the original error message generated by the system.
  183. * @param {String} message - HTML content that is a hopefully friendlier message for the user explaining the error.
  184. * @param {number} line - What line the error occurred on.
  185. */
  186. BlockPyFeedback.prototype.internalError = function(original, name, message) {
  187. original = this.prettyPrintError(original);
  188. this.title.html(name);
  189. this.original.show().html(original);
  190. this.body.html(message);
  191. this.main.model.status.error("internal");
  192. this.main.components.printer.print("Internal error! Please show this to an instructor!");
  193. this.main.components.server.logEvent('feedback', "Internal Error", name+"\n|\n"+original+"\n|\n"+message);
  194. }
  195. /**
  196. * Show an incorrect code message related to a problem as specified by the Checker. This will appear in
  197. * the Feedback area, the Printer, and also log to the server. The relevant line of
  198. * code or block will also be highlighted.
  199. *
  200. * @param {String} original - HTML content that represents the original error message generated by the system.
  201. * @param {String} message - HTML content that is a hopefully friendlier message for the user explaining the error.
  202. * @param {number} line - What line the error occurred on.
  203. */
  204. BlockPyFeedback.prototype.instructorFeedback = function(name, message, line) {
  205. this.title.html(name);
  206. this.original.hide();
  207. this.body.html(message);
  208. this.main.model.status.error("feedback");
  209. if (line !== undefined) {
  210. this.main.components.editor.highlightError(line-1);
  211. }
  212. this.main.components.server.logEvent('feedback', "Instructor Feedback", name+"\n|\n"+"\n|\n"+message);
  213. }
  214. /**
  215. * Show "Empty Program" error, indicating the student hasn't written any code. This will appear in
  216. * the Feedback area, the Printer, and also log to the server. The relevant line of
  217. * code or block will also be highlighted.
  218. *
  219. * @param {String} original - HTML content that represents the original error message generated by the system.
  220. * @param {String} message - HTML content that is a hopefully friendlier message for the user explaining the error.
  221. * @param {number} line - What line the error occurred on.
  222. */
  223. BlockPyFeedback.prototype.emptyProgram = function() {
  224. this.title.html("Blank Program");
  225. this.original.hide().html("");
  226. this.body.html("You have not written any code yet.");
  227. this.main.model.status.error("runtime");
  228. this.main.components.server.logEvent('feedback', "Empty Program");
  229. }
  230. /**
  231. * Converts any kind of error (usually a Skulpt one) into a prettier version that's ready
  232. * for users to see. If it's already a string, it is passed along unchanged. But Skulpt
  233. * errors have to be processed more closely.
  234. */
  235. BlockPyFeedback.prototype.prettyPrintError = function(error) {
  236. if (typeof error === "string") {
  237. return error;
  238. } else {
  239. // A weird skulpt thing?
  240. if (error.tp$str !== undefined) {
  241. return error.tp$str().v;
  242. } else {
  243. return ""+error.name + ": " + error.message;
  244. }
  245. }
  246. }
  247. /**
  248. * Print an error to the printers -- the on screen one and the browser one. This
  249. * will attempt to provide extra explanation and context for an error.
  250. * Notice that this is largely for Run-time errors that will be thrown when the code
  251. * is executed, as opposed to ones raised elsewhere in the environment.
  252. *
  253. * @param {String} error - The error message to be analyzed and printed.
  254. */
  255. BlockPyFeedback.prototype.printError = function(error) {
  256. //console.log(error);
  257. original = this.prettyPrintError(error);
  258. this.title.html(error.tp$name);
  259. this.original.show().html(original);
  260. if (error.tp$name == "ParseError") {
  261. this.body.html("While attempting to convert the Python code into blocks, I found a syntax error. In other words, your Python code has a spelling or grammatical mistake. You should check to make sure that you have written all of your code correctly. To me, it looks like the problem is on line "+ error.args.v[2]+', where it says:&lt;br>&lt;code>'+error.args.v[3][2]+'&lt;/code>', error.args.v[2]);
  262. } else if (error.constructor == Sk.builtin.NameError
  263. &amp;&amp; error.args.v.length > 0
  264. &amp;&amp; error.args.v[0].v == "name '___' is not defined") {
  265. this.body.html("You have incomplete blocks. Make sure that you do not have any dangling blocks or blocks that are connected incorrectly.&lt;br>&lt;br>If you look at the text view of your Python code, you'll see &lt;code>___&lt;/code> in the code. The converter will create these &lt;code>___&lt;/code> to show that you have a block that's missing a piece.");
  266. } else if (error.tp$name in EXTENDED_ERROR_EXPLANATION) {
  267. this.body.html(EXTENDED_ERROR_EXPLANATION[error.tp$name]);
  268. } else {
  269. this.body.html(error.enhanced);
  270. }
  271. console.error(error);
  272. if (error.stack) {
  273. console.error(error.stack);
  274. }
  275. this.main.model.status.error("runtime");
  276. this.main.components.editor.highlightError(error.traceback[0].lineno-1);
  277. this.main.components.server.logEvent('feedback', "Runtime", original);
  278. }
  279. </code></pre>
  280. </article>
  281. </section>
  282. </div>
  283. <nav>
  284. <h2><a href="index.html">Home</a></h2><h3>Classes</h3><ul><li><a href="BlockPy.html">BlockPy</a></li><li><a href="BlockPyCorgis.html">BlockPyCorgis</a></li><li><a href="BlockPyDialog.html">BlockPyDialog</a></li><li><a href="BlockPyEditor.html">BlockPyEditor</a></li><li><a href="BlockPyEngine.html">BlockPyEngine</a></li><li><a href="BlockPyEnglish.html">BlockPyEnglish</a></li><li><a href="BlockPyFeedback.html">BlockPyFeedback</a></li><li><a href="BlockPyHistory.html">BlockPyHistory</a></li><li><a href="BlockPyPresentation.html">BlockPyPresentation</a></li><li><a href="BlockPyPrinter.html">BlockPyPrinter</a></li><li><a href="BlockPyServer.html">BlockPyServer</a></li><li><a href="BlockPyToolbar.html">BlockPyToolbar</a></li><li><a href="LocalStorageWrapper.html">LocalStorageWrapper</a></li><li><a href="PythonToBlocks.html">PythonToBlocks</a></li></ul><h3>Global</h3><ul><li><a href="global.html#BlockPyInterface">BlockPyInterface</a></li><li><a href="global.html#cloneNode">cloneNode</a></li><li><a href="global.html#encodeHTML">encodeHTML</a></li><li><a href="global.html#expandArray">expandArray</a></li><li><a href="global.html#EXTENDED_ERROR_EXPLANATION">EXTENDED_ERROR_EXPLANATION</a></li><li><a href="global.html#indent">indent</a></li><li><a href="global.html#instructor_module">instructor_module</a></li><li><a href="global.html#prettyPrintDateTime">prettyPrintDateTime</a></li><li><a href="global.html#randomInteger">randomInteger</a></li><li><a href="global.html#set_button_loaded">set_button_loaded</a></li><li><a href="global.html#timerGuard">timerGuard</a></li></ul>
  285. </nav>
  286. <br class="clear">
  287. <footer>
  288. Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.4.3</a> on Sun Mar 26 2017 09:45:03 GMT-0400 (Eastern Daylight Time)
  289. </footer>
  290. <script> prettyPrint(); </script>
  291. <script src="scripts/linenumber.js"> </script>
  292. </body>
  293. </html>