diff -r 488665d49417 -r 57ce13805b6f includes/clientside/tinymce/plugins/safari/editor_plugin_src.js --- 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, '' + ed.selection.getContent() + ''); - });*/ + // 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('


', {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 + 'XX'); + ed.getBody().innerHTML = ed.getBody().innerHTML.replace(/mce_marker/g, ed.dom.processHTML(v) + 'XX'); 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); });