Skip to content

Commit

Permalink
Merge branch 't/10778'
Browse files Browse the repository at this point in the history
  • Loading branch information
Piotr Jasiun committed Jan 7, 2014
2 parents 2699ee7 + 3ee3e3b commit e3c7913
Show file tree
Hide file tree
Showing 2 changed files with 77 additions and 16 deletions.
1 change: 1 addition & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ CKEditor 4 Changelog
* [#11126](http://dev.ckeditor.com/ticket/11126): Fixed: Native undo executed once reached the bottom of snapshot stack.
* [#11131](http://dev.ckeditor.com/ticket/11131): [[Divarea](http://ckeditor.com/addon/divarea)] Fixed: Error thrown when switching to source mode if selection was in widget's nested editable.
* [#11139](http://dev.ckeditor.com/ticket/11139): [[Divarea](http://ckeditor.com/addon/divarea)] Fixed: Elements path is not cleared after switching to source mode.
* [#10778](http://dev.ckeditor.com/ticket/10778): Fix bug with range enlarge; range no longer expanded visible whitespace.

## CKEditor 4.3.1

Expand Down
92 changes: 76 additions & 16 deletions core/dom/range.js
Original file line number Diff line number Diff line change
Expand Up @@ -922,6 +922,8 @@ CKEDITOR.dom.range = function( root ) {
* @param {Boolean} [excludeBrs=false] Whether include line-breaks when expanding.
*/
enlarge: function( unit, excludeBrs ) {
var leadingWhitespaceRegex = new RegExp( /[^\s\ufeff]/ );

switch ( unit ) {
case CKEDITOR.ENLARGE_INLINE:
var enlargeInlineOnly = 1;
Expand Down Expand Up @@ -1029,7 +1031,7 @@ CKEDITOR.dom.range = function( root ) {
} else if ( sibling.type == CKEDITOR.NODE_TEXT ) {
siblingText = sibling.getText();

if ( /[^\s\ufeff]/.test( siblingText ) )
if ( leadingWhitespaceRegex.test( siblingText ) )
sibling = null;

isWhiteSpace = /[\s\ufeff]$/.test( siblingText );
Expand All @@ -1047,7 +1049,7 @@ CKEDITOR.dom.range = function( root ) {

siblingText = sibling.getText();

if ( ( /[^\s\ufeff]/ ).test( siblingText ) ) // Spaces + Zero Width No-Break Space (U+FEFF)
if ( leadingWhitespaceRegex.test( siblingText ) ) // Spaces + Zero Width No-Break Space (U+FEFF)
sibling = null;
else {
var allChildren = sibling.$.getElementsByTagName( '*' );
Expand Down Expand Up @@ -1115,20 +1117,76 @@ CKEDITOR.dom.range = function( root ) {
enlargeable = sibling = null;
commonReached = needsWhiteSpace = false;

if ( container.type == CKEDITOR.NODE_TEXT ) {
// Check if there is any non-space text after the
// offset. Otherwise, container is null.
container = !CKEDITOR.tools.trim( container.substring( offset ) ).length && container;
// Function check if there are only whitespaces from the given starting point
// (startContainer and startOffset) till the end on block.
// Examples ("[" is the start point):
// - <p>foo[ </p> - will return true,
// - <p><b>foo[ </b> </p> - will return true,
// - <p>foo[ bar</p> - will return false,
// - <p><b>foo[ </b>bar</p> - will return false,
// - <p>foo[ <b></b></p> - will return false.
function onlyWhiteSpaces( startContainer, startOffset ) {
// We need to enlarge range if there is white space at the end of the block,
// because it is not displayed in WYSIWYG mode and user can not select it. So
// "<p>foo[bar] </p>" should be changed to "<p>foo[bar ]</p>". On the other hand
// we should do nothing if we are not at the end of the block, so this should not
// be changed: "<p><i>[foo] </i>bar</p>".
var walkerRange = new CKEDITOR.dom.range( boundary );
walkerRange.setStart( startContainer, startOffset );
// The guard will find the end of range so I put boundary here.
walkerRange.setEndAt( boundary, CKEDITOR.POSITION_BEFORE_END );

var walker = new CKEDITOR.dom.walker( walkerRange ),
node;

walker.guard = function( node, movingOut ) {
// Stop if you exit block.
return !( node.type == CKEDITOR.NODE_ELEMENT && node.isBlockBoundary() );
};

while ( ( node = walker.next() ) ) {
if ( node.type != CKEDITOR.NODE_TEXT ) {
// Stop if you enter to any node (walker.next() will return node only
// it goes out, not if it is go into node).
return false;
} else {
// Trim the first node to startOffset.
if ( node != startContainer )
siblingText = node.getText();
else
siblingText = node.substring( startOffset )

// If we found only whitespace in the node, it
// means that we'll need more whitespace to be able
// to expand. For example, <i> can be expanded in
// "A <i> [B]</i>", but not in "A<i> [B]</i>".
needsWhiteSpace = !( container && container.getLength() );
// Check if it is white space.
if ( leadingWhitespaceRegex.test( siblingText ) )
return false;
}
}

if ( container ) {
if ( !( sibling = container.getNext() ) )
enlargeable = container.getParent();
return true;
}

if ( container.type == CKEDITOR.NODE_TEXT ) {
// Check if there is only white space after the offset.
if ( CKEDITOR.tools.trim( container.substring( offset ) ).length ) {
// If we found only whitespace in the node, it
// means that we'll need more whitespace to be able
// to expand. For example, <i> can be expanded in
// "A <i> [B]</i>", but not in "A<i> [B]</i>".
needsWhiteSpace = true;
} else {
needsWhiteSpace = !container.getLength();

if ( offset == container.getLength() ) {
// If we are at the end of container and this is the last text node,
// we should enlarge end to the parent.
if ( !( sibling = container.getNext() ) )
enlargeable = container.getParent();
} else {
// If we are in the middle on text node and there are only whitespaces
// till the end of block, we should enlarge element.
if ( onlyWhiteSpaces( container, offset ) )
enlargeable = container.getParent();
}
}
} else {
// Get the node right after the boudary to be checked
Expand Down Expand Up @@ -1165,7 +1223,9 @@ CKEDITOR.dom.range = function( root ) {
if ( sibling.type == CKEDITOR.NODE_TEXT ) {
siblingText = sibling.getText();

if ( /[^\s\ufeff]/.test( siblingText ) )
// Check if there are not whitespace characters till the end of editable.
// If so stop expanding.
if ( !onlyWhiteSpaces( sibling, 0 ) )
sibling = null;

isWhiteSpace = /^[\s\ufeff]/.test( siblingText );
Expand All @@ -1183,7 +1243,7 @@ CKEDITOR.dom.range = function( root ) {

siblingText = sibling.getText();

if ( ( /[^\s\ufeff]/ ).test( siblingText ) )
if ( leadingWhitespaceRegex.test( siblingText ) )
sibling = null;
else {
allChildren = sibling.$.getElementsByTagName( '*' );
Expand Down

0 comments on commit e3c7913

Please sign in to comment.