X-Git-Url: https://git.immae.eu/?a=blobdiff_plain;f=sources%2Fcore%2Fselection.js;h=d44db3bc282dd62f268cd77ce2c20f34468436c3;hb=317f8f8f0651488f226b5280a8f036c7c135c639;hp=573b890e18d89bd42f58550f4ccd7e99f456bfe4;hpb=3332bebe4da6dfa0fe3e4b2abddc84b1cc62f8f5;p=perso%2FImmae%2FProjets%2Fpackagist%2Fpiedsjaloux-ckeditor-component.git
diff --git a/sources/core/selection.js b/sources/core/selection.js
index 573b890..d44db3b 100644
--- a/sources/core/selection.js
+++ b/sources/core/selection.js
@@ -1,9 +1,217 @@
/**
- * @license Copyright (c) 2003-2016, CKSource - Frederico Knabben. All rights reserved.
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
* For licensing, see LICENSE.md or http://ckeditor.com/license
*/
( function() {
+ var isMSSelection = typeof window.getSelection != 'function',
+ nextRev = 1,
+ // http://dev.ckeditor.com/ticket/13816
+ fillingCharSequence = CKEDITOR.tools.repeat( '\u200b', 7 ),
+ fillingCharSequenceRegExp = new RegExp( fillingCharSequence + '( )?', 'g' ),
+ isSelectingTable;
+
+ // #### table selection : START
+ // @param {CKEDITOR.dom.range[]} ranges
+ // @param {Boolean} allowPartially Whether a collapsed selection within table is recognized to be a valid selection.
+ // This happens for WebKits on MacOS, when you right click inside the table.
+ function isTableSelection( ranges, allowPartially ) {
+ if ( ranges.length === 0 ) {
+ return false;
+ }
+
+ var node,
+ i;
+
+ function isPartiallySelected( range ) {
+ var startCell = range.startContainer.getAscendant( { td: 1, th: 1 }, true ),
+ endCell = range.endContainer.getAscendant( { td: 1, th: 1 }, true ),
+ trim = CKEDITOR.tools.trim,
+ selected;
+
+ // Check if the selection is inside one cell and we don't have any nested table contents selected.
+ if ( !startCell || !startCell.equals( endCell ) || startCell.findOne( 'td, th, tr, tbody, table' ) ) {
+ return false;
+ }
+
+ selected = range.cloneContents();
+
+ // Empty selection is still partially selected.
+ if ( !selected.getFirst() ) {
+ return true;
+ }
+
+ return trim( selected.getFirst().getText() ) !== trim( startCell.getText() );
+ }
+
+ // Edge case: partially selected text node inside one table cell or cursor inside cell.
+ if ( !allowPartially && ranges.length === 1 &&
+ ( ranges[ 0 ].collapsed || isPartiallySelected( ranges[ 0 ] ) ) ) {
+ return false;
+ }
+
+ for ( i = 0; i < ranges.length; i++ ) {
+ node = ranges[ i ]._getTableElement();
+
+ if ( !node ) {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ // After performing fake table selection, the real selection is limited
+ // to the first selected cell. Therefore to check if the real selection
+ // matches the fake selection, we check if the table cell from fake selection's
+ // first range and real selection's range are the same.
+ // Also if the selection is collapsed, we should check if it's placed inside the table
+ // in which the fake selection is or inside nested table. Such selection occurs after right mouse click.
+ function isRealTableSelection( selection, fakeSelection ) {
+ var ranges = selection.getRanges(),
+ fakeRanges = fakeSelection.getRanges(),
+ table = ranges.length && ranges[ 0 ]._getTableElement() &&
+ ranges[ 0 ]._getTableElement().getAscendant( 'table', true ),
+ fakeTable = fakeRanges.length && fakeRanges[ 0 ]._getTableElement() &&
+ fakeRanges[ 0 ]._getTableElement().getAscendant( 'table', true ),
+ isTableRange = ranges.length === 1 && ranges[ 0 ]._getTableElement() &&
+ ranges[ 0 ]._getTableElement().is( 'table' ),
+ isFakeTableRange = fakeRanges.length === 1 && fakeRanges[ 0 ]._getTableElement() &&
+ fakeRanges[ 0 ]._getTableElement().is( 'table' );
+
+ function isValidTableSelection( table, fakeTable, ranges, fakeRanges ) {
+ var isMenuOpen = ranges.length === 1 && ranges[ 0 ].collapsed,
+ // In case of WebKit on MacOS, when checking real selection, we must allow selection to be partial.
+ // Otherwise the check will fail for table selection with opened context menu.
+ isInTable = isTableSelection( ranges, !!CKEDITOR.env.webkit ) && isTableSelection( fakeRanges );
+
+ return isSameTable( table, fakeTable ) && ( isMenuOpen || isInTable );
+ }
+
+ function isSameTable( table, fakeTable ) {
+ if ( !table || !fakeTable ) {
+ return false;
+ }
+
+ return table.equals( fakeTable ) || fakeTable.contains( table );
+ }
+
+ if ( isValidTableSelection( table, fakeTable, ranges, fakeRanges ) ) {
+ // Edge case: when editor contains only table and that table is selected using selectAll command,
+ // then the selection is not properly refreshed and it must be done manually.
+ if ( isTableRange && !isFakeTableRange ) {
+ fakeSelection.selectRanges( ranges );
+ }
+ return true;
+ }
+
+ return false;
+ }
+
+ function getSelectedCells( ranges ) {
+ var cells = [],
+ node,
+ i;
+
+ function getCellsFromElement( element ) {
+ var cells = element.find( 'td, th' ),
+ cellsArray = [],
+ i;
+
+ for ( i = 0; i < cells.count(); i++ ) {
+ cellsArray.push( cells.getItem( i ) );
+ }
+
+ return cellsArray;
+ }
+
+ for ( i = 0; i < ranges.length; i++ ) {
+ node = ranges[ i ]._getTableElement();
+
+ if ( node.is && node.is( { td: 1, th: 1 } ) ) {
+ cells.push( node );
+ } else {
+ cells = cells.concat( getCellsFromElement( node ) );
+ }
+ }
+
+ return cells;
+ }
+
+ // Cells in the same row are separated by tab and the rows are separated by new line, e.g.
+ // Cell 1.1 Cell 1.2
+ // Cell 2.1 Cell 2.2
+ function getTextFromSelectedCells( ranges ) {
+ var cells = getSelectedCells( ranges ),
+ txt = '',
+ currentRow = [],
+ lastRow,
+ i;
+
+ for ( i = 0; i < cells.length; i++ ) {
+ if ( lastRow && !lastRow.equals( cells[ i ].getAscendant( 'tr' ) ) ) {
+ txt += currentRow.join( '\t' ) + '\n';
+ lastRow = cells[ i ].getAscendant( 'tr' );
+ currentRow = [];
+ } else if ( i === 0 ) {
+ lastRow = cells[ i ].getAscendant( 'tr' );
+ }
+
+ currentRow.push( cells[ i ].getText() );
+ }
+
+ txt += currentRow.join( '\t' );
+
+ return txt;
+ }
+
+ function performFakeTableSelection( ranges ) {
+ var editor = this.root.editor,
+ realSelection = editor.getSelection( 1 ),
+ cache;
+
+ // Cleanup after previous selection - e.g. remove hidden sel container.
+ this.reset();
+
+ // Indicate that the table is being fake-selected to prevent infinite loop
+ // inside `selectRanges`.
+ isSelectingTable = true;
+
+ // Cancel selectionchange for the real selection.
+ realSelection.root.once( 'selectionchange', function( evt ) {
+ evt.cancel();
+ }, null, null, 0 );
+
+ // Move real selection to the first selected range.
+ realSelection.selectRanges( [ ranges[ 0 ] ] );
+
+ cache = this._.cache;
+
+ // Caches given ranges.
+ cache.ranges = new CKEDITOR.dom.rangeList( ranges );
+ cache.type = CKEDITOR.SELECTION_TEXT;
+ cache.selectedElement = ranges[ 0 ]._getTableElement();
+
+ // `selectedText` should contain text from all selected data ("plain text table")
+ // to be compatible with Firefox's implementation.
+ cache.selectedText = getTextFromSelectedCells( ranges );
+
+ // Properties that will not be available when isFake.
+ cache.nativeSel = null;
+
+ this.isFake = 1;
+ this.rev = nextRev++;
+
+ // Save this selection, so it can be returned by editor.getSelection().
+ editor._.fakeSelection = this;
+
+ isSelectingTable = false;
+
+ // Fire selectionchange, just like a normal selection.
+ this.root.fire( 'selectionchange' );
+ }
+ // #### table selection : END
+
// #### checkSelectionChange : START
// The selection change check basically saves the element parent tree of
@@ -16,10 +224,9 @@
if ( sel ) {
realSel = this.getSelection( 1 );
-
- // If real (not locked/stored) selection was moved from hidden container,
- // then the fake-selection must be invalidated.
- if ( !realSel || !realSel.isHidden() ) {
+ // If real (not locked/stored) selection was moved from hidden container
+ // or is not a table one, then the fake-selection must be invalidated.
+ if ( !realSel || ( !realSel.isHidden() && !isRealTableSelection( realSel, sel ) ) ) {
// Remove the cache from fake-selection references in use elsewhere.
sel.reset();
@@ -41,8 +248,10 @@
var currentPath = this.elementPath();
if ( !currentPath.compare( this._.selectionPreviousPath ) ) {
+ // Handle case when dialog inserts new element but parent block and path (so also focus context) does not change. (http://dev.ckeditor.com/ticket/13362)
+ var sameBlockParent = this._.selectionPreviousPath && this._.selectionPreviousPath.blockLimit.equals( currentPath.blockLimit );
// Cache the active element, which we'll eventually lose on Webkit.
- if ( CKEDITOR.env.webkit )
+ if ( CKEDITOR.env.webkit && !sameBlockParent )
this._.previousActive = this.document.getActive();
this._.selectionPreviousPath = currentPath;
@@ -89,7 +298,7 @@
// * is a visible node,
// * is a non-empty element (this rule will accept elements like because they
// they were not accepted by the isVisible() check, not not which cannot absorb the caret).
- // See #12621.
+ // See http://dev.ckeditor.com/ticket/12621.
function mayAbsorbCaret( node ) {
if ( isVisible( node ) )
return true;
@@ -130,8 +339,8 @@
if ( ctxRequiresFix( previous ) || ctxRequiresFix( next, 1 ) )
return true;
- // Empty block/inline element is also affected. ^,
^
(#7222)
- // If you found this line confusing check #12655.
+ // Empty block/inline element is also affected. ^,
^
(http://dev.ckeditor.com/ticket/7222)
+ // If you found this line confusing check http://dev.ckeditor.com/ticket/12655.
if ( !( previous || next ) && !( ct.type == CKEDITOR.NODE_ELEMENT && ct.isBlockBoundary() && ct.getBogus() ) )
return true;
@@ -147,7 +356,7 @@
return fillingChar;
}
- // Checks if a filling char has been used, eventualy removing it (#1272).
+ // Checks if a filling char has been used, eventually removing it (http://dev.ckeditor.com/ticket/1272).
function checkFillingCharSequenceNodeReady( editable ) {
var fillingChar = editable.getCustomData( 'cke-fillingChar' );
@@ -156,6 +365,7 @@
// creating it.
if ( fillingChar.getCustomData( 'ready' ) ) {
removeFillingCharSequenceNode( editable );
+ editable.editor.fire( 'selectionCheck' );
} else {
fillingChar.setCustomData( 'ready', 1 );
}
@@ -167,7 +377,7 @@
if ( fillingChar ) {
// Text selection position might get mangled by
- // subsequent dom modification, save it now for restoring. (#8617)
+ // subsequent dom modification, save it now for restoring. (http://dev.ckeditor.com/ticket/8617)
if ( keepSelection !== false ) {
var sel = editable.getDocument().getSelection().getNative(),
// Be error proof.
@@ -203,11 +413,11 @@
}
}
- // #13816
+ // http://dev.ckeditor.com/ticket/13816
function removeFillingCharSequenceString( str, nbspAware ) {
if ( nbspAware ) {
return str.replace( fillingCharSequenceRegExp, function( m, p ) {
- // #10291 if filling char is followed by a space replace it with NBSP.
+ // http://dev.ckeditor.com/ticket/10291 if filling char is followed by a space replace it with NBSP.
return p ? '\xa0' : '';
} );
} else {
@@ -234,10 +444,11 @@
}
// Creates cke_hidden_sel container and puts real selection there.
- function hideSelection( editor ) {
- var style = CKEDITOR.env.ie ? 'display:none' : 'position:fixed;top:0;left:-1000px',
+ function hideSelection( editor, ariaLabel ) {
+ var content = ariaLabel || ' ',
+ style = CKEDITOR.env.ie && CKEDITOR.env.version < 14 ? 'display:none' : 'position:fixed;top:0;left:-1000px',
hiddenEl = CKEDITOR.dom.element.createFromHtml(
- '
',
+ '
' + content + '
',
editor.document );
editor.fire( 'lockSnapshot' );
@@ -382,7 +593,7 @@
( enclosedNode = range.getEnclosedNode() ) && enclosedNode.type == CKEDITOR.NODE_ELEMENT ) {
// So far we can't say that enclosed element is non-editable. Before checking,
// we'll shrink range (clone). Shrinking will stop on non-editable range, or
- // innermost element (#11114).
+ // innermost element (http://dev.ckeditor.com/ticket/11114).
clone = range.clone();
clone.shrink( CKEDITOR.SHRINK_ELEMENT, true );
@@ -516,7 +727,7 @@
// Give the editable an initial selection on first focus,
// put selection at a consistent position at the start
- // of the contents. (#9507)
+ // of the contents. (http://dev.ckeditor.com/ticket/9507)
if ( CKEDITOR.env.gecko ) {
editable.attachListener( editable, 'focus', function( evt ) {
evt.removeListener();
@@ -524,7 +735,7 @@
if ( restoreSel !== 0 ) {
var nativ = editor.getSelection().getNative();
// Do it only if the native selection is at an unwanted
- // place (at the very start of the editable). #10119
+ // place (at the very start of the editable). http://dev.ckeditor.com/ticket/10119
if ( nativ && nativ.isCollapsed && nativ.anchorNode == editable.$ ) {
var rng = editor.createRange();
rng.moveToElementEditStart( editable );
@@ -539,9 +750,17 @@
// On Webkit we use DOMFocusIn which is fired more often than focus - e.g. when moving from main editable
// to nested editable (or the opposite). Unlock selection all, but restore only when it was locked
// for the same active element, what will e.g. mean restoring after displaying dialog.
- if ( restoreSel && CKEDITOR.env.webkit )
+ if ( restoreSel && CKEDITOR.env.webkit ) {
restoreSel = editor._.previousActive && editor._.previousActive.equals( doc.getActive() );
+ // On Webkit when editor uses divarea, native focus causes editable viewport to scroll
+ // to the top (when there is no active selection inside while focusing) so the scroll
+ // position should be restored after focusing back editable area. (http://dev.ckeditor.com/ticket/14659)
+ if ( restoreSel && editor._.previousScrollTop != null && editor._.previousScrollTop != editable.$.scrollTop ) {
+ editable.$.scrollTop = editor._.previousScrollTop;
+ }
+ }
+
editor.unlockSelection( restoreSel );
restoreSel = 0;
}, null, null, -1 );
@@ -588,7 +807,7 @@
editable.attachListener( editable, 'mousedown', function( evt ) {
// IE scrolls document to top on right mousedown
// when editor has no focus, remember this scroll
- // position and revert it before context menu opens. (#5778)
+ // position and revert it before context menu opens. (http://dev.ckeditor.com/ticket/5778)
if ( evt.data.$.button == 2 ) {
var sel = editor.document.getSelection();
if ( !sel || sel.getType() == CKEDITOR.SELECTION_NONE )
@@ -607,9 +826,12 @@
// When content doc is in standards mode, IE doesn't focus the editor when
// clicking at the region below body (on html element) content, we emulate
- // the normal behavior on old IEs. (#1659, #7932)
+ // the normal behavior on old IEs. (http://dev.ckeditor.com/ticket/1659, http://dev.ckeditor.com/ticket/7932)
if ( doc.$.compatMode != 'BackCompat' ) {
if ( CKEDITOR.env.ie7Compat || CKEDITOR.env.ie6Compat ) {
+ var textRng,
+ startRng;
+
html.on( 'mousedown', function( evt ) {
evt = evt.data;
@@ -641,7 +863,7 @@
html.removeListener( 'mousemove', onHover );
removeListeners();
- // Make it in effect on mouse up. (#9022)
+ // Make it in effect on mouse up. (http://dev.ckeditor.com/ticket/9022)
textRng.select();
}
@@ -652,11 +874,11 @@
evt.$.y < html.$.clientHeight &&
evt.$.x < html.$.clientWidth ) {
// Start to build the text range.
- var textRng = body.$.createTextRange();
+ textRng = body.$.createTextRange();
moveRangeToPoint( textRng, evt.$.clientX, evt.$.clientY );
// Records the dragging start of the above text range.
- var startRng = textRng.duplicate();
+ startRng = textRng.duplicate();
html.on( 'mousemove', onHover );
outerDoc.on( 'mouseup', onSelectEnd );
@@ -670,7 +892,7 @@
if ( CKEDITOR.env.version > 7 && CKEDITOR.env.version < 11 ) {
html.on( 'mousedown', function( evt ) {
if ( evt.data.getTarget().is( 'html' ) ) {
- // Limit the text selection mouse move inside of editable. (#9715)
+ // Limit the text selection mouse move inside of editable. (http://dev.ckeditor.com/ticket/9715)
outerDoc.on( 'mouseup', onSelectEnd );
html.on( 'mouseup', onSelectEnd );
}
@@ -684,6 +906,14 @@
// 2. After the accomplish of keyboard and mouse events.
editable.attachListener( editable, 'selectionchange', checkSelectionChange, editor );
editable.attachListener( editable, 'keyup', checkSelectionChangeTimeout, editor );
+ // http://dev.ckeditor.com/ticket/14407 - Don't even let anything happen if the selection is in a non-editable element.
+ editable.attachListener( editable, 'keydown', function( evt ) {
+ var sel = this.getSelection( 1 );
+ if ( nonEditableAscendant( sel ) ) {
+ sel.selectElement( nonEditableAscendant( sel ) );
+ evt.data.preventDefault();
+ }
+ }, editor );
// Always fire the selection change on focus gain.
// On Webkit do this on DOMFocusIn, because the selection is unlocked on it too and
// we need synchronization between those listeners to not lost cached editor._.previousActive property
@@ -693,7 +923,7 @@
editor.selectionChange( 1 );
} );
- // #9699: On Webkit&Gecko in inline editor we have to check selection when it was changed
+ // http://dev.ckeditor.com/ticket/9699: On Webkit&Gecko in inline editor we have to check selection when it was changed
// by dragging and releasing mouse button outside editable. Dragging (mousedown)
// has to be initialized in editable, but for mouseup we listen on document element.
if ( isInline && ( CKEDITOR.env.webkit || CKEDITOR.env.gecko ) ) {
@@ -707,11 +937,11 @@
mouseDown = 0;
} );
}
- // In all other cases listen on simple mouseup over editable, as we did before #9699.
+ // In all other cases listen on simple mouseup over editable, as we did before http://dev.ckeditor.com/ticket/9699.
//
// Use document instead of editable in non-IEs for observing mouseup
// since editable won't fire the event if selection process started within iframe and ended out
- // of the editor (#9851).
+ // of the editor (http://dev.ckeditor.com/ticket/9851).
else {
editable.attachListener( CKEDITOR.env.ie ? editable : doc.getDocumentElement(), 'mouseup', checkSelectionChangeTimeout, editor );
}
@@ -733,18 +963,18 @@
case 8: // BACKSPACE
case 45: // INS
case 46: // DEl
- removeFillingCharSequenceNode( editable );
+ if ( editable.hasFocus ) {
+ removeFillingCharSequenceNode( editable );
+ }
}
}, null, null, -1 );
}
- // Automatically select non-editable element when navigating into
- // it by left/right or backspace/del keys.
editable.attachListener( editable, 'keydown', getOnKeyDownListener( editor ), null, null, -1 );
function moveRangeToPoint( range, x, y ) {
- // Error prune in IE7. (#9034, #9110)
+ // Error prune in IE7. (http://dev.ckeditor.com/ticket/9034, http://dev.ckeditor.com/ticket/9110)
try {
range.moveToPoint( x, y );
} catch ( e ) {}
@@ -765,14 +995,27 @@
range = sel.createRange();
// The selection range is reported on host, but actually it should applies to the content doc.
- if ( sel.type != 'None' && range.parentElement().ownerDocument == doc.$ )
+ // The parentElement may be null for read only mode in IE10 and below (http://dev.ckeditor.com/ticket/9780).
+ if ( sel.type != 'None' && range.parentElement() && range.parentElement().ownerDocument == doc.$ )
range.select();
}
+
+ function nonEditableAscendant( sel ) {
+ if ( CKEDITOR.env.ie ) {
+ var range = sel.getRanges()[ 0 ],
+ ascendant = range ? range.startContainer.getAscendant( function( parent ) {
+ return parent.type == CKEDITOR.NODE_ELEMENT &&
+ ( parent.getAttribute( 'contenteditable' ) == 'false' || parent.getAttribute( 'contenteditable' ) == 'true' );
+ }, true ) : null ;
+
+ return range && ascendant.getAttribute( 'contenteditable' ) == 'false' && ascendant;
+ }
+ }
} );
editor.on( 'setData', function() {
// Invalidate locked selection when unloading DOM.
- // (#9521, #5217#comment:32 and #11500#comment:11)
+ // (http://dev.ckeditor.com/ticket/9521, http://dev.ckeditor.com/ticket/5217#comment:32 and http://dev.ckeditor.com/ticket/11500#comment:11)
editor.unlockSelection();
// Webkit's selection will mess up after the data loading.
@@ -786,7 +1029,7 @@
editor.unlockSelection();
} );
- // IE9 might cease to work if there's an object selection inside the iframe (#7639).
+ // IE9 might cease to work if there's an object selection inside the iframe (http://dev.ckeditor.com/ticket/7639).
if ( CKEDITOR.env.ie9Compat )
editor.on( 'beforeDestroy', clearSelection, null, null, 9 );
@@ -802,7 +1045,7 @@
// When loaded data are ready check whether hidden selection container was not loaded.
editor.on( 'loadSnapshot', function() {
var isElement = CKEDITOR.dom.walker.nodeType( CKEDITOR.NODE_ELEMENT ),
- // TODO replace with el.find() which will be introduced in #9764,
+ // TODO replace with el.find() which will be introduced in http://dev.ckeditor.com/ticket/9764,
// because it may happen that hidden sel container won't be the last element.
last = editor.editable().getLast( isElement );
@@ -849,7 +1092,7 @@
} );
// On WebKit only, we need a special "filling" char on some situations
- // (#1272). Here we set the events that should invalidate that char.
+ // (http://dev.ckeditor.com/ticket/1272). Here we set the events that should invalidate that char.
if ( CKEDITOR.env.webkit ) {
CKEDITOR.on( 'instanceReady', function( evt ) {
var editor = evt.editor;
@@ -864,7 +1107,7 @@
// Filter Undo snapshot's HTML to get rid of Filling Char Sequence.
// Note: CKEDITOR.dom.range.createBookmark2() normalizes snapshot's
- // bookmarks to anticipate the removal of FCSeq from the snapshot's HTML (#13816).
+ // bookmarks to anticipate the removal of FCSeq from the snapshot's HTML (http://dev.ckeditor.com/ticket/13816).
editor.on( 'getSnapshot', function( evt ) {
if ( evt.data ) {
evt.data = removeFillingCharSequenceString( evt.data );
@@ -873,7 +1116,7 @@
// Filter data to get rid of Filling Char Sequence. Filter on #toDataFormat
// instead of #getData because once removed, FCSeq may leave an empty element,
- // which should be pruned by the dataProcessor (#13816).
+ // which should be pruned by the dataProcessor (http://dev.ckeditor.com/ticket/13816).
// Note: Used low priority to filter when dataProcessor works on strings,
// not pseudoâDOM.
editor.on( 'toDataFormat', function( evt ) {
@@ -1039,9 +1282,6 @@
*/
CKEDITOR.SELECTION_ELEMENT = 3;
- var isMSSelection = typeof window.getSelection != 'function',
- nextRev = 1;
-
/**
* Manipulates the selection within a DOM element. If the current browser selection
* spans outside of the element, an empty selection object is returned.
@@ -1121,7 +1361,7 @@
// Selection out of concerned range, empty the selection.
// TODO check whether this condition cannot be reverted to its old
- // form (commented out) after we closed #10438.
+ // form (commented out) after we closed http://dev.ckeditor.com/ticket/10438.
//if ( !( rangeParent && ( root.equals( rangeParent ) || root.contains( rangeParent ) ) ) ) {
if ( !(
rangeParent &&
@@ -1142,10 +1382,6 @@
var styleObjectElements = { img: 1, hr: 1, li: 1, table: 1, tr: 1, td: 1, th: 1, embed: 1, object: 1, ol: 1, ul: 1,
a: 1, input: 1, form: 1, select: 1, textarea: 1, button: 1, fieldset: 1, thead: 1, tfoot: 1 };
- // #13816
- var fillingCharSequence = CKEDITOR.tools.repeat( '\u200b', 7 ),
- fillingCharSequenceRegExp = new RegExp( fillingCharSequence + '( )?', 'g' );
-
CKEDITOR.tools.extend( CKEDITOR.dom.selection, {
_removeFillingCharSequenceString: removeFillingCharSequenceString,
_createFillingCharSequenceNode: createFillingCharSequenceNode,
@@ -1167,7 +1403,7 @@
*
* var selection = editor.getSelection().getNative();
*
- * @returns {Object} The native browser selection object.
+ * @returns {Object} The native browser selection object or null if this is a fake selection.
*/
getNative: function() {
if ( this._.cache.nativeSel !== undefined )
@@ -1259,7 +1495,7 @@
* alert( ranges.length );
*
* @method
- * @param {Boolean} [onlyEditables] If set to `true`, this function retrives editable ranges only.
+ * @param {Boolean} [onlyEditables] If set to `true`, this function retrieves editable ranges only.
* @returns {Array} Range instances that represent the current selection.
*/
getRanges: ( function() {
@@ -1290,7 +1526,7 @@
index = -1,
position, distance, container;
- // Binary search over all element childs to test the range to see whether
+ // Binary search over all element children to test the range to see whether
// range is right on the boundary of one element.
while ( startIndex <= endIndex ) {
index = Math.floor( ( startIndex + endIndex ) / 2 );
@@ -1306,8 +1542,8 @@
return { container: parent, offset: getNodeIndex( child ) };
}
- // All childs are text nodes,
- // or to the right hand of test range are all text nodes. (#6992)
+ // All children are text nodes,
+ // or to the right hand of test range are all text nodes. (http://dev.ckeditor.com/ticket/6992)
if ( index == -1 || index == siblings.length - 1 && position < 0 ) {
// Adapt test range to embrace the entire parent contents.
testRange.moveToElementText( parent );
@@ -1315,7 +1551,7 @@
// IE report line break as CRLF with range.text but
// only LF with textnode.nodeValue, normalize them to avoid
- // breaking character counting logic below. (#3949)
+ // breaking character counting logic below. (http://dev.ckeditor.com/ticket/3949)
distance = testRange.text.replace( /(\r\n|\r)/g, '\n' ).length;
siblings = parent.childNodes;
@@ -1351,7 +1587,7 @@
// IE report line break as CRLF with range.text but
// only LF with textnode.nodeValue, normalize them to avoid
- // breaking character counting logic below. (#3949)
+ // breaking character counting logic below. (http://dev.ckeditor.com/ticket/3949)
distance = testRange.text.replace( /(\r\n|\r)/g, '\n' ).length;
// Actual range anchor right beside test range at the inner boundary of text node.
@@ -1368,7 +1604,7 @@
}
child = sibling;
}
- // Measurement in IE could be somtimes wrong because of