save_page_handler.cc 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475
  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 "atom/browser/api/save_page_handler.h"
  5. #include <string>
  6. #include "atom/browser/atom_browser_context.h"
  7. #include "base/callback.h"
  8. #include "base/files/file_path.h"
  9. #include "content/public/browser/web_contents.h"
  10. namespace atom {
  11. namespace api {
  12. SavePageHandler::SavePageHandler(content::WebContents* web_contents,
  13. const SavePageCallback& callback)
  14. : web_contents_(web_contents), callback_(callback) {}
  15. SavePageHandler::~SavePageHandler() {}
  16. void SavePageHandler::OnDownloadCreated(content::DownloadManager* manager,
  17. content::DownloadItem* item) {
  18. // OnDownloadCreated is invoked during WebContents::SavePage, so the |item|
  19. // here is the one stated by WebContents::SavePage.
  20. item->AddObserver(this);
  21. }
  22. bool SavePageHandler::Handle(const base::FilePath& full_path,
  23. const content::SavePageType& save_type) {
  24. auto* download_manager = content::BrowserContext::GetDownloadManager(
  25. web_contents_->GetBrowserContext());
  26. download_manager->AddObserver(this);
  27. // Chromium will create a 'foo_files' directory under the directory of saving
  28. // page 'foo.html' for holding other resource files of 'foo.html'.
  29. base::FilePath saved_main_directory_path = full_path.DirName().Append(
  30. full_path.RemoveExtension().BaseName().value() +
  31. FILE_PATH_LITERAL("_files"));
  32. bool result =
  33. web_contents_->SavePage(full_path, saved_main_directory_path, save_type);
  34. download_manager->RemoveObserver(this);
  35. // If initialization fails which means fail to create |DownloadItem|, we need
  36. // to delete the |SavePageHandler| instance to avoid memory-leak.
  37. if (!result)
  38. delete this;
  39. return result;
  40. }
  41. void SavePageHandler::OnDownloadUpdated(content::DownloadItem* item) {
  42. if (item->IsDone()) {
  43. v8::Isolate* isolate = v8::Isolate::GetCurrent();
  44. v8::Locker locker(isolate);
  45. v8::HandleScope handle_scope(isolate);
  46. if (item->GetState() == content::DownloadItem::COMPLETE) {
  47. callback_.Run(v8::Null(isolate));
  48. } else {
  49. v8::Local<v8::String> error_message =
  50. v8::String::NewFromUtf8(isolate, "Fail to save page");
  51. callback_.Run(v8::Exception::Error(error_message));
  52. }
  53. Destroy(item);
  54. }
  55. }
  56. void SavePageHandler::Destroy(content::DownloadItem* item) {
  57. item->RemoveObserver(this);
  58. delete this;
  59. }
  60. } // namespace api
  61. } // namespace atom