save_page_handler.cc 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566
  1. // Copyright (c) 2015 GitHub, Inc.
  2. // Use of this source code is governed by the MIT license that can be
  3. // found in the LICENSE file.
  4. #include "shell/browser/api/save_page_handler.h"
  5. #include <utility>
  6. #include "base/files/file_path.h"
  7. #include "base/functional/callback.h"
  8. #include "content/public/browser/web_contents.h"
  9. #include "shell/browser/electron_browser_context.h"
  10. namespace electron::api {
  11. SavePageHandler::SavePageHandler(content::WebContents* web_contents,
  12. gin_helper::Promise<void> promise)
  13. : web_contents_(web_contents), promise_(std::move(promise)) {}
  14. SavePageHandler::~SavePageHandler() = default;
  15. void SavePageHandler::OnDownloadCreated(content::DownloadManager* manager,
  16. download::DownloadItem* item) {
  17. // OnDownloadCreated is invoked during WebContents::SavePage, so the |item|
  18. // here is the one stated by WebContents::SavePage.
  19. item->AddObserver(this);
  20. }
  21. bool SavePageHandler::Handle(const base::FilePath& full_path,
  22. const content::SavePageType& save_type) {
  23. auto* download_manager =
  24. web_contents_->GetBrowserContext()->GetDownloadManager();
  25. download_manager->AddObserver(this);
  26. // Chromium will create a 'foo_files' directory under the directory of saving
  27. // page 'foo.html' for holding other resource files of 'foo.html'.
  28. base::FilePath saved_main_directory_path = full_path.DirName().Append(
  29. full_path.RemoveExtension().BaseName().value() +
  30. FILE_PATH_LITERAL("_files"));
  31. bool result =
  32. web_contents_->SavePage(full_path, saved_main_directory_path, save_type);
  33. download_manager->RemoveObserver(this);
  34. // If initialization fails which means fail to create |DownloadItem|, we need
  35. // to delete the |SavePageHandler| instance to avoid memory-leak.
  36. if (!result) {
  37. promise_.RejectWithErrorMessage("Failed to save the page");
  38. delete this;
  39. }
  40. return result;
  41. }
  42. void SavePageHandler::OnDownloadUpdated(download::DownloadItem* item) {
  43. if (item->IsDone()) {
  44. if (item->GetState() == download::DownloadItem::COMPLETE)
  45. promise_.Resolve();
  46. else
  47. promise_.RejectWithErrorMessage("Failed to save the page.");
  48. Destroy(item);
  49. }
  50. }
  51. void SavePageHandler::Destroy(download::DownloadItem* item) {
  52. item->RemoveObserver(this);
  53. delete this;
  54. }
  55. } // namespace electron::api