Index: chrome/android/shell/java/src/org/chromium/chrome/shell/omnibox/SuggestionPopup.java |
diff --git a/chrome/android/shell/java/src/org/chromium/chrome/shell/omnibox/SuggestionPopup.java b/chrome/android/shell/java/src/org/chromium/chrome/shell/omnibox/SuggestionPopup.java |
new file mode 100644 |
index 0000000000000000000000000000000000000000..184af651eb1e236b9bcfb2c0ca39027edec87abb |
--- /dev/null |
+++ b/chrome/android/shell/java/src/org/chromium/chrome/shell/omnibox/SuggestionPopup.java |
@@ -0,0 +1,150 @@ |
+// Copyright 2014 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+package org.chromium.chrome.shell.omnibox; |
+ |
+import android.content.Context; |
+import android.os.Handler; |
+import android.text.Editable; |
+import android.text.TextUtils; |
+import android.text.TextWatcher; |
+import android.view.View; |
+import android.widget.AdapterView; |
+import android.widget.AdapterView.OnItemClickListener; |
+import android.widget.ListPopupWindow; |
+import android.widget.PopupWindow.OnDismissListener; |
+import android.widget.TextView; |
+ |
+import org.chromium.chrome.browser.omnibox.AutocompleteController; |
+import org.chromium.chrome.browser.omnibox.AutocompleteController.OnSuggestionsReceivedListener; |
+import org.chromium.chrome.browser.omnibox.OmniboxSuggestion; |
+import org.chromium.chrome.shell.ChromeShellToolbar; |
+import org.chromium.chrome.shell.R; |
+ |
+import java.util.List; |
+ |
+/** |
+ * Displays suggestions for the text that is entered to the ChromeShell URL field. |
+ */ |
+public class SuggestionPopup implements OnSuggestionsReceivedListener, TextWatcher { |
+ private static final long SUGGESTION_START_DELAY_MS = 30; |
+ |
+ private final Context mContext; |
+ private final TextView mUrlField; |
+ private final ChromeShellToolbar mToolbar; |
+ private final AutocompleteController mAutocomplete; |
+ |
+ private boolean mHasStartedNewOmniboxEditSession; |
+ private Runnable mRequestSuggestions; |
+ private ListPopupWindow mSuggestionsPopup; |
+ private SuggestionArrayAdapter mSuggestionArrayAdapter; |
+ |
+ /** |
+ * Initializes a suggestion popup that will track urlField value and display suggestions based |
+ * on that value. |
+ */ |
+ public SuggestionPopup(Context context, TextView urlField, |
+ ChromeShellToolbar toolbar) { |
+ mContext = context; |
+ mUrlField = urlField; |
+ mToolbar = toolbar; |
+ mAutocomplete = new AutocompleteController(this); |
+ } |
+ |
+ private void navigateToSuggestion(int position) { |
+ mToolbar.getCurrentTab().loadUrlWithSanitization( |
+ mSuggestionArrayAdapter.getItem(position).getUrl()); |
+ mUrlField.clearFocus(); |
+ mToolbar.setKeyboardVisibilityForUrl(false); |
+ mToolbar.getCurrentTab().getView().requestFocus(); |
+ dismissPopup(); |
+ } |
+ |
+ private void dismissPopup() { |
+ if (mSuggestionsPopup != null) { |
+ mSuggestionsPopup.dismiss(); |
+ mSuggestionsPopup = null; |
+ } |
+ } |
+ |
+ /** |
+ * Signals the autocomplete controller to stop generating suggestions and |
+ * cancels the queued task to start the autocomplete controller, if any. |
+ * |
+ * @param clear Whether to clear the most recent autocomplete results. |
+ */ |
+ private void stopAutocomplete(boolean clear) { |
+ if (mAutocomplete != null) mAutocomplete.stop(clear); |
+ if (mRequestSuggestions != null) mRequestSuggestions = null; |
+ } |
+ |
+ // OnSuggestionsReceivedListener implementation |
+ |
+ @Override |
+ public void onSuggestionsReceived(List<OmniboxSuggestion> suggestions, |
+ String inlineAutocompleteText) { |
+ if (!mUrlField.isFocused() || suggestions.isEmpty()) |
+ return; |
+ if (mSuggestionsPopup == null) { |
+ mSuggestionsPopup = new ListPopupWindow( |
+ mContext, null, android.R.attr.autoCompleteTextViewStyle); |
+ mSuggestionsPopup.setOnDismissListener(new OnDismissListener() { |
+ @Override |
+ public void onDismiss() { |
+ mHasStartedNewOmniboxEditSession = false; |
+ mSuggestionArrayAdapter = null; |
+ } |
+ }); |
+ } |
+ mSuggestionsPopup.setWidth(mUrlField.getWidth()); |
+ mSuggestionArrayAdapter = |
+ new SuggestionArrayAdapter(mContext, R.layout.dropdown_item, suggestions); |
+ mSuggestionsPopup.setAdapter(mSuggestionArrayAdapter); |
+ mSuggestionsPopup.setAnchorView(mUrlField); |
+ mSuggestionsPopup.setOnItemClickListener(new OnItemClickListener() { |
+ @Override |
+ public void onItemClick(AdapterView<?> parent, View view, int position, long id) { |
+ navigateToSuggestion(position); |
+ } |
+ }); |
+ mSuggestionsPopup.show(); |
+ } |
+ |
+ // TextWatcher implementation |
+ |
+ @Override |
+ public void afterTextChanged(final Editable editableText) { |
+ if (!mHasStartedNewOmniboxEditSession) { |
+ mAutocomplete.resetSession(); |
+ mHasStartedNewOmniboxEditSession = true; |
+ } |
+ |
+ stopAutocomplete(false); |
+ if (TextUtils.isEmpty(editableText)) { |
+ dismissPopup(); |
+ } else { |
+ assert mRequestSuggestions == null : "Multiple omnibox requests in flight."; |
+ mRequestSuggestions = new Runnable() { |
+ @Override |
+ public void run() { |
+ mRequestSuggestions = null; |
+ mAutocomplete.start( |
+ mToolbar.getCurrentTab().getProfile(), |
+ mToolbar.getCurrentTab().getUrl(), |
+ editableText.toString(), false); |
+ } |
+ }; |
+ new Handler().postDelayed(mRequestSuggestions, SUGGESTION_START_DELAY_MS); |
+ } |
+ } |
+ |
+ @Override |
+ public void beforeTextChanged(CharSequence s, int start, int count, int after) { |
+ mRequestSuggestions = null; |
+ } |
+ |
+ @Override |
+ public void onTextChanged(CharSequence s, int start, int before, int count) { |
+ } |
+} |