diff options
Diffstat (limited to 'ui/jquery.ui.autocomplete.js')
-rw-r--r-- | ui/jquery.ui.autocomplete.js | 55 |
1 files changed, 37 insertions, 18 deletions
diff --git a/ui/jquery.ui.autocomplete.js b/ui/jquery.ui.autocomplete.js index 6b06cfe2c..9871b52d7 100644 --- a/ui/jquery.ui.autocomplete.js +++ b/ui/jquery.ui.autocomplete.js @@ -47,8 +47,15 @@ $.widget( "ui.autocomplete", { _create: function() { var self = this, - doc = this.element[ 0 ].ownerDocument, + // Some browsers only repeat keydown events, not keypress events, + // so we use the suppressKeyPress flag to determine if we've already + // handled the keydown event. #7269 + // Unfortunately the code for & in keypress is the same as the up arrow, + // so we use the suppressKeyPressRepeat flag to avoid handling keypress + // events when we know the keydown event was used to modify the + // search term. #7799 suppressKeyPress, + suppressKeyPressRepeat, suppressInput; this.valueMethod = this.element[ this.element.is( "input,textarea" ) ? "val" : "text" ]; @@ -66,11 +73,13 @@ $.widget( "ui.autocomplete", { if ( self.options.disabled || self.element.prop( "readOnly" ) ) { suppressKeyPress = true; suppressInput = true; + suppressKeyPressRepeat = true; return; } suppressKeyPress = false; suppressInput = false; + suppressKeyPressRepeat = false; var keyCode = $.ui.keyCode; switch( event.keyCode ) { case keyCode.PAGE_UP: @@ -110,10 +119,13 @@ $.widget( "ui.autocomplete", { self.menu.select( event ); break; case keyCode.ESCAPE: - self._value( self.term ); - self.close( event ); + if ( self.menu.element.is(":visible") ) { + self._value( self.term ); + self.close( event ); + } break; default: + suppressKeyPressRepeat = true; // search timeout should be triggered before the input value is changed self._searchTimeout( event ); break; @@ -125,6 +137,9 @@ $.widget( "ui.autocomplete", { event.preventDefault(); return; } + if ( suppressKeyPressRepeat ) { + return; + } // replicate some key handlers to allow them to repeat in Firefox and Opera var keyCode = $.ui.keyCode; @@ -181,7 +196,7 @@ $.widget( "ui.autocomplete", { }; this.menu = $( "<ul></ul>" ) .addClass( "ui-autocomplete" ) - .appendTo( $( this.options.appendTo || "body", doc )[0] ) + .appendTo( this.document.find( this.options.appendTo || "body" )[0] ) // prevent the close-on-blur in case of a "slow" click on the menu (long mousedown) .mousedown(function( event ) { // clicking on the scrollbar causes focus to shift to the body @@ -191,7 +206,7 @@ $.widget( "ui.autocomplete", { var menuElement = self.menu.element[ 0 ]; if ( !$( event.target ).closest( ".ui-menu-item" ).length ) { setTimeout(function() { - $( document ).one( 'mousedown', function( event ) { + self.document.one( 'mousedown', function( event ) { if ( event.target !== self.element[ 0 ] && event.target !== menuElement && !$.contains( menuElement, event.target ) ) { @@ -223,7 +238,7 @@ $.widget( "ui.autocomplete", { previous = self.previous; // only trigger when focus was lost (click on menu) - if ( self.element[0] !== doc.activeElement ) { + if ( self.element[0] !== self.document[0].activeElement ) { self.element.focus(); self.previous = previous; // #6109 - IE triggers two focus events and the second @@ -244,22 +259,24 @@ $.widget( "ui.autocomplete", { self.close( event ); self.selectedItem = item; - }, - blur: function( event, ui ) { - // don't set the value of the text field if it's already correct - // this prevents moving the cursor unnecessarily - if ( self.menu.element.is(":visible") && - ( self._value() !== self.term ) ) { - self._value( self.term ); - } } }) .zIndex( this.element.zIndex() + 1 ) .hide() .data( "menu" ); + if ( $.fn.bgiframe ) { this.menu.element.bgiframe(); } + + // turning off autocomplete prevents the browser from remembering the + // value when navigating through history, so we re-enable autocomplete + // if the page is unloaded before the widget is destroyed. #7790 + this._bind( this.window, { + beforeunload: function() { + this.element.removeAttr( "autocomplete" ); + } + }); }, _destroy: function() { @@ -274,12 +291,12 @@ $.widget( "ui.autocomplete", { }, _setOption: function( key, value ) { - this._super( "_setOption", key, value ); + this._super( key, value ); if ( key === "source" ) { this._initSource(); } if ( key === "appendTo" ) { - this.menu.element.appendTo( $( value || "body", this.element[0].ownerDocument )[0] ) + this.menu.element.appendTo( this.document.find( value || "body" )[0] ); } if ( key === "disabled" && value && this.xhr ) { this.xhr.abort(); @@ -328,7 +345,7 @@ $.widget( "ui.autocomplete", { clearTimeout( self.searching ); self.searching = setTimeout(function() { // only search if the value has changed - if ( self.term != self._value() ) { + if ( self.term !== self._value() ) { self.selectedItem = null; self.search( null, event ); } @@ -435,7 +452,9 @@ $.widget( "ui.autocomplete", { _resizeMenu: function() { var ul = this.menu.element; ul.outerWidth( Math.max( - ul.width( "" ).outerWidth(), + // Firefox wraps long text (possibly a rounding bug) + // so we add 1px to avoid the wrapping (#7513) + ul.width( "" ).outerWidth() + 1, this.element.outerWidth() ) ); }, |