1 /* 2 Copyright (c) 2003-2009, CKSource - Frederico Knabben. All rights reserved. 3 For licensing, see LICENSE.html or http://ckeditor.com/license 4 */ 5 6 CKEDITOR.dialog.add( 'pastefromword', function( editor ) 7 { 8 return { 9 title : editor.lang.pastefromword.title, 10 minWidth : 400, 11 minHeight : 340, 12 htmlToLoad : '<!doctype html><script type="text/javascript">' 13 + 'window.onload = function()' 14 + '{' 15 + 'if ( ' + CKEDITOR.env.ie + ' ) ' 16 + 'document.body.contentEditable = "true";' 17 + 'else ' 18 + 'document.designMode = "on";' 19 + 'window.focus();' 20 + '};' 21 + '</script><style>body { margin: 3px; height: 95%; } </style><body></body>', 22 cleanWord : function( editor, html, ignoreFont, removeStyles ) 23 { 24 html = html.replace(/<o:p>\s*<\/o:p>/g, '') ; 25 html = html.replace(/<o:p>[\s\S]*?<\/o:p>/g, ' ') ; 26 27 // Remove mso-xxx styles. 28 html = html.replace( /\s*mso-[^:]+:[^;"]+;?/gi, '' ) ; 29 30 // Remove margin styles. 31 html = html.replace( /\s*MARGIN: 0cm 0cm 0pt\s*;/gi, '' ) ; 32 html = html.replace( /\s*MARGIN: 0cm 0cm 0pt\s*"/gi, "\"" ) ; 33 34 html = html.replace( /\s*TEXT-INDENT: 0cm\s*;/gi, '' ) ; 35 html = html.replace( /\s*TEXT-INDENT: 0cm\s*"/gi, "\"" ) ; 36 37 html = html.replace( /\s*TEXT-ALIGN: [^\s;]+;?"/gi, "\"" ) ; 38 39 html = html.replace( /\s*PAGE-BREAK-BEFORE: [^\s;]+;?"/gi, "\"" ) ; 40 41 html = html.replace( /\s*FONT-VARIANT: [^\s;]+;?"/gi, "\"" ) ; 42 43 html = html.replace( /\s*tab-stops:[^;"]*;?/gi, '' ) ; 44 html = html.replace( /\s*tab-stops:[^"]*/gi, '' ) ; 45 46 // Remove FONT face attributes. 47 if ( ignoreFont ) 48 { 49 html = html.replace( /\s*face="[^"]*"/gi, '' ) ; 50 html = html.replace( /\s*face=[^ >]*/gi, '' ) ; 51 52 html = html.replace( /\s*FONT-FAMILY:[^;"]*;?/gi, '' ) ; 53 } 54 55 // Remove Class attributes 56 html = html.replace(/<(\w[^>]*) class=([^ |>]*)([^>]*)/gi, "<$1$3") ; 57 58 // Remove styles. 59 if ( removeStyles ) 60 html = html.replace( /<(\w[^>]*) style="([^\"]*)"([^>]*)/gi, "<$1$3" ) ; 61 62 // Remove style, meta and link tags 63 html = html.replace( /<STYLE[^>]*>[\s\S]*?<\/STYLE[^>]*>/gi, '' ) ; 64 html = html.replace( /<(?:META|LINK)[^>]*>\s*/gi, '' ) ; 65 66 // Remove empty styles. 67 html = html.replace( /\s*style="\s*"/gi, '' ) ; 68 69 html = html.replace( /<SPAN\s*[^>]*>\s* \s*<\/SPAN>/gi, ' ' ) ; 70 71 html = html.replace( /<SPAN\s*[^>]*><\/SPAN>/gi, '' ) ; 72 73 // Remove Lang attributes 74 html = html.replace(/<(\w[^>]*) lang=([^ |>]*)([^>]*)/gi, "<$1$3") ; 75 76 html = html.replace( /<SPAN\s*>([\s\S]*?)<\/SPAN>/gi, '$1' ) ; 77 78 html = html.replace( /<FONT\s*>([\s\S]*?)<\/FONT>/gi, '$1' ) ; 79 80 // Remove XML elements and declarations 81 html = html.replace(/<\\?\?xml[^>]*>/gi, '' ) ; 82 83 // Remove w: tags with contents. 84 html = html.replace( /<w:[^>]*>[\s\S]*?<\/w:[^>]*>/gi, '' ) ; 85 86 // Remove Tags with XML namespace declarations: <o:p><\/o:p> 87 html = html.replace(/<\/?\w+:[^>]*>/gi, '' ) ; 88 89 // Remove comments [SF BUG-1481861]. 90 html = html.replace(/<\!--[\s\S]*?-->/g, '' ) ; 91 92 html = html.replace( /<(U|I|STRIKE)> <\/\1>/g, ' ' ) ; 93 94 html = html.replace( /<H\d>\s*<\/H\d>/gi, '' ) ; 95 96 // Remove "display:none" tags. 97 html = html.replace( /<(\w+)[^>]*\sstyle="[^"]*DISPLAY\s?:\s?none[\s\S]*?<\/\1>/ig, '' ) ; 98 99 // Remove language tags 100 html = html.replace( /<(\w[^>]*) language=([^ |>]*)([^>]*)/gi, "<$1$3") ; 101 102 // Remove onmouseover and onmouseout events (from MS Word comments effect) 103 html = html.replace( /<(\w[^>]*) onmouseover="([^\"]*)"([^>]*)/gi, "<$1$3") ; 104 html = html.replace( /<(\w[^>]*) onmouseout="([^\"]*)"([^>]*)/gi, "<$1$3") ; 105 106 if ( editor.config.pasteFromWordKeepsStructure ) 107 { 108 // The original <Hn> tag send from Word is something like this: <Hn style="margin-top:0px;margin-bottom:0px"> 109 html = html.replace( /<H(\d)([^>]*)>/gi, '<h$1>' ) ; 110 111 // Word likes to insert extra <font> tags, when using MSIE. (Wierd). 112 html = html.replace( /<(H\d)><FONT[^>]*>([\s\S]*?)<\/FONT><\/\1>/gi, '<$1>$2<\/$1>' ); 113 html = html.replace( /<(H\d)><EM>([\s\S]*?)<\/EM><\/\1>/gi, '<$1>$2<\/$1>' ); 114 } 115 else 116 { 117 html = html.replace( /<H1([^>]*)>/gi, '<div$1><b><font size="6">' ) ; 118 html = html.replace( /<H2([^>]*)>/gi, '<div$1><b><font size="5">' ) ; 119 html = html.replace( /<H3([^>]*)>/gi, '<div$1><b><font size="4">' ) ; 120 html = html.replace( /<H4([^>]*)>/gi, '<div$1><b><font size="3">' ) ; 121 html = html.replace( /<H5([^>]*)>/gi, '<div$1><b><font size="2">' ) ; 122 html = html.replace( /<H6([^>]*)>/gi, '<div$1><b><font size="1">' ) ; 123 124 html = html.replace( /<\/H\d>/gi, '<\/font><\/b><\/div>' ) ; 125 126 // Transform <P> to <DIV> 127 var re = new RegExp( '(<P)([^>]*>[\\s\\S]*?)(<\/P>)', 'gi' ) ; // Different because of a IE 5.0 error 128 html = html.replace( re, '<div$2<\/div>' ) ; 129 130 // Remove empty tags (three times, just to be sure). 131 // This also removes any empty anchor 132 html = html.replace( /<([^\s>]+)(\s[^>]*)?>\s*<\/\1>/g, '' ) ; 133 html = html.replace( /<([^\s>]+)(\s[^>]*)?>\s*<\/\1>/g, '' ) ; 134 html = html.replace( /<([^\s>]+)(\s[^>]*)?>\s*<\/\1>/g, '' ) ; 135 } 136 137 return html ; 138 }, 139 onShow : function() 140 { 141 var container = this.getContentElement( 'general', 'editing_area' ).getElement(), 142 iframe = CKEDITOR.dom.element.createFromHtml( '<iframe src="javascript:void(0)" frameborder="0" allowtransparency="1"></iframe>' ); 143 144 iframe.setStyles( 145 { 146 width : '346px', 147 height : '152px', 148 'background-color' : 'white', 149 border : '1px solid black' 150 } ); 151 container.setHtml( '' ); 152 container.append( iframe ); 153 if ( CKEDITOR.env.ie ) 154 container.setStyle( 'height', ( iframe.$.offsetHeight + 2 ) + 'px' ); 155 156 var isCustomDomain = CKEDITOR.env.ie && document.domain != window.location.hostname; 157 if ( isCustomDomain ) 158 { 159 CKEDITOR._cke_htmlToLoad = this.definition.htmlToLoad; 160 iframe.setAttribute( 'src', 161 'javascript:void( (function(){' + 162 'document.open();' + 163 'document.domain="' + document.domain + '";' + 164 'document.write( window.parent.CKEDITOR._cke_htmlToLoad );' + 165 'delete window.parent.CKEDITOR._cke_htmlToLoad;' + 166 'document.close();' + 167 '})() )' ); 168 } 169 else 170 { 171 var doc = iframe.$.contentWindow.document; 172 doc.open(); 173 doc.write( this.definition.htmlToLoad ); 174 doc.close(); 175 } 176 }, 177 onOk : function() 178 { 179 var container = this.getContentElement( 'general', 'editing_area' ).getElement(), 180 iframe = container.getFirst(), 181 editor = this.getParentEditor(), 182 html = this.definition.cleanWord( editor, iframe.$.contentWindow.document.body.innerHTML, 183 this.getValueOf( 'general', 'ignoreFontFace' ), 184 this.getValueOf( 'general', 'removeStyle' ) ); 185 186 this.restoreSelection(); 187 editor.insertHtml( html ); 188 }, 189 contents : 190 [ 191 { 192 id : 'general', 193 label : editor.lang.pastefromword.title, 194 elements : 195 [ 196 { 197 type : 'html', 198 style : 'white-space: normal;', 199 onShow : function() 200 { 201 /* 202 * SAFARI BUG: The advice label would overflow if the table layout 203 * isn't fixed. 204 */ 205 if ( CKEDITOR.env.webkit ) 206 this.getElement().getAscendant( 'table' ).setStyle( 'table-layout', 'fixed' ); 207 }, 208 html : editor.lang.pastefromword.advice 209 }, 210 { 211 type : 'html', 212 id : 'editing_area', 213 style : 'width: 100%; height: 100%;', 214 html : '<div> </div>' 215 }, 216 { 217 type : 'vbox', 218 padding : 0, 219 children : 220 [ 221 { 222 type : 'checkbox', 223 id : 'ignoreFontFace', 224 label : editor.lang.pastefromword.ignoreFontFace, 225 'default' : true 226 }, 227 { 228 type : 'checkbox', 229 id : 'removeStyle', 230 label : editor.lang.pastefromword.removeStyle 231 } 232 ] 233 } 234 ] 235 } 236 ] 237 }; 238 } ); 239