|
31 | 31 |
|
32 | 32 | ipythonExample = function (dom) {
|
33 | 33 | if (ace === undefined) {
|
34 |
| - Sk.asserts.fail("No ace"); |
| 34 | + throw Error("No ace"); |
35 | 35 | }
|
36 | 36 | this.editor = dom;
|
| 37 | + |
| 38 | + // focus the current inCell on clickGuard click event |
37 | 39 | this.clickGuard = document.getElementById("clickGuard");
|
38 | 40 | this.clickGuard.addEventListener("click", () => {
|
39 | 41 | this.inCell.focus();
|
40 | 42 | });
|
| 43 | + |
| 44 | + // add a keyboard interrupt feature |
41 | 45 | const keyboardInterrupt = (e) => {
|
42 | 46 | if (e.ctrlKey && e.key === "c") {
|
43 | 47 | // faile safe for keyboard interrupt
|
|
47 | 51 | this.editor.addEventListener("keydown", keyboardInterrupt);
|
48 | 52 | this.clickGuard.addEventListener("keydown", keyboardInterrupt);
|
49 | 53 |
|
| 54 | + // prepend browser info |
50 | 55 | const infoElement = document.createElement("DIV");
|
51 | 56 | infoElement.innerText = info;
|
52 | 57 | infoElement.style.margin = "5px";
|
53 | 58 | this.editor.appendChild(infoElement);
|
54 | 59 |
|
| 60 | + // setup some basics |
55 | 61 | this.inputs = [];
|
56 | 62 | this.idx = 0;
|
57 |
| - this.inCell; |
58 |
| - this.outCell; |
59 |
| - this.printCell; |
60 | 63 | this.newCells();
|
61 | 64 | this.outf = this.outf.bind(this);
|
62 | 65 | this.lineHeight = this.inCell.renderer.lineHeight || 16;
|
63 | 66 | this.pad = 15;
|
64 | 67 |
|
| 68 | + // configure the skulpt environment |
65 | 69 | Sk.configure({
|
66 | 70 | output: this.outf,
|
67 | 71 | __future__: Sk.python3,
|
|
90 | 94 | ipythonExample.prototype.execute = function () {
|
91 | 95 | stopExecution = false;
|
92 | 96 | const code = this.inCell.getValue();
|
93 |
| - const codeAsPyStr = new Sk.builtin.str(code); |
94 |
| - Sk.globals["_i" + this.inputs.length] = codeAsPyStr; |
95 |
| - Sk.misceval.callsimArray(Sk.globals.In.append, [Sk.globals.In, codeAsPyStr]); |
| 97 | + const codeAsPyStr = Sk.ffi.remapToPy(code); |
| 98 | + Sk.globals["_i" + this.inputs.length] = codeAsPyStr; // add the input to globals as per ipython |
| 99 | + Sk.globals.In.v.push(codeAsPyStr); |
96 | 100 | this.inputs[this.inputs.length - 1] = code;
|
97 | 101 |
|
98 |
| - let compile_code = code.trimEnd() || "None"; |
| 102 | + let compile_code = code.trimEnd() || "None"; // always have a last line |
99 | 103 |
|
100 | 104 | const lines = compile_code.split("\n");
|
101 | 105 | let last_line = lines[lines.length - 1];
|
|
110 | 114 | lines[lines.length - 1] = "_" + this.inputs.length + " = " + last_line;
|
111 | 115 | }
|
112 | 116 | compile_code = lines.join("\n");
|
| 117 | + // ace editor stuff |
113 | 118 | this.inCell.setReadOnly(true);
|
114 | 119 | this.inCell.renderer.$cursorLayer.element.style.opacity = 0;
|
| 120 | + |
| 121 | + // allow suspension and check the stopExecution flag in case of keyboard interrupt |
115 | 122 | const executionPromise = Sk.misceval.asyncToPromise(() => Sk.importMainWithBody("ipython", false, compile_code, true), {
|
116 | 123 | "*": () => {
|
117 | 124 | if (stopExecution) {
|
|
130 | 137 |
|
131 | 138 | const last_input = Sk.globals["_" + this.inputs.length];
|
132 | 139 | if (Sk.builtin.checkNone(last_input) || last_input === undefined) {
|
133 |
| - delete Sk.globals["_" + this.inputs.length]; |
| 140 | + delete Sk.globals["_" + this.inputs.length]; // if the last input evaluated to None remove it from globals |
134 | 141 | } else {
|
135 | 142 | this.outCell.setValue(Sk.ffi.remapToJs(Sk.misceval.objectRepr(last_input)), -1);
|
136 | 143 | if (last_input !== Sk.globals.Out) {
|
|
0 commit comments