зеркало из https://github.com/mozilla/gecko-dev.git
Backed out changeset bb2acd046eae (bug 1497580) for clipboard failures on test_clipboard_events.html. CLOSED TREE
This commit is contained in:
Родитель
517c9916eb
Коммит
0b8074bdd7
|
@ -34,16 +34,12 @@
|
||||||
|
|
||||||
#include "mozilla/Encoding.h"
|
#include "mozilla/Encoding.h"
|
||||||
|
|
||||||
|
|
||||||
using namespace mozilla;
|
using namespace mozilla;
|
||||||
|
|
||||||
// Idle timeout for receiving selection and property notify events (microsec)
|
// Idle timeout for receiving selection and property notify events (microsec)
|
||||||
const int kClipboardTimeout = 500000;
|
const int kClipboardTimeout = 500000;
|
||||||
|
|
||||||
// We add this prefix to HTML markup, so that GetHTMLCharset can correctly
|
|
||||||
// detect the HTML as UTF-8 encoded.
|
|
||||||
static const char kHTMLMarkupPrefix[] =
|
|
||||||
R"(<meta http-equiv="content-type" content="text/html; charset=utf-8">)";
|
|
||||||
|
|
||||||
// Callback when someone asks us for the data
|
// Callback when someone asks us for the data
|
||||||
void
|
void
|
||||||
clipboard_get_cb(GtkClipboard *aGtkClipboard,
|
clipboard_get_cb(GtkClipboard *aGtkClipboard,
|
||||||
|
@ -531,31 +527,6 @@ nsClipboard::SelectionGetEvent(GtkClipboard *aClipboard,
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (selectionTarget == gdk_atom_intern(kHTMLMime, FALSE)) {
|
|
||||||
rv = trans->GetTransferData(kHTMLMime, getter_AddRefs(item), &len);
|
|
||||||
if (!item || NS_FAILED(rv)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
nsCOMPtr<nsISupportsString> wideString;
|
|
||||||
wideString = do_QueryInterface(item);
|
|
||||||
if (!wideString) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
nsAutoString ucs2string;
|
|
||||||
wideString->GetData(ucs2string);
|
|
||||||
|
|
||||||
nsAutoCString html;
|
|
||||||
// Add the prefix so the encoding is correctly detected.
|
|
||||||
html.AppendLiteral(kHTMLMarkupPrefix);
|
|
||||||
AppendUTF16toUTF8(ucs2string, html);
|
|
||||||
|
|
||||||
gtk_selection_data_set(aSelectionData, selectionTarget, 8,
|
|
||||||
(const guchar*)html.get(), html.Length());
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Try to match up the selection data target to something our
|
// Try to match up the selection data target to something our
|
||||||
// transferable provides.
|
// transferable provides.
|
||||||
gchar *target_name = gdk_atom_name(selectionTarget);
|
gchar *target_name = gdk_atom_name(selectionTarget);
|
||||||
|
@ -574,10 +545,31 @@ nsClipboard::SelectionGetEvent(GtkClipboard *aClipboard,
|
||||||
item, &primitive_data, len);
|
item, &primitive_data, len);
|
||||||
|
|
||||||
if (primitive_data) {
|
if (primitive_data) {
|
||||||
|
// Check to see if the selection data is text/html
|
||||||
|
if (selectionTarget == gdk_atom_intern (kHTMLMime, FALSE)) {
|
||||||
|
/*
|
||||||
|
* "text/html" can be encoded UCS2. It is recommended that
|
||||||
|
* documents transmitted as UCS2 always begin with a ZERO-WIDTH
|
||||||
|
* NON-BREAKING SPACE character (hexadecimal FEFF, also called
|
||||||
|
* Byte Order Mark (BOM)). Adding BOM can help other app to
|
||||||
|
* detect mozilla use UCS2 encoding when copy-paste.
|
||||||
|
*/
|
||||||
|
guchar *buffer = (guchar *)
|
||||||
|
g_malloc((len * sizeof(guchar)) + sizeof(char16_t));
|
||||||
|
if (!buffer)
|
||||||
|
return;
|
||||||
|
char16_t prefix = 0xFEFF;
|
||||||
|
memcpy(buffer, &prefix, sizeof(prefix));
|
||||||
|
memcpy(buffer + sizeof(prefix), primitive_data, len);
|
||||||
|
g_free((guchar *)primitive_data);
|
||||||
|
primitive_data = (guchar *)buffer;
|
||||||
|
len += sizeof(prefix);
|
||||||
|
}
|
||||||
|
|
||||||
gtk_selection_data_set(aSelectionData, selectionTarget,
|
gtk_selection_data_set(aSelectionData, selectionTarget,
|
||||||
8, /* 8 bits in a unit */
|
8, /* 8 bits in a unit */
|
||||||
(const guchar *)primitive_data, len);
|
(const guchar *)primitive_data, len);
|
||||||
free(primitive_data);
|
g_free(primitive_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
g_free(target_name);
|
g_free(target_name);
|
||||||
|
@ -664,19 +656,8 @@ void ConvertHTMLtoUCS2(const char* data, int32_t dataLength,
|
||||||
outUnicodeLen = 0;
|
outUnicodeLen = 0;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto dataSpan = MakeSpan(data, dataLength);
|
|
||||||
// Remove kHTMLMarkupPrefix again, it won't necessarily cause any
|
|
||||||
// issues, but might confuse other users.
|
|
||||||
const size_t prefixLen = ArrayLength(kHTMLMarkupPrefix) - 1;
|
|
||||||
if (dataSpan.Length() >= prefixLen &&
|
|
||||||
!strncmp(data, kHTMLMarkupPrefix, prefixLen)) {
|
|
||||||
dataSpan = dataSpan.From(prefixLen);
|
|
||||||
}
|
|
||||||
|
|
||||||
auto decoder = encoding->NewDecoder();
|
auto decoder = encoding->NewDecoder();
|
||||||
CheckedInt<size_t> needed =
|
CheckedInt<size_t> needed = decoder->MaxUTF16BufferLength(dataLength);
|
||||||
decoder->MaxUTF16BufferLength(dataSpan.Length());
|
|
||||||
if (!needed.isValid() || needed.value() > INT32_MAX) {
|
if (!needed.isValid() || needed.value() > INT32_MAX) {
|
||||||
outUnicodeLen = 0;
|
outUnicodeLen = 0;
|
||||||
return;
|
return;
|
||||||
|
@ -691,13 +672,17 @@ void ConvertHTMLtoUCS2(const char* data, int32_t dataLength,
|
||||||
size_t written;
|
size_t written;
|
||||||
bool hadErrors;
|
bool hadErrors;
|
||||||
Tie(result, read, written, hadErrors) =
|
Tie(result, read, written, hadErrors) =
|
||||||
decoder->DecodeToUTF16(AsBytes(dataSpan),
|
decoder->DecodeToUTF16(AsBytes(MakeSpan(data, dataLength)),
|
||||||
MakeSpan(*unicodeData, needed.value()),
|
MakeSpan(*unicodeData, needed.value()),
|
||||||
true);
|
true);
|
||||||
MOZ_ASSERT(result == kInputEmpty);
|
MOZ_ASSERT(result == kInputEmpty);
|
||||||
MOZ_ASSERT(read == size_t(dataSpan.Length()));
|
MOZ_ASSERT(read == size_t(dataLength));
|
||||||
MOZ_ASSERT(written <= needed.value());
|
MOZ_ASSERT(written <= needed.value());
|
||||||
Unused << hadErrors;
|
Unused << hadErrors;
|
||||||
|
#ifdef DEBUG_CLIPBOARD
|
||||||
|
if (read != dataLength)
|
||||||
|
printf("didn't consume all the bytes\n");
|
||||||
|
#endif
|
||||||
outUnicodeLen = written;
|
outUnicodeLen = written;
|
||||||
// null terminate.
|
// null terminate.
|
||||||
(*unicodeData)[outUnicodeLen] = '\0';
|
(*unicodeData)[outUnicodeLen] = '\0';
|
||||||
|
|
Загрузка…
Ссылка в новой задаче