X-Git-Url: https://jasonwoof.com/gitweb/?a=blobdiff_plain;f=_source%2Fplugins%2Fselection%2Fplugin.js;h=3d707fc99ed284ad564f0e5475ec6480595fb59a;hb=055b6b0792ce7dc53d47af606b367c04b927c2ab;hp=747d3f588ed1972fd58fa4ea6969277a45035766;hpb=8761695d9b70afe75905deaac88f78c1f8aeb32d;p=ckeditor.git diff --git a/_source/plugins/selection/plugin.js b/_source/plugins/selection/plugin.js index 747d3f5..3d707fc 100644 --- a/_source/plugins/selection/plugin.js +++ b/_source/plugins/selection/plugin.js @@ -1,5 +1,5 @@ /* -Copyright (c) 2003-2009, CKSource - Frederico Knabben. All rights reserved. +Copyright (c) 2003-2010, CKSource - Frederico Knabben. All rights reserved. For licensing, see LICENSE.html or http://ckeditor.com/license */ @@ -17,7 +17,7 @@ For licensing, see LICENSE.html or http://ckeditor.com/license // In IE, the "selectionchange" event may still get thrown when // releasing the WYSIWYG mode, so we need to check it first. var sel = this.getSelection(); - if ( !sel ) + if ( !sel || !sel.document.getWindow().$ ) return; var firstElement = sel.getStartElement(); @@ -72,6 +72,7 @@ For licensing, see LICENSE.html or http://ckeditor.com/license var selectAllCmd = { + modes : { wysiwyg : 1, source : 1 }, exec : function( editor ) { switch ( editor.mode ) @@ -80,7 +81,18 @@ For licensing, see LICENSE.html or http://ckeditor.com/license editor.document.$.execCommand( 'SelectAll', false, null ); break; case 'source' : - // TODO + // Select the contents of the textarea + var textarea = editor.textarea.$ ; + if ( CKEDITOR.env.ie ) + { + textarea.createTextRange().execCommand( 'SelectAll' ) ; + } + else + { + textarea.selectionStart = 0 ; + textarea.selectionEnd = textarea.value.length ; + } + textarea.focus() ; } }, canUndo : false @@ -92,7 +104,9 @@ For licensing, see LICENSE.html or http://ckeditor.com/license { editor.on( 'contentDom', function() { - var doc = editor.document; + var doc = editor.document, + body = doc.getBody(), + html = doc.getDocumentElement(); if ( CKEDITOR.env.ie ) { @@ -102,30 +116,39 @@ For licensing, see LICENSE.html or http://ckeditor.com/license // than firing the selection change event. var savedRange, - saveEnabled; + saveEnabled, + restoreEnabled = 1; // "onfocusin" is fired before "onfocus". It makes it // possible to restore the selection before click // events get executed. - doc.on( 'focusin', function() + body.on( 'focusin', function( evt ) { + // If there are elements with layout they fire this event but + // it must be ignored to allow edit its contents #4682 + if ( evt.data.$.srcElement.nodeName != 'BODY' ) + return; + // If we have saved a range, restore it at this // point. if ( savedRange ) { - // Well not break because of this. - try + if ( restoreEnabled ) { - savedRange.select(); + // Well not break because of this. + try + { + savedRange.select(); + } + catch (e) + {} } - catch (e) - {} savedRange = null; } }); - editor.window.on( 'focus', function() + body.on( 'focus', function() { // Enable selections to be saved. saveEnabled = true; @@ -133,25 +156,65 @@ For licensing, see LICENSE.html or http://ckeditor.com/license saveSelection(); }); - // Check document selection before 'blur' fired, this - // will prevent us from breaking text selection somewhere - // else on the host page.(#3909) - editor.document.on( 'beforedeactivate', function() + body.on( 'beforedeactivate', function( evt ) { + // Ignore this event if it's caused by focus switch between + // internal editable control type elements, e.g. layouted paragraph. (#4682) + if ( evt.data.$.toElement ) + return; + // Disable selections from being saved. saveEnabled = false; + restoreEnabled = 1; + }); - // IE may leave the selection still inside the - // document. Let's force it to be removed. - // TODO: The following has effect for - // collapsed selections. - editor.document.$.execCommand( 'Unselect' ); + // IE before version 8 will leave cursor blinking inside the document after + // editor blurred unless we clean up the selection. (#4716) + if ( CKEDITOR.env.ie && CKEDITOR.env.version < 8 ) + { + editor.on( 'blur', function( evt ) + { + editor.document && editor.document.$.selection.empty(); }); + } + + // Listening on document element ensures that + // scrollbar is included. (#5280) + html.on( 'mousedown', function () + { + // Lock restore selection now, as we have + // a followed 'click' event which introduce + // new selection. (#5735) + restoreEnabled = 0; + }); + + html.on( 'mouseup', function () + { + restoreEnabled = 1; + }); + + // In IE6/7 the blinking cursor appears, but contents are + // not editable. (#5634) + if ( CKEDITOR.env.ie && ( CKEDITOR.env.ie7Compat || CKEDITOR.env.version < 8 || CKEDITOR.env.quirks ) ) + { + // The 'click' event is not fired when clicking the + // scrollbars, so we can use it to check whether + // the empty space following has been clicked. + html.on( 'click', function( evt ) + { + if ( evt.data.getTarget().getName() == 'html' ) + editor.getSelection().getRanges()[ 0 ].select(); + }); + } // IE fires the "selectionchange" event when clicking // inside a selection. We don't want to capture that. - doc.on( 'mousedown', disableSave ); - doc.on( 'mouseup', + body.on( 'mousedown', function () + { + disableSave(); + }); + + body.on( 'mouseup', function() { saveEnabled = true; @@ -162,8 +225,8 @@ For licensing, see LICENSE.html or http://ckeditor.com/license 0 ); }); - doc.on( 'keydown', disableSave ); - doc.on( 'keyup', + body.on( 'keydown', disableSave ); + body.on( 'keyup', function() { saveEnabled = true; @@ -185,7 +248,8 @@ For licensing, see LICENSE.html or http://ckeditor.com/license if ( saveEnabled ) { var doc = editor.document, - sel = doc && doc.$.selection; + sel = editor.getSelection(), + nativeSel = sel && sel.getNative(); // There is a very specific case, when clicking // inside a text selection. In that case, the @@ -195,7 +259,7 @@ For licensing, see LICENSE.html or http://ckeditor.com/license // range at the very start of the document. In // such situation we have to test the range, to // be sure it's valid. - if ( testIt && sel && sel.type == 'None' ) + if ( testIt && nativeSel && nativeSel.type == 'None' ) { // The "InsertImage" command can be used to // test whether the selection is good or not. @@ -208,7 +272,18 @@ For licensing, see LICENSE.html or http://ckeditor.com/license } } - savedRange = sel && sel.createRange(); + // Avoid saving selection from within text input. (#5747) + var parentTag; + if ( nativeSel && nativeSel.type && nativeSel.type != 'Control' + && ( parentTag = nativeSel.createRange() ) + && ( parentTag = parentTag.parentElement() ) + && ( parentTag = parentTag.nodeName ) + && parentTag.toLowerCase() in { input: 1, textarea : 1 } ) + { + return; + } + + savedRange = nativeSel && sel.getRanges()[ 0 ]; checkSelectionChangeTimeout.call( editor ); } @@ -333,7 +408,7 @@ For licensing, see LICENSE.html or http://ckeditor.com/license var styleObjectElements = { - img:1,hr:1,li:1,table:1,tr:1,td:1,embed:1,object:1,ol:1,ul:1, + 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, th:1, thead:1, tfoot:1 }; @@ -441,6 +516,15 @@ For licensing, see LICENSE.html or http://ckeditor.com/license return ( cache.type = type ); }, + /** + * Retrieve the {@link CKEDITOR.dom.range} instances that represent the current selection. + * Note: Some browsers returns multiple ranges even on a sequent selection, e.g. Firefox returns + * one range for each table cell when one or more table row is selected. + * @return {Array} + * @example + * var ranges = selection.getRanges(); + * alert(ranges.length); + */ getRanges : CKEDITOR.env.ie ? ( function() @@ -467,17 +551,21 @@ For licensing, see LICENSE.html or http://ckeditor.com/license testRange = range.duplicate(); testRange.moveToElementText( child ); - testRange.collapse(); - var comparison = testRange.compareEndPoints( 'StartToStart', range ); + var comparisonStart = testRange.compareEndPoints( 'StartToStart', range ), + comparisonEnd = testRange.compareEndPoints( 'EndToStart', range ); + + testRange.collapse(); - if ( comparison > 0 ) + if ( comparisonStart > 0 ) break; - else if ( comparison === 0 ) - return { - container : parent, - offset : i - }; + // When selection stay at the side of certain self-closing elements, e.g. BR, + // our comparison will never shows an equality. (#4824) + else if ( !comparisonStart + || comparisonEnd == 1 && comparisonStart == -1 ) + return { container : parent, offset : i }; + else if ( !comparisonEnd ) + return { container : parent, offset : i + 1 }; testRange = null; } @@ -496,8 +584,17 @@ For licensing, see LICENSE.html or http://ckeditor.com/license // breaking character counting logic below. (#3949) var distance = testRange.text.replace( /(\r\n|\r)/g, '\n' ).length; - while ( distance > 0 ) - distance -= siblings[ --i ].nodeValue.length; + try + { + while ( distance > 0 ) + distance -= siblings[ --i ].nodeValue.length; + } + // Measurement in IE could be somtimes wrong because of