X-Git-Url: https://git.immae.eu/?p=perso%2FImmae%2FProjets%2Fpackagist%2Fludivine-ckeditor-component.git;a=blobdiff_plain;f=sources%2Fcore%2Fdom%2Frange.js;h=742c24c6586010c06370b67099d12cf8515b4a20;hp=64070743a30d29214605d9ab6a6f5b67fcc40366;hb=1794320dcfdfcd19572fb1676294f9853a6bbc20;hpb=c63493c899de714b05b0521bb38aab60d19030ef
diff --git a/sources/core/dom/range.js b/sources/core/dom/range.js
index 6407074..742c24c 100644
--- a/sources/core/dom/range.js
+++ b/sources/core/dom/range.js
@@ -204,9 +204,14 @@ CKEDITOR.dom.range = function( root ) {
// This allows us to not think about startNode == endNode case later on.
// We do that only when cloning, because in other cases we can safely split this text node
// and hence we can easily handle this case as many others.
- if ( isClone && endNode.type == CKEDITOR.NODE_TEXT && startNode.equals( endNode ) ) {
- startNode = range.document.createText( startNode.substring( startOffset, endOffset ) );
- docFrag.append( startNode );
+
+ // We need to handle situation when selection startNode is type of NODE_ELEMENT (#426).
+ if ( isClone &&
+ endNode.type == CKEDITOR.NODE_TEXT &&
+ ( startNode.equals( endNode ) || ( startNode.type === CKEDITOR.NODE_ELEMENT && startNode.getFirst().equals( endNode ) ) ) ) {
+
+ // Here we should always be inside one text node.
+ docFrag.append( range.document.createText( endNode.substring( startOffset, endOffset ) ) );
return;
}
@@ -214,7 +219,7 @@ CKEDITOR.dom.range = function( root ) {
// second part. The removal will be handled by the rest of the code.
if ( endNode.type == CKEDITOR.NODE_TEXT ) {
// If Extract or Delete we can split the text node,
- // but if Clone (2), then we cannot modify the DOM (#11586) so we mark the text node for cloning.
+ // but if Clone (2), then we cannot modify the DOM (http://dev.ckeditor.com/ticket/11586) so we mark the text node for cloning.
if ( !isClone ) {
endNode = endNode.split( endOffset );
} else {
@@ -243,7 +248,7 @@ CKEDITOR.dom.range = function( root ) {
// be handled by the rest of the code .
if ( startNode.type == CKEDITOR.NODE_TEXT ) {
// If Extract or Delete we can split the text node,
- // but if Clone (2), then we cannot modify the DOM (#11586) so we mark
+ // but if Clone (2), then we cannot modify the DOM (http://dev.ckeditor.com/ticket/11586) so we mark
// the text node for cloning.
if ( !isClone ) {
startNode.split( startOffset );
@@ -373,7 +378,7 @@ CKEDITOR.dom.range = function( root ) {
// If we don't do that, in next iterations nodes will be appended to wrong parent.
//
// We can just take first child because the algorithm guarantees
- // that this will be the only child on this level. (#13568)
+ // that this will be the only child on this level. (http://dev.ckeditor.com/ticket/13568)
levelParent = levelParent.getChild( 0 );
}
}
@@ -405,7 +410,7 @@ CKEDITOR.dom.range = function( root ) {
// When Extracting, move the removed node to the docFrag.
if ( isExtract ) {
- newParent.append( node );
+ newParent.append( node, toStart );
}
}
@@ -574,7 +579,7 @@ CKEDITOR.dom.range = function( root ) {
// Tolerant bogus br when checking at the end of block.
// Reject any text node unless it's being bookmark
// OR it's spaces.
- // Reject any element unless it's being invisible empty. (#3883)
+ // Reject any element unless it's being invisible empty. (http://dev.ckeditor.com/ticket/3883)
return !checkStart && isBogus( node ) ||
node.type == CKEDITOR.NODE_ELEMENT &&
node.is( CKEDITOR.dtd.$removeEmpty );
@@ -1052,7 +1057,7 @@ CKEDITOR.dom.range = function( root ) {
}
// Sometimes the endNode will come right before startNode for collapsed
- // ranges. Fix it. (#3780)
+ // ranges. Fix it. (http://dev.ckeditor.com/ticket/3780)
if ( startNode.getPosition( endNode ) & CKEDITOR.POSITION_FOLLOWING )
startNode = endNode;
@@ -1324,13 +1329,13 @@ CKEDITOR.dom.range = function( root ) {
isWhiteSpace = /[\s\ufeff]$/.test( siblingText );
} else {
- // #12221 (Chrome) plus #11111 (Safari).
+ // http://dev.ckeditor.com/ticket/12221 (Chrome) plus http://dev.ckeditor.com/ticket/11111 (Safari).
var offsetWidth0 = CKEDITOR.env.webkit ? 1 : 0;
// If this is a visible element.
// We need to check for the bookmark attribute because IE insists on
- // rendering the display:none nodes we use for bookmarks. (#3363)
- // Line-breaks (br) are rendered with zero width, which we don't want to include. (#7041)
+ // rendering the display:none nodes we use for bookmarks. (http://dev.ckeditor.com/ticket/3363)
+ // Line-breaks (br) are rendered with zero width, which we don't want to include. (http://dev.ckeditor.com/ticket/7041)
if ( ( sibling.$.offsetWidth > offsetWidth0 || excludeBrs && sibling.is( 'br' ) ) && !sibling.data( 'cke-bookmark' ) ) {
// We'll accept it only if we need
// whitespace, and this is an inline
@@ -1399,7 +1404,7 @@ CKEDITOR.dom.range = function( root ) {
// Process the end boundary. This is basically the same
// code used for the start boundary, with small changes to
- // make it work in the oposite side (to the right). This
+ // make it work in the opposite side (to the right). This
// makes it difficult to reuse the code here. So, fixes to
// the above code are likely to be replicated here.
@@ -1482,7 +1487,7 @@ CKEDITOR.dom.range = function( root ) {
}
}
} else {
- // Get the node right after the boudary to be checked
+ // Get the node right after the boundary to be checked
// first.
sibling = container.getChild( offset );
@@ -1525,8 +1530,8 @@ CKEDITOR.dom.range = function( root ) {
} else if ( sibling.type == CKEDITOR.NODE_ELEMENT ) {
// If this is a visible element.
// We need to check for the bookmark attribute because IE insists on
- // rendering the display:none nodes we use for bookmarks. (#3363)
- // Line-breaks (br) are rendered with zero width, which we don't want to include. (#7041)
+ // rendering the display:none nodes we use for bookmarks. (http://dev.ckeditor.com/ticket/3363)
+ // Line-breaks (br) are rendered with zero width, which we don't want to include. (http://dev.ckeditor.com/ticket/7041)
if ( ( sibling.$.offsetWidth > 0 || excludeBrs && sibling.is( 'br' ) ) && !sibling.data( 'cke-bookmark' ) ) {
// We'll accept it only if we need
// whitespace, and this is an inline
@@ -1617,7 +1622,7 @@ CKEDITOR.dom.range = function( root ) {
boundaryGuard = function( node ) {
// We should not check contents of non-editable elements. It may happen
// that inline widget has display:table child which should not block range#enlarge.
- // When encoutered non-editable element...
+ // When encountered non-editable element...
if ( node.type == CKEDITOR.NODE_ELEMENT && node.getAttribute( 'contenteditable' ) == 'false' ) {
if ( inNonEditable ) {
// ... in which we already were, reset it (because we're leaving it) and return.
@@ -1639,7 +1644,7 @@ CKEDITOR.dom.range = function( root ) {
blockBoundary = node;
return retval;
},
- // Record the encounted 'tailBr' for later use.
+ // Record the encountered 'tailBr' for later use.
tailBrGuard = function( node ) {
var retval = boundaryGuard( node );
if ( !retval && node.is && node.is( 'br' ) )
@@ -1660,7 +1665,7 @@ CKEDITOR.dom.range = function( root ) {
this.setStartAt( blockBoundary, !blockBoundary.is( 'br' ) && ( !enlargeable && this.checkStartOfBlock() ||
enlargeable && blockBoundary.contains( enlargeable ) ) ? CKEDITOR.POSITION_AFTER_START : CKEDITOR.POSITION_AFTER_END );
- // Avoid enlarging the range further when end boundary spans right after the BR. (#7490)
+ // Avoid enlarging the range further when end boundary spans right after the BR. (http://dev.ckeditor.com/ticket/7490)
if ( unit == CKEDITOR.ENLARGE_LIST_ITEM_CONTENTS ) {
var theRange = this.clone();
walker = new CKEDITOR.dom.walker( theRange );
@@ -1715,18 +1720,28 @@ CKEDITOR.dom.range = function( root ) {
},
/**
- * Descrease the range to make sure that boundaries
- * always anchor beside text nodes or innermost element.
+ * Decreases the range to make sure that boundaries
+ * always anchor beside text nodes or the innermost element.
*
* @param {Number} mode The shrinking mode ({@link CKEDITOR#SHRINK_ELEMENT} or {@link CKEDITOR#SHRINK_TEXT}).
*
- * * {@link CKEDITOR#SHRINK_ELEMENT} - Shrink the range boundaries to the edge of the innermost element.
- * * {@link CKEDITOR#SHRINK_TEXT} - Shrink the range boudaries to anchor by the side of enclosed text
- * node, range remains if there's no text nodes on boundaries at all.
- *
- * @param {Boolean} selectContents Whether result range anchors at the inner OR outer boundary of the node.
+ * * {@link CKEDITOR#SHRINK_ELEMENT} – Shrinks the range boundaries to the edge of the innermost element.
+ * * {@link CKEDITOR#SHRINK_TEXT} – Shrinks the range boundaries to anchor by the side of enclosed text
+ * node. The range remains if there are no text nodes available on boundaries.
+ *
+ * @param {Boolean} [selectContents=false] Whether the resulting range anchors at the inner OR outer boundary of the node.
+ * @param {Boolean/Object} [options=true] If this parameter is of a Boolean type, it is treated as
+ * `options.shrinkOnBlockBoundary`. This parameter was added in 4.7.0.
+ * @param {Boolean} [options.shrinkOnBlockBoundary=true] Whether the block boundary should be included in
+ * the shrunk range.
+ * @param {Boolean} [options.skipBogus=false] Whether bogus `
` elements should be ignored while
+ * `mode` is set to {@link CKEDITOR#SHRINK_TEXT}. This option was added in 4.7.0.
*/
- shrink: function( mode, selectContents, shrinkOnBlockBoundary ) {
+ shrink: function( mode, selectContents, options ) {
+ var shrinkOnBlockBoundary = typeof options === 'boolean' ? options :
+ ( options && typeof options.shrinkOnBlockBoundary === 'boolean' ? options.shrinkOnBlockBoundary : true ),
+ skipBogus = options && options.skipBogus;
+
// Unable to shrink a collapsed range.
if ( !this.collapsed ) {
mode = mode || CKEDITOR.SHRINK_TEXT;
@@ -1749,7 +1764,7 @@ CKEDITOR.dom.range = function( root ) {
walkerRange.setStartAfter( startContainer );
else {
// Enlarge the range properly to avoid walker making
- // DOM changes caused by triming the text nodes later.
+ // DOM changes caused by trimming the text nodes later.
walkerRange.setStartBefore( startContainer );
moveStart = 0;
}
@@ -1767,7 +1782,8 @@ CKEDITOR.dom.range = function( root ) {
}
var walker = new CKEDITOR.dom.walker( walkerRange ),
- isBookmark = CKEDITOR.dom.walker.bookmark();
+ isBookmark = CKEDITOR.dom.walker.bookmark(),
+ isBogus = CKEDITOR.dom.walker.bogus();
walker.evaluator = function( node ) {
return node.type == ( mode == CKEDITOR.SHRINK_ELEMENT ? CKEDITOR.NODE_ELEMENT : CKEDITOR.NODE_TEXT );
@@ -1775,6 +1791,11 @@ CKEDITOR.dom.range = function( root ) {
var currentElement;
walker.guard = function( node, movingOut ) {
+ // Skipping bogus before other cases (http://dev.ckeditor.com/ticket/17010).
+ if ( skipBogus && isBogus( node ) ) {
+ return true;
+ }
+
if ( isBookmark( node ) )
return true;
@@ -1816,7 +1837,7 @@ CKEDITOR.dom.range = function( root ) {
/**
* Inserts a node at the start of the range. The range will be expanded
- * the contain the node.
+ * to contain the node.
*
* @param {CKEDITOR.dom.node} node
*/
@@ -1843,7 +1864,7 @@ CKEDITOR.dom.range = function( root ) {
},
/**
- * Moves the range to given position according to specified node.
+ * Moves the range to a given position according to the specified node.
*
* // HTML:
Foo bar
* range.moveToPosition( elB, CKEDITOR.POSITION_BEFORE_START ); @@ -1851,7 +1872,7 @@ CKEDITOR.dom.range = function( root ) { * * See also {@link #setStartAt} and {@link #setEndAt}. * - * @param {CKEDITOR.dom.node} node The node according to which position will be set. + * @param {CKEDITOR.dom.node} node The node according to which the position will be set. * @param {Number} position One of {@link CKEDITOR#POSITION_BEFORE_START}, * {@link CKEDITOR#POSITION_AFTER_START}, {@link CKEDITOR#POSITION_BEFORE_END}, * {@link CKEDITOR#POSITION_AFTER_END}. @@ -2118,7 +2139,7 @@ CKEDITOR.dom.range = function( root ) { // So even if the initial range was placed before the bogus