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 /**
  7  * @file Clipboard support
  8  */
  9
 10 (function()
 11 {
 12 	// Tries to execute any of the paste, cut or copy commands in IE. Returns a
 13 	// boolean indicating that the operation succeeded.
 14 	var execIECommand = function( editor, command )
 15 	{
 16 		var doc = editor.document,
 17 			body = doc.getBody();
 18
 19 		var	enabled = false;
 20 		var onExec = function()
 21 		{
 22 			enabled = true;
 23 		};
 24
 25 		// The following seems to be the only reliable way to detect that
 26 		// clipboard commands are enabled in IE. It will fire the
 27 		// onpaste/oncut/oncopy events only if the security settings allowed
 28 		// the command to execute.
 29 		body.on( command, onExec );
 30
 31 		doc.$.execCommand( command );
 32
 33 		body.removeListener( command, onExec );
 34
 35 		return enabled;
 36 	};
 37
 38 	// Attempts to execute the Cut and Copy operations.
 39 	var tryToCutCopy =
 40 		CKEDITOR.env.ie ?
 41 			function( editor, type )
 42 			{
 43 				return execIECommand( editor, type );
 44 			}
 45 		:		// !IE.
 46 			function( editor, type )
 47 			{
 48 				try
 49 				{
 50 					// Other browsers throw an error if the command is disabled.
 51 					return editor.document.$.execCommand( type );
 52 				}
 53 				catch( e )
 54 				{
 55 					return false;
 56 				}
 57 			};
 58
 59 	// A class that represents one of the cut or copy commands.
 60 	var cutCopyCmd = function( type )
 61 	{
 62 		this.type = type;
 63 	};
 64
 65 	cutCopyCmd.prototype =
 66 	{
 67 		exec : function( editor, data )
 68 		{
 69 			var success = tryToCutCopy( editor, this.type );
 70
 71 			if ( !success )
 72 				alert( editor.lang.clipboard[ this.type + 'Error' ] );		// Show cutError or copyError.
 73
 74 			return success;
 75 		}
 76 	};
 77
 78 	// Paste command.
 79 	var pasteCmd =
 80 		CKEDITOR.env.ie ?
 81 			{
 82 				exec : function( editor, data )
 83 				{
 84 					// Prevent IE from pasting at the begining of the document.
 85 					editor.focus();
 86
 87 					if ( !editor.fire( 'beforePaste' )
 88 						&& !execIECommand( editor, 'paste' ) )
 89 					{
 90 							editor.openDialog( 'paste' );
 91 					}
 92 				}
 93 			}
 94 		:
 95 			{
 96 				exec : function( editor )
 97 				{
 98 					try
 99 					{
100 						if ( !editor.fire( 'beforePaste' )
101 							&& !editor.document.$.execCommand( 'Paste', false, null ) )
102 						{
103 							throw 0;
104 						}
105 					}
106 					catch ( e )
107 					{
108 						// Open the paste dialog.
109 						editor.openDialog( 'paste' );
110 					}
111 				}
112 			};
113
114 	// Listens for some clipboard related keystrokes, so they get customized.
115 	var onKey = function( event )
116 	{
117 		switch ( event.data.keyCode )
118 		{
119 			// Paste
120 			case CKEDITOR.CTRL + 86 :		// CTRL+V
121 			case CKEDITOR.SHIFT + 45 :		// SHIFT+INS
122 				if ( this.fire( 'beforePaste' ) )
123 					event.cancel();
124 				return;
125
126 			// Cut
127 			case CKEDITOR.CTRL + 88 :		// CTRL+X
128 			case CKEDITOR.SHIFT + 46 :		// SHIFT+DEL
129 				// Save Undo snapshot.
130 		}
131 	};
132
133 	// Register the plugin.
134 	CKEDITOR.plugins.add( 'clipboard',
135 		{
136 			init : function( editor )
137 			{
138 				function addButtonCommand( buttonName, commandName, command, ctxMenuOrder )
139 				{
140 					var lang = editor.lang[ commandName ];
141
142 					editor.addCommand( commandName, command );
143 					editor.ui.addButton( buttonName,
144 						{
145 							label : lang,
146 							command : commandName
147 						});
148
149 					// If the "menu" plugin is loaded, register the menu item.
150 					if ( editor.addMenuItems )
151 					{
152 						editor.addMenuItem( commandName,
153 							{
154 								label : lang,
155 								command : commandName,
156 								group : 'clipboard',
157 								order : ctxMenuOrder
158 							});
159 					}
160 				}
161
162 				addButtonCommand( 'Cut', 'cut', new cutCopyCmd( 'cut' ), 1 );
163 				addButtonCommand( 'Copy', 'copy', new cutCopyCmd( 'copy' ), 4 );
164 				addButtonCommand( 'Paste', 'paste', pasteCmd, 8 );
165
166 				CKEDITOR.dialog.add( 'paste', CKEDITOR.getUrl( this.path + 'dialogs/paste.js' ) );
167
168 				editor.on( 'key', onKey, editor );
169
170 				// If the "contextmenu" plugin is loaded, register the listeners.
171 				if ( editor.contextMenu )
172 				{
173 					editor.contextMenu.addListener( function()
174 						{
175 							return {
176 								cut : CKEDITOR.TRISTATE_DISABLED ,
177 								copy : CKEDITOR.TRISTATE_DISABLED,
178 								paste : CKEDITOR.TRISTATE_DISABLED };
179 						});
180 				}
181 			}
182 		});
183 })();
184