mumuki-gobstones-runner 2.8.4 → 2.8.5

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b81904b19b4ecb207d1b52ffec98b8cd617b83f47eb02ec37b4fdd33f7087db4
4
- data.tar.gz: ad185dffbfc9c311578b2f4ab5a71f0b42cf4bd2110563ede627e4050d1280d8
3
+ metadata.gz: 5a1f462df1de2aa09e7025bc39fb066ebae0cf95203e2863276e549c57b35550
4
+ data.tar.gz: b1e8fbb1a19f96b130b5a5a25b3d8e582932b5c1d4063ece0ddcfe5358394980
5
5
  SHA512:
6
- metadata.gz: a9f6ac4c47444e5ff26c1151d19a120dd797bf16d394518399157be3eda926b869064b9536ee940c0587168bea17b2e492dad48678460cb9f5558fd5ecc1909f
7
- data.tar.gz: 87e3b5464e1daf5027c0f84e9fe806076f343542e0bd4ce1ca3bdea61ee345e7f46bc066bca4ca8267a8dad8dd7c9ce8581c5e6cb3b81a35042b8c088f1fa643
6
+ metadata.gz: dbb901882298f1c889730748bfb60ba8016535198e2953d6f5b72f986f617c65230cdf06b7a7a6326459d9a11b2d46945df9dc1c9faf10c5b46f05fcab65fa8e
7
+ data.tar.gz: 3ce96b0e01751e64a831a56565352eb378b612aee687d074e116911d305004f97e7c9feacb5522b2582b264a1ad90c1a67fdb4ded965504c2a56aa1a427bfe5e
@@ -4,6 +4,12 @@
4
4
  <link href="./gobstones-code-runner.html" rel="import"/>
5
5
  <script src="./hammer.min.js"></script>
6
6
 
7
+ <script>
8
+ function postpone(action) {
9
+ return setTimeout(action, 50);
10
+ }
11
+ </script>
12
+
7
13
  <dom-module id="mu-gobstones-custom-editor">
8
14
 
9
15
  <template>
@@ -20,15 +26,6 @@
20
26
  </template>
21
27
 
22
28
  <script>
