fix out-of-date check, don't panic on failed ajax
[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 = "/" + arguments[1] + "/text";
22
23                 if (arguments[2] !== undefined)
24                                 path += "/" + arguments[2];
25
26                         return base_path + path;
27                 }
28
29                 if (vname == "ajax_document_history") {
30
31                         return base_path + "/" + arguments[1] + "/history";
32                 }
33
34                 if (vname == "ajax_document_gallery") {
35
36                         return base_path + "/" + arguments[1] + "/gallery";
37                 }
38
39                 if (vname == "ajax_document_diff")
40                         return base_path + "/" + arguments[1] + "/diff";
41
42         if (vname == "ajax_document_rev")
43             return base_path + "/" + arguments[1] + "/rev";
44
45                 if (vname == "ajax_document_addtag")
46                         return base_path + "/" + arguments[1] + "/tags";
47
48                 if (vname == "ajax_publish")
49                         return base_path + "/" + arguments[1] + "/publish";
50
51                 console.log("Couldn't reverse match:", vname);
52                 return "/404.html";
53         };
54
55         /*
56          * Document Abstraction
57          */
58         function WikiDocument(element_id) {
59                 var meta = $('#' + element_id);
60                 this.id = meta.attr('data-document-name');
61
62                 this.revision = $("*[data-key='revision']", meta).text();
63                 this.readonly = !!$("*[data-key='readonly']", meta).text();
64
65                 this.galleryLink = $("*[data-key='gallery']", meta).text();
66                 this.galleryImages = [];
67                 this.text = null;
68                 this.has_local_changes = false;
69                 this._lock = -1;
70                 this._context_lock = -1;
71                 this._lock_count = 0;
72         };
73
74         WikiDocument.prototype.triggerDocumentChanged = function() {
75                 $(document).trigger('wlapi_document_changed', this);
76         };
77         /*
78          * Fetch text of this document.
79          */
80         WikiDocument.prototype.fetch = function(params) {
81                 params = $.extend({}, noops, params);
82                 var self = this;
83                 $.ajax({
84                         method: "GET",
85                         url: reverse("ajax_document_text", self.id),
86                         data: {"revision": self.revision},
87                         dataType: 'json',
88                         success: function(data) {
89                                 var changed = false;
90
91                                 if (self.text === null || self.revision !== data.revision) {
92                                         self.text = data.text;
93                                         self.revision = data.revision;
94                                         self.gallery = data.gallery;
95                                         changed = true;
96                                         self.triggerDocumentChanged();
97                                 };
98
99                                 self.has_local_changes = false;
100                                 params['success'](self, changed);
101                         },
102                         error: function() {
103                                 params['failure'](self, "Nie udało się wczytać treści dokumentu.");
104                         }
105                 });
106         };
107         /*
108          * Fetch history of this document.
109          *
110          * from - First revision to fetch (default = 0) upto - Last revision to
111          * fetch (default = tip)
112          *
113          */
114         WikiDocument.prototype.fetchHistory = function(params) {
115                 /* this doesn't modify anything, so no locks */
116                 params = $.extend({}, noops, params);
117                 var self = this;
118                 $.ajax({
119                         method: "GET",
120                         url: reverse("ajax_document_history", self.id),
121                         dataType: 'json',
122                         data: {
123                                 "from": params['from'],
124                                 "upto": params['upto']
125                         },
126                         success: function(data) {
127                                 params['success'](self, data);
128                         },
129                         error: function() {
130                                 params['failure'](self, "Nie udało się wczytać historii dokumentu.");
131                         }
132                 });
133         };
134         WikiDocument.prototype.fetchDiff = function(params) {
135                 /* this doesn't modify anything, so no locks */
136                 var self = this;
137                 params = $.extend({
138                         'from': self.revision,
139                         'to': self.revision
140                 }, noops, params);
141                 $.ajax({
142                         method: "GET",
143                         url: reverse("ajax_document_diff", self.id),
144                         dataType: 'html',
145                         data: {
146                                 "from": params['from'],
147                                 "to": params['to']
148                         },
149                         success: function(data) {
150                                 params['success'](self, data);
151                         },
152                         error: function() {
153                                 params['failure'](self, "Nie udało się wczytać porównania wersji.");
154                         }
155                 });
156         };
157
158     WikiDocument.prototype.checkRevision = function(params) {
159         /* this doesn't modify anything, so no locks */
160         var self = this;
161         $.ajax({
162             method: "GET",
163             url: reverse("ajax_document_rev", self.id),
164             dataType: 'text',
165             success: function(data) {
166                 if (data == '' && params.error)
167                     params.error();
168                 else if (data != self.revision)
169                     params.outdated();
170             }
171         });
172     };
173
174         /*
175          * Fetch gallery
176          */
177         WikiDocument.prototype.refreshGallery = function(params) {
178                 params = $.extend({}, noops, params);
179                 var self = this;
180                 $.ajax({
181                         method: "GET",
182                         url: reverse("ajax_document_gallery", self.galleryLink),
183                         dataType: 'json',
184                         // data: {},
185                         success: function(data) {
186                                 self.galleryImages = data;
187                                 params['success'](self, data);
188                         },
189                         error: function() {
190                                 self.galleryImages = [];
191                                 params['failure'](self, "<p>Nie udało się wczytać galerii pod nazwą: '" + self.galleryLink + "'.</p>");
192                         }
193                 });
194         };
195
196         /*
197          * Set document's text
198          */
199         WikiDocument.prototype.setText = function(text) {
200                 this.text = text;
201                 this.has_local_changes = true;
202         };
203
204         /*
205          * Set document's gallery link
206          */
207         WikiDocument.prototype.setGalleryLink = function(gallery) {
208                 this.galleryLink = gallery;
209                 this.has_local_changes = true;
210         };
211
212         /*
213          * Save text back to the server
214          */
215         WikiDocument.prototype.save = function(params) {
216                 params = $.extend({}, noops, params);
217                 var self = this;
218
219                 if (!self.has_local_changes) {
220                         console.log("Abort: no changes.");
221                         return params['success'](self, false, "Nie ma zmian do zapisania.");
222                 };
223
224                 // Serialize form to dictionary
225                 var data = {};
226                 $.each(params['form'].serializeArray(), function() {
227                         data[this.name] = this.value;
228                 });
229
230                 var metaComment = '<!--';
231                 metaComment += '\n\tgallery:' + self.galleryLink;
232                 metaComment += '\n-->\n'
233
234                 data['textsave-text'] = metaComment + self.text;
235
236                 $.ajax({
237                         url: reverse("ajax_document_text", self.id),
238                         type: "POST",
239                         dataType: "json",
240                         data: data,
241                         success: function(data) {
242                                 var changed = false;
243
244                 $('#header').removeClass('saving');
245
246                                 if (data.text) {
247                                         self.text = data.text;
248                                         self.revision = data.revision;
249                                         self.gallery = data.gallery;
250                                         changed = true;
251                                         self.triggerDocumentChanged();
252                                 };
253
254                                 params['success'](self, changed, ((changed && "Udało się zapisać :)") || "Twoja wersja i serwera jest identyczna"));
255                         },
256                         error: function(xhr) {
257                 if ($('#header').hasClass('saving')) {
258                     $('#header').removeClass('saving');
259                     $.blockUI({
260                         message: "<p>Nie udało się zapisać zmian. <br/><button onclick='$.unblockUI()'>OK</button></p>"
261                     })
262                 }
263                 else {
264                     try {
265                         params['failure'](self, $.parseJSON(xhr.responseText));
266                     }
267                     catch (e) {
268                         params['failure'](self, {
269                             "__message": "<p>Nie udało się zapisać - błąd serwera.</p>"
270                         });
271                     };
272                 }
273
274                         }
275                 });
276
277         $('#save-hide').click(function(){
278             $('#header').addClass('saving');
279             $.unblockUI();
280             $.wiki.blocking.unblock();
281         });
282         }; /* end of save() */
283
284         WikiDocument.prototype.publish = function(params) {
285                 params = $.extend({}, noops, params);
286                 var self = this;
287                 $.ajax({
288                         url: reverse("ajax_publish", self.id),
289                         type: "POST",
290                         dataType: "json",
291                         success: function(data) {
292                                 params.success(self, data);
293                         },
294                         error: function(xhr) {
295                                 if (xhr.status == 403 || xhr.status == 401) {
296                                         params.failure(self, "Nie masz uprawnień lub nie jesteś zalogowany.");
297                                 }
298                                 else {
299                                         try {
300                                                 params.failure(self, xhr.responseText);
301                                         }
302                                         catch (e) {
303                                                 params.failure(self, "Nie udało się - błąd serwera.");
304                                         };
305                                 };
306
307                         }
308                 });
309         };
310         WikiDocument.prototype.setTag = function(params) {
311                 params = $.extend({}, noops, params);
312                 var self = this;
313                 var data = {
314                         "addtag-id": self.id,
315                 };
316
317                 /* unpack form */
318                 $.each(params.form.serializeArray(), function() {
319                         data[this.name] = this.value;
320                 });
321
322                 $.ajax({
323                         url: reverse("ajax_document_addtag", self.id),
324                         type: "POST",
325                         dataType: "json",
326                         data: data,
327                         success: function(data) {
328                                 params.success(self, data.message);
329                         },
330                         error: function(xhr) {
331                                 if (xhr.status == 403 || xhr.status == 401) {
332                                         params.failure(self, {
333                                                 "__all__": ["Nie masz uprawnień lub nie jesteś zalogowany."]
334                                         });
335                                 }
336                                 else {
337                                         try {
338                                                 params.failure(self, $.parseJSON(xhr.responseText));
339                                         }
340                                         catch (e) {
341                                                 params.failure(self, {
342                                                         "__all__": ["Nie udało się - błąd serwera."]
343                                                 });
344                                         };
345                                 };
346                         }
347                 });
348         };
349
350         $.wikiapi.WikiDocument = WikiDocument;
351 })(jQuery);