summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorkristianm@chromium.org <kristianm@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-12-04 02:50:15 +0000
committerkristianm@chromium.org <kristianm@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-12-04 02:50:15 +0000
commitbe6fcc7020d8ce58a179b93869afaf2e71d82fdd (patch)
tree9ac3fe840cdc95ef5dc468fb25ed9719e12dcaaf
parenta188c82ea0c4f25d99ed445b0b36aac0d9cf9121 (diff)
downloadchromium_src-be6fcc7020d8ce58a179b93869afaf2e71d82fdd.zip
chromium_src-be6fcc7020d8ce58a179b93869afaf2e71d82fdd.tar.gz
chromium_src-be6fcc7020d8ce58a179b93869afaf2e71d82fdd.tar.bz2
Enable pasting HTML content from the Android clipboard
BUG=316717 Review URL: https://codereview.chromium.org/59023007 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@238530 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--base/android/java/src/org/chromium/base/ApiCompatibilityUtils.java7
-rw-r--r--ui/android/java/src/org/chromium/ui/base/Clipboard.java39
-rw-r--r--ui/base/clipboard/clipboard_android.cc51
-rw-r--r--ui/base/clipboard/clipboard_unittest.cc4
4 files changed, 63 insertions, 38 deletions
diff --git a/base/android/java/src/org/chromium/base/ApiCompatibilityUtils.java b/base/android/java/src/org/chromium/base/ApiCompatibilityUtils.java
index b902f93..26ec7b9 100644
--- a/base/android/java/src/org/chromium/base/ApiCompatibilityUtils.java
+++ b/base/android/java/src/org/chromium/base/ApiCompatibilityUtils.java
@@ -42,6 +42,13 @@ public class ApiCompatibilityUtils {
}
/**
+ * @return True if the running version of the Android supports HTML clipboard.
+ */
+ public static boolean isHTMLClipboardSupported() {
+ return Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN;
+ }
+
+ /**
* @see android.view.View#setLayoutDirection(int)
*/
public static void setLayoutDirection(View view, int layoutDirection) {
diff --git a/ui/android/java/src/org/chromium/ui/base/Clipboard.java b/ui/android/java/src/org/chromium/ui/base/Clipboard.java
index e62c84a..9e5cf61 100644
--- a/ui/android/java/src/org/chromium/ui/base/Clipboard.java
+++ b/ui/android/java/src/org/chromium/ui/base/Clipboard.java
@@ -4,6 +4,7 @@
package org.chromium.ui.base;
+import org.chromium.base.ApiCompatibilityUtils;
import org.chromium.base.CalledByNative;
import org.chromium.base.JNINamespace;
@@ -77,6 +78,23 @@ public class Clipboard {
}
/**
+ * Gets the HTML text of top item on the primary clip on the Android clipboard.
+ *
+ * @return a Java string with the html text if any, or null if there is no html
+ * text or no entries on the primary clip.
+ */
+ @CalledByNative
+ private String getHTMLText() {
+ if (isHTMLClipboardSupported()) {
+ final ClipData clip = mClipboardManager.getPrimaryClip();
+ if (clip != null && clip.getItemCount() > 0) {
+ return clip.getItemAt(0).getHtmlText();
+ }
+ }
+ return null;
+ }
+
+ /**
* Emulates the behavior of the now-deprecated
* {@link android.text.ClipboardManager#setText(CharSequence)}, setting the
* clipboard's current primary clip to a plain-text clip that consists of
@@ -100,29 +118,14 @@ public class Clipboard {
*/
@CalledByNative
private void setHTMLText(final String html, final String text) {
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
+ if (isHTMLClipboardSupported()) {
mClipboardManager.setPrimaryClip(
ClipData.newHtmlText(null, text, html));
}
}
- /**
- * Approximates the behavior of the now-deprecated
- * {@link android.text.ClipboardManager#hasText()}, returning true if and
- * only if the clipboard has a primary clip and that clip contains a plain
- * non-empty text entry (without attempting coercion - URLs and intents
- * will cause this method to return false).
- *
- * @return as described above
- */
- @SuppressWarnings("javadoc")
@CalledByNative
- private boolean hasPlainText() {
- final ClipData clip = mClipboardManager.getPrimaryClip();
- if (clip != null && clip.getItemCount() > 0) {
- final CharSequence text = clip.getItemAt(0).getText();
- return !TextUtils.isEmpty(text);
- }
- return false;
+ private static boolean isHTMLClipboardSupported() {
+ return ApiCompatibilityUtils.isHTMLClipboardSupported();
}
}
diff --git a/ui/base/clipboard/clipboard_android.cc b/ui/base/clipboard/clipboard_android.cc
index fc9ba00..f0971c4 100644
--- a/ui/base/clipboard/clipboard_android.cc
+++ b/ui/base/clipboard/clipboard_android.cc
@@ -129,39 +129,50 @@ void ClipboardMap::Clear() {
// If the internal map contains a plain-text entry and it does not match that
// in the Android clipboard, clear the map and insert the Android text into it.
+// If there is an HTML entry in the Android clipboard it gets inserted in the
+// map.
void ClipboardMap::SyncWithAndroidClipboard() {
lock_.AssertAcquired();
JNIEnv* env = AttachCurrentThread();
+ // Update the plain text clipboard entry
std::map<std::string, std::string>::const_iterator it =
map_.find(kPlainTextFormat);
-
- if (!Java_Clipboard_hasPlainText(env, clipboard_manager_.obj())) {
- if (it != map_.end())
+ ScopedJavaLocalRef<jstring> java_string_text =
+ Java_Clipboard_getCoercedText(env, clipboard_manager_.obj());
+ if (java_string_text.obj()) {
+ std::string android_string = ConvertJavaStringToUTF8(java_string_text);
+ if (!android_string.empty() &&
+ (it == map_.end() || it->second != android_string)) {
+ // There is a different string in the Android clipboard than we have.
+ // Clear the map on our side.
+ map_.clear();
+ map_[kPlainTextFormat] = android_string;
+ }
+ } else {
+ if (it != map_.end()) {
// We have plain text on this side, but Android doesn't. Nuke ours.
map_.clear();
- return;
+ }
}
- ScopedJavaLocalRef<jstring> java_string =
- Java_Clipboard_getCoercedText(env, clipboard_manager_.obj());
-
- if (!java_string.obj()) {
- // Tolerate a null value from the Java side, even though that should not
- // happen since hasPlainText has already returned true.
- // Should only happen if someone is using the clipboard on multiple
- // threads and clears it out after hasPlainText but before we get here...
- if (it != map_.end())
- // We have plain text on this side, but Android doesn't. Nuke ours.
- map_.clear();
+ if (!Java_Clipboard_isHTMLClipboardSupported(env)) {
return;
}
- // If Android text differs from ours (or we have none), then copy Android's.
- std::string android_string = ConvertJavaStringToUTF8(java_string);
- if (it == map_.end() || it->second != android_string) {
- map_.clear();
- map_[kPlainTextFormat] = android_string;
+ // Update the html clipboard entry
+ ScopedJavaLocalRef<jstring> java_string_html =
+ Java_Clipboard_getHTMLText(env, clipboard_manager_.obj());
+ if (java_string_html.obj()) {
+ std::string android_string = ConvertJavaStringToUTF8(java_string_html);
+ if (!android_string.empty()) {
+ map_[kHTMLFormat] = android_string;
+ return;
+ }
+ }
+ it = map_.find(kHTMLFormat);
+ if (it != map_.end()) {
+ map_.erase(kHTMLFormat);
}
}
diff --git a/ui/base/clipboard/clipboard_unittest.cc b/ui/base/clipboard/clipboard_unittest.cc
index c423e41..d3aa530 100644
--- a/ui/base/clipboard/clipboard_unittest.cc
+++ b/ui/base/clipboard/clipboard_unittest.cc
@@ -89,11 +89,13 @@ TEST_F(ClipboardTest, TextTest) {
TEST_F(ClipboardTest, HTMLTest) {
string16 markup(ASCIIToUTF16("<string>Hi!</string>")), markup_result;
+ string16 plain(ASCIIToUTF16("Hi!")), plain_result;
std::string url("http://www.example.com/"), url_result;
{
ScopedClipboardWriter clipboard_writer(&clipboard(),
CLIPBOARD_TYPE_COPY_PASTE);
+ clipboard_writer.WriteText(plain);
clipboard_writer.WriteHTML(markup, url);
}
@@ -175,10 +177,12 @@ TEST_F(ClipboardTest, TrickyHTMLTest) {
string16 markup(ASCIIToUTF16("<em>Bye!<!--EndFragment --></em>")),
markup_result;
std::string url, url_result;
+ string16 plain(ASCIIToUTF16("Bye!")), plain_result;
{
ScopedClipboardWriter clipboard_writer(&clipboard(),
CLIPBOARD_TYPE_COPY_PASTE);
+ clipboard_writer.WriteText(plain);
clipboard_writer.WriteHTML(markup, url);
}