OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chrome/browser/ui/webui/omnibox/omnibox_ui_handler.h" | 5 #include "chrome/browser/ui/webui/omnibox/omnibox_ui_handler.h" |
6 | 6 |
7 #include <string> | 7 #include <string> |
8 | 8 |
9 #include "base/bind.h" | 9 #include "base/bind.h" |
10 #include "base/string16.h" | 10 #include "base/string16.h" |
(...skipping 15 matching lines...) Expand all Loading... |
26 web_ui()->RegisterMessageCallback("startOmniboxQuery", | 26 web_ui()->RegisterMessageCallback("startOmniboxQuery", |
27 base::Bind(&OmniboxUIHandler::StartOmniboxQuery, | 27 base::Bind(&OmniboxUIHandler::StartOmniboxQuery, |
28 base::Unretained(this))); | 28 base::Unretained(this))); |
29 } | 29 } |
30 | 30 |
31 // This function gets called when the AutocompleteController possibly | 31 // This function gets called when the AutocompleteController possibly |
32 // has new results. We package those results in a DictionaryValue | 32 // has new results. We package those results in a DictionaryValue |
33 // object result_to_output and call the javascript function | 33 // object result_to_output and call the javascript function |
34 // handleNewAutocompleteResult. Here's an example populated | 34 // handleNewAutocompleteResult. Here's an example populated |
35 // result_to_output object: | 35 // result_to_output object: |
36 // { 'done': false, | 36 // { |
| 37 // 'done': false, |
37 // 'time_since_omnibox_started_ms': 15, | 38 // 'time_since_omnibox_started_ms': 15, |
38 // 'num_items': 4, | 39 // 'combined_results' : { |
39 // 'item_0': { | 40 // 'num_items': 4, |
40 // 'destination_url': 'http://mail.google.com', | 41 // 'item_0': { |
41 // 'provider_name': 'HistoryURL', | 42 // 'destination_url': 'http://mail.google.com', |
42 // 'relevance': 1410, | 43 // 'provider_name': 'HistoryURL', |
43 // 'is_default_match': true, | 44 // 'relevance': 1410, |
44 // ... | 45 // ... |
45 // } | 46 // } |
46 // 'item_1: { | 47 // 'item_1: { |
| 48 // ... |
| 49 // } |
47 // ... | 50 // ... |
48 // } | 51 // } |
49 // ... | 52 // 'results_by_provider': { |
| 53 // 'HistoryURL' : { |
| 54 // 'num_items': 3, |
| 55 // ... |
| 56 // } |
| 57 // 'Search' : { |
| 58 // 'num_items': 1, |
| 59 // ... |
| 60 // } |
| 61 // ... |
| 62 // } |
50 // } | 63 // } |
51 // For reference, the javascript code that unpacks this object and | 64 // For reference, the javascript code that unpacks this object and |
52 // displays it is in chrome/browser/resources/omnibox.js | 65 // displays it is in chrome/browser/resources/omnibox.js |
53 // | |
54 // TODO(mpearson): Instead of iterating over the sorted-and- | |
55 // duplicate-eliminated results, perhaps it would be useful to also | |
56 // poll all the AutocompleteController's providers. This will require | |
57 // changing the AutocompleteController's interface. | |
58 void OmniboxUIHandler::OnResultChanged(bool default_match_changed) { | 66 void OmniboxUIHandler::OnResultChanged(bool default_match_changed) { |
59 const AutocompleteResult& result = controller_->result(); | |
60 base::DictionaryValue result_to_output; | 67 base::DictionaryValue result_to_output; |
61 // Fill in result-level information. | 68 // Fill in general information. |
62 result_to_output.SetBoolean("done", controller_->done()); | 69 result_to_output.SetBoolean("done", controller_->done()); |
63 result_to_output.SetInteger("time_since_omnibox_started_ms", | 70 result_to_output.SetInteger("time_since_omnibox_started_ms", |
64 (base::Time::Now() - time_omnibox_started_).InMilliseconds()); | 71 (base::Time::Now() - time_omnibox_started_).InMilliseconds()); |
65 result_to_output.SetInteger("num_items", result.size()); | 72 // Fill in the merged/combined results the controller has provided. |
66 // Fill in per-match information. | 73 AddResultToDictionary("combined_results", controller_->result().begin(), |
| 74 controller_->result().end(), &result_to_output); |
| 75 // Fill results from each individual provider as well. |
| 76 for (ACProviders::const_iterator it(controller_->providers()->begin()); |
| 77 it != controller_->providers()->end(); ++it) { |
| 78 AddResultToDictionary(std::string("results_by_provider.") + (*it)->name(), |
| 79 (*it)->matches().begin(), (*it)->matches().end(), &result_to_output); |
| 80 } |
| 81 // Add done; send the results. |
| 82 web_ui()->CallJavascriptFunction("omniboxDebug.handleNewAutocompleteResult", |
| 83 result_to_output); |
| 84 } |
| 85 |
| 86 // For details on the format of the DictionaryValue that this function |
| 87 // populates, see the comments by OnResultChanged(). |
| 88 void OmniboxUIHandler::AddResultToDictionary(const std::string prefix, |
| 89 ACMatches::const_iterator it, |
| 90 ACMatches::const_iterator end, |
| 91 base::DictionaryValue* output) { |
67 int i = 0; | 92 int i = 0; |
68 for (ACMatches::const_iterator it = result.begin(); it != result.end(); | 93 for (; it != end; ++it, ++i) { |
69 ++it, ++i) { | 94 std::string item_prefix(prefix + StringPrintf(".item_%d", i)); |
70 std::string prefix(StringPrintf("item_%d", i)); | |
71 if (it->provider != NULL) { | 95 if (it->provider != NULL) { |
72 result_to_output.SetString(prefix + ".provider_name", | 96 output->SetString(item_prefix + ".provider_name", it->provider->name()); |
73 it->provider->name()); | 97 output->SetBoolean(item_prefix + ".provider_done", it->provider->done()); |
74 result_to_output.SetBoolean(prefix + ".provider_done", | |
75 it->provider->done()); | |
76 } | 98 } |
77 result_to_output.SetInteger(prefix + ".relevance", it->relevance); | 99 output->SetInteger(item_prefix + ".relevance", it->relevance); |
78 result_to_output.SetBoolean(prefix + ".deletable", it->deletable); | 100 output->SetBoolean(item_prefix + ".deletable", it->deletable); |
79 result_to_output.SetString(prefix + ".fill_into_edit", it->fill_into_edit); | 101 output->SetString(item_prefix + ".fill_into_edit", it->fill_into_edit); |
80 result_to_output.SetInteger(prefix + ".inline_autocomplete_offset", | 102 output->SetInteger(item_prefix + ".inline_autocomplete_offset", |
81 it->inline_autocomplete_offset); | 103 it->inline_autocomplete_offset); |
82 result_to_output.SetString(prefix + ".destination_url", | 104 output->SetString(item_prefix + ".destination_url", |
83 it->destination_url.spec()); | 105 it->destination_url.spec()); |
84 result_to_output.SetString(prefix + ".contents", it->contents); | 106 output->SetString(item_prefix + ".contents", it->contents); |
85 // At this time, we're not bothering to send along the long vector that | 107 // At this time, we're not bothering to send along the long vector that |
86 // represent contents classification. i.e., for each character, what | 108 // represent contents classification. i.e., for each character, what |
87 // type of text it is. | 109 // type of text it is. |
88 result_to_output.SetString(prefix + ".description", it->description); | 110 output->SetString(item_prefix + ".description", it->description); |
89 // At this time, we're not bothering to send along the long vector that | 111 // At this time, we're not bothering to send along the long vector that |
90 // represents description classification. i.e., for each character, what | 112 // represents description classification. i.e., for each character, what |
91 // type of text it is. | 113 // type of text it is. |
92 result_to_output.SetInteger(prefix + ".transition", it->transition); | 114 output->SetInteger(item_prefix + ".transition", it->transition); |
93 result_to_output.SetBoolean(prefix + ".is_history_what_you_typed_match", | 115 output->SetBoolean(item_prefix + ".is_history_what_you_typed_match", |
94 it->is_history_what_you_typed_match); | 116 it->is_history_what_you_typed_match); |
95 result_to_output.SetString(prefix + ".type", | 117 output->SetString(item_prefix + ".type", |
96 AutocompleteMatch::TypeToString(it->type)); | 118 AutocompleteMatch::TypeToString(it->type)); |
97 if ((it->template_url != NULL) && (it->template_url->url() != NULL)) { | 119 if ((it->template_url != NULL) && (it->template_url->url() != NULL)) { |
98 result_to_output.SetString(prefix + ".template_url", | 120 output->SetString(item_prefix + ".template_url", |
99 it->template_url->url()->url()); | 121 it->template_url->url()->url()); |
100 } | 122 } |
101 result_to_output.SetBoolean(prefix + ".starred", it->starred); | 123 output->SetBoolean(item_prefix + ".starred", it->starred); |
102 result_to_output.SetBoolean(prefix + ".from_previous", it->from_previous); | 124 output->SetBoolean(item_prefix + ".from_previous", it->from_previous); |
103 result_to_output.SetBoolean(prefix + ".is_default_match", | |
104 it == result.default_match()); | |
105 } | 125 } |
106 web_ui()->CallJavascriptFunction("omniboxDebug.handleNewAutocompleteResult", | 126 output->SetInteger(prefix + ".num_items", i); |
107 result_to_output); | |
108 } | 127 } |
109 | 128 |
110 void OmniboxUIHandler::StartOmniboxQuery( | 129 void OmniboxUIHandler::StartOmniboxQuery( |
111 const base::ListValue* one_element_input_string) { | 130 const base::ListValue* one_element_input_string) { |
112 string16 input_string = ExtractStringValue(one_element_input_string); | 131 string16 input_string = ExtractStringValue(one_element_input_string); |
113 string16 empty_string; | 132 string16 empty_string; |
114 // Tell the autocomplete controller to start working on the | 133 // Tell the autocomplete controller to start working on the |
115 // input. It's okay if the previous request hasn't yet finished; | 134 // input. It's okay if the previous request hasn't yet finished; |
116 // the autocomplete controller is smart enough to stop the previous | 135 // the autocomplete controller is smart enough to stop the previous |
117 // query before it starts the new one. By the way, in this call to | 136 // query before it starts the new one. By the way, in this call to |
118 // Start(), we use the default/typical values for all parameters. | 137 // Start(), we use the default/typical values for all parameters. |
119 time_omnibox_started_ = base::Time::Now(); | 138 time_omnibox_started_ = base::Time::Now(); |
120 controller_->Start(input_string, | 139 controller_->Start(input_string, |
121 empty_string, // user's desired tld (top-level domain) | 140 empty_string, // user's desired tld (top-level domain) |
122 false, // don't prevent inline autocompletion | 141 false, // don't prevent inline autocompletion |
123 false, // no preferred keyword provider | 142 false, // no preferred keyword provider |
124 true, // allow exact keyword matches | 143 true, // allow exact keyword matches |
125 AutocompleteInput::ALL_MATCHES); // want all matches | 144 AutocompleteInput::ALL_MATCHES); // want all matches |
126 } | 145 } |
OLD | NEW |