* These plugins provide extra functionality for interaction with textareas.
*/
( function( $ ) {
+
+if (document.selection && document.selection.createRange) {
+ // On IE, patch the focus() method to restore the windows' scroll position
+ // (bug 32241)
+ $.fn.extend({
+ focus : (function ( _focus ) {
+ return function () {
+ if ( arguments.length == 0 ) {
+ var $w = $( window );
+ var state = {top: $w.scrollTop(), left: $w.scrollLeft()};
+ var result = _focus.apply( this, arguments );
+ window.scrollTo( state.top, state.left );
+ return result;
+ }
+ return _focus.apply( this, arguments );
+ };
+ })( $.fn.focus )
+ });
+}
+
$.fn.textSelection = function( command, options ) {
/**
}
}
+/**
+ * Helper function for IE for activating the textarea. Called only in the
+ * IE-specific code paths below; makes use of IE-specific non-standard
+ * function setActive() if possible to avoid screen flicker.
+ */
+function activateElementOnIE( element ) {
+ if ( element.setActive ) {
+ element.setActive(); // bug 32241: doesn't scroll
+ } else {
+ $( element ).focus(); // may scroll (but we patched it above)
+ }
+}
+
var fn = {
/**
* Get the contents of the textarea
if ( $(e).is( ':hidden' ) ) {
// Do nothing
} else if ( document.selection && document.selection.createRange ) {
- e.focus();
+ activateElementOnIE( e );
var range = document.selection.createRange();
retval = range.text;
} else if ( e.selectionStart || e.selectionStart == '0' ) {
var isSample = false;
if ( this.style.display == 'none' ) {
// Do nothing
+ } else if ( document.selection && document.selection.createRange ) {
+ // IE
+
+ // Note that IE9 will trigger the next section unless we check this first.
+ // See bug 35201.
+
+ activateElementOnIE( this );
+ if ( context ) {
+ context.fn.restoreCursorAndScrollTop();
+ }
+ if ( options.selectionStart !== undefined ) {
+ $(this).textSelection( 'setSelection', { 'start': options.selectionStart, 'end': options.selectionEnd } );
+ }
+
+ var selText = $(this).textSelection( 'getSelection' );
+ var scrollTop = this.scrollTop;
+ var range = document.selection.createRange();
+
+ checkSelectedText();
+ var insertText = pre + selText + post;
+ if ( options.splitlines ) {
+ insertText = doSplitLines( selText, pre, post );
+ }
+ if ( options.ownline && range.moveStart ) {
+ var range2 = document.selection.createRange();
+ range2.collapse();
+ range2.moveStart( 'character', -1 );
+ // FIXME: Which check is correct?
+ if ( range2.text != "\r" && range2.text != "\n" && range2.text != "" ) {
+ insertText = "\n" + insertText;
+ pre += "\n";
+ }
+ var range3 = document.selection.createRange();
+ range3.collapse( false );
+ range3.moveEnd( 'character', 1 );
+ if ( range3.text != "\r" && range3.text != "\n" && range3.text != "" ) {
+ insertText += "\n";
+ post += "\n";
+ }
+ }
+
+ range.text = insertText;
+ if ( isSample && options.selectPeri && range.moveStart ) {
+ range.moveStart( 'character', - post.length - selText.length );
+ range.moveEnd( 'character', - post.length );
+ }
+ range.select();
+ // Restore the scroll position
+ this.scrollTop = scrollTop;
} else if ( this.selectionStart || this.selectionStart == '0' ) {
// Mozilla/Opera
+
$(this).focus();
if ( options.selectionStart !== undefined ) {
$(this).textSelection( 'setSelection', { 'start': options.selectionStart, 'end': options.selectionEnd } );
this.selectionStart = startPos + insertText.length;
this.selectionEnd = this.selectionStart;
}
- } else if ( document.selection && document.selection.createRange ) {
- // IE
- $(this).focus();
- if ( context ) {
- context.fn.restoreCursorAndScrollTop();
- }
- if ( options.selectionStart !== undefined ) {
- $(this).textSelection( 'setSelection', { 'start': options.selectionStart, 'end': options.selectionEnd } );
- }
-
- var selText = $(this).textSelection( 'getSelection' );
- var scrollTop = this.scrollTop;
- var range = document.selection.createRange();
-
- checkSelectedText();
- var insertText = pre + selText + post;
- if ( options.splitlines ) {
- insertText = doSplitLines( selText, pre, post );
- }
- if ( options.ownline && range.moveStart ) {
- var range2 = document.selection.createRange();
- range2.collapse();
- range2.moveStart( 'character', -1 );
- // FIXME: Which check is correct?
- if ( range2.text != "\r" && range2.text != "\n" && range2.text != "" ) {
- insertText = "\n" + insertText;
- pre += "\n";
- }
- var range3 = document.selection.createRange();
- range3.collapse( false );
- range3.moveEnd( 'character', 1 );
- if ( range3.text != "\r" && range3.text != "\n" && range3.text != "" ) {
- insertText += "\n";
- post += "\n";
- }
- }
-
- range.text = insertText;
- if ( isSample && options.selectPeri && range.moveStart ) {
- range.moveStart( 'character', - post.length - selText.length );
- range.moveEnd( 'character', - post.length );
- }
- range.select();
- // Restore the scroll position
- this.scrollTop = scrollTop;
}
$(this).trigger( 'encapsulateSelection', [ options.pre, options.peri, options.post, options.ownline,
options.replace, options.spitlines ] );
* Get the position (in resolution of bytes not nessecarily characters)
* in a textarea
*
+ * Will focus the textarea in some browsers (IE/Opera)
+ *
* @fixme document the options parameters
*/
getCaretPosition: function( options ) {
function getCaret( e ) {
var caretPos = 0, endPos = 0;
- if ( $.browser.msie ) {
+ if ( document.selection && document.selection.createRange ) {
+ // IE doesn't properly report non-selected caret position through
+ // the selection ranges when textarea isn't focused. This can
+ // lead to saving a bogus empty selection, which then screws up
+ // whatever we do later (bug 31847).
+ activateElementOnIE( e );
+
// IE Support
var preFinished = false;
var periFinished = false;