JasonWoof Got questions, comments, patches, etc.? Contact Jason Woofenden
vanilla ckeditor-4.0_full
[ckeditor.git] / _source / plugins / clipboard / plugin.js
diff --git a/_source/plugins/clipboard/plugin.js b/_source/plugins/clipboard/plugin.js
deleted file mode 100644 (file)
index 558ffd7..0000000
+++ /dev/null
@@ -1,509 +0,0 @@
-/*\r
-Copyright (c) 2003-2013, 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
-               // IE6/7: document.execCommand has problem to paste into positioned element.\r
-               ( CKEDITOR.env.version > 7 ? doc.$ : doc.$.selection.createRange() ) [ '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, false, null );\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
-               this.startDisabled = true;\r
-       };\r
-\r
-       cutCopyCmd.prototype =\r
-       {\r
-               exec : function( editor, data )\r
-               {\r
-                       this.type == 'cut' && fixCut( editor );\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
-       {\r
-               canUndo : false,\r
-\r
-               exec :\r
-                       CKEDITOR.env.ie ?\r
-                               function( editor )\r
-                               {\r
-                                       // Prevent IE from pasting at the begining of the document.\r
-                                       editor.focus();\r
-\r
-                                       if ( !editor.document.getBody().fire( 'beforepaste' )\r
-                                                && !execIECommand( editor, 'paste' ) )\r
-                                       {\r
-                                               editor.fire( 'pasteDialog' );\r
-                                               return false;\r
-                                       }\r
-                               }\r
-                       :\r
-                               function( editor )\r
-                               {\r
-                                       try\r
-                                       {\r
-                                               if ( !editor.document.getBody().fire( 'beforepaste' )\r
-                                                        && !editor.document.$.execCommand( 'Paste', false, null ) )\r
-                                               {\r
-                                                       throw 0;\r
-                                               }\r
-                                       }\r
-                                       catch ( e )\r
-                                       {\r
-                                               setTimeout( function()\r
-                                                       {\r
-                                                               editor.fire( 'pasteDialog' );\r
-                                                       }, 0 );\r
-                                               return false;\r
-                                       }\r
-                               }\r
-       };\r
-\r
-       // Listens for some clipboard related keystrokes, so they get customized.\r
-       var onKey = function( event )\r
-       {\r
-               if ( this.mode != 'wysiwyg' )\r
-                       return;\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 body = this.document.getBody();\r
-\r
-                               // 1. Opera just misses the "paste" event.\r
-                               // 2. Firefox's "paste" event comes too late to have the plain\r
-                               // text paste bin to work.\r
-                               if ( CKEDITOR.env.opera || CKEDITOR.env.gecko )\r
-                                       body.fire( 'paste' );\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
-                               var editor = this;\r
-                               this.fire( 'saveSnapshot' );            // Save before paste\r
-                               setTimeout( function()\r
-                                       {\r
-                                               editor.fire( 'saveSnapshot' );          // Save after paste\r
-                                       }, 0 );\r
-               }\r
-       };\r
-\r
-       function cancel( evt ) { evt.cancel(); }\r
-\r
-       // Allow to peek clipboard content by redirecting the\r
-       // pasting content into a temporary bin and grab the content of it.\r
-       function getClipboardData( evt, mode, callback )\r
-       {\r
-               var doc = this.document;\r
-\r
-               // Avoid recursions on 'paste' event or consequent paste too fast. (#5730)\r
-               if ( doc.getById( 'cke_pastebin' ) )\r
-                       return;\r
-\r
-               // If the browser supports it, get the data directly\r
-               if ( mode == 'text' && evt.data && evt.data.$.clipboardData )\r
-               {\r
-                       // evt.data.$.clipboardData.types contains all the flavours in Mac's Safari, but not on windows.\r
-                       var plain = evt.data.$.clipboardData.getData( 'text/plain' );\r
-                       if ( plain )\r
-                       {\r
-                               evt.data.preventDefault();\r
-                               callback( plain );\r
-                               return;\r
-                       }\r
-               }\r
-\r
-               var sel = this.getSelection(),\r
-                       range = new CKEDITOR.dom.range( doc );\r
-\r
-               // Create container to paste into\r
-               var pastebin = new CKEDITOR.dom.element( mode == 'text' ? 'textarea' : CKEDITOR.env.webkit ? 'body' : 'div', doc );\r
-               pastebin.setAttribute( 'id', 'cke_pastebin' );\r
-               // Safari requires a filler node inside the div to have the content pasted into it. (#4882)\r
-               CKEDITOR.env.webkit && pastebin.append( doc.createText( '\xa0' ) );\r
-               doc.getBody().append( pastebin );\r
-\r
-               pastebin.setStyles(\r
-                       {\r
-                               position : 'absolute',\r
-                               // Position the bin exactly at the position of the selected element\r
-                               // to avoid any subsequent document scroll.\r
-                               top : sel.getStartElement().getDocumentPosition().y + 'px',\r
-                               width : '1px',\r
-                               height : '1px',\r
-                               overflow : 'hidden'\r
-                       });\r
-\r
-               // It's definitely a better user experience if we make the paste-bin pretty unnoticed\r
-               // by pulling it off the screen.\r
-               pastebin.setStyle( this.config.contentsLangDirection == 'ltr' ? 'left' : 'right', '-1000px' );\r
-\r
-               var bms = sel.createBookmarks();\r
-\r
-               this.on( 'selectionChange', cancel, null, null, 0 );\r
-\r
-               // Turn off design mode temporarily before give focus to the paste bin.\r
-               if ( mode == 'text' )\r
-                       pastebin.$.focus();\r
-               else\r
-               {\r
-                       range.setStartAt( pastebin, CKEDITOR.POSITION_AFTER_START );\r
-                       range.setEndAt( pastebin, CKEDITOR.POSITION_BEFORE_END );\r
-                       range.select( true );\r
-               }\r
-\r
-               var editor  = this;\r
-               // Wait a while and grab the pasted contents\r
-               window.setTimeout( function()\r
-               {\r
-                       // Restore properly the document focus. (#5684, #8849)\r
-                       editor.document.getBody().focus();\r
-\r
-                       editor.removeListener( 'selectionChange', cancel );\r
-\r
-                       // IE7: selection must go before removing paste bin. (#8691)\r
-                       if ( CKEDITOR.env.ie7Compat )\r
-                       {\r
-                               sel.selectBookmarks( bms );\r
-                               pastebin.remove();\r
-                       }\r
-                       // Webkit: selection must go after removing paste bin. (#8921)\r
-                       else\r
-                       {\r
-                               pastebin.remove();\r
-                               sel.selectBookmarks( bms );\r
-                       }\r
-\r
-                       // Grab the HTML contents.\r
-                       // We need to look for a apple style wrapper on webkit it also adds\r
-                       // a div wrapper if you copy/paste the body of the editor.\r
-                       // Remove hidden div and restore selection.\r
-                       var bogusSpan;\r
-                       pastebin = ( CKEDITOR.env.webkit\r
-                                                && ( bogusSpan = pastebin.getFirst() )\r
-                                                && ( bogusSpan.is && bogusSpan.hasClass( 'Apple-style-span' ) ) ?\r
-                                                       bogusSpan : pastebin );\r
-\r
-                       callback( pastebin[ 'get' + ( mode == 'text' ? 'Value' : 'Html' ) ]() );\r
-               }, 0 );\r
-       }\r
-\r
-       // Cutting off control type element in IE standards breaks the selection entirely. (#4881)\r
-       function fixCut( editor )\r
-       {\r
-               if ( !CKEDITOR.env.ie || CKEDITOR.env.quirks )\r
-                       return;\r
-\r
-               var sel = editor.getSelection();\r
-               var control;\r
-               if( ( sel.getType() == CKEDITOR.SELECTION_ELEMENT ) && ( control = sel.getSelectedElement() ) )\r
-               {\r
-                       var range = sel.getRanges()[ 0 ];\r
-                       var dummy = editor.document.createText( '' );\r
-                       dummy.insertBefore( control );\r
-                       range.setStartBefore( dummy );\r
-                       range.setEndAfter( control );\r
-                       sel.selectRanges( [ range ] );\r
-\r
-                       // Clear up the fix if the paste wasn't succeeded.\r
-                       setTimeout( function()\r
-                       {\r
-                               // Element still online?\r
-                               if ( control.getParent() )\r
-                               {\r
-                                       dummy.remove();\r
-                                       sel.selectElement( control );\r
-                               }\r
-                       }, 0 );\r
-               }\r
-       }\r
-\r
-       var depressBeforeEvent,\r
-               inReadOnly;\r
-       function stateFromNamedCommand( command, editor )\r
-       {\r
-               var retval;\r
-\r
-               if ( inReadOnly && command in { Paste : 1, Cut : 1 } )\r
-                       return CKEDITOR.TRISTATE_DISABLED;\r
-\r
-               if ( command == 'Paste' )\r
-               {\r
-                       // IE Bug: queryCommandEnabled('paste') fires also 'beforepaste(copy/cut)',\r
-                       // guard to distinguish from the ordinary sources (either\r
-                       // keyboard paste or execCommand) (#4874).\r
-                       CKEDITOR.env.ie && ( depressBeforeEvent = 1 );\r
-                       try\r
-                       {\r
-                               // Always return true for Webkit (which always returns false).\r
-                               retval = editor.document.$.queryCommandEnabled( command ) || CKEDITOR.env.webkit;\r
-                       }\r
-                       catch( er ) {}\r
-                       depressBeforeEvent = 0;\r
-               }\r
-               // Cut, Copy - check if the selection is not empty\r
-               else\r
-               {\r
-                       var sel = editor.getSelection(),\r
-                               ranges = sel && sel.getRanges();\r
-                       retval = sel && !( ranges.length == 1 && ranges[ 0 ].collapsed );\r
-               }\r
-\r
-               return retval ? CKEDITOR.TRISTATE_OFF : CKEDITOR.TRISTATE_DISABLED;\r
-       }\r
-\r
-       function setToolbarStates()\r
-       {\r
-               if ( this.mode != 'wysiwyg' )\r
-                       return;\r
-\r
-               var pasteState = stateFromNamedCommand( 'Paste', this );\r
-\r
-               this.getCommand( 'cut' ).setState( stateFromNamedCommand( 'Cut', this ) );\r
-               this.getCommand( 'copy' ).setState( stateFromNamedCommand( 'Copy', this ) );\r
-               this.getCommand( 'paste' ).setState( pasteState );\r
-               this.fire( 'pasteState', pasteState );\r
-       }\r
-\r
-       // Register the plugin.\r
-       CKEDITOR.plugins.add( 'clipboard',\r
-               {\r
-                       requires : [ 'dialog', 'htmldataprocessor' ],\r
-                       init : function( editor )\r
-                       {\r
-                               // Inserts processed data into the editor at the end of the\r
-                               // events chain.\r
-                               editor.on( 'paste', function( evt )\r
-                                       {\r
-                                               var data = evt.data;\r
-                                               if ( data[ 'html' ] )\r
-                                                       editor.insertHtml( data[ 'html' ] );\r
-                                               else if ( data[ 'text' ] )\r
-                                                       editor.insertText( data[ 'text' ] );\r
-\r
-                                               setTimeout( function () { editor.fire( 'afterPaste' ); }, 0 );\r
-\r
-                                       }, null, null, 1000 );\r
-\r
-                               editor.on( 'pasteDialog', function( evt )\r
-                                       {\r
-                                               setTimeout( function()\r
-                                               {\r
-                                                       // Open default paste dialog.\r
-                                                       editor.openDialog( 'paste' );\r
-                                               }, 0 );\r
-                                       });\r
-\r
-                               editor.on( 'pasteState', function( evt )\r
-                                       {\r
-                                               editor.getCommand( 'paste' ).setState( evt.data );\r
-                                       });\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
-                               // We'll be catching all pasted content in one line, regardless of whether the\r
-                               // it's introduced by a document command execution (e.g. toolbar buttons) or\r
-                               // user paste behaviors. (e.g. Ctrl-V)\r
-                               editor.on( 'contentDom', function()\r
-                               {\r
-                                       var body = editor.document.getBody();\r
-\r
-                                       // Intercept the paste before it actually takes place.\r
-                                       body.on( !CKEDITOR.env.ie ? 'paste' : 'beforepaste', function( evt )\r
-                                               {\r
-                                                       if ( depressBeforeEvent )\r
-                                                               return;\r
-\r
-                                                       // Dismiss the (wrong) 'beforepaste' event fired on toolbar menu open.\r
-                                                       var domEvent = evt.data && evt.data.$;\r
-                                                       if ( CKEDITOR.env.ie && domEvent && !domEvent.ctrlKey )\r
-                                                               return;\r
-\r
-                                                       // Fire 'beforePaste' event so clipboard flavor get customized\r
-                                                       // by other plugins.\r
-                                                       var eventData =  { mode : 'html' };\r
-                                                       editor.fire( 'beforePaste', eventData );\r
-\r
-                                                       getClipboardData.call( editor, evt, eventData.mode, function ( data )\r
-                                                       {\r
-                                                               // The very last guard to make sure the\r
-                                                               // paste has successfully happened.\r
-                                                               if ( !( data = CKEDITOR.tools.trim( data.replace( /<span[^>]+data-cke-bookmark[^<]*?<\/span>/ig,'' ) ) ) )\r
-                                                                       return;\r
-\r
-                                                               var dataTransfer = {};\r
-                                                               dataTransfer[ eventData.mode ] = data;\r
-                                                               editor.fire( 'paste', dataTransfer );\r
-                                                       } );\r
-                                               });\r
-\r
-                                       if ( CKEDITOR.env.ie )\r
-                                       {\r
-                                               // Dismiss the (wrong) 'beforepaste' event fired on context menu open. (#7953)\r
-                                               body.on( 'contextmenu', function()\r
-                                               {\r
-                                                       depressBeforeEvent = 1;\r
-                                                       // Important: The following timeout will be called only after menu closed.\r
-                                                       setTimeout( function() { depressBeforeEvent = 0; }, 0 );\r
-                                               } );\r
-\r
-                                               // Handle IE's late coming "paste" event when pasting from\r
-                                               // browser toolbar/context menu.\r
-                                               body.on( 'paste', function( evt )\r
-                                               {\r
-                                                       if ( !editor.document.getById( 'cke_pastebin' ) )\r
-                                                       {\r
-                                                               // Prevent native paste.\r
-                                                               evt.data.preventDefault();\r
-\r
-                                                               depressBeforeEvent = 0;\r
-                                                               // Resort to the paste command.\r
-                                                               pasteCmd.exec( editor );\r
-                                                       }\r
-                                               } );\r
-                                       }\r
-\r
-                                       body.on( 'beforecut', function() { !depressBeforeEvent && fixCut( editor ); } );\r
-\r
-                                       body.on( 'mouseup', function(){ setTimeout( function(){ setToolbarStates.call( editor ); }, 0 ); }, editor );\r
-                                       body.on( 'keyup', setToolbarStates, editor );\r
-                               });\r
-\r
-                               // For improved performance, we're checking the readOnly state on selectionChange instead of hooking a key event for that.\r
-                               editor.on( 'selectionChange', function( evt )\r
-                               {\r
-                                       inReadOnly = evt.data.selection.getRanges()[ 0 ].checkReadOnly();\r
-                                       setToolbarStates.call( editor );\r
-                               });\r
-\r
-                               // If the "contextmenu" plugin is loaded, register the listeners.\r
-                               if ( editor.contextMenu )\r
-                               {\r
-                                       editor.contextMenu.addListener( function( element, selection )\r
-                                               {\r
-                                                       var readOnly = selection.getRanges()[ 0 ].checkReadOnly();\r
-                                                       return {\r
-                                                               cut : stateFromNamedCommand( 'Cut', editor ),\r
-                                                               copy : stateFromNamedCommand( 'Copy', editor ),\r
-                                                               paste : stateFromNamedCommand( 'Paste', editor )\r
-                                                       };\r
-                                               });\r
-                               }\r
-                       }\r
-               });\r
-})();\r
-\r
-/**\r
- * Fired when a clipboard operation is about to be taken into the editor.\r
- * Listeners can manipulate the data to be pasted before having it effectively\r
- * inserted into the document.\r
- * @name CKEDITOR.editor#paste\r
- * @since 3.1\r
- * @event\r
- * @param {String} [data.html] The HTML data to be pasted. If not available, e.data.text will be defined.\r
- * @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.\r
- */\r
-\r
-/**\r
- * Internal event to open the Paste dialog\r
- * @name CKEDITOR.editor#pasteDialog\r
- * @event\r
- */\r