X-Git-Url: https://jasonwoof.com/gitweb/?p=ckeditor.git;a=blobdiff_plain;f=_source%2Fplugins%2Fselection%2Fplugin.js;h=4c77c43fe4825d50bae3cb1eb927a1686cedb485;hp=3a0a181d2954b6a2d96b8c64f326da8480b884fd;hb=fb481ba0a7d298e3e7b9034fcb9f2afdc6e8e796;hpb=6e682412d5cc0dfaedb376482e585bf2989c6863 diff --git a/_source/plugins/selection/plugin.js b/_source/plugins/selection/plugin.js index 3a0a181..4c77c43 100644 --- a/_source/plugins/selection/plugin.js +++ b/_source/plugins/selection/plugin.js @@ -72,29 +72,32 @@ For licensing, see LICENSE.html or http://ckeditor.com/license function rangeRequiresFix( range ) { - function isInlineCt( node ) + function isTextCt( node, isAtEnd ) { - return node && node.type == CKEDITOR.NODE_ELEMENT - && node.getName() in CKEDITOR.dtd.$removeEmpty; - } + if ( !node || node.type == CKEDITOR.NODE_TEXT ) + return false; - function singletonBlock( node ) - { - var body = range.document.getBody(); - return !node.is( 'body' ) && body.getChildCount() == 1; + var testRng = range.clone(); + return testRng[ 'moveToElementEdit' + ( isAtEnd ? 'End' : 'Start' ) ]( node ); } - var start = range.startContainer, - offset = range.startOffset; + var ct = range.startContainer; + + var previous = range.getPreviousNode( isVisible, null, ct ), + next = range.getNextNode( isVisible, null, ct ); - if ( start.type == CKEDITOR.NODE_TEXT ) - return false; + // Any adjacent text container may absorb the cursor, e.g. + //

text^foo

+ //

foo^text

+ //
^

foo

+ if ( isTextCt( previous ) || isTextCt( next, 1 ) ) + return true; - // 1. Empty inline element. ^ - // 2. Adjoin to inline element.

text^

- // 3. The only empty block in document.

^

