From 30c933b7dccb968845e6e1b6546a5337fafbefa0 Mon Sep 17 00:00:00 2001
From: Piotr Jasiun
Date: Mon, 2 Dec 2013 16:38:34 +0100
Subject: [PATCH 1/8] Makes code more readable and ready to future changes.
---
core/dom/range.js | 19 +++++++++----------
1 file changed, 9 insertions(+), 10 deletions(-)
diff --git a/core/dom/range.js b/core/dom/range.js
index 69af9790f3f..497fc293270 100644
--- a/core/dom/range.js
+++ b/core/dom/range.js
@@ -1116,17 +1116,16 @@ CKEDITOR.dom.range = function( root ) {
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;
-
- // If we found only whitespace in the node, it
- // means that we'll need more whitespace to be able
- // to expand. For example, can be expanded in
- // "A [B]", but not in "A [B]".
- needsWhiteSpace = !( container && container.getLength() );
+ // 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, can be expanded in
+ // "A [B]", but not in "A [B]".
+ needsWhiteSpace = true;
+ } else {
+ needsWhiteSpace = !container.getLength();
- if ( container ) {
if ( !( sibling = container.getNext() ) )
enlargeable = container.getParent();
}
From 965209d17025967e88bbf83effb68f7bddf7d1d1 Mon Sep 17 00:00:00 2001
From: Piotr Jasiun
Date: Mon, 2 Dec 2013 17:24:20 +0100
Subject: [PATCH 2/8] Check id offset == container.length before enlarge end.
---
core/dom/range.js | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/core/dom/range.js b/core/dom/range.js
index 497fc293270..7c9729b6cfa 100644
--- a/core/dom/range.js
+++ b/core/dom/range.js
@@ -1126,7 +1126,9 @@ CKEDITOR.dom.range = function( root ) {
} else {
needsWhiteSpace = !container.getLength();
- if ( !( sibling = container.getNext() ) )
+ // If we are at the end of container and this is the last text node
+ // we should enlarged end to the parent.
+ if ( offset == container.getLength() && !( sibling = container.getNext() ) )
enlargeable = container.getParent();
}
} else {
From abb35f58edf747f298dff2639080d74ec3ae4b76 Mon Sep 17 00:00:00 2001
From: Piotr Jasiun
Date: Wed, 4 Dec 2013 14:24:36 +0100
Subject: [PATCH 3/8] Check whitespaces using walker instead of regexp.
---
core/dom/range.js | 66 +++++++++++++++++++++++++++++++++++++++++++----
1 file changed, 61 insertions(+), 5 deletions(-)
diff --git a/core/dom/range.js b/core/dom/range.js
index 7c9729b6cfa..14468d247e5 100644
--- a/core/dom/range.js
+++ b/core/dom/range.js
@@ -1115,6 +1115,53 @@ CKEDITOR.dom.range = function( root ) {
enlargeable = sibling = null;
commonReached = needsWhiteSpace = 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
+ // "foo[bar]
" should be changed to "foo[bar ]
". On the other hand
+ // we should do nothing if we are not at the end of the block, so this should not
+ // be changed: "[foo] bar
".
+ 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.
+ if ( node.type == CKEDITOR.NODE_ELEMENT && node.isBlockBoundary() )
+ return false;
+
+ // Stop if you exit contenteditable.
+ if ( node.type == CKEDITOR.NODE_ELEMENT && node.getAttribute( 'contenteditable' ) == 'false' )
+ return false;
+
+ return true;
+ };
+
+ 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 )
+
+ // Check if it is white space.
+ if ( ( /[^\s\ufeff]/.test( siblingText ) ) )
+ return false;
+ }
+ }
+
+ 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 ) {
@@ -1126,10 +1173,17 @@ CKEDITOR.dom.range = function( root ) {
} else {
needsWhiteSpace = !container.getLength();
- // If we are at the end of container and this is the last text node
- // we should enlarged end to the parent.
- if ( offset == container.getLength() && !( sibling = container.getNext() ) )
- enlargeable = container.getParent();
+ 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
@@ -1166,7 +1220,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 );
From 53459159842ff026035ddf7b9e70fc88e32c7f9d Mon Sep 17 00:00:00 2001
From: Piotr Jasiun
Date: Fri, 3 Jan 2014 16:46:44 +0100
Subject: [PATCH 4/8] Removed unneeded condition from walker.guard.
---
core/dom/range.js | 9 +--------
1 file changed, 1 insertion(+), 8 deletions(-)
diff --git a/core/dom/range.js b/core/dom/range.js
index 14468d247e5..350f993be4f 100644
--- a/core/dom/range.js
+++ b/core/dom/range.js
@@ -1131,14 +1131,7 @@ CKEDITOR.dom.range = function( root ) {
walker.guard = function( node, movingOut ) {
// Stop if you exit block.
- if ( node.type == CKEDITOR.NODE_ELEMENT && node.isBlockBoundary() )
- return false;
-
- // Stop if you exit contenteditable.
- if ( node.type == CKEDITOR.NODE_ELEMENT && node.getAttribute( 'contenteditable' ) == 'false' )
- return false;
-
- return true;
+ return !( node.type == CKEDITOR.NODE_ELEMENT && node.isBlockBoundary() );
};
while ( ( node = walker.next() ) ) {
From 1bce25451e13519e333ba86f3c481264250c0ca4 Mon Sep 17 00:00:00 2001
From: Piotr Jasiun
Date: Fri, 3 Jan 2014 17:29:23 +0100
Subject: [PATCH 5/8] Compile regexp.
---
core/dom/range.js | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/core/dom/range.js b/core/dom/range.js
index 350f993be4f..9a3a9de90db 100644
--- a/core/dom/range.js
+++ b/core/dom/range.js
@@ -1127,7 +1127,8 @@ CKEDITOR.dom.range = function( root ) {
walkerRange.setEndAt( boundary, CKEDITOR.POSITION_BEFORE_END );
var walker = new CKEDITOR.dom.walker( walkerRange ),
- node;
+ node,
+ whitespaceRegexp = new RegExp( /[^\s\ufeff]/ );
walker.guard = function( node, movingOut ) {
// Stop if you exit block.
@@ -1147,7 +1148,7 @@ CKEDITOR.dom.range = function( root ) {
siblingText = node.substring( startOffset )
// Check if it is white space.
- if ( ( /[^\s\ufeff]/.test( siblingText ) ) )
+ if ( ( whitespaceRegexp.test( siblingText ) ) )
return false;
}
}
From 7842a7bf1fda3e6330018e2f2b312e4489dca0da Mon Sep 17 00:00:00 2001
From: Piotr Jasiun
Date: Fri, 3 Jan 2014 17:38:11 +0100
Subject: [PATCH 6/8] Added comment to onlyWhiteSpaces.
---
core/dom/range.js | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/core/dom/range.js b/core/dom/range.js
index 9a3a9de90db..6b8e22197a3 100644
--- a/core/dom/range.js
+++ b/core/dom/range.js
@@ -1115,6 +1115,14 @@ CKEDITOR.dom.range = function( root ) {
enlargeable = sibling = null;
commonReached = needsWhiteSpace = false;
+ // 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):
+ // - foo[
- will return true,
+ // - foo[
- will return true,
+ // - foo[ bar
- will return false,
+ // - foo[ bar
- will return false,
+ // - foo[
- 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
From 94b1ee592d6761b2a433212336c0a598eb2776f2 Mon Sep 17 00:00:00 2001
From: Aleksander Nowodzinski
Date: Tue, 7 Jan 2014 10:31:13 +0100
Subject: [PATCH 7/8] Re-used the regex.
---
core/dom/range.js | 13 +++++++------
1 file changed, 7 insertions(+), 6 deletions(-)
diff --git a/core/dom/range.js b/core/dom/range.js
index 6b8e22197a3..e97b52156a9 100644
--- a/core/dom/range.js
+++ b/core/dom/range.js
@@ -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;
@@ -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 );
@@ -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( '*' );
@@ -1135,8 +1137,7 @@ CKEDITOR.dom.range = function( root ) {
walkerRange.setEndAt( boundary, CKEDITOR.POSITION_BEFORE_END );
var walker = new CKEDITOR.dom.walker( walkerRange ),
- node,
- whitespaceRegexp = new RegExp( /[^\s\ufeff]/ );
+ node;
walker.guard = function( node, movingOut ) {
// Stop if you exit block.
@@ -1156,7 +1157,7 @@ CKEDITOR.dom.range = function( root ) {
siblingText = node.substring( startOffset )
// Check if it is white space.
- if ( ( whitespaceRegexp.test( siblingText ) ) )
+ if ( leadingWhitespaceRegex.test( siblingText ) )
return false;
}
}
@@ -1242,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( '*' );
From 3ee3e3bdf8a346f36f7692998bac780b676049fb Mon Sep 17 00:00:00 2001
From: Piotr Jasiun
Date: Tue, 7 Jan 2014 16:32:14 +0100
Subject: [PATCH 8/8] Changelog entry.
---
CHANGES.md | 1 +
1 file changed, 1 insertion(+)
diff --git a/CHANGES.md b/CHANGES.md
index ceaf72f196b..96d35fee0e8 100644
--- a/CHANGES.md
+++ b/CHANGES.md
@@ -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