JasonWoof Got questions, comments, patches, etc.? Contact Jason Woofenden
vanilla ckeditor-3.1
[ckeditor.git] / _source / plugins / pastetext / plugin.js
index 3a1678d..d391fd6 100644 (file)
@@ -1,5 +1,5 @@
 /*\r
-Copyright (c) 2003-2009, CKSource - Frederico Knabben. All rights reserved.\r
+Copyright (c) 2003-2010, CKSource - Frederico Knabben. All rights reserved.\r
 For licensing, see LICENSE.html or http://ckeditor.com/license\r
 */\r
 \r
@@ -14,18 +14,60 @@ For licensing, see LICENSE.html or http://ckeditor.com/license
        {\r
                exec : function( editor )\r
                {\r
-                       // We use getClipboardData just to test if the clipboard access has\r
-                       // been granted by the user.\r
-                       if ( CKEDITOR.getClipboardData() === false || !window.clipboardData )\r
+                       var clipboardText = CKEDITOR.tools.tryThese(\r
+                               function()\r
+                               {\r
+                                       var clipboardText = window.clipboardData.getData( 'Text' );\r
+                                       if ( !clipboardText )\r
+                                               throw 0;\r
+                                       return clipboardText;\r
+                               },\r
+                               function()\r
+                               {\r
+                                       window.netscape.security.PrivilegeManager.enablePrivilege( "UniversalXPConnect" );\r
+\r
+                                       var clip = window.Components.classes[ "@mozilla.org/widget/clipboard;1" ]\r
+                                                       .getService( window.Components.interfaces.nsIClipboard );\r
+                                       var trans = window.Components.classes[ "@mozilla.org/widget/transferable;1" ]\r
+                                                       .createInstance( window.Components.interfaces.nsITransferable );\r
+                                       trans.addDataFlavor( "text/unicode" );\r
+                                       clip.getData( trans, clip.kGlobalClipboard );\r
+\r
+                                       var str = {}, strLength = {}, clipboardText;\r
+                                       trans.getTransferData( "text/unicode", str, strLength );\r
+                                       str = str.value.QueryInterface( window.Components.interfaces.nsISupportsString );\r
+                                       clipboardText = str.data.substring( 0, strLength.value / 2 );\r
+                                       return clipboardText;\r
+                               }\r
+                               // Any other approach that's working...\r
+                               );\r
+\r
+                       if ( !clipboardText )   // Clipboard access privilege is not granted.\r
                        {\r
                                editor.openDialog( 'pastetext' );\r
-                               return;\r
+                               return false;\r
                        }\r
+                       else\r
+                               editor.fire( 'paste', { 'text' : clipboardText } );\r
 \r
-                       editor.insertText( window.clipboardData.getData( 'Text' ) );\r
+                       return true;\r
                }\r
        };\r
 \r
+       function doInsertText( doc, text )\r
+       {\r
+               // Native text insertion.\r
+               if( CKEDITOR.env.ie )\r
+               {\r
+                       var selection = doc.selection;\r
+                       if ( selection.type == 'Control' )\r
+                               selection.clear();\r
+                       selection.createRange().pasteHTML( text );\r
+               }\r
+               else\r
+                       doc.execCommand( 'inserthtml', false, text );\r
+       }\r
+\r
        // Register the plugin.\r
        CKEDITOR.plugins.add( 'pastetext',\r
        {\r
@@ -44,99 +86,77 @@ For licensing, see LICENSE.html or http://ckeditor.com/license
 \r
                        if ( editor.config.forcePasteAsPlainText )\r
                        {\r
-                               editor.on( 'beforePaste', function( event )\r
+                               // Intercept the default pasting process.\r
+                               editor.on( 'beforeCommandExec', function ( evt )\r
+                               {\r
+                                       if ( evt.data.name == 'paste' )\r
                                        {\r
-                                               if ( editor.mode == "wysiwyg" )\r
-                                               {\r
-                                                       setTimeout( function() { command.exec(); }, 0 );\r
-                                                       event.cancel();\r
-                                               }\r
-                                       },\r
-                                       null, null, 20 );\r
+                                               editor.execCommand( 'pastetext' );\r
+                                               evt.cancel();\r
+                                       }\r
+                               }, null, null, 0 );\r
                        }\r
                },\r
+\r
                requires : [ 'clipboard' ]\r
        });\r
 \r
