X-Git-Url: https://svn.cri.mines-paristech.fr/git/ckeditor.git/blobdiff_plain/256592bf803e851aa7fc953e08a6e9e58d970f8c..871bad8291b6dbc29d489d95d185458caab25158:/skins/ckeditor/_source/plugins/enterkey/plugin.js diff --git a/skins/ckeditor/_source/plugins/enterkey/plugin.js b/skins/ckeditor/_source/plugins/enterkey/plugin.js new file mode 100644 index 0000000..59a4f82 --- /dev/null +++ b/skins/ckeditor/_source/plugins/enterkey/plugin.js @@ -0,0 +1,413 @@ +/* +Copyright (c) 2003-2011, CKSource - Frederico Knabben. All rights reserved. +For licensing, see LICENSE.html or http://ckeditor.com/license +*/ + +(function() +{ + CKEDITOR.plugins.add( 'enterkey', + { + requires : [ 'keystrokes', 'indent' ], + + init : function( editor ) + { + editor.addCommand( 'enter', { + modes : { wysiwyg:1 }, + editorFocus : false, + exec : function( editor ){ enter( editor ); } + }); + + editor.addCommand( 'shiftEnter', { + modes : { wysiwyg:1 }, + editorFocus : false, + exec : function( editor ){ shiftEnter( editor ); } + }); + + var keystrokes = editor.keystrokeHandler.keystrokes; + keystrokes[ 13 ] = 'enter'; + keystrokes[ CKEDITOR.SHIFT + 13 ] = 'shiftEnter'; + } + }); + + CKEDITOR.plugins.enterkey = + { + enterBlock : function( editor, mode, range, forceMode ) + { + // Get the range for the current selection. + range = range || getRange( editor ); + + // We may not have valid ranges to work on, like when inside a + // contenteditable=false element. + if ( !range ) + return; + + var doc = range.document; + + var atBlockStart = range.checkStartOfBlock(), + atBlockEnd = range.checkEndOfBlock(), + path = new CKEDITOR.dom.elementPath( range.startContainer ), + block = path.block; + + // Exit the list when we're inside an empty list item block. (#5376) + if ( atBlockStart && atBlockEnd ) + { + if ( block && ( block.is( 'li' ) || block.getParent().is( 'li' ) ) ) + { + editor.execCommand( 'outdent' ); + return; + } + } + // Don't split
if we're in the middle of it, act as shift enter key.
+ else if ( block && block.is( 'pre' ) )
+ {
+ if ( !atBlockEnd )
+ {
+ enterBr( editor, mode, range, forceMode );
+ return;
+ }
+ }
+ // Don't split caption blocks. (#7944)
+ else if ( block && CKEDITOR.dtd.$captionBlock[ block.getName() ] )
+ {
+ enterBr( editor, mode, range, forceMode );
+ return;
+ }
+
+ // Determine the block element to be used.
+ var blockTag = ( mode == CKEDITOR.ENTER_DIV ? 'div' : 'p' );
+
+ // Split the range.
+ var splitInfo = range.splitBlock( blockTag );
+
+ if ( !splitInfo )
+ return;
+
+ // Get the current blocks.
+ var previousBlock = splitInfo.previousBlock,
+ nextBlock = splitInfo.nextBlock;
+
+ var isStartOfBlock = splitInfo.wasStartOfBlock,
+ isEndOfBlock = splitInfo.wasEndOfBlock;
+
+ var node;
+
+ // If this is a block under a list item, split it as well. (#1647)
+ if ( nextBlock )
+ {
+ node = nextBlock.getParent();
+ if ( node.is( 'li' ) )
+ {
+ nextBlock.breakParent( node );
+ nextBlock.move( nextBlock.getNext(), 1 );
+ }
+ }
+ else if ( previousBlock && ( node = previousBlock.getParent() ) && node.is( 'li' ) )
+ {
+ previousBlock.breakParent( node );
+ node = previousBlock.getNext();
+ range.moveToElementEditStart( node );
+ previousBlock.move( previousBlock.getPrevious() );
+ }
+
+ // If we have both the previous and next blocks, it means that the
+ // boundaries were on separated blocks, or none of them where on the
+ // block limits (start/end).
+ if ( !isStartOfBlock && !isEndOfBlock )
+ {
+ // If the next block is an (#4711).
+ if ( isPre && !CKEDITOR.env.gecko )
+ lineBreak = doc.createText( CKEDITOR.env.ie ? '\r' : '\n' );
+ else
+ lineBreak = doc.createElement( 'br' );
+
+ range.deleteContents();
+ range.insertNode( lineBreak );
+
+ // IE has different behavior regarding position.
+ if ( CKEDITOR.env.ie )
+ range.setStartAt( lineBreak, CKEDITOR.POSITION_AFTER_END );
+ else
+ {
+ // A text node is required by Gecko only to make the cursor blink.
+ // We need some text inside of it, so the bogus
is properly
+ // created.
+ doc.createText( '\ufeff' ).insertAfter( lineBreak );
+
+ // If we are at the end of a block, we must be sure the bogus node is available in that block.
+ if ( isEndOfBlock )
+ lineBreak.getParent().appendBogus();
+
+ // Now we can remove the text node contents, so the caret doesn't
+ // stop on it.
+ lineBreak.getNext().$.nodeValue = '';
+
+ range.setStartAt( lineBreak.getNext(), CKEDITOR.POSITION_AFTER_START );
+
+ // Scroll into view, for non IE.
+ var dummy = null;
+
+ // BR is not positioned in Opera and Webkit.
+ if ( !CKEDITOR.env.gecko )
+ {
+ dummy = doc.createElement( 'span' );
+ // We need have some contents for Webkit to position it
+ // under parent node. ( #3681)
+ dummy.setHtml(' ');
+ }
+ else
+ dummy = doc.createElement( 'br' );
+
+ dummy.insertBefore( lineBreak.getNext() );
+ dummy.scrollIntoView();
+ dummy.remove();
+ }
+ }
+
+ // This collapse guarantees the cursor will be blinking.
+ range.collapse( true );
+
+ range.select( isPre );
+ }
+ };
+
+ var plugin = CKEDITOR.plugins.enterkey,
+ enterBr = plugin.enterBr,
+ enterBlock = plugin.enterBlock,
+ headerTagRegex = /^h[1-6]$/;
+
+ function shiftEnter( editor )
+ {
+ // Only effective within document.
+ if ( editor.mode != 'wysiwyg' )
+ return false;
+
+ // On SHIFT+ENTER:
+ // 1. We want to enforce the mode to be respected, instead
+ // of cloning the current block. (#77)
+ return enter( editor, editor.config.shiftEnterMode, 1 );
+ }
+
+ function enter( editor, mode, forceMode )
+ {
+ forceMode = editor.config.forceEnterMode || forceMode;
+
+ // Only effective within document.
+ if ( editor.mode != 'wysiwyg' )
+ return false;
+
+ if ( !mode )
+ mode = editor.config.enterMode;
+
+ // Use setTimout so the keys get cancelled immediatelly.
+ setTimeout( function()
+ {
+ editor.fire( 'saveSnapshot' ); // Save undo step.
+ if ( mode == CKEDITOR.ENTER_BR )
+ enterBr( editor, mode, null, forceMode );
+ else
+ enterBlock( editor, mode, null, forceMode );
+
+ }, 0 );
+
+ return true;
+ }
+
+ function getRange( editor )
+ {
+ // Get the selection ranges.
+ var ranges = editor.getSelection().getRanges( true );
+
+ // Delete the contents of all ranges except the first one.
+ for ( var i = ranges.length - 1 ; i > 0 ; i-- )
+ {
+ ranges[ i ].deleteContents();
+ }
+
+ // Return the first range.
+ return ranges[ 0 ];
+ }
+})();