1 /* 2 Copyright (c) 2003-2012, CKSource - Frederico Knabben. All rights reserved. 3 For licensing, see LICENSE.html or http://ckeditor.com/license 4 */ 5 (function() 6 { 7 function forceHtmlMode( evt ) { evt.data.mode = 'html'; } 8 9 CKEDITOR.plugins.add( 'pastefromword', 10 { 11 init : function( editor ) 12 { 13 14 // Flag indicate this command is actually been asked instead of a generic 15 // pasting. 16 var forceFromWord = 0; 17 var resetFromWord = function( evt ) 18 { 19 evt && evt.removeListener(); 20 editor.removeListener( 'beforePaste', forceHtmlMode ); 21 forceFromWord && setTimeout( function() { forceFromWord = 0; }, 0 ); 22 }; 23 24 // Features bring by this command beside the normal process: 25 // 1. No more bothering of user about the clean-up. 26 // 2. Perform the clean-up even if content is not from MS-Word. 27 // (e.g. from a MS-Word similar application.) 28 editor.addCommand( 'pastefromword', 29 { 30 canUndo : false, 31 exec : function() 32 { 33 // Ensure the received data format is HTML and apply content filtering. (#6718) 34 forceFromWord = 1; 35 editor.on( 'beforePaste', forceHtmlMode ); 36 37 if ( editor.execCommand( 'paste', 'html' ) === false ) 38 { 39 editor.on( 'dialogShow', function ( evt ) 40 { 41 evt.removeListener(); 42 evt.data.on( 'cancel', resetFromWord ); 43 }); 44 45 editor.on( 'dialogHide', function( evt ) 46 { 47 evt.data.removeListener( 'cancel', resetFromWord ); 48 } ); 49 } 50 51 editor.on( 'afterPaste', resetFromWord ); 52 } 53 }); 54 55 // Register the toolbar button. 56 editor.ui.addButton( 'PasteFromWord', 57 { 58 label : editor.lang.pastefromword.toolbar, 59 command : 'pastefromword' 60 }); 61 62 editor.on( 'pasteState', function( evt ) 63 { 64 editor.getCommand( 'pastefromword' ).setState( evt.data ); 65 }); 66 67 editor.on( 'paste', function( evt ) 68 { 69 var data = evt.data, 70 mswordHtml; 71 72 // MS-WORD format sniffing. 73 if ( ( mswordHtml = data[ 'html' ] ) 74 && ( forceFromWord || ( /(class=\"?Mso|style=\"[^\"]*\bmso\-|w:WordDocument)/ ).test( mswordHtml ) ) ) 75 { 76 var isLazyLoad = this.loadFilterRules( function() 77 { 78 // Event continuation with the original data. 79 if ( isLazyLoad ) 80 editor.fire( 'paste', data ); 81 else if ( !editor.config.pasteFromWordPromptCleanup 82 || ( forceFromWord || confirm( editor.lang.pastefromword.confirmCleanup ) ) ) 83 { 84 data[ 'html' ] = CKEDITOR.cleanWord( mswordHtml, editor ); 85 } 86 }); 87 88 // The cleanup rules are to be loaded, we should just cancel 89 // this event. 90 isLazyLoad && evt.cancel(); 91 } 92 }, this ); 93 }, 94 95 loadFilterRules : function( callback ) 96 { 97 98 var isLoaded = CKEDITOR.cleanWord; 99 100 if ( isLoaded ) 101 callback(); 102 else 103 { 104 var filterFilePath = CKEDITOR.getUrl( 105 CKEDITOR.config.pasteFromWordCleanupFile 106 || ( this.path + 'filter/default.js' ) ); 107 108 // Load with busy indicator. 109 CKEDITOR.scriptLoader.load( filterFilePath, callback, null, true ); 110 } 111 112 return !isLoaded; 113 }, 114 115 requires : [ 'clipboard' ] 116 }); 117 })(); 118 119 /** 120 * Whether to prompt the user about the clean up of content being pasted from 121 * MS Word. 122 * @name CKEDITOR.config.pasteFromWordPromptCleanup 123 * @since 3.1 124 * @type Boolean 125 * @default undefined 126 * @example 127 * config.pasteFromWordPromptCleanup = true; 128 */ 129 130 /** 131 * The file that provides the MS Word cleanup function for pasting operations. 132 * Note: This is a global configuration shared by all editor instances present 133 * in the page. 134 * @name CKEDITOR.config.pasteFromWordCleanupFile 135 * @since 3.1 136 * @type String 137 * @default 'default' 138 * @example 139 * // Load from 'pastefromword' plugin 'filter' sub folder (custom.js file). 140 * CKEDITOR.config.pasteFromWordCleanupFile = 'custom'; 141 */ 142