use attr instead of data
[redakcja.git] / redakcja / static / edumed / js / edumed.js
1 (function() {
2   var $, Binding, EduModule, Excercise, Luki, Przyporzadkuj, Uporzadkuj, Wybor, Zastap, excercise,
3     __hasProp = Object.prototype.hasOwnProperty,
4     __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor; child.__super__ = parent.prototype; return child; };
5
6   $ = jQuery;
7
8   Binding = (function() {
9
10     function Binding(handler, element) {
11       this.handler = handler;
12       this.element = element;
13       $(this.element).data(this.handler, this);
14     }
15
16     return Binding;
17
18   })();
19
20   EduModule = (function(_super) {
21
22     __extends(EduModule, _super);
23
24     function EduModule(element) {
25       var _this = this;
26       EduModule.__super__.constructor.call(this, 'edumodule', element);
27       $("[name=teacher-toggle]").change(function(ev) {
28         if ($(ev.target).is(":checked")) {
29           return $(".teacher", _this.element).addClass("show");
30         } else {
31           return $(".teacher", _this.element).removeClass("show");
32         }
33       });
34     }
35
36     return EduModule;
37
38   })(Binding);
39
40   Excercise = (function(_super) {
41
42     __extends(Excercise, _super);
43
44     function Excercise(element) {
45       var _this = this;
46       Excercise.__super__.constructor.call(this, 'excercise', element);
47       $(".check", this.element).click(function() {
48         return _this.check();
49       });
50       $('.solutions', this.element).click(function() {
51         return _this.show_solutions();
52       });
53     }
54
55     Excercise.prototype.piece_correct = function(qpiece) {
56       return $(qpiece).removeClass('incorrect').addClass('correct');
57     };
58
59     Excercise.prototype.piece_incorrect = function(qpiece) {
60       return $(qpiece).removeClass('correct').addClass('incorrect');
61     };
62
63     Excercise.prototype.check = function() {
64       var score, scores,
65         _this = this;
66       scores = [];
67       $(".question", this.element).each(function(i, question) {
68         return scores.push(_this.check_question(question));
69       });
70       score = [0, 0];
71       $.each(scores, function(i, s) {
72         score[0] += s[0];
73         return score[1] += s[1];
74       });
75       return this.show_score(score);
76     };
77
78     Excercise.prototype.get_value_list = function(elem, data_key, numbers) {
79       var vl;
80       vl = $(elem).attr("data-" + data_key).split(/[ ,]+/).map($.trim);
81       if (numbers) {
82         vl = vl.map(function(x) {
83           return parseInt(x);
84         });
85       }
86       return vl;
87     };
88
89     Excercise.prototype.get_value_optional_list = function(elem, data_key) {
90       var mandat, opt, v, vals, _i, _len;
91       vals = this.get_value_list(elem, data_key);
92       mandat = [];
93       opt = [];
94       for (_i = 0, _len = vals.length; _i < _len; _i++) {
95         v = vals[_i];
96         if (v.slice(-1) === "?") {
97           opt.push(v.slice(0, -1));
98         } else {
99           mandat.push(v);
100         }
101       }
102       return [mandat, opt];
103     };
104
105     Excercise.prototype.show_score = function(score) {
106       return $(".message", this.element).text("Wynik: " + score[0] + " / " + score[1]);
107     };
108
109     return Excercise;
110
111   })(Binding);
112
113   Wybor = (function(_super) {
114
115     __extends(Wybor, _super);
116
117     function Wybor(element) {
118       Wybor.__super__.constructor.call(this, element);
119     }
120
121     Wybor.prototype.check_question = function(question) {
122       var all, good, solution,
123         _this = this;
124       all = 0;
125       good = 0;
126       solution = this.get_value_list(question, 'solution', true);
127       $(".question-piece", question).each(function(i, qpiece) {
128         var is_checked, piece_no, should_be_checked;
129         piece_no = parseInt($(qpiece).attr('data-no'));
130         should_be_checked = solution.indexOf(piece_no) >= 0;
131         is_checked = $("input", qpiece).is(":checked");
132         if (should_be_checked) all += 1;
133         if (is_checked) {
134           if (should_be_checked) {
135             good += 1;
136             return _this.piece_correct(qpiece);
137           } else {
138             return _this.piece_incorrect(qpiece);
139           }
140         } else {
141           return $(qpiece).removeClass("correct,incorrect");
142         }
143       });
144       return [good, all];
145     };
146
147     Wybor.prototype.show_solutions = function() {};
148
149     return Wybor;
150
151   })(Excercise);
152
153   Uporzadkuj = (function(_super) {
154
155     __extends(Uporzadkuj, _super);
156
157     function Uporzadkuj(element) {
158       Uporzadkuj.__super__.constructor.call(this, element);
159       $('ol, ul', this.element).sortable({
160         items: "> li"
161       });
162     }
163
164     Uporzadkuj.prototype.check_question = function(question) {
165       var all, correct, pkt, pkts, positions, sorted, _ref;
166       positions = this.get_value_list(question, 'original', true);
167       sorted = positions.sort();
168       pkts = $('.question-piece', question);
169       correct = 0;
170       all = 0;
171       for (pkt = 0, _ref = pkts.length; 0 <= _ref ? pkt < _ref : pkt > _ref; 0 <= _ref ? pkt++ : pkt--) {
172         all += 1;
173         if (pkts.eq(pkt).data('pos') === sorted[pkt]) {
174           correct += 1;
175           this.piece_correct(pkts.eq(pkt));
176         } else {
177           this.piece_incorrect(pkts.eq(pkt));
178         }
179       }
180       return [correct, all];
181     };
182
183     return Uporzadkuj;
184
185   })(Excercise);
186
187   Luki = (function(_super) {
188
189     __extends(Luki, _super);
190
191     function Luki(element) {
192       Luki.__super__.constructor.call(this, element);
193     }
194
195     Luki.prototype.check = function() {
196       var all, correct,
197         _this = this;
198       all = 0;
199       correct = 0;
200       $(".question-piece", this.element).each(function(i, qpiece) {
201         if ($(qpiece).data('solution') === $(qpiece).val()) {
202           _this.piece_correct(qpiece);
203           correct += 1;
204         } else {
205           _this.piece_incorrect(qpiece);
206         }
207         return all += 1;
208       });
209       return this.show_score([correct, all]);
210     };
211
212     return Luki;
213
214   })(Excercise);
215
216   Zastap = (function(_super) {
217
218     __extends(Zastap, _super);
219
220     function Zastap(element) {
221       var _this = this;
222       Zastap.__super__.constructor.call(this, element);
223       $(".paragraph", this.element).each(function(i, par) {
224         var spans;
225         _this.wrap_words($(par), $('<span class="zastap question-piece"/>'));
226         spans = $("> span", par).attr("contenteditable", "true");
227         return spans.click(function(ev) {
228           spans.filter(':not(:empty)').removeClass('editing');
229           return $(ev.target).addClass('editing');
230         });
231       });
232     }
233
234     Zastap.prototype.check = function() {
235       var all, correct,
236         _this = this;
237       all = 0;
238       correct = 0;
239       $(".question-piece", this.element).each(function(i, qpiece) {
240         var should_be_changed, txt;
241         txt = $(qpiece).data('original');
242         should_be_changed = false;
243         if (!(txt != null)) {
244           txt = $(qpiece).data('solution');
245           should_be_changed = true;
246         }
247         if (!(txt != null)) return;
248         if (should_be_changed) all += 1;
249         if (txt !== $(qpiece).text()) {
250           return _this.piece_incorrect(qpiece);
251         } else {
252           if (should_be_changed) {
253             _this.piece_correct(qpiece);
254             return correct += 1;
255           }
256         }
257       });
258       return this.show_score([correct, all]);
259     };
260
261     Zastap.prototype.wrap_words = function(element, wrapper) {
262       var chld, i, ignore, insertWrapped, j, len, space, wordb, _ref, _results;
263       ignore = /^[ \t.,:;()]+/;
264       insertWrapped = function(txt, elem) {
265         var nw;
266         nw = wrapper.clone();
267         return $(document.createTextNode(txt)).wrap(nw).parent().attr("data-original", txt).insertBefore(elem);
268       };
269       _results = [];
270       for (j = _ref = element.get(0).childNodes.length - 1; _ref <= 0 ? j <= 0 : j >= 0; _ref <= 0 ? j++ : j--) {
271         chld = element.get(0).childNodes[j];
272         if (chld.nodeType === document.TEXT_NODE) {
273           len = chld.textContent.length;
274           wordb = 0;
275           i = 0;
276           while (i < len) {
277             space = ignore.exec(chld.textContent.substr(i));
278             if (space != null) {
279               if (wordb < i) {
280                 insertWrapped(chld.textContent.substr(wordb, i - wordb), chld);
281               }
282               $(document.createTextNode(space[0])).insertBefore(chld);
283               i += space[0].length;
284               wordb = i;
285             } else {
286               i = i + 1;
287             }
288           }
289           if (wordb < len - 1) {
290             insertWrapped(chld.textContent.substr(wordb, len - 1 - wordb), chld);
291           }
292           _results.push($(chld).remove());
293         } else {
294           _results.push(void 0);
295         }
296       }
297       return _results;
298     };
299
300     return Zastap;
301
302   })(Excercise);
303
304   Przyporzadkuj = (function(_super) {
305
306     __extends(Przyporzadkuj, _super);
307
308     Przyporzadkuj.prototype.is_multiple = function() {
309       var qp, _i, _len, _ref;
310       _ref = $(".question-piece", this.element);
311       for (_i = 0, _len = _ref.length; _i < _len; _i++) {
312         qp = _ref[_i];
313         if ($(qp).data('solution').split(/[ ,]+/).length > 1) return true;
314       }
315       return false;
316     };
317
318     function Przyporzadkuj(element) {
319       var _this = this;
320       Przyporzadkuj.__super__.constructor.call(this, element);
321       this.multiple = this.is_multiple();
322       $(".question", this.element).each(function(i, question) {
323         var draggable_opts, helper_opts;
324         draggable_opts = {
325           revert: 'invalid'
326         };
327         if (_this.multiple) {
328           helper_opts = {
329             helper: "clone"
330           };
331         } else {
332           helper_opts = {};
333         }
334         $(".draggable", question).draggable($.extend({}, draggable_opts, helper_opts));
335         $(".predicate .droppable", question).droppable({
336           accept: function(draggable) {
337             var $draggable, $predicate, added, _i, _len, _ref;
338             $draggable = $(draggable);
339             if (!$draggable.is(".draggable")) return false;
340             $predicate = $(this);
341             _ref = $predicate.find("li");
342             for (_i = 0, _len = _ref.length; _i < _len; _i++) {
343               added = _ref[_i];
344               if ($(added).text() === $draggable.text()) return false;
345             }
346             return true;
347           },
348           drop: function(ev, ui) {
349             var added;
350             added = ui.draggable.clone();
351             added.attr('style', '');
352             $(ev.target).append(added);
353             added.draggable(draggable_opts);
354             if (!_this.multiple || ui.draggable.closest(".predicate").length > 0) {
355               return ui.draggable.remove();
356             }
357           }
358         });
359         return $(".subject", question).droppable({
360           accept: ".draggable",
361           drop: function(ev, ui) {
362             var added;
363             if ($(ui.draggable).closest(".subject").length > 0) return;
364             added = ui.draggable.clone();
365             added.attr('style', '');
366             if (!_this.multiple) {
367               $(ev.target).append(added);
368               added.draggable($.extend({}, draggable_opts, helper_opts));
369             }
370             return ui.draggable.remove();
371           }
372         });
373       });
374     }
375
376     Przyporzadkuj.prototype.check_question = function(question) {
377       var all, all_multiple, count, mandatory, optional, pn, pred, qp, v, _i, _j, _len, _len2, _ref, _ref2;
378       count = 0;
379       all = 0;
380       all_multiple = 0;
381       _ref = $(".predicate .question-piece", question);
382       for (_i = 0, _len = _ref.length; _i < _len; _i++) {
383         qp = _ref[_i];
384         pred = $(qp).closest("[data-predicate]");
385         v = this.get_value_optional_list(qp, 'solution');
386         mandatory = v[0];
387         optional = v[1];
388         all_multiple += mandatory.length + optional.length;
389         pn = pred.data('predicate');
390         if (mandatory.indexOf(pn) >= 0 || optional.indexOf(pn) >= 0) {
391           count += 1;
392           this.piece_correct(qp);
393         } else {
394           this.piece_incorrect(qp);
395         }
396         all += 1;
397       }
398       if (this.multiple) {
399         _ref2 = $(".subject .question-piece", question);
400         for (_j = 0, _len2 = _ref2.length; _j < _len2; _j++) {
401           qp = _ref2[_j];
402           v = this.get_value_optional_list(qp, 'solution');
403           mandatory = v[0];
404           optional = v[1];
405           all_multiple += mandatory.length + optional.length;
406         }
407         return [count, all_multiple];
408       } else {
409         return [count, all];
410       }
411     };
412
413     return Przyporzadkuj;
414
415   })(Excercise);
416
417   excercise = function(ele) {
418     var cls, es;
419     es = {
420       wybor: Wybor,
421       uporzadkuj: Uporzadkuj,
422       luki: Luki,
423       zastap: Zastap,
424       przyporzadkuj: Przyporzadkuj
425     };
426     cls = es[$(ele).attr('data-type')];
427     return new cls(ele);
428   };
429
430   window.edumed = {
431     'EduModule': EduModule
432   };
433
434   $(document).ready(function() {
435     new EduModule($("#book-text"));
436     return $(".excercise").each(function(i, el) {
437       return excercise(this);
438     });
439   });
440
441 }).call(this);