fixes #875: detect work on outdated revision
[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 != self.revision)
167                     params.error();
168             }
169         });
170     };
171
172         /*
173          * Fetch gallery
174          */
175         WikiDocument.prototype.refreshGallery = function(params) {
176                 params = $.extend({}, noops, params);
177                 var self = this;
178                 $.ajax({
179                         method: "GET",
180                         url: reverse("ajax_document_gallery", self.galleryLink),
181                         dataType: 'json',
182                         // data: {},
183                         success: function(data) {
184                                 self.galleryImages = data;
185                                 params['success'](self, data);
186                         },
187                         error: function() {
188                                 self.galleryImages = [];
189                                 params['failure'](self, "<p>Nie udało się wczytać galerii pod nazwą: '" + self.galleryLink + "'.</p>");
190                         }
191                 });
192         };
193
194         /*
195          * Set document's text
196          */
197         WikiDocument.prototype.setText = function(text) {
198                 this.text = text;
199                 this.has_local_changes = true;
200         };
201
202         /*
203          * Set document's gallery link
204          */
205         WikiDocument.prototype.setGalleryLink = function(gallery) {
206                 this.galleryLink = gallery;
207                 this.has_local_changes = true;
208         };
209
210         /*
211          * Save text back to the server
212          */
213         WikiDocument.prototype.save = function(params) {
214                 params = $.extend({}, noops, params);
215                 var self = this;
216
217                 if (!self.has_local_changes) {
218                         console.log("Abort: no changes.");
219                         return params['success'](self, false, "Nie ma zmian do zapisania.");
220                 };
221
222                 // Serialize form to dictionary
223                 var data = {};
224                 $.each(params['form'].serializeArray(), function() {
225                         data[this.name] = this.value;
226                 });
227
228                 var metaComment = '<!--';
229                 metaComment += '\n\tgallery:' + self.galleryLink;
230                 metaComment += '\n-->\n'
231
232                 data['textsave-text'] = metaComment + self.text;
233
234                 $.ajax({
235                         url: reverse("ajax_document_text", self.id),
236                         type: "POST",
237                         dataType: "json",
238                         data: data,
239                         success: function(data) {
240                                 var changed = false;
241
242                 $('#header').removeClass('saving');
243
244                                 if (data.text) {
245                                         self.text = data.text;
246                                         self.revision = data.revision;
247                                         self.gallery = data.gallery;
248                                         changed = true;
249                                         self.triggerDocumentChanged();
250                                 };
251
252                                 params['success'](self, changed, ((changed && "Udało się zapisać :)") || "Twoja wersja i serwera jest identyczna"));
253                         },
254                         error: function(xhr) {
255                 if ($('#header').hasClass('saving')) {
256                     $('#header').removeClass('saving');
257                     $.blockUI({
258                         message: "<p>Nie udało się zapisać zmian. <br/><button onclick='$.unblockUI()'>OK</button></p>"
259                     })
260                 }
261                 else {
262                     try {
263                         params['failure'](self, $.parseJSON(xhr.responseText));
264                     }
265                     catch (e) {
266                         params['failure'](self, {
267                             "__message": "<p>Nie udało się zapisać - błąd serwera.</p>"
268                         });
269                     };
270                 }
271
272                         }
273                 });
274
275         $('#save-hide').click(function(){
276             $('#header').addClass('saving');
277             $.unblockUI();
278             $.wiki.blocking.unblock();
279         });
280         }; /* end of save() */
281
282         WikiDocument.prototype.publish = function(params) {
283                 params = $.extend({}, noops, params);
284                 var self = this;
285                 $.ajax({
286                         url: reverse("ajax_publish", self.id),
287                         type: "POST",
288                         dataType: "json",
289                         success: function(data) {
290                                 params.success(self, data);
291                         },
292                         error: function(xhr) {
293                                 if (xhr.status == 403 || xhr.status == 401) {
294                                         params.failure(self, "Nie masz uprawnień lub nie jesteś zalogowany.");
295                                 }
296                                 else {
297                                         try {
298                                                 params.failure(self, xhr.responseText);
299                                         }
300                                         catch (e) {
301                                                 params.failure(self, "Nie udało się - błąd serwera.");
302                                         };
303                                 };
304
305                         }
306                 });
307         };
308         WikiDocument.prototype.setTag = function(params) {
309                 params = $.extend({}, noops, params);
310                 var self = this;
311                 var data = {
312                         "addtag-id": self.id,
313                 };
314
315                 /* unpack form */
316                 $.each(params.form.serializeArray(), function() {
317                         data[this.name] = this.value;
318                 });
319
320                 $.ajax({
321                         url: reverse("ajax_document_addtag", self.id),
322                         type: "POST",
323                         dataType: "json",
324                         data: data,
325                         success: function(data) {
326                                 params.success(self, data.message);
327                         },
328                         error: function(xhr) {
329                                 if (xhr.status == 403 || xhr.status == 401) {
330                                         params.failure(self, {
331                                                 "__all__": ["Nie masz uprawnień lub nie jesteś zalogowany."]
332                                         });
333                                 }
334                                 else {
335                                         try {
336                                                 params.failure(self, $.parseJSON(xhr.responseText));
337                                         }
338                                         catch (e) {
339                                                 params.failure(self, {
340                                                         "__all__": ["Nie udało się - błąd serwera."]
341                                                 });
342                                         };
343                                 };
344                         }
345                 });
346         };
347
348         $.wikiapi.WikiDocument = WikiDocument;
349 })(jQuery);