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