blob: e463d8fe9b20d7df1d92ad26cfbe715775fcb116 [file] [log] [blame]
// Copyright 2017 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.content.browser.input;
import android.content.Context;
import android.text.SpannableString;
import android.text.Spanned;
import android.text.style.TextAppearanceSpan;
import android.view.View;
import org.chromium.content.R;
import org.chromium.content.browser.WindowAndroidProvider;
/**
* A subclass of SuggestionsPopupWindow to be used for showing suggestions from one or more
* SuggestionSpans.
*/
public class TextSuggestionsPopupWindow extends SuggestionsPopupWindow {
private SuggestionInfo[] mSuggestionInfos;
private TextAppearanceSpan mPrefixSpan;
private TextAppearanceSpan mSuffixSpan;
/**
* @param context Android context to use.
* @param textSuggestionHost TextSuggestionHost instance (used to communicate with Blink).
* @param parentView The view used to attach the PopupWindow.
* @param windowAndroidProvider A WindowAndroidProvider instance used to get the window size.
*/
public TextSuggestionsPopupWindow(Context context, TextSuggestionHost textSuggestionHost,
View parentView, WindowAndroidProvider windowAndroidProvider) {
super(context, textSuggestionHost, parentView, windowAndroidProvider);
mPrefixSpan = new TextAppearanceSpan(context, R.style.SuggestionPrefixOrSuffix);
mSuffixSpan = new TextAppearanceSpan(context, R.style.SuggestionPrefixOrSuffix);
}
/**
* Shows the text suggestion menu at the specified coordinates (relative to the viewport).
*/
public void show(double caretX, double caretY, String highlightedText,
SuggestionInfo[] suggestionInfos) {
mSuggestionInfos = suggestionInfos.clone();
// Android's Editor.java shows the "Add to dictonary" button if and only if there's a
// SuggestionSpan with FLAG_MISSPELLED set. However, some OEMs (e.g. Samsung) appear to
// change the behavior on their devices to never show this button, since their IMEs don't go
// through the normal spell-checking API and instead add SuggestionSpans directly. Since
// it's difficult to determine how the OEM has set up the native menu, we instead only show
// the "Add to dictionary" button for spelling markers added by Chrome from running the
// system spell checker. SuggestionSpans with FLAG_MISSPELLED set (i.e., a spelling
// underline added directly by the IME) do not show this button.
setAddToDictionaryEnabled(false);
super.show(caretX, caretY, highlightedText);
}
@Override
protected int getSuggestionsCount() {
return mSuggestionInfos.length;
}
@Override
protected Object getSuggestionItem(int position) {
return mSuggestionInfos[position];
}
@Override
protected SpannableString getSuggestionText(int position) {
final SuggestionInfo suggestionInfo = mSuggestionInfos[position];
SpannableString suggestionText = new SpannableString(suggestionInfo.getPrefix()
+ suggestionInfo.getSuggestion() + suggestionInfo.getSuffix());
// Gray out prefix text (if any).
suggestionText.setSpan(mPrefixSpan, 0, suggestionInfo.getPrefix().length(),
Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
// Gray out suffix text (if any).
suggestionText.setSpan(mSuffixSpan,
suggestionInfo.getPrefix().length() + suggestionInfo.getSuggestion().length(),
suggestionInfo.getPrefix().length() + suggestionInfo.getSuggestion().length()
+ suggestionInfo.getSuffix().length(),
Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
return suggestionText;
}
@Override
protected void applySuggestion(int position) {
SuggestionInfo info = mSuggestionInfos[position];
mTextSuggestionHost.applyTextSuggestion(info.getMarkerTag(), info.getSuggestionIndex());
}
}