| | 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; } </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 | } ); |