From 017c4f19fd91aa1f658131fae272617a14598a12 Mon Sep 17 00:00:00 2001 From: Thomas Date: Wed, 9 Oct 2013 12:02:52 +0200 Subject: Refactor multi-threaded autocomple contact searching to make it available for other purposes, too --- plugins/acl/acl.php | 4 +- program/js/app.js | 200 ++++++++++++++++++++++++++---------- program/steps/mail/autocomplete.inc | 4 +- 3 files changed, 147 insertions(+), 61 deletions(-) diff --git a/plugins/acl/acl.php b/plugins/acl/acl.php index a840bcd58..203340bdb 100644 --- a/plugins/acl/acl.php +++ b/plugins/acl/acl.php @@ -86,7 +86,7 @@ class acl extends rcube_plugin $this->load_config(); $search = rcube_utils::get_input_value('_search', rcube_utils::INPUT_GPC, true); - $sid = rcube_utils::get_input_value('_id', rcube_utils::INPUT_GPC); + $reqid = rcube_utils::get_input_value('_reqid', rcube_utils::INPUT_GPC); $users = array(); if ($this->init_ldap()) { @@ -115,7 +115,7 @@ class acl extends rcube_plugin sort($users, SORT_LOCALE_STRING); - $this->rc->output->command('ksearch_query_results', $users, $search, $sid); + $this->rc->output->command('ksearch_query_results', $users, $search, $reqid); $this->rc->output->send(); } diff --git a/program/js/app.js b/program/js/app.js index e89e85e52..654faa024 100644 --- a/program/js/app.js +++ b/program/js/app.js @@ -31,6 +31,7 @@ function rcube_webmail() this.onloads = []; this.messages = {}; this.group2expand = {}; + this.http_request_jobs = {}; // webmail client settings this.dblclick_time = 500; @@ -4338,7 +4339,7 @@ function rcube_webmail() p = inp_value.lastIndexOf(this.env.recipients_separator, cpos-1), q = inp_value.substring(p+1, cpos), min = this.env.autocomplete_min_length, - ac = this.ksearch_data; + data = this.ksearch_data; // trim query string q = $.trim(q); @@ -4365,34 +4366,26 @@ function rcube_webmail() return; // ...new search value contains old one and previous search was not finished or its result was empty - if (old_value && old_value.length && q.startsWith(old_value) && (!ac || ac.num <= 0) && this.env.contacts && !this.env.contacts.length) + if (old_value && old_value.length && q.startsWith(old_value) && (!data || data.num <= 0) && this.env.contacts && !this.env.contacts.length) return; - var i, lock, source, xhr, reqid = new Date().getTime(), - post_data = {_search: q, _id: reqid}, - threads = props && props.threads ? props.threads : 1, - sources = props && props.sources ? props.sources : [], - action = props && props.action ? props.action : 'mail/autocomplete'; - - this.ksearch_data = {id: reqid, sources: sources.slice(), action: action, - locks: [], requests: [], num: sources.length}; - - for (i=0; i 1 && source === undefined) - break; - - post_data._source = source ? source : ''; - lock = this.display_message(this.get_label('searching'), 'loading'); - xhr = this.http_post(action, post_data, lock); + var sources = props && props.sources ? props.sources : ['']; + var reqid = this.multi_thread_http_request({ + items: sources, + threads: props && props.threads ? props.threads : 1, + action: props && props.action ? props.action : 'mail/autocomplete', + postdata: { _search:q, _source:'%s' }, + lock: this.display_message(this.get_label('searching'), 'loading') + }); - this.ksearch_data.locks.push(lock); - this.ksearch_data.requests.push(xhr); - } + this.ksearch_data = { id:reqid, sources:sources.slice(), num:sources.length }; }; this.ksearch_query_results = function(results, search, reqid) { + // trigger multi-thread http response callback + this.multi_thread_http_response(results, reqid); + // search stopped in meantime? if (!this.ksearch_value) return; @@ -4404,7 +4397,6 @@ function rcube_webmail() // display search results var i, len, ul, li, text, init, value = this.ksearch_value, - data = this.ksearch_data, maxlen = this.env.autocomplete_max ? this.env.autocomplete_max : 15; // create results pane if not present @@ -4458,27 +4450,8 @@ function rcube_webmail() if (len) this.env.contacts = this.env.contacts.concat(results); - // run next parallel search - if (data.id == reqid) { - data.num--; - if (maxlen > 0 && data.sources.length) { - var lock, xhr, source = data.sources.shift(), post_data; - if (source) { - post_data = {_search: value, _id: reqid, _source: source}; - lock = this.display_message(this.get_label('searching'), 'loading'); - xhr = this.http_post(data.action, post_data, lock); - - this.ksearch_data.locks.push(lock); - this.ksearch_data.requests.push(xhr); - } - } - else if (!maxlen) { - if (!this.ksearch_msg) - this.ksearch_msg = this.display_message(this.get_label('autocompletemore')); - // abort pending searches - this.ksearch_abort(); - } - } + if (this.ksearch_data.id == reqid) + this.ksearch_data.num--; }; this.ksearch_click = function(node) @@ -4513,7 +4486,8 @@ function rcube_webmail() // Clears autocomplete data/requests this.ksearch_destroy = function() { - this.ksearch_abort(); + if (this.ksearch_data) + this.multi_thread_request_abort(this.ksearch_data.id); if (this.ksearch_info) this.hide_message(this.ksearch_info); @@ -4524,18 +4498,6 @@ function rcube_webmail() this.ksearch_data = null; this.ksearch_info = null; this.ksearch_msg = null; - } - - // Aborts pending autocomplete requests - this.ksearch_abort = function() - { - var i, len, ac = this.ksearch_data; - - if (!ac) - return; - - for (i=0, len=ac.locks.length; i 0 && i < prop.requests.length; i++) { + if (prop.requests[i].abort) + prop.requests[i].abort(); + } + + prop.running = 0; + prop.cancelled = true; + this.set_busy(false, '', prop.lock); + } + }; + // post the given form to a hidden iframe this.async_upload_form = function(form, action, onload) { diff --git a/program/steps/mail/autocomplete.inc b/program/steps/mail/autocomplete.inc index c15de92cf..5b8b49dba 100644 --- a/program/steps/mail/autocomplete.inc +++ b/program/steps/mail/autocomplete.inc @@ -49,7 +49,7 @@ $mode = (int) $RCMAIL->config->get('addressbook_search_mode'); $single = (bool) $RCMAIL->config->get('autocomplete_single'); $search = rcube_utils::get_input_value('_search', rcube_utils::INPUT_GPC, true); $source = rcube_utils::get_input_value('_source', rcube_utils::INPUT_GPC); -$sid = rcube_utils::get_input_value('_id', rcube_utils::INPUT_GPC); +$reqid = rcube_utils::get_input_value('_reqid', rcube_utils::INPUT_GPC); if (strlen($source)) { $book_types = array($source); @@ -154,5 +154,5 @@ if (!empty($book_types) && strlen($search)) { } } -$OUTPUT->command('ksearch_query_results', $contacts, $search, $sid); +$OUTPUT->command('ksearch_query_results', $contacts, $search, $reqid); $OUTPUT->send(); -- cgit v1.2.3