* Better "motto" display.
[redakcja.git] / platforma / static / js / wiki / base.js
1 (function($)
2 {
3         var noop = function() { };
4
5         $.wiki = {
6                 perspectives: {},
7                 cls: {}
8         };
9
10         $.wiki.activePerspective = function() {
11                 return this.perspectives[$("#tabs li.active").attr('id')];
12         };
13
14         $.wiki.exitContext = function() {
15                 var ap = this.activePerspective();
16                 if(ap) ap.onExit();
17                 return ap;
18         };
19
20         $.wiki.enterContext = function(ap) {
21                 if(ap) ap.onEnter();
22         };
23
24         $.wiki.isDirty = function() {
25                 var ap = this.activePerspective();
26                 return (!!CurrentDocument && CurrentDocument.has_local_changes) || ap.dirty();
27         };
28
29         $.wiki.newTab = function(doc, title, klass) {
30                 var base_id = 'id' + Math.floor(Math.random()* 5000000000);
31                 var id = (''+klass)+'_' + base_id;
32                 var $tab = $('<li id="'+id+'" data-ui-related="'+base_id+'" data-ui-jsclass="'+klass+'" >'
33                                 + title + '<img src="/static/icons/close.png" class="tabclose"></li>');
34                 var $view = $('<div class="editor '+klass+'" id="'+base_id+'"> </div>');
35
36                 this.perspectives[id] = new $.wiki[klass]({
37                         doc: doc,
38                         id: id,
39                         base_id: base_id,
40                 });
41
42                 $('#tabs').append($tab);
43                 $view.hide().appendTo('#editor');
44                 return {
45                         tab: $tab[0],
46                         view: $view[0],
47                 };
48         };
49
50         $.wiki.initTab = function(options) {
51                 var klass = $(options.tab).attr('data-ui-jsclass');
52
53                 return new $.wiki[klass]({
54                         doc: options.doc,
55                         id: $(options.tab).attr('id'),
56                         callback: function() {
57                                 $.wiki.perspectives[this.perspective_id] = this;
58                                 if(options.callback)
59                                         options.callback.call(this);
60                         }
61                 });
62         };
63
64         $.wiki.perspectiveForTab = function(tab) { // element or id
65                 return this.perspectives[ $(tab).attr('id')];
66         }
67
68         $.wiki.switchToTab = function(tab){
69                 var self = this;
70                 var $tab = $(tab);
71
72                 if($tab.length != 1)
73                         $tab = $(DEFAULT_PERSPECTIVE);
74
75                 var $old = $('#tabs li').filter('.active');
76
77                 $old.each(function(){
78                         $(this).removeClass('active');
79                         $('#' + $(this).attr('data-ui-related')).hide();
80                         self.perspectives[$(this).attr('id')].onExit();
81                 });
82
83                 /* show new */
84                 $tab.addClass('active');
85                 $('#' + $tab.attr('data-ui-related')).show();
86
87                 console.log($tab);
88                 console.log($.wiki.perspectives);
89
90                 $.wiki.perspectives[$tab.attr('id')].onEnter();
91         };
92
93         /*
94          * Basic perspective.
95          */
96         $.wiki.Perspective = function(options) {
97                 if(!options) return;
98
99                 this.doc = options.doc;
100                 if (options.id) {
101                         this.perspective_id = options.id;
102                 }
103                 else {
104                         this.perspective_id = '';
105                 }
106
107                 if(options.callback)
108                         options.callback.call(this);
109         };
110
111         $.wiki.Perspective.prototype.toString = function() {
112                 return this.perspective_id;
113         };
114
115         $.wiki.Perspective.prototype.dirty = function() {
116                 return true;
117         };
118
119         $.wiki.Perspective.prototype.onEnter = function () {
120                 // called when perspective in initialized
121                 if (this.perspective_id) {
122                         document.location.hash = '#' + this.perspective_id;
123                 }
124
125                 console.log(document.location.hash);
126         };
127
128         $.wiki.Perspective.prototype.onExit = function () {
129                 // called when user switches to another perspective
130                 document.location.hash = '';
131         };
132
133         $.wiki.Perspective.prototype.destroy = function() {
134                 // pass
135         };
136
137         $.wiki.Perspective.prototype.freezeState = function () {
138                 // free UI state (don't store data here)
139         };
140
141         $.wiki.Perspective.prototype.unfreezeState = function (frozenState) {
142                 // restore UI state
143         };
144
145         /*
146          * Stub rendering (used in generating history)
147          */
148         $.wiki.renderStub = function(params)
149         {
150                 params = $.extend({ 'filters': {} }, params);
151                 var $elem = params.stub.clone();
152                 $elem.removeClass('row-stub');
153                 params.container.append($elem);
154
155                 $('*[data-stub-value]', $elem).each(function() {
156                         var $this = $(this);
157                         var field = $this.attr('data-stub-value');
158
159                         var value = params.data[field];
160
161                         if(params.filters[field])
162                                 value = params.filters[field](value);
163
164                         if(value === null || value === undefined) return;
165
166                         if(!$this.attr('data-stub-target')) {
167                                 $this.text(value);
168                         }
169                         else {
170                                 $this.attr($this.attr('data-stub-target'), value);
171                                 $this.removeAttr('data-stub-target');
172                                 $this.removeAttr('data-stub-value');
173                         }
174                 });
175
176                 $elem.show();
177                 return $elem;
178         };
179
180         /*
181          * Dialogs
182          */
183         function GenericDialog(element) {
184                 if(!element) return;
185
186                 var self = this;
187
188                 self.$elem = $(element);
189
190                 if(!self.$elem.attr('data-ui-initialized')) {
191                         console.log("Initializing dialog", this);
192                         self.initialize();
193                         self.$elem.attr('data-ui-initialized', true);
194                 }
195
196                 self.show();
197         };
198
199         GenericDialog.prototype = {
200
201                 /*
202                 * Steps to follow when the dialog in first loaded on page.
203                 */
204                 initialize: function(){
205                         var self = this;
206
207                         /* bind buttons */
208                         $('button[data-ui-action]', self.$elem).click(function(event) {
209                                 event.preventDefault();
210
211                                 var action = $(this).attr('data-ui-action');
212                                 console.log("Button pressed, action: ", action);
213
214                                 try {
215                                         self[action + "Action"].call(self);
216                                 } catch(e) {
217                                         console.log("Action failed:", e);
218                                         // always hide on cancel
219                                         if(action == 'cancel')
220                                                 self.hide();
221                                 }
222                         });
223                 },
224
225                 /*
226                  * Prepare dialog for user. Clear any unnessary data.
227                 */
228                 show: function() {
229                         $.blockUI({
230                                 message: this.$elem,
231                                 css: {
232                                         'top': '25%',
233                                         'left': '25%',
234                                         'width': '50%'
235                                 }
236                         });
237                 },
238
239                 hide: function(){
240                         $.unblockUI();
241                 },
242
243                 cancelAction: function() {
244                         this.hide();
245                 },
246
247                 doneAction: function() {
248                         this.hide();
249                 },
250
251                 clearForm: function() {
252                         $("*[data-ui-error-for]", this.$elem).text('');
253                 },
254
255                 reportErrors: function(errors) {
256                         var global = $("*[data-ui-error-for='__all__']", this.$elem);
257                         var unassigned = [];
258
259                         for (var field_name in errors)
260                         {
261                                 var span = $("*[data-ui-error-for='"+field_name+"']", this.$elem);
262
263                                 if(!span.length) {
264                                         unassigned.push(field_name);
265                                         continue;
266                                 }
267
268                                 span.text(errors[field_name].join(' '));
269                         }
270
271                         if(unassigned.length > 0)
272                                 global.text( global.text() + 'W formularzu wystąpiły błędy');
273                 }
274         };
275
276         $.wiki.cls.GenericDialog = GenericDialog;
277
278         $.wiki.showDialog = function(selector, options) {
279                 var elem = $(selector);
280
281                 if(elem.length != 1) {
282                         console.log("Failed to show dialog:", selector, elem);
283                         return false;
284                 }
285
286                 try {
287                     var klass = elem.attr('data-ui-jsclass');
288                         return new $.wiki.cls[klass](elem, options);
289                 } catch(e) {
290                         console.log("Failed to show dialog", selector, klass, e);
291                         return false;
292                 }
293         };
294
295 })(jQuery);