| Index: content/browser/web_contents/web_contents_view_aura.cc
|
| ===================================================================
|
| --- content/browser/web_contents/web_contents_view_aura.cc (revision 245808)
|
| +++ content/browser/web_contents/web_contents_view_aura.cc (working copy)
|
| @@ -6,8 +6,10 @@
|
|
|
| #include "base/auto_reset.h"
|
| #include "base/command_line.h"
|
| +#include "base/file_util.h"
|
| #include "base/metrics/histogram.h"
|
| #include "base/strings/utf_string_conversions.h"
|
| +#include "content/browser/download/drag_download_util.h"
|
| #include "content/browser/frame_host/interstitial_page_impl.h"
|
| #include "content/browser/frame_host/navigation_entry_impl.h"
|
| #include "content/browser/renderer_host/dip_util.h"
|
| @@ -21,6 +23,7 @@
|
| #include "content/browser/web_contents/aura/window_slider.h"
|
| #include "content/browser/web_contents/touch_editable_impl_aura.h"
|
| #include "content/browser/web_contents/web_contents_impl.h"
|
| +#include "content/public/browser/content_browser_client.h"
|
| #include "content/public/browser/notification_observer.h"
|
| #include "content/public/browser/notification_registrar.h"
|
| #include "content/public/browser/notification_source.h"
|
| @@ -33,6 +36,7 @@
|
| #include "content/public/browser/web_contents_observer.h"
|
| #include "content/public/browser/web_contents_view_delegate.h"
|
| #include "content/public/browser/web_drag_dest_delegate.h"
|
| +#include "content/public/common/content_client.h"
|
| #include "content/public/common/content_switches.h"
|
| #include "content/public/common/drop_data.h"
|
| #include "net/base/net_util.h"
|
| @@ -256,12 +260,76 @@
|
| }
|
| provider->SetFileContents(file_name, drop_data.file_contents);
|
| }
|
| +
|
| +void PrepareDragForDownload(
|
| + const DropData& drop_data,
|
| + ui::OSExchangeData::Provider* provider,
|
| + WebContentsImpl* web_contents) {
|
| + const GURL& page_url = web_contents->GetLastCommittedURL();
|
| + const std::string& page_encoding = web_contents->GetEncoding();
|
| +
|
| + // Parse the download metadata.
|
| + base::string16 mime_type;
|
| + base::FilePath file_name;
|
| + GURL download_url;
|
| + if (!ParseDownloadMetadata(drop_data.download_metadata,
|
| + &mime_type,
|
| + &file_name,
|
| + &download_url))
|
| + return;
|
| +
|
| + // Generate the file name based on both mime type and proposed file name.
|
| + std::string default_name =
|
| + GetContentClient()->browser()->GetDefaultDownloadName();
|
| + base::FilePath generated_download_file_name =
|
| + net::GenerateFileName(download_url,
|
| + std::string(),
|
| + std::string(),
|
| + base::UTF16ToUTF8(file_name.value()),
|
| + base::UTF16ToUTF8(mime_type),
|
| + default_name);
|
| +
|
| + // http://crbug.com/332579
|
| + base::ThreadRestrictions::ScopedAllowIO allow_file_operations;
|
| +
|
| + base::FilePath temp_dir_path;
|
| + if (!file_util::CreateNewTempDirectory(FILE_PATH_LITERAL("chrome_drag"),
|
| + &temp_dir_path))
|
| + return;
|
| +
|
| + base::FilePath download_path =
|
| + temp_dir_path.Append(generated_download_file_name);
|
| +
|
| + // We cannot know when the target application will be done using the temporary
|
| + // file, so schedule it to be deleted after rebooting.
|
| + base::DeleteFileAfterReboot(download_path);
|
| + base::DeleteFileAfterReboot(temp_dir_path);
|
| +
|
| + // Provide the data as file (CF_HDROP). A temporary download file with the
|
| + // Zone.Identifier ADS (Alternate Data Stream) attached will be created.
|
| + scoped_refptr<DragDownloadFile> download_file =
|
| + new DragDownloadFile(
|
| + download_path,
|
| + scoped_ptr<net::FileStream>(),
|
| + download_url,
|
| + Referrer(page_url, drop_data.referrer_policy),
|
| + page_encoding,
|
| + web_contents);
|
| + ui::OSExchangeData::DownloadFileInfo file_download(base::FilePath(),
|
| + download_file.get());
|
| + provider->SetDownloadFileInfo(file_download);
|
| +}
|
| #endif
|
|
|
| // Utility to fill a ui::OSExchangeDataProvider object from DropData.
|
| void PrepareDragData(const DropData& drop_data,
|
| - ui::OSExchangeData::Provider* provider) {
|
| + ui::OSExchangeData::Provider* provider,
|
| + WebContentsImpl* web_contents) {
|
| #if defined(OS_WIN)
|
| + // Put download before file contents to prefer the download of a image over
|
| + // its thumbnail link.
|
| + if (!drop_data.download_metadata.empty())
|
| + PrepareDragForDownload(drop_data, provider, web_contents);
|
| // We set the file contents before the URL because the URL also sets file
|
| // contents (to a .URL shortcut). We want to prefer file content data over
|
| // a shortcut so we add it first.
|
| @@ -1363,7 +1431,7 @@
|
| touch_editable_->EndTouchEditing();
|
|
|
| ui::OSExchangeData::Provider* provider = ui::OSExchangeData::CreateProvider();
|
| - PrepareDragData(drop_data, provider);
|
| + PrepareDragData(drop_data, provider, web_contents_);
|
|
|
| ui::OSExchangeData data(provider); // takes ownership of |provider|.
|
|
|
|
|