comparison static/js/tiny_mce/plugins/spellchecker/editor_plugin_src.js @ 442:6c182ceb7147

Fixing #217; upgrade TinyMCE to 3.4.2 and enable the paste plugin.
author Brian Neal <bgneal@gmail.com>
date Thu, 26 May 2011 00:43:49 +0000
parents 88b2b9cb8c1f
children
comparison
equal deleted inserted replaced
441:33d0c55e57a9 442:6c182ceb7147
68 }); 68 });
69 } else 69 } else
70 t._done(); 70 t._done();
71 }); 71 });
72 72
73 ed.onInit.add(function() { 73 if (ed.settings.content_css !== false)
74 if (ed.settings.content_css !== false) 74 ed.contentCSS.push(url + '/css/content.css');
75 ed.dom.loadCSS(url + '/css/content.css');
76 });
77 75
78 ed.onClick.add(t._showMenu, t); 76 ed.onClick.add(t._showMenu, t);
79 ed.onContextMenu.add(t._showMenu, t); 77 ed.onContextMenu.add(t._showMenu, t);
80 ed.onBeforeGetContent.add(function() { 78 ed.onBeforeGetContent.add(function() {
81 if (t.active) 79 if (t.active)
130 m.add({title : 'spellchecker.langs', 'class' : 'mceMenuItemTitle'}).setDisabled(1); 128 m.add({title : 'spellchecker.langs', 'class' : 'mceMenuItemTitle'}).setDisabled(1);
131 each(t.languages, function(v, k) { 129 each(t.languages, function(v, k) {
132 var o = {icon : 1}, mi; 130 var o = {icon : 1}, mi;
133 131
134 o.onclick = function() { 132 o.onclick = function() {
133 if (v == t.selectedLang) {
134 return;
135 }
135 mi.setSelected(1); 136 mi.setSelected(1);
136 t.selectedItem.setSelected(0); 137 t.selectedItem.setSelected(0);
137 t.selectedItem = mi; 138 t.selectedItem = mi;
138 t.selectedLang = v; 139 t.selectedLang = v;
139 }; 140 };
218 219
219 se.moveToBookmark(b); 220 se.moveToBookmark(b);
220 }, 221 },
221 222
222 _markWords : function(wl) { 223 _markWords : function(wl) {
223 var r1, r2, r3, r4, r5, w = '', ed = this.editor, re = this._getSeparators(), dom = ed.dom, nl = []; 224 var ed = this.editor, dom = ed.dom, doc = ed.getDoc(), se = ed.selection, b = se.getBookmark(), nl = [],
224 var se = ed.selection, b = se.getBookmark(); 225 w = wl.join('|'), re = this._getSeparators(), rx = new RegExp('(^|[' + re + '])(' + w + ')(?=[' + re + ']|$)', 'g');
225
226 each(wl, function(v) {
227 w += (w ? '|' : '') + v;
228 });
229
230 r1 = new RegExp('([' + re + '])(' + w + ')([' + re + '])', 'g');
231 r2 = new RegExp('^(' + w + ')', 'g');
232 r3 = new RegExp('(' + w + ')([' + re + ']?)$', 'g');
233 r4 = new RegExp('^(' + w + ')([' + re + ']?)$', 'g');
234 r5 = new RegExp('(' + w + ')([' + re + '])', 'g');
235 226
236 // Collect all text nodes 227 // Collect all text nodes
237 this._walk(this.editor.getBody(), function(n) { 228 this._walk(ed.getBody(), function(n) {
238 if (n.nodeType == 3) { 229 if (n.nodeType == 3) {
239 nl.push(n); 230 nl.push(n);
240 } 231 }
241 }); 232 });
242 233
243 // Wrap incorrect words in spans 234 // Wrap incorrect words in spans
244 each(nl, function(n) { 235 each(nl, function(n) {
245 var v; 236 var node, elem, txt, pos, v = n.nodeValue;
246 237
247 if (n.nodeType == 3) { 238 if (rx.test(v)) {
248 v = n.nodeValue; 239 // Encode the content
249 240 v = dom.encode(v);
250 if (r1.test(v) || r2.test(v) || r3.test(v) || r4.test(v)) { 241 // Create container element
251 v = dom.encode(v); 242 elem = dom.create('span', {'class' : 'mceItemHidden'});
252 v = v.replace(r5, '<span class="mceItemHiddenSpellWord">$1</span>$2'); 243
253 v = v.replace(r3, '<span class="mceItemHiddenSpellWord">$1</span>$2'); 244 // Following code fixes IE issues by creating text nodes
254 245 // using DOM methods instead of innerHTML.
255 dom.replace(dom.create('span', {'class' : 'mceItemHidden'}, v), n); 246 // Bug #3124: <PRE> elements content is broken after spellchecking.
247 // Bug #1408: Preceding whitespace characters are removed
248 // @TODO: I'm not sure that both are still issues on IE9.
249 if (tinymce.isIE) {
250 // Enclose mispelled words with temporal tag
251 v = v.replace(rx, '$1<mcespell>$2</mcespell>');
252 // Loop over the content finding mispelled words
253 while ((pos = v.indexOf('<mcespell>')) != -1) {
254 // Add text node for the content before the word
255 txt = v.substring(0, pos);
256 if (txt.length) {
257 node = doc.createTextNode(dom.decode(txt));
258 elem.appendChild(node);
259 }
260 v = v.substring(pos+10);
261 pos = v.indexOf('</mcespell>');
262 txt = v.substring(0, pos);
263 v = v.substring(pos+11);
264 // Add span element for the word
265 elem.appendChild(dom.create('span', {'class' : 'mceItemHiddenSpellWord'}, txt));
266 }
267 // Add text node for the rest of the content
268 if (v.length) {
269 node = doc.createTextNode(dom.decode(v));
270 elem.appendChild(node);
271 }
272 } else {
273 // Other browsers preserve whitespace characters on innerHTML usage
274 elem.innerHTML = v.replace(rx, '$1<span class="mceItemHiddenSpellWord">$2</span>');
256 } 275 }
276
277 // Finally, replace the node with the container
278 dom.replace(elem, n);
257 } 279 }
258 }); 280 });
259 281
260 se.moveToBookmark(b); 282 se.moveToBookmark(b);
261 }, 283 },
264 var t = this, ed = t.editor, m = t._menu, p1, dom = ed.dom, vp = dom.getViewPort(ed.getWin()), wordSpan = e.target; 286 var t = this, ed = t.editor, m = t._menu, p1, dom = ed.dom, vp = dom.getViewPort(ed.getWin()), wordSpan = e.target;
265 287
266 e = 0; // Fixes IE memory leak 288 e = 0; // Fixes IE memory leak
267 289
268 if (!m) { 290 if (!m) {
269 p1 = DOM.getPos(ed.getContentAreaContainer()); 291 m = ed.controlManager.createDropMenu('spellcheckermenu', {'class' : 'mceNoIcons'});
270 //p2 = DOM.getPos(ed.getContainer());
271
272 m = ed.controlManager.createDropMenu('spellcheckermenu', {
273 offset_x : p1.x,
274 offset_y : p1.y,
275 'class' : 'mceNoIcons'
276 });
277
278 t._menu = m; 292 t._menu = m;
279 } 293 }
280 294
281 if (dom.hasClass(wordSpan, 'mceItemHiddenSpellWord')) { 295 if (dom.hasClass(wordSpan, 'mceItemHiddenSpellWord')) {
282 m.removeAll(); 296 m.removeAll();
356 } 370 }
357 371
358 m.update(); 372 m.update();
359 }); 373 });
360 374
375 p1 = dom.getPos(ed.getContentAreaContainer());
376 m.settings.offset_x = p1.x;
377 m.settings.offset_y = p1.y;
378
361 ed.selection.select(wordSpan); 379 ed.selection.select(wordSpan);
362 p1 = dom.getPos(wordSpan); 380 p1 = dom.getPos(wordSpan);
363 m.showMenu(p1.x, p1.y + wordSpan.offsetHeight - vp.y); 381 m.showMenu(p1.x, p1.y + wordSpan.offsetHeight - vp.y);
364 382
365 return tinymce.dom.Event.cancel(e); 383 return tinymce.dom.Event.cancel(e);