includes/clientside/tinymce/plugins/safari/editor_plugin_src.js
changeset 778 57ce13805b6f
parent 543 dffcbfbc4e59
child 1193 e3b94bd055dc
--- a/includes/clientside/tinymce/plugins/safari/editor_plugin_src.js	Sun Dec 21 15:35:46 2008 -0500
+++ b/includes/clientside/tinymce/plugins/safari/editor_plugin_src.js	Sun Dec 21 16:28:00 2008 -0500
@@ -8,6 +8,29 @@
 (function() {
 	var Event = tinymce.dom.Event, grep = tinymce.grep, each = tinymce.each, inArray = tinymce.inArray, isOldWebKit = tinymce.isOldWebKit;
 
+	function isEmpty(d, e, f) {
+		var w, n;
+
+		w = d.createTreeWalker(e, NodeFilter.SHOW_ALL, null, false);
+		while (n = w.nextNode()) {
+			// Filter func
+			if (f) {
+				if (!f(n))
+					return false;
+			}
+
+			// Non whitespace text node
+			if (n.nodeType == 3 && n.nodeValue && /[^\s\u00a0]+/.test(n.nodeValue))
+				return false;
+
+			// Is non text element byt still content
+			if (n.nodeType == 1 && /^(HR|IMG|TABLE)$/.test(n.nodeName))
+				return false;
+		}
+
+		return true;
+	};
+
 	tinymce.create('tinymce.plugins.Safari', {
 		init : function(ed) {
 			var t = this, dom;
@@ -20,10 +43,17 @@
 			t.webKitFontSizes = ['x-small', 'small', 'medium', 'large', 'x-large', 'xx-large', '-webkit-xxx-large'];
 			t.namedFontSizes = ['xx-small', 'x-small','small','medium','large','x-large', 'xx-large'];
 
-			// Safari will crash if the build in createlink command is used
-/*			ed.addCommand('CreateLink', function(u, v) {
-				ed.execCommand("mceInsertContent", false, '<a href="' + dom.encode(v) + '">' + ed.selection.getContent() + '</a>');
-			});*/
+			// Safari CreateLink command will not work correctly on images that is aligned
+			ed.addCommand('CreateLink', function(u, v) {
+				var n = ed.selection.getNode(), dom = ed.dom, a;
+
+				if (n && (/^(left|right)$/i.test(dom.getStyle(n, 'float', 1)) || /^(left|right)$/i.test(dom.getAttrib(n, 'align')))) {
+					a = dom.create('a', {href : v}, n.cloneNode());
+					n.parentNode.replaceChild(a, n);
+					ed.selection.select(a);
+				} else
+					ed.getDoc().execCommand("CreateLink", false, v);
+			});
 
 			ed.onPaste.add(function(ed, e) {
 				function removeStyles(e) {
@@ -46,16 +76,26 @@
 			});
 
 			ed.onKeyUp.add(function(ed, e) {
-				var h, b;
+				var h, b, r, n, s;
 
 				// If backspace or delete key
 				if (e.keyCode == 46 || e.keyCode == 8) {
 					b = ed.getBody();
 					h = b.innerHTML;
+					s = ed.selection;
 
 					// If there is no text content or images or hr elements then remove everything
-					if (b.childNodes.length == 1 && !/<(img|hr)/.test(h) && tinymce.trim(h.replace(/<[^>]+>/g, '')).length == 0)
-						ed.setContent('', {format : 'raw'});
+					if (b.childNodes.length == 1 && !/<(img|hr)/.test(h) && tinymce.trim(h.replace(/<[^>]+>/g, '')).length == 0) {
+						// Inject paragrah and bogus br
+						ed.setContent('<p><br mce_bogus="1" /></p>', {format : 'raw'});
+
+						// Move caret before bogus br
+						n = b.firstChild;
+						r = s.getRng();
+						r.setStart(n, 0);
+						r.setEnd(n, 0);
+						s.setRng(r);
+					}
 				}
 			});
 
@@ -72,49 +112,88 @@
 			// Workaround for InsertHTML bug, http://bugs.webkit.org/show_bug.cgi?id=16382
 			ed.addCommand('mceInsertContent', function(u, v) {
 				ed.getDoc().execCommand("InsertText", false, 'mce_marker');
-				ed.getBody().innerHTML = ed.getBody().innerHTML.replace(/mce_marker/g, v + '<span id="_mce_tmp">XX</span>');
+				ed.getBody().innerHTML = ed.getBody().innerHTML.replace(/mce_marker/g, ed.dom.processHTML(v) + '<span id="_mce_tmp">XX</span>');
 				ed.selection.select(ed.dom.get('_mce_tmp'));
 				ed.getDoc().execCommand("Delete", false, ' ');
 			});
 
-			// Workaround for missing shift+enter support, http://bugs.webkit.org/show_bug.cgi?id=16973
 			ed.onKeyPress.add(function(ed, e) {
-				if (e.keyCode == 13 && (e.shiftKey || ed.settings.force_br_newlines && ed.selection.getNode().nodeName != 'LI')) {
-					t._insertBR(ed);
-					Event.cancel(e);
+				var se, li, lic, r1, r2, n, sel, doc, be, af, pa;
+
+				if (e.keyCode == 13) {
+					sel = ed.selection;
+					se = sel.getNode();
+
+					// Workaround for missing shift+enter support, http://bugs.webkit.org/show_bug.cgi?id=16973
+					if (e.shiftKey || ed.settings.force_br_newlines && se.nodeName != 'LI') {
+						t._insertBR(ed);
+						Event.cancel(e);
+					}
+
+					// Workaround for DIV elements produced by Safari
+					if (li = dom.getParent(se, 'LI')) {
+						lic = dom.getParent(li, 'OL,UL');
+						doc = ed.getDoc();
+
+						pa = dom.create('p');
+						dom.add(pa, 'br', {mce_bogus : "1"});
+
+						if (isEmpty(doc, li)) {
+							// If list in list then use browser default behavior
+							if (n = dom.getParent(lic.parentNode, 'LI,OL,UL'))
+								return;
+
+							n = dom.getParent(lic, 'p,h1,h2,h3,h4,h5,h6,div') || lic;
+
+							// Create range from the start of block element to the list item
+							r1 = doc.createRange();
+							r1.setStartBefore(n);
+							r1.setEndBefore(li);
+
+							// Create range after the list to the end of block element
+							r2 = doc.createRange();
+							r2.setStartAfter(li);
+							r2.setEndAfter(n);
+
+							be = r1.cloneContents();
+							af = r2.cloneContents();
+
+							if (!isEmpty(doc, af))
+								dom.insertAfter(af, n);
+
+							dom.insertAfter(pa, n);
+
+							if (!isEmpty(doc, be))
+								dom.insertAfter(be, n);
+
+							dom.remove(n);
+
+							n = pa.firstChild;
+							r1 = doc.createRange();
+							r1.setStartBefore(n);
+							r1.setEndBefore(n);
+							sel.setRng(r1);
+
+							return Event.cancel(e);
+						}
+					}
 				}
 			});
 
-			// Safari returns incorrect values
-			ed.addQueryValueHandler('FontSize', function(u, v) {
-				var e, v;
-
-				// Check for the real font size at the start of selection
-				if ((e = ed.dom.getParent(ed.selection.getStart(), 'span')) && (v = e.style.fontSize))
-					return tinymce.inArray(t.namedFontSizes, v) + 1;
-
-				// Check for the real font size at the end of selection
-				if ((e = ed.dom.getParent(ed.selection.getEnd(), 'span')) && (v = e.style.fontSize))
-					return tinymce.inArray(t.namedFontSizes, v) + 1;
+			// Safari doesn't place lists outside block elements
+			ed.onExecCommand.add(function(ed, cmd) {
+				var sel, dom, bl, bm;
 
-				// Return default value it's better than nothing right!
-				return ed.getDoc().queryCommandValue('FontSize');
-			});
-
-			// Safari returns incorrect values
-			ed.addQueryValueHandler('FontName', function(u, v) {
-				var e, v;
+				if (cmd == 'InsertUnorderedList' || cmd == 'InsertOrderedList') {
+					sel = ed.selection;
+					dom = ed.dom;
 
-				// Check for the real font name at the start of selection
-				if ((e = ed.dom.getParent(ed.selection.getStart(), 'span')) && (v = e.style.fontFamily))
-					return v.replace(/, /g, ',');
-
-				// Check for the real font name at the end of selection
-				if ((e = ed.dom.getParent(ed.selection.getEnd(), 'span')) && (v = e.style.fontFamily))
-					return v.replace(/, /g, ',');
-
-				// Return default value it's better than nothing right!
-				return ed.getDoc().queryCommandValue('FontName');
+					if (bl = dom.getParent(sel.getNode(), function(n) {return /^(H[1-6]|P|ADDRESS|PRE)$/.test(n.nodeName);})) {
+						bm = sel.getBookmark();
+						dom.remove(bl, 1);
+						sel.moveToBookmark(bm);
+					}
+				}
 			});
 
 			// Workaround for bug, http://bugs.webkit.org/show_bug.cgi?id=12250
@@ -128,34 +207,9 @@
 					t.selElm = null;
 			});
 
-/*			ed.onBeforeExecCommand.add(function(ed, c, b) {
-				var r = t.bookmarkRng;
-
-				// Restore selection
-				if (r) {
-					ed.selection.setRng(r);
-					t.bookmarkRng = null;
-					//console.debug('restore', r.startContainer, r.startOffset, r.endContainer, r.endOffset);
-				}
-			});*/
-
 			ed.onInit.add(function() {
 				t._fixWebKitSpans();
 
-/*				ed.windowManager.onOpen.add(function() {
-					var r = ed.selection.getRng();
-
-					// Store selection if valid
-					if (r.startContainer != ed.getDoc()) {
-						t.bookmarkRng = r.cloneRange();
-						//console.debug('store', r.startContainer, r.startOffset, r.endContainer, r.endOffset);
-					}
-				});
-
-				ed.windowManager.onClose.add(function() {
-					t.bookmarkRng = null;
-				});*/
-
 				if (isOldWebKit)
 					t._patchSafari2x(ed);
 			});