bgneal@312
|
1 /**
|
bgneal@312
|
2 * editor_plugin_src.js
|
bgneal@312
|
3 *
|
bgneal@312
|
4 * Copyright 2009, Moxiecode Systems AB
|
bgneal@312
|
5 * Released under LGPL License.
|
bgneal@312
|
6 *
|
bgneal@312
|
7 * License: http://tinymce.moxiecode.com/license
|
bgneal@312
|
8 * Contributing: http://tinymce.moxiecode.com/contributing
|
bgneal@312
|
9 */
|
bgneal@312
|
10
|
bgneal@312
|
11 (function() {
|
bgneal@312
|
12 var JSONRequest = tinymce.util.JSONRequest, each = tinymce.each, DOM = tinymce.DOM;
|
bgneal@312
|
13
|
bgneal@312
|
14 tinymce.create('tinymce.plugins.SpellcheckerPlugin', {
|
bgneal@312
|
15 getInfo : function() {
|
bgneal@312
|
16 return {
|
bgneal@312
|
17 longname : 'Spellchecker',
|
bgneal@312
|
18 author : 'Moxiecode Systems AB',
|
bgneal@312
|
19 authorurl : 'http://tinymce.moxiecode.com',
|
bgneal@312
|
20 infourl : 'http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/spellchecker',
|
bgneal@312
|
21 version : tinymce.majorVersion + "." + tinymce.minorVersion
|
bgneal@312
|
22 };
|
bgneal@312
|
23 },
|
bgneal@312
|
24
|
bgneal@312
|
25 init : function(ed, url) {
|
bgneal@312
|
26 var t = this, cm;
|
bgneal@312
|
27
|
bgneal@312
|
28 t.url = url;
|
bgneal@312
|
29 t.editor = ed;
|
bgneal@312
|
30 t.rpcUrl = ed.getParam("spellchecker_rpc_url", "{backend}");
|
bgneal@312
|
31
|
bgneal@312
|
32 if (t.rpcUrl == '{backend}') {
|
bgneal@312
|
33 // Sniff if the browser supports native spellchecking (Don't know of a better way)
|
bgneal@312
|
34 if (tinymce.isIE)
|
bgneal@312
|
35 return;
|
bgneal@312
|
36
|
bgneal@312
|
37 t.hasSupport = true;
|
bgneal@312
|
38
|
bgneal@312
|
39 // Disable the context menu when spellchecking is active
|
bgneal@312
|
40 ed.onContextMenu.addToTop(function(ed, e) {
|
bgneal@312
|
41 if (t.active)
|
bgneal@312
|
42 return false;
|
bgneal@312
|
43 });
|
bgneal@312
|
44 }
|
bgneal@312
|
45
|
bgneal@312
|
46 // Register commands
|
bgneal@312
|
47 ed.addCommand('mceSpellCheck', function() {
|
bgneal@312
|
48 if (t.rpcUrl == '{backend}') {
|
bgneal@312
|
49 // Enable/disable native spellchecker
|
bgneal@312
|
50 t.editor.getBody().spellcheck = t.active = !t.active;
|
bgneal@312
|
51 return;
|
bgneal@312
|
52 }
|
bgneal@312
|
53
|
bgneal@312
|
54 if (!t.active) {
|
bgneal@312
|
55 ed.setProgressState(1);
|
bgneal@312
|
56 t._sendRPC('checkWords', [t.selectedLang, t._getWords()], function(r) {
|
bgneal@312
|
57 if (r.length > 0) {
|
bgneal@312
|
58 t.active = 1;
|
bgneal@312
|
59 t._markWords(r);
|
bgneal@312
|
60 ed.setProgressState(0);
|
bgneal@312
|
61 ed.nodeChanged();
|
bgneal@312
|
62 } else {
|
bgneal@312
|
63 ed.setProgressState(0);
|
bgneal@312
|
64
|
bgneal@312
|
65 if (ed.getParam('spellchecker_report_no_misspellings', true))
|
bgneal@312
|
66 ed.windowManager.alert('spellchecker.no_mpell');
|
bgneal@312
|
67 }
|
bgneal@312
|
68 });
|
bgneal@312
|
69 } else
|
bgneal@312
|
70 t._done();
|
bgneal@312
|
71 });
|
bgneal@312
|
72
|
bgneal@442
|
73 if (ed.settings.content_css !== false)
|
bgneal@442
|
74 ed.contentCSS.push(url + '/css/content.css');
|
bgneal@312
|
75
|
bgneal@312
|
76 ed.onClick.add(t._showMenu, t);
|
bgneal@312
|
77 ed.onContextMenu.add(t._showMenu, t);
|
bgneal@312
|
78 ed.onBeforeGetContent.add(function() {
|
bgneal@312
|
79 if (t.active)
|
bgneal@312
|
80 t._removeWords();
|
bgneal@312
|
81 });
|
bgneal@312
|
82
|
bgneal@312
|
83 ed.onNodeChange.add(function(ed, cm) {
|
bgneal@312
|
84 cm.setActive('spellchecker', t.active);
|
bgneal@312
|
85 });
|
bgneal@312
|
86
|
bgneal@312
|
87 ed.onSetContent.add(function() {
|
bgneal@312
|
88 t._done();
|
bgneal@312
|
89 });
|
bgneal@312
|
90
|
bgneal@312
|
91 ed.onBeforeGetContent.add(function() {
|
bgneal@312
|
92 t._done();
|
bgneal@312
|
93 });
|
bgneal@312
|
94
|
bgneal@312
|
95 ed.onBeforeExecCommand.add(function(ed, cmd) {
|
bgneal@312
|
96 if (cmd == 'mceFullScreen')
|
bgneal@312
|
97 t._done();
|
bgneal@312
|
98 });
|
bgneal@312
|
99
|
bgneal@312
|
100 // Find selected language
|
bgneal@312
|
101 t.languages = {};
|
bgneal@312
|
102 each(ed.getParam('spellchecker_languages', '+English=en,Danish=da,Dutch=nl,Finnish=fi,French=fr,German=de,Italian=it,Polish=pl,Portuguese=pt,Spanish=es,Swedish=sv', 'hash'), function(v, k) {
|
bgneal@312
|
103 if (k.indexOf('+') === 0) {
|
bgneal@312
|
104 k = k.substring(1);
|
bgneal@312
|
105 t.selectedLang = v;
|
bgneal@312
|
106 }
|
bgneal@312
|
107
|
bgneal@312
|
108 t.languages[k] = v;
|
bgneal@312
|
109 });
|
bgneal@312
|
110 },
|
bgneal@312
|
111
|
bgneal@312
|
112 createControl : function(n, cm) {
|
bgneal@312
|
113 var t = this, c, ed = t.editor;
|
bgneal@312
|
114
|
bgneal@312
|
115 if (n == 'spellchecker') {
|
bgneal@312
|
116 // Use basic button if we use the native spellchecker
|
bgneal@312
|
117 if (t.rpcUrl == '{backend}') {
|
bgneal@312
|
118 // Create simple toggle button if we have native support
|
bgneal@312
|
119 if (t.hasSupport)
|
bgneal@312
|
120 c = cm.createButton(n, {title : 'spellchecker.desc', cmd : 'mceSpellCheck', scope : t});
|
bgneal@312
|
121
|
bgneal@312
|
122 return c;
|
bgneal@312
|
123 }
|
bgneal@312
|
124
|
bgneal@312
|
125 c = cm.createSplitButton(n, {title : 'spellchecker.desc', cmd : 'mceSpellCheck', scope : t});
|
bgneal@312
|
126
|
bgneal@312
|
127 c.onRenderMenu.add(function(c, m) {
|
bgneal@312
|
128 m.add({title : 'spellchecker.langs', 'class' : 'mceMenuItemTitle'}).setDisabled(1);
|
bgneal@312
|
129 each(t.languages, function(v, k) {
|
bgneal@312
|
130 var o = {icon : 1}, mi;
|
bgneal@312
|
131
|
bgneal@312
|
132 o.onclick = function() {
|
bgneal@442
|
133 if (v == t.selectedLang) {
|
bgneal@442
|
134 return;
|
bgneal@442
|
135 }
|
bgneal@312
|
136 mi.setSelected(1);
|
bgneal@312
|
137 t.selectedItem.setSelected(0);
|
bgneal@312
|
138 t.selectedItem = mi;
|
bgneal@312
|
139 t.selectedLang = v;
|
bgneal@312
|
140 };
|
bgneal@312
|
141
|
bgneal@312
|
142 o.title = k;
|
bgneal@312
|
143 mi = m.add(o);
|
bgneal@312
|
144 mi.setSelected(v == t.selectedLang);
|
bgneal@312
|
145
|
bgneal@312
|
146 if (v == t.selectedLang)
|
bgneal@312
|
147 t.selectedItem = mi;
|
bgneal@312
|
148 })
|
bgneal@312
|
149 });
|
bgneal@312
|
150
|
bgneal@312
|
151 return c;
|
bgneal@312
|
152 }
|
bgneal@312
|
153 },
|
bgneal@312
|
154
|
bgneal@312
|
155 // Internal functions
|
bgneal@312
|
156
|
bgneal@312
|
157 _walk : function(n, f) {
|
bgneal@312
|
158 var d = this.editor.getDoc(), w;
|
bgneal@312
|
159
|
bgneal@312
|
160 if (d.createTreeWalker) {
|
bgneal@312
|
161 w = d.createTreeWalker(n, NodeFilter.SHOW_TEXT, null, false);
|
bgneal@312
|
162
|
bgneal@312
|
163 while ((n = w.nextNode()) != null)
|
bgneal@312
|
164 f.call(this, n);
|
bgneal@312
|
165 } else
|
bgneal@312
|
166 tinymce.walk(n, f, 'childNodes');
|
bgneal@312
|
167 },
|
bgneal@312
|
168
|
bgneal@312
|
169 _getSeparators : function() {
|
bgneal@312
|
170 var re = '', i, str = this.editor.getParam('spellchecker_word_separator_chars', '\\s!"#$%&()*+,-./:;<=>?@[\]^_{|}§©«®±¶·¸»¼½¾¿×÷¤\u201d\u201c');
|
bgneal@312
|
171
|
bgneal@312
|
172 // Build word separator regexp
|
bgneal@312
|
173 for (i=0; i<str.length; i++)
|
bgneal@312
|
174 re += '\\' + str.charAt(i);
|
bgneal@312
|
175
|
bgneal@312
|
176 return re;
|
bgneal@312
|
177 },
|
bgneal@312
|
178
|
bgneal@312
|
179 _getWords : function() {
|
bgneal@312
|
180 var ed = this.editor, wl = [], tx = '', lo = {}, rawWords = [];
|
bgneal@312
|
181
|
bgneal@312
|
182 // Get area text
|
bgneal@312
|
183 this._walk(ed.getBody(), function(n) {
|
bgneal@312
|
184 if (n.nodeType == 3)
|
bgneal@312
|
185 tx += n.nodeValue + ' ';
|
bgneal@312
|
186 });
|
bgneal@312
|
187
|
bgneal@312
|
188 // split the text up into individual words
|
bgneal@312
|
189 if (ed.getParam('spellchecker_word_pattern')) {
|
bgneal@312
|
190 // look for words that match the pattern
|
bgneal@312
|
191 rawWords = tx.match('(' + ed.getParam('spellchecker_word_pattern') + ')', 'gi');
|
bgneal@312
|
192 } else {
|
bgneal@312
|
193 // Split words by separator
|
bgneal@312
|
194 tx = tx.replace(new RegExp('([0-9]|[' + this._getSeparators() + '])', 'g'), ' ');
|
bgneal@312
|
195 tx = tinymce.trim(tx.replace(/(\s+)/g, ' '));
|
bgneal@312
|
196 rawWords = tx.split(' ');
|
bgneal@312
|
197 }
|
bgneal@312
|
198
|
bgneal@312
|
199 // Build word array and remove duplicates
|
bgneal@312
|
200 each(rawWords, function(v) {
|
bgneal@312
|
201 if (!lo[v]) {
|
bgneal@312
|
202 wl.push(v);
|
bgneal@312
|
203 lo[v] = 1;
|
bgneal@312
|
204 }
|
bgneal@312
|
205 });
|
bgneal@312
|
206
|
bgneal@312
|
207 return wl;
|
bgneal@312
|
208 },
|
bgneal@312
|
209
|
bgneal@312
|
210 _removeWords : function(w) {
|
bgneal@312
|
211 var ed = this.editor, dom = ed.dom, se = ed.selection, b = se.getBookmark();
|
bgneal@312
|
212
|
bgneal@312
|
213 each(dom.select('span').reverse(), function(n) {
|
bgneal@312
|
214 if (n && (dom.hasClass(n, 'mceItemHiddenSpellWord') || dom.hasClass(n, 'mceItemHidden'))) {
|
bgneal@312
|
215 if (!w || dom.decode(n.innerHTML) == w)
|
bgneal@312
|
216 dom.remove(n, 1);
|
bgneal@312
|
217 }
|
bgneal@312
|
218 });
|
bgneal@312
|
219
|
bgneal@312
|
220 se.moveToBookmark(b);
|
bgneal@312
|
221 },
|
bgneal@312
|
222
|
bgneal@312
|
223 _markWords : function(wl) {
|
bgneal@442
|
224 var ed = this.editor, dom = ed.dom, doc = ed.getDoc(), se = ed.selection, b = se.getBookmark(), nl = [],
|
bgneal@442
|
225 w = wl.join('|'), re = this._getSeparators(), rx = new RegExp('(^|[' + re + '])(' + w + ')(?=[' + re + ']|$)', 'g');
|
bgneal@312
|
226
|
bgneal@312
|
227 // Collect all text nodes
|
bgneal@442
|
228 this._walk(ed.getBody(), function(n) {
|
bgneal@312
|
229 if (n.nodeType == 3) {
|
bgneal@312
|
230 nl.push(n);
|
bgneal@312
|
231 }
|
bgneal@312
|
232 });
|
bgneal@312
|
233
|
bgneal@312
|
234 // Wrap incorrect words in spans
|
bgneal@312
|
235 each(nl, function(n) {
|
bgneal@442
|
236 var node, elem, txt, pos, v = n.nodeValue;
|
bgneal@312
|
237
|
bgneal@442
|
238 if (rx.test(v)) {
|
bgneal@442
|
239 // Encode the content
|
bgneal@442
|
240 v = dom.encode(v);
|
bgneal@442
|
241 // Create container element
|
bgneal@442
|
242 elem = dom.create('span', {'class' : 'mceItemHidden'});
|
bgneal@312
|
243
|
bgneal@442
|
244 // Following code fixes IE issues by creating text nodes
|
bgneal@442
|
245 // using DOM methods instead of innerHTML.
|
bgneal@442
|
246 // Bug #3124: <PRE> elements content is broken after spellchecking.
|
bgneal@442
|
247 // Bug #1408: Preceding whitespace characters are removed
|
bgneal@442
|
248 // @TODO: I'm not sure that both are still issues on IE9.
|
bgneal@442
|
249 if (tinymce.isIE) {
|
bgneal@442
|
250 // Enclose mispelled words with temporal tag
|
bgneal@442
|
251 v = v.replace(rx, '$1<mcespell>$2</mcespell>');
|
bgneal@442
|
252 // Loop over the content finding mispelled words
|
bgneal@442
|
253 while ((pos = v.indexOf('<mcespell>')) != -1) {
|
bgneal@442
|
254 // Add text node for the content before the word
|
bgneal@442
|
255 txt = v.substring(0, pos);
|
bgneal@442
|
256 if (txt.length) {
|
bgneal@442
|
257 node = doc.createTextNode(dom.decode(txt));
|
bgneal@442
|
258 elem.appendChild(node);
|
bgneal@442
|
259 }
|
bgneal@442
|
260 v = v.substring(pos+10);
|
bgneal@442
|
261 pos = v.indexOf('</mcespell>');
|
bgneal@442
|
262 txt = v.substring(0, pos);
|
bgneal@442
|
263 v = v.substring(pos+11);
|
bgneal@442
|
264 // Add span element for the word
|
bgneal@442
|
265 elem.appendChild(dom.create('span', {'class' : 'mceItemHiddenSpellWord'}, txt));
|
bgneal@442
|
266 }
|
bgneal@442
|
267 // Add text node for the rest of the content
|
bgneal@442
|
268 if (v.length) {
|
bgneal@442
|
269 node = doc.createTextNode(dom.decode(v));
|
bgneal@442
|
270 elem.appendChild(node);
|
bgneal@442
|
271 }
|
bgneal@442
|
272 } else {
|
bgneal@442
|
273 // Other browsers preserve whitespace characters on innerHTML usage
|
bgneal@442
|
274 elem.innerHTML = v.replace(rx, '$1<span class="mceItemHiddenSpellWord">$2</span>');
|
bgneal@442
|
275 }
|
bgneal@312
|
276
|
bgneal@442
|
277 // Finally, replace the node with the container
|
bgneal@442
|
278 dom.replace(elem, n);
|
bgneal@312
|
279 }
|
bgneal@312
|
280 });
|
bgneal@312
|
281
|
bgneal@312
|
282 se.moveToBookmark(b);
|
bgneal@312
|
283 },
|
bgneal@312
|
284
|
bgneal@312
|
285 _showMenu : function(ed, e) {
|
bgneal@312
|
286 var t = this, ed = t.editor, m = t._menu, p1, dom = ed.dom, vp = dom.getViewPort(ed.getWin()), wordSpan = e.target;
|
bgneal@312
|
287
|
bgneal@312
|
288 e = 0; // Fixes IE memory leak
|
bgneal@312
|
289
|
bgneal@312
|
290 if (!m) {
|
bgneal@442
|
291 m = ed.controlManager.createDropMenu('spellcheckermenu', {'class' : 'mceNoIcons'});
|
bgneal@312
|
292 t._menu = m;
|
bgneal@312
|
293 }
|
bgneal@312
|
294
|
bgneal@312
|
295 if (dom.hasClass(wordSpan, 'mceItemHiddenSpellWord')) {
|
bgneal@312
|
296 m.removeAll();
|
bgneal@312
|
297 m.add({title : 'spellchecker.wait', 'class' : 'mceMenuItemTitle'}).setDisabled(1);
|
bgneal@312
|
298
|
bgneal@312
|
299 t._sendRPC('getSuggestions', [t.selectedLang, dom.decode(wordSpan.innerHTML)], function(r) {
|
bgneal@312
|
300 var ignoreRpc;
|
bgneal@312
|
301
|
bgneal@312
|
302 m.removeAll();
|
bgneal@312
|
303
|
bgneal@312
|
304 if (r.length > 0) {
|
bgneal@312
|
305 m.add({title : 'spellchecker.sug', 'class' : 'mceMenuItemTitle'}).setDisabled(1);
|
bgneal@312
|
306 each(r, function(v) {
|
bgneal@312
|
307 m.add({title : v, onclick : function() {
|
bgneal@312
|
308 dom.replace(ed.getDoc().createTextNode(v), wordSpan);
|
bgneal@312
|
309 t._checkDone();
|
bgneal@312
|
310 }});
|
bgneal@312
|
311 });
|
bgneal@312
|
312
|
bgneal@312
|
313 m.addSeparator();
|
bgneal@312
|
314 } else
|
bgneal@312
|
315 m.add({title : 'spellchecker.no_sug', 'class' : 'mceMenuItemTitle'}).setDisabled(1);
|
bgneal@312
|
316
|
bgneal@312
|
317 ignoreRpc = t.editor.getParam("spellchecker_enable_ignore_rpc", '');
|
bgneal@312
|
318 m.add({
|
bgneal@312
|
319 title : 'spellchecker.ignore_word',
|
bgneal@312
|
320 onclick : function() {
|
bgneal@312
|
321 var word = wordSpan.innerHTML;
|
bgneal@312
|
322
|
bgneal@312
|
323 dom.remove(wordSpan, 1);
|
bgneal@312
|
324 t._checkDone();
|
bgneal@312
|
325
|
bgneal@312
|
326 // tell the server if we need to
|
bgneal@312
|
327 if (ignoreRpc) {
|
bgneal@312
|
328 ed.setProgressState(1);
|
bgneal@312
|
329 t._sendRPC('ignoreWord', [t.selectedLang, word], function(r) {
|
bgneal@312
|
330 ed.setProgressState(0);
|
bgneal@312
|
331 });
|
bgneal@312
|
332 }
|
bgneal@312
|
333 }
|
bgneal@312
|
334 });
|
bgneal@312
|
335
|
bgneal@312
|
336 m.add({
|
bgneal@312
|
337 title : 'spellchecker.ignore_words',
|
bgneal@312
|
338 onclick : function() {
|
bgneal@312
|
339 var word = wordSpan.innerHTML;
|
bgneal@312
|
340
|
bgneal@312
|
341 t._removeWords(dom.decode(word));
|
bgneal@312
|
342 t._checkDone();
|
bgneal@312
|
343
|
bgneal@312
|
344 // tell the server if we need to
|
bgneal@312
|
345 if (ignoreRpc) {
|
bgneal@312
|
346 ed.setProgressState(1);
|
bgneal@312
|
347 t._sendRPC('ignoreWords', [t.selectedLang, word], function(r) {
|
bgneal@312
|
348 ed.setProgressState(0);
|
bgneal@312
|
349 });
|
bgneal@312
|
350 }
|
bgneal@312
|
351 }
|
bgneal@312
|
352 });
|
bgneal@312
|
353
|
bgneal@312
|
354
|
bgneal@312
|
355 if (t.editor.getParam("spellchecker_enable_learn_rpc")) {
|
bgneal@312
|
356 m.add({
|
bgneal@312
|
357 title : 'spellchecker.learn_word',
|
bgneal@312
|
358 onclick : function() {
|
bgneal@312
|
359 var word = wordSpan.innerHTML;
|
bgneal@312
|
360
|
bgneal@312
|
361 dom.remove(wordSpan, 1);
|
bgneal@312
|
362 t._checkDone();
|
bgneal@312
|
363
|
bgneal@312
|
364 ed.setProgressState(1);
|
bgneal@312
|
365 t._sendRPC('learnWord', [t.selectedLang, word], function(r) {
|
bgneal@312
|
366 ed.setProgressState(0);
|
bgneal@312
|
367 });
|
bgneal@312
|
368 }
|
bgneal@312
|
369 });
|
bgneal@312
|
370 }
|
bgneal@312
|
371
|
bgneal@312
|
372 m.update();
|
bgneal@312
|
373 });
|
bgneal@312
|
374
|
bgneal@442
|
375 p1 = dom.getPos(ed.getContentAreaContainer());
|
bgneal@442
|
376 m.settings.offset_x = p1.x;
|
bgneal@442
|
377 m.settings.offset_y = p1.y;
|
bgneal@442
|
378
|
bgneal@312
|
379 ed.selection.select(wordSpan);
|
bgneal@312
|
380 p1 = dom.getPos(wordSpan);
|
bgneal@312
|
381 m.showMenu(p1.x, p1.y + wordSpan.offsetHeight - vp.y);
|
bgneal@312
|
382
|
bgneal@312
|
383 return tinymce.dom.Event.cancel(e);
|
bgneal@312
|
384 } else
|
bgneal@312
|
385 m.hideMenu();
|
bgneal@312
|
386 },
|
bgneal@312
|
387
|
bgneal@312
|
388 _checkDone : function() {
|
bgneal@312
|
389 var t = this, ed = t.editor, dom = ed.dom, o;
|
bgneal@312
|
390
|
bgneal@312
|
391 each(dom.select('span'), function(n) {
|
bgneal@312
|
392 if (n && dom.hasClass(n, 'mceItemHiddenSpellWord')) {
|
bgneal@312
|
393 o = true;
|
bgneal@312
|
394 return false;
|
bgneal@312
|
395 }
|
bgneal@312
|
396 });
|
bgneal@312
|
397
|
bgneal@312
|
398 if (!o)
|
bgneal@312
|
399 t._done();
|
bgneal@312
|
400 },
|
bgneal@312
|
401
|
bgneal@312
|
402 _done : function() {
|
bgneal@312
|
403 var t = this, la = t.active;
|
bgneal@312
|
404
|
bgneal@312
|
405 if (t.active) {
|
bgneal@312
|
406 t.active = 0;
|
bgneal@312
|
407 t._removeWords();
|
bgneal@312
|
408
|
bgneal@312
|
409 if (t._menu)
|
bgneal@312
|
410 t._menu.hideMenu();
|
bgneal@312
|
411
|
bgneal@312
|
412 if (la)
|
bgneal@312
|
413 t.editor.nodeChanged();
|
bgneal@312
|
414 }
|
bgneal@312
|
415 },
|
bgneal@312
|
416
|
bgneal@312
|
417 _sendRPC : function(m, p, cb) {
|
bgneal@312
|
418 var t = this;
|
bgneal@312
|
419
|
bgneal@312
|
420 JSONRequest.sendRPC({
|
bgneal@312
|
421 url : t.rpcUrl,
|
bgneal@312
|
422 method : m,
|
bgneal@312
|
423 params : p,
|
bgneal@312
|
424 success : cb,
|
bgneal@312
|
425 error : function(e, x) {
|
bgneal@312
|
426 t.editor.setProgressState(0);
|
bgneal@312
|
427 t.editor.windowManager.alert(e.errstr || ('Error response: ' + x.responseText));
|
bgneal@312
|
428 }
|
bgneal@312
|
429 });
|
bgneal@312
|
430 }
|
bgneal@312
|
431 });
|
bgneal@312
|
432
|
bgneal@312
|
433 // Register plugin
|
bgneal@312
|
434 tinymce.PluginManager.add('spellchecker', tinymce.plugins.SpellcheckerPlugin);
|
bgneal@312
|
435 })();
|