data() considered harmful
[edumed.git] / catalogue / static / catalogue / js / edumed.js
1 // Generated by CoffeeScript 1.4.0
2 (function() {
3   var $, Binding, EduModule, Exercise, Luki, PrawdaFalsz, Przyporzadkuj, Uporzadkuj, Wybor, Zastap, exercise,
4     __hasProp = {}.hasOwnProperty,
5     __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; };
6
7   $ = jQuery;
8
9   Binding = (function() {
10
11     function Binding(handler, element) {
12       this.handler = handler;
13       this.element = element;
14       $(this.element).data(this.handler, this);
15     }
16
17     return Binding;
18
19   })();
20
21   EduModule = (function(_super) {
22
23     __extends(EduModule, _super);
24
25     function EduModule(element) {
26       EduModule.__super__.constructor.call(this, 'edumodule', element);
27     }
28
29     return EduModule;
30
31   })(Binding);
32
33   Exercise = (function(_super) {
34
35     __extends(Exercise, _super);
36
37     function Exercise(element) {
38       var _this = this;
39       Exercise.__super__.constructor.call(this, 'exercise', element);
40       $(this.element).data("exercise-html", $(this.element).html());
41       $(".check", this.element).click(function(ev) {
42         _this.check();
43         $(ev.target).next(".retry").show();
44         return $(ev.target).hide();
45       });
46       $(".retry", this.element).click(function(ev) {
47         return _this.retry();
48       });
49       $('.solutions', this.element).click(function() {
50         _this.show_solutions();
51         return $(".comment", _this.element).show();
52       });
53       $('.reset', this.element).click(function() {
54         return _this.reset();
55       });
56     }
57
58     Exercise.prototype.retry = function() {
59       $(".correct, .incorrect", this.element).removeClass("correct incorrect");
60       $(".check", this.element).show();
61       return $(".retry", this.element).hide();
62     };
63
64     Exercise.prototype.reset = function() {
65       $(this.element).html($(this.element).data('exercise-html'));
66       return exercise(this.element);
67     };
68
69     Exercise.prototype.piece_correct = function(qpiece) {
70       return $(qpiece).removeClass('incorrect').addClass('correct');
71     };
72
73     Exercise.prototype.piece_incorrect = function(qpiece) {
74       return $(qpiece).removeClass('correct').addClass('incorrect');
75     };
76
77     Exercise.prototype.check = function() {
78       var score, scores,
79         _this = this;
80       scores = [];
81       $(".question", this.element).each(function(i, question) {
82         return scores.push(_this.check_question(question));
83       });
84       score = [0, 0];
85       $.each(scores, function(i, s) {
86         score[0] += s[0];
87         return score[1] += s[1];
88       });
89       return this.show_score(score);
90     };
91
92     Exercise.prototype.show_solutions = function() {
93       var _this = this;
94       this.reset();
95       return $(".question", this.element).each(function(i, question) {
96         return _this.solve_question(question);
97       });
98     };
99
100     Exercise.prototype.get_value_list = function(elem, data_key, numbers) {
101       var vl;
102       vl = $(elem).attr("data-" + data_key).split(/[ ,]+/).map($.trim);
103       if (numbers) {
104         vl = vl.map(function(x) {
105           return parseInt(x);
106         });
107       }
108       return vl;
109     };
110
111     Exercise.prototype.get_value_optional_list = function(elem, data_key) {
112       var mandat, opt, v, vals, _i, _len;
113       vals = this.get_value_list(elem, data_key);
114       mandat = [];
115       opt = [];
116       for (_i = 0, _len = vals.length; _i < _len; _i++) {
117         v = vals[_i];
118         if (v.slice(-1) === "?") {
119           opt.push(v.slice(0, -1));
120         } else {
121           mandat.push(v);
122         }
123       }
124       return [mandat, opt];
125     };
126
127     Exercise.prototype.show_score = function(score) {
128       var $msg;
129       $msg = $(".message", this.element);
130       $msg.text("Wynik: " + score[0] + " / " + score[1]);
131       if (score[0] === score[1]) {
132         return $msg.addClass("maxscore");
133       } else {
134         return $msg.removeClass("maxscore");
135       }
136     };
137
138     Exercise.prototype.draggable_equal = function($draggable1, $draggable2) {
139       return false;
140     };
141
142     Exercise.prototype.draggable_accept = function($draggable, $droppable) {
143       var d, dropped, _i, _len;
144       dropped = $droppable.closest("ul, ol").find(".draggable");
145       for (_i = 0, _len = dropped.length; _i < _len; _i++) {
146         d = dropped[_i];
147         if (this.draggable_equal($draggable, $(d))) {
148           return false;
149         }
150       }
151       return true;
152     };
153
154     Exercise.prototype.draggable_move = function($draggable, $placeholder, ismultiple) {
155       var $added,
156         _this = this;
157       $added = $draggable.clone();
158       $added.data("original", $draggable.get(0));
159       if (!ismultiple) {
160         $draggable.addClass('disabled').draggable('disable');
161       }
162       $placeholder.after($added);
163       if (!$placeholder.hasClass('multiple')) {
164         $placeholder.hide();
165       }
166       if ($added.is(".add-li")) {
167         $added.wrap("<li/>");
168       }
169       $added.append('<span class="remove">x</span><div class="clr"></div>');
170       return $('.remove', $added).click(function(ev) {
171         _this.retry();
172         if (!ismultiple) {
173           $($added.data('original')).removeClass('disabled').draggable('enable');
174         }
175         if ($added.is(".add-li")) {
176           $added = $added.closest('li');
177         }
178         $added.prev(".placeholder:not(.multiple)").show();
179         return $added.remove();
180       });
181     };
182
183     Exercise.prototype.dragging = function(ismultiple, issortable) {
184       var _this = this;
185       return $(".question", this.element).each(function(i, question) {
186         var draggable_opts, self;
187         draggable_opts = {
188           revert: 'invalid',
189           helper: 'clone',
190           start: _this.retry
191         };
192         $(".draggable", question).draggable(draggable_opts);
193         self = _this;
194         return $(".placeholder", question).droppable({
195           accept: function(draggable) {
196             var $draggable, is_accepted;
197             $draggable = $(draggable);
198             is_accepted = true;
199             if (!$draggable.is(".draggable")) {
200               is_accepted = false;
201             }
202             if (is_accepted) {
203               is_accepted = self.draggable_accept($draggable, $(this));
204             }
205             if (is_accepted) {
206               $(this).addClass('accepting');
207             } else {
208               $(this).removeClass('accepting');
209             }
210             return is_accepted;
211           },
212           drop: function(ev, ui) {
213             $(ev.target).removeClass('accepting dragover');
214             return _this.draggable_move($(ui.draggable), $(ev.target), ismultiple);
215           },
216           over: function(ev, ui) {
217             return $(ev.target).addClass('dragover');
218           },
219           out: function(ev, ui) {
220             return $(ev.target).removeClass('dragover');
221           }
222         });
223       });
224     };
225
226     return Exercise;
227
228   })(Binding);
229
230   Wybor = (function(_super) {
231
232     __extends(Wybor, _super);
233
234     function Wybor(element) {
235       Wybor.__super__.constructor.call(this, element);
236       $(".question-piece input", element).change(this.retry);
237     }
238
239     Wybor.prototype.check_question = function(question) {
240       var all, good, solution,
241         _this = this;
242       all = 0;
243       good = 0;
244       solution = this.get_value_list(question, 'solution');
245       $(".question-piece", question).each(function(i, qpiece) {
246         var is_checked, piece_name, piece_no, should_be_checked;
247         piece_no = $(qpiece).attr('data-no');
248         piece_name = $(qpiece).attr('data-name');
249         if (piece_name) {
250           should_be_checked = solution.indexOf(piece_name) >= 0;
251         } else {
252           should_be_checked = solution.indexOf(piece_no) >= 0;
253         }
254         is_checked = $("input", qpiece).is(":checked");
255         if (should_be_checked) {
256           all += 1;
257         }
258         if (is_checked) {
259           if (should_be_checked) {
260             good += 1;
261             return _this.piece_correct(qpiece);
262           } else {
263             return _this.piece_incorrect(qpiece);
264           }
265         } else {
266           return $(qpiece).removeClass("correct,incorrect");
267         }
268       });
269       return [good, all];
270     };
271
272     Wybor.prototype.solve_question = function(question) {
273       var solution,
274         _this = this;
275       solution = this.get_value_list(question, 'solution');
276       return $(".question-piece", question).each(function(i, qpiece) {
277         var piece_name, piece_no, should_be_checked;
278         piece_no = $(qpiece).attr('data-no');
279         piece_name = $(qpiece).attr('data-name');
280         if (piece_name) {
281           should_be_checked = solution.indexOf(piece_name) >= 0;
282         } else {
283           should_be_checked = solution.indexOf(piece_no) >= 0;
284         }
285         console.log("check " + $("input[type=checkbox]", qpiece).attr("id") + " -> " + should_be_checked);
286         return $("input[type=checkbox],input[type=radio]", qpiece).prop('checked', should_be_checked);
287       });
288     };
289
290     return Wybor;
291
292   })(Exercise);
293
294   Uporzadkuj = (function(_super) {
295
296     __extends(Uporzadkuj, _super);
297
298     function Uporzadkuj(element) {
299       Uporzadkuj.__super__.constructor.call(this, element);
300       $('ol, ul', this.element).sortable({
301         items: "> li",
302         start: this.retry
303       });
304     }
305
306     Uporzadkuj.prototype.check_question = function(question) {
307       var all, correct, pkt, pkts, positions, sorted, _i, _ref;
308       positions = this.get_value_list(question, 'original', true);
309       sorted = positions.sort();
310       pkts = $('.question-piece', question);
311       correct = 0;
312       all = 0;
313       for (pkt = _i = 0, _ref = pkts.length; 0 <= _ref ? _i < _ref : _i > _ref; pkt = 0 <= _ref ? ++_i : --_i) {
314         all += 1;
315         if (pkts.eq(pkt).data('pos') === sorted[pkt]) {
316           correct += 1;
317           this.piece_correct(pkts.eq(pkt));
318         } else {
319           this.piece_incorrect(pkts.eq(pkt));
320         }
321       }
322       return [correct, all];
323     };
324
325     Uporzadkuj.prototype.solve_question = function(question) {
326       var p, parent, pkts, positions, sorted, _i, _len, _results;
327       positions = this.get_value_list(question, 'original', true);
328       sorted = positions.sort();
329       pkts = $('.question-piece', question);
330       pkts.sort(function(a, b) {
331         var q, w;
332         q = $(a).data('pos');
333         w = $(b).data('pos');
334         if (q < w) {
335           return 1;
336         }
337         if (q > w) {
338           return -1;
339         }
340         return 0;
341       });
342       parent = pkts.eq(0).parent();
343       _results = [];
344       for (_i = 0, _len = pkts.length; _i < _len; _i++) {
345         p = pkts[_i];
346         _results.push(parent.prepend(p));
347       }
348       return _results;
349     };
350
351     return Uporzadkuj;
352
353   })(Exercise);
354
355   Luki = (function(_super) {
356
357     __extends(Luki, _super);
358
359     function Luki(element) {
360       Luki.__super__.constructor.call(this, element);
361       this.dragging(false, false);
362     }
363
364     Luki.prototype.check = function() {
365       var all, correct,
366         _this = this;
367       all = 0;
368       correct = 0;
369       $(".placeholder + .question-piece", this.element).each(function(i, qpiece) {
370         var $placeholder;
371         $placeholder = $(qpiece).prev(".placeholder");
372         if ($placeholder.data('solution') === $(qpiece).data('no')) {
373           _this.piece_correct(qpiece);
374           correct += 1;
375         } else {
376           _this.piece_incorrect(qpiece);
377         }
378         return all += 1;
379       });
380       return this.show_score([correct, all]);
381     };
382
383     Luki.prototype.solve_question = function(question) {
384       var _this = this;
385       return $(".placeholder", question).each(function(i, placeholder) {
386         var $qp;
387         $qp = $(".question-piece[data-no=" + $(placeholder).data('solution') + "]", question);
388         return _this.draggable_move($qp, $(placeholder), false);
389       });
390     };
391
392     return Luki;
393
394   })(Exercise);
395
396   Zastap = (function(_super) {
397
398     __extends(Zastap, _super);
399
400     function Zastap(element) {
401       var _this = this;
402       Zastap.__super__.constructor.call(this, element);
403       $(".paragraph", this.element).each(function(i, par) {
404         return _this.wrap_words($(par), $('<span class="placeholder zastap"/>'));
405       });
406       this.dragging(false, false);
407     }
408
409     Zastap.prototype.check = function() {
410       var all, correct,
411         _this = this;
412       all = 0;
413       correct = 0;
414       $(".paragraph", this.element).each(function(i, par) {
415         return $(".placeholder", par).each(function(j, qpiece) {
416           var $dragged, $qp;
417           $qp = $(qpiece);
418           $dragged = $qp.next(".draggable");
419           if ($qp.data("solution")) {
420             if ($dragged && $qp.data("solution") === $dragged.data("no")) {
421               _this.piece_correct($dragged);
422               correct += 1;
423             }
424             return all += 1;
425           }
426         });
427       });
428       return this.show_score([correct, all]);
429     };
430
431     Zastap.prototype.show_solutions = function() {
432       var _this = this;
433       this.reset();
434       return $(".paragraph", this.element).each(function(i, par) {
435         return $(".placeholder[data-solution]", par).each(function(j, qpiece) {
436           var $dr, $qp;
437           $qp = $(qpiece);
438           $dr = $(".draggable[data-no=" + $qp.data('solution') + "]", _this.element);
439           return _this.draggable_move($dr, $qp, false);
440         });
441       });
442     };
443
444     Zastap.prototype.wrap_words = function(element, wrapper) {
445       var chld, i, ignore, insertWrapped, j, len, space, wordb, _i, _ref, _results;
446       ignore = /^[ \t.,:;()]+/;
447       insertWrapped = function(txt, elem) {
448         var nw;
449         nw = wrapper.clone();
450         return $(document.createTextNode(txt)).wrap(nw).parent().attr("data-original", txt).insertBefore(elem);
451       };
452       _results = [];
453       for (j = _i = _ref = element.get(0).childNodes.length - 1; _ref <= 0 ? _i <= 0 : _i >= 0; j = _ref <= 0 ? ++_i : --_i) {
454         chld = element.get(0).childNodes[j];
455         if (chld.nodeType === document.TEXT_NODE) {
456           len = chld.textContent.length;
457           wordb = 0;
458           i = 0;
459           while (i < len) {
460             space = ignore.exec(chld.textContent.substr(i));
461             if (space != null) {
462               if (wordb < i) {
463                 insertWrapped(chld.textContent.substr(wordb, i - wordb), chld);
464               }
465               $(document.createTextNode(space[0])).insertBefore(chld);
466               i += space[0].length;
467               wordb = i;
468             } else {
469               i = i + 1;
470             }
471           }
472           if (wordb < len - 1) {
473             insertWrapped(chld.textContent.substr(wordb, len - 1 - wordb), chld);
474           }
475           _results.push($(chld).remove());
476         } else {
477           _results.push(void 0);
478         }
479       }
480       return _results;
481     };
482
483     return Zastap;
484
485   })(Exercise);
486
487   Przyporzadkuj = (function(_super) {
488
489     __extends(Przyporzadkuj, _super);
490
491     Przyporzadkuj.prototype.is_multiple = function() {
492       var qp, _i, _len, _ref;
493       _ref = $(".question-piece", this.element);
494       for (_i = 0, _len = _ref.length; _i < _len; _i++) {
495         qp = _ref[_i];
496         if ($(qp).attr('data-solution').split(/[ ,]+/).length > 1) {
497           return true;
498         }
499       }
500       return false;
501     };
502
503     function Przyporzadkuj(element) {
504       Przyporzadkuj.__super__.constructor.call(this, element);
505       this.multiple = this.is_multiple();
506       this.dragging(this.multiple, true);
507     }
508
509     Przyporzadkuj.prototype.draggable_equal = function(d1, d2) {
510       return d1.data("no") === d2.data("no");
511     };
512
513     Przyporzadkuj.prototype.check_question = function(question) {
514       var all, count, mandatory, minimum, optional, pn, pred, qp, v, _i, _j, _len, _len1, _ref, _ref1;
515       minimum = $(question).data("minimum");
516       count = 0;
517       all = 0;
518       if (!minimum) {
519         all = $(".subjects .question-piece", question).length;
520       }
521       _ref = $(".predicate [data-predicate]", question);
522       for (_i = 0, _len = _ref.length; _i < _len; _i++) {
523         pred = _ref[_i];
524         pn = $(pred).attr('data-predicate');
525         if (minimum != null) {
526           all += minimum;
527         }
528         _ref1 = $(".question-piece", pred);
529         for (_j = 0, _len1 = _ref1.length; _j < _len1; _j++) {
530           qp = _ref1[_j];
531           v = this.get_value_optional_list(qp, 'solution');
532           mandatory = v[0];
533           optional = v[1];
534           if (mandatory.indexOf(pn) >= 0 || (minimum && optional.indexOf(pn) >= 0)) {
535             count += 1;
536             this.piece_correct(qp);
537           } else {
538             this.piece_incorrect(qp);
539           }
540         }
541       }
542       return [count, all];
543     };
544
545     Przyporzadkuj.prototype.solve_question = function(question) {
546       var $ph, $pr, draggables, m, mandatory, minimum, optional, qp, v, _i, _len, _ref, _results;
547       minimum = $(question).data("min");
548       _ref = $(".subject .question-piece", question);
549       _results = [];
550       for (_i = 0, _len = _ref.length; _i < _len; _i++) {
551         qp = _ref[_i];
552         v = this.get_value_optional_list(qp, 'solution');
553         mandatory = v[0];
554         optional = v[1];
555         if (minimum) {
556           draggables = mandatory.count(optional).slice(0, minimum);
557         } else {
558           draggables = mandatory;
559         }
560         _results.push((function() {
561           var _j, _len1, _results1;
562           _results1 = [];
563           for (_j = 0, _len1 = draggables.length; _j < _len1; _j++) {
564             m = draggables[_j];
565             $pr = $(".predicate [data-predicate=" + m + "]", question);
566             $ph = $pr.find(".placeholder:visible");
567             _results1.push(this.draggable_move($(qp), $ph.eq(0), this.multiple));
568           }
569           return _results1;
570         }).call(this));
571       }
572       return _results;
573     };
574
575     return Przyporzadkuj;
576
577   })(Exercise);
578
579   PrawdaFalsz = (function(_super) {
580
581     __extends(PrawdaFalsz, _super);
582
583     function PrawdaFalsz(element) {
584       var qp, _i, _len, _ref,
585         _this = this;
586       PrawdaFalsz.__super__.constructor.call(this, element);
587       _ref = $(".question-piece", this.element);
588       for (_i = 0, _len = _ref.length; _i < _len; _i++) {
589         qp = _ref[_i];
590         $(".true", qp).click(function(ev) {
591           ev.preventDefault();
592           _this.retry();
593           $(ev.target).closest(".question-piece").data("value", "true");
594           return $(ev.target).addClass('chosen').siblings('a').removeClass('chosen');
595         });
596         $(".false", qp).click(function(ev) {
597           ev.preventDefault();
598           _this.retry();
599           $(ev.target).closest(".question-piece").data("value", "false");
600           return $(ev.target).addClass('chosen').siblings('a').removeClass('chosen');
601         });
602       }
603     }
604
605     PrawdaFalsz.prototype.check_question = function() {
606       var all, good, qp, _i, _len, _ref;
607       all = 0;
608       good = 0;
609       _ref = $(".question-piece", this.element);
610       for (_i = 0, _len = _ref.length; _i < _len; _i++) {
611         qp = _ref[_i];
612         if ($(qp).data("solution").toString() === $(qp).data("value")) {
613           good += 1;
614           this.piece_correct(qp);
615         } else {
616           this.piece_incorrect(qp);
617         }
618         all += 1;
619       }
620       return [good, all];
621     };
622
623     PrawdaFalsz.prototype.show_solutions = function() {
624       var qp, _i, _len, _ref, _results;
625       this.reset();
626       _ref = $(".question-piece", this.element);
627       _results = [];
628       for (_i = 0, _len = _ref.length; _i < _len; _i++) {
629         qp = _ref[_i];
630         if ($(qp).data('solution') === true) {
631           _results.push($(".true", qp).click());
632         } else {
633           _results.push($(".false", qp).click());
634         }
635       }
636       return _results;
637     };
638
639     return PrawdaFalsz;
640
641   })(Exercise);
642
643   exercise = function(ele) {
644     var cls, es;
645     es = {
646       wybor: Wybor,
647       uporzadkuj: Uporzadkuj,
648       luki: Luki,
649       zastap: Zastap,
650       przyporzadkuj: Przyporzadkuj,
651       prawdafalsz: PrawdaFalsz
652     };
653     cls = es[$(ele).attr('data-type')];
654     return new cls(ele);
655   };
656
657   window.edumed = {
658     'EduModule': EduModule
659   };
660
661   $(document).ready(function() {
662     new EduModule($("#book-text"));
663     return $(".exercise").each(function(i, el) {
664       return exercise(this);
665     });
666   });
667
668 }).call(this);