Lepsze obsługiwanie nieudanych merge oraz podawanie w vstorage.all_pages() jedynie...
[redakcja.git] / platforma / static / js / button_scripts.js
1 (function() {
2   var slice = Array.prototype.slice;
3   
4   function update(array, args) {
5     var arrayLength = array.length, length = args.length;
6     while (length--) array[arrayLength + length] = args[length];
7     return array;
8   };
9   
10   function merge(array, args) {
11     array = slice.call(array, 0);
12     return update(array, args);
13   };
14   
15   Function.prototype.bind = function(context) {
16     if (arguments.length < 2 && typeof arguments[0] === 'undefined') {
17       return this;
18     } 
19     var __method = this;
20     var args = slice.call(arguments, 1);
21     return function() {
22       var a = merge(args, arguments);
23       return __method.apply(context, a);
24     }
25   }
26   
27 })();
28
29
30 function ScriptletCenter()
31 {
32     this.scriptlets = {};
33
34     this.scriptlets['insert_tag'] = function(context, params)
35     {
36         var text = this.XMLEditorSelectedText(context);
37         var start_tag = '<'+params.tag;
38         var move_cursor = false;
39
40         for (var attr in params.attrs) {
41             start_tag += ' '+attr+'="' + params.attrs[attr] + '"';
42         }
43
44         start_tag += '>';
45         var end_tag = '</'+params.tag+'>';
46
47         if(text.length > 0) {
48             // tokenize
49             var output = '';
50             var token = '';
51             for(var index=0; index < text.length; index++)
52             {
53                 if (text[index].match(/\s/)) { // whitespace
54                     token += text[index];
55                 }
56                 else { // character
57                     output += token;
58                     if(output == token) output += start_tag;
59                     token = '';
60                     output += text[index];
61                 }
62             }
63
64             if( output[output.length-1] == '\\' ) {
65                 output = output.substr(0, output.length-1) + end_tag + '\\';
66             } else {
67                 output += end_tag;
68             }
69             output += token;
70         }
71         else {
72             if(params.nocontent) {
73                 output = "<"+params.tag +" />";
74             }
75             else {
76                 output = start_tag + end_tag;
77                 move_cursor = true;
78             }
79         }
80
81         this.XMLEditorReplaceSelectedText(context, output);
82
83         try {
84             if (move_cursor) {
85                 this.XMLEditorMoveCursorForward(context, params.tag.length+2);
86             }
87         } catch(e) {}
88
89     }.bind(this);
90
91     this.scriptlets['lineregexp'] = function(context, params) {
92
93         var exprs = $.map(params.exprs, function(expr) {
94             var opts = "g";
95             if(expr.length > 2) {
96                 opts = expr[2];
97             } return {
98                 rx: new RegExp(expr[0], opts),
99                 repl: expr[1]
100                 };
101         });
102
103         var partial = true;
104         var text = this.XMLEditorSelectedText(context);
105         if(!text) return;
106
107         var changed = 0;
108         var lines = text.split('\n');
109         lines = $.map(lines, function(line) {
110             var old_line = line;
111             $(exprs).each(function() {
112                 var expr = this;
113                 line = line.replace(expr.rx, expr.repl);
114             });
115
116             if(old_line != line) changed += 1;
117             return line;
118         });
119
120         if(changed > 0) {
121             this.XMLEditorReplaceSelectedText(context, lines.join('\n') );
122         }
123     }.bind(this);
124
125     this.scriptlets['codemirror_fontsize'] = function(context, params) {
126         var frameBody = this.XMLEditorBody(context);
127
128         if(params.fontSize) {
129             frameBody.css('font-size', params.fontSize);
130         }
131         else {
132             var old_size = parseInt(frameBody.css('font-size'), 10);
133             frameBody.css('font-size', old_size + (params.change || 0) );
134         }
135         
136     }.bind(this);
137
138     this.scriptlets['fulltextregexp'] = function(context, params) {
139         var exprs = $.map(params.exprs, function(expr) {
140             var opts = "mg";
141             if(expr.length > 2) {
142                 opts = expr[2];
143             }
144             return {
145                 rx: new RegExp(expr[0], opts),
146                 repl: expr[1]
147                 };
148         });
149
150         var text = this.XMLEditorSelectedText(context);
151         if(!text) return;
152         var original = text;
153         $(exprs).each(function() {
154             text = text.replace(this.rx, this.repl);
155         });
156
157         if( original != text) {
158             this.XMLEditorReplaceSelectedText(context, text);
159         }
160     }.bind(this);
161
162     this.scriptlets['macro'] = function(context, params) {
163         var self = this;
164
165         $(params).each(function() {
166             $.log(this[0], this[1]);
167             self.scriptlets[this[0]](context, this[1]);
168         });
169     }.bind(this);
170
171     this.scriptlets['lowercase'] = function(context, params)
172     {
173         var text = this.XMLEditorSelectedText(context);
174
175         if(!text) return;
176
177         var repl = '';
178         var lcase = text.toLowerCase();
179         var ucase = text.toUpperCase();
180
181         if(lcase == text) repl = ucase; /* was lowercase */
182         else if(ucase != text) repl = lcase; /* neither lower- or upper-case */
183         else { /* upper case -> camel-case */
184             var words = $(lcase.split(/\s/)).map(function() {
185                 if(this.length > 0) { 
186                     return this[0].toUpperCase() + this.slice(1);
187                 } else {
188                     return '';
189                 }
190             });
191             repl = words.join(' ');
192         }
193
194         if(repl != text) this.XMLEditorReplaceSelectedText(context, repl);
195     }.bind(this);
196
197
198     this.scriptlets["insert_stanza"] = function(context, params) {
199         var text = this.XMLEditorSelectedText(context);
200
201         if(text) {
202             var verses = text.split('\n');
203             text = ''; var buf = ''; var ebuf = '';
204             var first = true;
205
206             for(var i=0;  i < verses.length; i++) {
207                 var verse = verses[i].replace(/^\s+/, "").replace(/\s+$/, "");
208                 if(verse) {
209                     text += (buf ? buf + '/\n' : '') + ebuf;
210                     buf = (first ? '<strofa>\n' : '') + verses[i];
211                     ebuf = '';
212                     first = false;
213                 } else {
214                     ebuf += '\n' + verses[i];
215                 }
216             }
217             text = text + buf + '\n</strofa>' + ebuf;
218             this.XMLEditorReplaceSelectedText(context, text);
219         }
220
221         if (!text) {
222             this.XMLEditorMoveCursorForward(context, params.tag.length + 2);
223         }
224         
225     }.bind(this);
226
227 }
228
229 ScriptletCenter.prototype.XMLEditorSelectedText = function(panel) {
230     return panel.selection();
231 };
232
233 ScriptletCenter.prototype.XMLEditorReplaceSelectedText = function(panel, replacement)
234 {
235     panel.replaceSelection(replacement);
236     // Tell XML view that it's data has changed
237     // panel.contentView.editorDataChanged();
238 };
239
240 ScriptletCenter.prototype.XMLEditorMoveCursorForward = function(panel, n) {
241     var pos = panel.cursorPosition();
242     panel.selectLines(pos.line, pos.character + n);
243 };
244
245 var scriptletCenter;
246
247 $(function() {
248     scriptletCenter = new ScriptletCenter();
249 });