From e4a194ce42b8ea1e5440f99d1d8d26f55526ff6c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Scott=20Gonz=C3=A1lez?= Date: Tue, 28 May 2013 11:04:29 -0400 Subject: [PATCH] Autocomplete: Scope race condition handling to the instance. Fixes #9334 - Autocomplete: Multiple instances should be able to start asynchronous requests simultaneously. (cherry picked from commit 9e00e00f3b54770faa0291d6ee6fc1dcbad028cb) --- tests/unit/autocomplete/autocomplete_core.js | 28 +++++++++++++++++++ ui/jquery.ui.autocomplete.js | 29 +++++++++----------- 2 files changed, 41 insertions(+), 16 deletions(-) diff --git a/tests/unit/autocomplete/autocomplete_core.js b/tests/unit/autocomplete/autocomplete_core.js index b6dd139e0..679955d19 100644 --- a/tests/unit/autocomplete/autocomplete_core.js +++ b/tests/unit/autocomplete/autocomplete_core.js @@ -192,6 +192,34 @@ asyncTest( "handle race condition", function() { } }); +asyncTest( "simultaneous searches (#9334)", function() { + expect( 2 ); + var element = $( "#autocomplete" ).autocomplete({ + source: function( request, response ) { + setTimeout(function() { + response([ request.term ]); + }); + }, + response: function() { + ok( true, "response from first instance" ); + } + }), + element2 = $( "#autocomplete-textarea" ).autocomplete({ + source: function( request, response ) { + setTimeout(function() { + response([ request.term ]); + }); + }, + response: function() { + ok( true, "response from second instance" ); + start(); + } + }); + + element.autocomplete( "search", "test" ); + element2.autocomplete( "search", "test" ); +}); + test( "ARIA", function() { expect( 7 ); var element = $( "#autocomplete" ).autocomplete({ diff --git a/ui/jquery.ui.autocomplete.js b/ui/jquery.ui.autocomplete.js index 5dea71287..1f318078f 100644 --- a/ui/jquery.ui.autocomplete.js +++ b/ui/jquery.ui.autocomplete.js @@ -41,6 +41,7 @@ $.widget( "ui.autocomplete", { select: null }, + requestIndex: 0, pending: 0, _create: function() { @@ -415,24 +416,20 @@ $.widget( "ui.autocomplete", { this.source( { term: value }, this._response() ); }, - _response: (function() { - var requestIndex = 0; + _response: function() { + var index = ++this.requestIndex; - return function() { - var index = ++requestIndex; + return $.proxy(function( content ) { + if ( index === this.requestIndex ) { + this.__response( content ); + } - return $.proxy(function( content ) { - if ( index === requestIndex ) { - this.__response( content ); - } - - this.pending--; - if ( !this.pending ) { - this.element.removeClass( "ui-autocomplete-loading" ); - } - }, this ); - }; - })(), + this.pending--; + if ( !this.pending ) { + this.element.removeClass( "ui-autocomplete-loading" ); + } + }, this ); + }, __response: function( content ) { if ( content ) {