blob: 6aa47317560a8141a9c35af4bd25bb7d83aa82fd [file] [log] [blame]
Henrique Ferreiro0bb413bf2020-09-17 13:37:541// Copyright 2020 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "content/browser/renderer_host/drop_data_util.h"
6
7#include <string>
8#include <utility>
9#include <vector>
10
11#include "base/files/file_path.h"
12#include "base/strings/utf_string_conversions.h"
13#include "content/browser/native_file_system/native_file_system_manager_impl.h"
14#include "content/public/common/drop_data.h"
15#include "mojo/public/cpp/bindings/pending_remote.h"
16#include "services/network/public/mojom/referrer_policy.mojom-shared.h"
17#include "third_party/blink/public/mojom/native_file_system/native_file_system_drag_drop_token.mojom.h"
18#include "third_party/blink/public/mojom/page/drag.mojom.h"
19#include "ui/base/clipboard/clipboard_constants.h"
20#include "ui/base/dragdrop/file_info/file_info.h"
21#include "url/gurl.h"
22
23namespace content {
24
25blink::mojom::DragDataPtr DropDataToDragData(
26 const DropData& drop_data,
27 NativeFileSystemManagerImpl* native_file_system_manager,
28 int child_id) {
29 // These fields are currently unused when dragging into Blink.
30 DCHECK(drop_data.download_metadata.empty());
31 DCHECK(drop_data.file_contents.empty());
32 DCHECK(drop_data.file_contents_content_disposition.empty());
33
34 std::vector<blink::mojom::DragItemPtr> items;
35 if (drop_data.text) {
36 blink::mojom::DragItemStringPtr item = blink::mojom::DragItemString::New();
37 item->string_type = ui::kMimeTypeText;
38 item->string_data = *drop_data.text;
39 items.push_back(blink::mojom::DragItem::NewString(std::move(item)));
40 }
41 if (!drop_data.url.is_empty()) {
42 blink::mojom::DragItemStringPtr item = blink::mojom::DragItemString::New();
43 item->string_type = ui::kMimeTypeURIList;
44 item->string_data = base::UTF8ToUTF16(drop_data.url.spec());
45 item->title = drop_data.url_title;
46 items.push_back(blink::mojom::DragItem::NewString(std::move(item)));
47 }
48 if (drop_data.html) {
49 blink::mojom::DragItemStringPtr item = blink::mojom::DragItemString::New();
50 item->string_type = ui::kMimeTypeHTML;
51 item->string_data = *drop_data.html;
52 item->base_url = drop_data.html_base_url;
53 items.push_back(blink::mojom::DragItem::NewString(std::move(item)));
54 }
55 for (const ui::FileInfo& file : drop_data.filenames) {
56 blink::mojom::DragItemFilePtr item = blink::mojom::DragItemFile::New();
57 item->path = file.path;
58 item->display_name = file.display_name;
59 mojo::PendingRemote<blink::mojom::NativeFileSystemDragDropToken>
60 pending_token;
61 native_file_system_manager->CreateNativeFileSystemDragDropToken(
62 file.path, child_id, pending_token.InitWithNewPipeAndPassReceiver());
63 item->native_file_system_token = std::move(pending_token);
64 items.push_back(blink::mojom::DragItem::NewFile(std::move(item)));
65 }
66 for (const content::DropData::FileSystemFileInfo& file_system_file :
67 drop_data.file_system_files) {
68 blink::mojom::DragItemFileSystemFilePtr item =
69 blink::mojom::DragItemFileSystemFile::New();
70 item->url = file_system_file.url;
71 item->size = file_system_file.size;
72 item->file_system_id = file_system_file.filesystem_id;
73 items.push_back(blink::mojom::DragItem::NewFileSystemFile(std::move(item)));
74 }
75 for (const std::pair<base::string16, base::string16> data :
76 drop_data.custom_data) {
77 blink::mojom::DragItemStringPtr item = blink::mojom::DragItemString::New();
78 item->string_type = base::UTF16ToUTF8(data.first);
79 item->string_data = data.second;
80 items.push_back(blink::mojom::DragItem::NewString(std::move(item)));
81 }
82
83 return blink::mojom::DragData::New(std::move(items),
84 base::UTF16ToUTF8(drop_data.filesystem_id),
85 drop_data.referrer_policy);
86}
87
88DropData DragDataToDropData(const blink::mojom::DragData& drag_data) {
89 DropData result;
90
91 for (const blink::mojom::DragItemPtr& item : drag_data.items) {
92 switch (item->which()) {
93 case blink::mojom::DragItemDataView::Tag::STRING: {
94 const blink::mojom::DragItemStringPtr& string_item = item->get_string();
95 std::string str_type = string_item->string_type;
96 if (str_type == ui::kMimeTypeText) {
97 result.text = string_item->string_data;
98 } else if (str_type == ui::kMimeTypeURIList) {
99 result.url = GURL(string_item->string_data);
100 if (string_item->title)
101 result.url_title = *string_item->title;
102 } else if (str_type == ui::kMimeTypeDownloadURL) {
103 result.download_metadata = string_item->string_data;
104 result.referrer_policy = drag_data.referrer_policy;
105 } else if (str_type == ui::kMimeTypeHTML) {
106 result.html = string_item->string_data;
107 if (string_item->base_url)
108 result.html_base_url = *string_item->base_url;
109 } else {
110 result.custom_data.emplace(
111 base::UTF8ToUTF16(string_item->string_type),
112 string_item->string_data);
113 }
114 break;
115 }
116 case blink::mojom::DragItemDataView::Tag::BINARY: {
117 DCHECK(result.file_contents.empty());
118
119 const blink::mojom::DragItemBinaryPtr& binary_item = item->get_binary();
120 result.file_contents.reserve(binary_item->data.size());
121 result.file_contents_source_url = binary_item->source_url;
122 result.file_contents_filename_extension =
123 binary_item->filename_extension.value();
124 if (binary_item->content_disposition) {
125 result.file_contents_content_disposition =
126 *binary_item->content_disposition;
127 }
128 break;
129 }
130 case blink::mojom::DragItemDataView::Tag::FILE: {
131 const blink::mojom::DragItemFilePtr& file_item = item->get_file();
132 // TODO(varunjain): This only works on chromeos. Support win/mac/gtk.
133 result.filenames.emplace_back(file_item->path, file_item->display_name);
134 break;
135 }
136 case blink::mojom::DragItemDataView::Tag::FILE_SYSTEM_FILE: {
137 const blink::mojom::DragItemFileSystemFilePtr& file_system_file_item =
138 item->get_file_system_file();
139 DropData::FileSystemFileInfo info;
140 info.url = file_system_file_item->url;
141 info.size = file_system_file_item->size;
142 info.filesystem_id = file_system_file_item->file_system_id;
143 result.file_system_files.push_back(std::move(info));
144 break;
145 }
146 }
147 }
148 return result;
149}
150
151} // namespace content