429b0e663071661ea5ca2f2be8e501d62d618605
[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($container, $stub, data) 
149         {
150                 var $elem = $stub.clone();
151                 $elem.removeClass('row-stub');
152                 $container.append($elem);
153         
154                 $('*[data-stub-value]', $elem).each(function() {
155                         var $this = $(this);
156                         var field = $this.attr('data-stub-value');
157                         var value = data[field];
158                 
159                         if(value === null || value === undefined) return;
160                          
161                         if(!$this.attr('data-stub-target')) {
162                                 $this.text(value);                      
163                         }               
164                         else {
165                                 $this.attr($this.attr('data-stub-target'), value);
166                                 $this.removeAttr('data-stub-target');
167                                 $this.removeAttr('data-stub-value');                    
168                         }               
169                 });
170         
171                 $elem.show();
172                 return $elem;                                           
173         };
174         
175         /*
176          * Dialogs
177          */
178         function GenericDialog(element) {
179                 if(!element) return;
180                 
181                 var self = this;
182                                 
183                 self.$elem = $(element);
184                 
185                 if(!self.$elem.attr('data-ui-initialized')) {
186                         console.log("Initializing dialog", this);
187                         self.initialize();
188                         self.$elem.attr('data-ui-initialized', true);                   
189                 }
190                  
191                 self.show();                            
192         };
193         
194         GenericDialog.prototype = {
195         
196                 /*
197                 * Steps to follow when the dialog in first loaded on page.
198                 */
199                 initialize: function(){
200                         var self = this;
201                         
202                         /* bind buttons */
203                         $('button[data-ui-action]', self.$elem).click(function(event) {
204                                 event.preventDefault();
205                                 
206                                 var action = $(this).attr('data-ui-action');
207                                 console.log("Button pressed, action: ", action);
208                                  
209                                 try {
210                                         self[action + "Action"].call(self);
211                                 } catch(e) {
212                                         console.log("Action failed:", e);
213                                         // always hide on cancel
214                                         if(action == 'cancel')
215                                                 self.hide();                                    
216                                 }                                                               
217                         });                     
218                 },
219                 
220                 /* 
221                  * Prepare dialog for user. Clear any unnessary data.
222                 */
223                 show: function() {
224                         $.blockUI({
225                                 message: this.$elem,
226                                 css: {
227                                         'top': '25%',
228                                         'left': '25%',
229                                         'width': '50%'
230                                 }
231                         });
232                 },
233                 
234                 hide: function(){
235                         $.unblockUI();
236                 },
237                 
238                 cancelAction: function() {
239                         this.hide();                    
240                 },
241                 
242                 doneAction: function() {
243                         this.hide();
244                 },
245                 
246                 clearForm: function() {
247                         $("*[data-ui-error-for]", this.$elem).text('');
248                 },
249                 
250                 reportErrors: function(errors) {
251                         var global = $("*[data-ui-error-for='__all__']", this.$elem);
252                         var unassigned = [];
253                         
254                         for (var field_name in errors) 
255                         {                               
256                                 var span = $("*[data-ui-error-for='"+field_name+"']", this.$elem);
257                                 
258                                 if(!span.length) {
259                                         unassigned.push(field_name);
260                                         continue;
261                                 }
262                                 
263                                 span.text(errors[field_name].join(' '));        
264                         }
265                         
266                         if(unassigned.length > 0)
267                                 global.text( global.text() + 'W formularzu wystąpiły błędy');
268                 }       
269         };       
270         
271         $.wiki.cls.GenericDialog = GenericDialog;  
272          
273         $.wiki.showDialog = function(selector) {
274                 var elem = $(selector);
275                 
276                 if(elem.length != 1) {
277                         console.log("Failed to show dialog:", selector, elem);
278                         return false;                   
279                 }
280                 
281                 try {   
282                     var klass = elem.attr('data-ui-jsclass') 
283                         return new $.wiki.cls[klass](elem);                                             
284                 } catch(e) {
285                         console.log("Failed to show dialog", selector, klass, e);
286                         return false;
287                 }                
288         };
289         
290 })(jQuery);