Index: _source/plugins/selection/plugin.js
===================================================================
--- _source/plugins/selection/plugin.js (revision 6461)
+++ _source/plugins/selection/plugin.js (revision )
@@ -99,15 +99,31 @@
canUndo : false
};
- function createFillingChar( doc )
+ function createFillingChar( range )
{
+ var doc = range.document;
removeFillingChar( doc );
+ // Place a zero-width space so browser will be able to
+ // blink the cursor normally (#1272).
var fillingChar = doc.createText( '\u200B' );
doc.setCustomData( 'cke-fillingChar', fillingChar );
- return fillingChar;
+ range.insertNode( fillingChar );
+
+ var next = fillingChar.getNext();
+
+ // If the filling char is followed by a
, without
+ // having something before it, it'll not blink.
+ // Let's remove it in this case.
+ if ( next && !fillingChar.getPrevious() && next.type == CKEDITOR.NODE_ELEMENT && next.getName() == 'br' )
+ {
+ removeFillingChar( this.document );
+ range.moveToPosition( next, CKEDITOR.POSITION_BEFORE_START );
- }
+ }
+ else
+ range.moveToPosition( fillingChar, CKEDITOR.POSITION_AFTER_END );
+ }
function getFillingChar( doc )
{
@@ -148,40 +164,37 @@
{
// On WebKit only, we need a special "filling" char on some situations
// (#1272). Here we set the events that should invalidate that char.
- if ( CKEDITOR.env.webkit )
- {
- editor.on( 'selectionChange', function() { checkFillingChar( editor.document ); } );
- editor.on( 'beforeSetMode', function() { removeFillingChar( editor.document ); } );
- editor.on( 'key', function( e )
- {
- // Remove the filling char before some keys get
- // executed, so they'll not get blocked by it.
- switch ( e.data.keyCode )
- {
- case 37 : // LEFT-ARROW
- case 39 : // RIGHT-ARROW
- case 8 : // BACKSPACE
- removeFillingChar( editor.document );
- }
+ editor.on( 'selectionChange', function() { checkFillingChar( editor.document ); } );
+ editor.on( 'beforeSetMode', function() { removeFillingChar( editor.document ); } );
+ editor.on( 'key', function( e )
+ {
+ // Remove the filling char before some keys get
+ // executed, so they'll not get blocked by it.
+ switch ( e.data.keyCode )
+ {
+ case 37 : // LEFT-ARROW
+ case 39 : // RIGHT-ARROW
+ case 8 : // BACKSPACE
+ removeFillingChar( editor.document );
+ }
- });
+ } );
- var fillingCharBefore;
- function beforeData()
- {
- var fillingChar = getFillingChar( editor.document );
- fillingCharBefore = fillingChar && fillingChar.getText();
+ var fillingCharBefore;
+ function beforeData()
+ {
+ var fillingChar = getFillingChar( editor.document );
+ fillingCharBefore = fillingChar && fillingChar.getText();
fillingCharBefore && fillingChar.setText( fillingCharBefore.replace( /\u200B/g, '' ) );
- }
- function afterData()
- {
- var fillingChar = getFillingChar( editor.document );
- fillingChar && fillingChar.setText( fillingCharBefore );
- }
- editor.on( 'beforeUndoImage', beforeData );
- editor.on( 'afterUndoImage', afterData );
- editor.on( 'beforeGetData', beforeData, null, null, 0 );
- editor.on( 'getData', afterData );
+ }
+ function afterData()
+ {
+ var fillingChar = getFillingChar( editor.document );
+ fillingChar && fillingChar.setText( fillingCharBefore );
+ }
+ editor.on( 'beforeUndoImage', beforeData );
+ editor.on( 'afterUndoImage', afterData );
+ editor.on( 'beforeGetData', beforeData, null, null, 0 );
+ editor.on( 'getData', afterData );
- }
editor.on( 'contentDom', function()
{
@@ -1194,7 +1207,7 @@
* by clearing up the original selection.
* @param {CKEDITOR.dom.range} ranges
*/
- selectRanges : function( ranges )
+ selectRanges : function( ranges, forceExpand )
{
if ( this.isLocked )
{
@@ -1217,7 +1230,7 @@
}
if ( ranges[ 0 ] )
- ranges[ 0 ].select();
+ ranges[ 0 ].select( forceExpand );
this.reset();
}
@@ -1233,7 +1246,7 @@
{
sel.removeAllRanges();
// Remove any existing filling char first.
- CKEDITOR.env.webkit && removeFillingChar( this.document );
+ removeFillingChar( this.document );
}
for ( var i = 0 ; i < ranges.length ; i++ )
@@ -1284,27 +1297,9 @@
startContainer.appendText( '' );
}
- if ( range.collapsed && CKEDITOR.env.webkit )
- {
- // Append a zero-width space so WebKit will not try to
- // move the selection by itself (#1272).
- var fillingChar = createFillingChar( this.document );
- range.insertNode( fillingChar ) ;
+ if ( range.collapsed && ( forceExpand || CKEDITOR.env.webkit ) )
+ createFillingChar( range );
- var next = fillingChar.getNext();
-
- // If the filling char is followed by a
, whithout
- // having something before it, it'll not blink.
- // Let's remove it in this case.
- if ( next && !fillingChar.getPrevious() && next.type == CKEDITOR.NODE_ELEMENT && next.getName() == 'br' )
- {
- removeFillingChar( this.document );
- range.moveToPosition( next, CKEDITOR.POSITION_BEFORE_START );
- }
- else
- range.moveToPosition( fillingChar, CKEDITOR.POSITION_AFTER_END );
- }
-
nativeRange.setStart( range.startContainer.$, range.startOffset );
try
@@ -1394,10 +1389,7 @@
start.scrollIntoView();
}
};
-})();
-( function()
-{
var notWhitespaces = CKEDITOR.dom.walker.whitespaces( true ),
fillerTextRegex = /\ufeff|\u00a0/,
nonCells = { table:1,tbody:1,tr:1 };
@@ -1411,6 +1403,8 @@
var isStartMarkerAlone;
var dummySpan;
+ collapsed && forceExpand && createFillingChar( this );
+
// IE doesn't support selecting the entire table row/cell, move the selection into cells, e.g.
//
[cell | ... => [cell | ...
if ( this.startContainer.type == CKEDITOR.NODE_ELEMENT && this.startContainer.getName() in nonCells
@@ -1508,8 +1502,9 @@
this.document.fire( 'selectionchange' );
}
:
- function()
+ function( forceExpand )
{
- this.document.getSelection().selectRanges( [ this ] );
+ this.document.getSelection().selectRanges( [ this ], forceExpand );
};
+
-} )();
+})();
Index: _source/plugins/domiterator/plugin.js
===================================================================
--- _source/plugins/domiterator/plugin.js (revision 6368)
+++ _source/plugins/domiterator/plugin.js (revision )
@@ -108,6 +108,10 @@
{
this._.lastNode = this._.docEndMarker = range.document.createText( '' );
this._.lastNode.insertAfter( lastNode );
+ // If the current last is a bookmark, to make sure it will be included in the range,
+ // we need another marker as "getNextSourceNode" will always skip it.
+ if ( !bookmarkGuard( lastNode) )
+ this._.lastNode.clone().insertAfter( lastNode );
}
// Let's reuse this variable.
Index: _source/plugins/wysiwygarea/plugin.js
===================================================================
--- _source/plugins/wysiwygarea/plugin.js (revision 6486)
+++ _source/plugins/wysiwygarea/plugin.js (revision )
@@ -11,7 +11,7 @@
(function()
{
// List of elements in which has no way to move editing focus outside.
- var nonExitableElementNames = { table:1,pre:1 };
+ var nonExitableElementNames = { table:1,pre:1, ul:1,ol:1,dl:1,blockquote:1,form:1 };
// Matching an empty paragraph at the end of document.
var emptyParagraphRegexp = /(^|]*>)\s*<(p|div|address|h\d|center)[^>]*>\s*(?:
]*>| |\u00A0| )?\s*(:?<\/\2>)?\s*(?=$|<\/body>)/gi;
@@ -430,38 +430,7 @@
editor.selectionChange();
}
}
-
- // All browsers are incapable to moving cursor out of certain non-exitable
- // blocks (e.g. table, list, pre) at the end of document, make this happen by
- // place a bogus node there, which would be later removed by dataprocessor.
- var walkerRange = new CKEDITOR.dom.range( editor.document ),
- walker = new CKEDITOR.dom.walker( walkerRange );
- walkerRange.selectNodeContents( body );
- walker.evaluator = function( node )
- {
- return node.type == CKEDITOR.NODE_ELEMENT && ( node.getName() in nonExitableElementNames );
- };
- walker.guard = function( node, isMoveout )
- {
- return !( ( node.type == CKEDITOR.NODE_TEXT && isNotWhitespace( node ) ) || isMoveout );
- };
-
- if ( walker.previous() )
- {
- editor.fire( 'updateSnapshot' );
- restoreDirty( editor );
- CKEDITOR.env.ie && restoreSelection( selection );
-
- var paddingBlock;
- if ( enterMode != CKEDITOR.ENTER_BR )
- paddingBlock = body.append( new CKEDITOR.dom.element( enterMode == CKEDITOR.ENTER_P ? 'p' : 'div' ) );
- else
- paddingBlock = body;
-
- if ( !CKEDITOR.env.ie )
- paddingBlock.appendBogus();
- }
+ }
- }
CKEDITOR.plugins.add( 'wysiwygarea',
{
@@ -1216,8 +1185,48 @@
}
});
+ // All browsers are incapable to moving cursor out of certain non-exitable
+ // blocks (e.g. table, list, pre) at the end of document, enable this when
+ // user clicks on the padding bottom area of body.
+ editor.addCss( 'body{padding-bottom: 20px;}');
+ editor.on( 'contentDom', function ()
+ {
+ var doc = editor.document,
+ body = doc.getBody();
+
+ body.on( 'click', function ( evt )
+ {
+ evt = evt.data;
+
+ // All browsers are incapable to moving cursor out of certain non-exitable
+ // blocks (e.g. table, list, pre) at the end of document, make this happen by
+ // place a bogus node there, which would be later removed by dataprocessor.
+ if ( ( evt.$.offsetY || evt.$.layerY || evt.$.y ) > body.$.clientHeight - parseInt( body.getComputedStyle( 'padding-bottom' ) ) )
+ {
+ var walkerRange = new CKEDITOR.dom.range( editor.document ),
+ walker = new CKEDITOR.dom.walker( walkerRange );
+ walkerRange.selectNodeContents( body );
+ walker.evaluator = function( node )
+ {
+ return node.type == CKEDITOR.NODE_ELEMENT && ( node.getName() in nonExitableElementNames );
+ };
+ walker.guard = function( node, isMoveout )
+ {
+ return !( ( node.type == CKEDITOR.NODE_TEXT && isNotWhitespace( node ) ) || isMoveout );
+ };
+
+ if ( walker.previous() )
+ {
+ var range = new CKEDITOR.dom.range( doc );
+ range.moveToPosition( body, CKEDITOR.POSITION_BEFORE_END );
+ range.select( 1 );
+ evt.preventDefault();
- }
+ }
+ }
- });
+ });
+ });
+ }
+ });
// Fixing Firefox 'Back-Forward Cache' break design mode. (#4514)
if ( CKEDITOR.env.gecko )