JasonWoof Got questions, comments, patches, etc.? Contact Jason Woofenden
vanilla ckeditor-3.6.1
[ckeditor.git] / _source / plugins / enterkey / plugin.js
index 4114516..59a4f82 100644 (file)
@@ -1,5 +1,5 @@
 /*\r
-Copyright (c) 2003-2010, CKSource - Frederico Knabben. All rights reserved.\r
+Copyright (c) 2003-2011, CKSource - Frederico Knabben. All rights reserved.\r
 For licensing, see LICENSE.html or http://ckeditor.com/license\r
 */\r
 \r
@@ -11,9 +11,21 @@ For licensing, see LICENSE.html or http://ckeditor.com/license
 \r
                init : function( editor )\r
                {\r
-                       var specialKeys = editor.specialKeys;\r
-                       specialKeys[ 13 ] = enter;\r
-                       specialKeys[ CKEDITOR.SHIFT + 13 ] = shiftEnter;\r
+                       editor.addCommand( 'enter', {\r
+                               modes : { wysiwyg:1 },\r
+                               editorFocus : false,\r
+                               exec : function( editor ){ enter( editor ); }\r
+                       });\r
+\r
+                       editor.addCommand( 'shiftEnter', {\r
+                               modes : { wysiwyg:1 },\r
+                               editorFocus : false,\r
+                               exec : function( editor ){ shiftEnter( editor ); }\r
+                       });\r
+\r
+                       var keystrokes = editor.keystrokeHandler.keystrokes;\r
+                       keystrokes[ 13 ] = 'enter';\r
+                       keystrokes[ CKEDITOR.SHIFT + 13 ] = 'shiftEnter';\r
                }\r
        });\r
 \r
@@ -31,18 +43,35 @@ For licensing, see LICENSE.html or http://ckeditor.com/license
 \r
                        var doc = range.document;\r
 \r
+                       var atBlockStart = range.checkStartOfBlock(),\r
+                               atBlockEnd = range.checkEndOfBlock(),\r
+                               path = new CKEDITOR.dom.elementPath( range.startContainer ),\r
+                               block = path.block;\r
+\r
                        // Exit the list when we're inside an empty list item block. (#5376)\r
-                       if ( range.checkStartOfBlock() && range.checkEndOfBlock() )\r
+                       if ( atBlockStart && atBlockEnd )\r
                        {\r
-                               var path = new CKEDITOR.dom.elementPath( range.startContainer ),\r
-                                               block = path.block;\r
-\r
                                if ( block && ( block.is( 'li' ) || block.getParent().is( 'li' ) ) )\r
                                {\r
                                        editor.execCommand( 'outdent' );\r
                                        return;\r
                                }\r
                        }\r
+                       // Don't split <pre> if we're in the middle of it, act as shift enter key.\r
+                       else if ( block && block.is( 'pre' ) )\r
+                       {\r
+                               if ( !atBlockEnd )\r
+                               {\r
+                                       enterBr( editor, mode, range, forceMode );\r
+                                       return;\r
+                               }\r
+                       }\r
+                       // Don't split caption blocks. (#7944)\r
+                       else if ( block && CKEDITOR.dtd.$captionBlock[ block.getName() ] )\r
+                       {\r
+                               enterBr( editor, mode, range, forceMode );\r
+                               return;\r
+                       }\r
 \r
                        // Determine the block element to be used.\r
                        var blockTag = ( mode == CKEDITOR.ENTER_DIV ? 'div' : 'p' );\r
@@ -75,7 +104,8 @@ For licensing, see LICENSE.html or http://ckeditor.com/license
                        else if ( previousBlock && ( node = previousBlock.getParent() ) && node.is( 'li' ) )\r
                        {\r
                                previousBlock.breakParent( node );\r
-                               range.moveToElementEditStart( previousBlock.getNext() );\r
+                               node = previousBlock.getNext();\r
+                               range.moveToElementEditStart( node );\r
                                previousBlock.move( previousBlock.getPrevious() );\r
                        }\r
 \r
@@ -106,7 +136,8 @@ For licensing, see LICENSE.html or http://ckeditor.com/license
                                        // Do not enter this block if it's a header tag, or we are in\r
                                        // a Shift+Enter (#77). Create a new block element instead\r
                                        // (later in the code).\r
