teh legendary `Publish' button, oh yeah!
[redakcja.git] / redakcja / static / js / wiki / wikiapi.js
1 (function($) {
2         $.wikiapi = {};
3         var noop = function() {
4         };
5         var noops = {
6                 success: noop,
7                 failure: noop
8         };
9         /*
10          * Return absolute reverse path of given named view. (at least he have it
11          * hard-coded in one place)
12          *
13          * TODO: think of a way, not to hard-code it here ;)
14          *
15          */
16         function reverse() {
17                 var vname = arguments[0];
18                 var base_path = "/documents";
19
20                 if (vname == "ajax_document_text") {
21                         var path = "/text/" + arguments[1] + '/';
22
23                 if (arguments[2] !== undefined)
24                                 path += arguments[2] + '/';
25
26                         return base_path + path;
27                 }
28
29         if (vname == "ajax_document_revert") {
30             return base_path + "/revert/" + arguments[1] + '/';
31         }
32
33
34                 if (vname == "ajax_document_history") {
35
36                         return base_path + "/history/" + arguments[1] + '/';
37                 }
38
39                 if (vname == "ajax_document_gallery") {
40
41                         return base_path + "/gallery/" + arguments[1] + '/';
42                 }
43
44                 if (vname == "ajax_document_diff")
45                         return base_path + "/diff/" + arguments[1] + '/';
46
47         if (vname == "ajax_document_rev")
48             return base_path + "/rev/" + arguments[1] + '/';
49
50                 if (vname == "ajax_document_addtag")
51                         return base_path + "/tag/" + arguments[1] + '/';
52
53                 if (vname == "ajax_document_pubmark")
54                         return base_path + "/pubmark/" + arguments[1] + '/';
55
56                 if (vname == "ajax_publish")
57                         return base_path + "/publish/" + arguments[1] + '/';
58
59                 console.log("Couldn't reverse match:", vname);
60                 return "/404.html";
61         };
62
63         /*
64          * Document Abstraction
65          */
66         function WikiDocument(element_id) {
67                 var meta = $('#' + element_id);
68                 this.id = meta.attr('data-book') + '/' + meta.attr('data-chunk');
69
70                 this.revision = $("*[data-key='revision']", meta).text();
71                 this.readonly = !!$("*[data-key='readonly']", meta).text();
72
73                 this.galleryLink = $("*[data-key='gallery']", meta).text();
74                 this.galleryImages = [];
75                 this.text = null;
76                 this.has_local_changes = false;
77                 this._lock = -1;
78                 this._context_lock = -1;
79                 this._lock_count = 0;
80         };
81
82         WikiDocument.prototype.triggerDocumentChanged = function() {
83                 $(document).trigger('wlapi_document_changed', this);
84         };
85         /*
86          * Fetch text of this document.
87          */
88         WikiDocument.prototype.fetch = function(params) {
89                 params = $.extend({}, noops, params);
90                 var self = this;
91                 $.ajax({
92                         method: "GET",
93                         url: reverse("ajax_document_text", self.id),
94                         data: {"revision": self.revision},
95                         dataType: 'json',
96                         success: function(data) {
97                                 var changed = false;
98
99                                 if (self.text === null || self.revision !== data.revision) {
100                                         self.text = data.text;
101                                         self.revision = data.revision;
102                                         self.gallery = data.gallery;
103                                         changed = true;
104                                         self.triggerDocumentChanged();
105                                 };
106
107                                 self.has_local_changes = false;
108                                 params['success'](self, changed);
109                         },
110                         error: function() {
111                                 params['failure'](self, "Nie udało się wczytać treści dokumentu.");
112                         }
113                 });
114         };
115         /*
116          * Fetch history of this document.
117          *
118          * from - First revision to fetch (default = 0) upto - Last revision to
119          * fetch (default = tip)
120          *
121          */
122         WikiDocument.prototype.fetchHistory = function(params) {
123                 /* this doesn't modify anything, so no locks */
124                 params = $.extend({}, noops, params);
125                 var self = this;
126                 $.ajax({
127                         method: "GET",
128                         url: reverse("ajax_document_history", self.id),
129                         dataType: 'json',
130                         data: {
131                                 "from": params['from'],
132                                 "upto": params['upto']
133                         },
134                         success: function(data) {
135                                 params['success'](self, data);
136                         },
137                         error: function() {
138                                 params['failure'](self, "Nie udało się wczytać historii dokumentu.");
139                         }
140                 });
141         };
142         WikiDocument.prototype.fetchDiff = function(params) {
143                 /* this doesn't modify anything, so no locks */
144                 var self = this;
145                 params = $.extend({
146                         'from': self.revision,
147                         'to': self.revision
148                 }, noops, params);
149                 $.ajax({
150                         method: "GET",
151                         url: reverse("ajax_document_diff", self.id),
152                         dataType: 'html',
153                         data: {
154                                 "from": params['from'],
155                                 "to": params['to']
156                         },
157                         success: function(data) {
158                                 params['success'](self, data);
159                         },
160                         error: function() {
161                                 params['failure'](self, "Nie udało się wczytać porównania wersji.");
162                         }
163                 });
164         };
165
166     WikiDocument.prototype.checkRevision = function(params) {
167         /* this doesn't modify anything, so no locks */
168         var self = this;
169         $.ajax({
170             method: "GET",
171             url: reverse("ajax_document_rev", self.id),
172             dataType: 'text',
173             success: function(data) {
174                 if (data == '') {
175                     if (params.error)
176                         params.error();
177                 }
178                 else if (data != self.revision)
179                     params.outdated();
180             }
181         });
182     };
183
184         /*
185          * Fetch gallery
186          */
187         WikiDocument.prototype.refreshGallery = function(params) {
188                 params = $.extend({}, noops, params);
189                 var self = this;
190                 $.ajax({
191                         method: "GET",
192                         url: reverse("ajax_document_gallery", self.galleryLink),
193                         dataType: 'json',
194                         // data: {},
195                         success: function(data) {
196                                 self.galleryImages = data;
197                                 params['success'](self, data);
198                         },
199                         error: function() {
200                                 self.galleryImages = [];
201                                 params['failure'](self, "<p>Nie udało się wczytać galerii pod nazwą: '" + self.galleryLink + "'.</p>");
202                         }
203                 });
204         };
205
206         /*
207          * Set document's text
208          */
209         WikiDocument.prototype.setText = function(text) {
210                 this.text = text;
211                 this.has_local_changes = true;
212         };
213
214         /*
215          * Set document's gallery link
216          */
217         WikiDocument.prototype.setGalleryLink = function(gallery) {
218                 this.galleryLink = gallery;
219                 this.has_local_changes = true;
220         };
221
222         /*
223          * Save text back to the server
224          */
225         WikiDocument.prototype.save = function(params) {
226                 params = $.extend({}, noops, params);
227                 var self = this;
228
229                 if (!self.has_local_changes) {
230                         console.log("Abort: no changes.");
231                         return params['success'](self, false, "Nie ma zmian do zapisania.");
232                 };
233
234                 // Serialize form to dictionary
235                 var data = {};
236                 $.each(params['form'].serializeArray(), function() {
237                         data[this.name] = this.value;
238                 });
239
240                 data['textsave-text'] = self.text;
241
242                 $.ajax({
243                         url: reverse("ajax_document_text", self.id),
244                         type: "POST",
245                         dataType: "json",
246                         data: data,
247                         success: function(data) {
248                                 var changed = false;
249
250                 $('#header').removeClass('saving');
251
252                                 if (data.text) {
253                                         self.text = data.text;
254                                         self.revision = data.revision;
255                                         self.gallery = data.gallery;
256                                         changed = true;
257                                         self.triggerDocumentChanged();
258                                 };
259
260                                 params['success'](self, changed, ((changed && "Udało się zapisać :)") || "Twoja wersja i serwera jest identyczna"));
261                         },
262                         error: function(xhr) {
263                 if ($('#header').hasClass('saving')) {
264                     $('#header').removeClass('saving');
265                     $.blockUI({
266                         message: "<p>Nie udało się zapisać zmian. <br/><button onclick='$.unblockUI()'>OK</button></p>"
267                     })
268                 }
269                 else {
270                     try {
271                         params['failure'](self, $.parseJSON(xhr.responseText));
272                     }
273                     catch (e) {
274                         params['failure'](self, {
275                             "__message": "<p>Nie udało się zapisać - błąd serwera.</p>"
276                         });
277                     };
278                 }
279
280                         }
281                 });
282
283         $('#save-hide').click(function(){
284             $('#header').addClass('saving');
285             $.unblockUI();
286             $.wiki.blocking.unblock();
287         });
288         }; /* end of save() */
289
290     WikiDocument.prototype.revertToVersion = function(params) {
291         var self = this;
292         params = $.extend({}, noops, params);
293
294         if (params.revision >= this.revision) {
295             params.failure(self, 'Proszę wybrać rewizję starszą niż aktualna.');
296             return;
297         }
298
299         // Serialize form to dictionary
300         var data = {};
301         $.each(params['form'].serializeArray(), function() {
302             data[this.name] = this.value;
303         });
304
305         $.ajax({
306             url: reverse("ajax_document_revert", self.id),
307             type: "POST",
308             dataType: "json",
309             data: data,
310             success: function(data) {
311                 if (data.text) {
312                     self.text = data.text;
313                     self.revision = data.revision;
314                     self.gallery = data.gallery;
315                     self.triggerDocumentChanged();
316
317                     params.success(self, "Udało się przywrócić wersję :)");
318                 }
319                 else {
320                     params.failure(self, "Przywracana wersja identyczna z aktualną. Anulowano przywracanie.");
321                 }
322             },
323             error: function(xhr) {
324                 params.failure(self, "Nie udało się przywrócić wersji - błąd serwera.");
325             }
326         });
327     };
328
329         WikiDocument.prototype.publish = function(params) {
330                 params = $.extend({}, noops, params);
331                 var self = this;
332                 $.ajax({
333                         url: reverse("ajax_publish", self.id),
334                         type: "POST",
335                         dataType: "json",
336                         success: function(data) {
337                                 params.success(self, data);
338                         },
339                         error: function(xhr) {
340                                 if (xhr.status == 403 || xhr.status == 401) {
341                                         params.failure(self, "Nie masz uprawnień lub nie jesteś zalogowany.");
342                                 }
343                                 else {
344                                         try {
345                                                 params.failure(self, xhr.responseText);
346                                         }
347                                         catch (e) {
348                                                 params.failure(self, "Nie udało się - błąd serwera.");
349                                         };
350                                 };
351
352                         }
353                 });
354         };
355         WikiDocument.prototype.setTag = function(params) {
356                 params = $.extend({}, noops, params);
357                 var self = this;
358                 var data = {
359                         "addtag-id": self.id,
360                 };
361
362                 /* unpack form */
363                 $.each(params.form.serializeArray(), function() {
364                         data[this.name] = this.value;
365                 });
366
367                 $.ajax({
368                         url: reverse("ajax_document_addtag", self.id),
369                         type: "POST",
370                         dataType: "json",
371                         data: data,
372                         success: function(data) {
373                                 params.success(self, data.message);
374                         },
375                         error: function(xhr) {
376                                 if (xhr.status == 403 || xhr.status == 401) {
377                                         params.failure(self, {
378                                                 "__all__": ["Nie masz uprawnień lub nie jesteś zalogowany."]
379                                         });
380                                 }
381                                 else {
382                                         try {
383                                                 params.failure(self, $.parseJSON(xhr.responseText));
384                                         }
385                                         catch (e) {
386                                                 params.failure(self, {
387                                                         "__all__": ["Nie udało się - błąd serwera."]
388                                                 });
389                                         };
390                                 };
391                         }
392                 });
393         };
394
395         WikiDocument.prototype.pubmark = function(params) {
396                 params = $.extend({}, noops, params);
397                 var self = this;
398                 var data = {
399                         "pubmark-id": self.id,
400                 };
401
402                 /* unpack form */
403                 $.each(params.form.serializeArray(), function() {
404                         data[this.name] = this.value;
405                 });
406
407                 $.ajax({
408                         url: reverse("ajax_document_pubmark", self.id),
409                         type: "POST",
410                         dataType: "json",
411                         data: data,
412                         success: function(data) {
413                                 params.success(self, data.message);
414                         },
415                         error: function(xhr) {
416                                 if (xhr.status == 403 || xhr.status == 401) {
417                                         params.failure(self, {
418                                                 "__all__": ["Nie masz uprawnień lub nie jesteś zalogowany."]
419                                         });
420                                 }
421                                 else {
422                                         try {
423                                                 params.failure(self, $.parseJSON(xhr.responseText));
424                                         }
425                                         catch (e) {
426                                                 params.failure(self, {
427                                                         "__all__": ["Nie udało się - błąd serwera."]
428                                                 });
429                                         };
430                                 };
431                         }
432                 });
433         };
434
435         $.wikiapi.WikiDocument = WikiDocument;
436 })(jQuery);