1718ee0699aea42df5bf913bb6fe5359ca26e6fe
[oweals/karmaworld.git] / karmaworld / assets / js / note-detail.js
1
2 function rescalePdf(viewer) {
3   var scaleBase = 750;
4   var outlineWidth = 250;
5   var frameWidth = parseInt($('#note_container')[0].clientWidth);
6   var pdfWidth = frameWidth;
7
8   if ($(viewer.sidebar).hasClass('opened')){
9     pdfWidth = pdfWidth - 250;
10   }
11
12   var newPdfScale = pdfWidth / scaleBase;
13   viewer.rescale(newPdfScale);
14 }
15
16 function setupPdfViewer(noteframe, pdfViewer) {
17
18   $('#plus-btn').click(function (){
19     pdfViewer.rescale(1.20, true, [0,0]);
20   });
21
22   $('#minus-btn').click(function (){
23     pdfViewer.rescale(0.80, true, [0,0]);
24   });
25
26   // detect if the PDF viewer wants to show an outline
27   // at all
28   if ($(pdfViewer.sidebar).hasClass('opened')) {
29     var body = $(document.body);
30     // if the screen is less than 64em wide, hide the outline
31     if (parseInt($(body.width()).toEm({scope: body})) < 64) {
32       $(pdfViewer.sidebar).removeClass('opened');
33     }
34   }
35
36   $('#outline-btn').click(function() {
37     $(pdfViewer.sidebar).toggleClass('opened');
38     // rescale the PDF to fit the available space
39     rescalePdf(pdfViewer);
40   });
41
42   $('#scroll-to').change(function() {
43     page = parseInt($(this).val());
44     pdfViewer.scroll_to(page, [0,0]);
45   });
46
47   // rescale the PDF to fit the available space
48   rescalePdf(pdfViewer);
49 }
50
51 function writeNoteFrame(contents) {
52   var dstFrame = document.getElementById('noteframe');
53   var dstDoc = dstFrame.contentDocument || dstFrame.contentWindow.document;
54   dstDoc.write(contents);
55   dstDoc.close();
56 }
57
58 function setupAnnotator(noteElement, readOnly) {
59   noteElement.annotator({readOnly: readOnly});
60   noteElement.annotator('addPlugin', 'Store', {
61     prefix: '/ajax/annotations',
62     loadFromSearch: {
63       'uri': note_id
64     },
65     annotationData: {
66       'uri': note_id
67     }
68   });
69 }
70
71 function injectRemoteScript(url, noteframe, onload) {
72   var injectScript = noteframe.document.createElement("script");
73   injectScript.src = url;
74   injectScript.onload = onload;
75   noteframe.document.head.appendChild(injectScript);
76 }
77
78 function injectScript(scriptText, noteframe) {
79   var injectScript = noteframe.document.createElement("script");
80   injectScript.innerHTML = scriptText;
81   noteframe.document.body.appendChild(injectScript);
82 }
83
84 function injectRemoteCSS(url, noteframe) {
85   var injectCSS = noteframe.document.createElement("link");
86   injectCSS.href = url;
87   injectCSS.type = 'text/css';
88   injectCSS.rel = 'stylesheet';
89   noteframe.document.head.appendChild(injectCSS);
90 }
91
92 function tabHandler(event) {
93   // check for:
94   // key pressed was TAB
95   // key was pressed in last row
96   if (event.which == 9) {
97     var totalForms = parseInt($('#id_form-TOTAL_FORMS').attr('value'));
98     var formIndex = parseInt($(this).closest('div.keyword-form-row').data('index'));
99     if (formIndex === totalForms-1) {
100       addForm(event);
101       event.preventDefault();
102     }
103   }
104 }
105
106 function addForm(event) {
107   var prototypeForm = $('#keyword-form-prototype div.keyword-form-row').clone().appendTo('#keyword-form-rows');
108   var newForm = $('.keyword-form-row:last');
109   var totalForms = $('#id_form-TOTAL_FORMS').attr('value');
110   var newIdRoot = 'id_form-' + totalForms + '-';
111   var newNameRoot = 'form-' + totalForms + '-';
112
113   newForm.data('index', totalForms);
114
115   var keywordInput = newForm.find('.keyword');
116   keywordInput.attr('id', newIdRoot + 'keyword');
117   keywordInput.attr('name', newNameRoot + 'keyword');
118   keywordInput.focus();
119
120   var definitionInput = newForm.find('.definition');
121   definitionInput.attr('id', newIdRoot + 'definition');
122   definitionInput.attr('name', newNameRoot + 'definition');
123   definitionInput.keydown(tabHandler);
124
125   var objectIdInput = newForm.find('.object-id');
126   objectIdInput.attr('id', newIdRoot + 'id');
127   objectIdInput.attr('name', newNameRoot + 'id');
128
129   $('#id_form-TOTAL_FORMS').attr('value', parseInt(totalForms)+1);
130
131   keywordInput.focus();
132 }
133
134 function initNoteContentPage() {
135
136   $("#thank-button").click(function(event) {
137     event.preventDefault();
138
139     // increment number in page right away
140     var thankNumber = $("#thank-number");
141     thankNumber.text(parseInt(thankNumber.text()) + 1);
142
143     // disable thank button so it can't
144     // be pressed again
145     $(this).hide();
146     $('#thank-button-disabled').show();
147     $(this).unbind('click');
148
149     // tell server that somebody thanked
150     // this note
151     $.ajax({
152       url: note_thank_url,
153       dataType: "json",
154       type: 'POST'
155     });
156   });
157
158   $("#flag-button").click(function(event) {
159     event.preventDefault();
160
161     if (confirm('Do you wish to flag this note for deletion?')) {
162       // disable thank button so it can't
163       // be pressed again
164       $(this).hide();
165       $('#flag-button-disabled').show();
166       $(this).unbind('click');
167
168       // tell server that somebody flagged
169       // this note
170       $.ajax({
171         url: note_flag_url,
172         dataType: "json",
173         type: 'POST'
174       });
175     }
176   });
177
178   $('#save_note_tags').click(function(event) {
179     $.ajax({
180       url: edit_note_tags_url,
181       dataType: 'json',
182       data: $('#note_tags_input').val(),
183       type: 'POST',
184       success: function(data) {
185         $('#note_tags_form').slideUp();
186         $('.tags').empty();
187         $.each(data.fields.tags, function(index, tag) {
188           $('.tags').append($('<span>', { class: 'tag-span', text: tag }));
189         });
190         $('#note-tag-dialog').foundation('reveal', 'close');
191       }
192     });
193   });
194
195   $("#note-download-button").click(function(event) {
196     if (confirm('It costs 2 karma points to download a note. Are you sure?')) {
197       // disable handler so it won't be run again
198       $(this).unbind('click');
199
200       // tell server that somebody downloaded
201       // this note
202       $.ajax({
203         url: note_downloaded_url,
204         dataType: "json",
205         type: 'POST',
206         async: false
207       })
208     };
209   });
210
211   $('#delete-note-button').click(function (event) {
212     if (!confirm("Are you sure you want to delete this note?")) {
213       event.preventDefault();
214     }
215   });
216
217   // Embed the converted markdown if it is on the page, else default to the iframe
218   if ($('#note-markdown').length > 0) {
219     var note_markdown = $('#note-markdown');
220     note_markdown.html(marked(note_markdown.data('markdown')));
221     setupAnnotator(note_markdown, !user_authenticated);
222   } else {
223     $.ajax(note_contents_url, {
224       type: 'GET',
225       xhrFields: {
226         onprogress: function (progress) {
227           var percentage = Math.floor((progress.loaded / progress.total) * 100);
228           writeNoteFrame("<h3 style='text-align: center'>" + percentage + "%</h3>");
229         }
230       },
231       success: function(data, textStatus, jqXHR) {
232         writeNoteFrame(data);
233
234         // run setupAnnotator in frame context
235         var noteframe = document.getElementById('noteframe').contentWindow;
236
237         injectRemoteCSS(annotator_css_url, noteframe);
238         injectScript("csrf_token = '" + csrf_token + "';", noteframe);
239
240         injectRemoteScript("https://code.jquery.com/jquery-2.1.0.min.js", noteframe,
241           function() {
242             injectRemoteScript(setup_ajax_url, noteframe);
243             injectRemoteScript(annotator_js_url, noteframe,
244               function() {
245                 var js = "$(function() { \
246                   var document_selector = $('body'); \
247                   if ($('#page-container').length > 0) { \
248                     document_selector = $('#page-container'); \
249                   } \
250                   document_selector.annotator({readOnly: " + !user_authenticated + "}); \
251                   document_selector.annotator('addPlugin', 'Store', { \
252                     prefix: '/ajax/annotations', \
253                     loadFromSearch: { \
254                     'uri': " + note_id + " \
255                   }, \
256                   annotationData: { \
257                     'uri': " + note_id + " \
258                   } \
259                 }); })";
260                 injectScript(js, noteframe);
261
262                 if (pdfControls == true) {
263                   var pdfViewer = noteframe.pdf2htmlEX.defaultViewer;
264                   $(noteframe.document).ready(function() {
265                     setupPdfViewer(noteframe, pdfViewer);
266                   });
267                 }
268               });
269           });
270       },
271       error: function(data, textStatus, jqXHR) {
272         writeNoteFrame("<h3 style='text-align: center'>Sorry, your note could not be retrieved.</h3>");
273       }
274     });
275   }
276 }
277
278 function initNoteKeywordsPage() {
279   $('.definition').keydown(tabHandler);
280   $('#add-row-btn').click(addForm);
281
282   $('#keywords-data-table').dataTable({
283     // don't provide a option for the user to change the table page length
284     'bLengthChange': false,
285     'sDom': 't<"clear">'
286   });
287
288   $('#edit-keywords-button').click(function(event) {
289     $('#keywords-data-table').toggle();
290     $('#keyword-form').toggle();
291   });
292
293 }
294
295 function markQuestionCorrect(question) {
296   question.find('.quiz-question').addClass('correct');
297   question.find('.quiz-question').removeClass('incorrect');
298   question.find('.correct-label').show();
299   question.find('.incorrect-label').hide();
300 }
301
302 function markQuestionIncorrect(question) {
303   question.find('.quiz-question').addClass('incorrect');
304   question.find('.quiz-question').removeClass('correct');
305   question.find('.incorrect-label').show();
306   question.find('.correct-label').hide();
307 }
308
309 function initQuizPage() {
310   $('#check-answers-button').click(function() {
311     $('.quiz-question-wrapper').each(function() {
312       var choice = $(this).find('input:checked');
313       if (choice.length) {
314         console.log(choice);
315         if (choice.data('correct') == true) {
316           markQuestionCorrect($(this));
317         } else {
318           markQuestionIncorrect($(this));
319         }
320       }
321     });
322   });
323 }
324