save_page_handler.cc 2.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576
  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. download::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(download::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() == download::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. v8::NewStringType::kNormal)
  52. .ToLocalChecked();
  53. callback_.Run(v8::Exception::Error(error_message));
  54. }
  55. Destroy(item);
  56. }
  57. }
  58. void SavePageHandler::Destroy(download::DownloadItem* item) {
  59. item->RemoveObserver(this);
  60. delete this;
  61. }
  62. } // namespace api
  63. } // namespace atom