(#7222) - return !CKEDITOR.tools.trim( start.getHtml() ) ? isInlineCt( start ) || singletonBlock( start ) - : isInlineCt( start.getChild( offset - 1 ) ) || isInlineCt( start.getChild( offset ) ); + // Empty block/inline element is also affected. ^,

^

(#7222) + if ( !( previous || next ) && !( ct.type == CKEDITOR.NODE_ELEMENT && ct.isBlockBoundary() && ct.getBogus() ) ) + return true; + + return false; } var selectAllCmd = @@ -269,6 +272,7 @@ For licensing, see LICENSE.html or http://ckeditor.com/license editor.on( 'contentDom', function() { var doc = editor.document, + outerDoc = CKEDITOR.document, body = doc.getBody(), html = doc.getDocumentElement(); @@ -408,88 +412,117 @@ For licensing, see LICENSE.html or http://ckeditor.com/license saveSelection(); }); - // 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) - if ( ( CKEDITOR.env.ie7Compat || CKEDITOR.env.ie6Compat ) - && doc.$.compatMode != 'BackCompat' ) + // When content doc is in standards mode, IE doesn't produce text selection + // when click on the region outside of body, we emulate + // the correct behavior here. (#1659, #7932, # 9097) + if ( doc.$.compatMode != 'BackCompat' ) { - function moveRangeToPoint( range, x, y ) + if ( CKEDITOR.env.ie7Compat || CKEDITOR.env.ie6Compat ) { - // Error prune in IE7. (#9034, #9110) - try { range.moveToPoint( x, y ); } catch ( e ) {} - } + function moveRangeToPoint( range, x, y ) + { + // Error prune in IE7. (#9034, #9110) + try { range.moveToPoint( x, y ); } catch ( e ) {} + } - html.on( 'mousedown', function( evt ) - { - // Expand the text range along with mouse move. - function onHover( evt ) + html.on( 'mousedown', function( evt ) { - evt = evt.data.$; - if ( textRng ) + // Expand the text range along with mouse move. + function onHover( evt ) { - // Read the current cursor. - var rngEnd = body.$.createTextRange(); + evt = evt.data.$; + if ( textRng ) + { + // Read the current cursor. + var rngEnd = body.$.createTextRange(); + + moveRangeToPoint( rngEnd, evt.x, evt.y ); + + // Handle drag directions. + textRng.setEndPoint( + startRng.compareEndPoints( 'StartToStart', rngEnd ) < 0 ? + 'EndToEnd' : + 'StartToStart', + rngEnd ); + + // Update selection with new range. + textRng.select(); + } + } - moveRangeToPoint( rngEnd, evt.x, evt.y ); + function removeListeners() + { + outerDoc.removeListener( 'mouseup', onSelectEnd ); + html.removeListener( 'mouseup', onSelectEnd ); + } - // Handle drag directions. - textRng.setEndPoint( - textRng.compareEndPoints( 'StartToStart', rngEnd ) < 0 ? - 'EndToEnd' : - 'StartToStart', - rngEnd ); + function onSelectEnd() + { - // Update selection with new range. + html.removeListener( 'mousemove', onHover ); + removeListeners(); + + // Make it in effect on mouse up. (#9022) textRng.select(); } - } - - evt = evt.data.$; - // We're sure that the click happens at the region - // below body, but not on scrollbar. - if ( evt.y < html.$.clientHeight - && evt.y > body.$.offsetTop + body.$.clientHeight - && evt.x < html.$.clientWidth ) - { - // Start to build the text range. - var textRng = body.$.createTextRange(); - moveRangeToPoint( textRng, evt.x, evt.y ); + evt = evt.data; - html.on( 'mousemove', onHover ); + // We're sure that the click happens at the region + // outside body, but not on scrollbar. + if ( evt.getTarget().is( 'html' ) && + evt.$.x < html.$.clientWidth && + evt.$.y < html.$.clientHeight ) + { + // Start to build the text range. + var textRng = body.$.createTextRange(); + moveRangeToPoint( textRng, evt.$.x, evt.$.y ); + // Records the dragging start of the above text range. + var startRng = textRng.duplicate(); + + html.on( 'mousemove', onHover ); + outerDoc.on( 'mouseup', onSelectEnd ); + html.on( 'mouseup', onSelectEnd ); + } + }); + } - html.on( 'mouseup', function( evt ) + // It's much simpler for IE > 8, we just need to reselect the reported range. + if ( CKEDITOR.env.ie8 ) + { + html.on( 'mousedown', function( evt ) + { + if ( evt.data.getTarget().is( 'html' ) ) { - html.removeListener( 'mousemove', onHover ); - evt.removeListener(); + // Limit the text selection mouse move inside of editable. (#9715) + outerDoc.on( 'mouseup', onSelectEnd ); + html.on( 'mouseup', onSelectEnd ); + } - // Make it in effect on mouse up. (#9022) - textRng.select(); - } ); + }); + + function removeListeners() + { + outerDoc.removeListener( 'mouseup', onSelectEnd ); + html.removeListener( 'mouseup', onSelectEnd ); } - }); - } - // It's much simpler for IE8, we just need to reselect the reported range. - if ( CKEDITOR.env.ie8 ) - { - html.on( 'mouseup', function( evt ) - { - // The event is not fired when clicking on the scrollbars, - // so we can safely check the following to understand - // whether the empty space following has been clicked. - if ( evt.data.getTarget().getName() == 'html' ) + function onSelectEnd() { - var sel = CKEDITOR.document.$.selection, - 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.$ ) - range.select(); + removeListeners(); + + // The event is not fired when clicking on the scrollbars, + // so we can safely check the following to understand + // whether the empty space following has been clicked. + var sel = CKEDITOR.document.$.selection, + 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.$ ) + range.select(); } - } ); - } + } + } // IE is the only to provide the "selectionchange" // event. doc.on( 'selectionchange', saveSelection ); @@ -539,7 +572,8 @@ For licensing, see LICENSE.html or http://ckeditor.com/license return; } - savedRange = nativeSel && sel.getRanges()[ 0 ]; + // Not break because of this. (#9132) + try{ savedRange = nativeSel && sel.getRanges()[ 0 ]; } catch( er ) {} checkSelectionChangeTimeout.call( editor ); } @@ -558,6 +592,7 @@ For licensing, see LICENSE.html or http://ckeditor.com/license if ( CKEDITOR.env.webkit ) { + // Before keystroke is handled by editor, check to remove the filling char. doc.on( 'keydown', function( evt ) { var key = evt.data.getKey(); @@ -578,7 +613,7 @@ For licensing, see LICENSE.html or http://ckeditor.com/license removeFillingChar( editor.document ); } - }, null, null, 10 ); + }, null, null, -1 ); } }); @@ -1735,11 +1770,9 @@ For licensing, see LICENSE.html or http://ckeditor.com/license start.scrollIntoView(); } }; -})(); -( function() -{ var notWhitespaces = CKEDITOR.dom.walker.whitespaces( true ), + isVisible = CKEDITOR.dom.walker.invisible( 1 ), fillerTextRegex = /\ufeff|\u00a0/, nonCells = { table:1,tbody:1,tr:1 };