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"
|
|
|
|
|
2016-03-15 02:21:36 +00:00
|
|
|
#include <set>
|
2015-06-05 09:01:17 +00:00
|
|
|
#include <string>
|
|
|
|
#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/atom_javascript_dialog_manager.h"
|
2016-04-11 09:36:33 +00:00
|
|
|
#include "atom/browser/atom_security_state_model_client.h"
|
2015-06-05 06:55:07 +00:00
|
|
|
#include "atom/browser/native_window.h"
|
|
|
|
#include "atom/browser/ui/file_dialog.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"
|
2015-06-08 05:19:56 +00:00
|
|
|
#include "base/files/file_util.h"
|
2016-03-15 02:21:36 +00:00
|
|
|
#include "base/prefs/pref_service.h"
|
|
|
|
#include "base/prefs/scoped_user_pref_update.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"
|
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"
|
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-10-01 03:14:19 +00:00
|
|
|
#if defined(TOOLKIT_VIEWS)
|
|
|
|
#include "atom/browser/native_window_views.h"
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#if defined(USE_X11)
|
|
|
|
#include "atom/browser/browser.h"
|
|
|
|
#endif
|
|
|
|
|
2015-06-22 02:00:33 +00:00
|
|
|
using content::BrowserThread;
|
2016-04-11 09:36:33 +00:00
|
|
|
using security_state::SecurityStateModel;
|
2015-06-22 02:00:33 +00:00
|
|
|
|
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 {
|
|
|
|
FileSystem() {
|
|
|
|
}
|
|
|
|
FileSystem(const std::string& file_system_name,
|
|
|
|
const std::string& root_url,
|
|
|
|
const std::string& file_system_path)
|
|
|
|
: file_system_name(file_system_name),
|
|
|
|
root_url(root_url),
|
|
|
|
file_system_path(file_system_path) {
|
|
|
|
}
|
|
|
|
|
|
|
|
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) {
|
2015-06-05 06:55:07 +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(
|
|
|
|
storage::kFileSystemTypeNativeLocal,
|
|
|
|
std::string(),
|
|
|
|
path,
|
2016-03-15 02:21:36 +00:00
|
|
|
&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;
|
|
|
|
}
|
|
|
|
|
|
|
|
FileSystem CreateFileSystemStruct(
|
|
|
|
content::WebContents* web_contents,
|
|
|
|
const std::string& file_system_id,
|
|
|
|
const std::string& file_system_path) {
|
|
|
|
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);
|
2015-06-05 06:55:07 +00:00
|
|
|
return FileSystem(file_system_name, root_url, file_system_path);
|
|
|
|
}
|
|
|
|
|
|
|
|
base::DictionaryValue* CreateFileSystemValue(const FileSystem& file_system) {
|
|
|
|
base::DictionaryValue* file_system_value = new base::DictionaryValue();
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2015-06-22 02:00:33 +00:00
|
|
|
void WriteToFile(const base::FilePath& path,
|
|
|
|
const std::string& content) {
|
|
|
|
DCHECK_CURRENTLY_ON(BrowserThread::FILE);
|
|
|
|
DCHECK(!path.empty());
|
|
|
|
|
|
|
|
base::WriteFile(path, content.data(), content.size());
|
|
|
|
}
|
|
|
|
|
|
|
|
void AppendToFile(const base::FilePath& path,
|
|
|
|
const std::string& content) {
|
|
|
|
DCHECK_CURRENTLY_ON(BrowserThread::FILE);
|
|
|
|
DCHECK(!path.empty());
|
|
|
|
|
|
|
|
base::AppendToFile(path, content.data(), content.size());
|
|
|
|
}
|
|
|
|
|
2016-03-15 02:21:36 +00:00
|
|
|
PrefService* GetPrefService(content::WebContents* web_contents) {
|
|
|
|
auto context = web_contents->GetBrowserContext();
|
|
|
|
return static_cast<atom::AtomBrowserContext*>(context)->prefs();
|
|
|
|
}
|
|
|
|
|
|
|
|
std::set<std::string> GetAddedFileSystemPaths(
|
|
|
|
content::WebContents* web_contents) {
|
|
|
|
auto pref_service = GetPrefService(web_contents);
|
|
|
|
const base::DictionaryValue* file_system_paths_value =
|
|
|
|
pref_service->GetDictionary(prefs::kDevToolsFileSystemPaths);
|
|
|
|
std::set<std::string> result;
|
|
|
|
if (file_system_paths_value) {
|
|
|
|
base::DictionaryValue::Iterator it(*file_system_paths_value);
|
|
|
|
for (; !it.IsAtEnd(); it.Advance()) {
|
|
|
|
result.insert(it.key());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
2016-05-06 23:02:54 +00:00
|
|
|
bool IsDevToolsFileSystemAdded(
|
|
|
|
content::WebContents* web_contents,
|
|
|
|
const std::string& file_system_path) {
|
|
|
|
auto file_system_paths = GetAddedFileSystemPaths(web_contents);
|
|
|
|
return file_system_paths.find(file_system_path) != file_system_paths.end();
|
|
|
|
}
|
|
|
|
|
2016-04-11 09:36:33 +00:00
|
|
|
content::SecurityStyle SecurityLevelToSecurityStyle(
|
|
|
|
SecurityStateModel::SecurityLevel security_level) {
|
|
|
|
switch (security_level) {
|
|
|
|
case SecurityStateModel::NONE:
|
|
|
|
return content::SECURITY_STYLE_UNAUTHENTICATED;
|
|
|
|
case SecurityStateModel::SECURITY_WARNING:
|
|
|
|
case SecurityStateModel::SECURITY_POLICY_WARNING:
|
|
|
|
return content::SECURITY_STYLE_WARNING;
|
|
|
|
case SecurityStateModel::EV_SECURE:
|
|
|
|
case SecurityStateModel::SECURE:
|
|
|
|
return content::SECURITY_STYLE_AUTHENTICATED;
|
|
|
|
case SecurityStateModel::SECURITY_ERROR:
|
|
|
|
return content::SECURITY_STYLE_AUTHENTICATION_BROKEN;
|
|
|
|
}
|
|
|
|
|
|
|
|
return content::SECURITY_STYLE_UNKNOWN;
|
|
|
|
}
|
|
|
|
|
2015-06-05 06:55:07 +00:00
|
|
|
} // namespace
|
|
|
|
|
2015-06-24 14:23:38 +00:00
|
|
|
CommonWebContentsDelegate::CommonWebContentsDelegate()
|
2015-06-24 14:29:44 +00:00
|
|
|
: html_fullscreen_(false),
|
2016-05-06 23:02:54 +00:00
|
|
|
native_fullscreen_(false),
|
|
|
|
devtools_file_system_indexer_(new DevToolsFileSystemIndexer) {
|
2015-06-05 05:49:12 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
CommonWebContentsDelegate::~CommonWebContentsDelegate() {
|
|
|
|
}
|
|
|
|
|
2015-06-05 06:55:07 +00:00
|
|
|
void CommonWebContentsDelegate::InitWithWebContents(
|
2015-06-24 15:29:32 +00:00
|
|
|
content::WebContents* web_contents) {
|
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);
|
|
|
|
|
2015-06-05 06:55:07 +00:00
|
|
|
// Create InspectableWebContents.
|
|
|
|
web_contents_.reset(brightray::InspectableWebContents::Create(web_contents));
|
|
|
|
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(
|
|
|
|
content::WebContents* web_contents, NativeWindow* owner_window) {
|
2015-06-24 15:29:32 +00:00
|
|
|
owner_window_ = owner_window->GetWeakPtr();
|
|
|
|
NativeWindowRelay* relay = new NativeWindowRelay(owner_window_);
|
|
|
|
web_contents->SetUserData(relay->key, relay);
|
|
|
|
}
|
|
|
|
|
2015-06-05 06:55:07 +00:00
|
|
|
void CommonWebContentsDelegate::DestroyWebContents() {
|
|
|
|
web_contents_.reset();
|
|
|
|
}
|
|
|
|
|
2015-06-05 09:27:24 +00:00
|
|
|
content::WebContents* CommonWebContentsDelegate::GetWebContents() const {
|
|
|
|
if (!web_contents_)
|
|
|
|
return nullptr;
|
|
|
|
return web_contents_->GetWebContents();
|
|
|
|
}
|
|
|
|
|
|
|
|
content::WebContents*
|
|
|
|
CommonWebContentsDelegate::GetDevToolsWebContents() const {
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2015-06-05 06:55:07 +00:00
|
|
|
content::JavaScriptDialogManager*
|
|
|
|
CommonWebContentsDelegate::GetJavaScriptDialogManager(
|
|
|
|
content::WebContents* source) {
|
|
|
|
if (!dialog_manager_)
|
|
|
|
dialog_manager_.reset(new AtomJavaScriptDialogManager);
|
|
|
|
|
|
|
|
return dialog_manager_.get();
|
|
|
|
}
|
|
|
|
|
2015-06-05 07:12:38 +00:00
|
|
|
content::ColorChooser* CommonWebContentsDelegate::OpenColorChooser(
|
|
|
|
content::WebContents* web_contents,
|
|
|
|
SkColor color,
|
|
|
|
const std::vector<content::ColorSuggestion>& suggestions) {
|
|
|
|
return chrome::ShowColorChooser(web_contents, color);
|
|
|
|
}
|
|
|
|
|
|
|
|
void CommonWebContentsDelegate::RunFileChooser(
|
|
|
|
content::WebContents* guest,
|
|
|
|
const content::FileChooserParams& params) {
|
|
|
|
if (!web_dialog_helper_)
|
2015-06-24 14:29:44 +00:00
|
|
|
web_dialog_helper_.reset(new WebDialogHelper(owner_window()));
|
2015-06-05 07:12:38 +00:00
|
|
|
web_dialog_helper_->RunFileChooser(guest, params);
|
|
|
|
}
|
|
|
|
|
|
|
|
void CommonWebContentsDelegate::EnumerateDirectory(content::WebContents* guest,
|
|
|
|
int request_id,
|
|
|
|
const base::FilePath& path) {
|
|
|
|
if (!web_dialog_helper_)
|
2015-06-24 14:29:44 +00:00
|
|
|
web_dialog_helper_.reset(new WebDialogHelper(owner_window()));
|
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(
|
|
|
|
content::WebContents* source, const GURL& origin) {
|
|
|
|
if (!owner_window_)
|
|
|
|
return;
|
|
|
|
SetHtmlApiFullscreen(true);
|
|
|
|
owner_window_->NotifyWindowEnterHtmlFullScreen();
|
2016-03-08 14:28:53 +00:00
|
|
|
source->GetRenderViewHost()->GetWidget()->WasResized();
|
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();
|
2016-03-08 14:28:53 +00:00
|
|
|
source->GetRenderViewHost()->GetWidget()->WasResized();
|
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
|
|
|
}
|
|
|
|
|
2016-04-11 09:36:33 +00:00
|
|
|
content::SecurityStyle CommonWebContentsDelegate::GetSecurityStyle(
|
|
|
|
content::WebContents* web_contents,
|
|
|
|
content::SecurityStyleExplanations* explanations) {
|
|
|
|
auto model_client =
|
|
|
|
AtomSecurityStateModelClient::FromWebContents(web_contents);
|
|
|
|
|
|
|
|
const SecurityStateModel::SecurityInfo& security_info =
|
|
|
|
model_client->GetSecurityInfo();
|
|
|
|
|
|
|
|
const content::SecurityStyle security_style =
|
|
|
|
SecurityLevelToSecurityStyle(security_info.security_level);
|
|
|
|
|
|
|
|
explanations->ran_insecure_content_style =
|
|
|
|
SecurityLevelToSecurityStyle(
|
|
|
|
SecurityStateModel::kRanInsecureContentLevel);
|
|
|
|
explanations->displayed_insecure_content_style =
|
|
|
|
SecurityLevelToSecurityStyle(
|
|
|
|
SecurityStateModel::kDisplayedInsecureContentLevel);
|
|
|
|
|
|
|
|
explanations->scheme_is_cryptographic = security_info.scheme_is_cryptographic;
|
|
|
|
if (!security_info.scheme_is_cryptographic)
|
|
|
|
return security_style;
|
|
|
|
|
|
|
|
if (security_info.sha1_deprecation_status ==
|
|
|
|
SecurityStateModel::DEPRECATED_SHA1_MAJOR) {
|
|
|
|
explanations->broken_explanations.push_back(
|
|
|
|
content::SecurityStyleExplanation(
|
|
|
|
kSHA1Certificate,
|
|
|
|
kSHA1MajorDescription,
|
|
|
|
security_info.cert_id));
|
|
|
|
} else if (security_info.sha1_deprecation_status ==
|
|
|
|
SecurityStateModel::DEPRECATED_SHA1_MINOR) {
|
|
|
|
explanations->unauthenticated_explanations.push_back(
|
|
|
|
content::SecurityStyleExplanation(
|
|
|
|
kSHA1Certificate,
|
|
|
|
kSHA1MinorDescription,
|
|
|
|
security_info.cert_id));
|
|
|
|
}
|
|
|
|
|
|
|
|
explanations->ran_insecure_content =
|
|
|
|
security_info.mixed_content_status ==
|
|
|
|
SecurityStateModel::RAN_MIXED_CONTENT ||
|
|
|
|
security_info.mixed_content_status ==
|
|
|
|
SecurityStateModel::RAN_AND_DISPLAYED_MIXED_CONTENT;
|
|
|
|
explanations->displayed_insecure_content =
|
|
|
|
security_info.mixed_content_status ==
|
|
|
|
SecurityStateModel::DISPLAYED_MIXED_CONTENT ||
|
|
|
|
security_info.mixed_content_status ==
|
|
|
|
SecurityStateModel::RAN_AND_DISPLAYED_MIXED_CONTENT;
|
|
|
|
|
|
|
|
if (net::IsCertStatusError(security_info.cert_status)) {
|
|
|
|
std::string error_string = net::ErrorToString(
|
|
|
|
net::MapCertStatusToNetError(security_info.cert_status));
|
|
|
|
|
|
|
|
content::SecurityStyleExplanation explanation(
|
|
|
|
kCertificateError,
|
|
|
|
"There are issues with the site's certificate chain " + error_string,
|
|
|
|
security_info.cert_id);
|
|
|
|
|
|
|
|
if (net::IsCertStatusMinorError(security_info.cert_status))
|
|
|
|
explanations->unauthenticated_explanations.push_back(explanation);
|
|
|
|
else
|
|
|
|
explanations->broken_explanations.push_back(explanation);
|
|
|
|
} else {
|
|
|
|
if (security_info.sha1_deprecation_status ==
|
|
|
|
SecurityStateModel::NO_DEPRECATED_SHA1) {
|
|
|
|
explanations->secure_explanations.push_back(
|
|
|
|
content::SecurityStyleExplanation(
|
|
|
|
kValidCertificate,
|
|
|
|
kValidCertificateDescription,
|
|
|
|
security_info.cert_id));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (security_info.is_secure_protocol_and_ciphersuite) {
|
|
|
|
explanations->secure_explanations.push_back(
|
|
|
|
content::SecurityStyleExplanation(
|
|
|
|
kSecureProtocol,
|
|
|
|
kSecureProtocolDescription));
|
|
|
|
}
|
|
|
|
|
|
|
|
return security_style;
|
|
|
|
}
|
|
|
|
|
2015-06-05 06:55:07 +00:00
|
|
|
void CommonWebContentsDelegate::DevToolsSaveToFile(
|
|
|
|
const std::string& url, const std::string& content, bool save_as) {
|
|
|
|
base::FilePath path;
|
|
|
|
PathsMap::iterator it = saved_files_.find(url);
|
|
|
|
if (it != saved_files_.end() && !save_as) {
|
|
|
|
path = it->second;
|
|
|
|
} else {
|
|
|
|
file_dialog::Filters filters;
|
|
|
|
base::FilePath default_path(base::FilePath::FromUTF8Unsafe(url));
|
2015-06-24 14:29:44 +00:00
|
|
|
if (!file_dialog::ShowSaveDialog(owner_window(), url, default_path,
|
2015-06-05 06:55:07 +00:00
|
|
|
filters, &path)) {
|
|
|
|
base::StringValue url_value(url);
|
|
|
|
web_contents_->CallClientFunction(
|
|
|
|
"DevToolsAPI.canceledSaveURL", &url_value, nullptr, nullptr);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
saved_files_[url] = path;
|
2015-06-22 02:00:33 +00:00
|
|
|
BrowserThread::PostTaskAndReply(
|
|
|
|
BrowserThread::FILE, FROM_HERE,
|
|
|
|
base::Bind(&WriteToFile, path, content),
|
|
|
|
base::Bind(&CommonWebContentsDelegate::OnDevToolsSaveToFile,
|
|
|
|
base::Unretained(this), url));
|
2015-06-05 06:55:07 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void CommonWebContentsDelegate::DevToolsAppendToFile(
|
|
|
|
const std::string& url, const std::string& content) {
|
|
|
|
PathsMap::iterator it = saved_files_.find(url);
|
|
|
|
if (it == saved_files_.end())
|
|
|
|
return;
|
|
|
|
|
2015-06-22 02:00:33 +00:00
|
|
|
BrowserThread::PostTaskAndReply(
|
|
|
|
BrowserThread::FILE, FROM_HERE,
|
|
|
|
base::Bind(&AppendToFile, it->second, content),
|
|
|
|
base::Bind(&CommonWebContentsDelegate::OnDevToolsAppendToFile,
|
|
|
|
base::Unretained(this), url));
|
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",
|
|
|
|
&empty_file_system_value,
|
|
|
|
nullptr, nullptr);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
std::vector<FileSystem> file_systems;
|
|
|
|
for (auto file_system_path : file_system_paths) {
|
|
|
|
base::FilePath path = base::FilePath::FromUTF8Unsafe(file_system_path);
|
|
|
|
std::string file_system_id = RegisterFileSystem(GetDevToolsWebContents(),
|
|
|
|
path);
|
|
|
|
FileSystem file_system = CreateFileSystemStruct(GetDevToolsWebContents(),
|
|
|
|
file_system_id,
|
|
|
|
file_system_path);
|
|
|
|
file_systems.push_back(file_system);
|
|
|
|
}
|
|
|
|
|
|
|
|
base::ListValue file_system_value;
|
|
|
|
for (size_t i = 0; i < file_systems.size(); ++i)
|
|
|
|
file_system_value.Append(CreateFileSystemValue(file_systems[i]));
|
|
|
|
web_contents_->CallClientFunction("DevToolsAPI.fileSystemsLoaded",
|
|
|
|
&file_system_value, nullptr, nullptr);
|
|
|
|
}
|
|
|
|
|
2015-07-24 09:39:11 +00:00
|
|
|
void CommonWebContentsDelegate::DevToolsAddFileSystem(
|
|
|
|
const base::FilePath& file_system_path) {
|
|
|
|
base::FilePath path = file_system_path;
|
|
|
|
if (path.empty()) {
|
|
|
|
file_dialog::Filters filters;
|
|
|
|
base::FilePath default_path;
|
|
|
|
std::vector<base::FilePath> paths;
|
|
|
|
int flag = file_dialog::FILE_DIALOG_OPEN_DIRECTORY;
|
|
|
|
if (!file_dialog::ShowOpenDialog(owner_window(), "", default_path,
|
|
|
|
filters, flag, &paths))
|
|
|
|
return;
|
|
|
|
|
|
|
|
path = paths[0];
|
|
|
|
}
|
2015-06-05 06:55:07 +00:00
|
|
|
|
|
|
|
std::string file_system_id = RegisterFileSystem(GetDevToolsWebContents(),
|
2016-03-15 02:21:36 +00:00
|
|
|
path);
|
2016-05-06 23:02:54 +00:00
|
|
|
if (IsDevToolsFileSystemAdded(GetDevToolsWebContents(), path.AsUTF8Unsafe()))
|
2015-06-05 06:55:07 +00:00
|
|
|
return;
|
|
|
|
|
|
|
|
FileSystem file_system = CreateFileSystemStruct(GetDevToolsWebContents(),
|
2016-03-15 02:21:36 +00:00
|
|
|
file_system_id,
|
|
|
|
path.AsUTF8Unsafe());
|
|
|
|
scoped_ptr<base::DictionaryValue> file_system_value(
|
|
|
|
CreateFileSystemValue(file_system));
|
|
|
|
|
|
|
|
auto pref_service = GetPrefService(GetDevToolsWebContents());
|
|
|
|
DictionaryPrefUpdate update(pref_service, prefs::kDevToolsFileSystemPaths);
|
|
|
|
update.Get()->SetWithoutPathExpansion(
|
|
|
|
path.AsUTF8Unsafe(), base::Value::CreateNullValue());
|
|
|
|
|
|
|
|
web_contents_->CallClientFunction("DevToolsAPI.fileSystemAdded",
|
|
|
|
file_system_value.get(),
|
|
|
|
nullptr, 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();
|
2015-07-24 09:39:11 +00:00
|
|
|
storage::IsolatedContext::GetInstance()->
|
|
|
|
RevokeFileSystemByPath(file_system_path);
|
2015-06-05 06:55:07 +00:00
|
|
|
|
2016-03-15 02:21:36 +00:00
|
|
|
auto pref_service = GetPrefService(GetDevToolsWebContents());
|
|
|
|
DictionaryPrefUpdate update(pref_service, prefs::kDevToolsFileSystemPaths);
|
|
|
|
update.Get()->RemoveWithoutPathExpansion(path, nullptr);
|
2015-06-05 06:55:07 +00:00
|
|
|
|
2016-03-15 02:21:36 +00:00
|
|
|
base::StringValue file_system_path_value(path);
|
|
|
|
web_contents_->CallClientFunction("DevToolsAPI.fileSystemRemoved",
|
|
|
|
&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,
|
|
|
|
const std::string& file_system_path) {
|
|
|
|
if (!IsDevToolsFileSystemAdded(GetDevToolsWebContents(), file_system_path)) {
|
|
|
|
OnDevToolsIndexingDone(request_id, file_system_path);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
if (devtools_indexing_jobs_.count(request_id) != 0)
|
|
|
|
return;
|
|
|
|
devtools_indexing_jobs_[request_id] =
|
|
|
|
scoped_refptr<DevToolsFileSystemIndexer::FileSystemIndexingJob>(
|
|
|
|
devtools_file_system_indexer_->IndexPath(
|
|
|
|
file_system_path,
|
|
|
|
base::Bind(
|
|
|
|
&CommonWebContentsDelegate::OnDevToolsIndexingWorkCalculated,
|
|
|
|
base::Unretained(this),
|
|
|
|
request_id,
|
|
|
|
file_system_path),
|
|
|
|
base::Bind(&CommonWebContentsDelegate::OnDevToolsIndexingWorked,
|
|
|
|
base::Unretained(this),
|
|
|
|
request_id,
|
|
|
|
file_system_path),
|
|
|
|
base::Bind(&CommonWebContentsDelegate::OnDevToolsIndexingDone,
|
|
|
|
base::Unretained(this),
|
|
|
|
request_id,
|
|
|
|
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)) {
|
|
|
|
OnDevToolsSearchCompleted(request_id,
|
|
|
|
file_system_path,
|
|
|
|
std::vector<std::string>());
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
devtools_file_system_indexer_->SearchInPath(
|
|
|
|
file_system_path,
|
|
|
|
query,
|
|
|
|
base::Bind(&CommonWebContentsDelegate::OnDevToolsSearchCompleted,
|
|
|
|
base::Unretained(this),
|
|
|
|
request_id,
|
|
|
|
file_system_path));
|
|
|
|
}
|
|
|
|
|
2015-06-22 02:00:33 +00:00
|
|
|
void CommonWebContentsDelegate::OnDevToolsSaveToFile(
|
|
|
|
const std::string& url) {
|
|
|
|
// Notify DevTools.
|
|
|
|
base::StringValue url_value(url);
|
|
|
|
web_contents_->CallClientFunction(
|
|
|
|
"DevToolsAPI.savedURL", &url_value, nullptr, nullptr);
|
|
|
|
}
|
|
|
|
|
|
|
|
void CommonWebContentsDelegate::OnDevToolsAppendToFile(
|
|
|
|
const std::string& url) {
|
|
|
|
// Notify DevTools.
|
|
|
|
base::StringValue url_value(url);
|
|
|
|
web_contents_->CallClientFunction(
|
|
|
|
"DevToolsAPI.appendedToURL", &url_value, nullptr, nullptr);
|
|
|
|
}
|
|
|
|
|
2016-05-06 23:02:54 +00:00
|
|
|
void CommonWebContentsDelegate::OnDevToolsIndexingWorkCalculated(
|
|
|
|
int request_id,
|
|
|
|
const std::string& file_system_path,
|
|
|
|
int total_work) {
|
|
|
|
base::FundamentalValue request_id_value(request_id);
|
|
|
|
base::StringValue file_system_path_value(file_system_path);
|
|
|
|
base::FundamentalValue total_work_value(total_work);
|
|
|
|
web_contents_->CallClientFunction("DevToolsAPI.indexingTotalWorkCalculated",
|
|
|
|
&request_id_value,
|
|
|
|
&file_system_path_value,
|
|
|
|
&total_work_value);
|
|
|
|
}
|
|
|
|
|
|
|
|
void CommonWebContentsDelegate::OnDevToolsIndexingWorked(
|
|
|
|
int request_id,
|
|
|
|
const std::string& file_system_path,
|
|
|
|
int worked) {
|
|
|
|
base::FundamentalValue request_id_value(request_id);
|
|
|
|
base::StringValue file_system_path_value(file_system_path);
|
|
|
|
base::FundamentalValue worked_value(worked);
|
|
|
|
web_contents_->CallClientFunction("DevToolsAPI.indexingWorked",
|
|
|
|
&request_id_value,
|
|
|
|
&file_system_path_value,
|
|
|
|
&worked_value);
|
|
|
|
}
|
|
|
|
|
|
|
|
void CommonWebContentsDelegate::OnDevToolsIndexingDone(
|
|
|
|
int request_id,
|
|
|
|
const std::string& file_system_path) {
|
|
|
|
devtools_indexing_jobs_.erase(request_id);
|
|
|
|
base::FundamentalValue request_id_value(request_id);
|
|
|
|
base::StringValue file_system_path_value(file_system_path);
|
|
|
|
web_contents_->CallClientFunction("DevToolsAPI.indexingDone",
|
|
|
|
&request_id_value,
|
|
|
|
&file_system_path_value,
|
|
|
|
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;
|
|
|
|
for (std::vector<std::string>::const_iterator it(file_paths.begin());
|
|
|
|
it != file_paths.end(); ++it) {
|
|
|
|
file_paths_value.AppendString(*it);
|
|
|
|
}
|
|
|
|
base::FundamentalValue request_id_value(request_id);
|
|
|
|
base::StringValue file_system_path_value(file_system_path);
|
|
|
|
web_contents_->CallClientFunction("DevToolsAPI.searchCompleted",
|
|
|
|
&request_id_value,
|
|
|
|
&file_system_path_value,
|
|
|
|
&file_paths_value);
|
|
|
|
}
|
|
|
|
|
2015-10-01 03:14:19 +00:00
|
|
|
#if defined(TOOLKIT_VIEWS)
|
|
|
|
gfx::ImageSkia CommonWebContentsDelegate::GetDevToolsWindowIcon() {
|
|
|
|
if (!owner_window())
|
|
|
|
return gfx::ImageSkia();
|
|
|
|
return static_cast<views::WidgetDelegate*>(static_cast<NativeWindowViews*>(
|
|
|
|
owner_window()))->GetWindowAppIcon();
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#if defined(USE_X11)
|
|
|
|
void CommonWebContentsDelegate::GetDevToolsWindowWMClass(
|
|
|
|
std::string* name, std::string* class_name) {
|
|
|
|
*class_name = Browser::Get()->GetName();
|
2015-12-07 11:56:23 +00:00
|
|
|
*name = base::ToLowerASCII(*class_name);
|
2015-10-01 03:14:19 +00:00
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
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
|