4 * @author Moxiecode |
4 * @author Moxiecode |
5 * @copyright Copyright © 2004-2008, Moxiecode Systems AB, All rights reserved. |
5 * @copyright Copyright © 2004-2008, Moxiecode Systems AB, All rights reserved. |
6 */ |
6 */ |
7 |
7 |
8 (function() { |
8 (function() { |
9 var Event = tinymce.dom.Event, grep = tinymce.grep, each = tinymce.each, inArray = tinymce.inArray, isOldWebKit = tinymce.isOldWebKit; |
9 var Event = tinymce.dom.Event, grep = tinymce.grep, each = tinymce.each, inArray = tinymce.inArray; |
10 |
10 |
11 function isEmpty(d, e, f) { |
11 function isEmpty(d, e, f) { |
12 var w, n; |
12 var w, n; |
13 |
13 |
14 w = d.createTreeWalker(e, NodeFilter.SHOW_ALL, null, false); |
14 w = d.createTreeWalker(e, NodeFilter.SHOW_ALL, null, false); |
53 ed.selection.select(a); |
53 ed.selection.select(a); |
54 } else |
54 } else |
55 ed.getDoc().execCommand("CreateLink", false, v); |
55 ed.getDoc().execCommand("CreateLink", false, v); |
56 }); |
56 }); |
57 |
57 |
|
58 /* |
|
59 // WebKit generates spans out of thin air this patch used to remove them but it will also remove styles we want so it's disabled for now |
58 ed.onPaste.add(function(ed, e) { |
60 ed.onPaste.add(function(ed, e) { |
59 function removeStyles(e) { |
61 function removeStyles(e) { |
60 e = e.target; |
62 e = e.target; |
61 |
63 |
62 if (e.nodeType == 1) { |
64 if (e.nodeType == 1) { |
72 |
74 |
73 window.setTimeout(function() { |
75 window.setTimeout(function() { |
74 Event.remove(ed.getDoc(), 'DOMNodeInserted', removeStyles); |
76 Event.remove(ed.getDoc(), 'DOMNodeInserted', removeStyles); |
75 }, 0); |
77 }, 0); |
76 }); |
78 }); |
77 |
79 */ |
78 ed.onKeyUp.add(function(ed, e) { |
80 ed.onKeyUp.add(function(ed, e) { |
79 var h, b, r, n, s; |
81 var h, b, r, n, s; |
80 |
82 |
81 // If backspace or delete key |
83 // If backspace or delete key |
82 if (e.keyCode == 46 || e.keyCode == 8) { |
84 if (e.keyCode == 46 || e.keyCode == 8) { |
114 ed.getDoc().execCommand("InsertText", false, 'mce_marker'); |
116 ed.getDoc().execCommand("InsertText", false, 'mce_marker'); |
115 ed.getBody().innerHTML = ed.getBody().innerHTML.replace(/mce_marker/g, ed.dom.processHTML(v) + '<span id="_mce_tmp">XX</span>'); |
117 ed.getBody().innerHTML = ed.getBody().innerHTML.replace(/mce_marker/g, ed.dom.processHTML(v) + '<span id="_mce_tmp">XX</span>'); |
116 ed.selection.select(ed.dom.get('_mce_tmp')); |
118 ed.selection.select(ed.dom.get('_mce_tmp')); |
117 ed.getDoc().execCommand("Delete", false, ' '); |
119 ed.getDoc().execCommand("Delete", false, ' '); |
118 }); |
120 }); |
|
121 |
|
122 /* ed.onKeyDown.add(function(ed, e) { |
|
123 // Ctrl+A select all will fail on WebKit since if you paste the contents you selected it will produce a odd div wrapper |
|
124 if ((e.ctrlKey || e.metaKey) && e.keyCode == 65) { |
|
125 ed.selection.select(ed.getBody(), 1); |
|
126 return Event.cancel(e); |
|
127 } |
|
128 });*/ |
119 |
129 |
120 ed.onKeyPress.add(function(ed, e) { |
130 ed.onKeyPress.add(function(ed, e) { |
121 var se, li, lic, r1, r2, n, sel, doc, be, af, pa; |
131 var se, li, lic, r1, r2, n, sel, doc, be, af, pa; |
122 |
132 |
123 if (e.keyCode == 13) { |
133 if (e.keyCode == 13) { |
335 // Internal methods |
342 // Internal methods |
336 |
343 |
337 _fixWebKitSpans : function() { |
344 _fixWebKitSpans : function() { |
338 var t = this, ed = t.editor; |
345 var t = this, ed = t.editor; |
339 |
346 |
340 if (!isOldWebKit) { |
347 // Use mutator events on new WebKit |
341 // Use mutator events on new WebKit |
348 Event.add(ed.getDoc(), 'DOMNodeInserted', function(e) { |
342 Event.add(ed.getDoc(), 'DOMNodeInserted', function(e) { |
349 e = e.target; |
343 e = e.target; |
350 |
344 |
351 if (e && e.nodeType == 1) |
345 if (e && e.nodeType == 1) |
352 t._fixAppleSpan(e); |
346 t._fixAppleSpan(e); |
353 }); |
347 }); |
|
348 } else { |
|
349 // Do post command processing in old WebKit since the browser crashes on Mutator events :( |
|
350 ed.onExecCommand.add(function() { |
|
351 each(ed.dom.select('span'), function(n) { |
|
352 t._fixAppleSpan(n); |
|
353 }); |
|
354 |
|
355 ed.nodeChanged(); |
|
356 }); |
|
357 } |
|
358 }, |
354 }, |
359 |
355 |
360 _fixAppleSpan : function(e) { |
356 _fixAppleSpan : function(e) { |
361 var ed = this.editor, dom = ed.dom, fz = this.webKitFontSizes, fzn = this.namedFontSizes, s = ed.settings, st, p; |
357 var ed = this.editor, dom = ed.dom, fz = this.webKitFontSizes, fzn = this.namedFontSizes, s = ed.settings, st, p; |
362 |
358 |
410 if (st.verticalAlign == 'sub') |
406 if (st.verticalAlign == 'sub') |
411 dom.setAttrib(e, 'mce_name', 'sub'); |
407 dom.setAttrib(e, 'mce_name', 'sub'); |
412 |
408 |
413 dom.setAttrib(e, 'mce_fixed', '1'); |
409 dom.setAttrib(e, 'mce_fixed', '1'); |
414 } |
410 } |
415 }, |
|
416 |
|
417 _patchSafari2x : function(ed) { |
|
418 var t = this, setContent, getNode, dom = ed.dom, lr; |
|
419 |
|
420 // Inline dialogs |
|
421 if (ed.windowManager.onBeforeOpen) { |
|
422 ed.windowManager.onBeforeOpen.add(function() { |
|
423 r = ed.selection.getRng(); |
|
424 }); |
|
425 } |
|
426 |
|
427 // Fake select on 2.x |
|
428 ed.selection.select = function(n) { |
|
429 this.getSel().setBaseAndExtent(n, 0, n, 1); |
|
430 }; |
|
431 |
|
432 getNode = ed.selection.getNode; |
|
433 ed.selection.getNode = function() { |
|
434 return t.selElm || getNode.call(this); |
|
435 }; |
|
436 |
|
437 // Fake range on Safari 2.x |
|
438 ed.selection.getRng = function() { |
|
439 var t = this, s = t.getSel(), d = ed.getDoc(), r, rb, ra, di; |
|
440 |
|
441 // Fake range on Safari 2.x |
|
442 if (s.anchorNode) { |
|
443 r = d.createRange(); |
|
444 |
|
445 try { |
|
446 // Setup before range |
|
447 rb = d.createRange(); |
|
448 rb.setStart(s.anchorNode, s.anchorOffset); |
|
449 rb.collapse(1); |
|
450 |
|
451 // Setup after range |
|
452 ra = d.createRange(); |
|
453 ra.setStart(s.focusNode, s.focusOffset); |
|
454 ra.collapse(1); |
|
455 |
|
456 // Setup start/end points by comparing locations |
|
457 di = rb.compareBoundaryPoints(rb.START_TO_END, ra) < 0; |
|
458 r.setStart(di ? s.anchorNode : s.focusNode, di ? s.anchorOffset : s.focusOffset); |
|
459 r.setEnd(di ? s.focusNode : s.anchorNode, di ? s.focusOffset : s.anchorOffset); |
|
460 |
|
461 lr = r; |
|
462 } catch (ex) { |
|
463 // Sometimes fails, at least we tried to do it by the book. I hope Safari 2.x will go disappear soooon!!! |
|
464 } |
|
465 } |
|
466 |
|
467 return r || lr; |
|
468 }; |
|
469 |
|
470 // Fix setContent so it works |
|
471 setContent = ed.selection.setContent; |
|
472 ed.selection.setContent = function(h, s) { |
|
473 var r = this.getRng(), b; |
|
474 |
|
475 try { |
|
476 setContent.call(this, h, s); |
|
477 } catch (ex) { |
|
478 // Workaround for Safari 2.x |
|
479 b = dom.create('body'); |
|
480 b.innerHTML = h; |
|
481 |
|
482 each(b.childNodes, function(n) { |
|
483 r.insertNode(n.cloneNode(true)); |
|
484 }); |
|
485 } |
|
486 }; |
|
487 }, |
411 }, |
488 |
412 |
489 _insertBR : function(ed) { |
413 _insertBR : function(ed) { |
490 var dom = ed.dom, s = ed.selection, r = s.getRng(), br; |
414 var dom = ed.dom, s = ed.selection, r = s.getRng(), br; |
491 |
415 |