Complete serialization with pretty printing. Works both in FF and Webkit. This fixes...
[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['fulltextregexp'] = function(context, params) {
126         var exprs = $.map(params.exprs, function(expr) {
127             var opts = "mg";
128             if(expr.length > 2) {
129                 opts = expr[2];
130             }
131             return {
132                 rx: new RegExp(expr[0], opts),
133                 repl: expr[1]
134                 };
135         });
136
137         var text = this.XMLEditorSelectedText(context);
138         if(!text) return;
139         var original = text;
140         $(exprs).each(function() {
141             text = text.replace(this.rx, this.repl);
142         });
143
144         if( original != text) {
145             this.XMLEditorReplaceSelectedText(context, text);
146         }
147     }.bind(this);
148
149     this.scriptlets['macro'] = function(context, params) {
150         var self = this;
151
152         $(params).each(function() {
153             $.log(this[0], this[1]);
154             self.scriptlets[this[0]](context, this[1]);
155         });
156     }.bind(this);
157
158     this.scriptlets['lowercase'] = function(context, params)
159     {
160         var text = this.XMLEditorSelectedText(context);
161
162         if(!text) return;
163
164         var repl = '';
165         var lcase = text.toLowerCase();
166         var ucase = text.toUpperCase();
167
168         if(lcase == text) repl = ucase; /* was lowercase */
169         else if(ucase != text) repl = lcase; /* neither lower- or upper-case */
170         else { /* upper case -> camel-case */
171             var words = $(lcase.split(/\s/)).map(function() {
172                 if(this.length > 0) { 
173                     return this[0].toUpperCase() + this.slice(1);
174                 } else {
175                     return '';
176                 }
177             });
178             repl = words.join(' ');
179         }
180
181         if(repl != text) this.XMLEditorReplaceSelectedText(context, repl);
182     }.bind(this);
183
184
185     this.scriptlets["insert_stanza"] = function(context, params) {
186         var text = this.XMLEditorSelectedText(context);
187
188         if(text) {
189             var verses = text.split('\n');
190             text = ''; var buf = ''; var ebuf = '';
191             var first = true;
192
193             for(var i=0;  i < verses.length; i++) {
194                 var verse = verses[i].replace(/^\s+/, "").replace(/\s+$/, "");
195                 if(verse) {
196                     text += (buf ? buf + '/\n' : '') + ebuf;
197                     buf = (first ? '<strofa>\n' : '') + verses[i];
198                     ebuf = '';
199                     first = false;
200                 } else {
201                     ebuf += '\n' + verses[i];
202                 }
203             }
204             text = text + buf + '\n</strofa>' + ebuf;
205             this.XMLEditorReplaceSelectedText(context, text);
206         }
207
208         if (!text) {
209             this.XMLEditorMoveCursorForward(context, params.tag.length + 2);
210         }
211         
212     }.bind(this);
213
214 }
215
216 ScriptletCenter.prototype.XMLEditorSelectedText = function(panel) {
217     return panel.selection();
218 };
219
220 ScriptletCenter.prototype.XMLEditorReplaceSelectedText = function(panel, replacement)
221 {
222     panel.replaceSelection(replacement);
223     // Tell XML view that it's data has changed
224     // panel.contentView.editorDataChanged();
225 };
226
227 ScriptletCenter.prototype.XMLEditorMoveCursorForward = function(panel, n) {
228     var pos = panel.cursorPosition();
229     panel.selectLines(pos.line, pos.character + n);
230 };
231
232 var scriptletCenter;
233
234 $(function() {
235     scriptletCenter = new ScriptletCenter();
236 });