[ Index ]

PHP Cross Reference of Drupal 6 (gatewave)

title

Body

[close]

/sites/all/libraries/ckeditor/_source/plugins/clipboard/ -> plugin.js (source)

   1  /*

   2  Copyright (c) 2003-2010, 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          // 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              this.type == 'cut' && fixCut( editor );
  72  
  73              var success = tryToCutCopy( editor, this.type );
  74  
  75              if ( !success )
  76                  alert( editor.lang.clipboard[ this.type + 'Error' ] );        // Show cutError or copyError.

  77  
  78              return success;
  79          }
  80      };
  81  
  82      // Paste command.

  83      var pasteCmd =
  84      {
  85          canUndo : false,
  86  
  87          exec :
  88              CKEDITOR.env.ie ?
  89                  function( editor )
  90                  {
  91                      // Prevent IE from pasting at the begining of the document.

  92                      editor.focus();
  93  
  94                      if ( !editor.document.getBody().fire( 'beforepaste' )
  95                           && !execIECommand( editor, 'paste' ) )
  96                      {
  97                          editor.fire( 'pasteDialog' );
  98                          return false;
  99                      }
 100                  }
 101              :
 102                  function( editor )
 103                  {
 104                      try
 105                      {
 106                          if ( !editor.document.getBody().fire( 'beforepaste' )
 107                               && !editor.document.$.execCommand( 'Paste', false, null ) )
 108                          {
 109                              throw 0;
 110                          }
 111                      }
 112                      catch ( e )
 113                      {
 114                          setTimeout( function()
 115                              {
 116                                  editor.fire( 'pasteDialog' );
 117                              }, 0 );
 118                          return false;
 119                      }
 120                  }
 121      };
 122  
 123      // Listens for some clipboard related keystrokes, so they get customized.

 124      var onKey = function( event )
 125      {
 126          if ( this.mode != 'wysiwyg' )
 127              return;
 128  
 129          switch ( event.data.keyCode )
 130          {
 131              // Paste

 132              case CKEDITOR.CTRL + 86 :        // CTRL+V
 133              case CKEDITOR.SHIFT + 45 :        // SHIFT+INS
 134  
 135                  var body = this.document.getBody();
 136  
 137                  // Simulate 'beforepaste' event for all none-IEs.

 138                  if ( !CKEDITOR.env.ie && body.fire( 'beforepaste' ) )
 139                      event.cancel();
 140                  // Simulate 'paste' event for Opera/Firefox2.

 141                  else if ( CKEDITOR.env.opera
 142                           || CKEDITOR.env.gecko && CKEDITOR.env.version < 10900 )
 143                      body.fire( 'paste' );
 144                  return;
 145  
 146              // Cut

 147              case CKEDITOR.CTRL + 88 :        // CTRL+X
 148              case CKEDITOR.SHIFT + 46 :        // SHIFT+DEL
 149  
 150                  // Save Undo snapshot.

 151                  var editor = this;
 152                  this.fire( 'saveSnapshot' );        // Save before paste

 153                  setTimeout( function()
 154                      {
 155                          editor.fire( 'saveSnapshot' );        // Save after paste

 156                      }, 0 );
 157          }
 158      };
 159  
 160      // Allow to peek clipboard content by redirecting the

 161      // pasting content into a temporary bin and grab the content of it.

 162  	function getClipboardData( evt, mode, callback )
 163      {
 164          var doc = this.document;
 165  
 166          // Avoid recursions on 'paste' event for IE.

 167          if ( CKEDITOR.env.ie && doc.getById( 'cke_pastebin' ) )
 168              return;
 169  
 170          // If the browser supports it, get the data directly

 171          if (mode == 'text' && evt.data && evt.data.$.clipboardData)
 172          {
 173              // evt.data.$.clipboardData.types contains all the flavours in Mac's Safari, but not on windows.

 174              var plain = evt.data.$.clipboardData.getData( 'text/plain' );
 175              if (plain)
 176              {
 177                  evt.data.preventDefault();
 178                  callback( plain );
 179                  return;
 180              }
 181          }
 182  
 183          var sel = this.getSelection(),
 184              range = new CKEDITOR.dom.range( doc );
 185  
 186          // Create container to paste into

 187          var pastebin = new CKEDITOR.dom.element( mode == 'text' ? 'textarea' : CKEDITOR.env.webkit ? 'body' : 'div', doc );
 188          pastebin.setAttribute( 'id', 'cke_pastebin' );
 189          // Safari requires a filler node inside the div to have the content pasted into it. (#4882)

 190          CKEDITOR.env.webkit && pastebin.append( doc.createText( '\xa0' ) );
 191          doc.getBody().append( pastebin );
 192  
 193          pastebin.setStyles(
 194              {
 195                  position : 'absolute',
 196                  // Position the bin exactly at the position of the selected element

 197                  // to avoid any subsequent document scroll.

 198                  top : sel.getStartElement().getDocumentPosition().y + 'px',
 199                  width : '1px',
 200                  height : '1px',
 201                  overflow : 'hidden'
 202              });
 203  
 204          // It's definitely a better user experience if we make the paste-bin pretty unnoticed

 205          // by pulling it off the screen.

 206          pastebin.setStyle( this.config.contentsLangDirection == 'ltr' ? 'left' : 'right', '-1000px' );
 207  
 208          var bms = sel.createBookmarks();
 209  
 210          // Turn off design mode temporarily before give focus to the paste bin.

 211          if ( mode == 'text' )
 212          {
 213              if ( CKEDITOR.env.ie )
 214              {
 215                  var ieRange = doc.getBody().$.createTextRange();
 216                  ieRange.moveToElementText( pastebin.$ );
 217                  ieRange.execCommand( 'Paste' );
 218                  evt.data.preventDefault();
 219              }
 220              else
 221              {
 222                  doc.$.designMode = 'off';
 223                  pastebin.$.focus();
 224              }
 225          }
 226          else
 227          {
 228              range.setStartAt( pastebin, CKEDITOR.POSITION_AFTER_START );
 229              range.setEndAt( pastebin, CKEDITOR.POSITION_BEFORE_END );
 230              range.select( true );
 231          }
 232  
 233          // Wait a while and grab the pasted contents

 234          window.setTimeout( function()
 235          {
 236              mode == 'text' && !CKEDITOR.env.ie && ( doc.$.designMode = 'on' );
 237              pastebin.remove();
 238  
 239              // Grab the HTML contents.

 240              // We need to look for a apple style wrapper on webkit it also adds

 241              // a div wrapper if you copy/paste the body of the editor.

 242              // Remove hidden div and restore selection.

 243              var bogusSpan;
 244              pastebin = ( CKEDITOR.env.webkit
 245                           && ( bogusSpan = pastebin.getFirst() )
 246                           && ( bogusSpan.is && bogusSpan.hasClass( 'Apple-style-span' ) ) ?
 247                              bogusSpan : pastebin );
 248  
 249              sel.selectBookmarks( bms );
 250              callback( pastebin[ 'get' + ( mode == 'text' ? 'Value' : 'Html' ) ]() );
 251          }, 0 );
 252      }
 253  
 254      // Cutting off control type element in IE standards breaks the selection entirely. (#4881)

 255  	function fixCut( editor )
 256      {
 257          if ( !CKEDITOR.env.ie || editor.document.$.compatMode == 'BackCompat' )
 258              return;
 259  
 260          var sel = editor.getSelection();
 261          var control;
 262          if( ( sel.getType() == CKEDITOR.SELECTION_ELEMENT ) && ( control = sel.getSelectedElement() ) )
 263          {
 264              var range = sel.getRanges()[ 0 ];
 265              var dummy = editor.document.createText( '' );
 266              dummy.insertBefore( control );
 267              range.setStartBefore( dummy );
 268              range.setEndAfter( control );
 269              sel.selectRanges( [ range ] );
 270  
 271              // Clear up the fix if the paste wasn't succeeded.

 272              setTimeout( function()
 273              {
 274                  // Element still online?

 275                  if ( control.getParent() )
 276                  {
 277                      dummy.remove();
 278                      sel.selectElement( control );
 279                  }
 280              }, 0 );
 281          }
 282      }
 283  
 284      // Register the plugin.

 285      CKEDITOR.plugins.add( 'clipboard',
 286          {
 287              requires : [ 'dialog', 'htmldataprocessor' ],
 288              init : function( editor )
 289              {
 290                  // Inserts processed data into the editor at the end of the

 291                  // events chain.

 292                  editor.on( 'paste', function( evt )
 293                      {
 294                          var data = evt.data;
 295                          if ( data[ 'html' ] )
 296                              editor.insertHtml( data[ 'html' ] );
 297                          else if ( data[ 'text' ] )
 298                              editor.insertText( data[ 'text' ] );
 299  
 300                      }, null, null, 1000 );
 301  
 302                  editor.on( 'pasteDialog', function( evt )
 303                      {
 304                          setTimeout( function()
 305                          {
 306                              // Open default paste dialog.

 307                              editor.openDialog( 'paste' );
 308                          }, 0 );
 309                      });
 310  
 311  				function addButtonCommand( buttonName, commandName, command, ctxMenuOrder )
 312                  {
 313                      var lang = editor.lang[ commandName ];
 314  
 315                      editor.addCommand( commandName, command );
 316                      editor.ui.addButton( buttonName,
 317                          {
 318                              label : lang,
 319                              command : commandName
 320                          });
 321  
 322                      // If the "menu" plugin is loaded, register the menu item.

 323                      if ( editor.addMenuItems )
 324                      {
 325                          editor.addMenuItem( commandName,
 326                              {
 327                                  label : lang,
 328                                  command : commandName,
 329                                  group : 'clipboard',
 330                                  order : ctxMenuOrder
 331                              });
 332                      }
 333                  }
 334  
 335                  addButtonCommand( 'Cut', 'cut', new cutCopyCmd( 'cut' ), 1 );
 336                  addButtonCommand( 'Copy', 'copy', new cutCopyCmd( 'copy' ), 4 );
 337                  addButtonCommand( 'Paste', 'paste', pasteCmd, 8 );
 338  
 339                  CKEDITOR.dialog.add( 'paste', CKEDITOR.getUrl( this.path + 'dialogs/paste.js' ) );
 340  
 341                  editor.on( 'key', onKey, editor );
 342  
 343                  var mode = editor.config.forcePasteAsPlainText ? 'text' : 'html';
 344  
 345                  // We'll be catching all pasted content in one line, regardless of whether the

 346                  // it's introduced by a document command execution (e.g. toolbar buttons) or

 347                  // user paste behaviors. (e.g. Ctrl-V)

 348                  editor.on( 'contentDom', function()
 349                  {
 350                      var body = editor.document.getBody();
 351                      body.on( ( (mode == 'text' && CKEDITOR.env.ie) || CKEDITOR.env.webkit ) ? 'paste' : 'beforepaste',
 352                          function( evt )
 353                          {
 354                              if ( depressBeforeEvent )
 355                                  return;
 356  
 357                              getClipboardData.call( editor, evt, mode, function ( data )
 358                              {
 359                                  // The very last guard to make sure the

 360                                  // paste has successfully happened.

 361                                  if ( !data )
 362                                      return;
 363  
 364                                  var dataTransfer = {};
 365                                  dataTransfer[ mode ] = data;
 366                                  editor.fire( 'paste', dataTransfer );
 367                              } );
 368                          });
 369  
 370                      body.on( 'beforecut', function() { !depressBeforeEvent && fixCut( editor ); } );
 371                  });
 372  
 373                  // If the "contextmenu" plugin is loaded, register the listeners.

 374                  if ( editor.contextMenu )
 375                  {
 376                      var depressBeforeEvent;
 377  					function stateFromNamedCommand( command )
 378                      {
 379                          // IE Bug: queryCommandEnabled('paste') fires also 'beforepaste(copy/cut)',

 380                          // guard to distinguish from the ordinary sources( either

 381                          // keyboard paste or execCommand ) (#4874).

 382                          CKEDITOR.env.ie && ( depressBeforeEvent = 1 );
 383  
 384                          var retval = editor.document.$.queryCommandEnabled( command ) ? CKEDITOR.TRISTATE_OFF : CKEDITOR.TRISTATE_DISABLED;
 385                          depressBeforeEvent = 0;
 386                          return retval;
 387                      }
 388  
 389                      editor.contextMenu.addListener( function( element, selection )
 390                          {
 391                              var readOnly = selection.getCommonAncestor().isReadOnly();
 392                              return {
 393                                  cut : !readOnly && stateFromNamedCommand( 'Cut' ),
 394                                  copy : stateFromNamedCommand( 'Copy' ),
 395                                  paste : !readOnly && ( CKEDITOR.env.webkit ? CKEDITOR.TRISTATE_OFF : stateFromNamedCommand( 'Paste' ) )
 396                              };
 397                          });
 398                  }
 399              }
 400          });
 401  })();
 402  
 403  /**

 404   * Fired when a clipboard operation is about to be taken into the editor.

 405   * Listeners can manipulate the data to be pasted before having it effectively

 406   * inserted into the document.

 407   * @name CKEDITOR.editor#paste

 408   * @since 3.1

 409   * @event

 410   * @param {String} [data.html] The HTML data to be pasted. If not available, e.data.text will be defined.

 411   * @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.

 412   */


Generated: Thu Mar 24 11:18:33 2011 Cross-referenced by PHPXref 0.7