-       var clipboardDiv;\r
-\r
-       CKEDITOR.getClipboardData = function()\r
+       function doEnter( editor, mode, times, forceMode )\r
        {\r
-               if ( !CKEDITOR.env.ie )\r
-                       return false;\r
-\r
-               var doc = CKEDITOR.document,\r
-                       body = doc.getBody();\r
-\r
-               if ( !clipboardDiv )\r
+               while ( times-- )\r
                {\r
-                       clipboardDiv = doc.createElement( 'div',\r
-                               {\r
-                                       attributes :\r
-                                               {\r
-                                                       id: 'cke_hiddenDiv'\r
-                                               },\r
-                                       styles :\r
-                                               {\r
-                                                       position : 'absolute',\r
-                                                       visibility : 'hidden',\r
-                                                       overflow : 'hidden',\r
-                                                       width : '1px',\r
-                                                       height : '1px'\r
-                                               }\r
-                               });\r
-\r
-                       clipboardDiv.setHtml( '' );\r
-\r
-                       clipboardDiv.appendTo( body );\r
+                       CKEDITOR.plugins.enterkey[ mode == CKEDITOR.ENTER_BR ? 'enterBr' : 'enterBlock' ]\r
+                                       ( editor, mode, null, forceMode );\r
                }\r
+       }\r
 \r
-               // The "enabled" flag is used to check whether the paste operation has\r
-               // been completed (the onpaste event has been fired).\r
-               var     enabled = false;\r
-               var setEnabled = function()\r
-               {\r
-                       enabled = true;\r
-               };\r
-\r
-               body.on( 'paste', setEnabled );\r
-\r
-               // Create a text range and move it inside the div.\r
-               var textRange = body.$.createTextRange();\r
-               textRange.moveToElementText( clipboardDiv.$ );\r
-\r
-               // The execCommand in will fire the "onpaste", only if the\r
-               // security settings are enabled.\r
-               textRange.execCommand( 'Paste' );\r
-\r
-               // Get the DIV html and reset it.\r
-               var html = clipboardDiv.getHtml();\r
-               clipboardDiv.setHtml( '' );\r
-\r
-               body.removeListener( 'paste', setEnabled );\r
-\r
-               // Return the HTML or false if not enabled.\r
-               return enabled && html;\r
+       CKEDITOR.editor.prototype.insertText = function( text )\r
+       {\r
+               this.focus();\r
+               this.fire( 'saveSnapshot' );\r
+\r
+               var mode = this.getSelection().getStartElement().hasAscendant( 'pre', true ) ? CKEDITOR.ENTER_BR : this.config.enterMode,\r
+                       isEnterBrMode = mode == CKEDITOR.ENTER_BR,\r
+                       doc = this.document.$,\r
+                       self = this,\r
+                       line;\r
+\r
+               text = CKEDITOR.tools.htmlEncode( text.replace( /\r\n|\r/g, '\n' ) );\r
+\r
+               var startIndex = 0;\r
+               text.replace( /\n+/g, function( match, lastIndex )\r
+                {\r
+                       line = text.substring( startIndex, lastIndex );\r
+                       startIndex = lastIndex + match.length;\r
+                       line.length && doInsertText( doc, line );\r
+\r
+                       var lineBreakNums = match.length,\r
+                               // Duo consequence line-break as a enter block.\r
+                               enterBlockTimes = isEnterBrMode ? 0 : Math.floor( lineBreakNums / 2 ),\r
+                               // Per link-break as a enter br.\r
+                               enterBrTimes = isEnterBrMode ? lineBreakNums : lineBreakNums % 2;\r
+\r
+                       // Line-breaks are converted to editor enter key strokes.\r
+                       doEnter( self, mode, enterBlockTimes );\r
+                       doEnter( self, CKEDITOR.ENTER_BR, enterBrTimes, isEnterBrMode ? false : true );\r
+                });\r
+\r
+               // Insert the last text line of text.\r
+               line = text.substring( startIndex, text.length );\r
+               line.length && doInsertText( doc, line );\r
+\r
+               this.fire( 'saveSnapshot' );\r
        };\r
 })();\r
 \r
-CKEDITOR.editor.prototype.insertText = function( text )\r
-{\r
-       text = CKEDITOR.tools.htmlEncode( text );\r
-\r
-       // TODO: Replace the following with fill line break processing (see V2).\r
-       text = text.replace( /(?:\r\n)|\n|\r/g, '<br>' );\r
-\r
-       this.insertHtml( text );\r
-};\r
 \r
 /**\r
  * Whether to force all pasting operations to insert on plain text into the\r
  * editor, loosing any formatting information possibly available in the source\r
  * text.\r
+ * @name CKEDITOR.config.forcePasteAsPlainText\r
  * @type Boolean\r
  * @default false\r
  * @example\r
  * config.forcePasteAsPlainText = true;\r
  */\r
-CKEDITOR.config.forcePasteAsPlainText = false;\r