2015-06-05 05:49:12 +00:00
|
|
|
// Copyright (c) 2015 GitHub, Inc.
|
|
|
|
// Use of this source code is governed by the MIT license that can be
|
|
|
|
// found in the LICENSE file.
|
|
|
|
|
|
|
|
#include "atom/browser/common_web_contents_delegate.h"
|
|
|
|
|
2018-09-13 00:25:56 +00:00
|
|
|
#include <memory>
|
2016-03-15 02:21:36 +00:00
|
|
|
#include <set>
|
2015-06-05 09:01:17 +00:00
|
|
|
#include <string>
|
2018-09-13 00:25:56 +00:00
|
|
|
#include <utility>
|
2015-06-05 09:01:17 +00:00
|
|
|
#include <vector>
|
|
|
|
|
2016-03-15 02:21:36 +00:00
|
|
|
#include "atom/browser/atom_browser_context.h"
|
2015-06-05 06:55:07 +00:00
|
|
|
#include "atom/browser/native_window.h"
|
|
|
|
#include "atom/browser/ui/file_dialog.h"
|
2018-04-03 03:19:35 +00:00
|
|
|
#include "atom/browser/web_contents_preferences.h"
|
2015-06-05 07:12:38 +00:00
|
|
|
#include "atom/browser/web_dialog_helper.h"
|
2016-04-11 09:36:33 +00:00
|
|
|
#include "atom/common/atom_constants.h"
|
2018-05-29 08:09:51 +00:00
|
|
|
#include "atom/common/options_switches.h"
|
2015-06-08 05:19:56 +00:00
|
|
|
#include "base/files/file_util.h"
|
2018-09-12 13:45:08 +00:00
|
|
|
#include "base/json/json_reader.h"
|
2018-04-09 09:16:52 +00:00
|
|
|
#include "base/task_scheduler/post_task.h"
|
|
|
|
#include "base/threading/sequenced_task_runner_handle.h"
|
2015-06-13 08:02:16 +00:00
|
|
|
#include "chrome/browser/printing/print_preview_message_handler.h"
|
2015-06-13 13:23:45 +00:00
|
|
|
#include "chrome/browser/printing/print_view_manager_basic.h"
|
2017-01-24 01:51:11 +00:00
|
|
|
#include "chrome/browser/ssl/security_state_tab_helper.h"
|
2015-06-05 07:12:38 +00:00
|
|
|
#include "chrome/browser/ui/browser_dialogs.h"
|
2016-03-15 02:21:36 +00:00
|
|
|
#include "chrome/common/pref_names.h"
|
2016-08-26 22:30:02 +00:00
|
|
|
#include "components/prefs/pref_service.h"
|
|
|
|
#include "components/prefs/scoped_user_pref_update.h"
|
2017-01-24 01:51:11 +00:00
|
|
|
#include "components/security_state/content/content_utils.h"
|
|
|
|
#include "components/security_state/core/security_state.h"
|
2015-06-22 02:00:33 +00:00
|
|
|
#include "content/public/browser/browser_thread.h"
|
2015-06-05 06:55:07 +00:00
|
|
|
#include "content/public/browser/child_process_security_policy.h"
|
|
|
|
#include "content/public/browser/render_process_host.h"
|
|
|
|
#include "content/public/browser/render_view_host.h"
|
2016-03-08 14:28:53 +00:00
|
|
|
#include "content/public/browser/render_widget_host.h"
|
2016-04-11 09:36:33 +00:00
|
|
|
#include "content/public/browser/security_style_explanation.h"
|
|
|
|
#include "content/public/browser/security_style_explanations.h"
|
2015-06-05 06:55:07 +00:00
|
|
|
#include "storage/browser/fileapi/isolated_context.h"
|
|
|
|
|
2015-06-22 02:00:33 +00:00
|
|
|
using content::BrowserThread;
|
|
|
|
|
2015-06-05 05:49:12 +00:00
|
|
|
namespace atom {
|
|
|
|
|
2015-06-05 06:55:07 +00:00
|
|
|
namespace {
|
|
|
|
|
2016-03-15 02:21:36 +00:00
|
|
|
const char kRootName[] = "<root>";
|
|
|
|
|
2015-06-05 06:55:07 +00:00
|
|
|
struct FileSystem {
|
2018-04-18 01:55:30 +00:00
|
|
|
FileSystem() {}
|
2018-09-12 13:45:08 +00:00
|
|
|
FileSystem(const std::string& type,
|
|
|
|
const std::string& file_system_name,
|
2015-06-05 06:55:07 +00:00
|
|
|
const std::string& root_url,
|
|
|
|
const std::string& file_system_path)
|
2018-09-12 13:45:08 +00:00
|
|
|
: type(type),
|
|
|
|
file_system_name(file_system_name),
|
2018-04-18 01:55:30 +00:00
|
|
|
root_url(root_url),
|
|
|
|
file_system_path(file_system_path) {}
|
2015-06-05 06:55:07 +00:00
|
|
|
|
2018-09-12 13:45:08 +00:00
|
|
|
std::string type;
|
2015-06-05 06:55:07 +00:00
|
|
|
std::string file_system_name;
|
|
|
|
std::string root_url;
|
|
|
|
std::string file_system_path;
|
|
|
|
};
|
|
|
|
|
|
|
|
std::string RegisterFileSystem(content::WebContents* web_contents,
|
2016-03-15 02:21:36 +00:00
|
|
|
const base::FilePath& path) {
|
2018-04-17 22:41:47 +00:00
|
|
|
auto* isolated_context = storage::IsolatedContext::GetInstance();
|
2016-03-15 02:21:36 +00:00
|
|
|
std::string root_name(kRootName);
|
2015-06-05 06:55:07 +00:00
|
|
|
std::string file_system_id = isolated_context->RegisterFileSystemForPath(
|
2018-04-18 01:55:30 +00:00
|
|
|
storage::kFileSystemTypeNativeLocal, std::string(), path, &root_name);
|
2015-06-05 06:55:07 +00:00
|
|
|
|
|
|
|
content::ChildProcessSecurityPolicy* policy =
|
|
|
|
content::ChildProcessSecurityPolicy::GetInstance();
|
|
|
|
content::RenderViewHost* render_view_host = web_contents->GetRenderViewHost();
|
|
|
|
int renderer_id = render_view_host->GetProcess()->GetID();
|
|
|
|
policy->GrantReadFileSystem(renderer_id, file_system_id);
|
|
|
|
policy->GrantWriteFileSystem(renderer_id, file_system_id);
|
|
|
|
policy->GrantCreateFileForFileSystem(renderer_id, file_system_id);
|
|
|
|
policy->GrantDeleteFromFileSystem(renderer_id, file_system_id);
|
|
|
|
|
|
|
|
if (!policy->CanReadFile(renderer_id, path))
|
|
|
|
policy->GrantReadFile(renderer_id, path);
|
|
|
|
|
|
|
|
return file_system_id;
|
|
|
|
}
|
|
|
|
|
2018-04-18 01:55:30 +00:00
|
|
|
FileSystem CreateFileSystemStruct(content::WebContents* web_contents,
|
|
|
|
const std::string& file_system_id,
|
2018-09-12 13:45:08 +00:00
|
|
|
const std::string& file_system_path,
|
|
|
|
const std::string& type) {
|
2015-06-05 06:55:07 +00:00
|
|
|
const GURL origin = web_contents->GetURL().GetOrigin();
|
|
|
|
std::string file_system_name =
|
|
|
|
storage::GetIsolatedFileSystemName(origin, file_system_id);
|
|
|
|
std::string root_url = storage::GetIsolatedFileSystemRootURIString(
|
2016-03-15 02:21:36 +00:00
|
|
|
origin, file_system_id, kRootName);
|
2018-09-12 13:45:08 +00:00
|
|
|
return FileSystem(type, file_system_name, root_url, file_system_path);
|
2015-06-05 06:55:07 +00:00
|
|
|
}
|
|
|
|
|
2017-01-26 10:55:19 +00:00
|
|
|
std::unique_ptr<base::DictionaryValue> CreateFileSystemValue(
|
|
|
|
const FileSystem& file_system) {
|
|
|
|
std::unique_ptr<base::DictionaryValue> file_system_value(
|
|
|
|
new base::DictionaryValue());
|
2018-09-12 13:45:08 +00:00
|
|
|
file_system_value->SetString("type", file_system.type);
|
2015-06-05 06:55:07 +00:00
|
|
|
file_system_value->SetString("fileSystemName", file_system.file_system_name);
|
|
|
|
file_system_value->SetString("rootURL", file_system.root_url);
|
|
|
|
file_system_value->SetString("fileSystemPath", file_system.file_system_path);
|
|
|
|
return file_system_value;
|
|
|
|
}
|
|
|
|
|
2018-04-18 01:55:30 +00:00
|
|
|
void WriteToFile(const base::FilePath& path, const std::string& content) {
|
2018-04-09 09:16:52 +00:00
|
|
|
base::AssertBlockingAllowed();
|
2015-06-22 02:00:33 +00:00
|
|
|
DCHECK(!path.empty());
|
|
|
|
|
|
|
|
base::WriteFile(path, content.data(), content.size());
|
|
|
|
}
|
|
|
|
|
2018-04-18 01:55:30 +00:00
|
|
|
void AppendToFile(const base::FilePath& path, const std::string& content) {
|
2018-04-09 09:16:52 +00:00
|
|
|
base::AssertBlockingAllowed();
|
2015-06-22 02:00:33 +00:00
|
|
|
DCHECK(!path.empty());
|
|
|
|
|
|
|
|
base::AppendToFile(path, content.data(), content.size());
|
|
|
|
}
|
|
|
|
|
2016-03-15 02:21:36 +00:00
|
|
|
PrefService* GetPrefService(content::WebContents* web_contents) {
|
2018-04-17 22:41:47 +00:00
|
|
|
auto* context = web_contents->GetBrowserContext();
|
2016-03-15 02:21:36 +00:00
|
|
|
return static_cast<atom::AtomBrowserContext*>(context)->prefs();
|
|
|
|
}
|
|
|
|
|
2018-09-12 13:45:08 +00:00
|
|
|
std::map<std::string, std::string> GetAddedFileSystemPaths(
|
2016-03-15 02:21:36 +00:00
|
|
|
content::WebContents* web_contents) {
|
2018-04-17 22:41:47 +00:00
|
|
|
auto* pref_service = GetPrefService(web_contents);
|
2016-03-15 02:21:36 +00:00
|
|
|
const base::DictionaryValue* file_system_paths_value =
|
|
|
|
pref_service->GetDictionary(prefs::kDevToolsFileSystemPaths);
|
2018-09-12 13:45:08 +00:00
|
|
|
std::map<std::string, std::string> result;
|
2016-03-15 02:21:36 +00:00
|
|
|
if (file_system_paths_value) {
|
|
|
|
base::DictionaryValue::Iterator it(*file_system_paths_value);
|
|
|
|
for (; !it.IsAtEnd(); it.Advance()) {
|
2018-09-12 13:45:08 +00:00
|
|
|
std::string type =
|
|
|
|
it.value().is_string() ? it.value().GetString() : std::string();
|
|
|
|
result[it.key()] = type;
|
2016-03-15 02:21:36 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
2018-04-18 01:55:30 +00:00
|
|
|
bool IsDevToolsFileSystemAdded(content::WebContents* web_contents,
|
|
|
|
const std::string& file_system_path) {
|
2016-05-06 23:02:54 +00:00
|
|
|
auto file_system_paths = GetAddedFileSystemPaths(web_contents);
|
|
|
|
return file_system_paths.find(file_system_path) != file_system_paths.end();
|
|
|
|
}
|
|
|
|
|
2015-06-05 06:55:07 +00:00
|
|
|
} // namespace
|
|
|
|
|
2015-06-24 14:23:38 +00:00
|
|
|
CommonWebContentsDelegate::CommonWebContentsDelegate()
|
2018-04-09 09:16:52 +00:00
|
|
|
: devtools_file_system_indexer_(new DevToolsFileSystemIndexer),
|
|
|
|
file_task_runner_(
|
2018-09-12 13:45:08 +00:00
|
|
|
base::CreateSequencedTaskRunnerWithTraits({base::MayBlock()})),
|
|
|
|
weak_factory_(this) {}
|
2015-06-05 05:49:12 +00:00
|
|
|
|
2018-04-18 01:55:30 +00:00
|
|
|
CommonWebContentsDelegate::~CommonWebContentsDelegate() {}
|
2015-06-05 05:49:12 +00:00
|
|
|
|
2015-06-05 06:55:07 +00:00
|
|
|
void CommonWebContentsDelegate::InitWithWebContents(
|
2016-05-17 12:49:05 +00:00
|
|
|
content::WebContents* web_contents,
|
2018-08-16 22:57:40 +00:00
|
|
|
AtomBrowserContext* browser_context,
|
|
|
|
bool is_guest) {
|
2016-05-17 12:49:05 +00:00
|
|
|
browser_context_ = browser_context;
|
2015-06-05 06:55:07 +00:00
|
|
|
web_contents->SetDelegate(this);
|
|
|
|
|
2015-06-13 13:23:45 +00:00
|
|
|
printing::PrintViewManagerBasic::CreateForWebContents(web_contents);
|
2015-06-13 08:02:16 +00:00
|
|
|
printing::PrintPreviewMessageHandler::CreateForWebContents(web_contents);
|
|
|
|
|
2018-04-03 03:19:35 +00:00
|
|
|
// Determien whether the WebContents is offscreen.
|
|
|
|
auto* web_preferences = WebContentsPreferences::From(web_contents);
|
2018-05-29 08:09:51 +00:00
|
|
|
offscreen_ =
|
|
|
|
!web_preferences || web_preferences->IsEnabled(options::kOffscreen);
|
2018-04-03 03:19:35 +00:00
|
|
|
|
2015-06-05 06:55:07 +00:00
|
|
|
// Create InspectableWebContents.
|
2018-08-16 22:57:40 +00:00
|
|
|
web_contents_.reset(
|
|
|
|
brightray::InspectableWebContents::Create(web_contents, is_guest));
|
2015-06-05 06:55:07 +00:00
|
|
|
web_contents_->SetDelegate(this);
|
|
|
|
}
|
|
|
|
|
2015-06-24 15:29:32 +00:00
|
|
|
void CommonWebContentsDelegate::SetOwnerWindow(NativeWindow* owner_window) {
|
2015-10-01 06:41:01 +00:00
|
|
|
SetOwnerWindow(GetWebContents(), owner_window);
|
|
|
|
}
|
|
|
|
|
|
|
|
void CommonWebContentsDelegate::SetOwnerWindow(
|
2018-04-18 01:55:30 +00:00
|
|
|
content::WebContents* web_contents,
|
|
|
|
NativeWindow* owner_window) {
|
Implement initial, experimental BrowserView API
Right now, `<webview>` is the only way to embed additional content in a
`BrowserWindow`. Unfortunately `<webview>` suffers from a [number of
problems](https://github.com/electron/electron/issues?utf8=%E2%9C%93&q=is%3Aissue%20is%3Aopen%20label%3Awebview%20).
To make matters worse, many of these are upstream Chromium bugs instead
of Electron-specific bugs.
For us at [Figma](https://www.figma.com), the main issue is very slow
performance.
Despite the upstream improvements to `<webview>` through the OOPIF work, it is
probable that there will continue to be `<webview>`-specific bugs in the
future.
Therefore, this introduces a `<webview>` alternative to called `BrowserView`,
which...
- is a thin wrapper around `api::WebContents` (so bugs in `BrowserView` will
likely also be bugs in `BrowserWindow` web contents)
- is instantiated in the main process like `BrowserWindow` (and unlike
`<webview>`, which lives in the DOM of a `BrowserWindow` web contents)
- needs to be added to a `BrowserWindow` to display something on the screen
This implements the most basic API. The API is expected to evolve and change in
the near future and has consequently been marked as experimental. Please do not
use this API in production unless you are prepared to deal with breaking
changes.
In the future, we will want to change the API to support multiple
`BrowserView`s per window. We will also want to consider z-ordering
auto-resizing, and possibly even nested views.
2017-04-11 17:47:30 +00:00
|
|
|
owner_window_ = owner_window ? owner_window->GetWeakPtr() : nullptr;
|
2018-04-12 12:48:32 +00:00
|
|
|
auto relay = std::make_unique<NativeWindowRelay>(owner_window_);
|
2018-04-17 22:41:47 +00:00
|
|
|
auto* relay_key = relay->key;
|
Implement initial, experimental BrowserView API
Right now, `<webview>` is the only way to embed additional content in a
`BrowserWindow`. Unfortunately `<webview>` suffers from a [number of
problems](https://github.com/electron/electron/issues?utf8=%E2%9C%93&q=is%3Aissue%20is%3Aopen%20label%3Awebview%20).
To make matters worse, many of these are upstream Chromium bugs instead
of Electron-specific bugs.
For us at [Figma](https://www.figma.com), the main issue is very slow
performance.
Despite the upstream improvements to `<webview>` through the OOPIF work, it is
probable that there will continue to be `<webview>`-specific bugs in the
future.
Therefore, this introduces a `<webview>` alternative to called `BrowserView`,
which...
- is a thin wrapper around `api::WebContents` (so bugs in `BrowserView` will
likely also be bugs in `BrowserWindow` web contents)
- is instantiated in the main process like `BrowserWindow` (and unlike
`<webview>`, which lives in the DOM of a `BrowserWindow` web contents)
- needs to be added to a `BrowserWindow` to display something on the screen
This implements the most basic API. The API is expected to evolve and change in
the near future and has consequently been marked as experimental. Please do not
use this API in production unless you are prepared to deal with breaking
changes.
In the future, we will want to change the API to support multiple
`BrowserView`s per window. We will also want to consider z-ordering
auto-resizing, and possibly even nested views.
2017-04-11 17:47:30 +00:00
|
|
|
if (owner_window) {
|
2018-05-10 20:52:17 +00:00
|
|
|
#if defined(TOOLKIT_VIEWS) && !defined(OS_MACOSX)
|
2018-04-05 00:53:51 +00:00
|
|
|
autofill_popup_.reset(new AutofillPopup());
|
|
|
|
#endif
|
2017-10-09 13:33:30 +00:00
|
|
|
web_contents->SetUserData(relay_key, std::move(relay));
|
Implement initial, experimental BrowserView API
Right now, `<webview>` is the only way to embed additional content in a
`BrowserWindow`. Unfortunately `<webview>` suffers from a [number of
problems](https://github.com/electron/electron/issues?utf8=%E2%9C%93&q=is%3Aissue%20is%3Aopen%20label%3Awebview%20).
To make matters worse, many of these are upstream Chromium bugs instead
of Electron-specific bugs.
For us at [Figma](https://www.figma.com), the main issue is very slow
performance.
Despite the upstream improvements to `<webview>` through the OOPIF work, it is
probable that there will continue to be `<webview>`-specific bugs in the
future.
Therefore, this introduces a `<webview>` alternative to called `BrowserView`,
which...
- is a thin wrapper around `api::WebContents` (so bugs in `BrowserView` will
likely also be bugs in `BrowserWindow` web contents)
- is instantiated in the main process like `BrowserWindow` (and unlike
`<webview>`, which lives in the DOM of a `BrowserWindow` web contents)
- needs to be added to a `BrowserWindow` to display something on the screen
This implements the most basic API. The API is expected to evolve and change in
the near future and has consequently been marked as experimental. Please do not
use this API in production unless you are prepared to deal with breaking
changes.
In the future, we will want to change the API to support multiple
`BrowserView`s per window. We will also want to consider z-ordering
auto-resizing, and possibly even nested views.
2017-04-11 17:47:30 +00:00
|
|
|
} else {
|
2017-10-09 13:33:30 +00:00
|
|
|
web_contents->RemoveUserData(relay_key);
|
2017-08-07 20:30:03 +00:00
|
|
|
relay.reset();
|
Implement initial, experimental BrowserView API
Right now, `<webview>` is the only way to embed additional content in a
`BrowserWindow`. Unfortunately `<webview>` suffers from a [number of
problems](https://github.com/electron/electron/issues?utf8=%E2%9C%93&q=is%3Aissue%20is%3Aopen%20label%3Awebview%20).
To make matters worse, many of these are upstream Chromium bugs instead
of Electron-specific bugs.
For us at [Figma](https://www.figma.com), the main issue is very slow
performance.
Despite the upstream improvements to `<webview>` through the OOPIF work, it is
probable that there will continue to be `<webview>`-specific bugs in the
future.
Therefore, this introduces a `<webview>` alternative to called `BrowserView`,
which...
- is a thin wrapper around `api::WebContents` (so bugs in `BrowserView` will
likely also be bugs in `BrowserWindow` web contents)
- is instantiated in the main process like `BrowserWindow` (and unlike
`<webview>`, which lives in the DOM of a `BrowserWindow` web contents)
- needs to be added to a `BrowserWindow` to display something on the screen
This implements the most basic API. The API is expected to evolve and change in
the near future and has consequently been marked as experimental. Please do not
use this API in production unless you are prepared to deal with breaking
changes.
In the future, we will want to change the API to support multiple
`BrowserView`s per window. We will also want to consider z-ordering
auto-resizing, and possibly even nested views.
2017-04-11 17:47:30 +00:00
|
|
|
}
|
2015-06-24 15:29:32 +00:00
|
|
|
}
|
|
|
|
|
2017-04-03 20:03:51 +00:00
|
|
|
void CommonWebContentsDelegate::ResetManagedWebContents(bool async) {
|
|
|
|
if (async) {
|
|
|
|
base::ThreadTaskRunnerHandle::Get()->DeleteSoon(FROM_HERE,
|
|
|
|
web_contents_.release());
|
|
|
|
} else {
|
|
|
|
web_contents_.reset();
|
|
|
|
}
|
2015-06-05 06:55:07 +00:00
|
|
|
}
|
|
|
|
|
2015-06-05 09:27:24 +00:00
|
|
|
content::WebContents* CommonWebContentsDelegate::GetWebContents() const {
|
|
|
|
if (!web_contents_)
|
|
|
|
return nullptr;
|
|
|
|
return web_contents_->GetWebContents();
|
|
|
|
}
|
|
|
|
|
2018-04-18 01:55:30 +00:00
|
|
|
content::WebContents* CommonWebContentsDelegate::GetDevToolsWebContents()
|
|
|
|
const {
|
2015-06-05 09:27:24 +00:00
|
|
|
if (!web_contents_)
|
|
|
|
return nullptr;
|
|
|
|
return web_contents_->GetDevToolsWebContents();
|
|
|
|
}
|
|
|
|
|
2015-06-05 09:45:17 +00:00
|
|
|
content::WebContents* CommonWebContentsDelegate::OpenURLFromTab(
|
|
|
|
content::WebContents* source,
|
|
|
|
const content::OpenURLParams& params) {
|
|
|
|
content::NavigationController::LoadURLParams load_url_params(params.url);
|
|
|
|
load_url_params.referrer = params.referrer;
|
|
|
|
load_url_params.transition_type = params.transition;
|
|
|
|
load_url_params.extra_headers = params.extra_headers;
|
|
|
|
load_url_params.should_replace_current_entry =
|
|
|
|
params.should_replace_current_entry;
|
|
|
|
load_url_params.is_renderer_initiated = params.is_renderer_initiated;
|
|
|
|
load_url_params.should_clear_history_list = true;
|
|
|
|
|
|
|
|
source->GetController().LoadURLWithParams(load_url_params);
|
|
|
|
return source;
|
|
|
|
}
|
|
|
|
|
2015-06-05 07:12:38 +00:00
|
|
|
bool CommonWebContentsDelegate::CanOverscrollContent() const {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
content::ColorChooser* CommonWebContentsDelegate::OpenColorChooser(
|
|
|
|
content::WebContents* web_contents,
|
|
|
|
SkColor color,
|
2018-04-08 16:17:23 +00:00
|
|
|
const std::vector<blink::mojom::ColorSuggestionPtr>& suggestions) {
|
2015-06-05 07:12:38 +00:00
|
|
|
return chrome::ShowColorChooser(web_contents, color);
|
|
|
|
}
|
|
|
|
|
|
|
|
void CommonWebContentsDelegate::RunFileChooser(
|
2016-09-06 08:24:37 +00:00
|
|
|
content::RenderFrameHost* render_frame_host,
|
2015-06-05 07:12:38 +00:00
|
|
|
const content::FileChooserParams& params) {
|
|
|
|
if (!web_dialog_helper_)
|
2018-04-03 03:19:35 +00:00
|
|
|
web_dialog_helper_.reset(new WebDialogHelper(owner_window(), offscreen_));
|
2016-09-06 08:24:37 +00:00
|
|
|
web_dialog_helper_->RunFileChooser(render_frame_host, params);
|
2015-06-05 07:12:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void CommonWebContentsDelegate::EnumerateDirectory(content::WebContents* guest,
|
|
|
|
int request_id,
|
|
|
|
const base::FilePath& path) {
|
|
|
|
if (!web_dialog_helper_)
|
2018-04-03 03:19:35 +00:00
|
|
|
web_dialog_helper_.reset(new WebDialogHelper(owner_window(), offscreen_));
|
2015-06-05 07:12:38 +00:00
|
|
|
web_dialog_helper_->EnumerateDirectory(guest, request_id, path);
|
|
|
|
}
|
|
|
|
|
2015-06-05 09:27:24 +00:00
|
|
|
void CommonWebContentsDelegate::EnterFullscreenModeForTab(
|
2018-04-18 01:55:30 +00:00
|
|
|
content::WebContents* source,
|
2018-09-15 00:17:50 +00:00
|
|
|
const GURL& origin,
|
|
|
|
const blink::WebFullscreenOptions& options) {
|
2015-06-05 09:27:24 +00:00
|
|
|
if (!owner_window_)
|
|
|
|
return;
|
|
|
|
SetHtmlApiFullscreen(true);
|
|
|
|
owner_window_->NotifyWindowEnterHtmlFullScreen();
|
2018-09-15 00:19:53 +00:00
|
|
|
source->GetRenderViewHost()->GetWidget()->SynchronizeVisualProperties();
|
2015-06-05 06:55:07 +00:00
|
|
|
}
|
|
|
|
|
2015-06-05 09:27:24 +00:00
|
|
|
void CommonWebContentsDelegate::ExitFullscreenModeForTab(
|
|
|
|
content::WebContents* source) {
|
|
|
|
if (!owner_window_)
|
|
|
|
return;
|
|
|
|
SetHtmlApiFullscreen(false);
|
|
|
|
owner_window_->NotifyWindowLeaveHtmlFullScreen();
|
2018-09-15 00:19:53 +00:00
|
|
|
source->GetRenderViewHost()->GetWidget()->SynchronizeVisualProperties();
|
2015-06-05 09:27:24 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
bool CommonWebContentsDelegate::IsFullscreenForTabOrPending(
|
|
|
|
const content::WebContents* source) const {
|
|
|
|
return html_fullscreen_;
|
2015-06-05 06:55:07 +00:00
|
|
|
}
|
|
|
|
|
2017-01-23 09:59:40 +00:00
|
|
|
blink::WebSecurityStyle CommonWebContentsDelegate::GetSecurityStyle(
|
2016-04-11 09:36:33 +00:00
|
|
|
content::WebContents* web_contents,
|
2017-01-24 01:51:11 +00:00
|
|
|
content::SecurityStyleExplanations* security_style_explanations) {
|
|
|
|
SecurityStateTabHelper* helper =
|
|
|
|
SecurityStateTabHelper::FromWebContents(web_contents);
|
|
|
|
DCHECK(helper);
|
|
|
|
security_state::SecurityInfo security_info;
|
|
|
|
helper->GetSecurityInfo(&security_info);
|
|
|
|
return security_state::GetSecurityStyle(security_info,
|
|
|
|
security_style_explanations);
|
2016-04-11 09:36:33 +00:00
|
|
|
}
|
|
|
|
|
2018-04-18 01:55:30 +00:00
|
|
|
void CommonWebContentsDelegate::DevToolsSaveToFile(const std::string& url,
|
|
|
|
const std::string& content,
|
|
|
|
bool save_as) {
|
2015-06-05 06:55:07 +00:00
|
|
|
base::FilePath path;
|
2016-07-10 11:09:55 +00:00
|
|
|
auto it = saved_files_.find(url);
|
2015-06-05 06:55:07 +00:00
|
|
|
if (it != saved_files_.end() && !save_as) {
|
|
|
|
path = it->second;
|
|
|
|
} else {
|
2017-02-08 01:32:58 +00:00
|
|
|
file_dialog::DialogSettings settings;
|
|
|
|
settings.parent_window = owner_window();
|
2018-04-03 03:19:35 +00:00
|
|
|
settings.force_detached = offscreen_;
|
2017-02-08 01:32:58 +00:00
|
|
|
settings.title = url;
|
|
|
|
settings.default_path = base::FilePath::FromUTF8Unsafe(url);
|
|
|
|
if (!file_dialog::ShowSaveDialog(settings, &path)) {
|
2017-06-16 20:50:03 +00:00
|
|
|
base::Value url_value(url);
|
2018-04-18 01:55:30 +00:00
|
|
|
web_contents_->CallClientFunction("DevToolsAPI.canceledSaveURL",
|
|
|
|
&url_value, nullptr, nullptr);
|
2015-06-05 06:55:07 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
saved_files_[url] = path;
|
2018-04-09 09:16:52 +00:00
|
|
|
// Notify DevTools.
|
|
|
|
base::Value url_value(url);
|
|
|
|
base::Value file_system_path_value(path.AsUTF8Unsafe());
|
|
|
|
web_contents_->CallClientFunction("DevToolsAPI.savedURL", &url_value,
|
|
|
|
&file_system_path_value, nullptr);
|
|
|
|
file_task_runner_->PostTask(FROM_HERE,
|
|
|
|
base::BindOnce(&WriteToFile, path, content));
|
2015-06-05 06:55:07 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void CommonWebContentsDelegate::DevToolsAppendToFile(
|
2018-04-18 01:55:30 +00:00
|
|
|
const std::string& url,
|
|
|
|
const std::string& content) {
|
2016-07-10 11:09:55 +00:00
|
|
|
auto it = saved_files_.find(url);
|
2015-06-05 06:55:07 +00:00
|
|
|
if (it == saved_files_.end())
|
|
|
|
return;
|
|
|
|
|
2018-04-09 09:16:52 +00:00
|
|
|
// Notify DevTools.
|
|
|
|
base::Value url_value(url);
|
|
|
|
web_contents_->CallClientFunction("DevToolsAPI.appendedToURL", &url_value,
|
|
|
|
nullptr, nullptr);
|
|
|
|
file_task_runner_->PostTask(
|
|
|
|
FROM_HERE, base::BindOnce(&AppendToFile, it->second, content));
|
2015-06-05 06:55:07 +00:00
|
|
|
}
|
|
|
|
|
2016-03-15 02:21:36 +00:00
|
|
|
void CommonWebContentsDelegate::DevToolsRequestFileSystems() {
|
|
|
|
auto file_system_paths = GetAddedFileSystemPaths(GetDevToolsWebContents());
|
|
|
|
if (file_system_paths.empty()) {
|
|
|
|
base::ListValue empty_file_system_value;
|
|
|
|
web_contents_->CallClientFunction("DevToolsAPI.fileSystemsLoaded",
|
2018-04-18 01:55:30 +00:00
|
|
|
&empty_file_system_value, nullptr,
|
|
|
|
nullptr);
|
2016-03-15 02:21:36 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
std::vector<FileSystem> file_systems;
|
2017-03-30 19:56:28 +00:00
|
|
|
for (const auto& file_system_path : file_system_paths) {
|
2018-09-12 13:45:08 +00:00
|
|
|
base::FilePath path =
|
|
|
|
base::FilePath::FromUTF8Unsafe(file_system_path.first);
|
2018-04-18 01:55:30 +00:00
|
|
|
std::string file_system_id =
|
|
|
|
RegisterFileSystem(GetDevToolsWebContents(), path);
|
2018-09-12 13:45:08 +00:00
|
|
|
FileSystem file_system =
|
|
|
|
CreateFileSystemStruct(GetDevToolsWebContents(), file_system_id,
|
|
|
|
file_system_path.first, file_system_path.second);
|
2016-03-15 02:21:36 +00:00
|
|
|
file_systems.push_back(file_system);
|
|
|
|
}
|
|
|
|
|
|
|
|
base::ListValue file_system_value;
|
2016-07-10 13:56:42 +00:00
|
|
|
for (const auto& file_system : file_systems)
|
2016-07-10 11:32:40 +00:00
|
|
|
file_system_value.Append(CreateFileSystemValue(file_system));
|
2016-03-15 02:21:36 +00:00
|
|
|
web_contents_->CallClientFunction("DevToolsAPI.fileSystemsLoaded",
|
|
|
|
&file_system_value, nullptr, nullptr);
|
|
|
|
}
|
|
|
|
|
2015-07-24 09:39:11 +00:00
|
|
|
void CommonWebContentsDelegate::DevToolsAddFileSystem(
|
2018-09-12 13:45:08 +00:00
|
|
|
const std::string& type,
|
2015-07-24 09:39:11 +00:00
|
|
|
const base::FilePath& file_system_path) {
|
|
|
|
base::FilePath path = file_system_path;
|
|
|
|
if (path.empty()) {
|
|
|
|
std::vector<base::FilePath> paths;
|
2017-02-08 01:32:58 +00:00
|
|
|
file_dialog::DialogSettings settings;
|
|
|
|
settings.parent_window = owner_window();
|
2018-04-03 03:19:35 +00:00
|
|
|
settings.force_detached = offscreen_;
|
2017-02-08 01:32:58 +00:00
|
|
|
settings.properties = file_dialog::FILE_DIALOG_OPEN_DIRECTORY;
|
|
|
|
if (!file_dialog::ShowOpenDialog(settings, &paths))
|
2015-07-24 09:39:11 +00:00
|
|
|
return;
|
|
|
|
|
|
|
|
path = paths[0];
|
|
|
|
}
|
2015-06-05 06:55:07 +00:00
|
|
|
|
2018-04-18 01:55:30 +00:00
|
|
|
std::string file_system_id =
|
|
|
|
RegisterFileSystem(GetDevToolsWebContents(), path);
|
2016-05-06 23:02:54 +00:00
|
|
|
if (IsDevToolsFileSystemAdded(GetDevToolsWebContents(), path.AsUTF8Unsafe()))
|
2015-06-05 06:55:07 +00:00
|
|
|
return;
|
|
|
|
|
2018-04-18 01:55:30 +00:00
|
|
|
FileSystem file_system = CreateFileSystemStruct(
|
2018-09-12 13:45:08 +00:00
|
|
|
GetDevToolsWebContents(), file_system_id, path.AsUTF8Unsafe(), type);
|
2016-05-23 01:59:39 +00:00
|
|
|
std::unique_ptr<base::DictionaryValue> file_system_value(
|
2016-03-15 02:21:36 +00:00
|
|
|
CreateFileSystemValue(file_system));
|
|
|
|
|
2018-04-17 22:41:47 +00:00
|
|
|
auto* pref_service = GetPrefService(GetDevToolsWebContents());
|
2016-03-15 02:21:36 +00:00
|
|
|
DictionaryPrefUpdate update(pref_service, prefs::kDevToolsFileSystemPaths);
|
2018-04-18 01:55:30 +00:00
|
|
|
update.Get()->SetWithoutPathExpansion(path.AsUTF8Unsafe(),
|
2018-09-12 13:45:08 +00:00
|
|
|
std::make_unique<base::Value>(type));
|
|
|
|
web_contents_->CallClientFunction("DevToolsAPI.fileSystemAdded", nullptr,
|
|
|
|
file_system_value.get(), nullptr);
|
2015-06-05 06:55:07 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void CommonWebContentsDelegate::DevToolsRemoveFileSystem(
|
2015-07-24 09:39:11 +00:00
|
|
|
const base::FilePath& file_system_path) {
|
2015-06-05 06:55:07 +00:00
|
|
|
if (!web_contents_)
|
|
|
|
return;
|
|
|
|
|
2016-03-15 02:21:36 +00:00
|
|
|
std::string path = file_system_path.AsUTF8Unsafe();
|
2018-04-18 01:55:30 +00:00
|
|
|
storage::IsolatedContext::GetInstance()->RevokeFileSystemByPath(
|
|
|
|
file_system_path);
|
2015-06-05 06:55:07 +00:00
|
|
|
|
2018-04-17 22:41:47 +00:00
|
|
|
auto* pref_service = GetPrefService(GetDevToolsWebContents());
|
2016-03-15 02:21:36 +00:00
|
|
|
DictionaryPrefUpdate update(pref_service, prefs::kDevToolsFileSystemPaths);
|
|
|
|
update.Get()->RemoveWithoutPathExpansion(path, nullptr);
|
2015-06-05 06:55:07 +00:00
|
|
|
|
2017-06-16 20:50:03 +00:00
|
|
|
base::Value file_system_path_value(path);
|
2016-03-15 02:21:36 +00:00
|
|
|
web_contents_->CallClientFunction("DevToolsAPI.fileSystemRemoved",
|
2018-04-18 01:55:30 +00:00
|
|
|
&file_system_path_value, nullptr, nullptr);
|
2015-06-05 06:55:07 +00:00
|
|
|
}
|
|
|
|
|
2016-05-06 23:02:54 +00:00
|
|
|
void CommonWebContentsDelegate::DevToolsIndexPath(
|
|
|
|
int request_id,
|
2018-09-12 13:45:08 +00:00
|
|
|
const std::string& file_system_path,
|
|
|
|
const std::string& excluded_folders_message) {
|
2016-05-06 23:02:54 +00:00
|
|
|
if (!IsDevToolsFileSystemAdded(GetDevToolsWebContents(), file_system_path)) {
|
|
|
|
OnDevToolsIndexingDone(request_id, file_system_path);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
if (devtools_indexing_jobs_.count(request_id) != 0)
|
|
|
|
return;
|
2018-09-12 13:45:08 +00:00
|
|
|
std::vector<std::string> excluded_folders;
|
|
|
|
std::unique_ptr<base::Value> parsed_excluded_folders =
|
|
|
|
base::JSONReader::Read(excluded_folders_message);
|
|
|
|
if (parsed_excluded_folders && parsed_excluded_folders->is_list()) {
|
|
|
|
const std::vector<base::Value>& folder_paths =
|
|
|
|
parsed_excluded_folders->GetList();
|
|
|
|
for (const base::Value& folder_path : folder_paths) {
|
|
|
|
if (folder_path.is_string())
|
|
|
|
excluded_folders.push_back(folder_path.GetString());
|
|
|
|
}
|
|
|
|
}
|
2016-05-06 23:02:54 +00:00
|
|
|
devtools_indexing_jobs_[request_id] =
|
|
|
|
scoped_refptr<DevToolsFileSystemIndexer::FileSystemIndexingJob>(
|
|
|
|
devtools_file_system_indexer_->IndexPath(
|
2018-09-12 13:45:08 +00:00
|
|
|
file_system_path, excluded_folders,
|
2016-05-06 23:02:54 +00:00
|
|
|
base::Bind(
|
|
|
|
&CommonWebContentsDelegate::OnDevToolsIndexingWorkCalculated,
|
2018-09-12 13:45:08 +00:00
|
|
|
weak_factory_.GetWeakPtr(), request_id, file_system_path),
|
2016-05-06 23:02:54 +00:00
|
|
|
base::Bind(&CommonWebContentsDelegate::OnDevToolsIndexingWorked,
|
2018-09-12 13:45:08 +00:00
|
|
|
weak_factory_.GetWeakPtr(), request_id,
|
|
|
|
file_system_path),
|
2016-05-06 23:02:54 +00:00
|
|
|
base::Bind(&CommonWebContentsDelegate::OnDevToolsIndexingDone,
|
2018-09-12 13:45:08 +00:00
|
|
|
weak_factory_.GetWeakPtr(), request_id,
|
2016-05-06 23:02:54 +00:00
|
|
|
file_system_path)));
|
|
|
|
}
|
|
|
|
|
|
|
|
void CommonWebContentsDelegate::DevToolsStopIndexing(int request_id) {
|
|
|
|
auto it = devtools_indexing_jobs_.find(request_id);
|
|
|
|
if (it == devtools_indexing_jobs_.end())
|
|
|
|
return;
|
|
|
|
it->second->Stop();
|
|
|
|
devtools_indexing_jobs_.erase(it);
|
|
|
|
}
|
|
|
|
|
|
|
|
void CommonWebContentsDelegate::DevToolsSearchInPath(
|
|
|
|
int request_id,
|
|
|
|
const std::string& file_system_path,
|
|
|
|
const std::string& query) {
|
|
|
|
if (!IsDevToolsFileSystemAdded(GetDevToolsWebContents(), file_system_path)) {
|
2018-04-18 01:55:30 +00:00
|
|
|
OnDevToolsSearchCompleted(request_id, file_system_path,
|
2016-05-06 23:02:54 +00:00
|
|
|
std::vector<std::string>());
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
devtools_file_system_indexer_->SearchInPath(
|
2018-04-18 01:55:30 +00:00
|
|
|
file_system_path, query,
|
2016-05-06 23:02:54 +00:00
|
|
|
base::Bind(&CommonWebContentsDelegate::OnDevToolsSearchCompleted,
|
2018-09-12 13:45:08 +00:00
|
|
|
weak_factory_.GetWeakPtr(), request_id, file_system_path));
|
2016-05-06 23:02:54 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void CommonWebContentsDelegate::OnDevToolsIndexingWorkCalculated(
|
|
|
|
int request_id,
|
|
|
|
const std::string& file_system_path,
|
|
|
|
int total_work) {
|
2017-04-05 08:34:53 +00:00
|
|
|
base::Value request_id_value(request_id);
|
2017-06-16 20:50:03 +00:00
|
|
|
base::Value file_system_path_value(file_system_path);
|
2017-04-05 08:34:53 +00:00
|
|
|
base::Value total_work_value(total_work);
|
2016-05-06 23:02:54 +00:00
|
|
|
web_contents_->CallClientFunction("DevToolsAPI.indexingTotalWorkCalculated",
|
2018-04-18 01:55:30 +00:00
|
|
|
&request_id_value, &file_system_path_value,
|
2016-05-06 23:02:54 +00:00
|
|
|
&total_work_value);
|
|
|
|
}
|
|
|
|
|
|
|
|
void CommonWebContentsDelegate::OnDevToolsIndexingWorked(
|
|
|
|
int request_id,
|
|
|
|
const std::string& file_system_path,
|
|
|
|
int worked) {
|
2017-04-05 08:34:53 +00:00
|
|
|
base::Value request_id_value(request_id);
|
2017-06-16 20:50:03 +00:00
|
|
|
base::Value file_system_path_value(file_system_path);
|
2017-04-05 08:34:53 +00:00
|
|
|
base::Value worked_value(worked);
|
2016-05-06 23:02:54 +00:00
|
|
|
web_contents_->CallClientFunction("DevToolsAPI.indexingWorked",
|
2018-04-18 01:55:30 +00:00
|
|
|
&request_id_value, &file_system_path_value,
|
2016-05-06 23:02:54 +00:00
|
|
|
&worked_value);
|
|
|
|
}
|
|
|
|
|
|
|
|
void CommonWebContentsDelegate::OnDevToolsIndexingDone(
|
|
|
|
int request_id,
|
|
|
|
const std::string& file_system_path) {
|
|
|
|
devtools_indexing_jobs_.erase(request_id);
|
2017-04-05 08:34:53 +00:00
|
|
|
base::Value request_id_value(request_id);
|
2017-06-16 20:50:03 +00:00
|
|
|
base::Value file_system_path_value(file_system_path);
|
2016-05-06 23:02:54 +00:00
|
|
|
web_contents_->CallClientFunction("DevToolsAPI.indexingDone",
|
2018-04-18 01:55:30 +00:00
|
|
|
&request_id_value, &file_system_path_value,
|
2016-05-06 23:02:54 +00:00
|
|
|
nullptr);
|
|
|
|
}
|
|
|
|
|
|
|
|
void CommonWebContentsDelegate::OnDevToolsSearchCompleted(
|
|
|
|
int request_id,
|
|
|
|
const std::string& file_system_path,
|
|
|
|
const std::vector<std::string>& file_paths) {
|
|
|
|
base::ListValue file_paths_value;
|
2016-07-10 11:32:40 +00:00
|
|
|
for (const auto& file_path : file_paths) {
|
|
|
|
file_paths_value.AppendString(file_path);
|
2016-05-06 23:02:54 +00:00
|
|
|
}
|
2017-04-05 08:34:53 +00:00
|
|
|
base::Value request_id_value(request_id);
|
2017-06-16 20:50:03 +00:00
|
|
|
base::Value file_system_path_value(file_system_path);
|
2016-05-06 23:02:54 +00:00
|
|
|
web_contents_->CallClientFunction("DevToolsAPI.searchCompleted",
|
2018-04-18 01:55:30 +00:00
|
|
|
&request_id_value, &file_system_path_value,
|
2016-05-06 23:02:54 +00:00
|
|
|
&file_paths_value);
|
|
|
|
}
|
|
|
|
|
2015-06-05 09:27:24 +00:00
|
|
|
void CommonWebContentsDelegate::SetHtmlApiFullscreen(bool enter_fullscreen) {
|
|
|
|
// Window is already in fullscreen mode, save the state.
|
|
|
|
if (enter_fullscreen && owner_window_->IsFullscreen()) {
|
|
|
|
native_fullscreen_ = true;
|
|
|
|
html_fullscreen_ = true;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Exit html fullscreen state but not window's fullscreen mode.
|
|
|
|
if (!enter_fullscreen && native_fullscreen_) {
|
|
|
|
html_fullscreen_ = false;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
owner_window_->SetFullScreen(enter_fullscreen);
|
|
|
|
html_fullscreen_ = enter_fullscreen;
|
|
|
|
native_fullscreen_ = false;
|
|
|
|
}
|
|
|
|
|
2015-06-05 05:49:12 +00:00
|
|
|
} // namespace atom
|