source: sandbox/3.0/phpgwapi/js/ckeditor/_source/plugins/clipboard/plugin.js @ 2862

Revision 2862, 10.6 KB checked in by rodsouza, 14 years ago (diff)

Ticket #663 - Atualizando e centralizando o CKEditor (v. 3.2.1)

Line 
1/*
2Copyright (c) 2003-2010, CKSource - Frederico Knabben. All rights reserved.
3For 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                // IE6/7: document.execCommand has problem to paste into positioned element.
32                ( CKEDITOR.env.version > 7 ? doc.$ : doc.$.selection.createRange() ) [ 'execCommand' ]( command );
33
34                body.removeListener( command, onExec );
35
36                return enabled;
37        };
38
39        // Attempts to execute the Cut and Copy operations.
40        var tryToCutCopy =
41                CKEDITOR.env.ie ?
42                        function( editor, type )
43                        {
44                                return execIECommand( editor, type );
45                        }
46                :               // !IE.
47                        function( editor, type )
48                        {
49                                try
50                                {
51                                        // Other browsers throw an error if the command is disabled.
52                                        return editor.document.$.execCommand( type );
53                                }
54                                catch( e )
55                                {
56                                        return false;
57                                }
58                        };
59
60        // A class that represents one of the cut or copy commands.
61        var cutCopyCmd = function( type )
62        {
63                this.type = type;
64                this.canUndo = ( this.type == 'cut' );          // We can't undo copy to clipboard.
65        };
66
67        cutCopyCmd.prototype =
68        {
69                exec : function( editor, data )
70                {
71                        var success = tryToCutCopy( editor, this.type );
72
73                        if ( !success )
74                                alert( editor.lang.clipboard[ this.type + 'Error' ] );          // Show cutError or copyError.
75
76                        return success;
77                }
78        };
79
80        // Paste command.
81        var pasteCmd =
82        {
83                canUndo : false,
84
85                exec :
86                        CKEDITOR.env.ie ?
87                                function( editor )
88                                {
89                                        // Prevent IE from pasting at the begining of the document.
90                                        editor.focus();
91
92                                        if ( !editor.document.getBody().fire( 'beforepaste' )
93                                                 && !execIECommand( editor, 'paste' ) )
94                                        {
95                                                editor.fire( 'pasteDialog' );
96                                                return false;
97                                        }
98                                }
99                        :
100                                function( editor )
101                                {
102                                        try
103                                        {
104                                                if ( !editor.document.getBody().fire( 'beforepaste' )
105                                                         && !editor.document.$.execCommand( 'Paste', false, null ) )
106                                                {
107                                                        throw 0;
108                                                }
109                                        }
110                                        catch ( e )
111                                        {
112                                                setTimeout( function()
113                                                        {
114                                                                editor.fire( 'pasteDialog' );
115                                                        }, 0 );
116                                                return false;
117                                        }
118                                }
119        };
120
121        // Listens for some clipboard related keystrokes, so they get customized.
122        var onKey = function( event )
123        {
124                if ( this.mode != 'wysiwyg' )
125                        return;
126
127                switch ( event.data.keyCode )
128                {
129                        // Paste
130                        case CKEDITOR.CTRL + 86 :               // CTRL+V
131                        case CKEDITOR.SHIFT + 45 :              // SHIFT+INS
132
133                                var body = this.document.getBody();
134
135                                // Simulate 'beforepaste' event for all none-IEs.
136                                if ( !CKEDITOR.env.ie && body.fire( 'beforepaste' ) )
137                                        event.cancel();
138                                // Simulate 'paste' event for Opera/Firefox2.
139                                else if ( CKEDITOR.env.opera
140                                                 || CKEDITOR.env.gecko && CKEDITOR.env.version < 10900 )
141                                        body.fire( 'paste' );
142                                return;
143
144                        // Cut
145                        case CKEDITOR.CTRL + 88 :               // CTRL+X
146                        case CKEDITOR.SHIFT + 46 :              // SHIFT+DEL
147
148                                // Save Undo snapshot.
149                                var editor = this;
150                                this.fire( 'saveSnapshot' );            // Save before paste
151                                setTimeout( function()
152                                        {
153                                                editor.fire( 'saveSnapshot' );          // Save after paste
154                                        }, 0 );
155                }
156        };
157
158        // Allow to peek clipboard content by redirecting the
159        // pasting content into a temporary bin and grab the content of it.
160        function getClipboardData( evt, mode, callback )
161        {
162                var doc = this.document;
163
164                // Avoid recursions on 'paste' event for IE.
165                if ( CKEDITOR.env.ie && doc.getById( 'cke_pastebin' ) )
166                        return;
167
168                // If the browser supports it, get the data directly
169                if (mode == 'text' && evt.data && evt.data.$.clipboardData)
170                {
171                        // evt.data.$.clipboardData.types contains all the flavours in Mac's Safari, but not on windows.
172                        var plain = evt.data.$.clipboardData.getData( 'text/plain' );
173                        if (plain)
174                        {
175                                evt.data.preventDefault();
176                                callback( plain );
177                                return;
178                        }
179                }
180
181                var sel = this.getSelection(),
182                        range = new CKEDITOR.dom.range( doc );
183
184                // Create container to paste into
185                var pastebin = new CKEDITOR.dom.element( mode == 'text' ? 'textarea' : 'div', doc );
186                pastebin.setAttribute( 'id', 'cke_pastebin' );
187                // Safari requires a filler node inside the div to have the content pasted into it. (#4882)
188                CKEDITOR.env.webkit && pastebin.append( doc.createText( '\xa0' ) );
189                doc.getBody().append( pastebin );
190
191                // It's definitely a better user experience if we make the paste-bin pretty unnoticed
192                // by pulling it off the screen.
193                pastebin.setStyles(
194                        {
195                                position : 'absolute',
196                                left : '-1000px',
197                                // Position the bin exactly at the position of the selected element
198                                // to avoid any subsequent document scroll.
199                                top : sel.getStartElement().getDocumentPosition().y + 'px',
200                                width : '1px',
201                                height : '1px',
202                                overflow : 'hidden'
203                        });
204
205                var bms = sel.createBookmarks();
206
207                // Turn off design mode temporarily before give focus to the paste bin.
208                if ( mode == 'text' )
209                {
210                        if ( CKEDITOR.env.ie )
211                        {
212                                var ieRange = doc.getBody().$.createTextRange();
213                                ieRange.moveToElementText( pastebin.$ );
214                                ieRange.execCommand( 'Paste' );
215                                evt.data.preventDefault();
216                        }
217                        else
218                        {
219                                doc.$.designMode = 'off';
220                                pastebin.$.focus();
221                        }
222                }
223                else
224                {
225                        range.setStartAt( pastebin, CKEDITOR.POSITION_AFTER_START );
226                        range.setEndAt( pastebin, CKEDITOR.POSITION_BEFORE_END );
227                        range.select( true );
228                }
229
230                // Wait a while and grab the pasted contents
231                window.setTimeout( function()
232                {
233                        mode == 'text' && !CKEDITOR.env.ie && ( doc.$.designMode = 'on' );
234                        pastebin.remove();
235
236                        // Grab the HTML contents.
237                        // We need to look for a apple style wrapper on webkit it also adds
238                        // a div wrapper if you copy/paste the body of the editor.
239                        // Remove hidden div and restore selection.
240                        var bogusSpan;
241                        pastebin = ( CKEDITOR.env.webkit
242                                                 && ( bogusSpan = pastebin.getFirst() )
243                                                 && ( bogusSpan.is && bogusSpan.hasClass( 'Apple-style-span' ) ) ?
244                                                        bogusSpan : pastebin );
245
246                        sel.selectBookmarks( bms );
247                        callback( pastebin[ 'get' + ( mode == 'text' ? 'Value' : 'Html' ) ]() );
248                }, 0 );
249        }
250
251        // Register the plugin.
252        CKEDITOR.plugins.add( 'clipboard',
253                {
254                        requires : [ 'dialog', 'htmldataprocessor' ],
255                        init : function( editor )
256                        {
257                                // Inserts processed data into the editor at the end of the
258                                // events chain.
259                                editor.on( 'paste', function( evt )
260                                        {
261                                                var data = evt.data;
262                                                if ( data[ 'html' ] )
263                                                        editor.insertHtml( data[ 'html' ] );
264                                                else if ( data[ 'text' ] )
265                                                        editor.insertText( data[ 'text' ] );
266
267                                        }, null, null, 1000 );
268
269                                editor.on( 'pasteDialog', function( evt )
270                                        {
271                                                setTimeout( function()
272                                                {
273                                                        // Open default paste dialog.
274                                                        editor.openDialog( 'paste' );
275                                                }, 0 );
276                                        });
277
278                                function addButtonCommand( buttonName, commandName, command, ctxMenuOrder )
279                                {
280                                        var lang = editor.lang[ commandName ];
281
282                                        editor.addCommand( commandName, command );
283                                        editor.ui.addButton( buttonName,
284                                                {
285                                                        label : lang,
286                                                        command : commandName
287                                                });
288
289                                        // If the "menu" plugin is loaded, register the menu item.
290                                        if ( editor.addMenuItems )
291                                        {
292                                                editor.addMenuItem( commandName,
293                                                        {
294                                                                label : lang,
295                                                                command : commandName,
296                                                                group : 'clipboard',
297                                                                order : ctxMenuOrder
298                                                        });
299                                        }
300                                }
301
302                                addButtonCommand( 'Cut', 'cut', new cutCopyCmd( 'cut' ), 1 );
303                                addButtonCommand( 'Copy', 'copy', new cutCopyCmd( 'copy' ), 4 );
304                                addButtonCommand( 'Paste', 'paste', pasteCmd, 8 );
305
306                                CKEDITOR.dialog.add( 'paste', CKEDITOR.getUrl( this.path + 'dialogs/paste.js' ) );
307
308                                editor.on( 'key', onKey, editor );
309
310                                var mode = editor.config.forcePasteAsPlainText ? 'text' : 'html';
311
312                                // We'll be catching all pasted content in one line, regardless of whether the
313                                // it's introduced by a document command execution (e.g. toolbar buttons) or
314                                // user paste behaviors. (e.g. Ctrl-V)
315                                editor.on( 'contentDom', function()
316                                {
317                                        var body = editor.document.getBody();
318                                        body.on( ( (mode == 'text' && CKEDITOR.env.ie) || CKEDITOR.env.webkit ) ? 'paste' : 'beforepaste',
319                                                function( evt )
320                                                {
321                                                        if ( depressBeforePasteEvent )
322                                                                return;
323
324                                                        getClipboardData.call( editor, evt, mode, function ( data )
325                                                        {
326                                                                // The very last guard to make sure the
327                                                                // paste has successfully happened.
328                                                                if ( !data )
329                                                                        return;
330
331                                                                var dataTransfer = {};
332                                                                dataTransfer[ mode ] = data;
333                                                                editor.fire( 'paste', dataTransfer );
334                                                        } );
335                                                });
336
337                                });
338
339                                // If the "contextmenu" plugin is loaded, register the listeners.
340                                if ( editor.contextMenu )
341                                {
342                                        var depressBeforePasteEvent;
343                                        function stateFromNamedCommand( command )
344                                        {
345                                                // IE Bug: queryCommandEnabled('paste') fires also 'beforepaste',
346                                                // guard to distinguish from the ordinary sources( either
347                                                // keyboard paste or execCommand ) (#4874).
348                                                CKEDITOR.env.ie && command == 'Paste'&& ( depressBeforePasteEvent = 1 );
349
350                                                var retval = editor.document.$.queryCommandEnabled( command ) ? CKEDITOR.TRISTATE_OFF : CKEDITOR.TRISTATE_DISABLED;
351                                                depressBeforePasteEvent = 0;
352                                                return retval;
353                                        }
354
355                                        editor.contextMenu.addListener( function()
356                                                {
357                                                        return {
358                                                                cut : stateFromNamedCommand( 'Cut' ),
359
360                                                                // Browser bug: 'Cut' has the correct states for both Copy and Cut.
361                                                                copy : stateFromNamedCommand( 'Cut' ),
362                                                                paste : CKEDITOR.env.webkit ? CKEDITOR.TRISTATE_OFF : stateFromNamedCommand( 'Paste' )
363                                                        };
364                                                });
365                                }
366                        }
367                });
368})();
369
370/**
371 * Fired when a clipboard operation is about to be taken into the editor.
372 * Listeners can manipulate the data to be pasted before having it effectively
373 * inserted into the document.
374 * @name CKEDITOR.editor#paste
375 * @since 3.1
376 * @event
377 * @param {String} [data.html] The HTML data to be pasted. If not available, e.data.text will be defined.
378 * @param {String} [data.text] The plain text data to be pasted, available when plain text operations are to used. If not available, e.data.html will be defined.
379 */
Note: See TracBrowser for help on using the repository browser.