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