23
- function postpone(action) {
24
- return setTimeout(action, 50);
25
- }
26
-
27
- function gbsBoardRemoveBorder(board) {
28
- board._setBorderOff();
29
- board.updateStyles();
30
- }
31
-
32
29
  const compilationModes = {
33
30
  gameFramework: {
34
31
  compile: ({ main, teacher, ...args }) => {
@@ -46,7 +43,9 @@
46
43
 
47
44
  scrollToMainBlock: (blockly) => {
48
45
  const mainBlock = blockly.getBlocksOfType('procedures_defnoreturnnoparams')[0];
49
- blockly.scrollToBlock(mainBlock.id);
46
+ if (mainBlock) {
47
+ blockly.scrollToBlock(mainBlock.id);
48
+ }
50
49
  },
51
50
 
52
51
  defaultCode: `<%= @game_framework_default %>`
@@ -90,184 +89,228 @@
90
89
  }
91
90
  },
92
91
 
93
- attached: function () {
94
- const setBlocklySounds = () => {
95
- Blockly.WorkspaceAudio.prototype.preload = () => {
96
- for (var soundName in this.SOUNDS_) {
97
- let sound = this.SOUNDS_[soundName];
98
- sound.volume = 0.01;
99
- let playPromise = sound.play();
100
- playPromise && playPromise.then(sound.pause.bind(sound));
101
- if (goog.userAgent.IPAD || goog.userAgent.IPHONE) break;
102
- }
103
- };
104
- };
92
+ // ==== Polymer events
105
93
 
106
- const setBlocklyColors = () => {
107
- Blockly.HSV_SATURATION = 0.64;
108
- Blockly.HSV_VALUE = 1;
94
+ attached() {
95
+ this.$exerciseContainer = $('.mu-kids-exercise');
109
96
 
110
- Blockly.MUMUKI_COLORS = {
111
- pink: "#FF5C82",
112
- blue: "#5CBEFF",
113
- yellow: "#FFC95C",
114
- green: "#5CED71"
115
- };
97
+ /*
98
+ https://polymer-library.polymer-project.org/1.0/docs/devguide/registering-elements#initialization-order
116
99
 
117
- // reserved
118
- Blockly.CUSTOM_COLORS.program = Blockly.MUMUKI_COLORS.pink;
119
- Blockly.CUSTOM_COLORS.interactiveProgram = Blockly.MUMUKI_COLORS.pink;
120
- Blockly.CUSTOM_COLORS.interactiveBinding = Blockly.MUMUKI_COLORS.pink;
121
- Blockly.CUSTOM_COLORS.procedure = Blockly.MUMUKI_COLORS.pink;
122
- Blockly.CUSTOM_COLORS.function = Blockly.MUMUKI_COLORS.pink;
123
- Blockly.CUSTOM_COLORS.complete = Blockly.MUMUKI_COLORS.pink;
124
-
125
- // control structures
126
- Blockly.CUSTOM_COLORS.controlStructure = this._isKindergarten() ? Blockly.MUMUKI_COLORS.green : Blockly.MUMUKI_COLORS.yellow;
127
-
128
- // commands
129
- Blockly.CUSTOM_COLORS.primitiveCommand = Blockly.MUMUKI_COLORS.yellow;
130
- Blockly.CUSTOM_COLORS.primitiveProcedure = Blockly.MUMUKI_COLORS.yellow;
131
- Blockly.CUSTOM_COLORS.procedure_call = Blockly.MUMUKI_COLORS.yellow;
132
- Blockly.CUSTOM_COLORS.assignation = Blockly.MUMUKI_COLORS.yellow;
133
-
134
- // expressions
135
- Blockly.Msg.MATH_HUE = Blockly.MUMUKI_COLORS.blue;
136
- Blockly.CUSTOM_COLORS.literalExpression = Blockly.MUMUKI_COLORS.blue;
137
- Blockly.CUSTOM_COLORS.primitiveExpression = Blockly.MUMUKI_COLORS.blue;
138
- Blockly.CUSTOM_COLORS.operator = Blockly.MUMUKI_COLORS.blue;
139
- Blockly.CUSTOM_COLORS.variable = Blockly.MUMUKI_COLORS.blue;
140
- Blockly.CUSTOM_COLORS.parameter = Blockly.MUMUKI_COLORS.blue;
141
- Blockly.CUSTOM_COLORS.primitiveFunction = Blockly.MUMUKI_COLORS.blue;
142
- Blockly.CUSTOM_COLORS.function_call = Blockly.MUMUKI_COLORS.blue;
143
-
144
- setTimeout(() => {
145
- this.getBlockly().testColors(Blockly.CUSTOM_COLORS);
146
- });
147
- };
100
+ There are no guarantees with regard to initialization timing between sibling elements.
101
+ This means that siblings may become ready in any order.
102
+ For accessing sibling elements when an element initializes, you can call async from inside the attached callback.
103
+ */
104
+ this.async(() => {
105
+ this._configureBlocklyAppearance();
106
+ this._configureBlocklyBehavior();
107
+ });
108
+ },
148
109
 
149
- const setBlocklyCustomSettings = () => {
150
- if (typeof Blockly === 'undefined' || !Blockly.CUSTOM_COLORS) return postpone(setBlocklyCustomSettings);
110
+ // ==== Public methods (accesible from other components)
151
111
 
152
- // The display mode configuration could be monkey-patched here, like this:
153
- Blockly.displayModes.iconic.iconSize = 64;
154
- Blockly.displayModes.iconic.procedureDefIcon = `${this.localMediaUrl}main-procedure.png`;
112
+ reset() {
113
+ const blockly = this._getBlockly();
114
+ blockly.workspaceXml = blockly.initialXml;
115
+ this._scrollToMainBlock();
116
+ },
155
117
 
156
- Blockly.displayMode = this._isKindergarten() ? 'iconic' : 'text';
157
- setBlocklySounds();
158
- setBlocklyColors();
118
+ setToolbox(toolboxXml) {
119
+ this._getBlockly().toolbox = { defaultToolbox: toolboxXml };
120
+ // Blockly's workspace is destroyed when toolbox changes, so we initialize it here.
121
+ this._initializeBlocklyWorkspace();
122
+ },
159
123
 
160
- // Removing "/" from the block id character set to avoid syntax errors
161
- Blockly.utils.genUid.soup_ = Blockly.utils.genUid.soup_.replace("/", "");
162
- };
124
+ compile(code) {
125
+ return this._compilationMode().compile(code);
126
+ },
163
127
 
164
- const updateFields = () => {
165
- const blockly = this.getBlockly();
128
+ hasInteractiveProgram() {
129
+ return this._getBlockly().initialXml.indexOf("block type=\"InteractiveProgram\"") !== -1;
130
+ },
166
131
 
167
- const editorValue = this.getEditorValue();
168
- if (editorValue) {
169
- editorValue.value = blockly.workspaceXml;
170
- }
132
+ hasCustomToolbox() {
133
+ return $('gs-toolbox').length;
134
+ },
171
135
 
172
- if (this.teacherMode) {
173
- const editorExtra = this.getEditorExtra();
174
- if (editorExtra) {
175
- editorExtra.value = blockly.workspaceXml;
176
- }
177
- }
136
+ toggleInteractiveMode() {
137
+ this.$exerciseContainer.toggleClass('play-mode');
138
+ this._triggerResize();
139
+ },
178
140
 
179
- if (typeof angular !== 'undefined') {
180
- angular.element(editorValue).triggerHandler("change");
181
- }
141
+ getTeacherCode() {
142
+ const extraCode = this._getExtraCode();
143
+ if (!extraCode) return;
144
+ this.$.blocklyTmp.workspaceXml = extraCode;
145
+ return this.$.blocklyTmp.generateCode();
146
+ },
182
147
 
183
- const submit = $("kids-submit-button")[0];
184
- if (submit && submit.$.runner.isRunning) {
185
- submit.$.runner.stop();
186
- }
187
- };
148
+ getStudentCode: function () {
149
+ return this
150
+ ._getBlockly()
151
+ .generateCode({withRegions: true, clearErrors: false});
152
+ },
188
153
 
189
- this.$exerciseContainer = $('.mu-kids-exercise');
154
+ getStudentXml: function () {
155
+ return this._getStudentSolution() || "";
156
+ },
190
157
 
191
- const setTrashPosition = () => {
192
- var width = $('#blocklyDiv').width() - 68;
193
- var height = $('#blocklyDiv').height() - 210;
194
- $('.blocklyTrash').css("transform", `translate(${width}px, ${height}px)`);
195
- $('.blocklyTrash').css("display", "unset");
196
- };
158
+ getTestCode() {
159
+ return this._getEditorTest().value;
160
+ },
197
161
 
198
- var setTrashTimeout;
162
+ removeBlockErrors() {
163
+ return this._getBlockly().workspace.removeBlockErrors();
164
+ },
199
165
 
200
- const localOnResize = () => {
201
- clearTimeout(setTrashTimeout);
202
- setTrashTimeout = setTimeout(() => {
203
- setTrashPosition();
204
- });
205
- };
166
+ showBlockError(region, error) {
167
+ this._getBlockly().scrollToBlock(region);
168
+ this._getBlockly().showBlockError(region, error.message);
169
+ },
206
170
 
207
- const triggerResizeOnContextModalClose = () => {
208
- $('.mu-kids-context, .mu-kids-results').on('hidden.bs.modal shown.bs.modal', function () {
209
- localOnResize();
210
- })
211
- };
171
+ highlightBlock(region) {
172
+ this._getBlockly().highlightBlock(region);
173
+ },
212
174
 
213
- const relocateTrash = (blockly) => {
214
- blockly.workspace.trashcan.bottom_ = 150; //Setting vertical position programmatically to adjust the draggable area
215
- $(window).resize((e) => localOnResize());
216
- triggerResizeOnContextModalClose();
217
- };
175
+ // ==== Private methods (only for internal usage)
218
176
 
219
- const initialize = () => {
220
- postpone(() => {
221
- const blockly = this.getBlockly();
177
+ _configureBlocklyAppearance() {
178
+ this._getBlockly().showCategories = !this._isKindergarten();
179
+ this._setBlocklyDisplayMode();
180
+ this._setBlocklySounds();
181
+ this._setBlocklyColors();
222
182
 
223
- if (!blockly || !blockly.workspace) return initialize();
183
+ if (!this.readOnly) {
184
+ this._relocateTrashOnResize();
185
+ }
224
186
 
225
- blockly.showCategories = !this._isKindergarten();
187
+ // Removing "/" from the block id character set to avoid syntax errors
188
+ Blockly.utils.genUid.soup_ = Blockly.utils.genUid.soup_.replace("/", "");
189
+ },
226
190
 
227
- if (!this.readOnly) {
228
- relocateTrash(blockly);
229
- }
191
+ _configureBlocklyBehavior() {
192
+ this._setTeacherActions();
193
+ this._setGameActions();
230
194
 
231
- this.setTeacherActions(blockly);
232
- this._setInitialXml(blockly);
233
- this.interactiveMode = blockly.initialXml.indexOf("block type=\"InteractiveProgram\"") !== -1;
234
- if (this.interactiveMode) this.setInteractiveLayout();
235
- this._initializeWorkspace(blockly, () => {
236
- localOnResize();
237
- blockly._onresize();
195
+ // Blockly's workspace is destroyed when toolbox changes, so it doesn't make sense to initialize it here.
196
+ if (!this.hasCustomToolbox()) {
197
+ this._initializeBlocklyWorkspace();
198
+ }
238
199
 
239
- this._subscribeToWorkspace(blockly, updateFields);
240
- });
200
+ this._registerLayoutChangedEvent();
201
+ },
241
202
 
242
- const hasCustomToolbox = $('gs-toolbox').length;
243
- if(!hasCustomToolbox) this.enableContextButton();
203
+ _relocateTrashOnResize() {
204
+ $('.mu-kids-context, .mu-kids-results').on('hidden.bs.modal shown.bs.modal', () => {
205
+ this._relocateTrash();
206
+ });
244
207
 
245
- this._registerLayoutChangedEvent();
246
- });
208
+ $(window).resize(() => this._relocateTrash());
209
+ },
210
+
211
+ _initializeBlocklyWorkspace() {
212
+ this._setInitialXml();
213
+ this._initializeWorkspace();
214
+ this._subscribeToWorkspace(() => this._updateSolution());
215
+
216
+ if (this.hasInteractiveProgram()) {
217
+ this._setInteractiveLayout();
218
+ }
219
+
220
+ mumuki.assetsLoadedFor('editor');
221
+ },
222
+
223
+ _relocateTrash() {
224
+ const width = $('#blocklyDiv').width() - 68;
225
+ const height = $('#blocklyDiv').height() - 210;
226
+ $('.blocklyTrash').css("transform", `translate(${width}px, ${height}px)`);
227
+ $('.blocklyTrash').css("display", "unset");
228
+ },
229
+
230
+ _updateSolution() {
231
+ const blockly = this._getBlockly();
232
+
233
+ if (this.teacherMode) {
234
+ this._setExtraCode(blockly.workspaceXml);
235
+ } else {
236
+ this._setStudentSolution(blockly.workspaceXml);
237
+ }
238
+
239
+ // TODO: this hack enables Angular two-way binding for Bibliotheca. Should be replaced with Mumuki events system
240
+ if (typeof angular !== 'undefined') {
241
+ angular.element(this._getStudentEditor()).triggerHandler("change");
242
+ angular.element(this._getEditorExtra()).triggerHandler("change");
243
+ }
244
+
245
+ this._stopExecution();
246
+ },
247
+
248
+ _setBlocklySounds() {
249
+ Blockly.WorkspaceAudio.prototype.preload = () => {
250
+ for (const soundName in this.SOUNDS_) {
251
+ const sound = this.SOUNDS_[soundName];
252
+ sound.volume = 0.01;
253
+ const playPromise = sound.play();
254
+ playPromise && playPromise.then(sound.pause.bind(sound));
255
+ if (goog.userAgent.IPAD || goog.userAgent.IPHONE) break;
256
+ }
257
+ };
258
+ },
259
+
260
+ _setBlocklyColors() {
261
+ Blockly.HSV_SATURATION = 0.64;
262
+ Blockly.HSV_VALUE = 1;
263
+
264
+ Blockly.MUMUKI_COLORS = {
265
+ pink: "#FF5C82",
266
+ blue: "#5CBEFF",
267
+ yellow: "#FFC95C",
268
+ green: "#5CED71"
247
269
  };
248
270
 
249
- setBlocklyCustomSettings();
250
- initialize();
271
+ // reserved
272
+ Blockly.CUSTOM_COLORS.program = Blockly.MUMUKI_COLORS.pink;
273
+ Blockly.CUSTOM_COLORS.interactiveProgram = Blockly.MUMUKI_COLORS.pink;
274
+ Blockly.CUSTOM_COLORS.interactiveBinding = Blockly.MUMUKI_COLORS.pink;
275
+ Blockly.CUSTOM_COLORS.procedure = Blockly.MUMUKI_COLORS.pink;
276
+ Blockly.CUSTOM_COLORS.function = Blockly.MUMUKI_COLORS.pink;
277
+ Blockly.CUSTOM_COLORS.complete = Blockly.MUMUKI_COLORS.pink;
278
+
279
+ // control structures
280
+ Blockly.CUSTOM_COLORS.controlStructure = this._isKindergarten() ? Blockly.MUMUKI_COLORS.green : Blockly.MUMUKI_COLORS.yellow;
281
+
282
+ // commands
283
+ Blockly.CUSTOM_COLORS.primitiveCommand = Blockly.MUMUKI_COLORS.yellow;
284
+ Blockly.CUSTOM_COLORS.primitiveProcedure = Blockly.MUMUKI_COLORS.yellow;
285
+ Blockly.CUSTOM_COLORS.procedure_call = Blockly.MUMUKI_COLORS.yellow;
286
+ Blockly.CUSTOM_COLORS.assignation = Blockly.MUMUKI_COLORS.yellow;
287
+
288
+ // expressions
289
+ Blockly.Msg.MATH_HUE = Blockly.MUMUKI_COLORS.blue;
290
+ Blockly.CUSTOM_COLORS.literalExpression = Blockly.MUMUKI_COLORS.blue;
291
+ Blockly.CUSTOM_COLORS.primitiveExpression = Blockly.MUMUKI_COLORS.blue;
292
+ Blockly.CUSTOM_COLORS.operator = Blockly.MUMUKI_COLORS.blue;
293
+ Blockly.CUSTOM_COLORS.variable = Blockly.MUMUKI_COLORS.blue;
294
+ Blockly.CUSTOM_COLORS.parameter = Blockly.MUMUKI_COLORS.blue;
295
+ Blockly.CUSTOM_COLORS.primitiveFunction = Blockly.MUMUKI_COLORS.blue;
296
+ Blockly.CUSTOM_COLORS.function_call = Blockly.MUMUKI_COLORS.blue;
251
297
  },
252
298
 
253
- toggleInteractiveMode() {
254
- this.$exerciseContainer.toggleClass('play-mode');
255
- this.triggerResize();
299
+ _setBlocklyDisplayMode() {
300
+ // The display mode configuration could be monkey-patched here, like this:
301
+ Blockly.displayModes.iconic.iconSize = 64;
302
+ Blockly.displayModes.iconic.procedureDefIcon = `${this.localMediaUrl}main-procedure.png`;
303
+
304
+ Blockly.displayMode = this._isKindergarten() ? 'iconic' : 'text';
256
305
  },
257
306
 
258
- triggerResize() {
259
- let event = document.createEvent('HTMLEvents');
307
+ _triggerResize() {
308
+ const event = document.createEvent('HTMLEvents');
260
309
  event.initEvent('resize', true, false);
261
310
  document.dispatchEvent(event);
262
311
  },
263
312
 
264
- reset(code) {
265
- const blockly = this.getBlockly();
266
- blockly.workspaceXml = code || blockly.initialXml;
267
- this._scrollToMainBlock();
268
- },
269
-
270
- setInteractiveLayout() {
313
+ _setInteractiveLayout() {
271
314
  this.$exerciseContainer.addClass('mu-kids-interactive');
272
315
  $('.mu-final-state').html('<gs-keyboard/>');
273
316
  $('.mu-editor').append($('<kids-interactive-submit-button/>'));
@@ -277,82 +320,86 @@
277
320
  })
278
321
  },
279
322
 
280
- setTeacherActions(blockly) {
323
+ _setTeacherActions() {
281
324
  const teacherCode = this.getTeacherCode();
282
- if (teacherCode) {
283
- setTimeout(() => {
284
- const actions = new Parser().getActionsFromSource(teacherCode);
285
-
286
- blockly.primitiveProcedures = this._withDefaultIcons(actions, 'procedureDeclarations');
287
- blockly.primitiveFunctions = this._withDefaultIcons(actions, 'functionDeclarations');
288
- });
325
+ if (!teacherCode) {
326
+ return;
289
327
  }
328
+
329
+ const blockly = this._getBlockly();
330
+ const actions = new Parser().getActionsFromSource(teacherCode);
331
+ blockly.primitiveProcedures = this._withDefaultIcons(actions, 'procedureDeclarations');
332
+ blockly.primitiveFunctions = this._withDefaultIcons(actions, 'functionDeclarations');
290
333
  },
291
334
 
292
- setGameActions(blockly) {
335
+ _setGameActions() {
336
+ const blockly = this._getBlockly();
293
337
  if (this._isGame()) {
294
338
  blockly.primitiveProcedures = blockly.primitiveProcedures || [];
295
339
  blockly.primitiveProcedures = blockly.primitiveProcedures.concat([
296
- this.gamePrimitive('ShiftUp'),
297
- this.gamePrimitive('ShiftDown'),
298
- this.gamePrimitive('ShiftLeft'),
299
- this.gamePrimitive('ShiftRight')
340
+ this._gamePrimitive('ShiftUp'),
341
+ this._gamePrimitive('ShiftDown'),
342
+ this._gamePrimitive('ShiftLeft'),
343
+ this._gamePrimitive('ShiftRight')
300
344
  ]);
301
345
  }
302
346
  },
303
347
 
304
- gamePrimitive(name) {
305
- return { alias: 'procedureDeclaration', name: name, attributes: {block_icon: `<%= @assets_url %>/media/${name}.png`} };
348
+ _gamePrimitive(name) {
349
+ return { alias: 'procedureDeclaration', name, attributes: {block_icon: `<%= @assets_url %>/media/${name}.png`} };
306
350
  },
307
351
 
308
- enableContextButton() {
309
- if(mumuki.kids && mumuki.assetsLoadedFor) {
310
- return mumuki.assetsLoadedFor('editor');
311
- } else {
312
- return postpone(this.enableContextButton.bind(this));
313
- }
352
+ _getBlockly() {
353
+ return this.$.blocklyElement;
354
+ },
314
355
 
356
+ _getStudentSolution() {
357
+ return this._getStudentEditor().value;
315
358
  },
316
359
 
317
- getBlockly: function () {
318
- return this.$.blocklyElement;
360
+ /**
361
+ * Sets the student solution xml, which corresponds
362
+ * to user content in laboratory, and default content in bibliotheca
363
+ */
364
+ _setStudentSolution(code) {
365
+ console.debug(`Setting student ${code}`)
366
+ this._getStudentEditor().value = code;
319
367
  },
320
368
 
321
- getStudentCode: function () {
322
- return this
323
- .getBlockly()
324
- .generateCode({withRegions: true, clearErrors: false});
369
+ _getDefaultCode() {
370
+ return this._getEditorDefaultValue().value;
325
371
  },
326
372
 
327
- getStudentXml: function () {
328
- return this.getEditorValue().value || "";
373
+ _getExtraCode() {
374
+ return this._getEditorExtra().value;
329
375
  },
330
376
 
331
- getTeacherCode: function () {
332
- const teacherXml = this.getEditorExtra();
333
- if (!teacherXml || !teacherXml.value) return;
334
- this.$.blocklyTmp.workspaceXml = teacherXml.value;
335
- return this.$.blocklyTmp.generateCode();
377
+ _setExtraCode(code) {
378
+ console.debug(`Setting extra ${code}`)
379
+ this._getEditorExtra().value = code;
336
380
  },
337
381
 
338
- getEditorValue: function() {
339
- return $("#mu-custom-editor-value")[0];
382
+ _getEditorExtra: function() {
383
+ return $("#mu-custom-editor-extra")[0] || {};
340
384
  },
341
385
 
342
- getEditorDefaultValue: function() {
343
- return $("#mu-custom-editor-default-value")[0];
386
+ _getEditorTest: function() {
387
+ return $("#mu-custom-editor-test")[0];
344
388
  },
345
389
 
346
- getEditorExtra: function() {
347
- return $("#mu-custom-editor-extra")[0];
390
+ _getStudentEditor: function() {
391
+ return $("#mu-custom-editor-value")[0] || {};
348
392
  },
349
393
 
350
- getEditorTest: function() {
351
- return $("#mu-custom-editor-test")[0];
394
+ _getEditorDefaultValue: function() {
395
+ return $("#mu-custom-editor-default-value")[0] || {};
352
396
  },
353
397
 
354
- compile(code) {
355
- return this._compilationMode().compile(code);
398
+ _stopExecution() {
399
+ const submit = $("kids-submit-button")[0];
400
+ if (submit && submit.$.runner.isRunning) {
401
+ submit.$.runner.stop();
402
+ }
356
403
  },
357
404
 
358
405
  _registerLayoutChangedEvent() {
@@ -361,12 +408,13 @@
361
408
  }
362
409
 
363
410
  mumuki.events.on('layoutChanged', () => {
364
- this.getEditorDefaultValue().value = this._compilationMode().defaultCode;
411
+ console.debug('layout changed');
412
+ this._setStudentSolution(this._compilationMode().defaultCode);
365
413
  });
366
414
  },
367
415
 
368
416
  _scrollToMainBlock() {
369
- this._compilationMode().scrollToMainBlock(this.getBlockly());
417
+ this._compilationMode().scrollToMainBlock(this._getBlockly());
370
418
  },
371
419
 
372
420
  _withDefaultIcons(actions, type) {
@@ -400,35 +448,31 @@
400
448
  return this._isGame() ? compilationModes.gameFramework : compilationModes.classic;
401
449
  },
402
450
 
403
- _setInitialXml: function (blockly) {
404
- const editorDefaultContent = this.getEditorDefaultValue();
405
- if (editorDefaultContent && editorDefaultContent.value) {
406
- blockly.initialXml = editorDefaultContent.value;
451
+ _setInitialXml: function () {
452
+ const blockly = this._getBlockly();
453
+ const defaultCode = this._getDefaultCode();
454
+ if (defaultCode) {
455
+ blockly.initialXml = defaultCode;
407
456
  } else {
408
457
  blockly.initialXml = blockly.workspaceXml;
409
458
  }
410
459
  },
411
460
 
412
- _initializeWorkspace: function(blockly, callback) {
413
- postpone(() => {
414
- const value = this.getEditorValue().value;
461
+ _initializeWorkspace() {
462
+ const blockly = this._getBlockly();
463
+ const value = this._getStudentSolution();
415
464
 
416
- blockly.workspaceXml = value || (
417
- this.teacherMode
418
- ? "<xml></xml>"
419
- : blockly.initialXml
420
- );
421
- this._scrollToMainBlock();
465
+ blockly.workspaceXml = value || (
466
+ this.teacherMode
467
+ ? "<xml></xml>"
468
+ : blockly.initialXml
469
+ );
422
470
 
423
- callback();
424
- });
471
+ this._scrollToMainBlock();
425
472
  },
426
473
 
427
- _subscribeToWorkspace: function(blockly, action) {
428
- setTimeout(() => {
429
- blockly.workspace.addChangeListener(action);
430
- action();
431
- });
474
+ _subscribeToWorkspace: function(action) {
475
+ this._getBlockly().workspace.addChangeListener(action);
432
476
  }
433
477
  });
434
478
  </script>
@@ -796,16 +840,21 @@
796
840
  finalBoard.update(table, head);
797
841
  }
798
842
 
799
- gbsBoardRemoveBorder(finalBoard);
843
+ this._removeBorder(finalBoard);
844
+ },
845
+
846
+ _removeBorder(board) {
847
+ board._setBorderOff();
848
+ board.updateStyles();
800
849
  },
801
850
 
802
851
  _highlight: function (region) {
803
- this._getBlockly().highlightBlock(region);
852
+ this.$editor.highlightBlock(region);
804
853
  },
805
854
 
806
855
  _showError: function (region, error) {
807
856
  const expectsTimeout = /expect_endless_while *: *true/.test(
808
- this.$editor.getEditorTest().value
857
+ this.$editor.getTestCode()
809
858
  );
810
859
 
811
860
  const isExpectedTimeout = (
@@ -815,8 +864,7 @@
815
864
 
816
865
  if (isExpectedTimeout) return;
817
866
 
818
- this._getBlockly().scrollToBlock(region);
819
- this._getBlockly().showBlockError(region, error.message);
867
+ this.$editor.showBlockError(region, error);
820
868
  },
821
869
 
822
870
  _cleanState: function () {
@@ -830,8 +878,8 @@
830
878
  finalBoard.boom = false;
831
879
  },
832
880
 
833
- _removeBlockErrors: function () {
834
- this._getBlockly().workspace.removeBlockErrors();
881
+ _removeBlockErrors() {
882
+ this.$editor.removeBlockErrors();
835
883
  },
836
884
 
837
885
  _getLastRegion: function (context = {}) {
@@ -839,10 +887,6 @@
839
887
  return regionStack && regionStack.filter(it => it).slice(-1)[0];
840
888
  },
841
889
 
842
- _getBlockly: function () {
843
- return this.$editor.getBlockly();
844
- },
845
-
846
890
  _getInitialBoards: function () {
847
891
  return $(".mu-initial-state gs-board");
848
892
  },
@@ -869,7 +913,7 @@
869
913
  },
870
914
 
871
915
  _onResetState: function () {
872
- this._getBlockly().workspace.removeBlockErrors();
916
+ this._removeBlockErrors();
873
917
  this._resetBoards();
874
918
  this._toggleInitialState();
875
919
  this.multipleScenarios.resetIndicators();
@@ -891,31 +935,19 @@
891
935
  is: 'gs-toolbox',
892
936
  properties: {
893
937
  toolboxUrl: Object,
894
- observer: '_toolboxChanged'
938
+ observer: '_setEditorToolbox'
895
939
  },
896
940
 
897
941
  attached: function () {
898
- this._setToolbox();
899
- },
900
- _toolboxChanged: function () {
901
- this._setToolbox();
942
+ this.async(() => {
943
+ this._setEditorToolbox();
944
+ });
902
945
  },
903
- _setToolbox: function () {
946
+
947
+ _setEditorToolbox: function () {
904
948
  const editor = $("mu-gobstones-custom-editor")[0];
905
- const blockly = editor.getBlockly();
906
- if(blockly.readOnly) return;
907
- const previousCode = editor.getEditorValue().value;
908
949
  $.get(this.toolboxUrl, function (toolboxXml) {
909
- blockly.toolbox = { defaultToolbox: toolboxXml };
910
- editor.setTeacherActions(blockly);
911
- editor.setGameActions(blockly);
912
- // @faloi - I couldn't figure out why the workspace gets replaced with a generic code,
913
- // so here I force a reset with the code previously saved. Sorry not sorry.
914
- postpone(() => {
915
- editor.reset(previousCode);
916
- });
917
- }).always(function () {
918
- editor.enableContextButton();
950
+ editor.setToolbox(toolboxXml);
919
951
  });
920
952
  }
921
953
  });
@@ -1,3 +1,4 @@
1
+ /* eslint-disable */
1
2
  /*! Hammer.JS - v2.0.8 - 2016-04-23
2
3
  * http://hammerjs.github.io/
3
4
  *
@@ -1,3 +1,3 @@
1
1
  module GobstonesVersionHook
2
- VERSION = '2.8.4'
2
+ VERSION = '2.8.5'
3
3
  end
metadata CHANGED
@@ -1,14 +1,15 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mumuki-gobstones-runner
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.8.4
4
+ version: 2.8.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Rodrigo Alfonso
8
+ - Federico Aloi
8
9
  autorequire:
9
10
  bindir: bin
10
11
  cert_chain: []
11
- date: 2020-09-24 00:00:00.000000000 Z
12
+ date: 2020-10-16 00:00:00.000000000 Z
12
13
  dependencies:
13
14
  - !ruby/object:Gem::Dependency
14
15
  name: gobstones-board
@@ -173,6 +174,7 @@ dependencies:
173
174
  description:
174
175
  email:
175
176
  - rodri042@gmail.com
177
+ - federico.aloi@gmail.com
176
178
  executables: []
177
179
  extensions: []
178
180
  extra_rdoc_files: []