diff options
Diffstat (limited to 'src/core/clipboard_qt.cpp')
-rw-r--r-- | src/core/clipboard_qt.cpp | 103 |
1 files changed, 59 insertions, 44 deletions
diff --git a/src/core/clipboard_qt.cpp b/src/core/clipboard_qt.cpp index 69690dd99..3f49c6e3c 100644 --- a/src/core/clipboard_qt.cpp +++ b/src/core/clipboard_qt.cpp @@ -12,6 +12,7 @@ #include "base/logging.h" #include "base/strings/utf_offset_string_conversions.h" #include "base/strings/utf_string_conversions.h" +#include "base/types/variant_util.h" #include "third_party/skia/include/core/SkBitmap.h" #include "ui/base/clipboard/custom_data_helper.h" #include "ui/base/clipboard/clipboard.h" @@ -27,6 +28,8 @@ #include <QImageWriter> #include <QMimeData> +#include <memory> + namespace QtWebEngineCore { static void registerMetaTypes() @@ -60,12 +63,12 @@ using namespace QtWebEngineCore; namespace { -QScopedPointer<QMimeData> uncommittedData; +std::unique_ptr<QMimeData> uncommittedData; QMimeData *getUncommittedData() { if (!uncommittedData) uncommittedData.reset(new QMimeData); - return uncommittedData.data(); + return uncommittedData.get(); } } // namespace @@ -96,24 +99,23 @@ void ClipboardQt::WritePortableAndPlatformRepresentations(ui::ClipboardBuffer ty DCHECK(CalledOnValidThread()); DCHECK(IsSupportedClipboardBuffer(type)); - for (const auto &object : objects) - DispatchPortableRepresentation(object.first, object.second); - if (!platform_representations.empty()) DispatchPlatformRepresentations(std::move(platform_representations)); + for (const auto &object : objects) + DispatchPortableRepresentation(object.second); // Commit the accumulated data. if (uncommittedData) - QGuiApplication::clipboard()->setMimeData(uncommittedData.take(), + QGuiApplication::clipboard()->setMimeData(uncommittedData.release(), type == ui::ClipboardBuffer::kCopyPaste ? QClipboard::Clipboard : QClipboard::Selection); if (type == ui::ClipboardBuffer::kCopyPaste && IsSupportedClipboardBuffer(ui::ClipboardBuffer::kSelection)) { - ObjectMap::const_iterator text_iter = objects.find(PortableFormat::kText); + auto text_iter = objects.find(base::VariantIndexOfType<Data, TextData>()); if (text_iter != objects.end()) { // Copy text and SourceTag to the selection clipboard. WritePortableAndPlatformRepresentations(ui::ClipboardBuffer::kSelection, - ObjectMap(text_iter, text_iter + 1), + ObjectMap(text_iter, ++text_iter), {}, nullptr); } @@ -121,14 +123,14 @@ void ClipboardQt::WritePortableAndPlatformRepresentations(ui::ClipboardBuffer ty m_dataSrc[type] = std::move(data_src); } -void ClipboardQt::WriteText(const char *text_data, size_t text_len) +void ClipboardQt::WriteText(base::StringPiece text) { - getUncommittedData()->setText(QString::fromUtf8(text_data, text_len)); + getUncommittedData()->setText(toQString(text)); } -void ClipboardQt::WriteHTML(const char *markup_data, size_t markup_len, const char *url_data, size_t url_len) +void ClipboardQt::WriteHTML(base::StringPiece markup, absl::optional<base::StringPiece> source_url) { - QString markup_string = QString::fromUtf8(markup_data, markup_len); + QString markup_string = toQString(markup); #if defined (Q_OS_MACOS) // We need to prepend the charset on macOS to prevent garbled Unicode characters // when pasting to certain applications (e.g. Notes, TextEdit) @@ -139,11 +141,11 @@ void ClipboardQt::WriteHTML(const char *markup_data, size_t markup_len, const ch #if !defined(Q_OS_WIN) getUncommittedData()->setHtml(markup_string); #else - std::string url; - if (url_len > 0) - url.assign(url_data, url_len); + QString url; + if (source_url) + url = toQString(*source_url); - std::string cf_html = HtmlToCFHtml(markup_string.toStdString(), url); + std::string cf_html = HtmlToCFHtml(markup_string.toStdString(), url.toStdString()); size_t html_start = std::string::npos; size_t fragment_start = std::string::npos; size_t fragment_end = std::string::npos; @@ -157,9 +159,9 @@ void ClipboardQt::WriteHTML(const char *markup_data, size_t markup_len, const ch #endif // !defined(Q_OS_WIN) } -void ClipboardQt::WriteRTF(const char *rtf_data, size_t data_len) +void ClipboardQt::WriteRTF(base::StringPiece rtf) { - getUncommittedData()->setData(QString::fromLatin1(ui::kMimeTypeRTF), QByteArray(rtf_data, data_len)); + getUncommittedData()->setData(QString::fromLatin1(ui::kMimeTypeRTF), toQByteArray(rtf)); } void ClipboardQt::WriteWebSmartPaste() @@ -172,12 +174,12 @@ void ClipboardQt::WriteBitmap(const SkBitmap &bitmap) getUncommittedData()->setImageData(toQImage(bitmap).copy()); } -void ClipboardQt::WriteBookmark(const char *title_data, size_t title_len, const char *url_data, size_t url_len) +void ClipboardQt::WriteBookmark(base::StringPiece title_in, base::StringPiece url_in) { // FIXME: Untested, seems to be used only for drag-n-drop. // Write as a mozilla url (UTF16: URL, newline, title). - QString url = QString::fromUtf8(url_data, url_len); - QString title = QString::fromUtf8(title_data, title_len); + QString url = toQString(url_in); + QString title = toQString(title_in); QByteArray data; data.append(reinterpret_cast<const char *>(url.utf16()), url.size() * 2); @@ -186,9 +188,9 @@ void ClipboardQt::WriteBookmark(const char *title_data, size_t title_len, const getUncommittedData()->setData(QString::fromLatin1(ui::kMimeTypeMozillaURL), data); } -void ClipboardQt::WriteData(const ui::ClipboardFormatType &format, const char *data_data, size_t data_len) +void ClipboardQt::WriteData(const ui::ClipboardFormatType &format, base::span<const uint8_t> data) { - getUncommittedData()->setData(QString::fromStdString(format.GetName()), QByteArray(data_data, data_len)); + getUncommittedData()->setData(QString::fromStdString(format.GetName()), QByteArray((const char *)data.data(), data.size())); } bool ClipboardQt::IsFormatAvailable(const ui::ClipboardFormatType &format, @@ -198,9 +200,11 @@ bool ClipboardQt::IsFormatAvailable(const ui::ClipboardFormatType &format, const QMimeData *mimeData = QGuiApplication::clipboard()->mimeData( type == ui::ClipboardBuffer::kCopyPaste ? QClipboard::Clipboard : QClipboard::Selection); - if (format == ui::ClipboardFormatType::BitmapType()) - return mimeData && mimeData->hasImage(); - return mimeData && mimeData->hasFormat(QString::fromStdString(format.GetName())); + if (!mimeData) + return false; + if (format == ui::ClipboardFormatType::PngType()) + return mimeData->hasImage(); + return mimeData->hasFormat(QString::fromStdString(format.GetName())); } void ClipboardQt::Clear(ui::ClipboardBuffer type) @@ -224,18 +228,13 @@ void ClipboardQt::ReadAvailableTypes(ui::ClipboardBuffer type, type == ui::ClipboardBuffer::kCopyPaste ? QClipboard::Clipboard : QClipboard::Selection); if (!mimeData) return; - if (mimeData->hasImage() && !mimeData->formats().contains(QStringLiteral("image/png"))) - types->push_back(toString16(QStringLiteral("image/png"))); - const QStringList formats = mimeData->formats(); - for (const QString &mimeType : formats) { - // Special handling for chromium/x-web-custom-data. We must read the data - // and deserialize it to find the list of mime types to report. - if (mimeType == QString::fromLatin1(ui::kMimeTypeWebCustomData)) { - const QByteArray customData = mimeData->data(QString::fromLatin1(ui::kMimeTypeWebCustomData)); - ui::ReadCustomDataTypes(customData.constData(), customData.size(), types); - } else { - types->push_back(toString16(mimeType)); - } + + for (const auto& mime_type : GetStandardFormats(type, data_dst)) + types->push_back(mime_type); + + if (mimeData->hasFormat(QString::fromLatin1(ui::kMimeTypeWebCustomData))) { + const QByteArray customData = mimeData->data(QString::fromLatin1(ui::kMimeTypeWebCustomData)); + ui::ReadCustomDataTypes(customData.constData(), customData.size(), types); } } @@ -364,10 +363,10 @@ void ClipboardQt::ReadSvg(ui::ClipboardBuffer clipboard_type, *result = toString16(QString::fromUtf8(svgData)); } -void ClipboardQt::WriteSvg(const char *svg_data, size_t data_len) +void ClipboardQt::WriteSvg(base::StringPiece markup) { getUncommittedData()->setData(QString::fromLatin1(ui::kMimeTypeSvg), - QByteArray(svg_data, data_len)); + toQByteArray(markup)); } void ClipboardQt::ReadData(const ui::ClipboardFormatType &format, @@ -421,6 +420,11 @@ void ClipboardQt::WriteFilenames(std::vector<ui::FileInfo> filenames) getUncommittedData()->setUrls(urls); } +void ClipboardQt::WriteUnsanitizedHTML(base::StringPiece markup, absl::optional<base::StringPiece> source_url) +{ + WriteHTML(std::move(markup), std::move(source_url)); +} + #if defined(USE_OZONE) bool ClipboardQt::IsSelectionBufferAvailable() const { @@ -438,12 +442,23 @@ std::vector<std::u16string> ClipboardQt::GetStandardFormats(ui::ClipboardBuffer return {}; std::vector<std::u16string> types; + if (mimeData->hasImage()) + types.push_back(base::UTF8ToUTF16(ui::kMimeTypePNG)); + if (mimeData->hasHtml()) + types.push_back(base::UTF8ToUTF16(ui::kMimeTypeHTML)); + if (mimeData->hasText()) + types.push_back(base::UTF8ToUTF16(ui::kMimeTypeText)); + if (mimeData->hasUrls()) + types.push_back(base::UTF8ToUTF16(ui::kMimeTypeURIList)); const QStringList formats = mimeData->formats(); - if (mimeData->hasImage() && !formats.contains(QStringLiteral("image/png"))) - types.push_back(toString16(QStringLiteral("image/png"))); for (const QString &mimeType : formats) { - if (mimeType != QString::fromLatin1(ui::kMimeTypeWebCustomData)) - types.push_back(toString16(mimeType)); + auto mime_type = mimeType.toStdString(); + // Only add white-listed formats here + if (mime_type == ui::ClipboardFormatType::SvgType().GetName() || + mime_type == ui::ClipboardFormatType::RtfType().GetName()) { + types.push_back(base::UTF8ToUTF16(mime_type)); + continue; + } } return types; } |