JasonWoof Got questions, comments, patches, etc.? Contact Jason Woofenden
vanilla ckeditor-3.0
[ckeditor.git] / _source / plugins / clipboard / plugin.js
diff --git a/_source/plugins/clipboard/plugin.js b/_source/plugins/clipboard/plugin.js
new file mode 100644 (file)
index 0000000..c063b41
--- /dev/null
@@ -0,0 +1,208 @@
+/*\r
+Copyright (c) 2003-2009, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.html or http://ckeditor.com/license\r
+*/\r
+\r
+/**\r
+ * @file Clipboard support\r
+ */\r
+\r
+(function()\r
+{\r
+       // Tries to execute any of the paste, cut or copy commands in IE. Returns a\r
+       // boolean indicating that the operation succeeded.\r
+       var execIECommand = function( editor, command )\r
+       {\r
+               var doc = editor.document,\r
+                       body = doc.getBody();\r
+\r
+               var     enabled = false;\r
+               var onExec = function()\r
+               {\r
+                       enabled = true;\r
+               };\r
+\r
+               // The following seems to be the only reliable way to detect that\r
+               // clipboard commands are enabled in IE. It will fire the\r
+               // onpaste/oncut/oncopy events only if the security settings allowed\r
+               // the command to execute.\r
+               body.on( command, onExec );\r
+\r
+               doc.$.execCommand( command );\r
+\r
+               body.removeListener( command, onExec );\r
+\r
+               return enabled;\r
+       };\r
+\r
+       // Attempts to execute the Cut and Copy operations.\r
+       var tryToCutCopy =\r
+               CKEDITOR.env.ie ?\r
+                       function( editor, type )\r
+                       {\r
+                               return execIECommand( editor, type );\r
+                       }\r
+               :               // !IE.\r
+                       function( editor, type )\r
+                       {\r
+                               try\r
+                               {\r
+                                       // Other browsers throw an error if the command is disabled.\r
+                                       return editor.document.$.execCommand( type );\r
+                               }\r
+                               catch( e )\r
+                               {\r
+                                       return false;\r
+                               }\r
+                       };\r
+\r
+       // A class that represents one of the cut or copy commands.\r
+       var cutCopyCmd = function( type )\r
+       {\r
+               this.type = type;\r
+               this.canUndo = ( this.type == 'cut' );          // We can't undo copy to clipboard.\r
+       };\r
+\r
+       cutCopyCmd.prototype =\r
+       {\r
+               exec : function( editor, data )\r
+               {\r
+                       var success = tryToCutCopy( editor, this.type );\r
+\r
+                       if ( !success )\r
+                               alert( editor.lang.clipboard[ this.type + 'Error' ] );          // Show cutError or copyError.\r
+\r
+                       return success;\r
+               }\r
+       };\r
+\r
+       // Paste command.\r
+       var pasteCmd =\r
+               CKEDITOR.env.ie ?\r
+                       {\r
+                               exec : function( editor, data )\r
+                               {\r
+                                       // Prevent IE from pasting at the begining of the document.\r
+                                       editor.focus();\r
+\r
+                                       if ( !editor.fire( 'beforePaste' )\r
+                                               && !execIECommand( editor, 'paste' ) )\r
+                                       {\r
+                                                       editor.openDialog( 'paste' );\r
+                                       }\r
+                               }\r
+                       }\r
+               :\r
+                       {\r
+                               exec : function( editor )\r
+                               {\r
+                                       try\r
+                                       {\r
+                                               if ( !editor.fire( 'beforePaste' )\r
+                                                       && !editor.document.$.execCommand( 'Paste', false, null ) )\r
+                                               {\r
+                                                       throw 0;\r
+                                               }\r
+                                       }\r
+                                       catch ( e )\r
+                                       {\r
+                                               // Open the paste dialog.\r
+                                               editor.openDialog( 'paste' );\r
+                                       }\r
+                               }\r
+                       };\r
+\r
+       // Listens for some clipboard related keystrokes, so they get customized.\r
+       var onKey = function( event )\r
+       {\r
+               switch ( event.data.keyCode )\r
+               {\r
+                       // Paste\r
+                       case CKEDITOR.CTRL + 86 :               // CTRL+V\r
+                       case CKEDITOR.SHIFT + 45 :              // SHIFT+INS\r
+\r
+                               var editor = this;\r
+                               editor.fire( 'saveSnapshot' );          // Save before paste\r
+\r
+                               if ( editor.fire( 'beforePaste' ) )\r
+                                       event.cancel();\r
+\r
+                               setTimeout( function()\r
+                                       {\r
+                                               editor.fire( 'saveSnapshot' );          // Save after paste\r
+                                       }, 0 );\r
+                               return;\r
+\r
+                       // Cut\r
+                       case CKEDITOR.CTRL + 88 :               // CTRL+X\r
+                       case CKEDITOR.SHIFT + 46 :              // SHIFT+DEL\r
+\r
+                               // Save Undo snapshot.\r
+                               editor = this;\r
+                               editor.fire( 'saveSnapshot' );          // Save before paste\r
+                               setTimeout( function()\r
+                                       {\r
+                                               editor.fire( 'saveSnapshot' );          // Save after paste\r
+                                       }, 0 );\r
+               }\r
+       };\r
+\r
+       // Register the plugin.\r
+       CKEDITOR.plugins.add( 'clipboard',\r
+               {\r
+                       init : function( editor )\r
+                       {\r
+                               function addButtonCommand( buttonName, commandName, command, ctxMenuOrder )\r
+                               {\r
+                                       var lang = editor.lang[ commandName ];\r
+\r
+                                       editor.addCommand( commandName, command );\r
+                                       editor.ui.addButton( buttonName,\r
+                                               {\r
+                                                       label : lang,\r
+                                                       command : commandName\r
+                                               });\r
+\r
+                                       // If the "menu" plugin is loaded, register the menu item.\r
+                                       if ( editor.addMenuItems )\r
+                                       {\r
+                                               editor.addMenuItem( commandName,\r
+                                                       {\r
+                                                               label : lang,\r
+                                                               command : commandName,\r
+                                                               group : 'clipboard',\r
+                                                               order : ctxMenuOrder\r
+                                                       });\r
+                                       }\r
+                               }\r
+\r
+                               addButtonCommand( 'Cut', 'cut', new cutCopyCmd( 'cut' ), 1 );\r
+                               addButtonCommand( 'Copy', 'copy', new cutCopyCmd( 'copy' ), 4 );\r
+                               addButtonCommand( 'Paste', 'paste', pasteCmd, 8 );\r
+\r
+                               CKEDITOR.dialog.add( 'paste', CKEDITOR.getUrl( this.path + 'dialogs/paste.js' ) );\r
+\r
+                               editor.on( 'key', onKey, editor );\r
+\r
+                               // If the "contextmenu" plugin is loaded, register the listeners.\r
+                               if ( editor.contextMenu )\r
+                               {\r
+                                       function stateFromNamedCommand( command )\r
+                                       {\r
+                                               return editor.document.$.queryCommandEnabled( command ) ? CKEDITOR.TRISTATE_OFF : CKEDITOR.TRISTATE_DISABLED;\r
+                                       }\r
+\r
+                                       editor.contextMenu.addListener( function()\r
+                                               {\r
+                                                       return {\r
+                                                               cut : stateFromNamedCommand( 'Cut' ),\r
+\r
+                                                               // Browser bug: 'Cut' has the correct states for both Copy and Cut.\r
+                                                               copy : stateFromNamedCommand( 'Cut' ),\r
+                                                               paste : CKEDITOR.env.webkit ? CKEDITOR.TRISTATE_OFF : stateFromNamedCommand( 'Paste' )\r
+                                                       };\r
+                                               });\r
+                               }\r
+                       }\r
+               });\r
+})();\r