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