-                                       if ( previousBlock.is( 'li' ) || !headerTagRegex.test( previousBlock.getName() ) )\r
+                                       if ( previousBlock.is( 'li' ) ||\r
+                                                       ! ( headerTagRegex.test( previousBlock.getName() ) || previousBlock.is( 'pre' ) ) )\r
                                        {\r
                                                // Otherwise, duplicate the previous block.\r
                                                newBlock = previousBlock.clone();\r
@@ -117,9 +148,15 @@ For licensing, see LICENSE.html or http://ckeditor.com/license
 \r
                                if ( !newBlock )\r
                                {\r
-                                       newBlock = doc.createElement( blockTag );\r
-                                       if ( previousBlock && ( newBlockDir = previousBlock.getDirection() ) )\r
-                                               newBlock.setAttribute( 'dir', newBlockDir );\r
+                                       // We have already created a new list item. (#6849)\r
+                                       if ( node && node.is( 'li' ) )\r
+                                               newBlock = node;\r
+                                       else\r
+                                       {\r
+                                               newBlock = doc.createElement( blockTag );\r
+                                               if ( previousBlock && ( newBlockDir = previousBlock.getDirection() ) )\r
+                                                       newBlock.setAttribute( 'dir', newBlockDir );\r
+                                       }\r
                                }\r
                                // Force the enter block unless we're talking of a list item.\r
                                else if ( forceMode && !newBlock.is( 'li' ) )\r
@@ -150,7 +187,12 @@ For licensing, see LICENSE.html or http://ckeditor.com/license
                                if ( !CKEDITOR.env.ie )\r
                                        newBlock.appendBogus();\r
 \r
-                               range.insertNode( newBlock );\r
+                               if ( !newBlock.getParent() )\r
+                                       range.insertNode( newBlock );\r
+\r
+                               // list item start number should not be duplicated (#7330), but we need\r
+                               // to remove the attribute after it's onto the DOM tree because of old IEs (#7581).\r
+                               newBlock.is( 'li' ) && newBlock.removeAttribute( 'value' );\r
 \r
                                // This is tricky, but to make the new block visible correctly\r
                                // we must select it.\r
@@ -230,7 +272,7 @@ For licensing, see LICENSE.html or http://ckeditor.com/license
                                var newBlock,\r
                                        newBlockDir;\r
 \r
-                               if ( newBlockDir = startBlock.getDirection() )\r
+                               if ( ( newBlockDir = startBlock.getDirection() ) )\r
                                {\r
                                        newBlock = doc.createElement( 'div' );\r
                                        newBlock.setAttribute( 'dir', newBlockDir );\r
@@ -265,29 +307,27 @@ For licensing, see LICENSE.html or http://ckeditor.com/license
                                range.deleteContents();\r
                                range.insertNode( lineBreak );\r
 \r
-                               // A text node is required by Gecko only to make the cursor blink.\r
-                               // We need some text inside of it, so the bogus <br> is properly\r
-                               // created.\r
-                               if ( !CKEDITOR.env.ie )\r
-                                       doc.createText( '\ufeff' ).insertAfter( lineBreak );\r
-\r
-                               // If we are at the end of a block, we must be sure the bogus node is available in that block.\r
-                               if ( isEndOfBlock && !CKEDITOR.env.ie )\r
-                                       lineBreak.getParent().appendBogus();\r
-\r
-                               // Now we can remove the text node contents, so the caret doesn't\r
-                               // stop on it.\r
-                               if ( !CKEDITOR.env.ie )\r
-                                       lineBreak.getNext().$.nodeValue = '';\r
                                // IE has different behavior regarding position.\r
                                if ( CKEDITOR.env.ie )\r
                                        range.setStartAt( lineBreak, CKEDITOR.POSITION_AFTER_END );\r
                                else\r
+                               {\r
+                                       // A text node is required by Gecko only to make the cursor blink.\r
+                                       // We need some text inside of it, so the bogus <br> is properly\r
+                                       // created.\r
+                                       doc.createText( '\ufeff' ).insertAfter( lineBreak );\r
+\r
+                                       // If we are at the end of a block, we must be sure the bogus node is available in that block.\r
+                                       if ( isEndOfBlock )\r
+                                               lineBreak.getParent().appendBogus();\r
+\r
+                                       // Now we can remove the text node contents, so the caret doesn't\r
+                                       // stop on it.\r
+                                       lineBreak.getNext().$.nodeValue = '';\r
+\r
                                        range.setStartAt( lineBreak.getNext(), CKEDITOR.POSITION_AFTER_START );\r
 \r
-                               // Scroll into view, for non IE.\r
-                               if ( !CKEDITOR.env.ie )\r
-                               {\r
+                                       // Scroll into view, for non IE.\r
                                        var dummy = null;\r
 \r
                                        // BR is not positioned in Opera and Webkit.\r
@@ -328,14 +368,7 @@ For licensing, see LICENSE.html or http://ckeditor.com/license
                // On SHIFT+ENTER:\r
                // 1. We want to enforce the mode to be respected, instead\r
                // of cloning the current block. (#77)\r
-               // 2. Always perform a block break when inside <pre> (#5402).\r
-               if ( editor.getSelection().getStartElement().hasAscendant( 'pre', true ) )\r
-               {\r
-                       setTimeout( function() { enterBlock( editor, editor.config.enterMode, null, true ); }, 0 );\r
-                       return true;\r
-               }\r
-               else\r
-                       return enter( editor, editor.config.shiftEnterMode, 1 );\r
+               return enter( editor, editor.config.shiftEnterMode, 1 );\r
        }\r
 \r
        function enter( editor, mode, forceMode )\r
@@ -353,7 +386,7 @@ For licensing, see LICENSE.html or http://ckeditor.com/license
                setTimeout( function()\r
                        {\r
                                editor.fire( 'saveSnapshot' );  // Save undo step.\r
-                               if ( mode == CKEDITOR.ENTER_BR || editor.getSelection().getStartElement().hasAscendant( 'pre', 1 ) )\r
+                               if ( mode == CKEDITOR.ENTER_BR )\r
                                        enterBr( editor, mode, null, forceMode );\r
                                else\r
                                        enterBlock( editor, mode, null, forceMode );\r
@@ -363,7 +396,6 @@ For licensing, see LICENSE.html or http://ckeditor.com/license
                return true;\r
        }\r
 \r
-\r
        function getRange( editor )\r
        {\r
                // Get the selection ranges.\r