{\r
editor.on( 'contentDom', function()\r
{\r
- var doc = editor.document;\r
+ var doc = editor.document,\r
+ body = doc.getBody();\r
\r
if ( CKEDITOR.env.ie )\r
{\r
// "onfocusin" is fired before "onfocus". It makes it\r
// possible to restore the selection before click\r
// events get executed.\r
- doc.on( 'focusin', function()\r
+ body.on( 'focusin', function()\r
{\r
// If we have saved a range, restore it at this\r
// point.\r
saveSelection();\r
});\r
\r
- // Check document selection before 'blur' fired, this\r
- // will prevent us from breaking text selection somewhere\r
- // else on the host page.(#3909)\r
- editor.document.on( 'beforedeactivate', function()\r
+ body.on( 'beforedeactivate', function()\r
{\r
// Disable selections from being saved.\r
saveEnabled = false;\r
-\r
- // IE may leave the selection still inside the\r
- // document. Let's force it to be removed.\r
- // TODO: The following has effect for\r
- // collapsed selections.\r
- editor.document.$.execCommand( 'Unselect' );\r
});\r
\r
// IE fires the "selectionchange" event when clicking\r
// inside a selection. We don't want to capture that.\r
- doc.on( 'mousedown', disableSave );\r
- doc.on( 'mouseup',\r
- function()\r
+ body.on( 'mousedown', disableSave );\r
+ body.on( 'mouseup',\r
+ function( evt )\r
{\r
+ // IE context-menu event in table cells collapse\r
+ // whatever selection is, avoiding saving this\r
+ // 'wrong' snapshot.(#3001)\r
+ evt = evt.data;\r
+ if ( evt.$.button == 2 && evt.getTarget().hasAscendant( 'table' ) )\r
+ return;\r
+\r
saveEnabled = true;\r
setTimeout( function()\r
{\r
0 );\r
});\r
\r
- doc.on( 'keydown', disableSave );\r
- doc.on( 'keyup',\r
+ body.on( 'keydown', disableSave );\r
+ body.on( 'keyup',\r
function()\r
{\r
saveEnabled = true;\r
\r
var styleObjectElements =\r
{\r
- img:1,hr:1,li:1,table:1,tr:1,td:1,embed:1,object:1,ol:1,ul:1,\r
+ img:1,hr:1,li:1,table:1,tr:1,td:1,th:1,embed:1,object:1,ol:1,ul:1,\r
a:1, input:1, form:1, select:1, textarea:1, button:1, fieldset:1, th:1, thead:1, tfoot:1\r
};\r
\r
{\r
var startContainer = range.startContainer,\r
startOffset = range.startOffset;\r
+ // Limit the fix only to non-block elements.(#3950)\r
if ( startOffset == ( startContainer.getChildCount ?\r
- startContainer.getChildCount() : startContainer.getLength() ) )\r
+ startContainer.getChildCount() : startContainer.getLength() )\r
+ && !startContainer.isBlockBoundary() )\r
range.setStartAfter( startContainer );\r
else break;\r
}\r
}\r
this.selectRanges( ranges );\r
return this;\r
+ },\r
+\r
+ // Moving scroll bar to the current selection's start position.\r
+ scrollIntoView : function()\r
+ {\r
+ // If we have split the block, adds a temporary span at the\r
+ // range position and scroll relatively to it.\r
+ var start = this.getStartElement();\r
+ start.scrollIntoView();\r
}\r
};\r
})();\r
+( function()\r
+{\r
+var notWhitespaces = CKEDITOR.dom.walker.whitespaces( true );\r
+var fillerTextRegex = /\ufeff|\u00a0/;\r
\r
CKEDITOR.dom.range.prototype.select =\r
CKEDITOR.env.ie ?\r
// will expand and that the cursor will be blinking on the right place.\r
// Actually, we are using this flag just to avoid using this hack in all\r
// situations, but just on those needed.\r
- isStartMarkerAlone = forceExpand || !startNode.hasPrevious() || ( startNode.getPrevious().is && startNode.getPrevious().is( 'br' ) );\r
+ var next = startNode.getNext( notWhitespaces );\r
+ isStartMarkerAlone = ( !( next && next.getText && next.getText().match( fillerTextRegex ) ) // already a filler there?\r
+ && ( forceExpand || !startNode.hasPrevious() || ( startNode.getPrevious().is && startNode.getPrevious().is( 'br' ) ) ) );\r
\r
// Append a temporary <span></span> before the selection.\r
// This is needed to avoid IE destroying selections inside empty\r
selection.removeAllRanges();\r
selection.addRange( nativeRange );\r
};\r
+} )();\r