diff options
| author | hukl <contact@smyck.org> | 2009-02-17 21:54:39 +0100 |
|---|---|---|
| committer | hukl <contact@smyck.org> | 2009-02-17 21:54:39 +0100 |
| commit | f61b5b0597e0c25f084ee67d402f12a43a7a9947 (patch) | |
| tree | 3b4c3f9f38637f1a7ecf703ece4fd3bc4c6e2934 /public/javascripts/tiny_mce/plugins/safari | |
| parent | 3d3b786cc43266f6292f5edd25733dbb9bd6ed06 (diff) | |
added tinymce editor for body area of pages
Diffstat (limited to 'public/javascripts/tiny_mce/plugins/safari')
3 files changed, 516 insertions, 0 deletions
diff --git a/public/javascripts/tiny_mce/plugins/safari/blank.htm b/public/javascripts/tiny_mce/plugins/safari/blank.htm new file mode 100755 index 0000000..266808c --- /dev/null +++ b/public/javascripts/tiny_mce/plugins/safari/blank.htm | |||
| @@ -0,0 +1 @@ | |||
| <!-- WebKit --> \ No newline at end of file | |||
diff --git a/public/javascripts/tiny_mce/plugins/safari/editor_plugin.js b/public/javascripts/tiny_mce/plugins/safari/editor_plugin.js new file mode 100755 index 0000000..4daac19 --- /dev/null +++ b/public/javascripts/tiny_mce/plugins/safari/editor_plugin.js | |||
| @@ -0,0 +1 @@ | |||
| (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()){if(f){if(!f(n))return false;}if(n.nodeType==3&&n.nodeValue&&/[^\s\u00a0]+/.test(n.nodeValue))return false;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;if(!tinymce.isWebKit)return;t.editor=ed;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'];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){e=e.target;if(e.nodeType==1){e.style.cssText='';each(ed.dom.select('*',e),function(e){e.style.cssText='';});}};Event.add(ed.getDoc(),'DOMNodeInserted',removeStyles);window.setTimeout(function(){Event.remove(ed.getDoc(),'DOMNodeInserted',removeStyles);},0);});ed.onKeyUp.add(function(ed,e){var h,b,r,n,s;if(e.keyCode==46||e.keyCode==8){b=ed.getBody();h=b.innerHTML;s=ed.selection;if(b.childNodes.length==1&&!/<(img|hr)/.test(h)&&tinymce.trim(h.replace(/<[^>]+>/g,'')).length==0){ed.setContent('<p><br mce_bogus="1" /></p>',{format:'raw'});n=b.firstChild;r=s.getRng();r.setStart(n,0);r.setEnd(n,0);s.setRng(r);}}});ed.addCommand('FormatBlock',function(u,v){var dom=ed.dom,e=dom.getParent(ed.selection.getNode(),dom.isBlock);if(e)dom.replace(dom.create(v),e,1);else ed.getDoc().execCommand("FormatBlock",false,v);});ed.addCommand('mceInsertContent',function(u,v){ed.getDoc().execCommand("InsertText",false,'mce_marker');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,' ');});ed.onKeyPress.add(function(ed,e){var se,li,lic,r1,r2,n,sel,doc,be,af,pa;if(e.keyCode==13){sel=ed.selection;se=sel.getNode();if(e.shiftKey||ed.settings.force_br_newlines&&se.nodeName!='LI'){t._insertBR(ed);Event.cancel(e);}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(n=dom.getParent(lic.parentNode,'LI,OL,UL'))return;n=dom.getParent(lic,'p,h1,h2,h3,h4,h5,h6,div')||lic;r1=doc.createRange();r1.setStartBefore(n);r1.setEndBefore(li);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);}}}});ed.onExecCommand.add(function(ed,cmd){var sel,dom,bl,bm;if(cmd=='InsertUnorderedList'||cmd=='InsertOrderedList'){sel=ed.selection;dom=ed.dom;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);}}});ed.onClick.add(function(ed,e){e=e.target;if(e.nodeName=='IMG'){t.selElm=e;ed.selection.select(e);}else t.selElm=null;});ed.onInit.add(function(){t._fixWebKitSpans();if(isOldWebKit)t._patchSafari2x(ed);});ed.onSetContent.add(function(){dom=ed.dom;each(['strong','b','em','u','strike','sub','sup','a'],function(v){each(grep(dom.select(v)).reverse(),function(n){var nn=n.nodeName.toLowerCase(),st;if(nn=='a'){if(n.name)dom.replace(dom.create('img',{mce_name:'a',name:n.name,'class':'mceItemAnchor'}),n);return;}switch(nn){case'b':case'strong':if(nn=='b')nn='strong';st='font-weight: bold;';break;case'em':st='font-style: italic;';break;case'u':st='text-decoration: underline;';break;case'sub':st='vertical-align: sub;';break;case'sup':st='vertical-align: super;';break;case'strike':st='text-decoration: line-through;';break;}dom.replace(dom.create('span',{mce_name:nn,style:st,'class':'Apple-style-span'}),n,1);});});});ed.onPreProcess.add(function(ed,o){dom=ed.dom;each(grep(o.node.getElementsByTagName('span')).reverse(),function(n){var v,bg;if(o.get){if(dom.hasClass(n,'Apple-style-span')){bg=n.style.backgroundColor;switch(dom.getAttrib(n,'mce_name')){case'font':if(!ed.settings.convert_fonts_to_spans)dom.setAttrib(n,'style','');break;case'strong':case'em':case'sub':case'sup':dom.setAttrib(n,'style','');break;case'strike':case'u':if(!ed.settings.inline_styles)dom.setAttrib(n,'style','');else dom.setAttrib(n,'mce_name','');break;default:if(!ed.settings.inline_styles)dom.setAttrib(n,'style','');}if(bg)n.style.backgroundColor=bg;}}if(dom.hasClass(n,'mceItemRemoved'))dom.remove(n,1);});});ed.onPostProcess.add(function(ed,o){o.content=o.content.replace(/<br \/><\/(h[1-6]|div|p|address|pre)>/g,'</$1>');o.content=o.content.replace(/ id=\"undefined\"/g,'');});},getInfo:function(){return{longname:'Safari compatibility',author:'Moxiecode Systems AB',authorurl:'http://tinymce.moxiecode.com',infourl:'http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/safari',version:tinymce.majorVersion+"."+tinymce.minorVersion};},_fixWebKitSpans:function(){var t=this,ed=t.editor;if(!isOldWebKit){Event.add(ed.getDoc(),'DOMNodeInserted',function(e){e=e.target;if(e&&e.nodeType==1)t._fixAppleSpan(e);});}else{ed.onExecCommand.add(function(){each(ed.dom.select('span'),function(n){t._fixAppleSpan(n);});ed.nodeChanged();});}},_fixAppleSpan:function(e){var ed=this.editor,dom=ed.dom,fz=this.webKitFontSizes,fzn=this.namedFontSizes,s=ed.settings,st,p;if(dom.getAttrib(e,'mce_fixed'))return;if(e.nodeName=='SPAN'&&e.className=='Apple-style-span'){st=e.style;if(!s.convert_fonts_to_spans){if(st.fontSize){dom.setAttrib(e,'mce_name','font');dom.setAttrib(e,'size',inArray(fz,st.fontSize)+1);}if(st.fontFamily){dom.setAttrib(e,'mce_name','font');dom.setAttrib(e,'face',st.fontFamily);}if(st.color){dom.setAttrib(e,'mce_name','font');dom.setAttrib(e,'color',dom.toHex(st.color));}if(st.backgroundColor){dom.setAttrib(e,'mce_name','font');dom.setStyle(e,'background-color',st.backgroundColor);}}else{if(st.fontSize)dom.setStyle(e,'fontSize',fzn[inArray(fz,st.fontSize)]);}if(st.fontWeight=='bold')dom.setAttrib(e,'mce_name','strong');if(st.fontStyle=='italic')dom.setAttrib(e,'mce_name','em');if(st.textDecoration=='underline')dom.setAttrib(e,'mce_name','u');if(st.textDecoration=='line-through')dom.setAttrib(e,'mce_name','strike');if(st.verticalAlign=='super')dom.setAttrib(e,'mce_name','sup');if(st.verticalAlign=='sub')dom.setAttrib(e,'mce_name','sub');dom.setAttrib(e,'mce_fixed','1');}},_patchSafari2x:function(ed){var t=this,setContent,getNode,dom=ed.dom,lr;if(ed.windowManager.onBeforeOpen){ed.windowManager.onBeforeOpen.add(function(){r=ed.selection.getRng();});}ed.selection.select=function(n){this.getSel().setBaseAndExtent(n,0,n,1);};getNode=ed.selection.getNode;ed.selection.getNode=function(){return t.selElm||getNode.call(this);};ed.selection.getRng=function(){var t=this,s=t.getSel(),d=ed.getDoc(),r,rb,ra,di;if(s.anchorNode){r=d.createRange();try{rb=d.createRange();rb.setStart(s.anchorNode,s.anchorOffset);rb.collapse(1);ra=d.createRange();ra.setStart(s.focusNode,s.focusOffset);ra.collapse(1);di=rb.compareBoundaryPoints(rb.START_TO_END,ra)<0;r.setStart(di?s.anchorNode:s.focusNode,di?s.anchorOffset:s.focusOffset);r.setEnd(di?s.focusNode:s.anchorNode,di?s.focusOffset:s.anchorOffset);lr=r;}catch(ex){}}return r||lr;};setContent=ed.selection.setContent;ed.selection.setContent=function(h,s){var r=this.getRng(),b;try{setContent.call(this,h,s);}catch(ex){b=dom.create('body');b.innerHTML=h;each(b.childNodes,function(n){r.insertNode(n.cloneNode(true));});}};},_insertBR:function(ed){var dom=ed.dom,s=ed.selection,r=s.getRng(),br;r.insertNode(br=dom.create('br'));r.setStartAfter(br);r.setEndAfter(br);s.setRng(r);if(s.getSel().focusNode==br.previousSibling){s.select(dom.insertAfter(dom.doc.createTextNode('\u00a0'),br));s.collapse(1);}ed.getWin().scrollTo(0,dom.getPos(s.getRng().startContainer).y);}});tinymce.PluginManager.add('safari',tinymce.plugins.Safari);})(); \ No newline at end of file | |||
diff --git a/public/javascripts/tiny_mce/plugins/safari/editor_plugin_src.js b/public/javascripts/tiny_mce/plugins/safari/editor_plugin_src.js new file mode 100755 index 0000000..642d659 --- /dev/null +++ b/public/javascripts/tiny_mce/plugins/safari/editor_plugin_src.js | |||
| @@ -0,0 +1,514 @@ | |||
| 1 | /** | ||
| 2 | * $Id: editor_plugin_src.js 264 2007-04-26 20:53:09Z spocke $ | ||
| 3 | * | ||
| 4 | * @author Moxiecode | ||
| 5 | * @copyright Copyright © 2004-2008, Moxiecode Systems AB, All rights reserved. | ||
| 6 | */ | ||
| 7 | |||
| 8 | (function() { | ||
| 9 | var Event = tinymce.dom.Event, grep = tinymce.grep, each = tinymce.each, inArray = tinymce.inArray, isOldWebKit = tinymce.isOldWebKit; | ||
| 10 | |||
| 11 | function isEmpty(d, e, f) { | ||
| 12 | var w, n; | ||
| 13 | |||
| 14 | w = d.createTreeWalker(e, NodeFilter.SHOW_ALL, null, false); | ||
| 15 | while (n = w.nextNode()) { | ||
| 16 | // Filter func | ||
| 17 | if (f) { | ||
| 18 | if (!f(n)) | ||
| 19 | return false; | ||
| 20 | } | ||
| 21 | |||
| 22 | // Non whitespace text node | ||
| 23 | if (n.nodeType == 3 && n.nodeValue && /[^\s\u00a0]+/.test(n.nodeValue)) | ||
| 24 | return false; | ||
| 25 | |||
| 26 | // Is non text element byt still content | ||
| 27 | if (n.nodeType == 1 && /^(HR|IMG|TABLE)$/.test(n.nodeName)) | ||
| 28 | return false; | ||
| 29 | } | ||
| 30 | |||
| 31 | return true; | ||
| 32 | }; | ||
| 33 | |||
| 34 | tinymce.create('tinymce.plugins.Safari', { | ||
| 35 | init : function(ed) { | ||
| 36 | var t = this, dom; | ||
| 37 | |||
| 38 | // Ignore on non webkit | ||
| 39 | if (!tinymce.isWebKit) | ||
| 40 | return; | ||
| 41 | |||
| 42 | t.editor = ed; | ||
| 43 | t.webKitFontSizes = ['x-small', 'small', 'medium', 'large', 'x-large', 'xx-large', '-webkit-xxx-large']; | ||
| 44 | t.namedFontSizes = ['xx-small', 'x-small','small','medium','large','x-large', 'xx-large']; | ||
| 45 | |||
| 46 | // Safari CreateLink command will not work correctly on images that is aligned | ||
| 47 | ed.addCommand('CreateLink', function(u, v) { | ||
| 48 | var n = ed.selection.getNode(), dom = ed.dom, a; | ||
| 49 | |||
| 50 | if (n && (/^(left|right)$/i.test(dom.getStyle(n, 'float', 1)) || /^(left|right)$/i.test(dom.getAttrib(n, 'align')))) { | ||
| 51 | a = dom.create('a', {href : v}, n.cloneNode()); | ||
| 52 | n.parentNode.replaceChild(a, n); | ||
| 53 | ed.selection.select(a); | ||
| 54 | } else | ||
| 55 | ed.getDoc().execCommand("CreateLink", false, v); | ||
| 56 | }); | ||
| 57 | |||
| 58 | ed.onPaste.add(function(ed, e) { | ||
| 59 | function removeStyles(e) { | ||
| 60 | e = e.target; | ||
| 61 | |||
| 62 | if (e.nodeType == 1) { | ||
| 63 | e.style.cssText = ''; | ||
| 64 | |||
| 65 | each(ed.dom.select('*', e), function(e) { | ||
| 66 | e.style.cssText = ''; | ||
| 67 | }); | ||
| 68 | } | ||
| 69 | }; | ||
| 70 | |||
| 71 | Event.add(ed.getDoc(), 'DOMNodeInserted', removeStyles); | ||
| 72 | |||
| 73 | window.setTimeout(function() { | ||
| 74 | Event.remove(ed.getDoc(), 'DOMNodeInserted', removeStyles); | ||
| 75 | }, 0); | ||
| 76 | }); | ||
| 77 | |||
| 78 | ed.onKeyUp.add(function(ed, e) { | ||
| 79 | var h, b, r, n, s; | ||
| 80 | |||
| 81 | // If backspace or delete key | ||
| 82 | if (e.keyCode == 46 || e.keyCode == 8) { | ||
| 83 | b = ed.getBody(); | ||
| 84 | h = b.innerHTML; | ||
| 85 | s = ed.selection; | ||
| 86 | |||
| 87 | // If there is no text content or images or hr elements then remove everything | ||
| 88 | if (b.childNodes.length == 1 && !/<(img|hr)/.test(h) && tinymce.trim(h.replace(/<[^>]+>/g, '')).length == 0) { | ||
| 89 | // Inject paragrah and bogus br | ||
| 90 | ed.setContent('<p><br mce_bogus="1" /></p>', {format : 'raw'}); | ||
| 91 | |||
| 92 | // Move caret before bogus br | ||
| 93 | n = b.firstChild; | ||
| 94 | r = s.getRng(); | ||
| 95 | r.setStart(n, 0); | ||
| 96 | r.setEnd(n, 0); | ||
| 97 | s.setRng(r); | ||
| 98 | } | ||
| 99 | } | ||
| 100 | }); | ||
| 101 | |||
| 102 | // Workaround for FormatBlock bug, http://bugs.webkit.org/show_bug.cgi?id=16004 | ||
| 103 | ed.addCommand('FormatBlock', function(u, v) { | ||
| 104 | var dom = ed.dom, e = dom.getParent(ed.selection.getNode(), dom.isBlock); | ||
| 105 | |||
| 106 | if (e) | ||
| 107 | dom.replace(dom.create(v), e, 1); | ||
| 108 | else | ||
| 109 | ed.getDoc().execCommand("FormatBlock", false, v); | ||
| 110 | }); | ||
| 111 | |||
| 112 | // Workaround for InsertHTML bug, http://bugs.webkit.org/show_bug.cgi?id=16382 | ||
| 113 | ed.addCommand('mceInsertContent', function(u, v) { | ||
| 114 | 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>'); | ||
| 116 | ed.selection.select(ed.dom.get('_mce_tmp')); | ||
| 117 | ed.getDoc().execCommand("Delete", false, ' '); | ||
| 118 | }); | ||
| 119 | |||
| 120 | ed.onKeyPress.add(function(ed, e) { | ||
| 121 | var se, li, lic, r1, r2, n, sel, doc, be, af, pa; | ||
| 122 | |||
| 123 | if (e.keyCode == 13) { | ||
| 124 | sel = ed.selection; | ||
| 125 | se = sel.getNode(); | ||
| 126 | |||
| 127 | // Workaround for missing shift+enter support, http://bugs.webkit.org/show_bug.cgi?id=16973 | ||
| 128 | if (e.shiftKey || ed.settings.force_br_newlines && se.nodeName != 'LI') { | ||
| 129 | t._insertBR(ed); | ||
| 130 | Event.cancel(e); | ||
| 131 | } | ||
| 132 | |||
| 133 | // Workaround for DIV elements produced by Safari | ||
| 134 | if (li = dom.getParent(se, 'LI')) { | ||
| 135 | lic = dom.getParent(li, 'OL,UL'); | ||
| 136 | doc = ed.getDoc(); | ||
| 137 | |||
| 138 | pa = dom.create('p'); | ||
| 139 | dom.add(pa, 'br', {mce_bogus : "1"}); | ||
| 140 | |||
| 141 | if (isEmpty(doc, li)) { | ||
| 142 | // If list in list then use browser default behavior | ||
| 143 | if (n = dom.getParent(lic.parentNode, 'LI,OL,UL')) | ||
| 144 | return; | ||
| 145 | |||
| 146 | n = dom.getParent(lic, 'p,h1,h2,h3,h4,h5,h6,div') || lic; | ||
| 147 | |||
| 148 | // Create range from the start of block element to the list item | ||
| 149 | r1 = doc.createRange(); | ||
| 150 | r1.setStartBefore(n); | ||
| 151 | r1.setEndBefore(li); | ||
| 152 | |||
| 153 | // Create range after the list to the end of block element | ||
| 154 | r2 = doc.createRange(); | ||
| 155 | r2.setStartAfter(li); | ||
| 156 | r2.setEndAfter(n); | ||
| 157 | |||
| 158 | be = r1.cloneContents(); | ||
| 159 | af = r2.cloneContents(); | ||
| 160 | |||
| 161 | if (!isEmpty(doc, af)) | ||
| 162 | dom.insertAfter(af, n); | ||
| 163 | |||
| 164 | dom.insertAfter(pa, n); | ||
| 165 | |||
| 166 | if (!isEmpty(doc, be)) | ||
| 167 | dom.insertAfter(be, n); | ||
| 168 | |||
| 169 | dom.remove(n); | ||
| 170 | |||
| 171 | n = pa.firstChild; | ||
| 172 | r1 = doc.createRange(); | ||
| 173 | r1.setStartBefore(n); | ||
| 174 | r1.setEndBefore(n); | ||
| 175 | sel.setRng(r1); | ||
| 176 | |||
| 177 | return Event.cancel(e); | ||
| 178 | } | ||
| 179 | } | ||
| 180 | } | ||
| 181 | }); | ||
| 182 | |||
| 183 | // Safari doesn't place lists outside block elements | ||
| 184 | ed.onExecCommand.add(function(ed, cmd) { | ||
| 185 | var sel, dom, bl, bm; | ||
| 186 | |||
| 187 | if (cmd == 'InsertUnorderedList' || cmd == 'InsertOrderedList') { | ||
| 188 | sel = ed.selection; | ||
| 189 | dom = ed.dom; | ||
| 190 | |||
| 191 | if (bl = dom.getParent(sel.getNode(), function(n) {return /^(H[1-6]|P|ADDRESS|PRE)$/.test(n.nodeName);})) { | ||
| 192 | bm = sel.getBookmark(); | ||
| 193 | dom.remove(bl, 1); | ||
| 194 | sel.moveToBookmark(bm); | ||
| 195 | } | ||
| 196 | } | ||
| 197 | }); | ||
| 198 | |||
| 199 | // Workaround for bug, http://bugs.webkit.org/show_bug.cgi?id=12250 | ||
| 200 | ed.onClick.add(function(ed, e) { | ||
| 201 | e = e.target; | ||
| 202 | |||
| 203 | if (e.nodeName == 'IMG') { | ||
| 204 | t.selElm = e; | ||
| 205 | ed.selection.select(e); | ||
| 206 | } else | ||
| 207 | t.selElm = null; | ||
| 208 | }); | ||
| 209 | |||
| 210 | ed.onInit.add(function() { | ||
| 211 | t._fixWebKitSpans(); | ||
| 212 | |||
| 213 | if (isOldWebKit) | ||
| 214 | t._patchSafari2x(ed); | ||
| 215 | }); | ||
| 216 | |||
| 217 | ed.onSetContent.add(function() { | ||
| 218 | dom = ed.dom; | ||
| 219 | |||
| 220 | // Convert strong,b,em,u,strike to spans | ||
| 221 | each(['strong','b','em','u','strike','sub','sup','a'], function(v) { | ||
| 222 | each(grep(dom.select(v)).reverse(), function(n) { | ||
| 223 | var nn = n.nodeName.toLowerCase(), st; | ||
| 224 | |||
| 225 | // Convert anchors into images | ||
| 226 | if (nn == 'a') { | ||
| 227 | if (n.name) | ||
| 228 | dom.replace(dom.create('img', {mce_name : 'a', name : n.name, 'class' : 'mceItemAnchor'}), n); | ||
| 229 | |||
| 230 | return; | ||
| 231 | } | ||
| 232 | |||
| 233 | switch (nn) { | ||
| 234 | case 'b': | ||
| 235 | case 'strong': | ||
| 236 | if (nn == 'b') | ||
| 237 | nn = 'strong'; | ||
| 238 | |||
| 239 | st = 'font-weight: bold;'; | ||
| 240 | break; | ||
| 241 | |||
| 242 | case 'em': | ||
| 243 | st = 'font-style: italic;'; | ||
| 244 | break; | ||
| 245 | |||
| 246 | case 'u': | ||
| 247 | st = 'text-decoration: underline;'; | ||
| 248 | break; | ||
| 249 | |||
| 250 | case 'sub': | ||
| 251 | st = 'vertical-align: sub;'; | ||
| 252 | break; | ||
| 253 | |||
| 254 | case 'sup': | ||
| 255 | st = 'vertical-align: super;'; | ||
| 256 | break; | ||
| 257 | |||
| 258 | case 'strike': | ||
| 259 | st = 'text-decoration: line-through;'; | ||
| 260 | break; | ||
| 261 | } | ||
| 262 | |||
| 263 | dom.replace(dom.create('span', {mce_name : nn, style : st, 'class' : 'Apple-style-span'}), n, 1); | ||
| 264 | }); | ||
| 265 | }); | ||
| 266 | }); | ||
| 267 | |||
| 268 | ed.onPreProcess.add(function(ed, o) { | ||
| 269 | dom = ed.dom; | ||
| 270 | |||
| 271 | each(grep(o.node.getElementsByTagName('span')).reverse(), function(n) { | ||
| 272 | var v, bg; | ||
| 273 | |||
| 274 | if (o.get) { | ||
| 275 | if (dom.hasClass(n, 'Apple-style-span')) { | ||
| 276 | bg = n.style.backgroundColor; | ||
| 277 | |||
| 278 | switch (dom.getAttrib(n, 'mce_name')) { | ||
| 279 | case 'font': | ||
| 280 | if (!ed.settings.convert_fonts_to_spans) | ||
| 281 | dom.setAttrib(n, 'style', ''); | ||
| 282 | break; | ||
| 283 | |||
| 284 | case 'strong': | ||
| 285 | case 'em': | ||
| 286 | case 'sub': | ||
| 287 | case 'sup': | ||
| 288 | dom.setAttrib(n, 'style', ''); | ||
| 289 | break; | ||
| 290 | |||
| 291 | case 'strike': | ||
| 292 | case 'u': | ||
| 293 | if (!ed.settings.inline_styles) | ||
| 294 | dom.setAttrib(n, 'style', ''); | ||
| 295 | else | ||
| 296 | dom.setAttrib(n, 'mce_name', ''); | ||
| 297 | |||
| 298 | break; | ||
| 299 | |||
| 300 | default: | ||
| 301 | if (!ed.settings.inline_styles) | ||
| 302 | dom.setAttrib(n, 'style', ''); | ||
| 303 | } | ||
| 304 | |||
| 305 | |||
| 306 | if (bg) | ||
| 307 | n.style.backgroundColor = bg; | ||
| 308 | } | ||
| 309 | } | ||
| 310 | |||
| 311 | if (dom.hasClass(n, 'mceItemRemoved')) | ||
| 312 | dom.remove(n, 1); | ||
| 313 | }); | ||
| 314 | }); | ||
| 315 | |||
| 316 | ed.onPostProcess.add(function(ed, o) { | ||
| 317 | // Safari adds BR at end of all block elements | ||
| 318 | o.content = o.content.replace(/<br \/><\/(h[1-6]|div|p|address|pre)>/g, '</$1>'); | ||
| 319 | |||
| 320 | // Safari adds id="undefined" to HR elements | ||
| 321 | o.content = o.content.replace(/ id=\"undefined\"/g, ''); | ||
| 322 | }); | ||
| 323 | }, | ||
| 324 | |||
| 325 | getInfo : function() { | ||
| 326 | return { | ||
| 327 | longname : 'Safari compatibility', | ||
| 328 | author : 'Moxiecode Systems AB', | ||
| 329 | authorurl : 'http://tinymce.moxiecode.com', | ||
| 330 | infourl : 'http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/safari', | ||
| 331 | version : tinymce.majorVersion + "." + tinymce.minorVersion | ||
| 332 | }; | ||
| 333 | }, | ||
| 334 | |||
| 335 | // Internal methods | ||
| 336 | |||
| 337 | _fixWebKitSpans : function() { | ||
| 338 | var t = this, ed = t.editor; | ||
| 339 | |||
| 340 | if (!isOldWebKit) { | ||
| 341 | // Use mutator events on new WebKit | ||
| 342 | Event.add(ed.getDoc(), 'DOMNodeInserted', function(e) { | ||
| 343 | e = e.target; | ||
| 344 | |||
| 345 | if (e && e.nodeType == 1) | ||
| 346 | t._fixAppleSpan(e); | ||
| 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 | }, | ||
| 359 | |||
| 360 | _fixAppleSpan : function(e) { | ||
| 361 | var ed = this.editor, dom = ed.dom, fz = this.webKitFontSizes, fzn = this.namedFontSizes, s = ed.settings, st, p; | ||
| 362 | |||
| 363 | if (dom.getAttrib(e, 'mce_fixed')) | ||
| 364 | return; | ||
| 365 | |||
| 366 | // Handle Apple style spans | ||
| 367 | if (e.nodeName == 'SPAN' && e.className == 'Apple-style-span') { | ||
| 368 | st = e.style; | ||
| 369 | |||
| 370 | if (!s.convert_fonts_to_spans) { | ||
| 371 | if (st.fontSize) { | ||
| 372 | dom.setAttrib(e, 'mce_name', 'font'); | ||
| 373 | dom.setAttrib(e, 'size', inArray(fz, st.fontSize) + 1); | ||
| 374 | } | ||
| 375 | |||
| 376 | if (st.fontFamily) { | ||
| 377 | dom.setAttrib(e, 'mce_name', 'font'); | ||
| 378 | dom.setAttrib(e, 'face', st.fontFamily); | ||
| 379 | } | ||
| 380 | |||
| 381 | if (st.color) { | ||
| 382 | dom.setAttrib(e, 'mce_name', 'font'); | ||
| 383 | dom.setAttrib(e, 'color', dom.toHex(st.color)); | ||
| 384 | } | ||
| 385 | |||
| 386 | if (st.backgroundColor) { | ||
| 387 | dom.setAttrib(e, 'mce_name', 'font'); | ||
| 388 | dom.setStyle(e, 'background-color', st.backgroundColor); | ||
| 389 | } | ||
| 390 | } else { | ||
| 391 | if (st.fontSize) | ||
| 392 | dom.setStyle(e, 'fontSize', fzn[inArray(fz, st.fontSize)]); | ||
| 393 | } | ||
| 394 | |||
| 395 | if (st.fontWeight == 'bold') | ||
| 396 | dom.setAttrib(e, 'mce_name', 'strong'); | ||
| 397 | |||
| 398 | if (st.fontStyle == 'italic') | ||
| 399 | dom.setAttrib(e, 'mce_name', 'em'); | ||
| 400 | |||
| 401 | if (st.textDecoration == 'underline') | ||
| 402 | dom.setAttrib(e, 'mce_name', 'u'); | ||
| 403 | |||
| 404 | if (st.textDecoration == 'line-through') | ||
| 405 | dom.setAttrib(e, 'mce_name', 'strike'); | ||
| 406 | |||
| 407 | if (st.verticalAlign == 'super') | ||
| 408 | dom.setAttrib(e, 'mce_name', 'sup'); | ||
| 409 | |||
| 410 | if (st.verticalAlign == 'sub') | ||
| 411 | dom.setAttrib(e, 'mce_name', 'sub'); | ||
| 412 | |||
| 413 | dom.setAttrib(e, 'mce_fixed', '1'); | ||
| 414 | } | ||
| 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 | }, | ||
| 488 | |||
| 489 | _insertBR : function(ed) { | ||
| 490 | var dom = ed.dom, s = ed.selection, r = s.getRng(), br; | ||
| 491 | |||
| 492 | // Insert BR element | ||
| 493 | r.insertNode(br = dom.create('br')); | ||
| 494 | |||
| 495 | // Place caret after BR | ||
| 496 | r.setStartAfter(br); | ||
| 497 | r.setEndAfter(br); | ||
| 498 | s.setRng(r); | ||
| 499 | |||
| 500 | // Could not place caret after BR then insert an nbsp entity and move the caret | ||
| 501 | if (s.getSel().focusNode == br.previousSibling) { | ||
| 502 | s.select(dom.insertAfter(dom.doc.createTextNode('\u00a0'), br)); | ||
| 503 | s.collapse(1); | ||
| 504 | } | ||
| 505 | |||
| 506 | // Scroll to new position, scrollIntoView can't be used due to bug: http://bugs.webkit.org/show_bug.cgi?id=16117 | ||
| 507 | ed.getWin().scrollTo(0, dom.getPos(s.getRng().startContainer).y); | ||
| 508 | } | ||
| 509 | }); | ||
| 510 | |||
| 511 | // Register plugin | ||
| 512 | tinymce.PluginManager.add('safari', tinymce.plugins.Safari); | ||
| 513 | })(); | ||
| 514 | |||
