includes/clientside/tinymce/plugins/safari/editor_plugin_src.js
changeset 1193 e3b94bd055dc
parent 778 57ce13805b6f
equal deleted inserted replaced
1192:5882f0eebb34 1193:e3b94bd055dc
     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) {
   207 					t.selElm = null;
   217 					t.selElm = null;
   208 			});
   218 			});
   209 
   219 
   210 			ed.onInit.add(function() {
   220 			ed.onInit.add(function() {
   211 				t._fixWebKitSpans();
   221 				t._fixWebKitSpans();
   212 
       
   213 				if (isOldWebKit)
       
   214 					t._patchSafari2x(ed);
       
   215 			});
   222 			});
   216 
   223 
   217 			ed.onSetContent.add(function() {
   224 			ed.onSetContent.add(function() {
   218 				dom = ed.dom;
   225 				dom = ed.dom;
   219 
   226 
   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