summaryrefslogtreecommitdiff
path: root/public/javascripts/tiny_mce/plugins/paste
diff options
context:
space:
mode:
Diffstat (limited to 'public/javascripts/tiny_mce/plugins/paste')
-rwxr-xr-xpublic/javascripts/tiny_mce/plugins/paste/blank.htm22
-rwxr-xr-xpublic/javascripts/tiny_mce/plugins/paste/css/blank.css14
-rwxr-xr-xpublic/javascripts/tiny_mce/plugins/paste/css/pasteword.css3
-rw-r--r--[-rwxr-xr-x]public/javascripts/tiny_mce/plugins/paste/editor_plugin.js2
-rw-r--r--[-rwxr-xr-x]public/javascripts/tiny_mce/plugins/paste/editor_plugin_src.js706
-rw-r--r--[-rwxr-xr-x]public/javascripts/tiny_mce/plugins/paste/js/pastetext.js58
-rw-r--r--[-rwxr-xr-x]public/javascripts/tiny_mce/plugins/paste/js/pasteword.js79
-rw-r--r--[-rwxr-xr-x]public/javascripts/tiny_mce/plugins/paste/langs/en_dlg.js0
-rw-r--r--[-rwxr-xr-x]public/javascripts/tiny_mce/plugins/paste/pastetext.htm35
-rw-r--r--[-rwxr-xr-x]public/javascripts/tiny_mce/plugins/paste/pasteword.htm8
10 files changed, 496 insertions, 431 deletions
diff --git a/public/javascripts/tiny_mce/plugins/paste/blank.htm b/public/javascripts/tiny_mce/plugins/paste/blank.htm
deleted file mode 100755
index 7ba26bd..0000000
--- a/public/javascripts/tiny_mce/plugins/paste/blank.htm
+++ /dev/null
@@ -1,22 +0,0 @@
1<html xmlns="http://www.w3.org/1999/xhtml">
2<head>
3<title>blank_page</title>
4<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
5<link href="css/blank.css" rel="stylesheet" type="text/css" />
6<base target="_self" />
7<script type="text/javascript">
8function init() {
9 if (parent.tinymce.isIE)
10 document.body.contentEditable = true;
11 else
12 document.designMode = 'on';
13
14 parent.initIframe(document);
15 window.focus();
16}
17</script>
18</head>
19<body onload="init();">
20
21</body>
22</html>
diff --git a/public/javascripts/tiny_mce/plugins/paste/css/blank.css b/public/javascripts/tiny_mce/plugins/paste/css/blank.css
deleted file mode 100755
index 6b16bac..0000000
--- a/public/javascripts/tiny_mce/plugins/paste/css/blank.css
+++ /dev/null
@@ -1,14 +0,0 @@
1html, body {height:98%}
2body {
3background-color: #FFFFFF;
4font-family: Verdana, Arial, Helvetica, sans-serif;
5font-size: 10px;
6scrollbar-3dlight-color: #F0F0EE;
7scrollbar-arrow-color: #676662;
8scrollbar-base-color: #F0F0EE;
9scrollbar-darkshadow-color: #DDDDDD;
10scrollbar-face-color: #E0E0DD;
11scrollbar-highlight-color: #F0F0EE;
12scrollbar-shadow-color: #F0F0EE;
13scrollbar-track-color: #F5F5F5;
14}
diff --git a/public/javascripts/tiny_mce/plugins/paste/css/pasteword.css b/public/javascripts/tiny_mce/plugins/paste/css/pasteword.css
deleted file mode 100755
index b3be627..0000000
--- a/public/javascripts/tiny_mce/plugins/paste/css/pasteword.css
+++ /dev/null
@@ -1,3 +0,0 @@
1.sourceIframe {
2 border: 1px solid #808080;
3}
diff --git a/public/javascripts/tiny_mce/plugins/paste/editor_plugin.js b/public/javascripts/tiny_mce/plugins/paste/editor_plugin.js
index eeeebd5..473bb85 100755..100644
--- a/public/javascripts/tiny_mce/plugins/paste/editor_plugin.js
+++ b/public/javascripts/tiny_mce/plugins/paste/editor_plugin.js
@@ -1 +1 @@
(function(){var Event=tinymce.dom.Event;tinymce.create('tinymce.plugins.PastePlugin',{init:function(ed,url){var t=this;t.editor=ed;ed.addCommand('mcePasteText',function(ui,v){if(ui){if((ed.getParam('paste_use_dialog',true))||(!tinymce.isIE)){ed.windowManager.open({file:url+'/pastetext.htm',width:450,height:400,inline:1},{plugin_url:url});}else t._insertText(clipboardData.getData("Text"),true);}else t._insertText(v.html,v.linebreaks);});ed.addCommand('mcePasteWord',function(ui,v){if(ui){if((ed.getParam('paste_use_dialog',true))||(!tinymce.isIE)){ed.windowManager.open({file:url+'/pasteword.htm',width:450,height:400,inline:1},{plugin_url:url});}else t._insertText(t._clipboardHTML());}else t._insertWordContent(v);});ed.addCommand('mceSelectAll',function(){ed.execCommand('selectall');});ed.addButton('pastetext',{title:'paste.paste_text_desc',cmd:'mcePasteText',ui:true});ed.addButton('pasteword',{title:'paste.paste_word_desc',cmd:'mcePasteWord',ui:true});ed.addButton('selectall',{title:'paste.selectall_desc',cmd:'mceSelectAll'});if(ed.getParam("paste_auto_cleanup_on_paste",false)){ed.onPaste.add(function(ed,e){return t._handlePasteEvent(e)});}if(!tinymce.isIE&&ed.getParam("paste_auto_cleanup_on_paste",false)){ed.onKeyDown.add(function(ed,e){if(e.ctrlKey&&e.keyCode==86){window.setTimeout(function(){ed.execCommand("mcePasteText",true);},1);Event.cancel(e);}});}},getInfo:function(){return{longname:'Paste text/word',author:'Moxiecode Systems AB',authorurl:'http://tinymce.moxiecode.com',infourl:'http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/paste',version:tinymce.majorVersion+"."+tinymce.minorVersion};},_handlePasteEvent:function(e){var html=this._clipboardHTML(),ed=this.editor,sel=ed.selection,r;if(ed&&(r=sel.getRng())&&r.text.length>0)ed.execCommand('delete');if(html&&html.length>0)ed.execCommand('mcePasteWord',false,html);return Event.cancel(e);},_insertText:function(content,bLinebreaks){content=this.editor.dom.encode(content);if(content&&content.length>0){if(!this.editor.selection.isCollapsed())this.editor.execCommand("Delete");if(bLinebreaks){if(this.editor.getParam("paste_create_paragraphs",true)){var rl=this.editor.getParam("paste_replace_list",'\u2122,<sup>TM</sup>,\u2026,...,\u201c|\u201d,",\u2019,\',\u2013|\u2014|\u2015|\u2212,-').split(',');for(var i=0;i<rl.length;i+=2)content=content.replace(new RegExp(rl[i],'gi'),rl[i+1]);content=content.replace(/\r\n\r\n/g,'</p><p>');content=content.replace(/\r\r/g,'</p><p>');content=content.replace(/\n\n/g,'</p><p>');if((pos=content.indexOf('</p><p>'))!=-1){this.editor.execCommand("Delete");var node=this.editor.selection.getNode();var breakElms=[];do{if(node.nodeType==1){if(node.nodeName=="TD"||node.nodeName=="BODY")break;breakElms[breakElms.length]=node;}}while(node=node.parentNode);var before="",after="</p>";before+=content.substring(0,pos);for(var i=0;i<breakElms.length;i++){before+="</"+breakElms[i].nodeName+">";after+="<"+breakElms[(breakElms.length-1)-i].nodeName+">";}before+="<p>";content=before+content.substring(pos+7)+after;}}if(this.editor.getParam("paste_create_linebreaks",true)){content=content.replace(/\r\n/g,'<br />');content=content.replace(/\r/g,'<br />');content=content.replace(/\n/g,'<br />');}}this.editor.execCommand("mceInsertRawHTML",false,content);}},_insertWordContent:function(content){var t=this,ed=t.editor;if(content&&content.length>0){var bull=String.fromCharCode(8226);var middot=String.fromCharCode(183);if(ed.getParam('paste_insert_word_content_callback'))content=ed.execCallback('paste_insert_word_content_callback','before',content);var rl=ed.getParam("paste_replace_list",'\u2122,<sup>TM</sup>,\u2026,...,\x93|\x94|\u201c|\u201d,",\x60|\x91|\x92|\u2018|\u2019,\',\u2013|\u2014|\u2015|\u2212,-').split(',');for(var i=0;i<rl.length;i+=2)content=content.replace(new RegExp(rl[i],'gi'),rl[i+1]);if(this.editor.getParam("paste_convert_headers_to_strong",false)){content=content.replace(new RegExp('<p class=MsoHeading.*?>(.*?)<\/p>','gi'),'<p><b>$1</b></p>');}content=content.replace(new RegExp('tab-stops: list [0-9]+.0pt">','gi'),'">'+"--list--");content=content.replace(new RegExp(bull+"(.*?)<BR>","gi"),"<p>"+middot+"$1</p>");content=content.replace(new RegExp('<SPAN style="mso-list: Ignore">','gi'),"<span>"+bull);content=content.replace(/<o:p><\/o:p>/gi,"");content=content.replace(new RegExp('<br style="page-break-before: always;.*>','gi'),'-- page break --');content=content.replace(/<!--([\s\S]*?)-->|<style>[\s\S]*?<\/style>/g,"");content=content.replace(/<(meta|link)[^>]+>/g,"");if(this.editor.getParam("paste_remove_spans",true))content=content.replace(/<\/?span[^>]*>/gi,"");if(this.editor.getParam("paste_remove_styles",true))content=content.replace(new RegExp('<(\\w[^>]*) style="([^"]*)"([^>]*)','gi'),"<$1$3");content=content.replace(/<\/?font[^>]*>/gi,"");switch(this.editor.getParam("paste_strip_class_attributes","all")){case"all":content=content.replace(/<(\w[^>]*) class=([^ |>]*)([^>]*)/gi,"<$1$3");break;case"mso":content=content.replace(new RegExp('<(\\w[^>]*) class="?mso([^ |>]*)([^>]*)','gi'),"<$1$3");break;}content=content.replace(new RegExp('href="?'+this._reEscape(""+document.location)+'','gi'),'href="'+this.editor.documentBaseURI.getURI());content=content.replace(/<(\w[^>]*) lang=([^ |>]*)([^>]*)/gi,"<$1$3");content=content.replace(/<\\?\?xml[^>]*>/gi,"");content=content.replace(/<\/?\w+:[^>]*>/gi,"");content=content.replace(/-- page break --\s*<p>&nbsp;<\/p>/gi,"");content=content.replace(/-- page break --/gi,"");if(!this.editor.getParam('force_p_newlines')){content=content.replace('','','gi');content=content.replace('</p>','<br /><br />','gi');}if(!tinymce.isIE&&!this.editor.getParam('force_p_newlines')){content=content.replace(/<\/?p[^>]*>/gi,"");}content=content.replace(/<\/?div[^>]*>/gi,"");if(this.editor.getParam("paste_convert_middot_lists",true)){var div=ed.dom.create("div",null,content);var className=this.editor.getParam("paste_unindented_list_class","unIndentedList");while(this._convertMiddots(div,"--list--"));while(this._convertMiddots(div,middot,className));while(this._convertMiddots(div,bull));content=div.innerHTML;}if(this.editor.getParam("paste_convert_headers_to_strong",false)){content=content.replace(/<h[1-6]>&nbsp;<\/h[1-6]>/gi,'<p>&nbsp;&nbsp;</p>');content=content.replace(/<h[1-6]>/gi,'<p><b>');content=content.replace(/<\/h[1-6]>/gi,'</b></p>');content=content.replace(/<b>&nbsp;<\/b>/gi,'<b>&nbsp;&nbsp;</b>');content=content.replace(/^(&nbsp;)*/gi,'');}content=content.replace(/--list--/gi,"");if(ed.getParam('paste_insert_word_content_callback'))content=ed.execCallback('paste_insert_word_content_callback','after',content);this.editor.execCommand("mceInsertContent",false,content);if(this.editor.getParam('paste_force_cleanup_wordpaste',true)){var ed=this.editor;window.setTimeout(function(){ed.execCommand("mceCleanup");},1);}}},_reEscape:function(s){var l="?.\\*[](){}+^$:";var o="";for(var i=0;i<s.length;i++){var c=s.charAt(i);if(l.indexOf(c)!=-1)o+='\\'+c;else o+=c;}return o;},_convertMiddots:function(div,search,class_name){var ed=this.editor,mdot=String.fromCharCode(183),bull=String.fromCharCode(8226);var nodes,prevul,i,p,ul,li,np,cp,li;nodes=div.getElementsByTagName("p");for(i=0;i<nodes.length;i++){p=nodes[i];if(p.innerHTML.indexOf(search)==0){ul=ed.dom.create("ul");if(class_name)ul.className=class_name;li=ed.dom.create("li");li.innerHTML=p.innerHTML.replace(new RegExp(''+mdot+'|'+bull+'|--list--|&nbsp;',"gi"),'');ul.appendChild(li);np=p.nextSibling;while(np){if(np.nodeType==3&&new RegExp('^\\s$','m').test(np.nodeValue)){np=np.nextSibling;continue;}if(search==mdot){if(np.nodeType==1&&new RegExp('^o(\\s+|&nbsp;)').test(np.innerHTML)){if(!prevul){prevul=ul;ul=ed.dom.create("ul");prevul.appendChild(ul);}np.innerHTML=np.innerHTML.replace(/^o/,'');}else{if(prevul){ul=prevul;prevul=null;}if(np.nodeType!=1||np.innerHTML.indexOf(search)!=0)break;}}else{if(np.nodeType!=1||np.innerHTML.indexOf(search)!=0)break;}cp=np.nextSibling;li=ed.dom.create("li");li.innerHTML=np.innerHTML.replace(new RegExp(''+mdot+'|'+bull+'|--list--|&nbsp;',"gi"),'');np.parentNode.removeChild(np);ul.appendChild(li);np=cp;}p.parentNode.replaceChild(ul,p);return true;}}return false;},_clipboardHTML:function(){var div=document.getElementById('_TinyMCE_clipboardHTML');if(!div){var div=document.createElement('DIV');div.id='_TinyMCE_clipboardHTML';with(div.style){visibility='hidden';overflow='hidden';position='absolute';width=1;height=1;}document.body.appendChild(div);}div.innerHTML='';var rng=document.body.createTextRange();rng.moveToElementText(div);rng.execCommand('Paste');var html=div.innerHTML;div.innerHTML='';return html;}});tinymce.PluginManager.add('paste',tinymce.plugins.PastePlugin);})(); \ No newline at end of file (function(){var a=tinymce.each;tinymce.create("tinymce.plugins.PastePlugin",{init:function(c,d){var e=this,b;e.editor=c;e.url=d;e.onPreProcess=new tinymce.util.Dispatcher(e);e.onPostProcess=new tinymce.util.Dispatcher(e);e.onPreProcess.add(e._preProcess);e.onPostProcess.add(e._postProcess);e.onPreProcess.add(function(h,i){c.execCallback("paste_preprocess",h,i)});e.onPostProcess.add(function(h,i){c.execCallback("paste_postprocess",h,i)});function g(i){var h=c.dom;e.onPreProcess.dispatch(e,i);i.node=h.create("div",0,i.content);e.onPostProcess.dispatch(e,i);i.content=c.serializer.serialize(i.node,{getInner:1});if(/<(p|h[1-6]|ul|ol)/.test(i.content)){e._insertBlockContent(c,h,i.content)}else{e._insert(i.content)}}c.addCommand("mceInsertClipboardContent",function(h,i){g(i)});function f(l){var p,k,i,j=c.selection,o=c.dom,h=c.getBody(),m;if(o.get("_mcePaste")){return}p=o.add(h,"div",{id:"_mcePaste"},"&nbsp;");if(h!=c.getDoc().body){m=o.getPos(c.selection.getStart(),h).y}else{m=h.scrollTop}o.setStyles(p,{position:"absolute",left:-10000,top:m,width:1,height:1,overflow:"hidden"});if(tinymce.isIE){i=o.doc.body.createTextRange();i.moveToElementText(p);i.execCommand("Paste");o.remove(p);if(p.innerHTML==="&nbsp;"){return}g({content:p.innerHTML});return tinymce.dom.Event.cancel(l)}else{k=c.selection.getRng();p=p.firstChild;i=c.getDoc().createRange();i.setStart(p,0);i.setEnd(p,1);j.setRng(i);window.setTimeout(function(){var n="";a(o.select("div[id=_mcePaste]").reverse(),function(q){n+=(o.select("> span.Apple-style-span div",q)[0]||o.select("> span.Apple-style-span",q)[0]||q).innerHTML;o.remove(q)});if(k){j.setRng(k)}g({content:n})},0)}}if(c.getParam("paste_auto_cleanup_on_paste",true)){if(tinymce.isOpera||/Firefox\/2/.test(navigator.userAgent)){c.onKeyDown.add(function(h,i){if(((tinymce.isMac?i.metaKey:i.ctrlKey)&&i.keyCode==86)||(i.shiftKey&&i.keyCode==45)){f(i)}})}else{c.onPaste.addToTop(function(h,i){return f(i)})}}if(c.getParam("paste_block_drop")){c.onInit.add(function(){c.dom.bind(c.getBody(),["dragend","dragover","draggesture","dragdrop","drop","drag"],function(h){h.preventDefault();h.stopPropagation();return false})})}e._legacySupport()},getInfo:function(){return{longname:"Paste text/word",author:"Moxiecode Systems AB",authorurl:"http://tinymce.moxiecode.com",infourl:"http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/paste",version:tinymce.majorVersion+"."+tinymce.minorVersion}},_preProcess:function(d,g){var b=this.editor,c=g.content,f,e;function f(h){a(h,function(i){if(i.constructor==RegExp){c=c.replace(i,"")}else{c=c.replace(i[0],i[1])}})}if(/(class=\"?Mso|style=\"[^\"]*\bmso\-|w:WordDocument)/.test(c)||g.wordContent){g.wordContent=true;f([/^\s*(&nbsp;)+/g,/(&nbsp;|<br[^>]*>)+\s*$/g]);if(b.getParam("paste_convert_middot_lists",true)){f([[/<!--\[if !supportLists\]-->/gi,"$&__MCE_ITEM__"],[/(<span[^>]+:\s*symbol[^>]+>)/gi,"$1__MCE_ITEM__"],[/(<span[^>]+mso-list:[^>]+>)/gi,"$1__MCE_ITEM__"]])}f([/<!--[\s\S]+?-->/gi,/<\/?(img|font|meta|link|style|div|v:\w+)[^>]*>/gi,/<\\?\?xml[^>]*>/gi,/<\/?o:[^>]*>/gi,/ (id|name|language|type|on\w+|v:\w+)=\"([^\"]*)\"/gi,/ (id|name|language|type|on\w+|v:\w+)=(\w+)/gi,[/<(\/?)s>/gi,"<$1strike>"],/<script[^>]+>[\s\S]*?<\/script>/gi,[/&nbsp;/g,"\u00a0"]]);if(!b.getParam("paste_retain_style_properties")){f([/<\/?(span)[^>]*>/gi])}}e=b.getParam("paste_strip_class_attributes","all");if(e!="none"){if(e=="all"){f([/ class=\"([^\"]*)\"/gi,/ class=(\w+)/gi])}else{f([/ class=\"(mso[^\"]*)\"/gi,/ class=(mso\w+)/gi])}}if(b.getParam("paste_remove_spans")){f([/<\/?(span)[^>]*>/gi])}g.content=c},_postProcess:function(e,g){var d=this,c=d.editor,f=c.dom,b;if(g.wordContent){a(f.select("a",g.node),function(h){if(!h.href||h.href.indexOf("#_Toc")!=-1){f.remove(h,1)}});if(d.editor.getParam("paste_convert_middot_lists",true)){d._convertLists(e,g)}b=c.getParam("paste_retain_style_properties");if(tinymce.is(b,"string")){b=tinymce.explode(b)}a(f.select("*",g.node),function(l){var m={},j=0,k,n,h;if(b){for(k=0;k<b.length;k++){n=b[k];h=f.getStyle(l,n);if(h){m[n]=h;j++}}}f.setAttrib(l,"style","");if(b&&j>0){f.setStyles(l,m)}else{if(l.nodeName=="SPAN"&&!l.className){f.remove(l,true)}}})}if(c.getParam("paste_remove_styles")||(c.getParam("paste_remove_styles_if_webkit")&&tinymce.isWebKit)){a(f.select("*[style]",g.node),function(h){h.removeAttribute("style");h.removeAttribute("mce_style")})}else{if(tinymce.isWebKit){a(f.select("*",g.node),function(h){h.removeAttribute("mce_style")})}}},_convertLists:function(e,c){var g=e.editor.dom,f,j,b=-1,d,k=[],i,h;a(g.select("p",c.node),function(r){var n,s="",q,o,l,m;for(n=r.firstChild;n&&n.nodeType==3;n=n.nextSibling){s+=n.nodeValue}s=r.innerHTML.replace(/<\/?\w+[^>]*>/gi,"").replace(/&nbsp;/g,"\u00a0");if(/^(__MCE_ITEM__)+[\u2022\u00b7\u00a7\u00d8o]\s*\u00a0*/.test(s)){q="ul"}if(/^__MCE_ITEM__\s*\w+\.\s*\u00a0{2,}/.test(s)){q="ol"}if(q){d=parseFloat(r.style.marginLeft||0);if(d>b){k.push(d)}if(!f||q!=i){f=g.create(q);g.insertAfter(f,r)}else{if(d>b){f=j.appendChild(g.create(q))}else{if(d<b){l=tinymce.inArray(k,d);m=g.getParents(f.parentNode,q);f=m[m.length-1-l]||f}}}a(g.select("span",r),function(t){var p=t.innerHTML.replace(/<\/?\w+[^>]*>/gi,"");if(q=="ul"&&/^[\u2022\u00b7\u00a7\u00d8o]/.test(p)){g.remove(t)}else{if(/^[\s\S]*\w+\.(&nbsp;|\u00a0)*\s*/.test(p)){g.remove(t)}}});o=r.innerHTML;if(q=="ul"){o=r.innerHTML.replace(/__MCE_ITEM__/g,"").replace(/^[\u2022\u00b7\u00a7\u00d8o]\s*(&nbsp;|\u00a0)+\s*/,"")}else{o=r.innerHTML.replace(/__MCE_ITEM__/g,"").replace(/^\s*\w+\.(&nbsp;|\u00a0)+\s*/,"")}j=f.appendChild(g.create("li",0,o));g.remove(r);b=d;i=q}else{f=b=0}});h=c.node.innerHTML;if(h.indexOf("__MCE_ITEM__")!=-1){c.node.innerHTML=h.replace(/__MCE_ITEM__/g,"")}},_insertBlockContent:function(h,e,i){var c,g,d=h.selection,m,j,b,k,f;function l(p){var o;if(tinymce.isIE){o=h.getDoc().body.createTextRange();o.moveToElementText(p);o.collapse(false);o.select()}else{d.select(p,1);d.collapse(false)}}this._insert('<span id="_marker">&nbsp;</span>',1);g=e.get("_marker");c=e.getParent(g,"p,h1,h2,h3,h4,h5,h6,ul,ol,th,td");if(c&&!/TD|TH/.test(c.nodeName)){g=e.split(c,g);a(e.create("div",0,i).childNodes,function(o){m=g.parentNode.insertBefore(o.cloneNode(true),g)});l(m)}else{e.setOuterHTML(g,i);d.select(h.getBody(),1);d.collapse(0)}e.remove("_marker");j=d.getStart();b=e.getViewPort(h.getWin());k=h.dom.getPos(j).y;f=j.clientHeight;if(k<b.y||k+f>b.y+b.h){h.getDoc().body.scrollTop=k<b.y?k:k-b.h+25}},_insert:function(d,b){var c=this.editor;if(!c.selection.isCollapsed()){c.getDoc().execCommand("Delete",false,null)}c.execCommand(tinymce.isGecko?"insertHTML":"mceInsertContent",false,d,{skip_undo:b})},_legacySupport:function(){var c=this,b=c.editor;a(["mcePasteText","mcePasteWord"],function(d){b.addCommand(d,function(){b.windowManager.open({file:c.url+(d=="mcePasteText"?"/pastetext.htm":"/pasteword.htm"),width:parseInt(b.getParam("paste_dialog_width","450")),height:parseInt(b.getParam("paste_dialog_height","400")),inline:1})})});b.addButton("pastetext",{title:"paste.paste_text_desc",cmd:"mcePasteText"});b.addButton("pasteword",{title:"paste.paste_word_desc",cmd:"mcePasteWord"});b.addButton("selectall",{title:"paste.selectall_desc",cmd:"selectall"})}});tinymce.PluginManager.add("paste",tinymce.plugins.PastePlugin)})(); \ No newline at end of file
diff --git a/public/javascripts/tiny_mce/plugins/paste/editor_plugin_src.js b/public/javascripts/tiny_mce/plugins/paste/editor_plugin_src.js
index bb5f5aa..8641519 100755..100644
--- a/public/javascripts/tiny_mce/plugins/paste/editor_plugin_src.js
+++ b/public/javascripts/tiny_mce/plugins/paste/editor_plugin_src.js
@@ -1,81 +1,172 @@
1/** 1/**
2 * $Id: editor_plugin_src.js 919 2008-09-08 20:31:23Z spocke $ 2 * $Id: editor_plugin_src.js 1199 2009-08-18 11:55:59Z spocke $
3 * 3 *
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; 9 var each = tinymce.each;
10 10
11 tinymce.create('tinymce.plugins.PastePlugin', { 11 tinymce.create('tinymce.plugins.PastePlugin', {
12 init : function(ed, url) { 12 init : function(ed, url) {
13 var t = this; 13 var t = this, cb;
14 14
15 t.editor = ed; 15 t.editor = ed;
16 t.url = url;
16 17
17 // Register commands 18 // Setup plugin events
18 ed.addCommand('mcePasteText', function(ui, v) { 19 t.onPreProcess = new tinymce.util.Dispatcher(t);
19 if (ui) { 20 t.onPostProcess = new tinymce.util.Dispatcher(t);
20 if ((ed.getParam('paste_use_dialog', true)) || (!tinymce.isIE)) { 21
21 ed.windowManager.open({ 22 // Register default handlers
22 file : url + '/pastetext.htm', 23 t.onPreProcess.add(t._preProcess);
23 width : 450, 24 t.onPostProcess.add(t._postProcess);
24 height : 400, 25
25 inline : 1 26 // Register optional preprocess handler
26 }, { 27 t.onPreProcess.add(function(pl, o) {
27 plugin_url : url 28 ed.execCallback('paste_preprocess', pl, o);
28 });
29 } else
30 t._insertText(clipboardData.getData("Text"), true);
31 } else
32 t._insertText(v.html, v.linebreaks);
33 }); 29 });
34 30
35 ed.addCommand('mcePasteWord', function(ui, v) { 31 // Register optional postprocess
36 if (ui) { 32 t.onPostProcess.add(function(pl, o) {
37 if ((ed.getParam('paste_use_dialog', true)) || (!tinymce.isIE)) { 33 ed.execCallback('paste_postprocess', pl, o);
38 ed.windowManager.open({
39 file : url + '/pasteword.htm',
40 width : 450,
41 height : 400,
42 inline : 1
43 }, {
44 plugin_url : url
45 });
46 } else
47 t._insertText(t._clipboardHTML());
48 } else
49 t._insertWordContent(v);
50 }); 34 });
51 35
52 ed.addCommand('mceSelectAll', function() { 36 // This function executes the process handlers and inserts the contents
53 ed.execCommand('selectall'); 37 function process(o) {
38 var dom = ed.dom;
39
40 // Execute pre process handlers
41 t.onPreProcess.dispatch(t, o);
42
43 // Create DOM structure
44 o.node = dom.create('div', 0, o.content);
45
46 // Execute post process handlers
47 t.onPostProcess.dispatch(t, o);
48
49 // Serialize content
50 o.content = ed.serializer.serialize(o.node, {getInner : 1});
51
52 // Insert cleaned content. We need to handle insertion of contents containing block elements separately
53 if (/<(p|h[1-6]|ul|ol)/.test(o.content))
54 t._insertBlockContent(ed, dom, o.content);
55 else
56 t._insert(o.content);
57 };
58
59 // Add command for external usage
60 ed.addCommand('mceInsertClipboardContent', function(u, o) {
61 process(o);
54 }); 62 });
55 63
56 // Register buttons 64 // This function grabs the contents from the clipboard by adding a
57 ed.addButton('pastetext', {title : 'paste.paste_text_desc', cmd : 'mcePasteText', ui : true}); 65 // hidden div and placing the caret inside it and after the browser paste
58 ed.addButton('pasteword', {title : 'paste.paste_word_desc', cmd : 'mcePasteWord', ui : true}); 66 // is done it grabs that contents and processes that
59 ed.addButton('selectall', {title : 'paste.selectall_desc', cmd : 'mceSelectAll'}); 67 function grabContent(e) {
68 var n, or, rng, sel = ed.selection, dom = ed.dom, body = ed.getBody(), posY;
69
70 if (dom.get('_mcePaste'))
71 return;
72
73 // Create container to paste into
74 n = dom.add(body, 'div', {id : '_mcePaste'}, '&nbsp;');
60 75
61 if (ed.getParam("paste_auto_cleanup_on_paste", false)) { 76 // If contentEditable mode we need to find out the position of the closest element
62 ed.onPaste.add(function(ed, e) { 77 if (body != ed.getDoc().body)
63 return t._handlePasteEvent(e) 78 posY = dom.getPos(ed.selection.getStart(), body).y;
79 else
80 posY = body.scrollTop;
81
82 // Styles needs to be applied after the element is added to the document since WebKit will otherwise remove all styles
83 dom.setStyles(n, {
84 position : 'absolute',
85 left : -10000,
86 top : posY,
87 width : 1,
88 height : 1,
89 overflow : 'hidden'
64 }); 90 });
91
92 if (tinymce.isIE) {
93 // Select the container
94 rng = dom.doc.body.createTextRange();
95 rng.moveToElementText(n);
96 rng.execCommand('Paste');
97
98 // Remove container
99 dom.remove(n);
100
101 // Check if the contents was changed, if it wasn't then clipboard extraction failed probably due
102 // to IE security settings so we pass the junk though better than nothing right
103 if (n.innerHTML === '&nbsp;')
104 return;
105
106 // Process contents
107 process({content : n.innerHTML});
108
109 // Block the real paste event
110 return tinymce.dom.Event.cancel(e);
111 } else {
112 or = ed.selection.getRng();
113
114 // Move caret into hidden div
115 n = n.firstChild;
116 rng = ed.getDoc().createRange();
117 rng.setStart(n, 0);
118 rng.setEnd(n, 1);
119 sel.setRng(rng);
120
121 // Wait a while and grab the pasted contents
122 window.setTimeout(function() {
123 var h = '';
124
125 // WebKit will split the div into multiple ones so this will loop through then all and join them to get the whole HTML string
126 each(dom.select('div[id=_mcePaste]').reverse(), function(n) {
127 h += (dom.select('> span.Apple-style-span div', n)[0] || dom.select('> span.Apple-style-span', n)[0] || n).innerHTML;
128 dom.remove(n);
129 });
130
131 // Restore the old selection
132 if (or)
133 sel.setRng(or);
134
135 process({content : h});
136 }, 0);
137 }
138 };
139
140 // Check if we should use the new auto process method
141 if (ed.getParam('paste_auto_cleanup_on_paste', true)) {
142 // Is it's Opera or older FF use key handler
143 if (tinymce.isOpera || /Firefox\/2/.test(navigator.userAgent)) {
144 ed.onKeyDown.add(function(ed, e) {
145 if (((tinymce.isMac ? e.metaKey : e.ctrlKey) && e.keyCode == 86) || (e.shiftKey && e.keyCode == 45))
146 grabContent(e);
147 });
148 } else {
149 // Grab contents on paste event on Gecko and WebKit
150 ed.onPaste.addToTop(function(ed, e) {
151 return grabContent(e);
152 });
153 }
65 } 154 }
66 155
67 if (!tinymce.isIE && ed.getParam("paste_auto_cleanup_on_paste", false)) { 156 // Block all drag/drop events
68 // Force paste dialog if non IE browser 157 if (ed.getParam('paste_block_drop')) {
69 ed.onKeyDown.add(function(ed, e) { 158 ed.onInit.add(function() {
70 if (e.ctrlKey && e.keyCode == 86) { 159 ed.dom.bind(ed.getBody(), ['dragend', 'dragover', 'draggesture', 'dragdrop', 'drop', 'drag'], function(e) {
71 window.setTimeout(function() { 160 e.preventDefault();
72 ed.execCommand("mcePasteText", true); 161 e.stopPropagation();
73 }, 1);
74 162
75 Event.cancel(e); 163 return false;
76 } 164 });
77 }); 165 });
78 } 166 }
167
168 // Add legacy support
169 t._legacySupport();
79 }, 170 },
80 171
81 getInfo : function() { 172 getInfo : function() {
@@ -88,304 +179,331 @@
88 }; 179 };
89 }, 180 },
90 181
91 // Private methods 182 _preProcess : function(pl, o) {
92 183 var ed = this.editor, h = o.content, process, stripClass;
93 _handlePasteEvent : function(e) {
94 var html = this._clipboardHTML(), ed = this.editor, sel = ed.selection, r;
95
96 // Removes italic, strong etc, the if was needed due to bug #1437114
97 if (ed && (r = sel.getRng()) && r.text.length > 0)
98 ed.execCommand('delete');
99
100 if (html && html.length > 0)
101 ed.execCommand('mcePasteWord', false, html);
102
103 return Event.cancel(e);
104 },
105
106 _insertText : function(content, bLinebreaks) {
107 content = this.editor.dom.encode(content);
108
109 if (content && content.length > 0) {
110 // Delete any highlighted text before pasting
111 if (!this.editor.selection.isCollapsed())
112 this.editor.execCommand("Delete");
113 184
114 if (bLinebreaks) { 185 //console.log('Before preprocess:' + o.content);
115 // Special paragraph treatment
116 if (this.editor.getParam("paste_create_paragraphs", true)) {
117 var rl = this.editor.getParam("paste_replace_list", '\u2122,<sup>TM</sup>,\u2026,...,\u201c|\u201d,",\u2019,\',\u2013|\u2014|\u2015|\u2212,-').split(',');
118 for (var i=0; i<rl.length; i+=2)
119 content = content.replace(new RegExp(rl[i], 'gi'), rl[i+1]);
120 186
121 content = content.replace(/\r\n\r\n/g, '</p><p>'); 187 function process(items) {
122 content = content.replace(/\r\r/g, '</p><p>'); 188 each(items, function(v) {
123 content = content.replace(/\n\n/g, '</p><p>'); 189 // Remove or replace
124 190 if (v.constructor == RegExp)
125 // Has paragraphs 191 h = h.replace(v, '');
126 if ((pos = content.indexOf('</p><p>')) != -1) { 192 else
127 this.editor.execCommand("Delete"); 193 h = h.replace(v[0], v[1]);
128 194 });
129 var node = this.editor.selection.getNode(); 195 };
130
131 // Get list of elements to break
132 var breakElms = [];
133 196
134 do { 197 // Detect Word content and process it more aggressive
135 if (node.nodeType == 1) { 198 if (/(class=\"?Mso|style=\"[^\"]*\bmso\-|w:WordDocument)/.test(h) || o.wordContent) {
136 // Don't break tables and break at body 199 o.wordContent = true; // Mark the pasted contents as word specific content
137 if (node.nodeName == "TD" || node.nodeName == "BODY") 200 //console.log('Word contents detected.');
138 break;
139
140 breakElms[breakElms.length] = node;
141 }
142 } while(node = node.parentNode);
143 201
144 var before = "", after = "</p>"; 202 // Process away some basic content
145 before += content.substring(0, pos); 203 process([
204 /^\s*(&nbsp;)+/g, // nbsp entities at the start of contents
205 /(&nbsp;|<br[^>]*>)+\s*$/g // nbsp entities at the end of contents
206 ]);
146 207
147 for (var i=0; i<breakElms.length; i++) { 208 if (ed.getParam('paste_convert_middot_lists', true)) {
148 before += "</" + breakElms[i].nodeName + ">"; 209 process([
149 after += "<" + breakElms[(breakElms.length-1)-i].nodeName + ">"; 210 [/<!--\[if !supportLists\]-->/gi, '$&__MCE_ITEM__'], // Convert supportLists to a list item marker
150 } 211 [/(<span[^>]+:\s*symbol[^>]+>)/gi, '$1__MCE_ITEM__'], // Convert symbol spans to list items
212 [/(<span[^>]+mso-list:[^>]+>)/gi, '$1__MCE_ITEM__'] // Convert mso-list to item marker
213 ]);
214 }
151 215
152 before += "<p>"; 216 process([
153 content = before + content.substring(pos+7) + after; 217 /<!--[\s\S]+?-->/gi, // Word comments
154 } 218 /<\/?(img|font|meta|link|style|div|v:\w+)[^>]*>/gi, // Remove some tags including VML content
155 } 219 /<\\?\?xml[^>]*>/gi, // XML namespace declarations
220 /<\/?o:[^>]*>/gi, // MS namespaced elements <o:tag>
221 / (id|name|language|type|on\w+|v:\w+)=\"([^\"]*)\"/gi, // on.., class, style and language attributes with quotes
222 / (id|name|language|type|on\w+|v:\w+)=(\w+)/gi, // on.., class, style and language attributes without quotes (IE)
223 [/<(\/?)s>/gi, '<$1strike>'], // Convert <s> into <strike> for line-though
224 /<script[^>]+>[\s\S]*?<\/script>/gi, // All scripts elements for msoShowComment for example
225 [/&nbsp;/g, '\u00a0'] // Replace nsbp entites to char since it's easier to handle
226 ]);
156 227
157 if (this.editor.getParam("paste_create_linebreaks", true)) { 228 // Remove all spans if no styles is to be retained
158 content = content.replace(/\r\n/g, '<br />'); 229 if (!ed.getParam('paste_retain_style_properties')) {
159 content = content.replace(/\r/g, '<br />'); 230 process([
160 content = content.replace(/\n/g, '<br />'); 231 /<\/?(span)[^>]*>/gi
161 } 232 ]);
162 } 233 }
234 }
163 235
164 this.editor.execCommand("mceInsertRawHTML", false, content); 236 // Allow for class names to be retained if desired; either all, or just the ones from Word
237 // Note that the paste_strip_class_attributes: 'none, verify_css_classes: true is also a good variation.
238 stripClass = ed.getParam('paste_strip_class_attributes', 'all');
239 if (stripClass != 'none') {
240 if (stripClass == 'all') {
241 process([
242 / class=\"([^\"]*)\"/gi, // class attributes with quotes
243 / class=(\w+)/gi // class attributes without quotes (IE)
244 ]);
245 } else { // Only strip the 'mso*' classes
246 process([
247 / class=\"(mso[^\"]*)\"/gi, // class attributes with quotes
248 / class=(mso\w+)/gi // class attributes without quotes (IE)
249 ]);
250 }
165 } 251 }
166 },
167 252
168 _insertWordContent : function(content) { 253 // Remove spans option
169 var t = this, ed = t.editor; 254 if (ed.getParam('paste_remove_spans')) {
255 process([
256 /<\/?(span)[^>]*>/gi
257 ]);
258 }
170 259
171 if (content && content.length > 0) { 260 //console.log('After preprocess:' + h);
172 // Cleanup Word content
173 var bull = String.fromCharCode(8226);
174 var middot = String.fromCharCode(183);
175 261
176 if (ed.getParam('paste_insert_word_content_callback')) 262 o.content = h;
177 content = ed.execCallback('paste_insert_word_content_callback', 'before', content); 263 },
178 264
179 var rl = ed.getParam("paste_replace_list", '\u2122,<sup>TM</sup>,\u2026,...,\x93|\x94|\u201c|\u201d,",\x60|\x91|\x92|\u2018|\u2019,\',\u2013|\u2014|\u2015|\u2212,-').split(','); 265 /**
180 for (var i=0; i<rl.length; i+=2) 266 * Various post process items.
181 content = content.replace(new RegExp(rl[i], 'gi'), rl[i+1]); 267 */
268 _postProcess : function(pl, o) {
269 var t = this, ed = t.editor, dom = ed.dom, styleProps;
182 270
183 if (this.editor.getParam("paste_convert_headers_to_strong", false)) { 271 if (o.wordContent) {
184 content = content.replace(new RegExp('<p class=MsoHeading.*?>(.*?)<\/p>', 'gi'), '<p><b>$1</b></p>'); 272 // Remove named anchors or TOC links
185 } 273 each(dom.select('a', o.node), function(a) {
274 if (!a.href || a.href.indexOf('#_Toc') != -1)
275 dom.remove(a, 1);
276 });
186 277
187 content = content.replace(new RegExp('tab-stops: list [0-9]+.0pt">', 'gi'), '">' + "--list--"); 278 if (t.editor.getParam('paste_convert_middot_lists', true))
188 content = content.replace(new RegExp(bull + "(.*?)<BR>", "gi"), "<p>" + middot + "$1</p>"); 279 t._convertLists(pl, o);
189 content = content.replace(new RegExp('<SPAN style="mso-list: Ignore">', 'gi'), "<span>" + bull); // Covert to bull list
190 content = content.replace(/<o:p><\/o:p>/gi, "");
191 content = content.replace(new RegExp('<br style="page-break-before: always;.*>', 'gi'), '-- page break --'); // Replace pagebreaks
192 content = content.replace(/<!--([\s\S]*?)-->|<style>[\s\S]*?<\/style>/g, ""); // Word comments
193 content = content.replace(/<(meta|link)[^>]+>/g, ""); // Header elements
194 280
195 if (this.editor.getParam("paste_remove_spans", true)) 281 // Process styles
196 content = content.replace(/<\/?span[^>]*>/gi, ""); 282 styleProps = ed.getParam('paste_retain_style_properties'); // retained properties
197 283
198 if (this.editor.getParam("paste_remove_styles", true)) 284 // If string property then split it
199 content = content.replace(new RegExp('<(\\w[^>]*) style="([^"]*)"([^>]*)', 'gi'), "<$1$3"); 285 if (tinymce.is(styleProps, 'string'))
286 styleProps = tinymce.explode(styleProps);
200 287
201 content = content.replace(/<\/?font[^>]*>/gi, ""); 288 // Retains some style properties
289 each(dom.select('*', o.node), function(el) {
290 var newStyle = {}, npc = 0, i, sp, sv;
202 291
203 // Strips class attributes. 292 // Store a subset of the existing styles
204 switch (this.editor.getParam("paste_strip_class_attributes", "all")) { 293 if (styleProps) {
205 case "all": 294 for (i = 0; i < styleProps.length; i++) {
206 content = content.replace(/<(\w[^>]*) class=([^ |>]*)([^>]*)/gi, "<$1$3"); 295 sp = styleProps[i];
207 break; 296 sv = dom.getStyle(el, sp);
208 297
209 case "mso": 298 if (sv) {
210 content = content.replace(new RegExp('<(\\w[^>]*) class="?mso([^ |>]*)([^>]*)', 'gi'), "<$1$3"); 299 newStyle[sp] = sv;
211 break; 300 npc++;
212 } 301 }
302 }
303 }
213 304
214 content = content.replace(new RegExp('href="?' + this._reEscape("" + document.location) + '', 'gi'), 'href="' + this.editor.documentBaseURI.getURI()); 305 // Remove all of the existing styles
215 content = content.replace(/<(\w[^>]*) lang=([^ |>]*)([^>]*)/gi, "<$1$3"); 306 dom.setAttrib(el, 'style', '');
216 content = content.replace(/<\\?\?xml[^>]*>/gi, "");
217 content = content.replace(/<\/?\w+:[^>]*>/gi, "");
218 content = content.replace(/-- page break --\s*<p>&nbsp;<\/p>/gi, ""); // Remove pagebreaks
219 content = content.replace(/-- page break --/gi, ""); // Remove pagebreaks
220 307
221 // content = content.replace(/\/?&nbsp;*/gi, ""); &nbsp; 308 if (styleProps && npc > 0)
222 // content = content.replace(/<p>&nbsp;<\/p>/gi, ''); 309 dom.setStyles(el, newStyle); // Add back the stored subset of styles
310 else // Remove empty span tags that do not have class attributes
311 if (el.nodeName == 'SPAN' && !el.className)
312 dom.remove(el, true);
313 });
314 }
223 315
224 if (!this.editor.getParam('force_p_newlines')) { 316 // Remove all style information or only specifically on WebKit to avoid the style bug on that browser
225 content = content.replace('', '' ,'gi'); 317 if (ed.getParam("paste_remove_styles") || (ed.getParam("paste_remove_styles_if_webkit") && tinymce.isWebKit)) {
226 content = content.replace('</p>', '<br /><br />' ,'gi'); 318 each(dom.select('*[style]', o.node), function(el) {
319 el.removeAttribute('style');
320 el.removeAttribute('mce_style');
321 });
322 } else {
323 if (tinymce.isWebKit) {
324 // We need to compress the styles on WebKit since if you paste <img border="0" /> it will become <img border="0" style="... lots of junk ..." />
325 // Removing the mce_style that contains the real value will force the Serializer engine to compress the styles
326 each(dom.select('*', o.node), function(el) {
327 el.removeAttribute('mce_style');
328 });
227 } 329 }
330 }
331 },
228 332
229 if (!tinymce.isIE && !this.editor.getParam('force_p_newlines')) { 333 /**
230 content = content.replace(/<\/?p[^>]*>/gi, ""); 334 * Converts the most common bullet and number formats in Office into a real semantic UL/LI list.
231 } 335 */
336 _convertLists : function(pl, o) {
337 var dom = pl.editor.dom, listElm, li, lastMargin = -1, margin, levels = [], lastType, html;
232 338
233 content = content.replace(/<\/?div[^>]*>/gi, ""); 339 // Convert middot lists into real semantic lists
340 each(dom.select('p', o.node), function(p) {
341 var sib, val = '', type, html, idx, parents;
234 342
235 // Convert all middlot lists to UL lists 343 // Get text node value at beginning of paragraph
236 if (this.editor.getParam("paste_convert_middot_lists", true)) { 344 for (sib = p.firstChild; sib && sib.nodeType == 3; sib = sib.nextSibling)
237 var div = ed.dom.create("div", null, content); 345 val += sib.nodeValue;
238 346
239 // Convert all middot paragraphs to li elements 347 val = p.innerHTML.replace(/<\/?\w+[^>]*>/gi, '').replace(/&nbsp;/g, '\u00a0');
240 var className = this.editor.getParam("paste_unindented_list_class", "unIndentedList");
241 348
242 while (this._convertMiddots(div, "--list--")) ; // bull 349 // Detect unordered lists look for bullets
243 while (this._convertMiddots(div, middot, className)) ; // Middot 350 if (/^(__MCE_ITEM__)+[\u2022\u00b7\u00a7\u00d8o]\s*\u00a0*/.test(val))
244 while (this._convertMiddots(div, bull)) ; // bull 351 type = 'ul';
245 352
246 content = div.innerHTML; 353 // Detect ordered lists 1., a. or ixv.
247 } 354 if (/^__MCE_ITEM__\s*\w+\.\s*\u00a0{2,}/.test(val))
355 type = 'ol';
248 356
249 // Replace all headers with strong and fix some other issues 357 // Check if node value matches the list pattern: o&nbsp;&nbsp;
250 if (this.editor.getParam("paste_convert_headers_to_strong", false)) { 358 if (type) {
251 content = content.replace(/<h[1-6]>&nbsp;<\/h[1-6]>/gi, '<p>&nbsp;&nbsp;</p>'); 359 margin = parseFloat(p.style.marginLeft || 0);
252 content = content.replace(/<h[1-6]>/gi, '<p><b>');
253 content = content.replace(/<\/h[1-6]>/gi, '</b></p>');
254 content = content.replace(/<b>&nbsp;<\/b>/gi, '<b>&nbsp;&nbsp;</b>');
255 content = content.replace(/^(&nbsp;)*/gi, '');
256 }
257 360
258 content = content.replace(/--list--/gi, ""); // Remove --list-- 361 if (margin > lastMargin)
362 levels.push(margin);
259 363
260 if (ed.getParam('paste_insert_word_content_callback')) 364 if (!listElm || type != lastType) {
261 content = ed.execCallback('paste_insert_word_content_callback', 'after', content); 365 listElm = dom.create(type);
366 dom.insertAfter(listElm, p);
367 } else {
368 // Nested list element
369 if (margin > lastMargin) {
370 listElm = li.appendChild(dom.create(type));
371 } else if (margin < lastMargin) {
372 // Find parent level based on margin value
373 idx = tinymce.inArray(levels, margin);
374 parents = dom.getParents(listElm.parentNode, type);
375 listElm = parents[parents.length - 1 - idx] || listElm;
376 }
377 }
262 378
263 // Insert cleaned content 379 // Remove middot or number spans if they exists
264 this.editor.execCommand("mceInsertContent", false, content); 380 each(dom.select('span', p), function(span) {
381 var html = span.innerHTML.replace(/<\/?\w+[^>]*>/gi, '');
265 382
266 if (this.editor.getParam('paste_force_cleanup_wordpaste', true)) { 383 // Remove span with the middot or the number
267 var ed = this.editor; 384 if (type == 'ul' && /^[\u2022\u00b7\u00a7\u00d8o]/.test(html))
385 dom.remove(span);
386 else if (/^[\s\S]*\w+\.(&nbsp;|\u00a0)*\s*/.test(html))
387 dom.remove(span);
388 });
268 389
269 window.setTimeout(function() { 390 html = p.innerHTML;
270 ed.execCommand("mceCleanup");
271 }, 1); // Do normal cleanup detached from this thread
272 }
273 }
274 },
275 391
276 _reEscape : function(s) { 392 // Remove middot/list items
277 var l = "?.\\*[](){}+^$:"; 393 if (type == 'ul')
278 var o = ""; 394 html = p.innerHTML.replace(/__MCE_ITEM__/g, '').replace(/^[\u2022\u00b7\u00a7\u00d8o]\s*(&nbsp;|\u00a0)+\s*/, '');
395 else
396 html = p.innerHTML.replace(/__MCE_ITEM__/g, '').replace(/^\s*\w+\.(&nbsp;|\u00a0)+\s*/, '');
279 397
280 for (var i=0; i<s.length; i++) { 398 // Create li and add paragraph data into the new li
281 var c = s.charAt(i); 399 li = listElm.appendChild(dom.create('li', 0, html));
400 dom.remove(p);
282 401
283 if (l.indexOf(c) != -1) 402 lastMargin = margin;
284 o += '\\' + c; 403 lastType = type;
285 else 404 } else
286 o += c; 405 listElm = lastMargin = 0; // End list element
287 } 406 });
288 407
289 return o; 408 // Remove any left over makers
409 html = o.node.innerHTML;
410 if (html.indexOf('__MCE_ITEM__') != -1)
411 o.node.innerHTML = html.replace(/__MCE_ITEM__/g, '');
290 }, 412 },
291 413
292 _convertMiddots : function(div, search, class_name) { 414 /**
293 var ed = this.editor, mdot = String.fromCharCode(183), bull = String.fromCharCode(8226); 415 * This method will split the current block parent and insert the contents inside the split position.
294 var nodes, prevul, i, p, ul, li, np, cp, li; 416 * This logic can be improved so text nodes at the start/end remain in the start/end block elements
295 417 */
296 nodes = div.getElementsByTagName("p"); 418 _insertBlockContent : function(ed, dom, content) {
297 for (i=0; i<nodes.length; i++) { 419 var parentBlock, marker, sel = ed.selection, last, elm, vp, y, elmHeight;
298 p = nodes[i];
299 420
300 // Is middot 421 function select(n) {
301 if (p.innerHTML.indexOf(search) == 0) { 422 var r;
302 ul = ed.dom.create("ul");
303 423
304 if (class_name) 424 if (tinymce.isIE) {
305 ul.className = class_name; 425 r = ed.getDoc().body.createTextRange();
426 r.moveToElementText(n);
427 r.collapse(false);
428 r.select();
429 } else {
430 sel.select(n, 1);
431 sel.collapse(false);
432 }
433 };
306 434
307 // Add the first one 435 // Insert a marker for the caret position
308 li = ed.dom.create("li"); 436 this._insert('<span id="_marker">&nbsp;</span>', 1);
309 li.innerHTML = p.innerHTML.replace(new RegExp('' + mdot + '|' + bull + '|--list--|&nbsp;', "gi"), ''); 437 marker = dom.get('_marker');
310 ul.appendChild(li); 438 parentBlock = dom.getParent(marker, 'p,h1,h2,h3,h4,h5,h6,ul,ol,th,td');
311 439
312 // Add the rest 440 // If it's a parent block but not a table cell
313 np = p.nextSibling; 441 if (parentBlock && !/TD|TH/.test(parentBlock.nodeName)) {
314 while (np) { 442 // Split parent block
315 // If the node is whitespace, then 443 marker = dom.split(parentBlock, marker);
316 // ignore it and continue on.
317 if (np.nodeType == 3 && new RegExp('^\\s$', 'm').test(np.nodeValue)) {
318 np = np.nextSibling;
319 continue;
320 }
321 444
322 if (search == mdot) { 445 // Insert nodes before the marker
323 if (np.nodeType == 1 && new RegExp('^o(\\s+|&nbsp;)').test(np.innerHTML)) { 446 each(dom.create('div', 0, content).childNodes, function(n) {
324 // Second level of nesting 447 last = marker.parentNode.insertBefore(n.cloneNode(true), marker);
325 if (!prevul) { 448 });
326 prevul = ul;
327 ul = ed.dom.create("ul");
328 prevul.appendChild(ul);
329 }
330 np.innerHTML = np.innerHTML.replace(/^o/, '');
331 } else {
332 // Pop the stack if we're going back up to the first level
333 if (prevul) {
334 ul = prevul;
335 prevul = null;
336 }
337 // Not element or middot paragraph
338 if (np.nodeType != 1 || np.innerHTML.indexOf(search) != 0)
339 break;
340 }
341 } else {
342 // Not element or middot paragraph
343 if (np.nodeType != 1 || np.innerHTML.indexOf(search) != 0)
344 break;
345 }
346 449
347 cp = np.nextSibling; 450 // Move caret after marker
348 li = ed.dom.create("li"); 451 select(last);
349 li.innerHTML = np.innerHTML.replace(new RegExp('' + mdot + '|' + bull + '|--list--|&nbsp;', "gi"), ''); 452 } else {
350 np.parentNode.removeChild(np); 453 dom.setOuterHTML(marker, content);
351 ul.appendChild(li); 454 sel.select(ed.getBody(), 1);
352 np = cp; 455 sel.collapse(0);
353 } 456 }
354 457
355 p.parentNode.replaceChild(ul, p); 458 dom.remove('_marker'); // Remove marker if it's left
356 459
357 return true; 460 // Get element, position and height
358 } 461 elm = sel.getStart();
359 } 462 vp = dom.getViewPort(ed.getWin());
463 y = ed.dom.getPos(elm).y;
464 elmHeight = elm.clientHeight;
360 465
361 return false; 466 // Is element within viewport if not then scroll it into view
467 if (y < vp.y || y + elmHeight > vp.y + vp.h)
468 ed.getDoc().body.scrollTop = y < vp.y ? y : y - vp.h + 25;
362 }, 469 },
363 470
364 _clipboardHTML : function() { 471 /**
365 var div = document.getElementById('_TinyMCE_clipboardHTML'); 472 * Inserts the specified contents at the caret position.
473 */
474 _insert : function(h, skip_undo) {
475 var ed = this.editor;
366 476
367 if (!div) { 477 // First delete the contents seems to work better on WebKit
368 var div = document.createElement('DIV'); 478 if (!ed.selection.isCollapsed())
369 div.id = '_TinyMCE_clipboardHTML'; 479 ed.getDoc().execCommand('Delete', false, null);
370 480
371 with (div.style) { 481 // It's better to use the insertHTML method on Gecko since it will combine paragraphs correctly before inserting the contents
372 visibility = 'hidden'; 482 ed.execCommand(tinymce.isGecko ? 'insertHTML' : 'mceInsertContent', false, h, {skip_undo : skip_undo});
373 overflow = 'hidden'; 483 },
374 position = 'absolute';
375 width = 1;
376 height = 1;
377 }
378 484
379 document.body.appendChild(div); 485 /**
380 } 486 * This method will open the old style paste dialogs. Some users might want the old behavior but still use the new cleanup engine.
487 */
488 _legacySupport : function() {
489 var t = this, ed = t.editor;
490
491 // Register commands for backwards compatibility
492 each(['mcePasteText', 'mcePasteWord'], function(cmd) {
493 ed.addCommand(cmd, function() {
494 ed.windowManager.open({
495 file : t.url + (cmd == 'mcePasteText' ? '/pastetext.htm' : '/pasteword.htm'),
496 width : parseInt(ed.getParam("paste_dialog_width", "450")),
497 height : parseInt(ed.getParam("paste_dialog_height", "400")),
498 inline : 1
499 });
500 });
501 });
381 502
382 div.innerHTML = ''; 503 // Register buttons for backwards compatibility
383 var rng = document.body.createTextRange(); 504 ed.addButton('pastetext', {title : 'paste.paste_text_desc', cmd : 'mcePasteText'});
384 rng.moveToElementText(div); 505 ed.addButton('pasteword', {title : 'paste.paste_word_desc', cmd : 'mcePasteWord'});
385 rng.execCommand('Paste'); 506 ed.addButton('selectall', {title : 'paste.selectall_desc', cmd : 'selectall'});
386 var html = div.innerHTML;
387 div.innerHTML = '';
388 return html;
389 } 507 }
390 }); 508 });
391 509
diff --git a/public/javascripts/tiny_mce/plugins/paste/js/pastetext.js b/public/javascripts/tiny_mce/plugins/paste/js/pastetext.js
index 326bb16..c524f9e 100755..100644
--- a/public/javascripts/tiny_mce/plugins/paste/js/pastetext.js
+++ b/public/javascripts/tiny_mce/plugins/paste/js/pastetext.js
@@ -1,42 +1,36 @@
1tinyMCEPopup.requireLangPack(); 1tinyMCEPopup.requireLangPack();
2 2
3function saveContent() { 3var PasteTextDialog = {
4 if (document.forms[0].htmlSource.value == '') { 4 init : function() {
5 tinyMCEPopup.close(); 5 this.resize();
6 return false; 6 },
7 }
8
9 tinyMCEPopup.execCommand('mcePasteText', false, {
10 html : document.forms[0].htmlSource.value,
11 linebreaks : document.forms[0].linebreaks.checked
12 });
13 7
14 tinyMCEPopup.close(); 8 insert : function() {
15} 9 var h = tinyMCEPopup.dom.encode(document.getElementById('content').value), lines;
16 10
17function onLoadInit() { 11 // Convert linebreaks into paragraphs
18 tinyMCEPopup.resizeToInnerSize(); 12 if (document.getElementById('linebreaks').checked) {
13 lines = h.split(/\r?\n/);
14 if (lines.length > 1) {
15 h = '';
16 tinymce.each(lines, function(row) {
17 h += '<p>' + row + '</p>';
18 });
19 }
20 }
19 21
20 // Remove Gecko spellchecking 22 tinyMCEPopup.editor.execCommand('mceInsertClipboardContent', false, {content : h});
21 if (tinymce.isGecko) 23 tinyMCEPopup.close();
22 document.body.spellcheck = tinyMCEPopup.getParam("gecko_spellcheck"); 24 },
23 25
24 resizeInputs(); 26 resize : function() {
25} 27 var vp = tinyMCEPopup.dom.getViewPort(window), el;
26 28
27var wHeight=0, wWidth=0, owHeight=0, owWidth=0; 29 el = document.getElementById('content');
28 30
29function resizeInputs() { 31 el.style.width = (vp.w - 20) + 'px';
30 if (!tinymce.isIE) { 32 el.style.height = (vp.h - 90) + 'px';
31 wHeight = self.innerHeight-80;
32 wWidth = self.innerWidth-17;
33 } else {
34 wHeight = document.body.clientHeight-80;
35 wWidth = document.body.clientWidth-17;
36 } 33 }
34};
37 35
38 document.forms[0].htmlSource.style.height = Math.abs(wHeight) + 'px'; 36tinyMCEPopup.onInit.add(PasteTextDialog.init, PasteTextDialog);
39 document.forms[0].htmlSource.style.width = Math.abs(wWidth) + 'px';
40}
41
42tinyMCEPopup.onInit.add(onLoadInit); \ No newline at end of file
diff --git a/public/javascripts/tiny_mce/plugins/paste/js/pasteword.js b/public/javascripts/tiny_mce/plugins/paste/js/pasteword.js
index 6701b99..a52731c 100755..100644
--- a/public/javascripts/tiny_mce/plugins/paste/js/pasteword.js
+++ b/public/javascripts/tiny_mce/plugins/paste/js/pasteword.js
@@ -1,56 +1,51 @@
1tinyMCEPopup.requireLangPack(); 1tinyMCEPopup.requireLangPack();
2 2
3function saveContent() { 3var PasteWordDialog = {
4 var html = document.getElementById("frmData").contentWindow.document.body.innerHTML; 4 init : function() {
5 var ed = tinyMCEPopup.editor, el = document.getElementById('iframecontainer'), ifr, doc, css, cssHTML = '';
5 6
6 if (html == ''){ 7 // Create iframe
7 tinyMCEPopup.close(); 8 el.innerHTML = '<iframe id="iframe" src="javascript:\'\';" frameBorder="0" style="border: 1px solid gray"></iframe>';
8 return false; 9 ifr = document.getElementById('iframe');
9 } 10 doc = ifr.contentWindow.document;
10
11 tinyMCEPopup.execCommand('mcePasteWord', false, html);
12 tinyMCEPopup.close();
13}
14 11
15function onLoadInit() { 12 // Force absolute CSS urls
16 tinyMCEPopup.resizeToInnerSize(); 13 css = [ed.baseURI.toAbsolute("themes/" + ed.settings.theme + "/skins/" + ed.settings.skin + "/content.css")];
14 css = css.concat(tinymce.explode(ed.settings.content_css) || []);
15 tinymce.each(css, function(u) {
16 cssHTML += '<link href="' + ed.documentBaseURI.toAbsolute('' + u) + '" rel="stylesheet" type="text/css" />';
17 });
17 18
18 // Fix for endless reloading in FF 19 // Write content into iframe
19 window.setTimeout(createIFrame, 10); 20 doc.open();
20} 21 doc.write('<html><head>' + cssHTML + '</head><body class="mceContentBody" spellcheck="false"></body></html>');
22 doc.close();
21 23
22function createIFrame() { 24 doc.designMode = 'on';
23 document.getElementById('iframecontainer').innerHTML = '<iframe id="frmData" name="frmData" class="sourceIframe" src="blank.htm" height="280" width="400" frameborder="0" style="background-color:#FFFFFF; width:100%;" dir="ltr" wrap="soft"></iframe>'; 25 this.resize();
24}
25 26
26var wHeight=0, wWidth=0, owHeight=0, owWidth=0; 27 window.setTimeout(function() {
28 ifr.contentWindow.focus();
29 }, 10);
30 },
27 31
28function initIframe(doc) { 32 insert : function() {
29 var dir = tinyMCEPopup.editor.settings.directionality; 33 var h = document.getElementById('iframe').contentWindow.document.body.innerHTML;
30 34
31 doc.body.dir = dir; 35 tinyMCEPopup.editor.execCommand('mceInsertClipboardContent', false, {content : h, wordContent : true});
32 36 tinyMCEPopup.close();
33 // Remove Gecko spellchecking 37 },
34 if (tinymce.isGecko)
35 doc.body.spellcheck = tinyMCEPopup.getParam("gecko_spellcheck");
36 38
37 resizeInputs(); 39 resize : function() {
38} 40 var vp = tinyMCEPopup.dom.getViewPort(window), el;
39 41
40function resizeInputs() { 42 el = document.getElementById('iframe');
41 if (!tinymce.isIE) {
42 wHeight = self.innerHeight - 80;
43 wWidth = self.innerWidth - 18;
44 } else {
45 wHeight = document.body.clientHeight - 80;
46 wWidth = document.body.clientWidth - 18;
47 }
48 43
49 var elm = document.getElementById('frmData'); 44 if (el) {
50 if (elm) { 45 el.style.width = (vp.w - 20) + 'px';
51 elm.style.height = Math.abs(wHeight) + 'px'; 46 el.style.height = (vp.h - 90) + 'px';
52 elm.style.width = Math.abs(wWidth) + 'px'; 47 }
53 } 48 }
54} 49};
55 50
56tinyMCEPopup.onInit.add(onLoadInit); 51tinyMCEPopup.onInit.add(PasteWordDialog.init, PasteWordDialog);
diff --git a/public/javascripts/tiny_mce/plugins/paste/langs/en_dlg.js b/public/javascripts/tiny_mce/plugins/paste/langs/en_dlg.js
index eeac778..eeac778 100755..100644
--- a/public/javascripts/tiny_mce/plugins/paste/langs/en_dlg.js
+++ b/public/javascripts/tiny_mce/plugins/paste/langs/en_dlg.js
diff --git a/public/javascripts/tiny_mce/plugins/paste/pastetext.htm b/public/javascripts/tiny_mce/plugins/paste/pastetext.htm
index 2f2b341..42c3d9c 100755..100644
--- a/public/javascripts/tiny_mce/plugins/paste/pastetext.htm
+++ b/public/javascripts/tiny_mce/plugins/paste/pastetext.htm
@@ -4,31 +4,30 @@
4 <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" /> 4 <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
5 <script type="text/javascript" src="../../tiny_mce_popup.js"></script> 5 <script type="text/javascript" src="../../tiny_mce_popup.js"></script>
6 <script type="text/javascript" src="js/pastetext.js"></script> 6 <script type="text/javascript" src="js/pastetext.js"></script>
7 <base target="_self" />
8</head> 7</head>
9<body onresize="resizeInputs();" style="display:none; overflow:hidden;"> 8<body onresize="PasteTextDialog.resize();" style="display:none; overflow:hidden;">
10<form name="source" onsubmit="saveContent();return false;" action="#"> 9 <form name="source" onsubmit="return PasteTextDialog.insert();" action="#">
11 <div style="float: left" class="title">{#paste.paste_text_desc}</div> 10 <div style="float: left" class="title">{#paste.paste_text_desc}</div>
12 11
13 <div style="float: right"> 12 <div style="float: right">
14 <input type="checkbox" name="linebreaks" id="linebreaks" class="wordWrapCode" checked="checked" /><label for="linebreaks">{#paste_dlg.text_linebreaks}</label> 13 <input type="checkbox" name="linebreaks" id="linebreaks" class="wordWrapCode" checked="checked" /><label for="linebreaks">{#paste_dlg.text_linebreaks}</label>
15 </div> 14 </div>
16 15
17 <br style="clear: both" /> 16 <br style="clear: both" />
18 17
19 <div>{#paste_dlg.text_title}</div> 18 <div>{#paste_dlg.text_title}</div>
20 19
21 <textarea name="htmlSource" id="htmlSource" rows="15" cols="100" style="width: 100%; height: 100%; font-family: 'Courier New',Courier,mono; font-size: 12px;" dir="ltr" wrap="soft" class="mceFocus"></textarea> 20 <textarea id="content" name="content" rows="15" cols="100" style="width: 100%; height: 100%; font-family: 'Courier New',Courier,mono; font-size: 12px;" dir="ltr" wrap="soft" class="mceFocus"></textarea>
22 21
23 <div class="mceActionPanel"> 22 <div class="mceActionPanel">
24 <div style="float: left"> 23 <div style="float: left">
25 <input type="submit" name="insert" value="{#insert}" id="insert" /> 24 <input type="submit" name="insert" value="{#insert}" id="insert" />
26 </div> 25 </div>
27 26
28 <div style="float: right"> 27 <div style="float: right">
29 <input type="button" name="cancel" value="{#cancel}" onclick="tinyMCEPopup.close();" id="cancel" /> 28 <input type="button" name="cancel" value="{#cancel}" onclick="tinyMCEPopup.close();" id="cancel" />
29 </div>
30 </div> 30 </div>
31 </div> 31 </form>
32</form>
33</body> 32</body>
34</html> \ No newline at end of file 33</html> \ No newline at end of file
diff --git a/public/javascripts/tiny_mce/plugins/paste/pasteword.htm b/public/javascripts/tiny_mce/plugins/paste/pasteword.htm
index 9e5ab1b..f4a9b3d 100755..100644
--- a/public/javascripts/tiny_mce/plugins/paste/pasteword.htm
+++ b/public/javascripts/tiny_mce/plugins/paste/pasteword.htm
@@ -4,11 +4,9 @@
4 <title>{#paste.paste_word_desc}</title> 4 <title>{#paste.paste_word_desc}</title>
5 <script type="text/javascript" src="../../tiny_mce_popup.js"></script> 5 <script type="text/javascript" src="../../tiny_mce_popup.js"></script>
6 <script type="text/javascript" src="js/pasteword.js"></script> 6 <script type="text/javascript" src="js/pasteword.js"></script>
7 <link href="css/pasteword.css" rel="stylesheet" type="text/css" />
8 <base target="_self" />
9</head> 7</head>
10<body onresize="resizeInputs();" style="display:none; overflow:hidden;"> 8<body onresize="PasteWordDialog.resize();" style="display:none; overflow:hidden;">
11 <form name="source" onsubmit="saveContent();" action="#"> 9 <form name="source" onsubmit="return PasteWordDialog.insert();" action="#">
12 <div class="title">{#paste.paste_word_desc}</div> 10 <div class="title">{#paste.paste_word_desc}</div>
13 11
14 <div>{#paste_dlg.word_title}</div> 12 <div>{#paste_dlg.word_title}</div>
@@ -17,7 +15,7 @@
17 15
18 <div class="mceActionPanel"> 16 <div class="mceActionPanel">
19 <div style="float: left"> 17 <div style="float: left">
20 <input type="button" id="insert" name="insert" value="{#insert}" onclick="saveContent();" /> 18 <input type="submit" id="insert" name="insert" value="{#insert}" />
21 </div> 19 </div>
22 20
23 <div style="float: right"> 21 <div style="float: right">