Commit 69a5f8a0 authored by Moe Ahmadi's avatar Moe Ahmadi Committed by Commit Bot

Enables zero-prefix suggestions in the NTP realbox

- Queries AutocompleteController when the realbox gets focus and is empty.
- Stops AutocompleteController and clears Autocomplete results when
  realbox loses focus. Otherwise previous non-zero-prefix suggestions
  remain cached.
- Displays the clock icon for the personalized zero-prefix suggestions, if
  applicable.

Bug: 996516
Change-Id: Ib821e0f6f0e5b722f60b6388456c673a7b8b450b
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1786592
Commit-Queue: Moe Ahmadi <mahmadi@chromium.org>
Reviewed-by: default avatarDaniel Cheng <dcheng@chromium.org>
Reviewed-by: default avatarDan Beam <dbeam@chromium.org>
Reviewed-by: default avatarmanuk hovanesian <manukh@chromium.org>
Cr-Commit-Position: refs/heads/master@{#694829}
parent 038e6840
......@@ -388,6 +388,8 @@ window.chrome.embeddedSearch.searchBox.startCapturingKeyStrokes;
window.chrome.embeddedSearch.searchBox.stopCapturingKeyStrokes;
/** @param {string} input */
window.chrome.embeddedSearch.searchBox.queryAutocomplete;
/** @param {boolean} clearResult */
window.chrome.embeddedSearch.searchBox.stopAutocomplete;
/** @typedef {{offset: number, style: number}} */
let ACMatchClassification;
......
......@@ -99,6 +99,11 @@ const CLASSES = {
USE_NOTIFIER: 'use-notifier',
};
const SEARCH_HISTORY_MATCH_TYPES = [
'search-history',
'search-suggest-personalized',
];
/**
* Background color for Chrome dark mode. Used to determine if it is possible to
* display a Google Doodle, or if the notifier should be used instead.
......@@ -1028,8 +1033,8 @@ function onQueryAutocompleteDone(matches) {
let iconClass;
if (match.isSearchType) {
const isHistory = match.type === 'search-history';
const useClock = isHistory && configData.realboxUseClockIcon;
const isSearchHistory = SEARCH_HISTORY_MATCH_TYPES.includes(match.type);
const useClock = isSearchHistory && configData.realboxUseClockIcon;
iconClass = useClock ? CLASSES.CLOCK_ICON : CLASSES.SEARCH_ICON;
} else {
// TODO(crbug.com/997229): use chrome://favicon/<url> when perms allow.
......@@ -1205,15 +1210,16 @@ function onRealboxInput() {
/** @param {Event} e */
function onRealboxWrapperFocusIn(e) {
if (!e.target.matches(`#${IDS.REALBOX_MATCHES} a`)) {
return;
if (e.target.matches(`#${IDS.REALBOX}`) && !$(IDS.REALBOX).value) {
window.chrome.embeddedSearch.searchBox.queryAutocomplete('');
} else if (e.target.matches(`#${IDS.REALBOX_MATCHES} a`)) {
const selectedIndex = selectMatchEl(e.target);
// It doesn't really make sense to use fillFromMatch() here as the focus
// change drops the selection (and is probably just noisy to
// screenreaders).
const newFill = autocompleteMatches[selectedIndex].fillIntoEdit;
updateRealboxOutput({moveCursorToEnd: true, inline: '', text: newFill});
}
const selectedIndex = selectMatchEl(e.target);
// It doesn't really make sense to use fillFromMatch() here as the focus
// change drops the selection (and is probably just noisy to
// screenreaders).
const newFill = autocompleteMatches[selectedIndex].fillIntoEdit;
updateRealboxOutput({moveCursorToEnd: true, inline: '', text: newFill});
}
/** @param {Event} e */
......@@ -1221,6 +1227,8 @@ function onRealboxWrapperFocusOut(e) {
const relatedTarget = /** @type {Element} */ (e.relatedTarget);
if (!$(IDS.REALBOX_INPUT_WRAPPER).contains(relatedTarget)) {
hideRealboxMatches(); // Hide but don't clear input.
window.chrome.embeddedSearch.searchBox.stopAutocomplete(
/*clearResult=*/ true);
}
}
......
......@@ -451,6 +451,14 @@ void SearchIPCRouter::QueryAutocomplete(
delegate_->QueryAutocomplete(input, std::move(callback));
}
void SearchIPCRouter::StopAutocomplete(bool clear_result) {
if (!policy_->ShouldProcessStopAutocomplete(is_active_tab_)) {
return;
}
delegate_->StopAutocomplete(clear_result);
}
void SearchIPCRouter::set_delegate_for_testing(Delegate* delegate) {
DCHECK(delegate);
delegate_ = delegate;
......
......@@ -159,6 +159,8 @@ class SearchIPCRouter : public content::WebContentsObserver,
virtual void QueryAutocomplete(
const std::string& input,
chrome::mojom::EmbeddedSearch::QueryAutocompleteCallback callback) = 0;
virtual void StopAutocomplete(bool clear_result) = 0;
};
// An interface to be implemented by consumers of SearchIPCRouter objects to
......@@ -198,6 +200,7 @@ class SearchIPCRouter : public content::WebContentsObserver,
virtual bool ShouldProcessOptOutOfSearchSuggestions() = 0;
virtual bool ShouldProcessThemeChangeMessages() = 0;
virtual bool ShouldProcessQueryAutocomplete(bool is_active_tab) = 0;
virtual bool ShouldProcessStopAutocomplete(bool is_active_tab) = 0;
};
// Creates chrome::mojom::EmbeddedSearchClient connections on request.
......@@ -307,6 +310,7 @@ class SearchIPCRouter : public content::WebContentsObserver,
const std::string& input,
chrome::mojom::EmbeddedSearch::QueryAutocompleteCallback callback)
override;
void StopAutocomplete(bool clear_result) override;
void set_embedded_search_client_factory_for_testing(
std::unique_ptr<EmbeddedSearchClientFactory> factory) {
embedded_search_client_factory_ = std::move(factory);
......
......@@ -136,3 +136,8 @@ bool SearchIPCRouterPolicyImpl::ShouldProcessQueryAutocomplete(
bool is_active_tab) {
return is_active_tab && !is_incognito_ && search::IsInstantNTP(web_contents_);
}
bool SearchIPCRouterPolicyImpl::ShouldProcessStopAutocomplete(
bool is_active_tab) {
return is_active_tab && !is_incognito_ && search::IsInstantNTP(web_contents_);
}
......@@ -55,6 +55,7 @@ class SearchIPCRouterPolicyImpl : public SearchIPCRouter::Policy {
bool ShouldProcessOptOutOfSearchSuggestions() override;
bool ShouldProcessThemeChangeMessages() override;
bool ShouldProcessQueryAutocomplete(bool is_active_tab) override;
bool ShouldProcessStopAutocomplete(bool is_active_tab) override;
// Used by unit tests.
void set_is_incognito(bool is_incognito) {
......
......@@ -107,6 +107,7 @@ class MockSearchIPCRouterDelegate : public SearchIPCRouter::Delegate {
QueryAutocomplete,
void(const std::string& input,
chrome::mojom::EmbeddedSearch::QueryAutocompleteCallback callback));
MOCK_METHOD1(StopAutocomplete, void(bool clear_result));
};
class MockSearchIPCRouterPolicy : public SearchIPCRouter::Policy {
......@@ -142,6 +143,7 @@ class MockSearchIPCRouterPolicy : public SearchIPCRouter::Policy {
MOCK_METHOD0(ShouldSendLocalBackgroundSelected, bool());
MOCK_METHOD0(ShouldProcessThemeChangeMessages, bool());
MOCK_METHOD1(ShouldProcessQueryAutocomplete, bool(bool));
MOCK_METHOD1(ShouldProcessStopAutocomplete, bool(bool));
};
class MockEmbeddedSearchClientFactory
......
......@@ -552,7 +552,8 @@ void SearchTabHelper::QueryAutocomplete(
AutocompleteProvider::TYPE_BUILTIN |
AutocompleteProvider::TYPE_HISTORY_QUICK |
AutocompleteProvider::TYPE_HISTORY_URL |
AutocompleteProvider::TYPE_SEARCH;
AutocompleteProvider::TYPE_SEARCH |
AutocompleteProvider::TYPE_ZERO_SUGGEST;
autocomplete_controller_ = std::make_unique<AutocompleteController>(
std::make_unique<ChromeAutocompleteProviderClient>(profile()), this,
providers);
......@@ -560,9 +561,19 @@ void SearchTabHelper::QueryAutocomplete(
query_autocomplete_callback_ = std::move(callback);
autocomplete_controller_->Start(AutocompleteInput(
AutocompleteInput autocomplete_input(
base::UTF8ToUTF16(input), metrics::OmniboxEventProto::NTP_REALBOX,
ChromeAutocompleteSchemeClassifier(profile())));
ChromeAutocompleteSchemeClassifier(profile()));
autocomplete_input.set_from_omnibox_focus(input.empty());
autocomplete_controller_->Start(autocomplete_input);
}
void SearchTabHelper::StopAutocomplete(bool clear_result) {
if (!autocomplete_controller_) {
return;
}
autocomplete_controller_->Stop(clear_result);
}
OmniboxView* SearchTabHelper::GetOmniboxView() {
......
......@@ -141,6 +141,7 @@ class SearchTabHelper : public content::WebContentsObserver,
const std::string& input,
chrome::mojom::EmbeddedSearch::QueryAutocompleteCallback callback)
override;
void StopAutocomplete(bool clear_result) override;
// Overridden from InstantServiceObserver:
void ThemeInfoChanged(const ThemeBackgroundInfo& theme_info) override;
......
......@@ -165,6 +165,10 @@ interface EmbeddedSearch {
// Gets autocomplete matches from the browser.
QueryAutocomplete(string input) => (array<AutocompleteMatch> matches);
// Cancels the current autocomplete query. Clears the result set if
// |clear_result| is true.
StopAutocomplete(bool clear_result);
};
[Native]
......
......@@ -438,6 +438,10 @@ void SearchBox::QueryAutocomplete(const std::string& input) {
weak_ptr_factory_.GetWeakPtr()));
}
void SearchBox::StopAutocomplete(bool clear_result) {
embedded_search_service_->StopAutocomplete(clear_result);
}
void SearchBox::QueryAutocompleteResult(
std::vector<chrome::mojom::AutocompleteMatchPtr> results) {
if (can_run_js_in_renderframe_) {
......
......@@ -193,6 +193,10 @@ class SearchBox : public content::RenderFrameObserver,
// search term. Handled by |QueryAutocompleteResult|.
void QueryAutocomplete(const std::string& input);
// Cancels the current autocomplete query. Clears the result set if
// |clear_result| is true.
void StopAutocomplete(bool clear_result);
bool is_focused() const { return is_focused_; }
bool is_input_in_progress() const { return is_input_in_progress_; }
bool is_key_capture_enabled() const { return is_key_capture_enabled_; }
......
......@@ -620,6 +620,7 @@ class SearchBoxBindings : public gin::Wrappable<SearchBoxBindings> {
// Handlers for JS functions.
static void Paste(const std::string& text);
static void QueryAutocomplete(const std::string& input);
static void StopAutocomplete(bool clear_result);
static void StartCapturingKeyStrokes();
static void StopCapturingKeyStrokes();
......@@ -641,6 +642,7 @@ gin::ObjectTemplateBuilder SearchBoxBindings::GetObjectTemplateBuilder(
&SearchBoxBindings::IsKeyCaptureEnabled)
.SetMethod("paste", &SearchBoxBindings::Paste)
.SetMethod("queryAutocomplete", &SearchBoxBindings::QueryAutocomplete)
.SetMethod("stopAutocomplete", &SearchBoxBindings::StopAutocomplete)
.SetMethod("startCapturingKeyStrokes",
&SearchBoxBindings::StartCapturingKeyStrokes)
.SetMethod("stopCapturingKeyStrokes",
......@@ -683,6 +685,14 @@ void SearchBoxBindings::QueryAutocomplete(const std::string& input) {
search_box->QueryAutocomplete(input);
}
// static
void SearchBoxBindings::StopAutocomplete(bool clear_result) {
SearchBox* search_box = GetSearchBoxForCurrentContext();
if (!search_box)
return;
search_box->StopAutocomplete(clear_result);
}
// static
void SearchBoxBindings::StartCapturingKeyStrokes() {
SearchBox* search_box = GetSearchBoxForCurrentContext();
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment