From 01c2ca3612256f43ab3e53c3542a05845d92d75f Mon Sep 17 00:00:00 2001 From: MatmaRex Date: Sun, 9 Dec 2012 21:08:49 +0100 Subject: [PATCH] (bug 41342) jquery.suggestions: Call cancel before fetching. This caused race conditions in the calling code, if it used AJAX and they completed in different order than they were started. For example in mediawiki.searchSuggest, when one slowly types "wikipedia", 9 requests get sent (suggestions for "w", "wi", "wik", etc.), but they might not necessarily arrive in the same order, especially on slow (e.g. mobile) connections. Then you get the race condition effect - suggestions for "wikipedia" flash briefly and then are replaced by suggestions for "wik", even though the bolding is correct. This commit fixes the issue by using a function that was already present, that calls the callback as well as clearing the internal timeout, which for some reason wasn't used in this code path. Change-Id: I880a61e5e45a64bea6d679ed160c4be3da085dfa --- RELEASE-NOTES-1.21 | 2 ++ resources/jquery/jquery.suggestions.js | 14 +++++++------- 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/RELEASE-NOTES-1.21 b/RELEASE-NOTES-1.21 index 78ef1dfddf..f2cfbb7315 100644 --- a/RELEASE-NOTES-1.21 +++ b/RELEASE-NOTES-1.21 @@ -112,6 +112,8 @@ production.

,

or
to only

s, with a

hidden heading above them. If you are styling or scripting the headings in a custom way, this change will require updates to your site's CSS or JS. +* (bug 41342) jquery.suggestions should cancel any active (async) fetches + before it triggers another fetch. === API changes in 1.21 === * prop=revisions can now report the contentmodel and contentformat. diff --git a/resources/jquery/jquery.suggestions.js b/resources/jquery/jquery.suggestions.js index edc18a7940..ac579db1d6 100644 --- a/resources/jquery/jquery.suggestions.js +++ b/resources/jquery/jquery.suggestions.js @@ -49,8 +49,8 @@ $.suggestions = { /** - * Cancel any delayed updateSuggestions() call and inform the user so - * they can cancel their result fetching if they use AJAX or something + * Cancel any delayed maybeFetch() call and callback the context so + * they can cancel any async fetching if they use AJAX or something. */ cancel: function ( context ) { if ( context.data.timerID !== null ) { @@ -93,12 +93,12 @@ $.suggestions = { } } - // Cancel previous call - if ( context.data.timerID !== null ) { - clearTimeout( context.data.timerID ); - } + // Cancels any delayed maybeFetch call, and invokes context.config.cancel. + $.suggestions.cancel( context ); + if ( delayed ) { - // Start a new asynchronous call + // To avoid many started/aborted requests while typing, we're gonna take a short + // break before trying to fetch data. context.data.timerID = setTimeout( maybeFetch, context.config.delay ); } else { maybeFetch(); -- 2.20.1