mumuki-laboratory 8.1.1 → 8.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +19 -8
- data/app/assets/javascripts/mumuki_laboratory/application/bridge.js +2 -1
- data/app/assets/javascripts/mumuki_laboratory/application/button.js +4 -6
- data/app/assets/javascripts/mumuki_laboratory/application/codemirror-builder.js +3 -3
- data/app/assets/javascripts/mumuki_laboratory/application/codemirror.js +6 -6
- data/app/assets/javascripts/mumuki_laboratory/application/console.js +2 -2
- data/app/assets/javascripts/mumuki_laboratory/application/discussions.js +7 -7
- data/app/assets/javascripts/mumuki_laboratory/application/editors.js +1 -1
- data/app/assets/javascripts/mumuki_laboratory/application/elipsis.js +1 -1
- data/app/assets/javascripts/mumuki_laboratory/application/events.js +2 -2
- data/app/assets/javascripts/mumuki_laboratory/application/exercise.js +2 -2
- data/app/assets/javascripts/mumuki_laboratory/application/gamification.js +13 -3
- data/app/assets/javascripts/mumuki_laboratory/application/i18n.js +73 -0
- data/app/assets/javascripts/mumuki_laboratory/application/inputs.js +1 -1
- data/app/assets/javascripts/mumuki_laboratory/application/kids.js +26 -5
- data/app/assets/javascripts/mumuki_laboratory/application/kindergarten.js +13 -8
- data/app/assets/javascripts/mumuki_laboratory/application/messages.js +6 -6
- data/app/assets/javascripts/mumuki_laboratory/application/mu-modal-carrousel.js +1 -1
- data/app/assets/javascripts/mumuki_laboratory/application/multiple-choice.js +1 -1
- data/app/assets/javascripts/mumuki_laboratory/application/multiple-files.js +3 -3
- data/app/assets/javascripts/mumuki_laboratory/application/multiple-scenarios.js +1 -1
- data/app/assets/javascripts/mumuki_laboratory/application/pin.js +1 -1
- data/app/assets/javascripts/mumuki_laboratory/application/primary.js +6 -4
- data/app/assets/javascripts/mumuki_laboratory/application/progress.js +1 -1
- data/app/assets/javascripts/mumuki_laboratory/application/results-renderer.js +29 -2
- data/app/assets/javascripts/mumuki_laboratory/application/speech-bubble-renderer.js +4 -4
- data/app/assets/javascripts/mumuki_laboratory/application/submission.js +72 -48
- data/app/assets/javascripts/mumuki_laboratory/application/submissions-store.js +3 -3
- data/app/assets/javascripts/mumuki_laboratory/application/sync-mode.js +2 -2
- data/app/assets/javascripts/mumuki_laboratory/application/timer.js +1 -1
- data/app/assets/stylesheets/mumuki_laboratory/application/_layout.scss +7 -7
- data/app/assets/stylesheets/mumuki_laboratory/application/modules/_kids.scss +4 -0
- data/app/assets/stylesheets/mumuki_laboratory/application/modules/_kids_results.scss +1 -0
- data/app/assets/stylesheets/mumuki_laboratory/application/modules/_overlap.scss +0 -4
- data/app/assets/stylesheets/mumuki_laboratory/application/modules/_terms.scss +4 -0
- data/app/controllers/chapters_controller.rb +9 -5
- data/app/controllers/concerns/with_user_discussion_validation.rb +6 -0
- data/app/controllers/discussions_controller.rb +0 -6
- data/app/controllers/guide_container_controller.rb +2 -7
- data/app/helpers/assignment_result_helper.rb +1 -1
- data/app/helpers/contextualization_result_helper.rb +0 -8
- data/app/helpers/discussions_helper.rb +12 -4
- data/app/helpers/editor_tabs_helper.rb +1 -1
- data/app/helpers/icons_helper.rb +1 -1
- data/app/helpers/links_helper.rb +3 -3
- data/app/helpers/menu_bar_helper.rb +9 -1
- data/app/helpers/overlapped_buttons_helper.rb +6 -2
- data/app/views/book/show.html.erb +2 -2
- data/app/views/book_discussions/index.html.erb +3 -1
- data/app/views/chapters/show.html.erb +21 -9
- data/app/views/complements/show.html.erb +1 -1
- data/app/views/discussions/_message.html.erb +2 -2
- data/app/views/discussions/index.html.erb +11 -4
- data/app/views/exams/show.html.erb +1 -1
- data/app/views/exercise_solutions/_kids_level_up.html.erb +1 -1
- data/app/views/exercises/_exercise_assignment.html.erb +1 -1
- data/app/views/exercises/_read_only.html.erb +1 -1
- data/app/views/exercises/show.html.erb +2 -2
- data/app/views/layouts/_copyright.html.erb +1 -1
- data/app/views/layouts/_discussions.html.erb +0 -4
- data/app/views/layouts/_guide.html.erb +9 -36
- data/app/views/layouts/_guide_container.html.erb +28 -0
- data/app/views/layouts/_guide_title_icons.html.erb +9 -0
- data/app/views/layouts/_kids.html.erb +4 -4
- data/app/views/layouts/_kindergarten.html.erb +5 -5
- data/app/views/layouts/_social_media.html.erb +4 -4
- data/app/views/layouts/_timer.html.erb +1 -1
- data/app/views/layouts/application.html.erb +31 -27
- data/app/views/layouts/embedded.html.erb +14 -11
- data/app/views/layouts/exercise_inputs/editors/_code.html.erb +1 -6
- data/app/views/layouts/exercise_inputs/editors/_multiple_files.html.erb +4 -9
- data/app/views/layouts/exercise_inputs/forms/_problem_form.html.erb +1 -1
- data/app/views/layouts/exercise_inputs/layouts/_input_kindergarten.html.erb +1 -1
- data/app/views/layouts/modals/_guide_corollary.html.erb +13 -3
- data/app/views/layouts/modals/_kids_results.html.erb +2 -2
- data/app/views/layouts/modals/_kindergarten_context.html.erb +3 -3
- data/app/views/layouts/modals/_kindergarten_results.html.erb +3 -3
- data/app/views/layouts/modals/_kindergarten_results_aborted.html.erb +2 -2
- data/app/views/layouts/modals/_level_up.html.erb +1 -1
- data/app/views/lessons/show.html.erb +1 -1
- data/app/views/users/_edit_user_form.html.erb +1 -1
- data/app/views/users/_term.html.erb +1 -1
- data/app/views/users/_user_form.html.erb +1 -1
- data/lib/mumuki/laboratory/controllers/results_rendering.rb +2 -1
- data/lib/mumuki/laboratory/engine.rb +1 -1
- data/lib/mumuki/laboratory/locales/en.yml +5 -8
- data/lib/mumuki/laboratory/locales/es-CL.yml +5 -3
- data/lib/mumuki/laboratory/locales/es.yml +8 -10
- data/lib/mumuki/laboratory/locales/pt.yml +5 -8
- data/lib/mumuki/laboratory/version.rb +1 -1
- data/spec/controllers/discussions_controller_spec.rb +19 -0
- data/spec/controllers/exercise_solutions_controller_spec.rb +3 -2
- data/spec/dummy/db/schema.rb +50 -1
- data/spec/dummy/public/character/animations.json +1 -0
- data/{public → spec/dummy/public}/character/kibi/context.svg +0 -0
- data/{public → spec/dummy/public}/character/kibi/failure.svg +0 -0
- data/{public → spec/dummy/public}/character/kibi/jump.svg +0 -0
- data/spec/dummy/public/character/kibi/passed_with_warnings.svg +4 -0
- data/{public → spec/dummy/public}/character/kibi/success2_l.svg +0 -0
- data/{public → spec/dummy/public}/character/kibi/success_l.svg +0 -0
- data/{public → spec/dummy/public}/character/magnifying_glass/apparition.svg +0 -0
- data/{public → spec/dummy/public}/character/magnifying_glass/loop.svg +0 -0
- data/spec/features/chapters_flow_spec.rb +112 -0
- data/spec/features/login_flow_spec.rb +1 -1
- data/spec/features/terms_flow_spec.rb +2 -0
- data/spec/features/topic_flow_spec.rb +0 -1
- data/spec/helpers/icons_helper_spec.rb +3 -3
- data/spec/helpers/test_results_rendering_spec.rb +8 -8
- data/spec/helpers/with_navigation_spec.rb +14 -14
- data/spec/javascripts/gamification-spec.js +2 -2
- data/spec/javascripts/i18n-spec.js +79 -0
- data/spec/javascripts/kids-button-spec.js +36 -0
- metadata +136 -115
- data/spec/dummy/config/database.travis.yml +0 -4
- data/spec/features/chapter_spec.rb +0 -70
@@ -13,7 +13,7 @@ mumuki.load(() => {
|
|
13
13
|
this.$contextModalButton = new mumuki.Button($('#mu-kids-context .mu-kids-modal-button.mu-close'));
|
14
14
|
|
15
15
|
this.resultActions.passed = this._showSuccessPopup.bind(this);
|
16
|
-
this.resultActions.passed_with_warnings = this.
|
16
|
+
this.resultActions.passed_with_warnings = this._showPassedWithWarnings.bind(this);
|
17
17
|
this.resultActions.failed = this._showFailurePopup.bind(this);
|
18
18
|
this.resultActions.errored = this._showFailurePopup.bind(this);
|
19
19
|
this.resultActions.pending = this._showFailurePopup.bind(this);
|
@@ -50,6 +50,10 @@ mumuki.load(() => {
|
|
50
50
|
this.showNonAbortedPopup(data, 'success2_l');
|
51
51
|
}
|
52
52
|
|
53
|
+
_showPassedWithWarnings(data) {
|
54
|
+
this.showNonAbortedPopup(data, 'passed_with_warnings');
|
55
|
+
}
|
56
|
+
|
53
57
|
_showFailurePopup(data) {
|
54
58
|
this.showNonAbortedPopup(data, 'failure');
|
55
59
|
}
|
@@ -78,6 +82,7 @@ mumuki.load(() => {
|
|
78
82
|
|
79
83
|
restart() {
|
80
84
|
mumuki.presenterCharacter.playAnimation('talk', this.$bubbleCharacterAnimation);
|
85
|
+
this.hideOverlay();
|
81
86
|
}
|
82
87
|
|
83
88
|
// =======================
|
@@ -103,27 +108,27 @@ mumuki.load(() => {
|
|
103
108
|
this._action('play', 'stop', true, (speech) => {
|
104
109
|
mumuki.presenterCharacter.playAnimation('talk', mumuki.kids.$bubbleCharacterAnimation);
|
105
110
|
speech.speak(msg);
|
106
|
-
})
|
111
|
+
});
|
107
112
|
},
|
108
113
|
stop() {
|
109
|
-
this._action('stop', 'play', false, (speech) => speech.cancel())
|
114
|
+
this._action('stop', 'play', false, (speech) => speech.cancel());
|
110
115
|
},
|
111
116
|
_action(add, remove, isPlaying, callback) {
|
112
117
|
callback(window.speechSynthesis);
|
113
|
-
const $button = $('.mu-kindergarten-play-description')
|
118
|
+
const $button = $('.mu-kindergarten-play-description');
|
114
119
|
$button.find(`.mu-kindergarten-${add}`).addClass('hidden');
|
115
120
|
$button.find(`.mu-kindergarten-${remove}`).removeClass('hidden');
|
116
121
|
this._isPlaying = isPlaying;
|
117
122
|
},
|
118
123
|
verifyBrowserSupport() {
|
119
124
|
if (!window.speechSynthesis) {
|
120
|
-
const $button = $('.mu-kindergarten-play-description')
|
125
|
+
const $button = $('.mu-kindergarten-play-description');
|
121
126
|
$button.prop('disabled', true);
|
122
127
|
$button.css('cursor', 'not-allowed');
|
123
|
-
this._action('play', 'stop', false)
|
128
|
+
this._action('play', 'stop', false);
|
124
129
|
}
|
125
130
|
}
|
126
|
-
}
|
131
|
+
};
|
127
132
|
|
128
133
|
}
|
129
134
|
|
@@ -143,7 +148,7 @@ mumuki.load(() => {
|
|
143
148
|
const $hintMedia = $('.mu-kindergarten-hint-media');
|
144
149
|
if (!$hintMedia.get(0)) $button.addClass('hidden');
|
145
150
|
},
|
146
|
-
}
|
151
|
+
};
|
147
152
|
}
|
148
153
|
|
149
154
|
get context() {
|
@@ -1,7 +1,7 @@
|
|
1
1
|
mumuki.load(() => {
|
2
2
|
var Chat = {
|
3
3
|
$body: function () {
|
4
|
-
return $('body')
|
4
|
+
return $('body');
|
5
5
|
},
|
6
6
|
$newMessageModal: function () {
|
7
7
|
return $('.new-message-modal');
|
@@ -18,7 +18,7 @@ mumuki.load(() => {
|
|
18
18
|
$('.notifications-box').toggleClass('notifications-box-empty', !data.has_messages);
|
19
19
|
$('.pending-messages-filter').removeClass('pending-messages-filter');
|
20
20
|
$('button.btn-submit').removeClass('disabled');
|
21
|
-
$('.pending-messages-text').remove()
|
21
|
+
$('.pending-messages-text').remove();
|
22
22
|
},
|
23
23
|
readMessages: function (url) {
|
24
24
|
Chat.tokenRequest({
|
@@ -26,10 +26,10 @@ mumuki.load(() => {
|
|
26
26
|
method: 'POST',
|
27
27
|
success: Chat.setMessages,
|
28
28
|
xhrFields: {withCredentials: true}
|
29
|
-
})
|
29
|
+
});
|
30
30
|
},
|
31
31
|
tokenRequest: function (data) {
|
32
|
-
$.ajax(Chat.token.newRequest(data))
|
32
|
+
$.ajax(Chat.token.newRequest(data));
|
33
33
|
},
|
34
34
|
getMessages: function () {
|
35
35
|
if ($('.badge-messages').length == 0) {
|
@@ -74,7 +74,7 @@ mumuki.load(() => {
|
|
74
74
|
success: success,
|
75
75
|
error: error,
|
76
76
|
xhrFields: {withCredentials: true}
|
77
|
-
})
|
77
|
+
});
|
78
78
|
},
|
79
79
|
openNewMessageModal: function () {
|
80
80
|
Chat.$newMessageModal().modal({backdrop: false, keyboard: false});
|
@@ -89,5 +89,5 @@ mumuki.load(() => {
|
|
89
89
|
Chat.setMessagesInterval();
|
90
90
|
mumuki.Chat = Chat;
|
91
91
|
|
92
|
-
})
|
92
|
+
});
|
93
93
|
|
@@ -41,7 +41,7 @@ mumuki.ModalCarrousel = (() => {
|
|
41
41
|
|
42
42
|
_hidePreviousButtonIfFirstSlide() {
|
43
43
|
const $prev = $('.mu-kids-modal-button.mu-previous');
|
44
|
-
this._addClassIf($prev, 'hidden', () => this._activeSlide().is(':first-child'))
|
44
|
+
this._addClassIf($prev, 'hidden', () => this._activeSlide().is(':first-child'));
|
45
45
|
}
|
46
46
|
|
47
47
|
_showFirstSlide() {
|
@@ -103,11 +103,11 @@ mumuki.load(() => {
|
|
103
103
|
}
|
104
104
|
|
105
105
|
get highlightModes() {
|
106
|
-
return this._getDataFromHiddenInput('#highlight-modes')
|
106
|
+
return this._getDataFromHiddenInput('#highlight-modes');
|
107
107
|
}
|
108
108
|
|
109
109
|
get locales() {
|
110
|
-
return this._getDataFromHiddenInput('#multifile-locales')
|
110
|
+
return this._getDataFromHiddenInput('#multifile-locales');
|
111
111
|
}
|
112
112
|
|
113
113
|
setUpAddFile() {
|
@@ -131,7 +131,7 @@ mumuki.load(() => {
|
|
131
131
|
|
132
132
|
this._setVisibility(this._addFileButton, filesCount < this.MAX_TABS);
|
133
133
|
this.files.toArray().forEach(file => {
|
134
|
-
this._setVisibility(file.deleteButton, file.name !== this.mainFile && filesCount > 1)
|
134
|
+
this._setVisibility(file.deleteButton, file.name !== this.mainFile && filesCount > 1);
|
135
135
|
});
|
136
136
|
}
|
137
137
|
|
@@ -16,7 +16,6 @@ mumuki.load(() => {
|
|
16
16
|
super.initialize();
|
17
17
|
this.$characterSpeechBubble = $('.mu-kids-character-speech-bubble');
|
18
18
|
this.$characterSpeechBubbleNormal = this.$characterSpeechBubble.children('.mu-kids-character-speech-bubble-normal');
|
19
|
-
this.$overlay = $('.mu-kids-overlay');
|
20
19
|
this.$contextModalButton = new mumuki.Button($('.mu-kids-context .modal-footer button'));
|
21
20
|
|
22
21
|
this._paragraphHeight = undefined;
|
@@ -58,6 +57,10 @@ mumuki.load(() => {
|
|
58
57
|
this.showNonAbortedPopup(data, 'success2_l', 4000);
|
59
58
|
}
|
60
59
|
|
60
|
+
_showPassedWithWarnings(data) {
|
61
|
+
this.showNonAbortedPopup(data, 'passed_with_warnings', 4000);
|
62
|
+
}
|
63
|
+
|
61
64
|
_showFailurePopup(data) {
|
62
65
|
this._showOnCharacterBubble(data);
|
63
66
|
}
|
@@ -83,7 +86,7 @@ mumuki.load(() => {
|
|
83
86
|
this._$texts.hide();
|
84
87
|
this.$characterSpeechBubbleNormal.children('.' + $tab.data('target')).show();
|
85
88
|
this._updateSpeechParagraphs();
|
86
|
-
})
|
89
|
+
});
|
87
90
|
}
|
88
91
|
});
|
89
92
|
|
@@ -137,6 +140,7 @@ mumuki.load(() => {
|
|
137
140
|
const $bubble = this.$characterSpeechBubble;
|
138
141
|
Object.keys(this.resultActions).forEach($bubble.removeClass.bind($bubble));
|
139
142
|
mumuki.presenterCharacter.playAnimation('talk', this.$bubbleCharacterAnimation);
|
143
|
+
this.hideOverlay();
|
140
144
|
}
|
141
145
|
|
142
146
|
// =======================
|
@@ -150,7 +154,6 @@ mumuki.load(() => {
|
|
150
154
|
$bubble.find('.mu-kids-character-speech-bubble-failed').hide();
|
151
155
|
$bubble.find('.mu-kids-discussion-link').remove();
|
152
156
|
Object.keys(this.resultActions).forEach($bubble.removeClass.bind($bubble));
|
153
|
-
this.$overlay.hide();
|
154
157
|
}
|
155
158
|
|
156
159
|
_showMessageOnCharacterBubble(data) {
|
@@ -158,7 +161,6 @@ mumuki.load(() => {
|
|
158
161
|
renderer.setDiscussionsLinkHtml($('#mu-kids-discussion-link-html').html());
|
159
162
|
renderer.setResponseData(data);
|
160
163
|
renderer.render();
|
161
|
-
this.$overlay.show();
|
162
164
|
}
|
163
165
|
|
164
166
|
_showOnCharacterBubble(data) {
|
@@ -35,6 +35,32 @@ mumuki.renderers.results = (() => {
|
|
35
35
|
}
|
36
36
|
}
|
37
37
|
|
38
|
+
/**
|
39
|
+
* @param {SubmissionStatus} status
|
40
|
+
* @param {Boolean} isGamifiedContext
|
41
|
+
* @returns {string}
|
42
|
+
*/
|
43
|
+
function translatedTitleHtml(status, isGamifiedContext) {
|
44
|
+
return `
|
45
|
+
<h4 class="text-${classForStatus(status)} %>">
|
46
|
+
<strong><i class="fa-fw fas ${iconForStatus(status)}"></i> ${mumuki.I18n.t(status)}</strong>
|
47
|
+
${gamifiedContextHtml(isGamifiedContext)}
|
48
|
+
</h4>
|
49
|
+
`
|
50
|
+
}
|
51
|
+
|
52
|
+
/**
|
53
|
+
* @param {Boolean} isGamifiedContext
|
54
|
+
* @returns {string}
|
55
|
+
*/
|
56
|
+
function gamifiedContextHtml(isGamifiedContext) {
|
57
|
+
return (!isGamifiedContext) ? '' : `
|
58
|
+
<strong><small class="text-success">
|
59
|
+
<span class="mu-experience"></span>
|
60
|
+
</small></strong>
|
61
|
+
`
|
62
|
+
}
|
63
|
+
|
38
64
|
|
39
65
|
/**
|
40
66
|
* @param {SubmissionStatus} status
|
@@ -48,8 +74,9 @@ mumuki.renderers.results = (() => {
|
|
48
74
|
return {
|
49
75
|
classForStatus,
|
50
76
|
iconForStatus,
|
51
|
-
progressListItemClassForStatus
|
52
|
-
|
77
|
+
progressListItemClassForStatus,
|
78
|
+
translatedTitleHtml
|
79
|
+
};
|
53
80
|
})();
|
54
81
|
|
55
82
|
/** @deprecated use {@code mumuki.renderers.results.classForStatus} instead */
|
@@ -20,7 +20,7 @@ mumuki.renderers.speechBubble = (()=> {
|
|
20
20
|
|
21
21
|
_chooseResultItem() {
|
22
22
|
if (this._responseStatus() !== 'passed' && this._hasTips()) {
|
23
|
-
this._appendFirstTip()
|
23
|
+
this._appendFirstTip();
|
24
24
|
} else if (this._responseStatus() === 'failed') {
|
25
25
|
this._appendFirstFailedTestResultSummary();
|
26
26
|
} else if (this._responseStatus() === 'passed_with_warnings') {
|
@@ -29,7 +29,7 @@ mumuki.renderers.speechBubble = (()=> {
|
|
29
29
|
}
|
30
30
|
|
31
31
|
_appendFirstFailedTestResultSummary() {
|
32
|
-
const failedTestResult = this._failedTestResults()[0]
|
32
|
+
const failedTestResult = this._failedTestResults()[0];
|
33
33
|
if (failedTestResult && failedTestResult.summary) {
|
34
34
|
this._appendResultItem(mumuki.renderers.renderSpeechBubbleResultItem(failedTestResult.summary));
|
35
35
|
}
|
@@ -67,7 +67,7 @@ mumuki.renderers.speechBubble = (()=> {
|
|
67
67
|
}
|
68
68
|
|
69
69
|
_hasTips() {
|
70
|
-
return this.responseData.tips && this.responseData.tips.length
|
70
|
+
return this.responseData.tips && this.responseData.tips.length;
|
71
71
|
}
|
72
72
|
|
73
73
|
_failedTestResults() {
|
@@ -97,7 +97,7 @@ mumuki.renderers.speechBubble = (()=> {
|
|
97
97
|
return {
|
98
98
|
SpeechBubbleRenderer,
|
99
99
|
renderSpeechBubbleResultItem
|
100
|
-
}
|
100
|
+
};
|
101
101
|
})();
|
102
102
|
|
103
103
|
/** @deprecated use {@code mumuki.renderers.speechBubble.SpeechBubbleRenderer} instead */
|
@@ -55,8 +55,50 @@ mumuki.submission = (() => {
|
|
55
55
|
this.preventClick();
|
56
56
|
}
|
57
57
|
}
|
58
|
+
|
59
|
+
solutionSender(bridge, solution) {
|
60
|
+
return bridge._submitSolution(solution);
|
61
|
+
}
|
62
|
+
|
63
|
+
solutionProcessor(bridge, $submissionsResults, solution) {
|
64
|
+
const resultsBox = new ResultsBox($submissionsResults);
|
65
|
+
this.disable();
|
66
|
+
this.setWaitingText();
|
67
|
+
resultsBox.waiting();
|
68
|
+
return this.solutionSender(bridge, solution)
|
69
|
+
.done((data) => resultsBox.success(data, this))
|
70
|
+
.fail(() => resultsBox.error(this))
|
71
|
+
.always((data) => {
|
72
|
+
$(document).renderMuComponents();
|
73
|
+
resultsBox.done(data, this);
|
74
|
+
});
|
75
|
+
}
|
58
76
|
}
|
59
77
|
|
78
|
+
class KidsSubmitButton extends SubmitButton {
|
79
|
+
|
80
|
+
wait() {
|
81
|
+
mumuki.kids.showOverlay();
|
82
|
+
super.wait();
|
83
|
+
}
|
84
|
+
|
85
|
+
continue() {
|
86
|
+
mumuki.kids.hideOverlay();
|
87
|
+
super.continue();
|
88
|
+
}
|
89
|
+
|
90
|
+
solutionProcessor(bridge, $submissionsResults, solution) {
|
91
|
+
this.wait();
|
92
|
+
return this.solutionSender(bridge, solution)
|
93
|
+
.then((data) => mumuki.kids.showResult(data))
|
94
|
+
.always((data) => {
|
95
|
+
this.ready(() => {
|
96
|
+
mumuki.kids.restart();
|
97
|
+
this.continue();
|
98
|
+
});
|
99
|
+
});
|
100
|
+
}
|
101
|
+
}
|
60
102
|
|
61
103
|
// ==========
|
62
104
|
// Processing
|
@@ -67,14 +109,28 @@ mumuki.submission = (() => {
|
|
67
109
|
* restoring buttons state.
|
68
110
|
*
|
69
111
|
* The actual implementation of this method depends on contextual {@link _solutionProcessor}, which can
|
70
|
-
* be configured using {@link _registerSolutionProcessor}. Currently there are only two available processors
|
71
|
-
*
|
72
|
-
* on the exercise DOM.
|
112
|
+
* be configured using {@link _registerSolutionProcessor}. Currently there are only two available processors
|
113
|
+
* which are automatically choosen depending on the exercise DOM.
|
73
114
|
*
|
74
115
|
* @param {Submission} solution
|
75
116
|
*/
|
76
117
|
function processSolution(solution) {
|
77
|
-
mumuki.submission._solutionProcessor(solution);
|
118
|
+
return mumuki.submission._solutionProcessor(solution);
|
119
|
+
}
|
120
|
+
|
121
|
+
/**
|
122
|
+
* Just sends solution to the server without any further processing afterwards.
|
123
|
+
*
|
124
|
+
* Consider using {@link processSolution} instead if you want the whole functionality (making buttons wait, sending to server, rendering results,
|
125
|
+
* restoring buttons state).
|
126
|
+
* The implementation of this method isn't contextual, it always sends the solution using bridge module.
|
127
|
+
*
|
128
|
+
* @see mumuki.bridge
|
129
|
+
*
|
130
|
+
* @param {Submission} solution
|
131
|
+
*/
|
132
|
+
function sendSolution(solution) {
|
133
|
+
return mumuki.submission._solutionSender(solution);
|
78
134
|
}
|
79
135
|
|
80
136
|
/**
|
@@ -84,53 +140,19 @@ mumuki.submission = (() => {
|
|
84
140
|
* and should normally not be called by runners editor, but is exposed
|
85
141
|
* for further non-standard customizations.
|
86
142
|
*
|
87
|
-
* @param {
|
143
|
+
* @param {SubmitButton} submitButton
|
144
|
+
* @param {$ElementType} $submissionsResults
|
145
|
+
* @param {mumuki.bridge} bridge
|
88
146
|
*/
|
89
|
-
function _registerSolutionProcessor(
|
90
|
-
mumuki.submission.
|
91
|
-
|
92
|
-
|
93
|
-
/** Processor for kids layouts */
|
94
|
-
function _kidsSolutionProcessor(bridge, submitButton) {
|
95
|
-
return (solution) => {
|
96
|
-
submitButton.wait();
|
97
|
-
bridge._submitSolution(solution).always(function (data) {
|
98
|
-
submitButton.ready(() => {
|
99
|
-
mumuki.kids.restart();
|
100
|
-
submitButton.continue();
|
101
|
-
});
|
102
|
-
mumuki.kids.showResult(data);
|
103
|
-
});
|
104
|
-
}
|
105
|
-
}
|
106
|
-
|
107
|
-
/** Processor for non-kids layouts */
|
108
|
-
function _classicSolutionProcessor(bridge, submitButton, resultsBox) {
|
109
|
-
return (solution) => {
|
110
|
-
submitButton.disable();
|
111
|
-
submitButton.setWaitingText();
|
112
|
-
resultsBox.waiting();
|
113
|
-
bridge._submitSolution(solution).done(function (data) {
|
114
|
-
resultsBox.success(data, submitButton);
|
115
|
-
}).fail(function () {
|
116
|
-
resultsBox.error(submitButton);
|
117
|
-
}).always(function (data) {
|
118
|
-
$(document).renderMuComponents();
|
119
|
-
resultsBox.done(data, submitButton);
|
120
|
-
});
|
121
|
-
}
|
147
|
+
function _registerSolutionProcessor(submitButton, $submissionsResults, bridge) {
|
148
|
+
mumuki.submission._solutionSender = submitButton.solutionSender.bind(submitButton, bridge);
|
149
|
+
mumuki.submission._solutionProcessor = submitButton.solutionProcessor.bind(submitButton, bridge, $submissionsResults);
|
122
150
|
}
|
123
151
|
|
124
152
|
/** Selects the most appropriate solution processor */
|
125
153
|
function _selectSolutionProcessor(submitButton, $submissionsResults) {
|
126
154
|
const bridge = new mumuki.bridge.Laboratory();
|
127
|
-
|
128
|
-
if ($('.mu-kids-exercise').length) {
|
129
|
-
processor = _kidsSolutionProcessor(bridge, submitButton);
|
130
|
-
} else {
|
131
|
-
processor = _classicSolutionProcessor(bridge, submitButton, new ResultsBox($submissionsResults));
|
132
|
-
}
|
133
|
-
mumuki.submission._registerSolutionProcessor(processor);
|
155
|
+
mumuki.submission._registerSolutionProcessor(submitButton, $submissionsResults, bridge);
|
134
156
|
}
|
135
157
|
|
136
158
|
|
@@ -143,8 +165,8 @@ mumuki.submission = (() => {
|
|
143
165
|
if (!$submissionsResults) return;
|
144
166
|
|
145
167
|
const $btnSubmit = $('.btn-submit');
|
146
|
-
const
|
147
|
-
|
168
|
+
const buttonClass = mumuki.isKidsExercise() ? KidsSubmitButton : SubmitButton;
|
169
|
+
const submitButton = new buttonClass($btnSubmit, $('.submission_control'));
|
148
170
|
mumuki.submission._selectSolutionProcessor(submitButton, $submissionsResults);
|
149
171
|
|
150
172
|
submitButton.start(() => {
|
@@ -154,7 +176,6 @@ mumuki.submission = (() => {
|
|
154
176
|
submitButton.checkAttemptsLeft();
|
155
177
|
});
|
156
178
|
|
157
|
-
|
158
179
|
/**
|
159
180
|
* This module contains methods for submitting solution in at high level, dealing with network communication,
|
160
181
|
* and layout-sensitive UI updates. It is intended to be both used internally by standard editors and by runners
|
@@ -171,10 +192,13 @@ mumuki.submission = (() => {
|
|
171
192
|
*/
|
172
193
|
return {
|
173
194
|
processSolution,
|
195
|
+
sendSolution,
|
196
|
+
|
174
197
|
_registerSolutionProcessor,
|
175
198
|
_selectSolutionProcessor,
|
176
199
|
|
177
200
|
animateTimeoutError,
|
178
201
|
SubmitButton,
|
202
|
+
KidsSubmitButton,
|
179
203
|
};
|
180
204
|
})();
|