fix: use async save dialog for anchor download attribute (#16612)
This commit is contained in:
parent
bd4e14dcee
commit
927aac306f
2 changed files with 78 additions and 25 deletions
|
@ -100,23 +100,58 @@ void AtomDownloadManagerDelegate::OnDownloadPathGenerated(
|
||||||
if (relay)
|
if (relay)
|
||||||
window = relay->GetNativeWindow();
|
window = relay->GetNativeWindow();
|
||||||
|
|
||||||
auto* web_preferences = WebContentsPreferences::From(web_contents);
|
// Show save dialog if save path was not set already on item
|
||||||
bool offscreen =
|
|
||||||
!web_preferences || web_preferences->IsEnabled(options::kOffscreen);
|
|
||||||
|
|
||||||
base::FilePath path;
|
base::FilePath path;
|
||||||
GetItemSavePath(item, &path);
|
GetItemSavePath(item, &path);
|
||||||
// Show save dialog if save path was not set already on item
|
if (path.empty()) {
|
||||||
file_dialog::DialogSettings settings;
|
file_dialog::DialogSettings settings;
|
||||||
GetItemSaveDialogOptions(item, &settings);
|
GetItemSaveDialogOptions(item, &settings);
|
||||||
if (!settings.parent_window)
|
|
||||||
settings.parent_window = window;
|
if (!settings.parent_window)
|
||||||
settings.force_detached = offscreen;
|
settings.parent_window = window;
|
||||||
if (settings.title.size() == 0)
|
if (settings.title.size() == 0)
|
||||||
settings.title = item->GetURL().spec();
|
settings.title = item->GetURL().spec();
|
||||||
if (!settings.default_path.empty())
|
if (!settings.default_path.empty())
|
||||||
settings.default_path = default_path;
|
settings.default_path = default_path;
|
||||||
if (path.empty() && file_dialog::ShowSaveDialog(settings, &path)) {
|
|
||||||
|
auto* web_preferences = WebContentsPreferences::From(web_contents);
|
||||||
|
const bool offscreen =
|
||||||
|
!web_preferences || web_preferences->IsEnabled(options::kOffscreen);
|
||||||
|
settings.force_detached = offscreen;
|
||||||
|
|
||||||
|
auto dialog_callback =
|
||||||
|
base::Bind(&AtomDownloadManagerDelegate::OnDownloadSaveDialogDone,
|
||||||
|
base::Unretained(this), download_id, callback);
|
||||||
|
file_dialog::ShowSaveDialog(settings, dialog_callback);
|
||||||
|
} else {
|
||||||
|
callback.Run(path, download::DownloadItem::TARGET_DISPOSITION_PROMPT,
|
||||||
|
download::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, path,
|
||||||
|
download::DOWNLOAD_INTERRUPT_REASON_NONE);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(MAS_BUILD)
|
||||||
|
void AtomDownloadManagerDelegate::OnDownloadSaveDialogDone(
|
||||||
|
uint32_t download_id,
|
||||||
|
const content::DownloadTargetCallback& download_callback,
|
||||||
|
bool result,
|
||||||
|
const base::FilePath& path,
|
||||||
|
const std::string& bookmark)
|
||||||
|
#else
|
||||||
|
void AtomDownloadManagerDelegate::OnDownloadSaveDialogDone(
|
||||||
|
uint32_t download_id,
|
||||||
|
const content::DownloadTargetCallback& download_callback,
|
||||||
|
bool result,
|
||||||
|
const base::FilePath& path)
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
|
||||||
|
|
||||||
|
auto* item = download_manager_->GetDownload(download_id);
|
||||||
|
if (!item)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (result) {
|
||||||
// Remember the last selected download directory.
|
// Remember the last selected download directory.
|
||||||
AtomBrowserContext* browser_context = static_cast<AtomBrowserContext*>(
|
AtomBrowserContext* browser_context = static_cast<AtomBrowserContext*>(
|
||||||
download_manager_->GetBrowserContext());
|
download_manager_->GetBrowserContext());
|
||||||
|
@ -133,12 +168,15 @@ void AtomDownloadManagerDelegate::OnDownloadPathGenerated(
|
||||||
}
|
}
|
||||||
|
|
||||||
// Running the DownloadTargetCallback with an empty FilePath signals that the
|
// Running the DownloadTargetCallback with an empty FilePath signals that the
|
||||||
// download should be cancelled.
|
// download should be cancelled. If user cancels the file save dialog, run
|
||||||
// If user cancels the file save dialog, run the callback with empty FilePath.
|
// the callback with empty FilePath.
|
||||||
callback.Run(path, download::DownloadItem::TARGET_DISPOSITION_PROMPT,
|
const base::FilePath download_path = result ? path : base::FilePath();
|
||||||
download::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, path,
|
const auto interrupt_reason =
|
||||||
path.empty() ? download::DOWNLOAD_INTERRUPT_REASON_USER_CANCELED
|
download_path.empty() ? download::DOWNLOAD_INTERRUPT_REASON_USER_CANCELED
|
||||||
: download::DOWNLOAD_INTERRUPT_REASON_NONE);
|
: download::DOWNLOAD_INTERRUPT_REASON_NONE;
|
||||||
|
download_callback.Run(path, download::DownloadItem::TARGET_DISPOSITION_PROMPT,
|
||||||
|
download::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS,
|
||||||
|
download_path, interrupt_reason);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AtomDownloadManagerDelegate::Shutdown() {
|
void AtomDownloadManagerDelegate::Shutdown() {
|
||||||
|
|
|
@ -25,10 +25,6 @@ class AtomDownloadManagerDelegate : public content::DownloadManagerDelegate {
|
||||||
explicit AtomDownloadManagerDelegate(content::DownloadManager* manager);
|
explicit AtomDownloadManagerDelegate(content::DownloadManager* manager);
|
||||||
~AtomDownloadManagerDelegate() override;
|
~AtomDownloadManagerDelegate() override;
|
||||||
|
|
||||||
void OnDownloadPathGenerated(uint32_t download_id,
|
|
||||||
const content::DownloadTargetCallback& callback,
|
|
||||||
const base::FilePath& default_path);
|
|
||||||
|
|
||||||
// content::DownloadManagerDelegate:
|
// content::DownloadManagerDelegate:
|
||||||
void Shutdown() override;
|
void Shutdown() override;
|
||||||
bool DetermineDownloadTarget(
|
bool DetermineDownloadTarget(
|
||||||
|
@ -45,6 +41,25 @@ class AtomDownloadManagerDelegate : public content::DownloadManagerDelegate {
|
||||||
void GetItemSaveDialogOptions(download::DownloadItem* item,
|
void GetItemSaveDialogOptions(download::DownloadItem* item,
|
||||||
file_dialog::DialogSettings* settings);
|
file_dialog::DialogSettings* settings);
|
||||||
|
|
||||||
|
void OnDownloadPathGenerated(uint32_t download_id,
|
||||||
|
const content::DownloadTargetCallback& callback,
|
||||||
|
const base::FilePath& default_path);
|
||||||
|
|
||||||
|
#if defined(MAS_BUILD)
|
||||||
|
void OnDownloadSaveDialogDone(
|
||||||
|
uint32_t download_id,
|
||||||
|
const content::DownloadTargetCallback& download_callback,
|
||||||
|
bool result,
|
||||||
|
const base::FilePath& path,
|
||||||
|
const std::string& bookmark);
|
||||||
|
#else
|
||||||
|
void OnDownloadSaveDialogDone(
|
||||||
|
uint32_t download_id,
|
||||||
|
const content::DownloadTargetCallback& download_callback,
|
||||||
|
bool result,
|
||||||
|
const base::FilePath& path);
|
||||||
|
#endif
|
||||||
|
|
||||||
content::DownloadManager* download_manager_;
|
content::DownloadManager* download_manager_;
|
||||||
base::WeakPtrFactory<AtomDownloadManagerDelegate> weak_ptr_factory_;
|
base::WeakPtrFactory<AtomDownloadManagerDelegate> weak_ptr_factory_;
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue