1 // Copyright 2018 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 package org.chromium.chrome.browser.omnibox; 6 7 import android.content.res.Resources; 8 import android.text.Editable; 9 import android.text.Selection; 10 import android.text.TextUtils; 11 import android.view.ActionMode; 12 13 import androidx.annotation.ColorRes; 14 15 import org.chromium.base.ApiCompatibilityUtils; 16 import org.chromium.base.Callback; 17 import org.chromium.chrome.R; 18 import org.chromium.chrome.browser.omnibox.UrlBarProperties.AutocompleteText; 19 import org.chromium.chrome.browser.omnibox.UrlBarProperties.UrlBarTextState; 20 import org.chromium.ui.modelutil.PropertyKey; 21 import org.chromium.ui.modelutil.PropertyModel; 22 23 /** 24 * Handles translating the UrlBar model data to the view state. 25 */ 26 class UrlBarViewBinder { 27 /** 28 * @see 29 * PropertyModelChangeProcessor.ViewBinder#bind(Object, 30 * Object, Object) 31 */ bind(PropertyModel model, UrlBar view, PropertyKey propertyKey)32 public static void bind(PropertyModel model, UrlBar view, PropertyKey propertyKey) { 33 if (UrlBarProperties.ACTION_MODE_CALLBACK.equals(propertyKey)) { 34 ActionMode.Callback callback = model.get(UrlBarProperties.ACTION_MODE_CALLBACK); 35 if (callback == null && view.getCustomSelectionActionModeCallback() == null) return; 36 view.setCustomSelectionActionModeCallback(callback); 37 } else if (UrlBarProperties.ALLOW_FOCUS.equals(propertyKey)) { 38 view.setAllowFocus(model.get(UrlBarProperties.ALLOW_FOCUS)); 39 } else if (UrlBarProperties.AUTOCOMPLETE_TEXT.equals(propertyKey)) { 40 AutocompleteText autocomplete = model.get(UrlBarProperties.AUTOCOMPLETE_TEXT); 41 if (view.shouldAutocomplete()) { 42 view.setAutocompleteText(autocomplete.userText, autocomplete.autocompleteText); 43 } 44 } else if (UrlBarProperties.DELEGATE.equals(propertyKey)) { 45 view.setDelegate(model.get(UrlBarProperties.DELEGATE)); 46 } else if (UrlBarProperties.FOCUS_CHANGE_CALLBACK.equals(propertyKey)) { 47 final Callback<Boolean> focusChangeCallback = 48 model.get(UrlBarProperties.FOCUS_CHANGE_CALLBACK); 49 view.setOnFocusChangeListener((v, focused) -> { 50 if (focused) view.setIgnoreTextChangesForAutocomplete(false); 51 focusChangeCallback.onResult(focused); 52 }); 53 } else if (UrlBarProperties.SHOW_CURSOR.equals(propertyKey)) { 54 view.setCursorVisible(model.get(UrlBarProperties.SHOW_CURSOR)); 55 } else if (UrlBarProperties.TEXT_CONTEXT_MENU_DELEGATE.equals(propertyKey)) { 56 view.setTextContextMenuDelegate(model.get(UrlBarProperties.TEXT_CONTEXT_MENU_DELEGATE)); 57 } else if (UrlBarProperties.TEXT_STATE.equals(propertyKey)) { 58 UrlBarTextState state = model.get(UrlBarProperties.TEXT_STATE); 59 view.setIgnoreTextChangesForAutocomplete(true); 60 view.setText(state.text); 61 view.setTextForAutofillServices(state.textForAutofillServices); 62 view.setScrollState(state.scrollType, state.scrollToIndex); 63 view.setIgnoreTextChangesForAutocomplete(false); 64 65 if (view.hasFocus()) { 66 if (state.selectionState == UrlBarCoordinator.SelectionState.SELECT_ALL) { 67 view.selectAll(); 68 } else if (state.selectionState == UrlBarCoordinator.SelectionState.SELECT_END) { 69 view.setSelection(view.getText().length()); 70 } 71 } 72 } else if (UrlBarProperties.USE_DARK_TEXT_COLORS.equals(propertyKey)) { 73 updateTextColors(view, model.get(UrlBarProperties.USE_DARK_TEXT_COLORS)); 74 } else if (UrlBarProperties.URL_DIRECTION_LISTENER.equals(propertyKey)) { 75 view.setUrlDirectionListener(model.get(UrlBarProperties.URL_DIRECTION_LISTENER)); 76 } else if (UrlBarProperties.URL_TEXT_CHANGE_LISTENER.equals(propertyKey)) { 77 view.setUrlTextChangeListener(model.get(UrlBarProperties.URL_TEXT_CHANGE_LISTENER)); 78 } else if (UrlBarProperties.TEXT_CHANGED_LISTENER.equals(propertyKey)) { 79 view.setTextChangedListener(model.get(UrlBarProperties.TEXT_CHANGED_LISTENER)); 80 } else if (UrlBarProperties.WINDOW_DELEGATE.equals(propertyKey)) { 81 view.setWindowDelegate(model.get(UrlBarProperties.WINDOW_DELEGATE)); 82 } 83 } 84 updateTextColors(UrlBar view, boolean useDarkTextColors)85 private static void updateTextColors(UrlBar view, boolean useDarkTextColors) { 86 int originalHighlightColor; 87 Object highlightColorObj = view.getTag(R.id.highlight_color); 88 if (highlightColorObj == null || !(highlightColorObj instanceof Integer)) { 89 originalHighlightColor = view.getHighlightColor(); 90 view.setTag(R.id.highlight_color, originalHighlightColor); 91 } else { 92 originalHighlightColor = (Integer) highlightColorObj; 93 } 94 95 Resources resources = view.getResources(); 96 int textColor; 97 int hintColor; 98 int highlightColor; 99 if (useDarkTextColors) { 100 textColor = ApiCompatibilityUtils.getColor(resources, R.color.default_text_color_dark); 101 hintColor = 102 ApiCompatibilityUtils.getColor(resources, R.color.locationbar_dark_hint_text); 103 highlightColor = originalHighlightColor; 104 } else { 105 textColor = ApiCompatibilityUtils.getColor(resources, R.color.default_text_color_light); 106 hintColor = 107 ApiCompatibilityUtils.getColor(resources, R.color.locationbar_light_hint_text); 108 highlightColor = ApiCompatibilityUtils.getColor( 109 resources, R.color.highlight_color_on_light_text); 110 } 111 112 view.setTextColor(textColor); 113 setHintTextColor(view, hintColor); 114 view.setHighlightColor(highlightColor); 115 } 116 setHintTextColor(UrlBar view, @ColorRes int textColor)117 private static void setHintTextColor(UrlBar view, @ColorRes int textColor) { 118 // Note: Setting the hint text color only takes effect if there is not text in the URL bar. 119 // To get around this, set the URL to empty before setting the hint color and revert 120 // back to the previous text after. 121 boolean hasNonEmptyText = false; 122 int selectionStart = 0; 123 int selectionEnd = 0; 124 Editable text = view.getText(); 125 if (!TextUtils.isEmpty(text)) { 126 selectionStart = view.getSelectionStart(); 127 selectionEnd = view.getSelectionEnd(); 128 // Make sure the setText in this block does not affect the suggestions. 129 view.setIgnoreTextChangesForAutocomplete(true); 130 view.setText(""); 131 hasNonEmptyText = true; 132 } 133 view.setHintTextColor(textColor); 134 if (hasNonEmptyText) { 135 view.setText(text); 136 if (view.hasFocus()) { 137 Selection.setSelection(view.getText(), selectionStart, selectionEnd); 138 } 139 view.setIgnoreTextChangesForAutocomplete(false); 140 } 141 } 142 UrlBarViewBinder()143 private UrlBarViewBinder() {} 144 } 145