Ticket #1427: 1427.patch
File 1427.patch, 15.7 KB (added by , 15 years ago) |
---|
-
_source/plugins/clipboard/plugin.js
126 126 127 127 if ( editor.fire( 'beforePaste' ) ) 128 128 event.cancel(); 129 129 // Simulate native 'paste' event for Opera/Firefox2. 130 else if( CKEDITOR.env.opera 131 || CKEDITOR.env.gecko && CKEDITOR.env.version < 10900 ) 132 editor.document.getBody().fire( 'paste' ); 133 130 134 setTimeout( function() 131 135 { 132 136 editor.fire( 'saveSnapshot' ); // Save after paste … … 147 151 } 148 152 }; 149 153 154 // Allow to peek clipboard content by redirecting the 155 // pasting content into a temporary bin and grab the content of it. 156 function getPasteBin( evt, callback ) { 157 158 var doc = this.document; 159 160 // Avoid recursions on 'paste' event for IE. 161 if( CKEDITOR.env.ie && doc.getById( 'cke_pastebin' ) ) 162 return; 163 164 var sel = this.getSelection(), 165 range = new CKEDITOR.dom.range( doc ); 166 167 // Create container to paste into 168 var pastebin = CKEDITOR.dom.element.createFromHtml( '<div id="cke_pastebin"> </div>', doc ); 169 doc.getBody().append( pastebin ); 170 171 // Position the bin exactly at the position of the selected element 172 // to avoid any subsequent document scroll. 173 var position = sel.getStartElement().getDocumentPosition(); 174 pastebin.setStyles( { 175 position : 'absolute', 176 left : '-1000px', 177 top : position.y + 'px', 178 width : '1px', 179 height : '1px', 180 overflow : 'hidden' 181 } ); 182 183 if ( CKEDITOR.env.ie ) 184 { 185 // Select the container 186 var ieRange = doc.getBody().$.createTextRange(); 187 ieRange.moveToElementText( pastebin.$ ); 188 // Re-direct the paste target, will fire another 'paste' event. 189 ieRange.execCommand( 'Paste' ); 190 pastebin.remove(); 191 evt.data.preventDefault(); 192 callback( pastebin ); 193 } 194 else 195 { 196 var bms = sel.createBookmarks(); 197 range.selectNodeContents( pastebin ); 198 range.select(); 199 // Wait a while and grab the pasted contents 200 window.setTimeout( function() { 201 202 pastebin.remove(); 203 204 // Grab the HTML contents 205 // We need to look for a apple style wrapper on webkit it also adds a div wrapper if you copy/paste the body of the editor. 206 // Remove hidden div and restore selection 207 var bogusSpan; 208 pastebin = ( CKEDITOR.env.webkit 209 && ( bogusSpan = pastebin.getFirst() ) 210 && ( bogusSpan.is && bogusSpan.hasClass( 'Apple-style-span' ) ) ? 211 bogusSpan : pastebin ); 212 213 // Restore the old selection 214 sel.selectBookmarks( bms ); 215 callback( pastebin ); 216 217 }, 0 ); 218 } 219 }; 220 221 150 222 // Register the plugin. 151 223 CKEDITOR.plugins.add( 'clipboard', 152 224 { 153 225 init : function( editor ) 154 226 { 227 // Provide default 'html' paste handler. 228 editor.on( 'paste', function( evt ) 229 { 230 editor.insertHtml( evt.data[ 'html' ] ); 231 } ); 232 155 233 function addButtonCommand( buttonName, commandName, command, ctxMenuOrder ) 156 234 { 157 235 var lang = editor.lang[ commandName ]; … … 184 262 185 263 editor.on( 'key', onKey, editor ); 186 264 265 if( editor.config.autoDetectPaste ) 266 editor.on( 'contentDom', function() 267 { 268 var body = editor.document.getBody(); 269 body.on( 'paste', function( evt ) 270 { 271 getPasteBin.call( editor, evt, function ( pasteBin ) 272 { 273 var html = pasteBin.getHtml(), 274 dataTransfer = 275 { 276 'html' : html 277 }; 278 279 editor.fire( 'paste', dataTransfer ); 280 editor.fire( 'saveSnapshot' ); // Save after paste 281 } ); 282 } ); 283 284 } ); 285 187 286 // If the "contextmenu" plugin is loaded, register the listeners. 188 287 if ( editor.contextMenu ) 189 288 { … … 206 305 } 207 306 }); 208 307 })(); 308 309 /** 310 * Whether to automatically choose the right format when pasting based on the 311 * detection of content text OR just leave it to the browser's default paste behavior. 312 * @type Boolean 313 * @default true 314 * @example 315 * config.autoDetectPaste = false; 316 */ 317 CKEDITOR.config.autoDetectPaste = true; -
_source/plugins/pastefromword/dialogs/pastefromword.js
27 27 + 'dialog.fire( "iframeAdded", { iframe : iframe } );' 28 28 + '};' 29 29 + '</script><style>body { margin: 3px; height: 95%; } </style><body></body>', 30 cleanWord : function( editor, html, ignoreFont, removeStyles )31 {32 // Remove comments [SF BUG-1481861].33 html = html.replace(/<\!--[\s\S]*?-->/g, '' ) ;34 35 html = html.replace(/<o:p>\s*<\/o:p>/g, '') ;36 html = html.replace(/<o:p>[\s\S]*?<\/o:p>/g, ' ') ;37 38 // Remove mso-xxx styles.39 html = html.replace( /\s*mso-[^:]+:[^;"]+;?/gi, '' ) ;40 41 // Remove margin styles.42 html = html.replace( /\s*MARGIN: 0(?:cm|in) 0(?:cm|in) 0pt\s*;/gi, '' ) ;43 html = html.replace( /\s*MARGIN: 0(?:cm|in) 0(?:cm|in) 0pt\s*"/gi, "\"" ) ;44 45 html = html.replace( /\s*TEXT-INDENT: 0cm\s*;/gi, '' ) ;46 html = html.replace( /\s*TEXT-INDENT: 0cm\s*"/gi, "\"" ) ;47 48 html = html.replace( /\s*TEXT-ALIGN: [^\s;]+;?"/gi, "\"" ) ;49 50 html = html.replace( /\s*PAGE-BREAK-BEFORE: [^\s;]+;?"/gi, "\"" ) ;51 52 html = html.replace( /\s*FONT-VARIANT: [^\s;]+;?"/gi, "\"" ) ;53 54 html = html.replace( /\s*tab-stops:[^;"]*;?/gi, '' ) ;55 html = html.replace( /\s*tab-stops:[^"]*/gi, '' ) ;56 57 // Remove FONT face attributes.58 if ( ignoreFont )59 {60 html = html.replace( /\s*face="[^"]*"/gi, '' ) ;61 html = html.replace( /\s*face=[^ >]*/gi, '' ) ;62 63 html = html.replace( /\s*FONT-FAMILY:[^;"]*;?/gi, '' ) ;64 }65 66 // Remove Class attributes67 html = html.replace(/<(\w[^>]*) class=([^ |>]*)([^>]*)/gi, "<$1$3") ;68 69 // Remove styles.70 if ( removeStyles )71 html = html.replace( /<(\w[^>]*) style="([^\"]*)"([^>]*)/gi, "<$1$3" ) ;72 73 // Remove style, meta and link tags74 html = html.replace( /<STYLE[^>]*>[\s\S]*?<\/STYLE[^>]*>/gi, '' ) ;75 html = html.replace( /<(?:META|LINK)[^>]*>\s*/gi, '' ) ;76 77 // Remove empty styles.78 html = html.replace( /\s*style="\s*"/gi, '' ) ;79 80 html = html.replace( /<SPAN\s*[^>]*>\s* \s*<\/SPAN>/gi, ' ' ) ;81 82 html = html.replace( /<SPAN\s*[^>]*><\/SPAN>/gi, '' ) ;83 84 // Remove Lang attributes85 html = html.replace(/<(\w[^>]*) lang=([^ |>]*)([^>]*)/gi, "<$1$3") ;86 87 html = html.replace( /<SPAN\s*>([\s\S]*?)<\/SPAN>/gi, '$1' ) ;88 89 html = html.replace( /<FONT\s*>([\s\S]*?)<\/FONT>/gi, '$1' ) ;90 91 // Remove XML elements and declarations92 html = html.replace(/<\\?\?xml[^>]*>/gi, '' ) ;93 94 // Remove w: tags with contents.95 html = html.replace( /<w:[^>]*>[\s\S]*?<\/w:[^>]*>/gi, '' ) ;96 97 // Remove Tags with XML namespace declarations: <o:p><\/o:p>98 html = html.replace(/<\/?\w+:[^>]*>/gi, '' ) ;99 100 html = html.replace( /<(U|I|STRIKE)> <\/\1>/g, ' ' ) ;101 102 html = html.replace( /<H\d>\s*<\/H\d>/gi, '' ) ;103 104 // Remove "display:none" tags.105 html = html.replace( /<(\w+)[^>]*\sstyle="[^"]*DISPLAY\s?:\s?none[\s\S]*?<\/\1>/ig, '' ) ;106 107 // Remove language tags108 html = html.replace( /<(\w[^>]*) language=([^ |>]*)([^>]*)/gi, "<$1$3") ;109 110 // Remove onmouseover and onmouseout events (from MS Word comments effect)111 html = html.replace( /<(\w[^>]*) onmouseover="([^\"]*)"([^>]*)/gi, "<$1$3") ;112 html = html.replace( /<(\w[^>]*) onmouseout="([^\"]*)"([^>]*)/gi, "<$1$3") ;113 114 if ( editor.config.pasteFromWordKeepsStructure )115 {116 // The original <Hn> tag send from Word is something like this: <Hn style="margin-top:0px;margin-bottom:0px">117 html = html.replace( /<H(\d)([^>]*)>/gi, '<h$1>' ) ;118 119 // Word likes to insert extra <font> tags, when using MSIE. (Wierd).120 html = html.replace( /<(H\d)><FONT[^>]*>([\s\S]*?)<\/FONT><\/\1>/gi, '<$1>$2<\/$1>' );121 html = html.replace( /<(H\d)><EM>([\s\S]*?)<\/EM><\/\1>/gi, '<$1>$2<\/$1>' );122 }123 else124 {125 html = html.replace( /<H1([^>]*)>/gi, '<div$1><b><font size="6">' ) ;126 html = html.replace( /<H2([^>]*)>/gi, '<div$1><b><font size="5">' ) ;127 html = html.replace( /<H3([^>]*)>/gi, '<div$1><b><font size="4">' ) ;128 html = html.replace( /<H4([^>]*)>/gi, '<div$1><b><font size="3">' ) ;129 html = html.replace( /<H5([^>]*)>/gi, '<div$1><b><font size="2">' ) ;130 html = html.replace( /<H6([^>]*)>/gi, '<div$1><b><font size="1">' ) ;131 132 html = html.replace( /<\/H\d>/gi, '<\/font><\/b><\/div>' ) ;133 134 // Transform <P> to <DIV>135 var re = new RegExp( '(<P)([^>]*>[\\s\\S]*?)(<\/P>)', 'gi' ) ; // Different because of a IE 5.0 error136 html = html.replace( re, '<div$2<\/div>' ) ;137 138 // Remove empty tags (three times, just to be sure).139 // This also removes any empty anchor140 html = html.replace( /<([^\s>]+)(\s[^>]*)?>\s*<\/\1>/g, '' ) ;141 html = html.replace( /<([^\s>]+)(\s[^>]*)?>\s*<\/\1>/g, '' ) ;142 html = html.replace( /<([^\s>]+)(\s[^>]*)?>\s*<\/\1>/g, '' ) ;143 }144 145 return html ;146 },147 30 onShow : function() 148 31 { 149 32 // To avoid JAWS putting virtual cursor back to the editor document, … … 213 96 doc.close(); 214 97 } 215 98 }, 99 cleanWord : CKEDITOR.plugins.pastefromword.cleanWord, 216 100 onOk : function() 217 101 { 218 102 var container = this.getContentElement( 'general', 'editing_area' ).getElement(), … … 303 187 } 304 188 ] 305 189 }; 306 } );190 } ); -
_source/plugins/pastefromword/plugin.js
9 9 { 10 10 // Register the command. 11 11 editor.addCommand( 'pastefromword', new CKEDITOR.dialogCommand( 'pastefromword' ) ); 12 // Register the dialog. 13 CKEDITOR.dialog.add( 'pastefromword', this.path + 'dialogs/pastefromword.js' ); 12 14 13 15 // Register the toolbar button. 14 16 editor.ui.addButton( 'PasteFromWord', … … 17 19 command : 'pastefromword' 18 20 } ); 19 21 20 // Register the dialog. 21 CKEDITOR.dialog.add( 'pastefromword', this.path + 'dialogs/pastefromword.js' ); 22 } 22 var config = editor.config; 23 editor.on( 'paste', function( evt ) 24 { 25 var mswordHtml; 26 // MS-WORD format sniffing. 27 if ( ( mswordHtml = evt.data[ 'html' ] ) 28 && /(class=\"?Mso|style=\"[^\"]*\bmso\-|w:WordDocument)/.test( mswordHtml ) ) 29 { 30 // Perform cleaning with default configuration. 31 editor.insertHtml( 32 CKEDITOR.plugins.pastefromword.cleanWord( 33 editor, mswordHtml, 34 config.pasteFromWordIgnoreFontFace, 35 config.pasteFromWordRemoveStyle)); 36 37 // Cancel other html paste handlers. 38 evt.cancel(); 39 } 40 }, null, null, 9 ); 41 42 } 23 43 } ); 24 44 45 CKEDITOR.plugins.pastefromword = 46 { 47 cleanWord : function( editor, html, ignoreFont, removeStyles ) 48 { 49 // Remove comments [SF BUG-1481861]. 50 html = html.replace(/<\!--[\s\S]*?-->/g, '' ) ; 51 52 html = html.replace(/<o:p>\s*<\/o:p>/g, '') ; 53 html = html.replace(/<o:p>[\s\S]*?<\/o:p>/g, ' ') ; 54 55 // Remove mso-xxx styles. 56 html = html.replace( /\s*mso-[^:]+:[^;"]+;?/gi, '' ) ; 57 58 // Remove margin styles. 59 html = html.replace( /\s*MARGIN: 0(?:cm|in) 0(?:cm|in) 0pt\s*;/gi, '' ) ; 60 html = html.replace( /\s*MARGIN: 0(?:cm|in) 0(?:cm|in) 0pt\s*"/gi, "\"" ) ; 61 62 html = html.replace( /\s*TEXT-INDENT: 0cm\s*;/gi, '' ) ; 63 html = html.replace( /\s*TEXT-INDENT: 0cm\s*"/gi, "\"" ) ; 64 65 html = html.replace( /\s*TEXT-ALIGN: [^\s;]+;?"/gi, "\"" ) ; 66 67 html = html.replace( /\s*PAGE-BREAK-BEFORE: [^\s;]+;?"/gi, "\"" ) ; 68 69 html = html.replace( /\s*FONT-VARIANT: [^\s;]+;?"/gi, "\"" ) ; 70 71 html = html.replace( /\s*tab-stops:[^;"]*;?/gi, '' ) ; 72 html = html.replace( /\s*tab-stops:[^"]*/gi, '' ) ; 73 74 // Remove FONT face attributes. 75 if ( ignoreFont ) 76 { 77 html = html.replace( /\s*face="[^"]*"/gi, '' ) ; 78 html = html.replace( /\s*face=[^ >]*/gi, '' ) ; 79 80 html = html.replace( /\s*FONT-FAMILY:[^;"]*;?/gi, '' ) ; 81 } 82 83 // Remove Class attributes 84 html = html.replace(/<(\w[^>]*) class=([^ |>]*)([^>]*)/gi, "<$1$3") ; 85 86 // Remove styles. 87 if ( removeStyles ) 88 html = html.replace( /<(\w[^>]*) style="([^\"]*)"([^>]*)/gi, "<$1$3" ) ; 89 90 // Remove style, meta and link tags 91 html = html.replace( /<STYLE[^>]*>[\s\S]*?<\/STYLE[^>]*>/gi, '' ) ; 92 html = html.replace( /<(?:META|LINK)[^>]*>\s*/gi, '' ) ; 93 94 // Remove empty styles. 95 html = html.replace( /\s*style="\s*"/gi, '' ) ; 96 97 html = html.replace( /<SPAN\s*[^>]*>\s* \s*<\/SPAN>/gi, ' ' ) ; 98 99 html = html.replace( /<SPAN\s*[^>]*><\/SPAN>/gi, '' ) ; 100 101 // Remove Lang attributes 102 html = html.replace(/<(\w[^>]*) lang=([^ |>]*)([^>]*)/gi, "<$1$3") ; 103 104 html = html.replace( /<SPAN\s*>([\s\S]*?)<\/SPAN>/gi, '$1' ) ; 105 106 html = html.replace( /<FONT\s*>([\s\S]*?)<\/FONT>/gi, '$1' ) ; 107 108 // Remove XML elements and declarations 109 html = html.replace(/<\\?\?xml[^>]*>/gi, '' ) ; 110 111 // Remove w: tags with contents. 112 html = html.replace( /<w:[^>]*>[\s\S]*?<\/w:[^>]*>/gi, '' ) ; 113 114 // Remove Tags with XML namespace declarations: <o:p><\/o:p> 115 html = html.replace(/<\/?\w+:[^>]*>/gi, '' ) ; 116 117 html = html.replace( /<(U|I|STRIKE)> <\/\1>/g, ' ' ) ; 118 119 html = html.replace( /<H\d>\s*<\/H\d>/gi, '' ) ; 120 121 // Remove "display:none" tags. 122 html = html.replace( /<(\w+)[^>]*\sstyle="[^"]*DISPLAY\s?:\s?none[\s\S]*?<\/\1>/ig, '' ) ; 123 124 // Remove language tags 125 html = html.replace( /<(\w[^>]*) language=([^ |>]*)([^>]*)/gi, "<$1$3") ; 126 127 // Remove onmouseover and onmouseout events (from MS Word comments effect) 128 html = html.replace( /<(\w[^>]*) onmouseover="([^\"]*)"([^>]*)/gi, "<$1$3") ; 129 html = html.replace( /<(\w[^>]*) onmouseout="([^\"]*)"([^>]*)/gi, "<$1$3") ; 130 131 if ( editor.config.pasteFromWordKeepsStructure ) 132 { 133 // The original <Hn> tag send from Word is something like this: <Hn style="margin-top:0px;margin-bottom:0px"> 134 html = html.replace( /<H(\d)([^>]*)>/gi, '<h$1>' ) ; 135 136 // Word likes to insert extra <font> tags, when using MSIE. (Wierd). 137 html = html.replace( /<(H\d)><FONT[^>]*>([\s\S]*?)<\/FONT><\/\1>/gi, '<$1>$2<\/$1>' ); 138 html = html.replace( /<(H\d)><EM>([\s\S]*?)<\/EM><\/\1>/gi, '<$1>$2<\/$1>' ); 139 } 140 else 141 { 142 html = html.replace( /<H1([^>]*)>/gi, '<div$1><b><font size="6">' ) ; 143 html = html.replace( /<H2([^>]*)>/gi, '<div$1><b><font size="5">' ) ; 144 html = html.replace( /<H3([^>]*)>/gi, '<div$1><b><font size="4">' ) ; 145 html = html.replace( /<H4([^>]*)>/gi, '<div$1><b><font size="3">' ) ; 146 html = html.replace( /<H5([^>]*)>/gi, '<div$1><b><font size="2">' ) ; 147 html = html.replace( /<H6([^>]*)>/gi, '<div$1><b><font size="1">' ) ; 148 149 html = html.replace( /<\/H\d>/gi, '<\/font><\/b><\/div>' ) ; 150 151 // Transform <P> to <DIV> 152 var re = new RegExp( '(<P)([^>]*>[\\s\\S]*?)(<\/P>)', 'gi' ) ; // Different because of a IE 5.0 error 153 html = html.replace( re, '<div$2<\/div>' ) ; 154 155 // Remove empty tags (three times, just to be sure). 156 // This also removes any empty anchor 157 html = html.replace( /<([^\s>]+)(\s[^>]*)?>\s*<\/\1>/g, '' ) ; 158 html = html.replace( /<([^\s>]+)(\s[^>]*)?>\s*<\/\1>/g, '' ) ; 159 html = html.replace( /<([^\s>]+)(\s[^>]*)?>\s*<\/\1>/g, '' ) ; 160 } 161 162 return html ; 163 } 164 } 165 25 166 /** 26 167 * Whether the "Ignore font face definitions" checkbox is enabled by default in 27 168 * the Paste from Word dialog.