Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(5)

Unified Diff: chrome/android/java_staging/src/org/chromium/chrome/browser/omnibox/UrlBar.java

Issue 1206673003: Merge java_staging/src into java/src. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: rebase Created 5 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: chrome/android/java_staging/src/org/chromium/chrome/browser/omnibox/UrlBar.java
diff --git a/chrome/android/java_staging/src/org/chromium/chrome/browser/omnibox/UrlBar.java b/chrome/android/java_staging/src/org/chromium/chrome/browser/omnibox/UrlBar.java
deleted file mode 100644
index 6696bc54eb4ff93e90d903c7cbcebc6d688675fe..0000000000000000000000000000000000000000
--- a/chrome/android/java_staging/src/org/chromium/chrome/browser/omnibox/UrlBar.java
+++ /dev/null
@@ -1,1001 +0,0 @@
-// Copyright 2015 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.browser.omnibox;
-
-import android.content.ClipData;
-import android.content.ClipboardManager;
-import android.content.Context;
-import android.content.res.ColorStateList;
-import android.content.res.Resources;
-import android.graphics.Canvas;
-import android.graphics.Rect;
-import android.os.SystemClock;
-import android.text.Editable;
-import android.text.Layout;
-import android.text.Selection;
-import android.text.Spanned;
-import android.text.TextUtils;
-import android.text.TextWatcher;
-import android.util.AttributeSet;
-import android.view.GestureDetector;
-import android.view.KeyEvent;
-import android.view.MotionEvent;
-import android.view.View;
-import android.view.accessibility.AccessibilityEvent;
-import android.view.accessibility.AccessibilityManager;
-import android.view.accessibility.AccessibilityNodeInfo;
-import android.view.inputmethod.BaseInputConnection;
-import android.view.inputmethod.EditorInfo;
-import android.view.inputmethod.InputConnection;
-import android.view.inputmethod.InputConnectionWrapper;
-
-import org.chromium.base.VisibleForTesting;
-import org.chromium.chrome.R;
-import org.chromium.chrome.browser.UrlUtilities;
-import org.chromium.chrome.browser.omnibox.LocationBarLayout.OmniboxLivenessListener;
-import org.chromium.chrome.browser.tab.ChromeTab;
-import org.chromium.chrome.browser.widget.VerticallyFixedEditText;
-import org.chromium.content.browser.ContentViewCore;
-import org.chromium.ui.UiUtils;
-
-import java.net.MalformedURLException;
-import java.net.URI;
-import java.net.URISyntaxException;
-import java.net.URL;
-
-/**
- * The URL text entry view for the Omnibox.
- */
-public class UrlBar extends VerticallyFixedEditText {
- private static final String TAG = "UrlBar";
-
- /** The contents of the URL that precede the path/query after being formatted. */
- private String mFormattedUrlLocation;
-
- /** The contents of the URL that precede the path/query before formatting. */
- private String mOriginalUrlLocation;
-
- /** Overrides the text announced during accessibility events. */
- private String mAccessibilityTextOverride;
-
- private TextWatcher mLocationBarTextWatcher;
-
- private boolean mShowKeyboardOnWindowFocus;
-
- private boolean mFirstDrawComplete;
-
- /**
- * The text direction of the URL or query: LAYOUT_DIRECTION_LOCALE, LAYOUT_DIRECTION_LTR, or
- * LAYOUT_DIRECTION_RTL.
- * */
- private int mUrlDirection;
-
- private UrlBarDelegate mUrlBarDelegate;
-
- private UrlDirectionListener mUrlDirectionListener;
-
- private final AutocompleteSpan mAutocompleteSpan;
-
- /**
- * The gesture detector is used to detect long presses. Long presses require special treatment
- * because the URL bar has custom touch event handling. See: {@link #onTouchEvent}.
- */
- private final GestureDetector mGestureDetector;
- private boolean mFocused;
-
- private final ColorStateList mDarkHintColor;
- private final int mDarkDefaultTextColor;
- private final int mDarkHighlightColor;
-
- private final int mLightHintColor;
- private final int mLightDefaultTextColor;
- private final int mLightHighlightColor;
-
- private Boolean mUseDarkColors;
-
- private AccessibilityManager mAccessibilityManager;
- private boolean mDisableTextAccessibilityEvents;
-
- /**
- * Whether default TextView scrolling should be disabled because autocomplete has been added.
- * This allows the user entered text to be shown instead of the end of the autocomplete.
- */
- private boolean mDisableTextScrollingFromAutocomplete;
-
- private OmniboxLivenessListener mOmniboxLivenessListener;
-
- private long mFirstFocusTimeMs;
-
- private boolean mInBatchEditMode;
- private boolean mSelectionChangedInBatchMode;
-
- /**
- * Implement this to get updates when the direction of the text in the URL bar changes.
- * E.g. If the user is typing a URL, then erases it and starts typing a query in Arabic,
- * the direction will change from left-to-right to right-to-left.
- */
- interface UrlDirectionListener {
- /**
- * Called whenever the layout direction of the UrlBar changes.
- * @param layoutDirection the new direction: android.view.View.LAYOUT_DIRECTION_LTR or
- * android.view.View.LAYOUT_DIRECTION_RTL
- */
- public void onUrlDirectionChanged(int layoutDirection);
- }
-
- /**
- * Delegate used to communicate with the content side and the parent layout.
- */
- public interface UrlBarDelegate {
- /**
- * @return The current active {@link ChromeTab}.
- */
- ChromeTab getCurrentTab();
-
- /**
- * Notify the linked {@link TextWatcher} to ignore any changes made in the UrlBar text.
- * @param ignore Whether the changes should be ignored.
- */
- void setIgnoreURLBarModification(boolean ignore);
-
- /**
- * Called at the beginning of the focus change event before the underlying TextView
- * behavior is triggered.
- * @param gainFocus Whether the URL is gaining focus or not.
- */
- void onUrlPreFocusChanged(boolean gainFocus);
-
- /**
- * Called to notify that back key has been pressed while the focus in on the url bar.
- */
- void backKeyPressed();
-
- /**
- * @return Whether original url is shown for preview page.
- */
- boolean showingOriginalUrlForPreview();
-
- /**
- * @return Whether the light security theme should be used.
- */
- boolean shouldEmphasizeHttpsScheme();
- }
-
- public UrlBar(Context context, AttributeSet attrs) {
- super(context, attrs);
-
- Resources resources = getResources();
-
- mDarkDefaultTextColor = resources.getColor(R.color.url_emphasis_default_text);
- mDarkHintColor = getHintTextColors();
- mDarkHighlightColor = getHighlightColor();
-
- mLightDefaultTextColor = resources.getColor(R.color.url_emphasis_light_default_text);
- mLightHintColor = resources.getColor(R.color.locationbar_light_hint_text);
- mLightHighlightColor = resources.getColor(R.color.locationbar_light_selection_color);
-
- setUseDarkTextColors(true);
-
- mUrlDirection = LAYOUT_DIRECTION_LOCALE;
- mAutocompleteSpan = new AutocompleteSpan();
-
- // The URL Bar is derived from an text edit class, and as such is focusable by
- // default. This means that if it is created before the first draw of the UI it
- // will (as the only focusable element of the UI) get focus on the first draw.
- // We react to this by greying out the tab area and bringing up the keyboard,
- // which we don't want to do at startup. Prevent this by disabling focus until
- // the first draw.
- setFocusable(false);
- setFocusableInTouchMode(false);
-
- mGestureDetector = new GestureDetector(
- getContext(), new GestureDetector.SimpleOnGestureListener() {
- @Override
- public void onLongPress(MotionEvent e) {
- performLongClick();
- }
-
- @Override
- public boolean onSingleTapUp(MotionEvent e) {
- requestFocus();
- return true;
- }
- });
- mGestureDetector.setOnDoubleTapListener(null);
-
- mAccessibilityManager =
- (AccessibilityManager) context.getSystemService(Context.ACCESSIBILITY_SERVICE);
- }
-
- /**
- * Specifies whether the URL bar should use dark text colors or light colors.
- * @param useDarkColors Whether the text colors should be dark (i.e. appropriate for use
- * on a light background).
- */
- public void setUseDarkTextColors(boolean useDarkColors) {
- if (mUseDarkColors != null && mUseDarkColors.booleanValue() == useDarkColors) return;
-
- mUseDarkColors = useDarkColors;
- if (mUseDarkColors) {
- setTextColor(mDarkDefaultTextColor);
- setHighlightColor(mDarkHighlightColor);
- } else {
- setTextColor(mLightDefaultTextColor);
- setHighlightColor(mLightHighlightColor);
- }
-
- // Note: Setting the hint text color only takes effect if there is not text in the URL bar.
- // To get around this, set the URL to empty before setting the hint color and revert
- // back to the previous text after.
- boolean hasNonEmptyText = false;
- Editable text = getText();
- if (!TextUtils.isEmpty(text)) {
- setText("");
- hasNonEmptyText = true;
- }
- if (useDarkColors) {
- setHintTextColor(mDarkHintColor);
- } else {
- setHintTextColor(mLightHintColor);
- }
- if (hasNonEmptyText) setText(text);
-
- if (!hasFocus()) {
- deEmphasizeUrl();
- emphasizeUrl();
- }
- }
-
- /**
- * @return The search query text (non-null).
- */
- public String getQueryText() {
- return getEditableText() != null ? getEditableText().toString() : "";
- }
-
- /**
- * @return Whether the current cursor position is at the end of the user typed text (i.e.
- * at the beginning of the inline autocomplete text if present otherwise the very
- * end of the current text).
- */
- public boolean isCursorAtEndOfTypedText() {
- final int selectionStart = getSelectionStart();
- final int selectionEnd = getSelectionEnd();
-
- int expectedSelectionStart = getText().getSpanStart(mAutocompleteSpan);
- int expectedSelectionEnd = getText().length();
- if (expectedSelectionStart < 0) {
- expectedSelectionStart = expectedSelectionEnd;
- }
-
- return selectionStart == expectedSelectionStart && selectionEnd == expectedSelectionEnd;
- }
-
- /**
- * @return Whether the URL is currently in batch edit mode triggered by an IME. No external
- * text changes should be triggered while this is true.
- */
- public boolean isInBatchEditMode() {
- return mInBatchEditMode;
- }
-
- /**
- * @return The user text without the autocomplete text.
- */
- public String getTextWithoutAutocomplete() {
- int autoCompleteIndex = getText().getSpanStart(mAutocompleteSpan);
- if (autoCompleteIndex < 0) {
- return getQueryText();
- } else {
- return getQueryText().substring(0, autoCompleteIndex);
- }
- }
-
- /** @return Whether any autocomplete information is specified on the current text. */
- @VisibleForTesting
- protected boolean hasAutocomplete() {
- return getText().getSpanStart(mAutocompleteSpan) >= 0
- || mAutocompleteSpan.mAutocompleteText != null
- || mAutocompleteSpan.mUserText != null;
- }
-
- @Override
- public void onBeginBatchEdit() {
- super.onBeginBatchEdit();
- mInBatchEditMode = true;
- }
-
- @Override
- public void onEndBatchEdit() {
- super.onEndBatchEdit();
- mInBatchEditMode = false;
- if (mSelectionChangedInBatchMode) {
- validateSelection(getSelectionStart(), getSelectionEnd());
- mSelectionChangedInBatchMode = false;
- }
- }
-
- @Override
- protected void onSelectionChanged(int selStart, int selEnd) {
- if (!mInBatchEditMode) {
- validateSelection(selStart, selEnd);
- } else {
- mSelectionChangedInBatchMode = true;
- }
- super.onSelectionChanged(selStart, selEnd);
- }
-
- private void validateSelection(int selStart, int selEnd) {
- int spanStart = getText().getSpanStart(mAutocompleteSpan);
- int spanEnd = getText().getSpanEnd(mAutocompleteSpan);
- if (spanStart >= 0 && (spanStart != selStart || spanEnd != selEnd)) {
- // On selection changes, the autocomplete text has been accepted by the user or needs
- // to be deleted below.
- mAutocompleteSpan.clearSpan();
-
- // The autocomplete text will be deleted any time the selection occurs entirely before
- // the start of the autocomplete text. This is required because certain keyboards will
- // insert characters temporarily when starting a key entry gesture (whether it be
- // swyping a word or long pressing to get a special character). When this temporary
- // character appears, Chrome may decide to append some autocomplete, but the keyboard
- // will then remove this temporary character only while leaving the autocomplete text
- // alone. See crbug/273763 for more details.
- if (selEnd <= spanStart) getText().delete(spanStart, getText().length());
- }
- }
-
- @Override
- protected void onFocusChanged(boolean focused, int direction, Rect previouslyFocusedRect) {
- mFocused = focused;
- mUrlBarDelegate.onUrlPreFocusChanged(focused);
- if (!focused) mAutocompleteSpan.clearSpan();
- super.onFocusChanged(focused, direction, previouslyFocusedRect);
-
- if (focused && mFirstFocusTimeMs == 0) {
- mFirstFocusTimeMs = SystemClock.elapsedRealtime();
- if (mOmniboxLivenessListener != null) mOmniboxLivenessListener.onOmniboxFocused();
- }
- }
-
- /**
- * @return The elapsed realtime timestamp in ms of the first time the url bar was focused,
- * 0 if never.
- */
- public long getFirstFocusTime() {
- return mFirstFocusTimeMs;
- }
-
- @Override
- protected void onWindowVisibilityChanged(int visibility) {
- super.onWindowVisibilityChanged(visibility);
- if (visibility == View.GONE && isFocused()) mShowKeyboardOnWindowFocus = true;
- }
-
- @Override
- public void onWindowFocusChanged(boolean hasWindowFocus) {
- super.onWindowFocusChanged(hasWindowFocus);
- if (hasWindowFocus) {
- if (mShowKeyboardOnWindowFocus && isFocused()) {
- // Without the call to post(..), the keyboard was not getting shown when the
- // window regained focus despite this being the final call in the view system
- // flow.
- post(new Runnable() {
- @Override
- public void run() {
- UiUtils.showKeyboard(UrlBar.this);
- }
- });
- }
- mShowKeyboardOnWindowFocus = false;
- }
- }
-
- @Override
- public View focusSearch(int direction) {
- if (direction == View.FOCUS_BACKWARD
- && mUrlBarDelegate.getCurrentTab().getView() != null) {
- return mUrlBarDelegate.getCurrentTab().getView();
- } else {
- return super.focusSearch(direction);
- }
- }
-
- @Override
- public boolean onKeyPreIme(int keyCode, KeyEvent event) {
- if (keyCode == KeyEvent.KEYCODE_BACK) {
- if (event.getAction() == KeyEvent.ACTION_DOWN
- && event.getRepeatCount() == 0) {
- // Tell the framework to start tracking this event.
- getKeyDispatcherState().startTracking(event, this);
- return true;
- } else if (event.getAction() == KeyEvent.ACTION_UP) {
- getKeyDispatcherState().handleUpEvent(event);
- if (event.isTracking() && !event.isCanceled()) {
- mUrlBarDelegate.backKeyPressed();
- return true;
- }
- }
- }
- return super.onKeyPreIme(keyCode, event);
- }
-
- @Override
- public boolean onTouchEvent(MotionEvent event) {
- ChromeTab currentTab = mUrlBarDelegate.getCurrentTab();
- if (currentTab != null
- && currentTab.getBackgroundContentViewHelper() != null
- && mUrlBarDelegate.showingOriginalUrlForPreview()) {
- // When we are showing preview, we treat click on UrlBar as an event to force swapping
- // of content views.
- currentTab.getBackgroundContentViewHelper().forceSwappingContentViews();
- }
-
- if (!mFocused) {
- mGestureDetector.onTouchEvent(event);
- return true;
- }
-
- if (event.getAction() == MotionEvent.ACTION_DOWN && currentTab != null) {
- // Make sure to hide the current ContentView ActionBar.
- ContentViewCore viewCore = currentTab.getContentViewCore();
- if (viewCore != null) viewCore.hideSelectActionMode();
- }
-
- return super.onTouchEvent(event);
- }
-
- @Override
- public boolean bringPointIntoView(int offset) {
- if (mDisableTextScrollingFromAutocomplete) return false;
- return super.bringPointIntoView(offset);
- }
-
- @Override
- public boolean onPreDraw() {
- boolean retVal = super.onPreDraw();
- if (mDisableTextScrollingFromAutocomplete) {
- // super.onPreDraw will put the selection at the end of the text selection, but
- // in the case of autocomplete we want the last typed character to be shown, which
- // is the start of selection.
- mDisableTextScrollingFromAutocomplete = false;
- bringPointIntoView(getSelectionStart());
- retVal = true;
- }
- return retVal;
- }
-
- @Override
- public void onDraw(Canvas canvas) {
- super.onDraw(canvas);
-
- if (!mFirstDrawComplete) {
- mFirstDrawComplete = true;
-
- // We have now avoided the first draw problem (see the comment in
- // the constructor) so we want to make the URL bar focusable so that
- // touches etc. activate it.
- setFocusable(true);
- setFocusableInTouchMode(true);
-
- // The URL bar will now react correctly to a focus change event
- if (mOmniboxLivenessListener != null) mOmniboxLivenessListener.onOmniboxInteractive();
- }
-
- // Notify listeners if the URL's direction has changed.
- updateUrlDirection();
- }
-
- /**
- * If the direction of the URL has changed, update mUrlDirection and notify the
- * UrlDirectionListeners.
- */
- private void updateUrlDirection() {
- Layout layout = getLayout();
- if (layout == null) return;
-
- int urlDirection;
- if (length() == 0) {
- urlDirection = LAYOUT_DIRECTION_LOCALE;
- } else if (layout.getParagraphDirection(0) == Layout.DIR_LEFT_TO_RIGHT) {
- urlDirection = LAYOUT_DIRECTION_LTR;
- } else {
- urlDirection = LAYOUT_DIRECTION_RTL;
- }
-
- if (urlDirection != mUrlDirection) {
- mUrlDirection = urlDirection;
- if (mUrlDirectionListener != null) {
- mUrlDirectionListener.onUrlDirectionChanged(urlDirection);
- }
- }
- }
-
- /**
- * @return The text direction of the URL, e.g. LAYOUT_DIRECTION_LTR.
- */
- public int getUrlDirection() {
- return mUrlDirection;
- }
-
- /**
- * Sets the listener for changes in the url bar's layout direction. Also calls
- * onUrlDirectionChanged() immediately on the listener.
- *
- * @param listener The UrlDirectionListener to receive callbacks when the url direction changes,
- * or null to unregister any previously registered listener.
- */
- public void setUrlDirectionListener(UrlDirectionListener listener) {
- mUrlDirectionListener = listener;
- if (mUrlDirectionListener != null) {
- mUrlDirectionListener.onUrlDirectionChanged(mUrlDirection);
- }
- }
-
- void setLocationBarTextWatcher(TextWatcher locationBarTextWatcher) {
- mLocationBarTextWatcher = locationBarTextWatcher;
- }
-
- /**
- * Set the url delegate to handle communication from the {@link UrlBar} to the rest of the UI.
- * @param delegate The {@link UrlBarDelegate} to be used.
- */
- public void setDelegate(UrlBarDelegate delegate) {
- mUrlBarDelegate = delegate;
- }
-
- /**
- * Set {@link OmniboxLivenessListener} to be used for receiving interaction related messages
- * during startup.
- * @param listener The listener to use for sending the messages.
- */
- @VisibleForTesting
- public void setOmniboxLivenessListener(OmniboxLivenessListener listener) {
- mOmniboxLivenessListener = listener;
- }
-
- /**
- * Signal {@link OmniboxLivenessListener} that the omnibox is completely operational now.
- */
- @VisibleForTesting
- public void onOmniboxFullyFunctional() {
- if (mOmniboxLivenessListener != null) mOmniboxLivenessListener.onOmniboxFullyFunctional();
- }
-
- @Override
- public boolean onTextContextMenuItem(int id) {
- if (id == android.R.id.paste) {
- ClipboardManager clipboard = (ClipboardManager) getContext()
- .getSystemService(Context.CLIPBOARD_SERVICE);
- ClipData clipData = clipboard.getPrimaryClip();
- if (clipData != null) {
- StringBuilder builder = new StringBuilder();
- for (int i = 0; i < clipData.getItemCount(); i++) {
- builder.append(clipData.getItemAt(i).coerceToText(getContext()));
- }
- String pasteString = OmniboxViewUtil.sanitizeTextForPaste(builder.toString());
-
- int min = 0;
- int max = getText().length();
-
- if (isFocused()) {
- final int selStart = getSelectionStart();
- final int selEnd = getSelectionEnd();
-
- min = Math.max(0, Math.min(selStart, selEnd));
- max = Math.max(0, Math.max(selStart, selEnd));
- }
-
- Selection.setSelection(getText(), max);
- getText().replace(min, max, pasteString);
- return true;
- }
- }
-
- if (mOriginalUrlLocation == null || mFormattedUrlLocation == null) {
- return super.onTextContextMenuItem(id);
- }
-
- int selectedStartIndex = getSelectionStart();
- int selectedEndIndex = getSelectionEnd();
-
- // If we are copying/cutting the full previously formatted URL, reset the URL
- // text before initiating the TextViews handling of the context menu.
- String currentText = getText().toString();
- if (selectedStartIndex == 0
- && (id == android.R.id.cut || id == android.R.id.copy)
- && currentText.startsWith(mFormattedUrlLocation)
- && selectedEndIndex >= mFormattedUrlLocation.length()) {
- String newText = mOriginalUrlLocation
- + currentText.substring(mFormattedUrlLocation.length());
- selectedEndIndex = selectedEndIndex - mFormattedUrlLocation.length()
- + mOriginalUrlLocation.length();
- mUrlBarDelegate.setIgnoreURLBarModification(true);
- setText(newText);
- setSelection(0, selectedEndIndex);
- boolean retVal = super.onTextContextMenuItem(id);
- if (getText().toString().equals(newText)) {
- setText(currentText);
- setSelection(getText().length());
- }
- mUrlBarDelegate.setIgnoreURLBarModification(false);
- return retVal;
- }
- return super.onTextContextMenuItem(id);
- }
-
- /**
- * Sets the text content of the URL bar.
- *
- * @param url The original URL (or generic text) that can be used for copy/cut/paste.
- * @param formattedUrl Formatted URL for user display. Null if there isn't one.
- * @return Whether the visible text has changed.
- */
- public boolean setUrl(String url, String formattedUrl) {
- if (!TextUtils.isEmpty(formattedUrl)) {
- try {
- URL javaUrl = new URL(url);
- mFormattedUrlLocation =
- getUrlContentsPrePath(formattedUrl, javaUrl.getHost());
- mOriginalUrlLocation =
- getUrlContentsPrePath(url, javaUrl.getHost());
- } catch (MalformedURLException mue) {
- mOriginalUrlLocation = null;
- mFormattedUrlLocation = null;
- }
- } else {
- mOriginalUrlLocation = null;
- mFormattedUrlLocation = null;
- formattedUrl = url;
- }
-
- Editable previousText = getEditableText();
- setText(formattedUrl);
-
- if (!isFocused()) scrollToTLD();
-
- return !TextUtils.equals(previousText, getEditableText());
- }
-
- /**
- * Autocompletes the text on the url bar and selects the text that was not entered by the
- * user. Using append() instead of setText() to preserve the soft-keyboard layout.
- * @param userText user The text entered by the user.
- * @param inlineAutocompleteText The suggested autocompletion for the user's text.
- */
- public void setAutocompleteText(CharSequence userText, CharSequence inlineAutocompleteText) {
- boolean emptyAutocomplete = TextUtils.isEmpty(inlineAutocompleteText);
-
- if (!emptyAutocomplete) mDisableTextScrollingFromAutocomplete = true;
-
- int autocompleteIndex = userText.length();
-
- String previousText = getQueryText();
- CharSequence newText = TextUtils.concat(userText, inlineAutocompleteText);
-
- mUrlBarDelegate.setIgnoreURLBarModification(true);
- mDisableTextAccessibilityEvents = true;
-
- if (!TextUtils.equals(previousText, newText)) {
- // The previous text may also have included autocomplete text, so we only
- // append the new autocomplete text that has changed.
- if (TextUtils.indexOf(newText, previousText) == 0) {
- append(newText.subSequence(previousText.length(), newText.length()));
- } else {
- setUrl(newText.toString(), null);
- }
- }
-
- if (getSelectionStart() != autocompleteIndex
- || getSelectionEnd() != getText().length()) {
- setSelection(autocompleteIndex, getText().length());
-
- if (inlineAutocompleteText.length() != 0) {
- // Sending a TYPE_VIEW_TEXT_SELECTION_CHANGED accessibility event causes the
- // previous TYPE_VIEW_TEXT_CHANGED event to be swallowed. As a result the user
- // hears the autocomplete text but *not* the text they typed. Instead we send a
- // TYPE_ANNOUNCEMENT event, which doesn't swallow the text-changed event.
- announceForAccessibility(inlineAutocompleteText);
- }
- }
-
- if (emptyAutocomplete) {
- mAutocompleteSpan.clearSpan();
- } else {
- mAutocompleteSpan.setSpan(userText, inlineAutocompleteText);
- }
-
- mUrlBarDelegate.setIgnoreURLBarModification(false);
- mDisableTextAccessibilityEvents = false;
- }
-
- /**
- * Overrides the text announced when focusing on the field for accessibility. This value will
- * be cleared automatically when the text content changes for this view.
- * @param accessibilityOverride The text to be announced instead of the current text value
- * (or null if the text content should be read).
- */
- public void setAccessibilityTextOverride(String accessibilityOverride) {
- mAccessibilityTextOverride = accessibilityOverride;
- }
-
- private void scrollToTLD() {
- Editable url = getText();
- if (url == null || url.length() < 1) return;
- String urlString = url.toString();
- URL javaUrl;
- try {
- javaUrl = new URL(urlString);
- } catch (MalformedURLException mue) {
- return;
- }
- String host = javaUrl.getHost();
- if (host == null || host.isEmpty()) return;
- int hostStart = urlString.indexOf(host);
- int hostEnd = hostStart + host.length();
- setSelection(hostEnd);
- }
-
- @Override
- public void setText(CharSequence text, BufferType type) {
- mDisableTextScrollingFromAutocomplete = false;
-
- // Avoid setting the same text to the URL bar as it will mess up the scroll/cursor
- // position.
- // Setting the text is also quite expensive, so only do it when the text has changed
- // (since we apply spans when the URL is not focused, we only optimize this when the
- // URL is being edited).
- if (!TextUtils.equals(getEditableText(), text)) {
- super.setText(text, type);
- mAccessibilityTextOverride = null;
- }
-
- // Verify the autocomplete is still valid after the text change.
- if (mAutocompleteSpan != null
- && mAutocompleteSpan.mUserText != null
- && mAutocompleteSpan.mAutocompleteText != null) {
- if (getText().getSpanStart(mAutocompleteSpan) < 0) {
- mAutocompleteSpan.clearSpan();
- } else {
- Editable editableText = getEditableText();
- CharSequence previousUserText = mAutocompleteSpan.mUserText;
- CharSequence previousAutocompleteText = mAutocompleteSpan.mAutocompleteText;
- if (editableText.length()
- < (previousUserText.length() + previousAutocompleteText.length())) {
- mAutocompleteSpan.clearSpan();
- } else if (TextUtils.indexOf(getText(), previousUserText) != 0
- || TextUtils.indexOf(getText(), previousAutocompleteText)
- != previousUserText.length()) {
- mAutocompleteSpan.clearSpan();
- }
- }
- }
- }
-
- /**
- * Returns the portion of the URL that precedes the path/query section of the URL.
- *
- * @param url The url to be used to find the preceding portion.
- * @param host The host to be located in the URL to determine the location of the path.
- * @return The URL contents that precede the path (or the passed in URL if the host is
- * not found).
- */
- private static String getUrlContentsPrePath(String url, String host) {
- String urlPrePath = url;
- int hostIndex = url.indexOf(host);
- if (hostIndex >= 0) {
- int pathIndex = url.indexOf('/', hostIndex);
- if (pathIndex > 0) {
- urlPrePath = url.substring(0, pathIndex);
- } else {
- urlPrePath = url;
- }
- }
- return urlPrePath;
- }
-
- @Override
- public void sendAccessibilityEventUnchecked(AccessibilityEvent event) {
- if (mDisableTextAccessibilityEvents) {
- if (event.getEventType() == AccessibilityEvent.TYPE_VIEW_TEXT_SELECTION_CHANGED
- || event.getEventType() == AccessibilityEvent.TYPE_VIEW_TEXT_CHANGED) {
- return;
- }
- }
- super.sendAccessibilityEventUnchecked(event);
- }
-
- @Override
- public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) {
- super.onInitializeAccessibilityNodeInfo(info);
-
- if (mAccessibilityTextOverride != null) {
- info.setText(mAccessibilityTextOverride);
- }
- }
-
- @VisibleForTesting
- InputConnectionWrapper mInputConnection = new InputConnectionWrapper(null, true) {
- private final char[] mTempSelectionChar = new char[1];
-
- @Override
- public boolean commitText(CharSequence text, int newCursorPosition) {
- Editable currentText = getText();
- if (currentText == null) return super.commitText(text, newCursorPosition);
-
- int selectionStart = Selection.getSelectionStart(currentText);
- int selectionEnd = Selection.getSelectionEnd(currentText);
- int autocompleteIndex = currentText.getSpanStart(mAutocompleteSpan);
- // If the text being committed is a single character that matches the next character
- // in the selection (assumed to be the autocomplete text), we only move the text
- // selection instead clearing the autocomplete text causing flickering as the
- // autocomplete text will appear once the next suggestions are received.
- //
- // To be confident that the selection is an autocomplete, we ensure the selection
- // is at least one character and the end of the selection is the end of the
- // currently entered text.
- if (newCursorPosition == 1 && selectionStart > 0 && selectionStart != selectionEnd
- && selectionEnd >= currentText.length()
- && autocompleteIndex == selectionStart
- && text.length() == 1) {
- currentText.getChars(selectionStart, selectionStart + 1, mTempSelectionChar, 0);
- if (mTempSelectionChar[0] == text.charAt(0)) {
-
- // Since the text isn't changing, TalkBack won't read out the typed characters.
- // To work around this, explicitly send an accessibility event. crbug.com/416595
- if (mAccessibilityManager != null && mAccessibilityManager.isEnabled()) {
- AccessibilityEvent event = AccessibilityEvent.obtain(
- AccessibilityEvent.TYPE_VIEW_TEXT_CHANGED);
- event.setFromIndex(selectionStart);
- event.setRemovedCount(0);
- event.setAddedCount(1);
- event.setBeforeText(currentText.toString().substring(0, selectionStart));
- sendAccessibilityEventUnchecked(event);
- }
-
- if (mLocationBarTextWatcher != null) {
- mLocationBarTextWatcher.beforeTextChanged(currentText, 0, 0, 0);
- }
- setAutocompleteText(
- currentText.subSequence(0, selectionStart + 1),
- currentText.subSequence(selectionStart + 1, selectionEnd));
- if (mLocationBarTextWatcher != null) {
- mLocationBarTextWatcher.afterTextChanged(currentText);
- }
- return true;
- }
- }
- return super.commitText(text, newCursorPosition);
- }
-
- @Override
- public boolean setComposingText(CharSequence text, int newCursorPosition) {
- Editable currentText = getText();
- int autoCompleteSpanStart = currentText.getSpanStart(mAutocompleteSpan);
- if (autoCompleteSpanStart >= 0) {
- int composingEnd = BaseInputConnection.getComposingSpanEnd(currentText);
-
- // On certain device/keyboard combinations, the composing regions are specified
- // with a noticeable delay after the initial character is typed, and in certain
- // circumstances it does not check that the current state of the text matches the
- // expectations of it's composing region.
- // For example, you can be typing:
- // chrome://f
- // Chrome will autocomplete to:
- // chrome://f[lags]
- // And after the autocomplete has been set, the keyboard will set the composing
- // region to the last character and it assumes it is 'f' as it was the last
- // character the keyboard sent. If we commit this composition, the text will
- // look like:
- // chrome://flag[f]
- // And if we use the autocomplete clearing logic below, it will look like:
- // chrome://f[f]
- // To work around this, we see if the composition matches all the characters prior
- // to the autocomplete and just readjust the composing region to be that subset.
- //
- // See crbug.com/366732
- if (composingEnd == currentText.length()
- && autoCompleteSpanStart >= text.length()
- && TextUtils.equals(
- currentText.subSequence(
- autoCompleteSpanStart - text.length(),
- autoCompleteSpanStart),
- text)) {
- setComposingRegion(
- autoCompleteSpanStart - text.length(), autoCompleteSpanStart);
- }
-
- // Once composing text is being modified, the autocomplete text has been accepted
- // or has to be deleted.
- mAutocompleteSpan.clearSpan();
- Selection.setSelection(currentText, autoCompleteSpanStart);
- currentText.delete(autoCompleteSpanStart, currentText.length());
- }
- return super.setComposingText(text, newCursorPosition);
- }
- };
-
- @Override
- public InputConnection onCreateInputConnection(EditorInfo outAttrs) {
- mInputConnection.setTarget(super.onCreateInputConnection(outAttrs));
- return mInputConnection;
- }
-
- /**
- * Emphasize the TLD and second domain of the URL.
- */
- public void emphasizeUrl() {
- Editable url = getText();
- if (OmniboxUrlEmphasizer.hasEmphasisSpans(url) || hasFocus()) {
- return;
- }
-
- if (url.length() < 1) {
- return;
- }
-
- if (mUrlBarDelegate.showingOriginalUrlForPreview()) {
- // We will make the whole url as greyed out(Tailing url color). This is the UI
- // treatment we show to indicate that we are showing original url for preview page.
- OmniboxUrlEmphasizer.greyOutUrl(url, getResources(), mUseDarkColors);
- return;
- }
-
- // We retrieve the domain and registry from the full URL (the url bar shows a simplified
- // version of the URL).
- ChromeTab currentTab = mUrlBarDelegate.getCurrentTab();
- if (currentTab == null || currentTab.getProfile() == null) return;
-
- boolean isInternalPage = false;
- try {
- String tabUrl = currentTab.getUrl();
- isInternalPage = UrlUtilities.isInternalScheme(new URI(tabUrl));
- } catch (URISyntaxException e) {
- // Ignore as this only is for applying color
- }
-
- OmniboxUrlEmphasizer.emphasizeUrl(url, getResources(), currentTab.getProfile(),
- currentTab.getSecurityLevel(), isInternalPage,
- mUseDarkColors, mUrlBarDelegate.shouldEmphasizeHttpsScheme());
- }
-
- /**
- * Reset the modifications done to emphasize the TLD and second domain of the URL.
- */
- public void deEmphasizeUrl() {
- OmniboxUrlEmphasizer.deEmphasizeUrl(getText());
- }
-
- /**
- * Simple span used for tracking the current autocomplete state.
- */
- private class AutocompleteSpan {
- private CharSequence mUserText;
- private CharSequence mAutocompleteText;
-
- /**
- * Adds the span to the current text.
- * @param userText The user entered text.
- * @param autocompleteText The autocomplete text being appended.
- */
- public void setSpan(CharSequence userText, CharSequence autocompleteText) {
- Editable text = getText();
- text.removeSpan(this);
- mAutocompleteText = autocompleteText;
- mUserText = userText;
- text.setSpan(
- this,
- userText.length(),
- text.length(),
- Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
- }
-
- /** Removes this span from the current text and clears the internal state. */
- public void clearSpan() {
- getText().removeSpan(this);
- mAutocompleteText = null;
- mUserText = null;
- }
- }
-}

Powered by Google App Engine
This is Rietveld 408576698