diff options
| author | erdgeist <erdgeist@erdgeist.org> | 2026-06-27 16:58:53 +0200 |
|---|---|---|
| committer | erdgeist <erdgeist@erdgeist.org> | 2026-06-27 16:58:53 +0200 |
| commit | 420506e58fdfc84f1a5bede0a01dedf0af3bb4f3 (patch) | |
| tree | 57726b40e8aa9ccf80f874f39d3facefc0331420 /public/javascripts/tiny_mce/plugins/safari | |
| parent | 241d5e91b2b6716e2861cc77d319c3d3568343a8 (diff) | |
Stage 7: Rails 7.2 → 8.1 on Ruby 3.2.11
- Bump Rails to 8.1.3 (Ruby unchanged at 3.2.11, new gemset rails8-upgrade)
- config.load_defaults 8.1; merge app:update diffs for all environment files
- Remove routing-filter 0.7.0; replace with native scope '(:locale)' in
routes.rb and default_url_options in ApplicationController
- Delete config/initializers/routing_filter_rails71_patch.rb
- Replace vendored TinyMCE 3.x (~200 files) with tinymce-rails ~> 8.3;
migrate admin_interface.js from jQuery .tinymce()/advanced theme to
tinymce.init(); add config/tinymce.yml; note: TinyMCE 7+ is GPL
- rails-i18n ~> 8.0 added explicitly (previously indirect dependency)
- awesome_nested_set, acts-as-taggable-on pinned to git main/master
(gemspec activerecord < 8.1 ceiling; no functional incompatibility;
repin to version once upstream releases updated gemspecs)
- globalize ~> 7.0, libxml-ruby ~> 5.0, nokogiri ~> 1.18, pg ~> 1.5
- sass-rails, coffee-rails, uglifier moved from :assets group to main
(Sprockets 4 convention; :assets group no longer meaningful)
- Node: head, draft, lock_owner marked belongs_to optional: true
- Page: node, user, editor marked belongs_to optional: true
- Static assets in public/images/ and public/javascripts/ referenced via
plain HTML tags; Rails 8 load_defaults raises on pipeline helpers for
undeclared assets
- sessions_controller_test.rb: remove stale require and dead rescue_action
- users_controller_test.rb: assert button[type=submit] not input[type=submit]
(Rails 8 button_to renders <button> not <input>)
- test_helper.rb: node.reload after children.create! (awesome_nested_set
3.9.0 does not refresh parent in memory after callback)
- 129 runs, 339 assertions, 3 failures, 0 errors — identical baseline to 7.2
Diffstat (limited to 'public/javascripts/tiny_mce/plugins/safari')
3 files changed, 0 insertions, 440 deletions
diff --git a/public/javascripts/tiny_mce/plugins/safari/blank.htm b/public/javascripts/tiny_mce/plugins/safari/blank.htm deleted file mode 100644 index 266808c..0000000 --- a/public/javascripts/tiny_mce/plugins/safari/blank.htm +++ /dev/null | |||
| @@ -1 +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 deleted file mode 100644 index 794477c..0000000 --- a/public/javascripts/tiny_mce/plugins/safari/editor_plugin.js +++ /dev/null | |||
| @@ -1 +0,0 @@ | |||
| 1 | (function(){var a=tinymce.dom.Event,c=tinymce.grep,d=tinymce.each,b=tinymce.inArray;function e(j,i,h){var g,k;g=j.createTreeWalker(i,NodeFilter.SHOW_ALL,null,false);while(k=g.nextNode()){if(h){if(!h(k)){return false}}if(k.nodeType==3&&k.nodeValue&&/[^\s\u00a0]+/.test(k.nodeValue)){return false}if(k.nodeType==1&&/^(HR|IMG|TABLE)$/.test(k.nodeName)){return false}}return true}tinymce.create("tinymce.plugins.Safari",{init:function(f){var g=this,h;if(!tinymce.isWebKit){return}g.editor=f;g.webKitFontSizes=["x-small","small","medium","large","x-large","xx-large","-webkit-xxx-large"];g.namedFontSizes=["xx-small","x-small","small","medium","large","x-large","xx-large"];f.addCommand("CreateLink",function(k,j){var m=f.selection.getNode(),l=f.dom,i;if(m&&(/^(left|right)$/i.test(l.getStyle(m,"float",1))||/^(left|right)$/i.test(l.getAttrib(m,"align")))){i=l.create("a",{href:j},m.cloneNode());m.parentNode.replaceChild(i,m);f.selection.select(i)}else{f.getDoc().execCommand("CreateLink",false,j)}});f.onKeyUp.add(function(j,o){var l,i,m,p,k;if(o.keyCode==46||o.keyCode==8){i=j.getBody();l=i.innerHTML;k=j.selection;if(i.childNodes.length==1&&!/<(img|hr)/.test(l)&&tinymce.trim(l.replace(/<[^>]+>/g,"")).length==0){j.setContent('<p><br mce_bogus="1" /></p>',{format:"raw"});p=i.firstChild;m=k.getRng();m.setStart(p,0);m.setEnd(p,0);k.setRng(m)}}});f.addCommand("FormatBlock",function(j,i){var l=f.dom,k=l.getParent(f.selection.getNode(),l.isBlock);if(k){l.replace(l.create(i),k,1)}else{f.getDoc().execCommand("FormatBlock",false,i)}});f.addCommand("mceInsertContent",function(j,i){f.getDoc().execCommand("InsertText",false,"mce_marker");f.getBody().innerHTML=f.getBody().innerHTML.replace(/mce_marker/g,f.dom.processHTML(i)+'<span id="_mce_tmp">XX</span>');f.selection.select(f.dom.get("_mce_tmp"));f.getDoc().execCommand("Delete",false," ")});f.onKeyPress.add(function(o,p){var q,v,r,l,j,k,i,u,m,t,s;if(p.keyCode==13){i=o.selection;q=i.getNode();if(p.shiftKey||o.settings.force_br_newlines&&q.nodeName!="LI"){g._insertBR(o);a.cancel(p)}if(v=h.getParent(q,"LI")){r=h.getParent(v,"OL,UL");u=o.getDoc();s=h.create("p");h.add(s,"br",{mce_bogus:"1"});if(e(u,v)){if(k=h.getParent(r.parentNode,"LI,OL,UL")){return}k=h.getParent(r,"p,h1,h2,h3,h4,h5,h6,div")||r;l=u.createRange();l.setStartBefore(k);l.setEndBefore(v);j=u.createRange();j.setStartAfter(v);j.setEndAfter(k);m=l.cloneContents();t=j.cloneContents();if(!e(u,t)){h.insertAfter(t,k)}h.insertAfter(s,k);if(!e(u,m)){h.insertAfter(m,k)}h.remove(k);k=s.firstChild;l=u.createRange();l.setStartBefore(k);l.setEndBefore(k);i.setRng(l);return a.cancel(p)}}}});f.onExecCommand.add(function(i,k){var j,m,n,l;if(k=="InsertUnorderedList"||k=="InsertOrderedList"){j=i.selection;m=i.dom;if(n=m.getParent(j.getNode(),function(o){return/^(H[1-6]|P|ADDRESS|PRE)$/.test(o.nodeName)})){l=j.getBookmark();m.remove(n,1);j.moveToBookmark(l)}}});f.onClick.add(function(i,j){j=j.target;if(j.nodeName=="IMG"){g.selElm=j;i.selection.select(j)}else{g.selElm=null}});f.onInit.add(function(){g._fixWebKitSpans()});f.onSetContent.add(function(){h=f.dom;d(["strong","b","em","u","strike","sub","sup","a"],function(i){d(c(h.select(i)).reverse(),function(l){var k=l.nodeName.toLowerCase(),j;if(k=="a"){if(l.name){h.replace(h.create("img",{mce_name:"a",name:l.name,"class":"mceItemAnchor"}),l)}return}switch(k){case"b":case"strong":if(k=="b"){k="strong"}j="font-weight: bold;";break;case"em":j="font-style: italic;";break;case"u":j="text-decoration: underline;";break;case"sub":j="vertical-align: sub;";break;case"sup":j="vertical-align: super;";break;case"strike":j="text-decoration: line-through;";break}h.replace(h.create("span",{mce_name:k,style:j,"class":"Apple-style-span"}),l,1)})})});f.onPreProcess.add(function(i,j){h=i.dom;d(c(j.node.getElementsByTagName("span")).reverse(),function(m){var k,l;if(j.get){if(h.hasClass(m,"Apple-style-span")){l=m.style.backgroundColor;switch(h.getAttrib(m,"mce_name")){case"font":if(!i.settings.convert_fonts_to_spans){h.setAttrib(m,"style","")}break;case"strong":case"em":case"sub":case"sup":h.setAttrib(m,"style","");break;case"strike":case"u":if(!i.settings.inline_styles){h.setAttrib(m,"style","")}else{h.setAttrib(m,"mce_name","")}break;default:if(!i.settings.inline_styles){h.setAttrib(m,"style","")}}if(l){m.style.backgroundColor=l}}}if(h.hasClass(m,"mceItemRemoved")){h.remove(m,1)}})});f.onPostProcess.add(function(i,j){j.content=j.content.replace(/<br \/><\/(h[1-6]|div|p|address|pre)>/g,"</$1>");j.content=j.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 g=this,f=g.editor;a.add(f.getDoc(),"DOMNodeInserted",function(h){h=h.target;if(h&&h.nodeType==1){g._fixAppleSpan(h)}})},_fixAppleSpan:function(l){var g=this.editor,m=g.dom,i=this.webKitFontSizes,f=this.namedFontSizes,j=g.settings,h,k;if(m.getAttrib(l,"mce_fixed")){return}if(l.nodeName=="SPAN"&&l.className=="Apple-style-span"){h=l.style;if(!j.convert_fonts_to_spans){if(h.fontSize){m.setAttrib(l,"mce_name","font");m.setAttrib(l,"size",b(i,h.fontSize)+1)}if(h.fontFamily){m.setAttrib(l,"mce_name","font");m.setAttrib(l,"face",h.fontFamily)}if(h.color){m.setAttrib(l,"mce_name","font");m.setAttrib(l,"color",m.toHex(h.color))}if(h.backgroundColor){m.setAttrib(l,"mce_name","font");m.setStyle(l,"background-color",h.backgroundColor)}}else{if(h.fontSize){m.setStyle(l,"fontSize",f[b(i,h.fontSize)])}}if(h.fontWeight=="bold"){m.setAttrib(l,"mce_name","strong")}if(h.fontStyle=="italic"){m.setAttrib(l,"mce_name","em")}if(h.textDecoration=="underline"){m.setAttrib(l,"mce_name","u")}if(h.textDecoration=="line-through"){m.setAttrib(l,"mce_name","strike")}if(h.verticalAlign=="super"){m.setAttrib(l,"mce_name","sup")}if(h.verticalAlign=="sub"){m.setAttrib(l,"mce_name","sub")}m.setAttrib(l,"mce_fixed","1")}},_insertBR:function(f){var j=f.dom,h=f.selection,i=h.getRng(),g;i.insertNode(g=j.create("br"));i.setStartAfter(g);i.setEndAfter(g);h.setRng(i);if(h.getSel().focusNode==g.previousSibling){h.select(j.insertAfter(j.doc.createTextNode("\u00a0"),g));h.collapse(1)}f.getWin().scrollTo(0,j.getPos(h.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 deleted file mode 100644 index 6667b7c..0000000 --- a/public/javascripts/tiny_mce/plugins/safari/editor_plugin_src.js +++ /dev/null | |||
| @@ -1,438 +0,0 @@ | |||
| 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; | ||
| 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 | /* | ||
| 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 | ||
| 60 | ed.onPaste.add(function(ed, e) { | ||
| 61 | function removeStyles(e) { | ||
| 62 | e = e.target; | ||
| 63 | |||
| 64 | if (e.nodeType == 1) { | ||
| 65 | e.style.cssText = ''; | ||
| 66 | |||
| 67 | each(ed.dom.select('*', e), function(e) { | ||
| 68 | e.style.cssText = ''; | ||
| 69 | }); | ||
| 70 | } | ||
| 71 | }; | ||
| 72 | |||
| 73 | Event.add(ed.getDoc(), 'DOMNodeInserted', removeStyles); | ||
| 74 | |||
| 75 | window.setTimeout(function() { | ||
| 76 | Event.remove(ed.getDoc(), 'DOMNodeInserted', removeStyles); | ||
| 77 | }, 0); | ||
| 78 | }); | ||
| 79 | */ | ||
| 80 | ed.onKeyUp.add(function(ed, e) { | ||
| 81 | var h, b, r, n, s; | ||
| 82 | |||
| 83 | // If backspace or delete key | ||
| 84 | if (e.keyCode == 46 || e.keyCode == 8) { | ||
| 85 | b = ed.getBody(); | ||
| 86 | h = b.innerHTML; | ||
| 87 | s = ed.selection; | ||
| 88 | |||
| 89 | // If there is no text content or images or hr elements then remove everything | ||
| 90 | if (b.childNodes.length == 1 && !/<(img|hr)/.test(h) && tinymce.trim(h.replace(/<[^>]+>/g, '')).length == 0) { | ||
| 91 | // Inject paragrah and bogus br | ||
| 92 | ed.setContent('<p><br mce_bogus="1" /></p>', {format : 'raw'}); | ||
| 93 | |||
| 94 | // Move caret before bogus br | ||
| 95 | n = b.firstChild; | ||
| 96 | r = s.getRng(); | ||
| 97 | r.setStart(n, 0); | ||
| 98 | r.setEnd(n, 0); | ||
| 99 | s.setRng(r); | ||
| 100 | } | ||
| 101 | } | ||
| 102 | }); | ||
| 103 | |||
| 104 | // Workaround for FormatBlock bug, http://bugs.webkit.org/show_bug.cgi?id=16004 | ||
| 105 | ed.addCommand('FormatBlock', function(u, v) { | ||
| 106 | var dom = ed.dom, e = dom.getParent(ed.selection.getNode(), dom.isBlock); | ||
| 107 | |||
| 108 | if (e) | ||
| 109 | dom.replace(dom.create(v), e, 1); | ||
| 110 | else | ||
| 111 | ed.getDoc().execCommand("FormatBlock", false, v); | ||
| 112 | }); | ||
| 113 | |||
| 114 | // Workaround for InsertHTML bug, http://bugs.webkit.org/show_bug.cgi?id=16382 | ||
| 115 | ed.addCommand('mceInsertContent', function(u, v) { | ||
| 116 | ed.getDoc().execCommand("InsertText", false, 'mce_marker'); | ||
| 117 | ed.getBody().innerHTML = ed.getBody().innerHTML.replace(/mce_marker/g, ed.dom.processHTML(v) + '<span id="_mce_tmp">XX</span>'); | ||
| 118 | ed.selection.select(ed.dom.get('_mce_tmp')); | ||
| 119 | ed.getDoc().execCommand("Delete", false, ' '); | ||
| 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 | });*/ | ||
| 129 | |||
| 130 | ed.onKeyPress.add(function(ed, e) { | ||
| 131 | var se, li, lic, r1, r2, n, sel, doc, be, af, pa; | ||
| 132 | |||
| 133 | if (e.keyCode == 13) { | ||
| 134 | sel = ed.selection; | ||
| 135 | se = sel.getNode(); | ||
| 136 | |||
| 137 | // Workaround for missing shift+enter support, http://bugs.webkit.org/show_bug.cgi?id=16973 | ||
| 138 | if (e.shiftKey || ed.settings.force_br_newlines && se.nodeName != 'LI') { | ||
| 139 | t._insertBR(ed); | ||
| 140 | Event.cancel(e); | ||
| 141 | } | ||
| 142 | |||
| 143 | // Workaround for DIV elements produced by Safari | ||
| 144 | if (li = dom.getParent(se, 'LI')) { | ||
| 145 | lic = dom.getParent(li, 'OL,UL'); | ||
| 146 | doc = ed.getDoc(); | ||
| 147 | |||
| 148 | pa = dom.create('p'); | ||
| 149 | dom.add(pa, 'br', {mce_bogus : "1"}); | ||
| 150 | |||
| 151 | if (isEmpty(doc, li)) { | ||
| 152 | // If list in list then use browser default behavior | ||
| 153 | if (n = dom.getParent(lic.parentNode, 'LI,OL,UL')) | ||
| 154 | return; | ||
| 155 | |||
| 156 | n = dom.getParent(lic, 'p,h1,h2,h3,h4,h5,h6,div') || lic; | ||
| 157 | |||
| 158 | // Create range from the start of block element to the list item | ||
| 159 | r1 = doc.createRange(); | ||
| 160 | r1.setStartBefore(n); | ||
| 161 | r1.setEndBefore(li); | ||
| 162 | |||
| 163 | // Create range after the list to the end of block element | ||
| 164 | r2 = doc.createRange(); | ||
| 165 | r2.setStartAfter(li); | ||
| 166 | r2.setEndAfter(n); | ||
| 167 | |||
| 168 | be = r1.cloneContents(); | ||
| 169 | af = r2.cloneContents(); | ||
| 170 | |||
| 171 | if (!isEmpty(doc, af)) | ||
| 172 | dom.insertAfter(af, n); | ||
| 173 | |||
| 174 | dom.insertAfter(pa, n); | ||
| 175 | |||
| 176 | if (!isEmpty(doc, be)) | ||
| 177 | dom.insertAfter(be, n); | ||
| 178 | |||
| 179 | dom.remove(n); | ||
| 180 | |||
| 181 | n = pa.firstChild; | ||
| 182 | r1 = doc.createRange(); | ||
| 183 | r1.setStartBefore(n); | ||
| 184 | r1.setEndBefore(n); | ||
| 185 | sel.setRng(r1); | ||
| 186 | |||
| 187 | return Event.cancel(e); | ||
| 188 | } | ||
| 189 | } | ||
| 190 | } | ||
| 191 | }); | ||
| 192 | |||
| 193 | // Safari doesn't place lists outside block elements | ||
| 194 | ed.onExecCommand.add(function(ed, cmd) { | ||
| 195 | var sel, dom, bl, bm; | ||
| 196 | |||
| 197 | if (cmd == 'InsertUnorderedList' || cmd == 'InsertOrderedList') { | ||
| 198 | sel = ed.selection; | ||
| 199 | dom = ed.dom; | ||
| 200 | |||
| 201 | if (bl = dom.getParent(sel.getNode(), function(n) {return /^(H[1-6]|P|ADDRESS|PRE)$/.test(n.nodeName);})) { | ||
| 202 | bm = sel.getBookmark(); | ||
| 203 | dom.remove(bl, 1); | ||
| 204 | sel.moveToBookmark(bm); | ||
| 205 | } | ||
| 206 | } | ||
| 207 | }); | ||
| 208 | |||
| 209 | // Workaround for bug, http://bugs.webkit.org/show_bug.cgi?id=12250 | ||
| 210 | ed.onClick.add(function(ed, e) { | ||
| 211 | e = e.target; | ||
| 212 | |||
| 213 | if (e.nodeName == 'IMG') { | ||
| 214 | t.selElm = e; | ||
| 215 | ed.selection.select(e); | ||
| 216 | } else | ||
| 217 | t.selElm = null; | ||
| 218 | }); | ||
| 219 | |||
| 220 | ed.onInit.add(function() { | ||
| 221 | t._fixWebKitSpans(); | ||
| 222 | }); | ||
| 223 | |||
| 224 | ed.onSetContent.add(function() { | ||
| 225 | dom = ed.dom; | ||
| 226 | |||
| 227 | // Convert strong,b,em,u,strike to spans | ||
| 228 | each(['strong','b','em','u','strike','sub','sup','a'], function(v) { | ||
| 229 | each(grep(dom.select(v)).reverse(), function(n) { | ||
| 230 | var nn = n.nodeName.toLowerCase(), st; | ||
| 231 | |||
| 232 | // Convert anchors into images | ||
| 233 | if (nn == 'a') { | ||
| 234 | if (n.name) | ||
| 235 | dom.replace(dom.create('img', {mce_name : 'a', name : n.name, 'class' : 'mceItemAnchor'}), n); | ||
| 236 | |||
| 237 | return; | ||
| 238 | } | ||
| 239 | |||
| 240 | switch (nn) { | ||
| 241 | case 'b': | ||
| 242 | case 'strong': | ||
| 243 | if (nn == 'b') | ||
| 244 | nn = 'strong'; | ||
| 245 | |||
| 246 | st = 'font-weight: bold;'; | ||
| 247 | break; | ||
| 248 | |||
| 249 | case 'em': | ||
| 250 | st = 'font-style: italic;'; | ||
| 251 | break; | ||
| 252 | |||
| 253 | case 'u': | ||
| 254 | st = 'text-decoration: underline;'; | ||
| 255 | break; | ||
| 256 | |||
| 257 | case 'sub': | ||
| 258 | st = 'vertical-align: sub;'; | ||
| 259 | break; | ||
| 260 | |||
| 261 | case 'sup': | ||
| 262 | st = 'vertical-align: super;'; | ||
| 263 | break; | ||
| 264 | |||
| 265 | case 'strike': | ||
| 266 | st = 'text-decoration: line-through;'; | ||
| 267 | break; | ||
| 268 | } | ||
| 269 | |||
| 270 | dom.replace(dom.create('span', {mce_name : nn, style : st, 'class' : 'Apple-style-span'}), n, 1); | ||
| 271 | }); | ||
| 272 | }); | ||
| 273 | }); | ||
| 274 | |||
| 275 | ed.onPreProcess.add(function(ed, o) { | ||
| 276 | dom = ed.dom; | ||
| 277 | |||
| 278 | each(grep(o.node.getElementsByTagName('span')).reverse(), function(n) { | ||
| 279 | var v, bg; | ||
| 280 | |||
| 281 | if (o.get) { | ||
| 282 | if (dom.hasClass(n, 'Apple-style-span')) { | ||
| 283 | bg = n.style.backgroundColor; | ||
| 284 | |||
| 285 | switch (dom.getAttrib(n, 'mce_name')) { | ||
| 286 | case 'font': | ||
| 287 | if (!ed.settings.convert_fonts_to_spans) | ||
| 288 | dom.setAttrib(n, 'style', ''); | ||
| 289 | break; | ||
| 290 | |||
| 291 | case 'strong': | ||
| 292 | case 'em': | ||
| 293 | case 'sub': | ||
| 294 | case 'sup': | ||
| 295 | dom.setAttrib(n, 'style', ''); | ||
| 296 | break; | ||
| 297 | |||
| 298 | case 'strike': | ||
| 299 | case 'u': | ||
| 300 | if (!ed.settings.inline_styles) | ||
| 301 | dom.setAttrib(n, 'style', ''); | ||
| 302 | else | ||
| 303 | dom.setAttrib(n, 'mce_name', ''); | ||
| 304 | |||
| 305 | break; | ||
| 306 | |||
| 307 | default: | ||
| 308 | if (!ed.settings.inline_styles) | ||
| 309 | dom.setAttrib(n, 'style', ''); | ||
| 310 | } | ||
| 311 | |||
| 312 | |||
| 313 | if (bg) | ||
| 314 | n.style.backgroundColor = bg; | ||
| 315 | } | ||
| 316 | } | ||
| 317 | |||
| 318 | if (dom.hasClass(n, 'mceItemRemoved')) | ||
| 319 | dom.remove(n, 1); | ||
| 320 | }); | ||
| 321 | }); | ||
| 322 | |||
| 323 | ed.onPostProcess.add(function(ed, o) { | ||
| 324 | // Safari adds BR at end of all block elements | ||
| 325 | o.content = o.content.replace(/<br \/><\/(h[1-6]|div|p|address|pre)>/g, '</$1>'); | ||
| 326 | |||
| 327 | // Safari adds id="undefined" to HR elements | ||
| 328 | o.content = o.content.replace(/ id=\"undefined\"/g, ''); | ||
| 329 | }); | ||
| 330 | }, | ||
| 331 | |||
| 332 | getInfo : function() { | ||
| 333 | return { | ||
| 334 | longname : 'Safari compatibility', | ||
| 335 | author : 'Moxiecode Systems AB', | ||
| 336 | authorurl : 'http://tinymce.moxiecode.com', | ||
| 337 | infourl : 'http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/safari', | ||
| 338 | version : tinymce.majorVersion + "." + tinymce.minorVersion | ||
| 339 | }; | ||
| 340 | }, | ||
| 341 | |||
| 342 | // Internal methods | ||
| 343 | |||
| 344 | _fixWebKitSpans : function() { | ||
| 345 | var t = this, ed = t.editor; | ||
| 346 | |||
| 347 | // Use mutator events on new WebKit | ||
| 348 | Event.add(ed.getDoc(), 'DOMNodeInserted', function(e) { | ||
| 349 | e = e.target; | ||
| 350 | |||
| 351 | if (e && e.nodeType == 1) | ||
| 352 | t._fixAppleSpan(e); | ||
| 353 | }); | ||
| 354 | }, | ||
| 355 | |||
| 356 | _fixAppleSpan : function(e) { | ||
| 357 | var ed = this.editor, dom = ed.dom, fz = this.webKitFontSizes, fzn = this.namedFontSizes, s = ed.settings, st, p; | ||
| 358 | |||
| 359 | if (dom.getAttrib(e, 'mce_fixed')) | ||
| 360 | return; | ||
| 361 | |||
| 362 | // Handle Apple style spans | ||
| 363 | if (e.nodeName == 'SPAN' && e.className == 'Apple-style-span') { | ||
| 364 | st = e.style; | ||
| 365 | |||
| 366 | if (!s.convert_fonts_to_spans) { | ||
| 367 | if (st.fontSize) { | ||
| 368 | dom.setAttrib(e, 'mce_name', 'font'); | ||
| 369 | dom.setAttrib(e, 'size', inArray(fz, st.fontSize) + 1); | ||
| 370 | } | ||
| 371 | |||
| 372 | if (st.fontFamily) { | ||
| 373 | dom.setAttrib(e, 'mce_name', 'font'); | ||
| 374 | dom.setAttrib(e, 'face', st.fontFamily); | ||
| 375 | } | ||
| 376 | |||
| 377 | if (st.color) { | ||
| 378 | dom.setAttrib(e, 'mce_name', 'font'); | ||
| 379 | dom.setAttrib(e, 'color', dom.toHex(st.color)); | ||
| 380 | } | ||
| 381 | |||
| 382 | if (st.backgroundColor) { | ||
| 383 | dom.setAttrib(e, 'mce_name', 'font'); | ||
| 384 | dom.setStyle(e, 'background-color', st.backgroundColor); | ||
| 385 | } | ||
| 386 | } else { | ||
| 387 | if (st.fontSize) | ||
| 388 | dom.setStyle(e, 'fontSize', fzn[inArray(fz, st.fontSize)]); | ||
| 389 | } | ||
| 390 | |||
| 391 | if (st.fontWeight == 'bold') | ||
| 392 | dom.setAttrib(e, 'mce_name', 'strong'); | ||
| 393 | |||
| 394 | if (st.fontStyle == 'italic') | ||
| 395 | dom.setAttrib(e, 'mce_name', 'em'); | ||
| 396 | |||
| 397 | if (st.textDecoration == 'underline') | ||
| 398 | dom.setAttrib(e, 'mce_name', 'u'); | ||
| 399 | |||
| 400 | if (st.textDecoration == 'line-through') | ||
| 401 | dom.setAttrib(e, 'mce_name', 'strike'); | ||
| 402 | |||
| 403 | if (st.verticalAlign == 'super') | ||
| 404 | dom.setAttrib(e, 'mce_name', 'sup'); | ||
| 405 | |||
| 406 | if (st.verticalAlign == 'sub') | ||
| 407 | dom.setAttrib(e, 'mce_name', 'sub'); | ||
| 408 | |||
| 409 | dom.setAttrib(e, 'mce_fixed', '1'); | ||
| 410 | } | ||
| 411 | }, | ||
| 412 | |||
| 413 | _insertBR : function(ed) { | ||
| 414 | var dom = ed.dom, s = ed.selection, r = s.getRng(), br; | ||
| 415 | |||
| 416 | // Insert BR element | ||
| 417 | r.insertNode(br = dom.create('br')); | ||
| 418 | |||
| 419 | // Place caret after BR | ||
| 420 | r.setStartAfter(br); | ||
| 421 | r.setEndAfter(br); | ||
| 422 | s.setRng(r); | ||
| 423 | |||
| 424 | // Could not place caret after BR then insert an nbsp entity and move the caret | ||
| 425 | if (s.getSel().focusNode == br.previousSibling) { | ||
| 426 | s.select(dom.insertAfter(dom.doc.createTextNode('\u00a0'), br)); | ||
| 427 | s.collapse(1); | ||
| 428 | } | ||
| 429 | |||
| 430 | // Scroll to new position, scrollIntoView can't be used due to bug: http://bugs.webkit.org/show_bug.cgi?id=16117 | ||
| 431 | ed.getWin().scrollTo(0, dom.getPos(s.getRng().startContainer).y); | ||
| 432 | } | ||
| 433 | }); | ||
| 434 | |||
| 435 | // Register plugin | ||
| 436 | tinymce.PluginManager.add('safari', tinymce.plugins.Safari); | ||
| 437 | })(); | ||
| 438 | |||
