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..286f8ef9bb8f05557e58062f63f9b3851300990a 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,40 @@ public class SelectionPopupController extends ActionModeCallbackHelper { |
return clipMgr.hasPrimaryClip(); |
} |
+ // TODO(ctzsm): Remove this method after Android API is updated |
aelias_OOO_until_Jul13
2017/05/01 23:25:41
In reality, we will have to always keep this metho
aelias_OOO_until_Jul13
2017/05/01 23:25:41
The likely reality is that we'll keep this code fo
Shimi Zhang
2017/05/02 00:17:45
Done.
Shimi Zhang
2017/05/02 00:17:46
Done.
|
+ // 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; |
+ 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; |
+ } |
+ 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 +749,14 @@ public class SelectionPopupController extends ActionModeCallbackHelper { |
} |
/** |
+ * Perform a paste as plain text action. |
+ */ |
+ @VisibleForTesting |
+ void pasteAsPlainText() { |
+ mWebContents.pasteAsPlainText(); |
+ } |
+ |
+ /** |
* Perform a share action. |
*/ |
@VisibleForTesting |