Chromium Code Reviews| Index: content/public/android/java/src/org/chromium/content/browser/SelectionPopupController.java |
| diff --git a/content/public/android/java/src/org/chromium/content/browser/SelectionPopupController.java b/content/public/android/java/src/org/chromium/content/browser/SelectionPopupController.java |
| index df436286db9f02491051f09dbb0e97f44afb2607..e840629f8e3fd511287e0ca62d1c6fc10b889e80 100644 |
| --- a/content/public/android/java/src/org/chromium/content/browser/SelectionPopupController.java |
| +++ b/content/public/android/java/src/org/chromium/content/browser/SelectionPopupController.java |
| @@ -7,6 +7,8 @@ package org.chromium.content.browser; |
| import android.annotation.TargetApi; |
| import android.app.Activity; |
| import android.app.SearchManager; |
| +import android.content.ClipData; |
| +import android.content.ClipDescription; |
| import android.content.ClipboardManager; |
| import android.content.Context; |
| import android.content.Intent; |
| @@ -16,7 +18,11 @@ import android.content.res.Resources; |
| import android.graphics.Rect; |
| import android.os.Build; |
| import android.provider.Browser; |
| +import android.text.Spanned; |
| import android.text.TextUtils; |
| +import android.text.style.CharacterStyle; |
| +import android.text.style.ParagraphStyle; |
| +import android.text.style.UpdateAppearance; |
| import android.view.ActionMode; |
| import android.view.Menu; |
| import android.view.MenuInflater; |
| @@ -107,6 +113,7 @@ public class SelectionPopupController extends ActionModeCallbackHelper { |
| private boolean mIsPasswordType; |
| private boolean mIsInsertion; |
| private boolean mCanSelectAllForPastePopup; |
| + private boolean mCanEditRichlyForPastePopup; |
| private boolean mUnselectAllOnDismiss; |
| private String mLastSelectedText; |
| @@ -261,7 +268,7 @@ public class SelectionPopupController extends ActionModeCallbackHelper { |
| return actionMode; |
| } |
| - void createAndShowPastePopup(int x, int y, boolean canSelectAll) { |
| + void createAndShowPastePopup(int x, int y, boolean canSelectAll, boolean canEditRichly) { |
| if (mView.getParent() == null || mView.getVisibility() != View.VISIBLE) { |
| return; |
| } |
| @@ -269,6 +276,7 @@ public class SelectionPopupController extends ActionModeCallbackHelper { |
| if (!supportsFloatingActionMode() && !canPaste()) return; |
| destroyPastePopup(); |
| mCanSelectAllForPastePopup = canSelectAll; |
| + mCanEditRichlyForPastePopup = canEditRichly; |
| PastePopupMenuDelegate delegate = new PastePopupMenuDelegate() { |
| @Override |
| public void paste() { |
| @@ -277,6 +285,12 @@ public class SelectionPopupController extends ActionModeCallbackHelper { |
| } |
| @Override |
| + public void pasteAsPlainText() { |
| + mWebContents.pasteAsPlainText(); |
| + mWebContents.dismissTextHandles(); |
| + } |
| + |
| + @Override |
| public boolean canPaste() { |
| return SelectionPopupController.this.canPaste(); |
| } |
| @@ -290,6 +304,11 @@ public class SelectionPopupController extends ActionModeCallbackHelper { |
| public boolean canSelectAll() { |
| return SelectionPopupController.this.canSelectAll(); |
| } |
| + |
| + @Override |
| + public boolean canPasteAsPlainText() { |
| + return SelectionPopupController.this.canPasteAsPlainText(); |
| + } |
| }; |
| Context windowContext = mWindowAndroid.getContext().get(); |
| if (windowContext == null) return; |
| @@ -509,6 +528,39 @@ public class SelectionPopupController extends ActionModeCallbackHelper { |
| return clipMgr.hasPrimaryClip(); |
| } |
| + // Only check those classes affect appearance. |
| + private boolean hasStyleSpan(Spanned spanned) { |
| + Class<?>[] styleClasses = { |
| + CharacterStyle.class, ParagraphStyle.class, UpdateAppearance.class}; |
| + for (Class<?> clazz : styleClasses) { |
| + if (spanned.nextSpanTransition(-1, spanned.length(), clazz) < spanned.length()) { |
| + return true; |
| + } |
| + } |
| + return false; |
| + } |
| + |
| + // if need to show paste as plain text. |
| + @VisibleForTesting |
| + public boolean canPasteAsPlainText() { |
| + if (!BuildInfo.isAtLeastO()) return false; |
|
boliu
2017/05/02 17:31:57
comment explaining why this is O only
Shimi Zhang
2017/05/03 00:37:17
Done.
|
| + if (!mCanEditRichlyForPastePopup) return false; |
| + ClipboardManager clipMgr = |
| + (ClipboardManager) mContext.getSystemService(Context.CLIPBOARD_SERVICE); |
| + if (!clipMgr.hasPrimaryClip()) return false; |
| + |
| + // In case that plain text is a Spanned. |
| + ClipData clipData = clipMgr.getPrimaryClip(); |
| + ClipDescription description = clipData.getDescription(); |
| + CharSequence text = clipData.getItemAt(0).getText(); |
| + boolean isPlainType = description.hasMimeType(ClipDescription.MIMETYPE_TEXT_PLAIN); |
| + if (isPlainType && (text instanceof Spanned)) { |
| + Spanned spanned = (Spanned) text; |
| + if (hasStyleSpan(spanned)) return true; |
|
boliu
2017/05/02 17:31:57
can you explain this check? android APIs docs are
Shimi Zhang
2017/05/03 00:37:17
Per a discussion with TextView developer, those th
boliu
2017/05/03 00:44:44
This basically needs a comment explaining to some
|
| + } |
| + return description.hasMimeType(ClipDescription.MIMETYPE_TEXT_HTML); |
| + } |
| + |
| private void updateAssistMenuItem(MenuDescriptor descriptor) { |
| // There is no Assist functionality before Android O. |
| if (!BuildInfo.isAtLeastO() || mAssistMenuItemId == 0) return; |
| @@ -696,6 +748,14 @@ public class SelectionPopupController extends ActionModeCallbackHelper { |
| } |
| /** |
| + * Perform a paste as plain text action. |
| + */ |
| + @VisibleForTesting |
| + void pasteAsPlainText() { |
| + mWebContents.pasteAsPlainText(); |
| + } |
| + |
| + /** |
| * Perform a share action. |
| */ |
| @VisibleForTesting |