mirror of
https://github.com/electron/electron.git
synced 2026-02-26 03:01:17 -05:00
Compare commits
35 Commits
v3.0.0-bet
...
v3.0.0-nig
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b15a3ee2be | ||
|
|
7b043ac554 | ||
|
|
89a6f1efbb | ||
|
|
ce592a5705 | ||
|
|
12087b74e8 | ||
|
|
d365078022 | ||
|
|
3dbd84c224 | ||
|
|
2e479ff799 | ||
|
|
a341ae450a | ||
|
|
0aec308681 | ||
|
|
8e9c5b8338 | ||
|
|
6bc1e37156 | ||
|
|
7da7dd85e3 | ||
|
|
ccf8a797dc | ||
|
|
3301e05f33 | ||
|
|
b1c22ba531 | ||
|
|
873f39b159 | ||
|
|
11864e9e08 | ||
|
|
c8a21dbb92 | ||
|
|
97058837e7 | ||
|
|
ff539c1d61 | ||
|
|
9237d40e09 | ||
|
|
4721dc0856 | ||
|
|
1f7fd985dd | ||
|
|
d432e420ae | ||
|
|
635c3f53d8 | ||
|
|
ba703deee2 | ||
|
|
b03178105d | ||
|
|
ef0a6d9a1c | ||
|
|
4c7af6a429 | ||
|
|
d1886c5d22 | ||
|
|
c558dc2d7d | ||
|
|
be68cfd4ea | ||
|
|
115a15c356 | ||
|
|
d4fb904450 |
13
BUILD.gn
13
BUILD.gn
@@ -27,6 +27,12 @@ declare_args() {
|
||||
enable_desktop_capturer = true
|
||||
enable_run_as_node = true
|
||||
enable_osr = true
|
||||
|
||||
# Provide a fake location provider for mocking
|
||||
# the geolocation responses. Disable it if you
|
||||
# need to test with chromium's location provider.
|
||||
# Should not be enabled for release build.
|
||||
enable_fake_location_provider = !is_official_build
|
||||
}
|
||||
|
||||
filenames_gypi = exec_script(
|
||||
@@ -312,6 +318,13 @@ static_library("electron_lib") {
|
||||
sources = filenames_gypi.lib_sources
|
||||
set_sources_assignment_filter(sources_assignment_filter)
|
||||
|
||||
if (enable_fake_location_provider) {
|
||||
defines += [
|
||||
"OVERRIDE_LOCATION_PROVIDER"
|
||||
]
|
||||
sources += filenames_gypi.lib_sources_location_provider
|
||||
}
|
||||
|
||||
if (enable_run_as_node) {
|
||||
sources += [
|
||||
"atom/app/node_main.cc",
|
||||
|
||||
2
DEPS
2
DEPS
@@ -2,7 +2,7 @@ vars = {
|
||||
'chromium_version':
|
||||
'63.0.3239.150',
|
||||
'libchromiumcontent_revision':
|
||||
'92dc0accfae5cd133fa2a6758ae6b3ff4ff7e569',
|
||||
'dc2e7ebd2867d4329ebe7b6849e89cf3dc0afa8e',
|
||||
'node_version':
|
||||
'v9.7.0-33-g538a5023af',
|
||||
'native_mate_revision':
|
||||
|
||||
@@ -667,17 +667,17 @@ void App::OnNewWindowForTab() {
|
||||
}
|
||||
#endif
|
||||
|
||||
void App::OnLogin(LoginHandler* login_handler,
|
||||
void App::OnLogin(scoped_refptr<LoginHandler> login_handler,
|
||||
const base::DictionaryValue& request_details) {
|
||||
v8::Locker locker(isolate());
|
||||
v8::HandleScope handle_scope(isolate());
|
||||
bool prevent_default = false;
|
||||
content::WebContents* web_contents = login_handler->GetWebContents();
|
||||
if (web_contents) {
|
||||
prevent_default =
|
||||
Emit("login", WebContents::CreateFrom(isolate(), web_contents),
|
||||
request_details, login_handler->auth_info(),
|
||||
base::Bind(&PassLoginInformation, WrapRefCounted(login_handler)));
|
||||
prevent_default = Emit(
|
||||
"login", WebContents::CreateFrom(isolate(), web_contents),
|
||||
request_details, login_handler->auth_info(),
|
||||
base::Bind(&PassLoginInformation, base::RetainedRef(login_handler)));
|
||||
}
|
||||
|
||||
// Default behavior is to always cancel the auth.
|
||||
|
||||
@@ -98,7 +98,7 @@ class App : public AtomBrowserClient::Delegate,
|
||||
void OnActivate(bool has_visible_windows) override;
|
||||
void OnWillFinishLaunching() override;
|
||||
void OnFinishLaunching(const base::DictionaryValue& launch_info) override;
|
||||
void OnLogin(LoginHandler* login_handler,
|
||||
void OnLogin(scoped_refptr<LoginHandler> login_handler,
|
||||
const base::DictionaryValue& request_details) override;
|
||||
void OnAccessibilitySupportChanged() override;
|
||||
void OnPreMainMessageLoopRun() override;
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
#include "atom/browser/api/atom_api_cookies.h"
|
||||
|
||||
#include "atom/browser/atom_browser_context.h"
|
||||
#include "atom/browser/request_context_delegate.h"
|
||||
#include "atom/common/native_mate_converters/callback.h"
|
||||
#include "atom/common/native_mate_converters/gurl_converter.h"
|
||||
#include "atom/common/native_mate_converters/value_converter.h"
|
||||
@@ -253,9 +254,10 @@ void SetCookieOnIO(scoped_refptr<net::URLRequestContextGetter> getter,
|
||||
Cookies::Cookies(v8::Isolate* isolate, AtomBrowserContext* browser_context)
|
||||
: browser_context_(browser_context) {
|
||||
Init(isolate);
|
||||
auto subscription = browser_context->RegisterCookieChangeCallback(
|
||||
base::Bind(&Cookies::OnCookieChanged, base::Unretained(this)));
|
||||
browser_context->set_cookie_change_subscription(std::move(subscription));
|
||||
cookie_change_subscription_ =
|
||||
browser_context->GetRequestContextDelegate()
|
||||
->RegisterCookieChangeCallback(
|
||||
base::Bind(&Cookies::OnCookieChanged, base::Unretained(this)));
|
||||
}
|
||||
|
||||
Cookies::~Cookies() {}
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
|
||||
#include "atom/browser/api/trackable_object.h"
|
||||
#include "atom/browser/net/cookie_details.h"
|
||||
#include "base/callback.h"
|
||||
#include "base/callback_list.h"
|
||||
#include "native_mate/handle.h"
|
||||
#include "net/cookies/canonical_cookie.h"
|
||||
|
||||
@@ -59,6 +59,8 @@ class Cookies : public mate::TrackableObject<Cookies> {
|
||||
void OnCookieChanged(const CookieDetails*);
|
||||
|
||||
private:
|
||||
std::unique_ptr<base::CallbackList<void(const CookieDetails*)>::Subscription>
|
||||
cookie_change_subscription_;
|
||||
scoped_refptr<AtomBrowserContext> browser_context_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(Cookies);
|
||||
|
||||
@@ -78,13 +78,13 @@ class Protocol : public mate::TrackableObject<Protocol> {
|
||||
net::URLRequest* request,
|
||||
net::NetworkDelegate* network_delegate) const override {
|
||||
RequestJob* request_job = new RequestJob(request, network_delegate);
|
||||
request_job->SetHandlerInfo(isolate_, request_context_.get(), handler_);
|
||||
request_job->SetHandlerInfo(isolate_, request_context_, handler_);
|
||||
return request_job;
|
||||
}
|
||||
|
||||
private:
|
||||
v8::Isolate* isolate_;
|
||||
scoped_refptr<net::URLRequestContextGetter> request_context_;
|
||||
net::URLRequestContextGetter* request_context_;
|
||||
Protocol::Handler handler_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(CustomProtocolHandler);
|
||||
|
||||
@@ -244,7 +244,7 @@ class ResolveProxyHelper {
|
||||
: callback_(callback),
|
||||
original_thread_(base::ThreadTaskRunnerHandle::Get()) {
|
||||
scoped_refptr<net::URLRequestContextGetter> context_getter =
|
||||
browser_context->url_request_context_getter();
|
||||
browser_context->GetRequestContext();
|
||||
context_getter->GetNetworkTaskRunner()->PostTask(
|
||||
FROM_HERE, base::BindOnce(&ResolveProxyHelper::ResolveProxy,
|
||||
base::Unretained(this), context_getter, url));
|
||||
@@ -453,15 +453,6 @@ void SetDevToolsNetworkEmulationClientIdInIO(
|
||||
network_delegate->SetDevToolsNetworkEmulationClientId(client_id);
|
||||
}
|
||||
|
||||
// Clear protocol handlers in IO thread.
|
||||
void ClearJobFactoryInIO(
|
||||
scoped_refptr<brightray::URLRequestContextGetter> request_context_getter) {
|
||||
auto* job_factory = static_cast<AtomURLRequestJobFactory*>(
|
||||
request_context_getter->job_factory());
|
||||
if (job_factory)
|
||||
job_factory->Clear();
|
||||
}
|
||||
|
||||
void DestroyGlobalHandle(v8::Isolate* isolate,
|
||||
const v8::Global<v8::Value>& global_handle) {
|
||||
v8::Locker locker(isolate);
|
||||
@@ -495,10 +486,6 @@ Session::Session(v8::Isolate* isolate, AtomBrowserContext* browser_context)
|
||||
}
|
||||
|
||||
Session::~Session() {
|
||||
auto* getter = browser_context_->GetRequestContext();
|
||||
content::BrowserThread::PostTask(
|
||||
content::BrowserThread::IO, FROM_HERE,
|
||||
base::BindOnce(ClearJobFactoryInIO, base::RetainedRef(getter)));
|
||||
content::BrowserContext::GetDownloadManager(browser_context())
|
||||
->RemoveObserver(this);
|
||||
DestroyGlobalHandle(isolate(), cookies_);
|
||||
@@ -597,10 +584,9 @@ void Session::EnableNetworkEmulation(const mate::Dictionary& options) {
|
||||
devtools_network_emulation_client_id_, std::move(conditions));
|
||||
BrowserThread::PostTask(
|
||||
BrowserThread::IO, FROM_HERE,
|
||||
base::BindOnce(
|
||||
&SetDevToolsNetworkEmulationClientIdInIO,
|
||||
base::RetainedRef(browser_context_->url_request_context_getter()),
|
||||
devtools_network_emulation_client_id_));
|
||||
base::BindOnce(&SetDevToolsNetworkEmulationClientIdInIO,
|
||||
base::RetainedRef(browser_context_->GetRequestContext()),
|
||||
devtools_network_emulation_client_id_));
|
||||
}
|
||||
|
||||
void Session::DisableNetworkEmulation() {
|
||||
@@ -609,10 +595,9 @@ void Session::DisableNetworkEmulation() {
|
||||
devtools_network_emulation_client_id_, std::move(conditions));
|
||||
BrowserThread::PostTask(
|
||||
BrowserThread::IO, FROM_HERE,
|
||||
base::BindOnce(
|
||||
&SetDevToolsNetworkEmulationClientIdInIO,
|
||||
base::RetainedRef(browser_context_->url_request_context_getter()),
|
||||
std::string()));
|
||||
base::BindOnce(&SetDevToolsNetworkEmulationClientIdInIO,
|
||||
base::RetainedRef(browser_context_->GetRequestContext()),
|
||||
std::string()));
|
||||
}
|
||||
|
||||
void Session::SetCertVerifyProc(v8::Local<v8::Value> val,
|
||||
|
||||
@@ -571,6 +571,10 @@ double TopLevelWindow::GetOpacity() {
|
||||
return window_->GetOpacity();
|
||||
}
|
||||
|
||||
void TopLevelWindow::SetShape(const std::vector<gfx::Rect>& rects) {
|
||||
window_->widget()->SetShape(std::make_unique<std::vector<gfx::Rect>>(rects));
|
||||
}
|
||||
|
||||
void TopLevelWindow::SetRepresentedFilename(const std::string& filename) {
|
||||
window_->SetRepresentedFilename(filename);
|
||||
}
|
||||
@@ -993,6 +997,7 @@ void TopLevelWindow::BuildPrototype(v8::Isolate* isolate,
|
||||
.SetMethod("hasShadow", &TopLevelWindow::HasShadow)
|
||||
.SetMethod("setOpacity", &TopLevelWindow::SetOpacity)
|
||||
.SetMethod("getOpacity", &TopLevelWindow::GetOpacity)
|
||||
.SetMethod("setShape", &TopLevelWindow::SetShape)
|
||||
.SetMethod("setRepresentedFilename",
|
||||
&TopLevelWindow::SetRepresentedFilename)
|
||||
.SetMethod("getRepresentedFilename",
|
||||
|
||||
@@ -146,6 +146,7 @@ class TopLevelWindow : public mate::TrackableObject<TopLevelWindow>,
|
||||
bool HasShadow();
|
||||
void SetOpacity(const double opacity);
|
||||
double GetOpacity();
|
||||
void SetShape(const std::vector<gfx::Rect>& rects);
|
||||
void SetRepresentedFilename(const std::string& filename);
|
||||
std::string GetRepresentedFilename();
|
||||
void SetDocumentEdited(bool edited);
|
||||
|
||||
@@ -210,7 +210,7 @@ void Tray::PopUpContextMenu(mate::Arguments* args) {
|
||||
|
||||
void Tray::SetContextMenu(v8::Isolate* isolate, mate::Handle<Menu> menu) {
|
||||
menu_.Reset(isolate, menu.ToV8());
|
||||
tray_icon_->SetContextMenu(menu->model());
|
||||
tray_icon_->SetContextMenu(menu.IsEmpty() ? nullptr : menu->model());
|
||||
}
|
||||
|
||||
gfx::Rect Tray::GetBounds() {
|
||||
|
||||
@@ -125,6 +125,18 @@ bool URLRequest::ResponseState::Failed() const {
|
||||
return IsFlagSet(ResponseStateFlags::kFailed);
|
||||
}
|
||||
|
||||
mate::Dictionary URLRequest::GetUploadProgress(v8::Isolate* isolate) {
|
||||
mate::Dictionary progress = mate::Dictionary::CreateEmpty(isolate);
|
||||
|
||||
if (atom_request_) {
|
||||
progress.Set("active", true);
|
||||
atom_request_->GetUploadProgress(&progress);
|
||||
} else {
|
||||
progress.Set("active", false);
|
||||
}
|
||||
return progress;
|
||||
}
|
||||
|
||||
URLRequest::URLRequest(v8::Isolate* isolate, v8::Local<v8::Object> wrapper) {
|
||||
InitWith(isolate, wrapper);
|
||||
}
|
||||
@@ -183,6 +195,7 @@ void URLRequest::BuildPrototype(v8::Isolate* isolate,
|
||||
.SetMethod("setChunkedUpload", &URLRequest::SetChunkedUpload)
|
||||
.SetMethod("followRedirect", &URLRequest::FollowRedirect)
|
||||
.SetMethod("_setLoadFlags", &URLRequest::SetLoadFlags)
|
||||
.SetMethod("getUploadProgress", &URLRequest::GetUploadProgress)
|
||||
.SetProperty("notStarted", &URLRequest::NotStarted)
|
||||
.SetProperty("finished", &URLRequest::Finished)
|
||||
// Response APi
|
||||
|
||||
@@ -112,6 +112,7 @@ class URLRequest : public mate::EventEmitter<URLRequest> {
|
||||
void OnResponseData(scoped_refptr<const net::IOBufferWithSize> data);
|
||||
void OnResponseCompleted();
|
||||
void OnError(const std::string& error, bool isRequestError);
|
||||
mate::Dictionary GetUploadProgress(v8::Isolate* isolate);
|
||||
|
||||
protected:
|
||||
explicit URLRequest(v8::Isolate* isolate, v8::Local<v8::Object> wrapper);
|
||||
|
||||
@@ -766,7 +766,8 @@ void WebContents::RenderViewCreated(content::RenderViewHost* render_view_host) {
|
||||
}
|
||||
|
||||
void WebContents::RenderViewDeleted(content::RenderViewHost* render_view_host) {
|
||||
Emit("render-view-deleted", render_view_host->GetProcess()->GetID());
|
||||
Emit("render-view-deleted", render_view_host->GetProcess()->GetID(),
|
||||
base::GetProcId(render_view_host->GetProcess()->GetHandle()));
|
||||
}
|
||||
|
||||
void WebContents::RenderProcessGone(base::TerminationStatus status) {
|
||||
@@ -1722,10 +1723,6 @@ void WebContents::OnCursorChange(const content::WebCursor& cursor) {
|
||||
}
|
||||
}
|
||||
|
||||
void WebContents::SetSize(v8::Local<v8::Value>) {
|
||||
// TODO(zcbenz): Remove this method in 4.0.
|
||||
}
|
||||
|
||||
bool WebContents::IsGuest() const {
|
||||
return type_ == WEB_VIEW;
|
||||
}
|
||||
@@ -2022,7 +2019,6 @@ void WebContents::BuildPrototype(v8::Isolate* isolate,
|
||||
.SetMethod("beginFrameSubscription", &WebContents::BeginFrameSubscription)
|
||||
.SetMethod("endFrameSubscription", &WebContents::EndFrameSubscription)
|
||||
.SetMethod("startDrag", &WebContents::StartDrag)
|
||||
.SetMethod("setSize", &WebContents::SetSize)
|
||||
.SetMethod("isGuest", &WebContents::IsGuest)
|
||||
.SetMethod("attachToIframe", &WebContents::AttachToIframe)
|
||||
.SetMethod("isOffscreen", &WebContents::IsOffScreen)
|
||||
|
||||
@@ -198,7 +198,6 @@ class WebContents : public mate::TrackableObject<WebContents>,
|
||||
void CapturePage(mate::Arguments* args);
|
||||
|
||||
// Methods for creating <webview>.
|
||||
void SetSize(v8::Local<v8::Value>);
|
||||
bool IsGuest() const;
|
||||
void AttachToIframe(content::WebContents* embedder_web_contents,
|
||||
int embedder_frame_id);
|
||||
|
||||
@@ -95,7 +95,7 @@ void WebRequest::SetListener(Method method, Event type, mate::Arguments* args) {
|
||||
}
|
||||
|
||||
brightray::URLRequestContextGetter* url_request_context_getter =
|
||||
browser_context_->url_request_context_getter();
|
||||
browser_context_->GetRequestContext();
|
||||
if (!url_request_context_getter)
|
||||
return;
|
||||
BrowserThread::PostTask(
|
||||
|
||||
@@ -17,7 +17,6 @@
|
||||
#include "atom/browser/atom_resource_dispatcher_host_delegate.h"
|
||||
#include "atom/browser/atom_speech_recognition_manager_delegate.h"
|
||||
#include "atom/browser/child_web_contents_tracker.h"
|
||||
#include "atom/browser/login_handler.h"
|
||||
#include "atom/browser/native_window.h"
|
||||
#include "atom/browser/session_preferences.h"
|
||||
#include "atom/browser/web_contents_permission_helper.h"
|
||||
@@ -46,6 +45,7 @@
|
||||
#include "content/public/common/content_switches.h"
|
||||
#include "content/public/common/url_constants.h"
|
||||
#include "content/public/common/web_preferences.h"
|
||||
#include "device/geolocation/public/cpp/location_provider.h"
|
||||
#include "net/ssl/ssl_cert_request_info.h"
|
||||
#include "ppapi/host/ppapi_host.h"
|
||||
#include "services/network/public/cpp/resource_request_body.h"
|
||||
@@ -62,6 +62,10 @@
|
||||
#include "net/ssl/client_cert_store.h"
|
||||
#endif
|
||||
|
||||
#if defined(OVERRIDE_LOCATION_PROVIDER)
|
||||
#include "atom/browser/fake_location_provider.h"
|
||||
#endif // defined(OVERRIDE_LOCATION_PROVIDER)
|
||||
|
||||
using content::BrowserThread;
|
||||
|
||||
namespace atom {
|
||||
@@ -495,17 +499,13 @@ std::unique_ptr<net::ClientCertStore> AtomBrowserClient::CreateClientCertStore(
|
||||
#endif
|
||||
}
|
||||
|
||||
content::ResourceDispatcherHostLoginDelegate*
|
||||
AtomBrowserClient::CreateLoginDelegate(
|
||||
net::AuthChallengeInfo* auth_info,
|
||||
content::ResourceRequestInfo::WebContentsGetter web_contents_getter,
|
||||
bool is_main_frame,
|
||||
const GURL& url,
|
||||
bool first_auth_attempt,
|
||||
const base::Callback<void(const base::Optional<net::AuthCredentials>&)>&
|
||||
auth_required_callback) {
|
||||
return new LoginHandler(auth_info, web_contents_getter, url,
|
||||
auth_required_callback);
|
||||
std::unique_ptr<device::LocationProvider>
|
||||
AtomBrowserClient::OverrideSystemLocationProvider() {
|
||||
#if defined(OVERRIDE_LOCATION_PROVIDER)
|
||||
return std::make_unique<FakeLocationProvider>();
|
||||
#else
|
||||
return nullptr;
|
||||
#endif
|
||||
}
|
||||
|
||||
brightray::BrowserMainParts* AtomBrowserClient::OverrideCreateBrowserMainParts(
|
||||
|
||||
@@ -106,14 +106,8 @@ class AtomBrowserClient : public brightray::BrowserClient,
|
||||
void SiteInstanceDeleting(content::SiteInstance* site_instance) override;
|
||||
std::unique_ptr<net::ClientCertStore> CreateClientCertStore(
|
||||
content::ResourceContext* resource_context) override;
|
||||
content::ResourceDispatcherHostLoginDelegate* CreateLoginDelegate(
|
||||
net::AuthChallengeInfo* auth_info,
|
||||
content::ResourceRequestInfo::WebContentsGetter web_contents_getter,
|
||||
bool is_main_frame,
|
||||
const GURL& url,
|
||||
bool first_auth_attempt,
|
||||
const base::Callback<void(const base::Optional<net::AuthCredentials>&)>&
|
||||
auth_required_callback) override;
|
||||
std::unique_ptr<device::LocationProvider> OverrideSystemLocationProvider()
|
||||
override;
|
||||
|
||||
// brightray::BrowserClient:
|
||||
brightray::BrowserMainParts* OverrideCreateBrowserMainParts(
|
||||
|
||||
@@ -4,59 +4,30 @@
|
||||
|
||||
#include "atom/browser/atom_browser_context.h"
|
||||
|
||||
#include "atom/browser/api/atom_api_protocol.h"
|
||||
#include "atom/browser/atom_blob_reader.h"
|
||||
#include "atom/browser/atom_browser_main_parts.h"
|
||||
#include "atom/browser/atom_download_manager_delegate.h"
|
||||
#include "atom/browser/atom_permission_manager.h"
|
||||
#include "atom/browser/browser.h"
|
||||
#include "atom/browser/net/about_protocol_handler.h"
|
||||
#include "atom/browser/net/asar/asar_protocol_handler.h"
|
||||
#include "atom/browser/net/atom_cert_verifier.h"
|
||||
#include "atom/browser/net/atom_network_delegate.h"
|
||||
#include "atom/browser/net/atom_url_request_job_factory.h"
|
||||
#include "atom/browser/net/cookie_details.h"
|
||||
#include "atom/browser/net/http_protocol_handler.h"
|
||||
#include "atom/browser/request_context_delegate.h"
|
||||
#include "atom/browser/web_view_manager.h"
|
||||
#include "atom/common/atom_version.h"
|
||||
#include "atom/common/chrome_version.h"
|
||||
#include "atom/common/options_switches.h"
|
||||
#include "base/command_line.h"
|
||||
#include "base/files/file_path.h"
|
||||
#include "base/memory/ptr_util.h"
|
||||
#include "base/path_service.h"
|
||||
#include "base/strings/string_util.h"
|
||||
#include "base/strings/stringprintf.h"
|
||||
#include "base/task_scheduler/post_task.h"
|
||||
#include "chrome/common/chrome_paths.h"
|
||||
#include "chrome/common/pref_names.h"
|
||||
#include "components/prefs/pref_registry_simple.h"
|
||||
#include "content/browser/blob_storage/chrome_blob_storage_context.h"
|
||||
#include "content/public/browser/browser_thread.h"
|
||||
#include "content/public/browser/storage_partition.h"
|
||||
#include "content/public/common/url_constants.h"
|
||||
#include "content/public/common/user_agent.h"
|
||||
#include "net/ftp/ftp_network_layer.h"
|
||||
#include "net/url_request/data_protocol_handler.h"
|
||||
#include "net/url_request/ftp_protocol_handler.h"
|
||||
#include "net/url_request/url_request_context.h"
|
||||
#include "net/url_request/url_request_intercepting_job_factory.h"
|
||||
#include "url/url_constants.h"
|
||||
|
||||
using content::BrowserThread;
|
||||
|
||||
namespace atom {
|
||||
|
||||
namespace {
|
||||
|
||||
class NoCacheBackend : public net::HttpCache::BackendFactory {
|
||||
int CreateBackend(net::NetLog* net_log,
|
||||
std::unique_ptr<disk_cache::Backend>* backend,
|
||||
const net::CompletionCallback& callback) override {
|
||||
return net::ERR_FAILED;
|
||||
}
|
||||
};
|
||||
|
||||
std::string RemoveWhitespace(const std::string& str) {
|
||||
std::string trimmed;
|
||||
if (base::RemoveChars(str, " ", &trimmed))
|
||||
@@ -70,7 +41,8 @@ std::string RemoveWhitespace(const std::string& str) {
|
||||
AtomBrowserContext::AtomBrowserContext(const std::string& partition,
|
||||
bool in_memory,
|
||||
const base::DictionaryValue& options)
|
||||
: brightray::BrowserContext(partition, in_memory) {
|
||||
: brightray::BrowserContext(partition, in_memory),
|
||||
url_request_context_getter_(nullptr) {
|
||||
// Construct user agent string.
|
||||
Browser* browser = Browser::Get();
|
||||
std::string name = RemoveWhitespace(browser->GetName());
|
||||
@@ -86,87 +58,24 @@ AtomBrowserContext::AtomBrowserContext(const std::string& partition,
|
||||
user_agent_ = content::BuildUserAgentFromProduct(user_agent);
|
||||
|
||||
// Read options.
|
||||
use_cache_ = true;
|
||||
options.GetBoolean("cache", &use_cache_);
|
||||
base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
|
||||
bool use_cache = !command_line->HasSwitch(switches::kDisableHttpCache);
|
||||
options.GetBoolean("cache", &use_cache);
|
||||
|
||||
request_context_delegate_.reset(new RequestContextDelegate(use_cache));
|
||||
|
||||
// Initialize Pref Registry in brightray.
|
||||
InitPrefs();
|
||||
}
|
||||
|
||||
AtomBrowserContext::~AtomBrowserContext() {}
|
||||
AtomBrowserContext::~AtomBrowserContext() {
|
||||
url_request_context_getter_->set_delegate(nullptr);
|
||||
}
|
||||
|
||||
void AtomBrowserContext::SetUserAgent(const std::string& user_agent) {
|
||||
user_agent_ = user_agent;
|
||||
}
|
||||
|
||||
std::unique_ptr<base::CallbackList<void(const CookieDetails*)>::Subscription>
|
||||
AtomBrowserContext::RegisterCookieChangeCallback(
|
||||
const base::Callback<void(const CookieDetails*)>& cb) {
|
||||
return cookie_change_sub_list_.Add(cb);
|
||||
}
|
||||
|
||||
std::unique_ptr<net::NetworkDelegate>
|
||||
AtomBrowserContext::CreateNetworkDelegate() {
|
||||
return std::make_unique<AtomNetworkDelegate>();
|
||||
}
|
||||
|
||||
std::string AtomBrowserContext::GetUserAgent() {
|
||||
return user_agent_;
|
||||
}
|
||||
|
||||
std::unique_ptr<net::URLRequestJobFactory>
|
||||
AtomBrowserContext::CreateURLRequestJobFactory(
|
||||
content::ProtocolHandlerMap* protocol_handlers) {
|
||||
std::unique_ptr<AtomURLRequestJobFactory> job_factory(
|
||||
new AtomURLRequestJobFactory);
|
||||
|
||||
for (auto& it : *protocol_handlers) {
|
||||
job_factory->SetProtocolHandler(it.first,
|
||||
base::WrapUnique(it.second.release()));
|
||||
}
|
||||
protocol_handlers->clear();
|
||||
|
||||
job_factory->SetProtocolHandler(url::kAboutScheme,
|
||||
base::WrapUnique(new AboutProtocolHandler));
|
||||
job_factory->SetProtocolHandler(
|
||||
url::kDataScheme, base::WrapUnique(new net::DataProtocolHandler));
|
||||
job_factory->SetProtocolHandler(
|
||||
url::kFileScheme,
|
||||
base::WrapUnique(
|
||||
new asar::AsarProtocolHandler(base::CreateTaskRunnerWithTraits(
|
||||
{base::MayBlock(), base::TaskPriority::USER_VISIBLE,
|
||||
base::TaskShutdownBehavior::SKIP_ON_SHUTDOWN}))));
|
||||
job_factory->SetProtocolHandler(
|
||||
url::kHttpScheme,
|
||||
base::WrapUnique(new HttpProtocolHandler(url::kHttpScheme)));
|
||||
job_factory->SetProtocolHandler(
|
||||
url::kHttpsScheme,
|
||||
base::WrapUnique(new HttpProtocolHandler(url::kHttpsScheme)));
|
||||
job_factory->SetProtocolHandler(
|
||||
url::kWsScheme,
|
||||
base::WrapUnique(new HttpProtocolHandler(url::kWsScheme)));
|
||||
job_factory->SetProtocolHandler(
|
||||
url::kWssScheme,
|
||||
base::WrapUnique(new HttpProtocolHandler(url::kWssScheme)));
|
||||
|
||||
auto* host_resolver =
|
||||
url_request_context_getter()->GetURLRequestContext()->host_resolver();
|
||||
job_factory->SetProtocolHandler(
|
||||
url::kFtpScheme, net::FtpProtocolHandler::Create(host_resolver));
|
||||
|
||||
return std::move(job_factory);
|
||||
}
|
||||
|
||||
net::HttpCache::BackendFactory*
|
||||
AtomBrowserContext::CreateHttpCacheBackendFactory(
|
||||
const base::FilePath& base_path) {
|
||||
base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
|
||||
if (!use_cache_ || command_line->HasSwitch(switches::kDisableHttpCache))
|
||||
return new NoCacheBackend;
|
||||
else
|
||||
return brightray::BrowserContext::CreateHttpCacheBackendFactory(base_path);
|
||||
}
|
||||
|
||||
content::DownloadManagerDelegate*
|
||||
AtomBrowserContext::GetDownloadManagerDelegate() {
|
||||
if (!download_manager_delegate_.get()) {
|
||||
@@ -189,26 +98,6 @@ content::PermissionManager* AtomBrowserContext::GetPermissionManager() {
|
||||
return permission_manager_.get();
|
||||
}
|
||||
|
||||
std::unique_ptr<net::CertVerifier> AtomBrowserContext::CreateCertVerifier(
|
||||
brightray::RequireCTDelegate* ct_delegate) {
|
||||
return base::WrapUnique(new AtomCertVerifier(ct_delegate));
|
||||
}
|
||||
|
||||
std::vector<std::string> AtomBrowserContext::GetCookieableSchemes() {
|
||||
auto default_schemes = brightray::BrowserContext::GetCookieableSchemes();
|
||||
const auto& standard_schemes = atom::api::GetStandardSchemes();
|
||||
default_schemes.insert(default_schemes.end(), standard_schemes.begin(),
|
||||
standard_schemes.end());
|
||||
return default_schemes;
|
||||
}
|
||||
|
||||
void AtomBrowserContext::NotifyCookieChange(const net::CanonicalCookie& cookie,
|
||||
bool removed,
|
||||
net::CookieChangeCause cause) {
|
||||
CookieDetails cookie_details(&cookie, removed, cause);
|
||||
cookie_change_sub_list_.Notify(&cookie_details);
|
||||
}
|
||||
|
||||
void AtomBrowserContext::RegisterPrefs(PrefRegistrySimple* pref_registry) {
|
||||
pref_registry->RegisterFilePathPref(prefs::kSelectFileLastDirectory,
|
||||
base::FilePath());
|
||||
@@ -219,6 +108,16 @@ void AtomBrowserContext::RegisterPrefs(PrefRegistrySimple* pref_registry) {
|
||||
pref_registry->RegisterDictionaryPref(prefs::kDevToolsFileSystemPaths);
|
||||
}
|
||||
|
||||
std::string AtomBrowserContext::GetUserAgent() const {
|
||||
return user_agent_;
|
||||
}
|
||||
|
||||
void AtomBrowserContext::OnMainRequestContextCreated(
|
||||
brightray::URLRequestContextGetter* getter) {
|
||||
getter->set_delegate(request_context_delegate_.get());
|
||||
url_request_context_getter_ = getter;
|
||||
}
|
||||
|
||||
AtomBlobReader* AtomBrowserContext::GetBlobReader() {
|
||||
if (!blob_reader_.get()) {
|
||||
content::ChromeBlobStorageContext* blob_context =
|
||||
|
||||
@@ -8,17 +8,15 @@
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "base/callback_list.h"
|
||||
#include "brightray/browser/browser_context.h"
|
||||
|
||||
namespace atom {
|
||||
|
||||
class AtomBlobReader;
|
||||
class AtomDownloadManagerDelegate;
|
||||
class AtomNetworkDelegate;
|
||||
class AtomPermissionManager;
|
||||
class RequestContextDelegate;
|
||||
class WebViewManager;
|
||||
struct CookieDetails;
|
||||
|
||||
class AtomBrowserContext : public brightray::BrowserContext {
|
||||
public:
|
||||
@@ -31,24 +29,7 @@ class AtomBrowserContext : public brightray::BrowserContext {
|
||||
const base::DictionaryValue& options = base::DictionaryValue());
|
||||
|
||||
void SetUserAgent(const std::string& user_agent);
|
||||
// Register callbacks that needs to notified on any cookie store changes.
|
||||
std::unique_ptr<base::CallbackList<void(const CookieDetails*)>::Subscription>
|
||||
RegisterCookieChangeCallback(
|
||||
const base::Callback<void(const CookieDetails*)>& cb);
|
||||
|
||||
// brightray::URLRequestContextGetter::Delegate:
|
||||
std::unique_ptr<net::NetworkDelegate> CreateNetworkDelegate() override;
|
||||
std::string GetUserAgent() override;
|
||||
std::unique_ptr<net::URLRequestJobFactory> CreateURLRequestJobFactory(
|
||||
content::ProtocolHandlerMap* protocol_handlers) override;
|
||||
net::HttpCache::BackendFactory* CreateHttpCacheBackendFactory(
|
||||
const base::FilePath& base_path) override;
|
||||
std::unique_ptr<net::CertVerifier> CreateCertVerifier(
|
||||
brightray::RequireCTDelegate* ct_delegate) override;
|
||||
std::vector<std::string> GetCookieableSchemes() override;
|
||||
void NotifyCookieChange(const net::CanonicalCookie& cookie,
|
||||
bool removed,
|
||||
net::CookieChangeCause cause) override;
|
||||
AtomBlobReader* GetBlobReader();
|
||||
|
||||
// content::BrowserContext:
|
||||
content::DownloadManagerDelegate* GetDownloadManagerDelegate() override;
|
||||
@@ -57,14 +38,12 @@ class AtomBrowserContext : public brightray::BrowserContext {
|
||||
|
||||
// brightray::BrowserContext:
|
||||
void RegisterPrefs(PrefRegistrySimple* pref_registry) override;
|
||||
std::string GetUserAgent() const override;
|
||||
void OnMainRequestContextCreated(
|
||||
brightray::URLRequestContextGetter* getter) override;
|
||||
|
||||
AtomBlobReader* GetBlobReader();
|
||||
|
||||
void set_cookie_change_subscription(
|
||||
std::unique_ptr<
|
||||
base::CallbackList<void(const CookieDetails*)>::Subscription>
|
||||
subscription) {
|
||||
cookie_change_subscription_.swap(subscription);
|
||||
RequestContextDelegate* GetRequestContextDelegate() const {
|
||||
return request_context_delegate_.get();
|
||||
}
|
||||
|
||||
protected:
|
||||
@@ -74,16 +53,14 @@ class AtomBrowserContext : public brightray::BrowserContext {
|
||||
~AtomBrowserContext() override;
|
||||
|
||||
private:
|
||||
brightray::URLRequestContextGetter* url_request_context_getter_;
|
||||
|
||||
std::unique_ptr<AtomDownloadManagerDelegate> download_manager_delegate_;
|
||||
std::unique_ptr<WebViewManager> guest_manager_;
|
||||
std::unique_ptr<AtomPermissionManager> permission_manager_;
|
||||
std::unique_ptr<AtomBlobReader> blob_reader_;
|
||||
std::unique_ptr<RequestContextDelegate> request_context_delegate_;
|
||||
std::string user_agent_;
|
||||
bool use_cache_;
|
||||
|
||||
base::CallbackList<void(const CookieDetails*)> cookie_change_sub_list_;
|
||||
std::unique_ptr<base::CallbackList<void(const CookieDetails*)>::Subscription>
|
||||
cookie_change_subscription_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(AtomBrowserContext);
|
||||
};
|
||||
|
||||
@@ -237,9 +237,6 @@ void AtomBrowserMainParts::PostMainMessageLoopStart() {
|
||||
#if defined(OS_POSIX)
|
||||
HandleShutdownSignals();
|
||||
#endif
|
||||
// TODO(deepak1556): Enable this optionally based on response
|
||||
// from AtomPermissionManager.
|
||||
GetGeolocationControl()->UserDidOptIntoLocationServices();
|
||||
}
|
||||
|
||||
void AtomBrowserMainParts::PostMainMessageLoopRun() {
|
||||
|
||||
@@ -54,6 +54,10 @@ class AtomBrowserMainParts : public brightray::BrowserMainParts {
|
||||
// Returns a closure that can be used to remove |callback| from the list.
|
||||
void RegisterDestructionCallback(base::OnceClosure callback);
|
||||
|
||||
// Returns the connection to GeolocationControl which can be
|
||||
// used to enable the location services once per client.
|
||||
device::mojom::GeolocationControl* GetGeolocationControl();
|
||||
|
||||
Browser* browser() { return browser_.get(); }
|
||||
|
||||
protected:
|
||||
@@ -87,8 +91,6 @@ class AtomBrowserMainParts : public brightray::BrowserMainParts {
|
||||
std::unique_ptr<brightray::ViewsDelegate> views_delegate_;
|
||||
#endif
|
||||
|
||||
device::mojom::GeolocationControl* GetGeolocationControl();
|
||||
|
||||
// A fake BrowserProcess object that used to feed the source code from chrome.
|
||||
std::unique_ptr<BrowserProcess> fake_browser_process_;
|
||||
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
#include <vector>
|
||||
|
||||
#include "atom/browser/atom_browser_client.h"
|
||||
#include "atom/browser/atom_browser_main_parts.h"
|
||||
#include "atom/browser/web_contents_preferences.h"
|
||||
#include "content/public/browser/child_process_security_policy.h"
|
||||
#include "content/public/browser/permission_type.h"
|
||||
@@ -43,6 +44,7 @@ class AtomPermissionManager::PendingRequest {
|
||||
const StatusesCallback& callback)
|
||||
: render_process_id_(render_frame_host->GetProcess()->GetID()),
|
||||
callback_(callback),
|
||||
permissions_(permissions),
|
||||
results_(permissions.size(), blink::mojom::PermissionStatus::DENIED),
|
||||
remaining_results_(permissions.size()) {}
|
||||
|
||||
@@ -50,6 +52,18 @@ class AtomPermissionManager::PendingRequest {
|
||||
blink::mojom::PermissionStatus status) {
|
||||
DCHECK(!IsComplete());
|
||||
|
||||
if (status == blink::mojom::PermissionStatus::GRANTED) {
|
||||
const auto permission = permissions_[permission_id];
|
||||
if (permission == content::PermissionType::MIDI_SYSEX) {
|
||||
content::ChildProcessSecurityPolicy::GetInstance()
|
||||
->GrantSendMidiSysExMessage(render_process_id_);
|
||||
} else if (permission == content::PermissionType::GEOLOCATION) {
|
||||
AtomBrowserMainParts::Get()
|
||||
->GetGeolocationControl()
|
||||
->UserDidOptIntoLocationServices();
|
||||
}
|
||||
}
|
||||
|
||||
results_[permission_id] = status;
|
||||
--remaining_results_;
|
||||
}
|
||||
@@ -63,6 +77,7 @@ class AtomPermissionManager::PendingRequest {
|
||||
private:
|
||||
int render_process_id_;
|
||||
const StatusesCallback callback_;
|
||||
std::vector<content::PermissionType> permissions_;
|
||||
std::vector<blink::mojom::PermissionStatus> results_;
|
||||
size_t remaining_results_;
|
||||
};
|
||||
@@ -139,6 +154,10 @@ int AtomPermissionManager::RequestPermissionsWithDetails(
|
||||
content::ChildProcessSecurityPolicy::GetInstance()
|
||||
->GrantSendMidiSysExMessage(
|
||||
render_frame_host->GetProcess()->GetID());
|
||||
} else if (permission == content::PermissionType::GEOLOCATION) {
|
||||
AtomBrowserMainParts::Get()
|
||||
->GetGeolocationControl()
|
||||
->UserDidOptIntoLocationServices();
|
||||
}
|
||||
statuses.push_back(blink::mojom::PermissionStatus::GRANTED);
|
||||
}
|
||||
@@ -153,10 +172,6 @@ int AtomPermissionManager::RequestPermissionsWithDetails(
|
||||
|
||||
for (size_t i = 0; i < permissions.size(); ++i) {
|
||||
auto permission = permissions[i];
|
||||
if (permission == content::PermissionType::MIDI_SYSEX) {
|
||||
content::ChildProcessSecurityPolicy::GetInstance()
|
||||
->GrantSendMidiSysExMessage(render_frame_host->GetProcess()->GetID());
|
||||
}
|
||||
const auto callback =
|
||||
base::Bind(&AtomPermissionManager::OnPermissionResponse,
|
||||
base::Unretained(this), request_id, i);
|
||||
@@ -186,7 +201,6 @@ void AtomPermissionManager::OnPermissionResponse(
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void AtomPermissionManager::ResetPermission(content::PermissionType permission,
|
||||
const GURL& requesting_origin,
|
||||
const GURL& embedding_origin) {}
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
|
||||
#include "atom/browser/atom_browser_main_parts.h"
|
||||
#include "atom/browser/browser_observer.h"
|
||||
#include "atom/browser/login_handler.h"
|
||||
#include "atom/browser/native_window.h"
|
||||
#include "atom/browser/window_list.h"
|
||||
#include "base/files/file_util.h"
|
||||
@@ -164,7 +165,7 @@ void Browser::OnAccessibilitySupportChanged() {
|
||||
}
|
||||
|
||||
void Browser::RequestLogin(
|
||||
LoginHandler* login_handler,
|
||||
scoped_refptr<LoginHandler> login_handler,
|
||||
std::unique_ptr<base::DictionaryValue> request_details) {
|
||||
for (BrowserObserver& observer : observers_)
|
||||
observer.OnLogin(login_handler, *(request_details.get()));
|
||||
|
||||
@@ -33,7 +33,6 @@ class Image;
|
||||
namespace atom {
|
||||
|
||||
class AtomMenuModel;
|
||||
class LoginHandler;
|
||||
|
||||
// This class is used for control application-wide operations.
|
||||
class Browser : public WindowListObserver {
|
||||
@@ -229,7 +228,7 @@ class Browser : public WindowListObserver {
|
||||
void OnAccessibilitySupportChanged();
|
||||
|
||||
// Request basic auth login.
|
||||
void RequestLogin(LoginHandler* login_handler,
|
||||
void RequestLogin(scoped_refptr<LoginHandler> login_handler,
|
||||
std::unique_ptr<base::DictionaryValue> request_details);
|
||||
|
||||
void PreMainMessageLoopRun();
|
||||
|
||||
@@ -7,6 +7,8 @@
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "atom/browser/login_handler.h"
|
||||
#include "base/memory/scoped_refptr.h"
|
||||
#include "build/build_config.h"
|
||||
|
||||
namespace base {
|
||||
@@ -15,8 +17,6 @@ class DictionaryValue;
|
||||
|
||||
namespace atom {
|
||||
|
||||
class LoginHandler;
|
||||
|
||||
class BrowserObserver {
|
||||
public:
|
||||
// The browser is about to close all windows.
|
||||
@@ -49,7 +49,7 @@ class BrowserObserver {
|
||||
virtual void OnFinishLaunching(const base::DictionaryValue& launch_info) {}
|
||||
|
||||
// The browser requests HTTP login.
|
||||
virtual void OnLogin(LoginHandler* login_handler,
|
||||
virtual void OnLogin(scoped_refptr<LoginHandler> login_handler,
|
||||
const base::DictionaryValue& request_details) {}
|
||||
|
||||
// The browser's accessibility suppport has changed.
|
||||
|
||||
44
atom/browser/fake_location_provider.cc
Normal file
44
atom/browser/fake_location_provider.cc
Normal file
@@ -0,0 +1,44 @@
|
||||
// Copyright (c) 2018 GitHub, Inc.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "atom/browser/fake_location_provider.h"
|
||||
|
||||
#include "base/callback.h"
|
||||
#include "base/time/time.h"
|
||||
|
||||
namespace atom {
|
||||
|
||||
FakeLocationProvider::FakeLocationProvider() {
|
||||
position_.latitude = 10;
|
||||
position_.longitude = -10;
|
||||
position_.accuracy = 1;
|
||||
position_.error_code =
|
||||
device::mojom::Geoposition::ErrorCode::POSITION_UNAVAILABLE;
|
||||
}
|
||||
|
||||
FakeLocationProvider::~FakeLocationProvider() = default;
|
||||
|
||||
void FakeLocationProvider::SetUpdateCallback(
|
||||
const LocationProviderUpdateCallback& callback) {
|
||||
callback_ = callback;
|
||||
}
|
||||
|
||||
void FakeLocationProvider::StartProvider(bool high_accuracy) {}
|
||||
|
||||
void FakeLocationProvider::StopProvider() {}
|
||||
|
||||
const device::mojom::Geoposition& FakeLocationProvider::GetPosition() {
|
||||
return position_;
|
||||
}
|
||||
|
||||
void FakeLocationProvider::OnPermissionGranted() {
|
||||
if (!callback_.is_null()) {
|
||||
// Check device::ValidateGeoPosition for range of values.
|
||||
position_.error_code = device::mojom::Geoposition::ErrorCode::NONE;
|
||||
position_.timestamp = base::Time::Now();
|
||||
callback_.Run(this, position_);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace atom
|
||||
36
atom/browser/fake_location_provider.h
Normal file
36
atom/browser/fake_location_provider.h
Normal file
@@ -0,0 +1,36 @@
|
||||
// Copyright (c) 2018 GitHub, Inc.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef ATOM_BROWSER_FAKE_LOCATION_PROVIDER_H_
|
||||
#define ATOM_BROWSER_FAKE_LOCATION_PROVIDER_H_
|
||||
|
||||
#include "base/macros.h"
|
||||
#include "device/geolocation/public/cpp/location_provider.h"
|
||||
#include "services/device/public/mojom/geoposition.mojom.h"
|
||||
|
||||
namespace atom {
|
||||
|
||||
class FakeLocationProvider : public device::LocationProvider {
|
||||
public:
|
||||
FakeLocationProvider();
|
||||
~FakeLocationProvider() override;
|
||||
|
||||
// LocationProvider Implementation:
|
||||
void SetUpdateCallback(
|
||||
const LocationProviderUpdateCallback& callback) override;
|
||||
void StartProvider(bool high_accuracy) override;
|
||||
void StopProvider() override;
|
||||
const device::mojom::Geoposition& GetPosition() override;
|
||||
void OnPermissionGranted() override;
|
||||
|
||||
private:
|
||||
device::mojom::Geoposition position_;
|
||||
LocationProviderUpdateCallback callback_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(FakeLocationProvider);
|
||||
};
|
||||
|
||||
} // namespace atom
|
||||
|
||||
#endif // ATOM_BROWSER_FAKE_LOCATION_PROVIDER_H_
|
||||
@@ -5,6 +5,7 @@
|
||||
#include "atom/browser/login_handler.h"
|
||||
|
||||
#include "atom/browser/browser.h"
|
||||
#include "atom/common/native_mate_converters/net_converter.h"
|
||||
#include "base/values.h"
|
||||
#include "content/public/browser/browser_thread.h"
|
||||
#include "content/public/browser/web_contents.h"
|
||||
@@ -15,78 +16,75 @@ using content::BrowserThread;
|
||||
namespace atom {
|
||||
|
||||
LoginHandler::LoginHandler(
|
||||
net::AuthChallengeInfo* auth_info,
|
||||
content::ResourceRequestInfo::WebContentsGetter web_contents_getter,
|
||||
const GURL& url,
|
||||
const base::Callback<void(const base::Optional<net::AuthCredentials>&)>&
|
||||
auth_required_callback)
|
||||
: auth_info_(auth_info),
|
||||
web_contents_getter_(web_contents_getter),
|
||||
auth_required_callback_(auth_required_callback) {
|
||||
// Fill request details on IO thread.
|
||||
// TODO(deepak1556): Fill in method and referrer details to
|
||||
// avoid breaking the app login event.
|
||||
net::URLRequest* request,
|
||||
const net::AuthChallengeInfo& auth_info,
|
||||
const net::NetworkDelegate::AuthCallback& callback,
|
||||
net::AuthCredentials* credentials,
|
||||
const content::ResourceRequestInfo* resource_request_info)
|
||||
: credentials_(credentials),
|
||||
auth_info_(auth_info),
|
||||
auth_callback_(std::move(callback)),
|
||||
weak_factory_(this) {
|
||||
DCHECK_CURRENTLY_ON(BrowserThread::IO);
|
||||
|
||||
std::unique_ptr<base::DictionaryValue> request_details(
|
||||
new base::DictionaryValue);
|
||||
request_details->SetKey("url", base::Value(url.spec()));
|
||||
FillRequestDetails(request_details.get(), request);
|
||||
|
||||
web_contents_getter_ =
|
||||
resource_request_info->GetWebContentsGetterForRequest();
|
||||
|
||||
BrowserThread::PostTask(
|
||||
BrowserThread::UI, FROM_HERE,
|
||||
base::BindOnce(&Browser::RequestLogin, base::Unretained(Browser::Get()),
|
||||
base::RetainedRef(WrapRefCounted(this)),
|
||||
std::move(request_details)));
|
||||
base::RetainedRef(this), std::move(request_details)));
|
||||
}
|
||||
|
||||
LoginHandler::~LoginHandler() {}
|
||||
|
||||
void LoginHandler::Login(const base::string16& username,
|
||||
const base::string16& password) {
|
||||
DCHECK_CURRENTLY_ON(BrowserThread::UI);
|
||||
|
||||
BrowserThread::PostTask(
|
||||
BrowserThread::IO, FROM_HERE,
|
||||
base::BindOnce(&LoginHandler::DoLogin, weak_factory_.GetWeakPtr(),
|
||||
username, password));
|
||||
}
|
||||
|
||||
void LoginHandler::CancelAuth() {
|
||||
DCHECK_CURRENTLY_ON(BrowserThread::UI);
|
||||
|
||||
BrowserThread::PostTask(
|
||||
BrowserThread::IO, FROM_HERE,
|
||||
base::BindOnce(&LoginHandler::DoCancelAuth, weak_factory_.GetWeakPtr()));
|
||||
}
|
||||
|
||||
void LoginHandler::NotifyRequestDestroyed() {
|
||||
auth_callback_.Reset();
|
||||
credentials_ = nullptr;
|
||||
weak_factory_.InvalidateWeakPtrs();
|
||||
}
|
||||
|
||||
content::WebContents* LoginHandler::GetWebContents() const {
|
||||
DCHECK_CURRENTLY_ON(BrowserThread::UI);
|
||||
return web_contents_getter_.Run();
|
||||
}
|
||||
|
||||
void LoginHandler::Login(const base::string16& username,
|
||||
const base::string16& password) {
|
||||
DCHECK_CURRENTLY_ON(BrowserThread::UI);
|
||||
if (TestAndSetAuthHandled())
|
||||
return;
|
||||
BrowserThread::PostTask(
|
||||
BrowserThread::IO, FROM_HERE,
|
||||
base::BindOnce(&LoginHandler::DoLogin, this, username, password));
|
||||
}
|
||||
|
||||
void LoginHandler::CancelAuth() {
|
||||
DCHECK_CURRENTLY_ON(BrowserThread::UI);
|
||||
if (TestAndSetAuthHandled())
|
||||
return;
|
||||
BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
|
||||
base::BindOnce(&LoginHandler::DoCancelAuth, this));
|
||||
}
|
||||
|
||||
void LoginHandler::OnRequestCancelled() {
|
||||
TestAndSetAuthHandled();
|
||||
auth_required_callback_.Reset();
|
||||
}
|
||||
|
||||
// Marks authentication as handled and returns the previous handled state.
|
||||
bool LoginHandler::TestAndSetAuthHandled() {
|
||||
base::AutoLock lock(handled_auth_lock_);
|
||||
bool was_handled = handled_auth_;
|
||||
handled_auth_ = true;
|
||||
return was_handled;
|
||||
}
|
||||
|
||||
void LoginHandler::DoCancelAuth() {
|
||||
DCHECK_CURRENTLY_ON(BrowserThread::IO);
|
||||
if (!auth_required_callback_.is_null())
|
||||
std::move(auth_required_callback_).Run(base::nullopt);
|
||||
if (!auth_callback_.is_null())
|
||||
std::move(auth_callback_)
|
||||
.Run(net::NetworkDelegate::AUTH_REQUIRED_RESPONSE_CANCEL_AUTH);
|
||||
}
|
||||
|
||||
void LoginHandler::DoLogin(const base::string16& username,
|
||||
const base::string16& password) {
|
||||
DCHECK_CURRENTLY_ON(BrowserThread::IO);
|
||||
if (!auth_required_callback_.is_null()) {
|
||||
std::move(auth_required_callback_)
|
||||
.Run(net::AuthCredentials(username, password));
|
||||
if (!auth_callback_.is_null()) {
|
||||
credentials_->Set(username, password);
|
||||
std::move(auth_callback_)
|
||||
.Run(net::NetworkDelegate::AUTH_REQUIRED_RESPONSE_SET_AUTH);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -6,72 +6,65 @@
|
||||
#define ATOM_BROWSER_LOGIN_HANDLER_H_
|
||||
|
||||
#include "base/callback.h"
|
||||
#include "base/optional.h"
|
||||
#include "base/memory/ref_counted.h"
|
||||
#include "base/memory/weak_ptr.h"
|
||||
#include "base/strings/string16.h"
|
||||
#include "base/synchronization/lock.h"
|
||||
#include "content/public/browser/resource_dispatcher_host_login_delegate.h"
|
||||
#include "content/public/browser/resource_request_info.h"
|
||||
#include "net/base/network_delegate.h"
|
||||
|
||||
namespace content {
|
||||
class WebContents;
|
||||
}
|
||||
|
||||
namespace net {
|
||||
class AuthChallengeInfo;
|
||||
class AuthCredentials;
|
||||
} // namespace net
|
||||
|
||||
namespace atom {
|
||||
|
||||
// Handles the HTTP basic auth, must be created on IO thread.
|
||||
class LoginHandler : public content::ResourceDispatcherHostLoginDelegate {
|
||||
class LoginHandler : public base::RefCountedThreadSafe<LoginHandler> {
|
||||
public:
|
||||
LoginHandler(
|
||||
net::AuthChallengeInfo* auth_info,
|
||||
content::ResourceRequestInfo::WebContentsGetter web_contents_getter,
|
||||
const GURL& url,
|
||||
const base::Callback<void(const base::Optional<net::AuthCredentials>&)>&
|
||||
auth_required_callback);
|
||||
LoginHandler(net::URLRequest* request,
|
||||
const net::AuthChallengeInfo& auth_info,
|
||||
const net::NetworkDelegate::AuthCallback& callback,
|
||||
net::AuthCredentials* credentials,
|
||||
const content::ResourceRequestInfo* resource_request_info);
|
||||
|
||||
// The auth is cancelled, must be called on UI thread.
|
||||
void CancelAuth();
|
||||
|
||||
// The URLRequest associated with the auth is destroyed.
|
||||
void NotifyRequestDestroyed();
|
||||
|
||||
// Login with |username| and |password|, must be called on UI thread.
|
||||
void Login(const base::string16& username, const base::string16& password);
|
||||
|
||||
// Returns the WebContents associated with the request, must be called on UI
|
||||
// thread.
|
||||
content::WebContents* GetWebContents() const;
|
||||
|
||||
// The auth is cancelled, must be called on UI thread.
|
||||
void CancelAuth();
|
||||
|
||||
// Login with |username| and |password|, must be called on UI thread.
|
||||
void Login(const base::string16& username, const base::string16& password);
|
||||
|
||||
const net::AuthChallengeInfo* auth_info() const { return auth_info_.get(); }
|
||||
|
||||
protected:
|
||||
~LoginHandler() override;
|
||||
|
||||
// content::ResourceDispatcherHostLoginDelegate:
|
||||
void OnRequestCancelled() override;
|
||||
const net::AuthChallengeInfo* auth_info() const { return &auth_info_; }
|
||||
|
||||
private:
|
||||
friend class base::RefCountedThreadSafe<LoginHandler>;
|
||||
friend class base::DeleteHelper<LoginHandler>;
|
||||
|
||||
~LoginHandler();
|
||||
|
||||
// Must be called on IO thread.
|
||||
void DoCancelAuth();
|
||||
void DoLogin(const base::string16& username, const base::string16& password);
|
||||
|
||||
// Marks authentication as handled and returns the previous handled
|
||||
// state.
|
||||
bool TestAndSetAuthHandled();
|
||||
|
||||
// True if we've handled auth (Login or CancelAuth has been called).
|
||||
bool handled_auth_ = false;
|
||||
mutable base::Lock handled_auth_lock_;
|
||||
// Credentials to be used for the auth.
|
||||
net::AuthCredentials* credentials_;
|
||||
|
||||
// Who/where/what asked for the authentication.
|
||||
scoped_refptr<net::AuthChallengeInfo> auth_info_;
|
||||
const net::AuthChallengeInfo& auth_info_;
|
||||
|
||||
// WebContents associated with the login request.
|
||||
content::ResourceRequestInfo::WebContentsGetter web_contents_getter_;
|
||||
|
||||
base::Callback<void(const base::Optional<net::AuthCredentials>&)>
|
||||
auth_required_callback_;
|
||||
// Called with preferred value of net::NetworkDelegate::AuthRequiredResponse.
|
||||
net::NetworkDelegate::AuthCallback auth_callback_;
|
||||
|
||||
base::WeakPtrFactory<LoginHandler> weak_factory_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(LoginHandler);
|
||||
};
|
||||
|
||||
@@ -7,11 +7,17 @@
|
||||
#include <utility>
|
||||
|
||||
#include "atom/browser/api/atom_api_web_contents.h"
|
||||
#include "atom/browser/login_handler.h"
|
||||
#include "atom/common/native_mate_converters/net_converter.h"
|
||||
#include "atom/common/options_switches.h"
|
||||
#include "base/command_line.h"
|
||||
#include "base/stl_util.h"
|
||||
#include "base/strings/string_util.h"
|
||||
#include "content/public/browser/browser_thread.h"
|
||||
#include "content/public/browser/render_frame_host.h"
|
||||
#include "content/public/browser/resource_request_info.h"
|
||||
#include "net/base/load_flags.h"
|
||||
#include "net/base/net_errors.h"
|
||||
#include "net/url_request/url_request.h"
|
||||
#include "services/network/throttling/throttling_network_transaction.h"
|
||||
|
||||
@@ -231,7 +237,15 @@ AtomNetworkDelegate::ResponseListenerInfo::ResponseListenerInfo(
|
||||
AtomNetworkDelegate::ResponseListenerInfo::ResponseListenerInfo() = default;
|
||||
AtomNetworkDelegate::ResponseListenerInfo::~ResponseListenerInfo() = default;
|
||||
|
||||
AtomNetworkDelegate::AtomNetworkDelegate() {}
|
||||
AtomNetworkDelegate::AtomNetworkDelegate() {
|
||||
auto* command_line = base::CommandLine::ForCurrentProcess();
|
||||
if (command_line->HasSwitch(switches::kIgnoreConnectionsLimit)) {
|
||||
std::string value =
|
||||
command_line->GetSwitchValueASCII(switches::kIgnoreConnectionsLimit);
|
||||
ignore_connections_limit_domains_ = base::SplitString(
|
||||
value, ",", base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY);
|
||||
}
|
||||
}
|
||||
|
||||
AtomNetworkDelegate::~AtomNetworkDelegate() {}
|
||||
|
||||
@@ -262,9 +276,17 @@ int AtomNetworkDelegate::OnBeforeURLRequest(
|
||||
net::URLRequest* request,
|
||||
const net::CompletionCallback& callback,
|
||||
GURL* new_url) {
|
||||
if (!base::ContainsKey(response_listeners_, kOnBeforeRequest))
|
||||
return brightray::NetworkDelegate::OnBeforeURLRequest(request, callback,
|
||||
new_url);
|
||||
if (!base::ContainsKey(response_listeners_, kOnBeforeRequest)) {
|
||||
for (const auto& domain : ignore_connections_limit_domains_) {
|
||||
if (request->url().DomainIs(domain)) {
|
||||
// Allow unlimited concurrent connections.
|
||||
request->SetPriority(net::MAXIMUM_PRIORITY);
|
||||
request->SetLoadFlags(request->load_flags() | net::LOAD_IGNORE_LIMITS);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return net::OK;
|
||||
}
|
||||
|
||||
return HandleResponseEvent(kOnBeforeRequest, request, callback, new_url);
|
||||
}
|
||||
@@ -278,8 +300,7 @@ int AtomNetworkDelegate::OnBeforeStartTransaction(
|
||||
kDevToolsEmulateNetworkConditionsClientId,
|
||||
client_id_);
|
||||
if (!base::ContainsKey(response_listeners_, kOnBeforeSendHeaders))
|
||||
return brightray::NetworkDelegate::OnBeforeStartTransaction(
|
||||
request, callback, headers);
|
||||
return net::OK;
|
||||
|
||||
return HandleResponseEvent(kOnBeforeSendHeaders, request, callback, headers,
|
||||
*headers);
|
||||
@@ -288,10 +309,8 @@ int AtomNetworkDelegate::OnBeforeStartTransaction(
|
||||
void AtomNetworkDelegate::OnStartTransaction(
|
||||
net::URLRequest* request,
|
||||
const net::HttpRequestHeaders& headers) {
|
||||
if (!base::ContainsKey(simple_listeners_, kOnSendHeaders)) {
|
||||
brightray::NetworkDelegate::OnStartTransaction(request, headers);
|
||||
if (!base::ContainsKey(simple_listeners_, kOnSendHeaders))
|
||||
return;
|
||||
}
|
||||
|
||||
HandleSimpleEvent(kOnSendHeaders, request, headers);
|
||||
}
|
||||
@@ -303,8 +322,7 @@ int AtomNetworkDelegate::OnHeadersReceived(
|
||||
scoped_refptr<net::HttpResponseHeaders>* override,
|
||||
GURL* allowed) {
|
||||
if (!base::ContainsKey(response_listeners_, kOnHeadersReceived))
|
||||
return brightray::NetworkDelegate::OnHeadersReceived(
|
||||
request, callback, original, override, allowed);
|
||||
return net::OK;
|
||||
|
||||
return HandleResponseEvent(
|
||||
kOnHeadersReceived, request, callback,
|
||||
@@ -313,10 +331,8 @@ int AtomNetworkDelegate::OnHeadersReceived(
|
||||
|
||||
void AtomNetworkDelegate::OnBeforeRedirect(net::URLRequest* request,
|
||||
const GURL& new_location) {
|
||||
if (!base::ContainsKey(simple_listeners_, kOnBeforeRedirect)) {
|
||||
brightray::NetworkDelegate::OnBeforeRedirect(request, new_location);
|
||||
if (!base::ContainsKey(simple_listeners_, kOnBeforeRedirect))
|
||||
return;
|
||||
}
|
||||
|
||||
HandleSimpleEvent(kOnBeforeRedirect, request, new_location,
|
||||
request->response_headers(), request->GetSocketAddress(),
|
||||
@@ -325,10 +341,8 @@ void AtomNetworkDelegate::OnBeforeRedirect(net::URLRequest* request,
|
||||
|
||||
void AtomNetworkDelegate::OnResponseStarted(net::URLRequest* request,
|
||||
int net_error) {
|
||||
if (!base::ContainsKey(simple_listeners_, kOnResponseStarted)) {
|
||||
brightray::NetworkDelegate::OnResponseStarted(request, net_error);
|
||||
if (!base::ContainsKey(simple_listeners_, kOnResponseStarted))
|
||||
return;
|
||||
}
|
||||
|
||||
if (request->status().status() != net::URLRequestStatus::SUCCESS)
|
||||
return;
|
||||
@@ -346,33 +360,109 @@ void AtomNetworkDelegate::OnCompleted(net::URLRequest* request, bool started) {
|
||||
// Error event.
|
||||
OnErrorOccurred(request, started);
|
||||
return;
|
||||
} else if (request->response_headers() &&
|
||||
net::HttpResponseHeaders::IsRedirectResponseCode(
|
||||
request->response_headers()->response_code())) {
|
||||
}
|
||||
|
||||
if (request->response_headers() &&
|
||||
net::HttpResponseHeaders::IsRedirectResponseCode(
|
||||
request->response_headers()->response_code())) {
|
||||
// Redirect event.
|
||||
brightray::NetworkDelegate::OnCompleted(request, started);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!base::ContainsKey(simple_listeners_, kOnCompleted)) {
|
||||
brightray::NetworkDelegate::OnCompleted(request, started);
|
||||
if (!base::ContainsKey(simple_listeners_, kOnCompleted))
|
||||
return;
|
||||
}
|
||||
|
||||
HandleSimpleEvent(kOnCompleted, request, request->response_headers(),
|
||||
request->was_cached());
|
||||
}
|
||||
|
||||
void AtomNetworkDelegate::OnURLRequestDestroyed(net::URLRequest* request) {
|
||||
const auto& it = login_handler_map_.find(request->identifier());
|
||||
if (it != login_handler_map_.end()) {
|
||||
it->second->NotifyRequestDestroyed();
|
||||
it->second = nullptr;
|
||||
login_handler_map_.erase(it);
|
||||
}
|
||||
callbacks_.erase(request->identifier());
|
||||
}
|
||||
|
||||
net::NetworkDelegate::AuthRequiredResponse AtomNetworkDelegate::OnAuthRequired(
|
||||
net::URLRequest* request,
|
||||
const net::AuthChallengeInfo& auth_info,
|
||||
const AuthCallback& callback,
|
||||
net::AuthCredentials* credentials) {
|
||||
auto* resource_request_info =
|
||||
content::ResourceRequestInfo::ForRequest(request);
|
||||
if (!resource_request_info)
|
||||
return AUTH_REQUIRED_RESPONSE_NO_ACTION;
|
||||
login_handler_map_.emplace(
|
||||
request->identifier(),
|
||||
new LoginHandler(request, auth_info, std::move(callback), credentials,
|
||||
resource_request_info));
|
||||
return AUTH_REQUIRED_RESPONSE_IO_PENDING;
|
||||
}
|
||||
|
||||
bool AtomNetworkDelegate::OnCanGetCookies(const net::URLRequest& request,
|
||||
const net::CookieList& cookie_list) {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool AtomNetworkDelegate::OnCanSetCookie(
|
||||
const net::URLRequest& request,
|
||||
const net::CanonicalCookie& cookie_line,
|
||||
net::CookieOptions* options) {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool AtomNetworkDelegate::OnCanAccessFile(
|
||||
const net::URLRequest& request,
|
||||
const base::FilePath& original_path,
|
||||
const base::FilePath& absolute_path) const {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool AtomNetworkDelegate::OnCanEnablePrivacyMode(
|
||||
const GURL& url,
|
||||
const GURL& first_party_for_cookies) const {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool AtomNetworkDelegate::OnAreExperimentalCookieFeaturesEnabled() const {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool AtomNetworkDelegate::OnCancelURLRequestWithPolicyViolatingReferrerHeader(
|
||||
const net::URLRequest& request,
|
||||
const GURL& target_url,
|
||||
const GURL& referrer_url) const {
|
||||
return false;
|
||||
}
|
||||
|
||||
// TODO(deepak1556) : Enable after hooking into the reporting service
|
||||
// https://crbug.com/704259
|
||||
bool AtomNetworkDelegate::OnCanQueueReportingReport(
|
||||
const url::Origin& origin) const {
|
||||
return false;
|
||||
}
|
||||
|
||||
void AtomNetworkDelegate::OnCanSendReportingReports(
|
||||
std::set<url::Origin> origins,
|
||||
base::OnceCallback<void(std::set<url::Origin>)> result_callback) const {}
|
||||
|
||||
bool AtomNetworkDelegate::OnCanSetReportingClient(const url::Origin& origin,
|
||||
const GURL& endpoint) const {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool AtomNetworkDelegate::OnCanUseReportingClient(const url::Origin& origin,
|
||||
const GURL& endpoint) const {
|
||||
return false;
|
||||
}
|
||||
|
||||
void AtomNetworkDelegate::OnErrorOccurred(net::URLRequest* request,
|
||||
bool started) {
|
||||
if (!base::ContainsKey(simple_listeners_, kOnErrorOccurred)) {
|
||||
brightray::NetworkDelegate::OnCompleted(request, started);
|
||||
if (!base::ContainsKey(simple_listeners_, kOnErrorOccurred))
|
||||
return;
|
||||
}
|
||||
|
||||
HandleSimpleEvent(kOnErrorOccurred, request, request->was_cached(),
|
||||
request->status());
|
||||
|
||||
@@ -8,14 +8,14 @@
|
||||
#include <map>
|
||||
#include <set>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "base/callback.h"
|
||||
#include "base/synchronization/lock.h"
|
||||
#include "base/values.h"
|
||||
#include "brightray/browser/network_delegate.h"
|
||||
#include "content/public/browser/resource_request_info.h"
|
||||
#include "extensions/common/url_pattern.h"
|
||||
#include "net/base/net_errors.h"
|
||||
#include "net/base/network_delegate.h"
|
||||
#include "net/http/http_request_headers.h"
|
||||
#include "net/http/http_response_headers.h"
|
||||
|
||||
@@ -27,7 +27,9 @@ using URLPatterns = std::set<URLPattern>;
|
||||
|
||||
const char* ResourceTypeToString(content::ResourceType type);
|
||||
|
||||
class AtomNetworkDelegate : public brightray::NetworkDelegate {
|
||||
class LoginHandler;
|
||||
|
||||
class AtomNetworkDelegate : public net::NetworkDelegate {
|
||||
public:
|
||||
using ResponseCallback = base::Callback<void(const base::DictionaryValue&)>;
|
||||
using SimpleListener = base::Callback<void(const base::DictionaryValue&)>;
|
||||
@@ -86,6 +88,10 @@ class AtomNetworkDelegate : public brightray::NetworkDelegate {
|
||||
int OnBeforeStartTransaction(net::URLRequest* request,
|
||||
const net::CompletionCallback& callback,
|
||||
net::HttpRequestHeaders* headers) override;
|
||||
void OnBeforeSendHeaders(net::URLRequest* request,
|
||||
const net::ProxyInfo& proxy_info,
|
||||
const net::ProxyRetryInfoMap& proxy_retry_info,
|
||||
net::HttpRequestHeaders* headers) override {}
|
||||
void OnStartTransaction(net::URLRequest* request,
|
||||
const net::HttpRequestHeaders& headers) override;
|
||||
int OnHeadersReceived(
|
||||
@@ -97,8 +103,43 @@ class AtomNetworkDelegate : public brightray::NetworkDelegate {
|
||||
void OnBeforeRedirect(net::URLRequest* request,
|
||||
const GURL& new_location) override;
|
||||
void OnResponseStarted(net::URLRequest* request, int net_error) override;
|
||||
void OnNetworkBytesReceived(net::URLRequest* request,
|
||||
int64_t bytes_read) override {}
|
||||
void OnNetworkBytesSent(net::URLRequest* request,
|
||||
int64_t bytes_sent) override {}
|
||||
void OnCompleted(net::URLRequest* request, bool started) override;
|
||||
void OnURLRequestDestroyed(net::URLRequest* request) override;
|
||||
void OnPACScriptError(int line_number, const base::string16& error) override {
|
||||
}
|
||||
AuthRequiredResponse OnAuthRequired(
|
||||
net::URLRequest* request,
|
||||
const net::AuthChallengeInfo& auth_info,
|
||||
const AuthCallback& callback,
|
||||
net::AuthCredentials* credentials) override;
|
||||
bool OnCanGetCookies(const net::URLRequest& request,
|
||||
const net::CookieList& cookie_list) override;
|
||||
bool OnCanSetCookie(const net::URLRequest& request,
|
||||
const net::CanonicalCookie& cookie_line,
|
||||
net::CookieOptions* options) override;
|
||||
bool OnCanAccessFile(const net::URLRequest& request,
|
||||
const base::FilePath& original_path,
|
||||
const base::FilePath& absolute_path) const override;
|
||||
bool OnCanEnablePrivacyMode(
|
||||
const GURL& url,
|
||||
const GURL& first_party_for_cookies) const override;
|
||||
bool OnAreExperimentalCookieFeaturesEnabled() const override;
|
||||
bool OnCancelURLRequestWithPolicyViolatingReferrerHeader(
|
||||
const net::URLRequest& request,
|
||||
const GURL& target_url,
|
||||
const GURL& referrer_url) const override;
|
||||
bool OnCanQueueReportingReport(const url::Origin& origin) const override;
|
||||
void OnCanSendReportingReports(std::set<url::Origin> origins,
|
||||
base::OnceCallback<void(std::set<url::Origin>)>
|
||||
result_callback) const override;
|
||||
bool OnCanSetReportingClient(const url::Origin& origin,
|
||||
const GURL& endpoint) const override;
|
||||
bool OnCanUseReportingClient(const url::Origin& origin,
|
||||
const GURL& endpoint) const override;
|
||||
|
||||
private:
|
||||
void OnErrorOccurred(net::URLRequest* request, bool started);
|
||||
@@ -124,9 +165,11 @@ class AtomNetworkDelegate : public brightray::NetworkDelegate {
|
||||
T out,
|
||||
const base::DictionaryValue& response);
|
||||
|
||||
std::map<uint64_t, scoped_refptr<LoginHandler>> login_handler_map_;
|
||||
std::map<SimpleEvent, SimpleListenerInfo> simple_listeners_;
|
||||
std::map<ResponseEvent, ResponseListenerInfo> response_listeners_;
|
||||
std::map<uint64_t, net::CompletionCallback> callbacks_;
|
||||
std::vector<std::string> ignore_connections_limit_domains_;
|
||||
|
||||
// Client id for devtools network emulation.
|
||||
std::string client_id_;
|
||||
|
||||
@@ -70,11 +70,8 @@ scoped_refptr<AtomURLRequest> AtomURLRequest::Create(
|
||||
return nullptr;
|
||||
}
|
||||
scoped_refptr<brightray::URLRequestContextGetter> request_context_getter(
|
||||
browser_context->url_request_context_getter());
|
||||
browser_context->GetRequestContext());
|
||||
DCHECK(request_context_getter);
|
||||
if (!request_context_getter) {
|
||||
return nullptr;
|
||||
}
|
||||
scoped_refptr<AtomURLRequest> atom_url_request(new AtomURLRequest(delegate));
|
||||
if (content::BrowserThread::PostTask(
|
||||
content::BrowserThread::IO, FROM_HERE,
|
||||
@@ -504,4 +501,16 @@ void AtomURLRequest::InformDelegateErrorOccured(const std::string& error,
|
||||
delegate_->OnError(error, isRequestError);
|
||||
}
|
||||
|
||||
void AtomURLRequest::GetUploadProgress(mate::Dictionary* progress) const {
|
||||
net::UploadProgress upload_progress;
|
||||
if (request_) {
|
||||
progress->Set("started", true);
|
||||
upload_progress = request_->GetUploadProgress();
|
||||
} else {
|
||||
progress->Set("started", false);
|
||||
}
|
||||
progress->Set("current", upload_progress.position());
|
||||
progress->Set("total", upload_progress.size());
|
||||
}
|
||||
|
||||
} // namespace atom
|
||||
|
||||
@@ -43,6 +43,7 @@ class AtomURLRequest : public base::RefCountedThreadSafe<AtomURLRequest>,
|
||||
void PassLoginInformation(const base::string16& username,
|
||||
const base::string16& password) const;
|
||||
void SetLoadFlags(int flags) const;
|
||||
void GetUploadProgress(mate::Dictionary* progress) const;
|
||||
|
||||
protected:
|
||||
// Overrides of net::URLRequest::Delegate
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
|
||||
#include "atom/browser/api/atom_api_session.h"
|
||||
#include "atom/browser/atom_browser_context.h"
|
||||
#include "base/guid.h"
|
||||
#include "base/memory/ptr_util.h"
|
||||
#include "base/strings/string_util.h"
|
||||
#include "native_mate/dictionary.h"
|
||||
@@ -93,16 +94,15 @@ void URLRequestFetchJob::BeforeStartInUI(v8::Isolate* isolate,
|
||||
if (options.Get("session", &val)) {
|
||||
if (val->IsNull()) {
|
||||
// We have to create the URLRequestContextGetter on UI thread.
|
||||
url_request_context_getter_ = new brightray::URLRequestContextGetter(
|
||||
this, nullptr, base::FilePath(), true,
|
||||
BrowserThread::GetTaskRunnerForThread(BrowserThread::IO), nullptr,
|
||||
content::URLRequestInterceptorScopedVector());
|
||||
custom_browser_context_ =
|
||||
AtomBrowserContext::From(base::GenerateGUID(), true);
|
||||
url_request_context_getter_ =
|
||||
custom_browser_context_->GetRequestContext();
|
||||
} else {
|
||||
mate::Handle<api::Session> session;
|
||||
if (mate::ConvertFromV8(isolate, val, &session) && !session.IsEmpty()) {
|
||||
AtomBrowserContext* browser_context = session->browser_context();
|
||||
url_request_context_getter_ =
|
||||
browser_context->url_request_context_getter();
|
||||
url_request_context_getter_ = browser_context->GetRequestContext();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,16 +8,17 @@
|
||||
#include <string>
|
||||
|
||||
#include "atom/browser/net/js_asker.h"
|
||||
#include "brightray/browser/url_request_context_getter.h"
|
||||
#include "content/browser/streams/stream.h"
|
||||
#include "content/browser/streams/stream_read_observer.h"
|
||||
#include "net/url_request/url_fetcher_delegate.h"
|
||||
#include "net/url_request/url_request_context_getter.h"
|
||||
|
||||
namespace atom {
|
||||
|
||||
class AtomBrowserContext;
|
||||
|
||||
class URLRequestFetchJob : public JsAsker<net::URLRequestJob>,
|
||||
public net::URLFetcherDelegate,
|
||||
public brightray::URLRequestContextGetter::Delegate {
|
||||
public net::URLFetcherDelegate {
|
||||
public:
|
||||
URLRequestFetchJob(net::URLRequest*, net::NetworkDelegate*);
|
||||
~URLRequestFetchJob() override;
|
||||
@@ -51,6 +52,7 @@ class URLRequestFetchJob : public JsAsker<net::URLRequestJob>,
|
||||
void ClearPendingBuffer();
|
||||
void ClearWriteBuffer();
|
||||
|
||||
scoped_refptr<AtomBrowserContext> custom_browser_context_;
|
||||
scoped_refptr<net::URLRequestContextGetter> url_request_context_getter_;
|
||||
std::unique_ptr<net::URLFetcher> fetcher_;
|
||||
std::unique_ptr<net::HttpResponseInfo> response_info_;
|
||||
|
||||
@@ -4,6 +4,8 @@
|
||||
|
||||
#include "atom/browser/node_debugger.h"
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "base/command_line.h"
|
||||
#include "base/strings/utf_string_conversions.h"
|
||||
#include "libplatform/libplatform.h"
|
||||
@@ -25,10 +27,15 @@ void NodeDebugger::Start(node::MultiIsolatePlatform* platform) {
|
||||
node::DebugOptions options;
|
||||
for (auto& arg : base::CommandLine::ForCurrentProcess()->argv()) {
|
||||
#if defined(OS_WIN)
|
||||
options.ParseOption("Electron", base::UTF16ToUTF8(arg));
|
||||
const std::string nice_arg = base::UTF16ToUTF8(arg);
|
||||
#else
|
||||
options.ParseOption("Electron", arg);
|
||||
const std::string& nice_arg = arg;
|
||||
#endif
|
||||
// Stop handling arguments after a "--" to be consistent with Chromium
|
||||
if (nice_arg == "--")
|
||||
break;
|
||||
|
||||
options.ParseOption("Electron", nice_arg);
|
||||
}
|
||||
|
||||
// Set process._debugWaitConnect if --inspect-brk was specified to stop
|
||||
|
||||
163
atom/browser/request_context_delegate.cc
Normal file
163
atom/browser/request_context_delegate.cc
Normal file
@@ -0,0 +1,163 @@
|
||||
// Copyright (c) 2018 GitHub, Inc.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "atom/browser/request_context_delegate.h"
|
||||
|
||||
#include "atom/browser/api/atom_api_protocol.h"
|
||||
#include "atom/browser/net/about_protocol_handler.h"
|
||||
#include "atom/browser/net/asar/asar_protocol_handler.h"
|
||||
#include "atom/browser/net/atom_cert_verifier.h"
|
||||
#include "atom/browser/net/atom_network_delegate.h"
|
||||
#include "atom/browser/net/atom_url_request_job_factory.h"
|
||||
#include "atom/browser/net/cookie_details.h"
|
||||
#include "atom/browser/net/http_protocol_handler.h"
|
||||
#include "atom/common/options_switches.h"
|
||||
#include "base/strings/string_number_conversions.h"
|
||||
#include "base/task_scheduler/post_task.h"
|
||||
#include "content/public/browser/browser_thread.h"
|
||||
#include "content/public/common/url_constants.h"
|
||||
#include "net/ftp/ftp_network_layer.h"
|
||||
#include "net/url_request/data_protocol_handler.h"
|
||||
#include "net/url_request/ftp_protocol_handler.h"
|
||||
#include "net/url_request/url_request_context.h"
|
||||
#include "net/url_request/url_request_intercepting_job_factory.h"
|
||||
#include "url/url_constants.h"
|
||||
|
||||
using content::BrowserThread;
|
||||
|
||||
namespace atom {
|
||||
|
||||
namespace {
|
||||
|
||||
class NoCacheBackend : public net::HttpCache::BackendFactory {
|
||||
int CreateBackend(net::NetLog* net_log,
|
||||
std::unique_ptr<disk_cache::Backend>* backend,
|
||||
const net::CompletionCallback& callback) override {
|
||||
return net::ERR_FAILED;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
RequestContextDelegate::RequestContextDelegate(bool use_cache)
|
||||
: use_cache_(use_cache), weak_factory_(this) {}
|
||||
|
||||
RequestContextDelegate::~RequestContextDelegate() {}
|
||||
|
||||
std::unique_ptr<base::CallbackList<void(const CookieDetails*)>::Subscription>
|
||||
RequestContextDelegate::RegisterCookieChangeCallback(
|
||||
const base::Callback<void(const CookieDetails*)>& cb) {
|
||||
DCHECK_CURRENTLY_ON(BrowserThread::UI);
|
||||
|
||||
return cookie_change_sub_list_.Add(cb);
|
||||
}
|
||||
|
||||
void RequestContextDelegate::NotifyCookieChange(
|
||||
const net::CanonicalCookie& cookie,
|
||||
net::CookieChangeCause cause) {
|
||||
DCHECK_CURRENTLY_ON(BrowserThread::UI);
|
||||
|
||||
CookieDetails cookie_details(
|
||||
&cookie, !(cause == net::CookieChangeCause::INSERTED), cause);
|
||||
cookie_change_sub_list_.Notify(&cookie_details);
|
||||
}
|
||||
|
||||
std::unique_ptr<net::NetworkDelegate>
|
||||
RequestContextDelegate::CreateNetworkDelegate() {
|
||||
DCHECK_CURRENTLY_ON(BrowserThread::IO);
|
||||
|
||||
return std::make_unique<AtomNetworkDelegate>();
|
||||
}
|
||||
|
||||
std::unique_ptr<net::URLRequestJobFactory>
|
||||
RequestContextDelegate::CreateURLRequestJobFactory(
|
||||
net::URLRequestContext* url_request_context,
|
||||
content::ProtocolHandlerMap* protocol_handlers) {
|
||||
DCHECK_CURRENTLY_ON(BrowserThread::IO);
|
||||
|
||||
std::unique_ptr<AtomURLRequestJobFactory> job_factory(
|
||||
new AtomURLRequestJobFactory);
|
||||
|
||||
for (auto& it : *protocol_handlers) {
|
||||
job_factory->SetProtocolHandler(it.first,
|
||||
base::WrapUnique(it.second.release()));
|
||||
}
|
||||
protocol_handlers->clear();
|
||||
|
||||
job_factory->SetProtocolHandler(url::kAboutScheme,
|
||||
base::WrapUnique(new AboutProtocolHandler));
|
||||
job_factory->SetProtocolHandler(
|
||||
url::kDataScheme, base::WrapUnique(new net::DataProtocolHandler));
|
||||
job_factory->SetProtocolHandler(
|
||||
url::kFileScheme,
|
||||
base::WrapUnique(
|
||||
new asar::AsarProtocolHandler(base::CreateTaskRunnerWithTraits(
|
||||
{base::MayBlock(), base::TaskPriority::USER_VISIBLE,
|
||||
base::TaskShutdownBehavior::SKIP_ON_SHUTDOWN}))));
|
||||
job_factory->SetProtocolHandler(
|
||||
url::kHttpScheme,
|
||||
base::WrapUnique(new HttpProtocolHandler(url::kHttpScheme)));
|
||||
job_factory->SetProtocolHandler(
|
||||
url::kHttpsScheme,
|
||||
base::WrapUnique(new HttpProtocolHandler(url::kHttpsScheme)));
|
||||
job_factory->SetProtocolHandler(
|
||||
url::kWsScheme,
|
||||
base::WrapUnique(new HttpProtocolHandler(url::kWsScheme)));
|
||||
job_factory->SetProtocolHandler(
|
||||
url::kWssScheme,
|
||||
base::WrapUnique(new HttpProtocolHandler(url::kWssScheme)));
|
||||
|
||||
auto* host_resolver = url_request_context->host_resolver();
|
||||
job_factory->SetProtocolHandler(
|
||||
url::kFtpScheme, net::FtpProtocolHandler::Create(host_resolver));
|
||||
|
||||
return std::move(job_factory);
|
||||
}
|
||||
|
||||
net::HttpCache::BackendFactory*
|
||||
RequestContextDelegate::CreateHttpCacheBackendFactory(
|
||||
const base::FilePath& base_path) {
|
||||
DCHECK_CURRENTLY_ON(BrowserThread::IO);
|
||||
|
||||
base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
|
||||
if (!use_cache_) {
|
||||
return new NoCacheBackend;
|
||||
} else {
|
||||
int max_size = 0;
|
||||
base::StringToInt(
|
||||
command_line->GetSwitchValueASCII(switches::kDiskCacheSize), &max_size);
|
||||
|
||||
base::FilePath cache_path = base_path.Append(FILE_PATH_LITERAL("Cache"));
|
||||
return new net::HttpCache::DefaultBackend(
|
||||
net::DISK_CACHE, net::CACHE_BACKEND_DEFAULT, cache_path, max_size);
|
||||
}
|
||||
}
|
||||
|
||||
std::unique_ptr<net::CertVerifier> RequestContextDelegate::CreateCertVerifier(
|
||||
brightray::RequireCTDelegate* ct_delegate) {
|
||||
DCHECK_CURRENTLY_ON(BrowserThread::IO);
|
||||
|
||||
return std::make_unique<AtomCertVerifier>(ct_delegate);
|
||||
}
|
||||
|
||||
void RequestContextDelegate::GetCookieableSchemes(
|
||||
std::vector<std::string>* cookie_schemes) {
|
||||
DCHECK_CURRENTLY_ON(BrowserThread::IO);
|
||||
|
||||
const auto& standard_schemes = atom::api::GetStandardSchemes();
|
||||
cookie_schemes->insert(cookie_schemes->end(), standard_schemes.begin(),
|
||||
standard_schemes.end());
|
||||
}
|
||||
|
||||
void RequestContextDelegate::OnCookieChanged(const net::CanonicalCookie& cookie,
|
||||
net::CookieChangeCause cause) {
|
||||
DCHECK_CURRENTLY_ON(BrowserThread::IO);
|
||||
|
||||
BrowserThread::PostTask(
|
||||
BrowserThread::UI, FROM_HERE,
|
||||
base::BindRepeating(&RequestContextDelegate::NotifyCookieChange,
|
||||
weak_factory_.GetWeakPtr(), cookie, cause));
|
||||
}
|
||||
|
||||
} // namespace atom
|
||||
58
atom/browser/request_context_delegate.h
Normal file
58
atom/browser/request_context_delegate.h
Normal file
@@ -0,0 +1,58 @@
|
||||
// Copyright (c) 2018 GitHub, Inc.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef ATOM_BROWSER_REQUEST_CONTEXT_DELEGATE_H_
|
||||
#define ATOM_BROWSER_REQUEST_CONTEXT_DELEGATE_H_
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "base/callback_list.h"
|
||||
#include "base/macros.h"
|
||||
#include "base/memory/weak_ptr.h"
|
||||
#include "brightray/browser/url_request_context_getter.h"
|
||||
|
||||
namespace atom {
|
||||
|
||||
struct CookieDetails;
|
||||
|
||||
class RequestContextDelegate
|
||||
: public brightray::URLRequestContextGetter::Delegate {
|
||||
public:
|
||||
explicit RequestContextDelegate(bool use_cache);
|
||||
~RequestContextDelegate() override;
|
||||
|
||||
// Register callbacks that needs to notified on any cookie store changes.
|
||||
std::unique_ptr<base::CallbackList<void(const CookieDetails*)>::Subscription>
|
||||
RegisterCookieChangeCallback(
|
||||
const base::Callback<void(const CookieDetails*)>& cb);
|
||||
|
||||
protected:
|
||||
std::unique_ptr<net::NetworkDelegate> CreateNetworkDelegate() override;
|
||||
std::unique_ptr<net::URLRequestJobFactory> CreateURLRequestJobFactory(
|
||||
net::URLRequestContext* url_request_context,
|
||||
content::ProtocolHandlerMap* protocol_handlers) override;
|
||||
net::HttpCache::BackendFactory* CreateHttpCacheBackendFactory(
|
||||
const base::FilePath& base_path) override;
|
||||
std::unique_ptr<net::CertVerifier> CreateCertVerifier(
|
||||
brightray::RequireCTDelegate* ct_delegate) override;
|
||||
void GetCookieableSchemes(std::vector<std::string>* cookie_schemes) override;
|
||||
void OnCookieChanged(const net::CanonicalCookie& cookie,
|
||||
net::CookieChangeCause cause) override;
|
||||
|
||||
private:
|
||||
void NotifyCookieChange(const net::CanonicalCookie& cookie,
|
||||
net::CookieChangeCause cause);
|
||||
|
||||
base::CallbackList<void(const CookieDetails*)> cookie_change_sub_list_;
|
||||
bool use_cache_ = true;
|
||||
|
||||
base::WeakPtrFactory<RequestContextDelegate> weak_factory_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(RequestContextDelegate);
|
||||
};
|
||||
|
||||
} // namespace atom
|
||||
|
||||
#endif // ATOM_BROWSER_REQUEST_CONTEXT_DELEGATE_H_
|
||||
@@ -56,8 +56,8 @@ END
|
||||
//
|
||||
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
FILEVERSION 3,0,0,6
|
||||
PRODUCTVERSION 3,0,0,6
|
||||
FILEVERSION 3,0,0,20180904
|
||||
PRODUCTVERSION 3,0,0,20180904
|
||||
FILEFLAGSMASK 0x3fL
|
||||
#ifdef _DEBUG
|
||||
FILEFLAGS 0x1L
|
||||
|
||||
@@ -41,9 +41,15 @@ const CGFloat kVerticalTitleMargin = 2;
|
||||
|
||||
@implementation StatusItemView
|
||||
|
||||
- (id)initWithImage:(NSImage*)image icon:(atom::TrayIconCocoa*)icon {
|
||||
image_.reset([image copy]);
|
||||
- (void)dealloc {
|
||||
trayIcon_ = nil;
|
||||
menuController_ = nil;
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
- (id)initWithIcon:(atom::TrayIconCocoa*)icon {
|
||||
trayIcon_ = icon;
|
||||
menuController_ = nil;
|
||||
highlight_mode_ = atom::TrayIcon::HighlightMode::SELECTION;
|
||||
ignoreDoubleClickEvents_ = NO;
|
||||
forceHighlight_ = NO;
|
||||
@@ -89,6 +95,7 @@ const CGFloat kVerticalTitleMargin = 2;
|
||||
trackingArea_.reset();
|
||||
}
|
||||
[[NSStatusBar systemStatusBar] removeStatusItem:statusItem_];
|
||||
[statusItem_ setView:nil];
|
||||
statusItem_.reset();
|
||||
}
|
||||
|
||||
@@ -156,6 +163,8 @@ const CGFloat kVerticalTitleMargin = 2;
|
||||
|
||||
// The width of the icon.
|
||||
- (CGFloat)iconWidth {
|
||||
if (!image_ && title_)
|
||||
return kHorizontalMargin;
|
||||
CGFloat thickness = [[NSStatusBar systemStatusBar] thickness];
|
||||
CGFloat imageHeight = [image_ size].height;
|
||||
CGFloat imageWidth = [image_ size].width;
|
||||
@@ -424,7 +433,9 @@ const CGFloat kVerticalTitleMargin = 2;
|
||||
|
||||
namespace atom {
|
||||
|
||||
TrayIconCocoa::TrayIconCocoa() {}
|
||||
TrayIconCocoa::TrayIconCocoa() {
|
||||
status_item_view_.reset([[StatusItemView alloc] initWithIcon:this]);
|
||||
}
|
||||
|
||||
TrayIconCocoa::~TrayIconCocoa() {
|
||||
[status_item_view_ removeItem];
|
||||
@@ -433,12 +444,7 @@ TrayIconCocoa::~TrayIconCocoa() {
|
||||
}
|
||||
|
||||
void TrayIconCocoa::SetImage(const gfx::Image& image) {
|
||||
if (status_item_view_) {
|
||||
[status_item_view_ setImage:image.AsNSImage()];
|
||||
} else {
|
||||
status_item_view_.reset(
|
||||
[[StatusItemView alloc] initWithImage:image.AsNSImage() icon:this]);
|
||||
}
|
||||
[status_item_view_ setImage:image.IsEmpty() ? nil : image.AsNSImage()];
|
||||
}
|
||||
|
||||
void TrayIconCocoa::SetPressedImage(const gfx::Image& image) {
|
||||
@@ -474,11 +480,18 @@ void TrayIconCocoa::SetContextMenu(AtomMenuModel* menu_model) {
|
||||
// Substribe to MenuClosed event.
|
||||
if (menu_model_)
|
||||
menu_model_->RemoveObserver(this);
|
||||
menu_model->AddObserver(this);
|
||||
|
||||
// Create native menu.
|
||||
menu_.reset([[AtomMenuController alloc] initWithModel:menu_model
|
||||
useDefaultAccelerator:NO]);
|
||||
menu_model_ = menu_model;
|
||||
|
||||
if (menu_model) {
|
||||
menu_model->AddObserver(this);
|
||||
// Create native menu.
|
||||
menu_.reset([[AtomMenuController alloc] initWithModel:menu_model
|
||||
useDefaultAccelerator:NO]);
|
||||
} else {
|
||||
menu_.reset();
|
||||
}
|
||||
|
||||
[status_item_view_ setMenuController:menu_.get()];
|
||||
}
|
||||
|
||||
|
||||
@@ -31,6 +31,22 @@ bool IsPDFViewerEnabled() {
|
||||
#endif
|
||||
}
|
||||
|
||||
bool IsFakeLocationProviderEnabled() {
|
||||
#if defined(OVERRIDE_LOCATION_PROVIDER)
|
||||
return true;
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
bool IsViewApiEnabled() {
|
||||
#if defined(ENABLE_VIEW_API)
|
||||
return true;
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
void Initialize(v8::Local<v8::Object> exports,
|
||||
v8::Local<v8::Value> unused,
|
||||
v8::Local<v8::Context> context,
|
||||
@@ -39,6 +55,9 @@ void Initialize(v8::Local<v8::Object> exports,
|
||||
dict.SetMethod("isDesktopCapturerEnabled", &IsDesktopCapturerEnabled);
|
||||
dict.SetMethod("isOffscreenRenderingEnabled", &IsOffscreenRenderingEnabled);
|
||||
dict.SetMethod("isPDFViewerEnabled", &IsPDFViewerEnabled);
|
||||
dict.SetMethod("isFakeLocationProviderEnabled",
|
||||
&IsFakeLocationProviderEnabled);
|
||||
dict.SetMethod("isViewApiEnabled", &IsViewApiEnabled);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
#define ATOM_MAJOR_VERSION 3
|
||||
#define ATOM_MINOR_VERSION 0
|
||||
#define ATOM_PATCH_VERSION 0
|
||||
#define ATOM_PRE_RELEASE_VERSION -beta.6
|
||||
#define ATOM_PRE_RELEASE_VERSION -nightly.20180904
|
||||
|
||||
#ifndef ATOM_STRINGIFY
|
||||
#define ATOM_STRINGIFY(n) ATOM_STRINGIFY_HELPER(n)
|
||||
|
||||
@@ -211,6 +211,7 @@ void NodeBindings::Initialize() {
|
||||
|
||||
// Init node.
|
||||
// (we assume node::Init would not modify the parameters under embedded mode).
|
||||
// NOTE: If you change this line, please ping @codebytere or @MarshallOfSound
|
||||
node::Init(nullptr, nullptr, nullptr, nullptr);
|
||||
|
||||
#if defined(OS_WIN)
|
||||
|
||||
@@ -215,6 +215,12 @@ const char kWidevineCdmPath[] = "widevine-cdm-path";
|
||||
// Widevine CDM version.
|
||||
const char kWidevineCdmVersion[] = "widevine-cdm-version";
|
||||
|
||||
// Forces the maximum disk space to be used by the disk cache, in bytes.
|
||||
const char kDiskCacheSize[] = "disk-cache-size";
|
||||
|
||||
// Ignore the limit of 6 connections per host.
|
||||
const char kIgnoreConnectionsLimit[] = "ignore-connections-limit";
|
||||
|
||||
} // namespace switches
|
||||
|
||||
} // namespace atom
|
||||
|
||||
@@ -112,6 +112,9 @@ extern const char kWebviewTag[];
|
||||
extern const char kWidevineCdmPath[];
|
||||
extern const char kWidevineCdmVersion[];
|
||||
|
||||
extern const char kDiskCacheSize[];
|
||||
extern const char kIgnoreConnectionsLimit[];
|
||||
|
||||
} // namespace switches
|
||||
|
||||
} // namespace atom
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
#include "atom/renderer/content_settings_observer.h"
|
||||
#include "atom/renderer/preferences_manager.h"
|
||||
#include "base/command_line.h"
|
||||
#include "base/process/process_handle.h"
|
||||
#include "base/process/process.h"
|
||||
#include "base/strings/string_split.h"
|
||||
#include "base/strings/stringprintf.h"
|
||||
#include "chrome/renderer/media/chrome_key_systems.h"
|
||||
@@ -94,7 +94,8 @@ void RendererClientBase::DidCreateScriptContext(
|
||||
content::RenderFrame* render_frame) {
|
||||
// global.setHidden("contextId", `${processId}-${++nextContextId}`)
|
||||
std::string context_id = base::StringPrintf(
|
||||
"%" CrPRIdPid "-%d", base::GetCurrentProcId(), ++next_context_id_);
|
||||
"%" CrPRIdPid "-%d", base::GetProcId(base::Process::Current().Handle()),
|
||||
++next_context_id_);
|
||||
v8::Isolate* isolate = context->GetIsolate();
|
||||
v8::Local<v8::String> key = mate::StringToSymbol(isolate, "contextId");
|
||||
v8::Local<v8::Private> private_key = v8::Private::ForApi(isolate, key);
|
||||
|
||||
@@ -36,6 +36,7 @@ static_library("brightray") {
|
||||
"//components/prefs",
|
||||
"//content/public/browser",
|
||||
"//content/shell:resources",
|
||||
"//net:extras",
|
||||
"//net:net_with_v8",
|
||||
"//skia",
|
||||
"//ui/views",
|
||||
|
||||
@@ -112,6 +112,7 @@
|
||||
'libraries': [
|
||||
# Following libraries are always linked statically.
|
||||
'<(libchromiumcontent_dir)/libbase_static.a',
|
||||
'<(libchromiumcontent_dir)/libextras.a',
|
||||
'<(libchromiumcontent_dir)/libgtkui.a',
|
||||
'<(libchromiumcontent_dir)/libhttp_server.a',
|
||||
'<(libchromiumcontent_dir)/libdevice_service.a',
|
||||
@@ -206,6 +207,7 @@
|
||||
'libraries': [
|
||||
# Following libraries are always linked statically.
|
||||
'<(libchromiumcontent_dir)/libbase_static.a',
|
||||
'<(libchromiumcontent_dir)/libextras.a',
|
||||
'<(libchromiumcontent_dir)/libhttp_server.a',
|
||||
'<(libchromiumcontent_dir)/libdevice_service.a',
|
||||
'<(libchromiumcontent_dir)/libdom_keycode_converter.a',
|
||||
@@ -342,6 +344,7 @@
|
||||
'-ldxgi.lib',
|
||||
# Following libs are always linked statically.
|
||||
'<(libchromiumcontent_dir)/base_static.lib',
|
||||
'<(libchromiumcontent_dir)/extras.lib',
|
||||
'<(libchromiumcontent_dir)/sandbox.lib',
|
||||
'<(libchromiumcontent_dir)/sandbox_helper_win.lib',
|
||||
'<(libchromiumcontent_dir)/http_server.lib',
|
||||
|
||||
@@ -11,7 +11,6 @@
|
||||
#include "brightray/browser/brightray_paths.h"
|
||||
#include "brightray/browser/browser_client.h"
|
||||
#include "brightray/browser/inspectable_web_contents_impl.h"
|
||||
#include "brightray/browser/network_delegate.h"
|
||||
#include "brightray/browser/special_storage_policy.h"
|
||||
#include "brightray/browser/zoom_level_delegate.h"
|
||||
#include "brightray/common/application_info.h"
|
||||
@@ -20,7 +19,6 @@
|
||||
#include "components/prefs/pref_service.h"
|
||||
#include "components/prefs/pref_service_factory.h"
|
||||
#include "content/public/browser/browser_thread.h"
|
||||
#include "content/public/browser/resource_context.h"
|
||||
#include "content/public/browser/storage_partition.h"
|
||||
#include "net/base/escape.h"
|
||||
|
||||
@@ -37,25 +35,10 @@ std::string MakePartitionName(const std::string& input) {
|
||||
|
||||
} // namespace
|
||||
|
||||
class BrowserContext::ResourceContext : public content::ResourceContext {
|
||||
public:
|
||||
ResourceContext() : getter_(nullptr) {}
|
||||
|
||||
void set_url_request_context_getter(URLRequestContextGetter* getter) {
|
||||
getter_ = getter;
|
||||
}
|
||||
|
||||
private:
|
||||
net::HostResolver* GetHostResolver() override {
|
||||
return getter_->host_resolver();
|
||||
}
|
||||
|
||||
net::URLRequestContext* GetRequestContext() override {
|
||||
return getter_->GetURLRequestContext();
|
||||
}
|
||||
|
||||
URLRequestContextGetter* getter_;
|
||||
};
|
||||
// static
|
||||
void BrowserContextDeleter::Destruct(const BrowserContext* browser_context) {
|
||||
browser_context->OnDestruct();
|
||||
}
|
||||
|
||||
// static
|
||||
BrowserContext::BrowserContextMap BrowserContext::browser_context_map_;
|
||||
@@ -72,7 +55,6 @@ scoped_refptr<BrowserContext> BrowserContext::Get(const std::string& partition,
|
||||
|
||||
BrowserContext::BrowserContext(const std::string& partition, bool in_memory)
|
||||
: in_memory_(in_memory),
|
||||
resource_context_(new ResourceContext),
|
||||
storage_policy_(new SpecialStoragePolicy),
|
||||
weak_factory_(this) {
|
||||
if (!PathService::Get(DIR_USER_DATA, &path_)) {
|
||||
@@ -88,6 +70,8 @@ BrowserContext::BrowserContext(const std::string& partition, bool in_memory)
|
||||
|
||||
content::BrowserContext::Initialize(this, path_);
|
||||
|
||||
io_handle_ = new URLRequestContextGetter::Handle(GetWeakPtr());
|
||||
|
||||
browser_context_map_[PartitionKey(partition, in_memory)] = GetWeakPtr();
|
||||
}
|
||||
|
||||
@@ -95,13 +79,14 @@ BrowserContext::~BrowserContext() {
|
||||
DCHECK_CURRENTLY_ON(BrowserThread::UI);
|
||||
NotifyWillBeDestroyed(this);
|
||||
ShutdownStoragePartitions();
|
||||
if (BrowserThread::IsMessageLoopValid(BrowserThread::IO)) {
|
||||
BrowserThread::DeleteSoon(BrowserThread::IO, FROM_HERE,
|
||||
resource_context_.release());
|
||||
BrowserThread::PostTask(
|
||||
BrowserThread::IO, FROM_HERE,
|
||||
base::BindOnce(&URLRequestContextGetter::NotifyContextShutdownOnIO,
|
||||
base::RetainedRef(url_request_getter_)));
|
||||
io_handle_->ShutdownOnUIThread();
|
||||
}
|
||||
|
||||
void BrowserContext::OnDestruct() const {
|
||||
if (BrowserThread::CurrentlyOn(BrowserThread::UI)) {
|
||||
delete this;
|
||||
} else {
|
||||
BrowserThread::DeleteSoon(BrowserThread::UI, FROM_HERE, this);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -135,17 +120,10 @@ URLRequestContextGetter* BrowserContext::GetRequestContext() {
|
||||
net::URLRequestContextGetter* BrowserContext::CreateRequestContext(
|
||||
content::ProtocolHandlerMap* protocol_handlers,
|
||||
content::URLRequestInterceptorScopedVector protocol_interceptors) {
|
||||
DCHECK(!url_request_getter_.get());
|
||||
url_request_getter_ = new URLRequestContextGetter(
|
||||
this, static_cast<NetLog*>(BrowserClient::Get()->GetNetLog()), GetPath(),
|
||||
in_memory_, BrowserThread::GetTaskRunnerForThread(BrowserThread::IO),
|
||||
protocol_handlers, std::move(protocol_interceptors));
|
||||
resource_context_->set_url_request_context_getter(url_request_getter_.get());
|
||||
return url_request_getter_.get();
|
||||
}
|
||||
|
||||
std::unique_ptr<net::NetworkDelegate> BrowserContext::CreateNetworkDelegate() {
|
||||
return std::make_unique<NetworkDelegate>();
|
||||
return io_handle_
|
||||
->CreateMainRequestContextGetter(protocol_handlers,
|
||||
std::move(protocol_interceptors))
|
||||
.get();
|
||||
}
|
||||
|
||||
std::string BrowserContext::GetMediaDeviceIDSalt() {
|
||||
@@ -171,7 +149,7 @@ bool BrowserContext::IsOffTheRecord() const {
|
||||
}
|
||||
|
||||
content::ResourceContext* BrowserContext::GetResourceContext() {
|
||||
return resource_context_.get();
|
||||
return io_handle_->GetResourceContext();
|
||||
}
|
||||
|
||||
content::DownloadManagerDelegate* BrowserContext::GetDownloadManagerDelegate() {
|
||||
@@ -214,17 +192,19 @@ BrowserContext::CreateRequestContextForStoragePartition(
|
||||
bool in_memory,
|
||||
content::ProtocolHandlerMap* protocol_handlers,
|
||||
content::URLRequestInterceptorScopedVector request_interceptors) {
|
||||
NOTREACHED();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
net::URLRequestContextGetter* BrowserContext::CreateMediaRequestContext() {
|
||||
return url_request_getter_.get();
|
||||
return io_handle_->GetMainRequestContextGetter().get();
|
||||
}
|
||||
|
||||
net::URLRequestContextGetter*
|
||||
BrowserContext::CreateMediaRequestContextForStoragePartition(
|
||||
const base::FilePath& partition_path,
|
||||
bool in_memory) {
|
||||
NOTREACHED();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
||||
@@ -23,9 +23,15 @@ class SpecialStoragePolicy;
|
||||
|
||||
namespace brightray {
|
||||
|
||||
class BrowserContext : public base::RefCounted<BrowserContext>,
|
||||
public content::BrowserContext,
|
||||
public brightray::URLRequestContextGetter::Delegate {
|
||||
class BrowserContext;
|
||||
|
||||
struct BrowserContextDeleter {
|
||||
static void Destruct(const BrowserContext* browser_context);
|
||||
};
|
||||
|
||||
class BrowserContext
|
||||
: public base::RefCountedThreadSafe<BrowserContext, BrowserContextDeleter>,
|
||||
public content::BrowserContext {
|
||||
public:
|
||||
// Get the BrowserContext according to its |partition| and |in_memory|,
|
||||
// empty pointer when be returned when there is no matching BrowserContext.
|
||||
@@ -66,14 +72,14 @@ class BrowserContext : public base::RefCounted<BrowserContext>,
|
||||
const base::FilePath& partition_path,
|
||||
bool in_memory) override;
|
||||
std::string GetMediaDeviceIDSalt() override;
|
||||
|
||||
URLRequestContextGetter* url_request_context_getter() const {
|
||||
return url_request_getter_.get();
|
||||
}
|
||||
base::FilePath GetPath() const override;
|
||||
|
||||
void InitPrefs();
|
||||
PrefService* prefs() { return prefs_.get(); }
|
||||
|
||||
virtual std::string GetUserAgent() const = 0;
|
||||
virtual void OnMainRequestContextCreated(URLRequestContextGetter* getter) {}
|
||||
|
||||
protected:
|
||||
BrowserContext(const std::string& partition, bool in_memory);
|
||||
~BrowserContext() override;
|
||||
@@ -81,16 +87,14 @@ class BrowserContext : public base::RefCounted<BrowserContext>,
|
||||
// Subclasses should override this to register custom preferences.
|
||||
virtual void RegisterPrefs(PrefRegistrySimple* pref_registry) {}
|
||||
|
||||
// URLRequestContextGetter::Delegate:
|
||||
std::unique_ptr<net::NetworkDelegate> CreateNetworkDelegate() override;
|
||||
|
||||
base::FilePath GetPath() const override;
|
||||
|
||||
private:
|
||||
friend class base::RefCounted<BrowserContext>;
|
||||
class ResourceContext;
|
||||
friend class base::RefCountedThreadSafe<BrowserContext,
|
||||
BrowserContextDeleter>;
|
||||
friend class base::DeleteHelper<BrowserContext>;
|
||||
friend struct BrowserContextDeleter;
|
||||
|
||||
void RegisterInternalPrefs(PrefRegistrySimple* pref_registry);
|
||||
void OnDestruct() const;
|
||||
|
||||
// partition_id => browser_context
|
||||
struct PartitionKey {
|
||||
@@ -117,11 +121,12 @@ class BrowserContext : public base::RefCounted<BrowserContext>,
|
||||
base::FilePath path_;
|
||||
bool in_memory_;
|
||||
|
||||
std::unique_ptr<ResourceContext> resource_context_;
|
||||
scoped_refptr<URLRequestContextGetter> url_request_getter_;
|
||||
scoped_refptr<storage::SpecialStoragePolicy> storage_policy_;
|
||||
std::unique_ptr<PrefService> prefs_;
|
||||
std::unique_ptr<MediaDeviceIDSalt> media_device_id_salt_;
|
||||
// Self-destructing class responsible for creating URLRequestContextGetter
|
||||
// on the UI thread and deletes itself on the IO thread.
|
||||
URLRequestContextGetter::Handle* io_handle_;
|
||||
|
||||
base::WeakPtrFactory<BrowserContext> weak_factory_;
|
||||
|
||||
|
||||
@@ -484,7 +484,7 @@ void InspectableWebContentsImpl::LoadNetworkResource(
|
||||
net::URLFetcher* fetcher =
|
||||
(net::URLFetcher::Create(gurl, net::URLFetcher::GET, this)).release();
|
||||
pending_requests_[fetcher] = callback;
|
||||
fetcher->SetRequestContext(browser_context->url_request_context_getter());
|
||||
fetcher->SetRequestContext(browser_context->GetRequestContext());
|
||||
fetcher->SetExtraRequestHeaders(headers);
|
||||
fetcher->SaveResponseWithWriter(
|
||||
std::unique_ptr<net::URLFetcherResponseWriter>(
|
||||
@@ -735,6 +735,8 @@ void InspectableWebContentsImpl::WebContentsDestroyed() {
|
||||
for (const auto& pair : pending_requests_)
|
||||
delete pair.first;
|
||||
|
||||
pending_requests_.clear();
|
||||
|
||||
if (view_ && view_->GetDelegate())
|
||||
view_->GetDelegate()->DevToolsClosed();
|
||||
}
|
||||
|
||||
@@ -1,161 +0,0 @@
|
||||
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE-CHROMIUM file.
|
||||
|
||||
#include "brightray/browser/network_delegate.h"
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "base/command_line.h"
|
||||
#include "base/strings/string_split.h"
|
||||
#include "net/base/load_flags.h"
|
||||
#include "net/base/net_errors.h"
|
||||
#include "net/url_request/url_request.h"
|
||||
|
||||
namespace brightray {
|
||||
|
||||
namespace {
|
||||
|
||||
// Ignore the limit of 6 connections per host.
|
||||
const char kIgnoreConnectionsLimit[] = "ignore-connections-limit";
|
||||
|
||||
} // namespace
|
||||
|
||||
NetworkDelegate::NetworkDelegate() {
|
||||
auto* command_line = base::CommandLine::ForCurrentProcess();
|
||||
if (command_line->HasSwitch(kIgnoreConnectionsLimit)) {
|
||||
std::string value =
|
||||
command_line->GetSwitchValueASCII(kIgnoreConnectionsLimit);
|
||||
ignore_connections_limit_domains_ = base::SplitString(
|
||||
value, ",", base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY);
|
||||
}
|
||||
}
|
||||
|
||||
NetworkDelegate::~NetworkDelegate() {}
|
||||
|
||||
int NetworkDelegate::OnBeforeURLRequest(net::URLRequest* request,
|
||||
const net::CompletionCallback& callback,
|
||||
GURL* new_url) {
|
||||
for (const auto& domain : ignore_connections_limit_domains_) {
|
||||
if (request->url().DomainIs(domain)) {
|
||||
// Allow unlimited concurrent connections.
|
||||
request->SetPriority(net::MAXIMUM_PRIORITY);
|
||||
request->SetLoadFlags(request->load_flags() | net::LOAD_IGNORE_LIMITS);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return net::OK;
|
||||
}
|
||||
|
||||
int NetworkDelegate::OnBeforeStartTransaction(
|
||||
net::URLRequest* request,
|
||||
const net::CompletionCallback& callback,
|
||||
net::HttpRequestHeaders* headers) {
|
||||
return net::OK;
|
||||
}
|
||||
|
||||
void NetworkDelegate::OnStartTransaction(
|
||||
net::URLRequest* request,
|
||||
const net::HttpRequestHeaders& headers) {}
|
||||
|
||||
void NetworkDelegate::OnBeforeSendHeaders(
|
||||
net::URLRequest* request,
|
||||
const net::ProxyInfo& proxy_info,
|
||||
const net::ProxyRetryInfoMap& proxy_retry_info,
|
||||
net::HttpRequestHeaders* headers) {}
|
||||
|
||||
int NetworkDelegate::OnHeadersReceived(
|
||||
net::URLRequest* request,
|
||||
const net::CompletionCallback& callback,
|
||||
const net::HttpResponseHeaders* original_response_headers,
|
||||
scoped_refptr<net::HttpResponseHeaders>* override_response_headers,
|
||||
GURL* allowed_unsafe_redirect_url) {
|
||||
return net::OK;
|
||||
}
|
||||
|
||||
void NetworkDelegate::OnBeforeRedirect(net::URLRequest* request,
|
||||
const GURL& new_location) {}
|
||||
|
||||
void NetworkDelegate::OnResponseStarted(net::URLRequest* request,
|
||||
int net_error) {}
|
||||
|
||||
void NetworkDelegate::OnNetworkBytesReceived(net::URLRequest* request,
|
||||
int64_t bytes_read) {}
|
||||
|
||||
void NetworkDelegate::OnNetworkBytesSent(net::URLRequest* request,
|
||||
int64_t bytes_sent) {}
|
||||
|
||||
void NetworkDelegate::OnCompleted(net::URLRequest* request, bool started) {}
|
||||
|
||||
void NetworkDelegate::OnURLRequestDestroyed(net::URLRequest* request) {}
|
||||
|
||||
void NetworkDelegate::OnPACScriptError(int line_number,
|
||||
const base::string16& error) {}
|
||||
|
||||
NetworkDelegate::AuthRequiredResponse NetworkDelegate::OnAuthRequired(
|
||||
net::URLRequest* request,
|
||||
const net::AuthChallengeInfo& auth_info,
|
||||
const AuthCallback& callback,
|
||||
net::AuthCredentials* credentials) {
|
||||
return AUTH_REQUIRED_RESPONSE_NO_ACTION;
|
||||
}
|
||||
|
||||
bool NetworkDelegate::OnCanGetCookies(const net::URLRequest& request,
|
||||
const net::CookieList& cookie_list) {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool NetworkDelegate::OnCanSetCookie(const net::URLRequest& request,
|
||||
const net::CanonicalCookie& cookie_line,
|
||||
net::CookieOptions* options) {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool NetworkDelegate::OnCanAccessFile(
|
||||
const net::URLRequest& request,
|
||||
const base::FilePath& original_path,
|
||||
const base::FilePath& absolute_path) const {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool NetworkDelegate::OnCanEnablePrivacyMode(
|
||||
const GURL& url,
|
||||
const GURL& first_party_for_cookies) const {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool NetworkDelegate::OnAreExperimentalCookieFeaturesEnabled() const {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool NetworkDelegate::OnCancelURLRequestWithPolicyViolatingReferrerHeader(
|
||||
const net::URLRequest& request,
|
||||
const GURL& target_url,
|
||||
const GURL& referrer_url) const {
|
||||
return false;
|
||||
}
|
||||
|
||||
// TODO(deepak1556) : Enable after hooking into the reporting service
|
||||
// https://crbug.com/704259
|
||||
bool NetworkDelegate::OnCanQueueReportingReport(
|
||||
const url::Origin& origin) const {
|
||||
return false;
|
||||
}
|
||||
|
||||
void NetworkDelegate::OnCanSendReportingReports(
|
||||
std::set<url::Origin> origins,
|
||||
base::OnceCallback<void(std::set<url::Origin>)> result_callback) const {}
|
||||
|
||||
bool NetworkDelegate::OnCanSetReportingClient(const url::Origin& origin,
|
||||
const GURL& endpoint) const {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool NetworkDelegate::OnCanUseReportingClient(const url::Origin& origin,
|
||||
const GURL& endpoint) const {
|
||||
return false;
|
||||
}
|
||||
|
||||
} // namespace brightray
|
||||
@@ -1,88 +0,0 @@
|
||||
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE-CHROMIUM file.
|
||||
|
||||
#ifndef BRIGHTRAY_BROWSER_NETWORK_DELEGATE_H_
|
||||
#define BRIGHTRAY_BROWSER_NETWORK_DELEGATE_H_
|
||||
|
||||
#include <set>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "net/base/network_delegate.h"
|
||||
|
||||
namespace brightray {
|
||||
|
||||
class NetworkDelegate : public net::NetworkDelegate {
|
||||
public:
|
||||
NetworkDelegate();
|
||||
~NetworkDelegate() override;
|
||||
|
||||
protected:
|
||||
int OnBeforeURLRequest(net::URLRequest* request,
|
||||
const net::CompletionCallback& callback,
|
||||
GURL* new_url) override;
|
||||
int OnBeforeStartTransaction(net::URLRequest* request,
|
||||
const net::CompletionCallback& callback,
|
||||
net::HttpRequestHeaders* headers) override;
|
||||
void OnBeforeSendHeaders(net::URLRequest* request,
|
||||
const net::ProxyInfo& proxy_info,
|
||||
const net::ProxyRetryInfoMap& proxy_retry_info,
|
||||
net::HttpRequestHeaders* headers) override;
|
||||
void OnStartTransaction(net::URLRequest* request,
|
||||
const net::HttpRequestHeaders& headers) override;
|
||||
int OnHeadersReceived(
|
||||
net::URLRequest* request,
|
||||
const net::CompletionCallback& callback,
|
||||
const net::HttpResponseHeaders* original_response_headers,
|
||||
scoped_refptr<net::HttpResponseHeaders>* override_response_headers,
|
||||
GURL* allowed_unsafe_redirect_url) override;
|
||||
void OnBeforeRedirect(net::URLRequest* request,
|
||||
const GURL& new_location) override;
|
||||
void OnResponseStarted(net::URLRequest* request, int net_error) override;
|
||||
void OnNetworkBytesReceived(net::URLRequest* request,
|
||||
int64_t bytes_read) override;
|
||||
void OnNetworkBytesSent(net::URLRequest* request,
|
||||
int64_t bytes_sent) override;
|
||||
void OnCompleted(net::URLRequest* request, bool started) override;
|
||||
void OnURLRequestDestroyed(net::URLRequest* request) override;
|
||||
void OnPACScriptError(int line_number, const base::string16& error) override;
|
||||
AuthRequiredResponse OnAuthRequired(
|
||||
net::URLRequest* request,
|
||||
const net::AuthChallengeInfo& auth_info,
|
||||
const AuthCallback& callback,
|
||||
net::AuthCredentials* credentials) override;
|
||||
bool OnCanGetCookies(const net::URLRequest& request,
|
||||
const net::CookieList& cookie_list) override;
|
||||
bool OnCanSetCookie(const net::URLRequest& request,
|
||||
const net::CanonicalCookie& cookie_line,
|
||||
net::CookieOptions* options) override;
|
||||
bool OnCanAccessFile(const net::URLRequest& request,
|
||||
const base::FilePath& original_path,
|
||||
const base::FilePath& absolute_path) const override;
|
||||
bool OnCanEnablePrivacyMode(
|
||||
const GURL& url,
|
||||
const GURL& first_party_for_cookies) const override;
|
||||
bool OnAreExperimentalCookieFeaturesEnabled() const override;
|
||||
bool OnCancelURLRequestWithPolicyViolatingReferrerHeader(
|
||||
const net::URLRequest& request,
|
||||
const GURL& target_url,
|
||||
const GURL& referrer_url) const override;
|
||||
bool OnCanQueueReportingReport(const url::Origin& origin) const override;
|
||||
void OnCanSendReportingReports(std::set<url::Origin> origins,
|
||||
base::OnceCallback<void(std::set<url::Origin>)>
|
||||
result_callback) const override;
|
||||
bool OnCanSetReportingClient(const url::Origin& origin,
|
||||
const GURL& endpoint) const override;
|
||||
bool OnCanUseReportingClient(const url::Origin& origin,
|
||||
const GURL& endpoint) const override;
|
||||
|
||||
private:
|
||||
std::vector<std::string> ignore_connections_limit_domains_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(NetworkDelegate);
|
||||
};
|
||||
|
||||
} // namespace brightray
|
||||
|
||||
#endif // BRIGHTRAY_BROWSER_NETWORK_DELEGATE_H_
|
||||
@@ -12,14 +12,15 @@
|
||||
#include "base/strings/string_util.h"
|
||||
#include "base/task_scheduler/post_task.h"
|
||||
#include "brightray/browser/browser_client.h"
|
||||
#include "brightray/browser/browser_context.h"
|
||||
#include "brightray/browser/net/require_ct_delegate.h"
|
||||
#include "brightray/browser/net_log.h"
|
||||
#include "brightray/browser/network_delegate.h"
|
||||
#include "brightray/common/switches.h"
|
||||
#include "components/network_session_configurator/common/network_switches.h"
|
||||
#include "content/public/browser/browser_thread.h"
|
||||
#include "content/public/browser/cookie_store_factory.h"
|
||||
#include "content/public/browser/devtools_network_transaction_factory.h"
|
||||
#include "content/public/browser/resource_context.h"
|
||||
#include "net/base/host_mapping_rules.h"
|
||||
#include "net/cert/cert_verifier.h"
|
||||
#include "net/cert/ct_known_logs.h"
|
||||
@@ -29,6 +30,7 @@
|
||||
#include "net/cookies/cookie_monster.h"
|
||||
#include "net/cookies/cookie_store.h"
|
||||
#include "net/dns/mapped_host_resolver.h"
|
||||
#include "net/extras/sqlite/sqlite_channel_id_store.h"
|
||||
#include "net/http/http_auth_filter.h"
|
||||
#include "net/http/http_auth_handler_factory.h"
|
||||
#include "net/http/http_auth_preferences.h"
|
||||
@@ -58,83 +60,107 @@ using content::BrowserThread;
|
||||
|
||||
namespace brightray {
|
||||
|
||||
std::string URLRequestContextGetter::Delegate::GetUserAgent() {
|
||||
return base::EmptyString();
|
||||
}
|
||||
class ResourceContext : public content::ResourceContext {
|
||||
public:
|
||||
ResourceContext() = default;
|
||||
~ResourceContext() override = default;
|
||||
|
||||
std::unique_ptr<net::NetworkDelegate>
|
||||
URLRequestContextGetter::Delegate::CreateNetworkDelegate() {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
std::unique_ptr<net::URLRequestJobFactory>
|
||||
URLRequestContextGetter::Delegate::CreateURLRequestJobFactory(
|
||||
content::ProtocolHandlerMap* protocol_handlers) {
|
||||
std::unique_ptr<net::URLRequestJobFactoryImpl> job_factory(
|
||||
new net::URLRequestJobFactoryImpl);
|
||||
|
||||
for (auto& it : *protocol_handlers) {
|
||||
job_factory->SetProtocolHandler(it.first,
|
||||
base::WrapUnique(it.second.release()));
|
||||
net::HostResolver* GetHostResolver() override {
|
||||
if (request_context_)
|
||||
return request_context_->host_resolver();
|
||||
return nullptr;
|
||||
}
|
||||
protocol_handlers->clear();
|
||||
|
||||
job_factory->SetProtocolHandler(
|
||||
url::kDataScheme, base::WrapUnique(new net::DataProtocolHandler));
|
||||
job_factory->SetProtocolHandler(
|
||||
url::kFileScheme,
|
||||
base::WrapUnique(
|
||||
new net::FileProtocolHandler(base::CreateTaskRunnerWithTraits(
|
||||
{base::MayBlock(), base::TaskPriority::USER_VISIBLE,
|
||||
base::TaskShutdownBehavior::SKIP_ON_SHUTDOWN}))));
|
||||
net::URLRequestContext* GetRequestContext() override {
|
||||
return request_context_;
|
||||
}
|
||||
|
||||
return std::move(job_factory);
|
||||
private:
|
||||
friend class URLRequestContextGetter;
|
||||
|
||||
net::URLRequestContext* request_context_ = nullptr;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(ResourceContext);
|
||||
};
|
||||
|
||||
URLRequestContextGetter::Handle::Handle(
|
||||
base::WeakPtr<BrowserContext> browser_context)
|
||||
: resource_context_(new ResourceContext),
|
||||
browser_context_(browser_context),
|
||||
initialized_(false) {}
|
||||
|
||||
URLRequestContextGetter::Handle::~Handle() {}
|
||||
|
||||
content::ResourceContext* URLRequestContextGetter::Handle::GetResourceContext()
|
||||
const {
|
||||
DCHECK_CURRENTLY_ON(BrowserThread::UI);
|
||||
LazyInitialize();
|
||||
return resource_context_.get();
|
||||
}
|
||||
|
||||
net::HttpCache::BackendFactory*
|
||||
URLRequestContextGetter::Delegate::CreateHttpCacheBackendFactory(
|
||||
const base::FilePath& base_path) {
|
||||
auto* command_line = base::CommandLine::ForCurrentProcess();
|
||||
int max_size = 0;
|
||||
base::StringToInt(command_line->GetSwitchValueASCII(switches::kDiskCacheSize),
|
||||
&max_size);
|
||||
|
||||
base::FilePath cache_path = base_path.Append(FILE_PATH_LITERAL("Cache"));
|
||||
return new net::HttpCache::DefaultBackend(
|
||||
net::DISK_CACHE, net::CACHE_BACKEND_DEFAULT, cache_path, max_size);
|
||||
scoped_refptr<URLRequestContextGetter>
|
||||
URLRequestContextGetter::Handle::CreateMainRequestContextGetter(
|
||||
content::ProtocolHandlerMap* protocol_handlers,
|
||||
content::URLRequestInterceptorScopedVector protocol_interceptors) {
|
||||
DCHECK_CURRENTLY_ON(BrowserThread::UI);
|
||||
DCHECK(!main_request_context_getter_.get());
|
||||
main_request_context_getter_ = new URLRequestContextGetter(
|
||||
BrowserClient::Get()->GetNetLog(), resource_context_.get(),
|
||||
browser_context_->IsOffTheRecord(), browser_context_->GetUserAgent(),
|
||||
browser_context_->GetPath(), protocol_handlers,
|
||||
std::move(protocol_interceptors));
|
||||
browser_context_->OnMainRequestContextCreated(
|
||||
main_request_context_getter_.get());
|
||||
return main_request_context_getter_;
|
||||
}
|
||||
|
||||
std::unique_ptr<net::CertVerifier>
|
||||
URLRequestContextGetter::Delegate::CreateCertVerifier(
|
||||
RequireCTDelegate* ct_delegate) {
|
||||
return net::CertVerifier::CreateDefault();
|
||||
scoped_refptr<URLRequestContextGetter>
|
||||
URLRequestContextGetter::Handle::GetMainRequestContextGetter() const {
|
||||
return main_request_context_getter_;
|
||||
}
|
||||
|
||||
net::SSLConfigService*
|
||||
URLRequestContextGetter::Delegate::CreateSSLConfigService() {
|
||||
return new net::SSLConfigServiceDefaults;
|
||||
void URLRequestContextGetter::Handle::LazyInitialize() const {
|
||||
DCHECK_CURRENTLY_ON(BrowserThread::UI);
|
||||
if (initialized_)
|
||||
return;
|
||||
|
||||
initialized_ = true;
|
||||
content::BrowserContext::EnsureResourceContextInitialized(
|
||||
browser_context_.get());
|
||||
}
|
||||
|
||||
std::vector<std::string>
|
||||
URLRequestContextGetter::Delegate::GetCookieableSchemes() {
|
||||
return {"http", "https", "ws", "wss"};
|
||||
void URLRequestContextGetter::Handle::ShutdownOnUIThread() {
|
||||
DCHECK_CURRENTLY_ON(BrowserThread::UI);
|
||||
if (main_request_context_getter_.get()) {
|
||||
if (BrowserThread::IsThreadInitialized(BrowserThread::IO)) {
|
||||
BrowserThread::PostTask(
|
||||
BrowserThread::IO, FROM_HERE,
|
||||
base::BindOnce(&URLRequestContextGetter::NotifyContextShuttingDown,
|
||||
base::RetainedRef(main_request_context_getter_),
|
||||
std::move(resource_context_)));
|
||||
}
|
||||
}
|
||||
|
||||
if (!BrowserThread::DeleteSoon(BrowserThread::IO, FROM_HERE, this))
|
||||
delete this;
|
||||
}
|
||||
|
||||
URLRequestContextGetter::URLRequestContextGetter(
|
||||
Delegate* delegate,
|
||||
NetLog* net_log,
|
||||
const base::FilePath& base_path,
|
||||
ResourceContext* resource_context,
|
||||
bool in_memory,
|
||||
scoped_refptr<base::SingleThreadTaskRunner> io_task_runner,
|
||||
const std::string& user_agent,
|
||||
const base::FilePath& base_path,
|
||||
content::ProtocolHandlerMap* protocol_handlers,
|
||||
content::URLRequestInterceptorScopedVector protocol_interceptors)
|
||||
: delegate_(delegate),
|
||||
: job_factory_(nullptr),
|
||||
delegate_(nullptr),
|
||||
net_log_(net_log),
|
||||
resource_context_(resource_context),
|
||||
protocol_interceptors_(std::move(protocol_interceptors)),
|
||||
base_path_(base_path),
|
||||
in_memory_(in_memory),
|
||||
io_task_runner_(io_task_runner),
|
||||
protocol_interceptors_(std::move(protocol_interceptors)),
|
||||
job_factory_(nullptr),
|
||||
user_agent_(user_agent),
|
||||
context_shutting_down_(false) {
|
||||
// Must first be created on the UI thread.
|
||||
DCHECK_CURRENTLY_ON(BrowserThread::UI);
|
||||
@@ -142,48 +168,30 @@ URLRequestContextGetter::URLRequestContextGetter(
|
||||
if (protocol_handlers)
|
||||
std::swap(protocol_handlers_, *protocol_handlers);
|
||||
|
||||
if (delegate_)
|
||||
user_agent_ = delegate_->GetUserAgent();
|
||||
|
||||
// We must create the proxy config service on the UI loop on Linux because it
|
||||
// must synchronously run on the glib message loop. This will be passed to
|
||||
// the URLRequestContextStorage on the IO thread in GetURLRequestContext().
|
||||
proxy_config_service_ =
|
||||
net::ProxyResolutionService::CreateSystemProxyConfigService(
|
||||
io_task_runner_);
|
||||
BrowserThread::GetTaskRunnerForThread(BrowserThread::IO));
|
||||
}
|
||||
|
||||
URLRequestContextGetter::~URLRequestContextGetter() {}
|
||||
|
||||
void URLRequestContextGetter::NotifyContextShutdownOnIO() {
|
||||
void URLRequestContextGetter::NotifyContextShuttingDown(
|
||||
std::unique_ptr<ResourceContext> resource_context) {
|
||||
DCHECK_CURRENTLY_ON(BrowserThread::IO);
|
||||
|
||||
context_shutting_down_ = true;
|
||||
cookie_change_sub_.reset();
|
||||
resource_context.reset();
|
||||
net::URLRequestContextGetter::NotifyContextShuttingDown();
|
||||
url_request_context_.reset();
|
||||
storage_.reset();
|
||||
http_network_session_.reset();
|
||||
http_auth_preferences_.reset();
|
||||
host_mapping_rules_.reset();
|
||||
url_request_context_.reset();
|
||||
storage_.reset();
|
||||
ct_delegate_.reset();
|
||||
net::URLRequestContextGetter::NotifyContextShuttingDown();
|
||||
}
|
||||
|
||||
void URLRequestContextGetter::OnCookieChanged(
|
||||
const net::CanonicalCookie& cookie,
|
||||
net::CookieChangeCause cause) {
|
||||
DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
|
||||
|
||||
if (!delegate_ || context_shutting_down_)
|
||||
return;
|
||||
|
||||
content::BrowserThread::PostTask(
|
||||
content::BrowserThread::UI, FROM_HERE,
|
||||
base::BindOnce(&Delegate::NotifyCookieChange, base::Unretained(delegate_),
|
||||
cookie, !(cause == net::CookieChangeCause::INSERTED),
|
||||
cause));
|
||||
}
|
||||
|
||||
net::HostResolver* URLRequestContextGetter::host_resolver() {
|
||||
return url_request_context_->host_resolver();
|
||||
}
|
||||
|
||||
net::URLRequestContext* URLRequestContextGetter::GetURLRequestContext() {
|
||||
@@ -208,28 +216,46 @@ net::URLRequestContext* URLRequestContextGetter::GetURLRequestContext() {
|
||||
|
||||
storage_->set_network_delegate(delegate_->CreateNetworkDelegate());
|
||||
|
||||
std::unique_ptr<net::CookieStore> cookie_store;
|
||||
scoped_refptr<net::SQLiteChannelIDStore> channel_id_db;
|
||||
// Create a single task runner to use with the CookieStore and
|
||||
// ChannelIDStore.
|
||||
scoped_refptr<base::SequencedTaskRunner> cookie_background_task_runner =
|
||||
base::CreateSequencedTaskRunnerWithTraits(
|
||||
{base::MayBlock(), base::TaskPriority::BACKGROUND,
|
||||
base::TaskShutdownBehavior::BLOCK_SHUTDOWN});
|
||||
auto cookie_path = in_memory_
|
||||
? base::FilePath()
|
||||
: base_path_.Append(FILE_PATH_LITERAL("Cookies"));
|
||||
std::unique_ptr<net::CookieStore> cookie_store =
|
||||
content::CreateCookieStore(content::CookieStoreConfig(
|
||||
cookie_path, false, false, nullptr));
|
||||
storage_->set_cookie_store(std::move(cookie_store));
|
||||
if (!in_memory_) {
|
||||
channel_id_db = new net::SQLiteChannelIDStore(
|
||||
base_path_.Append(FILE_PATH_LITERAL("Origin Bound Certs")),
|
||||
cookie_background_task_runner);
|
||||
}
|
||||
std::unique_ptr<net::ChannelIDService> channel_id_service(
|
||||
new net::ChannelIDService(
|
||||
new net::DefaultChannelIDStore(channel_id_db.get())));
|
||||
content::CookieStoreConfig cookie_config(cookie_path, false, false,
|
||||
nullptr);
|
||||
cookie_config.channel_id_service = channel_id_service.get();
|
||||
cookie_config.background_task_runner = cookie_background_task_runner;
|
||||
cookie_store = content::CreateCookieStore(cookie_config);
|
||||
cookie_store->SetChannelIDServiceID(channel_id_service->GetUniqueID());
|
||||
|
||||
// Set custom schemes that can accept cookies.
|
||||
net::CookieMonster* cookie_monster =
|
||||
static_cast<net::CookieMonster*>(url_request_context_->cookie_store());
|
||||
cookie_monster->SetCookieableSchemes(delegate_->GetCookieableSchemes());
|
||||
static_cast<net::CookieMonster*>(cookie_store.get());
|
||||
std::vector<std::string> cookie_schemes({"http", "https", "ws", "wss"});
|
||||
delegate_->GetCookieableSchemes(&cookie_schemes);
|
||||
cookie_monster->SetCookieableSchemes(cookie_schemes);
|
||||
// Cookie store will outlive notifier by order of declaration
|
||||
// in the header.
|
||||
cookie_change_sub_ =
|
||||
url_request_context_->cookie_store()
|
||||
->GetChangeDispatcher()
|
||||
.AddCallbackForAllChanges(
|
||||
base::Bind(&URLRequestContextGetter::OnCookieChanged, this));
|
||||
|
||||
storage_->set_channel_id_service(std::make_unique<net::ChannelIDService>(
|
||||
new net::DefaultChannelIDStore(nullptr)));
|
||||
cookie_store->GetChangeDispatcher().AddCallbackForAllChanges(
|
||||
base::Bind(&URLRequestContextGetter::OnCookieChanged,
|
||||
base::RetainedRef(this)));
|
||||
storage_->set_cookie_store(std::move(cookie_store));
|
||||
storage_->set_channel_id_service(std::move(channel_id_service));
|
||||
|
||||
storage_->set_http_user_agent_settings(
|
||||
base::WrapUnique(new net::StaticHttpUserAgentSettings(
|
||||
@@ -307,7 +333,7 @@ net::URLRequestContext* URLRequestContextGetter::GetURLRequestContext() {
|
||||
storage_->set_transport_security_state(std::move(transport_security_state));
|
||||
storage_->set_cert_verifier(
|
||||
delegate_->CreateCertVerifier(ct_delegate_.get()));
|
||||
storage_->set_ssl_config_service(delegate_->CreateSSLConfigService());
|
||||
storage_->set_ssl_config_service(new net::SSLConfigServiceDefaults());
|
||||
storage_->set_http_auth_handler_factory(std::move(auth_handler_factory));
|
||||
std::unique_ptr<net::HttpServerProperties> server_properties(
|
||||
new net::HttpServerPropertiesImpl);
|
||||
@@ -360,7 +386,8 @@ net::URLRequestContext* URLRequestContextGetter::GetURLRequestContext() {
|
||||
std::move(backend), false));
|
||||
|
||||
std::unique_ptr<net::URLRequestJobFactory> job_factory =
|
||||
delegate_->CreateURLRequestJobFactory(&protocol_handlers_);
|
||||
delegate_->CreateURLRequestJobFactory(url_request_context_.get(),
|
||||
&protocol_handlers_);
|
||||
job_factory_ = job_factory.get();
|
||||
|
||||
// Set up interceptors in the reverse order.
|
||||
@@ -378,6 +405,9 @@ net::URLRequestContext* URLRequestContextGetter::GetURLRequestContext() {
|
||||
storage_->set_job_factory(std::move(top_job_factory));
|
||||
}
|
||||
|
||||
if (resource_context_)
|
||||
resource_context_->request_context_ = url_request_context_.get();
|
||||
|
||||
return url_request_context_.get();
|
||||
}
|
||||
|
||||
@@ -386,4 +416,11 @@ URLRequestContextGetter::GetNetworkTaskRunner() const {
|
||||
return BrowserThread::GetTaskRunnerForThread(BrowserThread::IO);
|
||||
}
|
||||
|
||||
void URLRequestContextGetter::OnCookieChanged(
|
||||
const net::CanonicalCookie& cookie,
|
||||
net::CookieChangeCause cause) const {
|
||||
if (delegate_)
|
||||
delegate_->OnCookieChanged(cookie, cause);
|
||||
}
|
||||
|
||||
} // namespace brightray
|
||||
|
||||
@@ -22,10 +22,6 @@
|
||||
#include "base/debug/leak_tracker.h"
|
||||
#endif
|
||||
|
||||
namespace base {
|
||||
class MessageLoop;
|
||||
}
|
||||
|
||||
namespace net {
|
||||
class HostMappingRules;
|
||||
class HostResolver;
|
||||
@@ -38,6 +34,8 @@ class URLRequestJobFactory;
|
||||
|
||||
namespace brightray {
|
||||
|
||||
class BrowserContext;
|
||||
class ResourceContext;
|
||||
class RequireCTDelegate;
|
||||
class NetLog;
|
||||
|
||||
@@ -48,55 +46,76 @@ class URLRequestContextGetter : public net::URLRequestContextGetter {
|
||||
Delegate() {}
|
||||
virtual ~Delegate() {}
|
||||
|
||||
virtual std::unique_ptr<net::NetworkDelegate> CreateNetworkDelegate();
|
||||
virtual std::string GetUserAgent();
|
||||
virtual std::unique_ptr<net::NetworkDelegate> CreateNetworkDelegate() = 0;
|
||||
virtual std::unique_ptr<net::URLRequestJobFactory>
|
||||
CreateURLRequestJobFactory(content::ProtocolHandlerMap* protocol_handlers);
|
||||
CreateURLRequestJobFactory(
|
||||
net::URLRequestContext* url_request_context,
|
||||
content::ProtocolHandlerMap* protocol_handlers) = 0;
|
||||
virtual net::HttpCache::BackendFactory* CreateHttpCacheBackendFactory(
|
||||
const base::FilePath& base_path);
|
||||
const base::FilePath& base_path) = 0;
|
||||
virtual std::unique_ptr<net::CertVerifier> CreateCertVerifier(
|
||||
RequireCTDelegate* ct_delegate);
|
||||
virtual net::SSLConfigService* CreateSSLConfigService();
|
||||
virtual std::vector<std::string> GetCookieableSchemes();
|
||||
virtual void NotifyCookieChange(const net::CanonicalCookie& cookie,
|
||||
bool removed,
|
||||
net::CookieChangeCause cause) {}
|
||||
RequireCTDelegate* ct_delegate) = 0;
|
||||
virtual void GetCookieableSchemes(
|
||||
std::vector<std::string>* cookie_schemes) {}
|
||||
virtual void OnCookieChanged(const net::CanonicalCookie& cookie,
|
||||
net::CookieChangeCause cause) {}
|
||||
};
|
||||
|
||||
URLRequestContextGetter(
|
||||
Delegate* delegate,
|
||||
NetLog* net_log,
|
||||
const base::FilePath& base_path,
|
||||
ResourceContext* resource_context,
|
||||
bool in_memory,
|
||||
scoped_refptr<base::SingleThreadTaskRunner> io_task_runner,
|
||||
const std::string& user_agent,
|
||||
const base::FilePath& base_path,
|
||||
content::ProtocolHandlerMap* protocol_handlers,
|
||||
content::URLRequestInterceptorScopedVector protocol_interceptors);
|
||||
|
||||
// net::CookieChangeDispatcher::CookieChangedCallback implementation.
|
||||
void OnCookieChanged(const net::CanonicalCookie& cookie,
|
||||
net::CookieChangeCause cause);
|
||||
|
||||
// net::URLRequestContextGetter:
|
||||
net::URLRequestContext* GetURLRequestContext() override;
|
||||
scoped_refptr<base::SingleThreadTaskRunner> GetNetworkTaskRunner()
|
||||
const override;
|
||||
|
||||
net::HostResolver* host_resolver();
|
||||
net::URLRequestJobFactory* job_factory() const { return job_factory_; }
|
||||
void set_delegate(Delegate* delegate) { delegate_ = delegate; }
|
||||
|
||||
void NotifyContextShutdownOnIO();
|
||||
// Discard reference to URLRequestContext and inform observers to
|
||||
// shutdown. Must be called only on IO thread.
|
||||
void NotifyContextShuttingDown(std::unique_ptr<ResourceContext>);
|
||||
|
||||
private:
|
||||
friend class BrowserContext;
|
||||
|
||||
// Responsible for destroying URLRequestContextGetter
|
||||
// on the IO thread.
|
||||
class Handle {
|
||||
public:
|
||||
explicit Handle(base::WeakPtr<BrowserContext> browser_context);
|
||||
~Handle();
|
||||
|
||||
scoped_refptr<URLRequestContextGetter> CreateMainRequestContextGetter(
|
||||
content::ProtocolHandlerMap* protocol_handlers,
|
||||
content::URLRequestInterceptorScopedVector protocol_interceptors);
|
||||
content::ResourceContext* GetResourceContext() const;
|
||||
scoped_refptr<URLRequestContextGetter> GetMainRequestContextGetter() const;
|
||||
|
||||
void ShutdownOnUIThread();
|
||||
|
||||
private:
|
||||
void LazyInitialize() const;
|
||||
|
||||
scoped_refptr<URLRequestContextGetter> main_request_context_getter_;
|
||||
std::unique_ptr<ResourceContext> resource_context_;
|
||||
base::WeakPtr<BrowserContext> browser_context_;
|
||||
mutable bool initialized_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(Handle);
|
||||
};
|
||||
|
||||
~URLRequestContextGetter() override;
|
||||
|
||||
Delegate* delegate_;
|
||||
|
||||
NetLog* net_log_;
|
||||
base::FilePath base_path_;
|
||||
bool in_memory_;
|
||||
scoped_refptr<base::SingleThreadTaskRunner> io_task_runner_;
|
||||
|
||||
std::string user_agent_;
|
||||
// net::CookieChangeDispatcher::CookieChangedCallback implementation.
|
||||
void OnCookieChanged(const net::CanonicalCookie& cookie,
|
||||
net::CookieChangeCause cause) const;
|
||||
|
||||
#if DCHECK_IS_ON()
|
||||
base::debug::LeakTracker<URLRequestContextGetter> leak_tracker_;
|
||||
@@ -110,11 +129,16 @@ class URLRequestContextGetter : public net::URLRequestContextGetter {
|
||||
std::unique_ptr<net::HttpAuthPreferences> http_auth_preferences_;
|
||||
std::unique_ptr<net::HttpNetworkSession> http_network_session_;
|
||||
std::unique_ptr<net::CookieChangeSubscription> cookie_change_sub_;
|
||||
|
||||
net::URLRequestJobFactory* job_factory_;
|
||||
Delegate* delegate_;
|
||||
NetLog* net_log_;
|
||||
ResourceContext* resource_context_;
|
||||
content::ProtocolHandlerMap protocol_handlers_;
|
||||
content::URLRequestInterceptorScopedVector protocol_interceptors_;
|
||||
|
||||
net::URLRequestJobFactory* job_factory_; // weak ref
|
||||
|
||||
base::FilePath base_path_;
|
||||
bool in_memory_;
|
||||
std::string user_agent_;
|
||||
bool context_shutting_down_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(URLRequestContextGetter);
|
||||
|
||||
@@ -50,9 +50,6 @@ const char kAuthServerWhitelist[] = "auth-server-whitelist";
|
||||
const char kAuthNegotiateDelegateWhitelist[] =
|
||||
"auth-negotiate-delegate-whitelist";
|
||||
|
||||
// Forces the maximum disk space to be used by the disk cache, in bytes.
|
||||
const char kDiskCacheSize[] = "disk-cache-size";
|
||||
|
||||
} // namespace switches
|
||||
|
||||
} // namespace brightray
|
||||
|
||||
@@ -17,7 +17,6 @@ extern const char kProxyPacUrl[];
|
||||
extern const char kDisableHttp2[];
|
||||
extern const char kAuthServerWhitelist[];
|
||||
extern const char kAuthNegotiateDelegateWhitelist[];
|
||||
extern const char kDiskCacheSize[];
|
||||
|
||||
} // namespace switches
|
||||
|
||||
|
||||
@@ -51,8 +51,6 @@
|
||||
'browser/net/require_ct_delegate.h',
|
||||
'browser/net_log.cc',
|
||||
'browser/net_log.h',
|
||||
'browser/network_delegate.cc',
|
||||
'browser/network_delegate.h',
|
||||
'browser/notification_delegate.h',
|
||||
'browser/notification_presenter.cc',
|
||||
'browser/notification_presenter.h',
|
||||
|
||||
@@ -182,6 +182,10 @@ tray.setHighlightMode('off')
|
||||
webContents.openDevTools({detach: true})
|
||||
// Replace with
|
||||
webContents.openDevTools({mode: 'detach'})
|
||||
|
||||
// Removed
|
||||
webContents.setSize(options)
|
||||
// There is no replacement for this API
|
||||
```
|
||||
|
||||
## `webFrame`
|
||||
@@ -198,6 +202,22 @@ webFrame.registerURLSchemeAsPrivileged('app', {secure: true})
|
||||
protocol.registerStandardSchemes(['app'], {secure: true})
|
||||
```
|
||||
|
||||
## `<webview>`
|
||||
|
||||
```js
|
||||
// Removed
|
||||
webview.setAttribute('disableguestresize', '')
|
||||
// There is no replacement for this API
|
||||
|
||||
// Removed
|
||||
webview.setAttribute('guestinstance', instanceId)
|
||||
// There is no replacement for this API
|
||||
|
||||
// Keyboard listeners no longer work on webview tag
|
||||
webview.onkeydown = () => { /* handler */ }
|
||||
webview.onkeyup = () => { /* handler */ }
|
||||
```
|
||||
|
||||
## Node Headers URL
|
||||
|
||||
This is the URL specified as `disturl` in a `.npmrc` file or as the `--dist-url`
|
||||
|
||||
@@ -1264,6 +1264,17 @@ Sets the opacity of the window. On Linux does nothing.
|
||||
|
||||
Returns `Number` - between 0.0 (fully transparent) and 1.0 (fully opaque)
|
||||
|
||||
#### `win.setShape(rects)` _Windows_ _Linux_ _Experimental_
|
||||
|
||||
* `rects` [Rectangle[]](structures/rectangle.md) - Sets a shape on the window.
|
||||
Passing an empty list reverts the window to being rectangular.
|
||||
|
||||
Setting a window shape determines the area within the window where the system
|
||||
permits drawing and user interaction. Outside of the given region, no pixels
|
||||
will be drawn and no mouse events will be registered. Mouse events outside of
|
||||
the region will not be received by that window, but will fall through to
|
||||
whatever is behind the window.
|
||||
|
||||
#### `win.setThumbarButtons(buttons)` _Windows_
|
||||
|
||||
* `buttons` [ThumbarButton[]](structures/thumbar-button.md)
|
||||
|
||||
@@ -215,3 +215,17 @@ response object,it will emit the `aborted` event.
|
||||
#### `request.followRedirect()`
|
||||
|
||||
Continues any deferred redirection request when the redirection mode is `manual`.
|
||||
|
||||
#### `request.getUploadProgress()`
|
||||
|
||||
Returns `Object`:
|
||||
|
||||
* `active` Boolean - Whether the request is currently active. If this is false
|
||||
no other properties will be set
|
||||
* `started` Boolean - Whether the upload has started. If this is false both
|
||||
`current` and `total` will be set to 0.
|
||||
* `current` Integer - The number of bytes that have been uploaded so far
|
||||
* `total` Integer - The number of bytes that will be uploaded this request
|
||||
|
||||
You can use this method in conjunction with `POST` requests to get the progress
|
||||
of a file upload or other data transfer.
|
||||
|
||||
@@ -275,7 +275,7 @@ The `position` is only available on Windows, and it is (0, 0) by default.
|
||||
|
||||
#### `tray.setContextMenu(menu)`
|
||||
|
||||
* `menu` Menu
|
||||
* `menu` Menu | null
|
||||
|
||||
Sets the context menu for this icon.
|
||||
|
||||
|
||||
@@ -1381,23 +1381,6 @@ win.webContents.on('did-finish-load', () => {
|
||||
|
||||
Shows pop-up dictionary that searches the selected word on the page.
|
||||
|
||||
#### `contents.setSize(options)`
|
||||
|
||||
Set the size of the page. This is only supported for `<webview>` guest contents.
|
||||
|
||||
* `options` Object
|
||||
* `enableAutoSize` Boolean (optional) - true to make the webview container automatically
|
||||
resize within the bounds specified by the attributes normal, min and max.
|
||||
* `normal` [Size](structures/size.md) (optional) - Normal size of the page. This can be used in
|
||||
combination with the [`disableguestresize`](webview-tag.md#disableguestresize)
|
||||
attribute to manually resize the webview guest contents.
|
||||
* `min` [Size](structures/size.md) (optional) - Minimum size of the page. This can be used in
|
||||
combination with the [`disableguestresize`](webview-tag.md#disableguestresize)
|
||||
attribute to manually resize the webview guest contents.
|
||||
* `max` [Size](structures/size.md) (optional) - Maximium size of the page. This can be used in
|
||||
combination with the [`disableguestresize`](webview-tag.md#disableguestresize)
|
||||
attribute to manually resize the webview guest contents.
|
||||
|
||||
#### `contents.isOffscreen()`
|
||||
|
||||
Returns `Boolean` - Indicates whether *offscreen rendering* is enabled.
|
||||
|
||||
@@ -62,33 +62,28 @@ and displays a "loading..." message during the load time:
|
||||
</script>
|
||||
```
|
||||
|
||||
## Internal implementation
|
||||
|
||||
Under the hood `webview` is implemented with [Out-of-Process iframes (OOPIFs)](https://www.chromium.org/developers/design-documents/oop-iframes).
|
||||
The `webview` tag is essentially a custom element using shadow DOM to wrap an
|
||||
`iframe` element inside it.
|
||||
|
||||
So the behavior of `webview` is very similar to a cross-domain `iframe`, as
|
||||
examples:
|
||||
|
||||
* When clicking into a `webview`, the page focus will move from the embedder
|
||||
frame to `webview`.
|
||||
* You can not add keyboard event listeners to `webview`.
|
||||
* All reactions between the embedder frame and `webview` are asynchronous.
|
||||
|
||||
## CSS Styling Notes
|
||||
|
||||
Please note that the `webview` tag's style uses `display:flex;` internally to
|
||||
ensure the child `object` element fills the full height and width of its `webview`
|
||||
container when used with traditional and flexbox layouts (since v0.36.11). Please
|
||||
do not overwrite the default `display:flex;` CSS property, unless specifying
|
||||
ensure the child `iframe` element fills the full height and width of its `webview`
|
||||
container when used with traditional and flexbox layouts. Please do not
|
||||
overwrite the default `display:flex;` CSS property, unless specifying
|
||||
`display:inline-flex;` for inline layout.
|
||||
|
||||
`webview` has issues being hidden using the `hidden` attribute or using
|
||||
`display: none;`. It can cause unusual rendering behaviour within its child
|
||||
`browserplugin` object and the web page is reloaded when the `webview` is
|
||||
un-hidden. The recommended approach is to hide the `webview` using
|
||||
`visibility: hidden`.
|
||||
|
||||
```html
|
||||
<style>
|
||||
webview {
|
||||
display:inline-flex;
|
||||
width:640px;
|
||||
height:480px;
|
||||
}
|
||||
webview.hide {
|
||||
visibility: hidden;
|
||||
}
|
||||
</style>
|
||||
```
|
||||
|
||||
## Tag Attributes
|
||||
|
||||
The `webview` tag has the following attributes:
|
||||
@@ -244,59 +239,6 @@ A list of strings which specifies the blink features to be disabled separated by
|
||||
The full list of supported feature strings can be found in the
|
||||
[RuntimeEnabledFeatures.json5][runtime-enabled-features] file.
|
||||
|
||||
### `guestinstance`
|
||||
|
||||
```html
|
||||
<webview src="https://www.github.com/" guestinstance="3"></webview>
|
||||
```
|
||||
|
||||
A value that links the webview to a specific webContents. When a webview
|
||||
first loads a new webContents is created and this attribute is set to its
|
||||
instance identifier. Setting this attribute on a new or existing webview
|
||||
connects it to the existing webContents that currently renders in a different
|
||||
webview.
|
||||
|
||||
The existing webview will see the `destroy` event and will then create a new
|
||||
webContents when a new url is loaded.
|
||||
|
||||
### `disableguestresize`
|
||||
|
||||
```html
|
||||
<webview src="https://www.github.com/" disableguestresize></webview>
|
||||
```
|
||||
|
||||
When this attribute is present the `webview` contents will be prevented from
|
||||
resizing when the `webview` element itself is resized.
|
||||
|
||||
This can be used in combination with
|
||||
[`webContents.setSize`](web-contents.md#contentssetsizeoptions) to manually
|
||||
resize the webview contents in reaction to a window size change. This can
|
||||
make resizing faster compared to relying on the webview element bounds to
|
||||
automatically resize the contents.
|
||||
|
||||
```javascript
|
||||
const {webContents} = require('electron')
|
||||
|
||||
// We assume that `win` points to a `BrowserWindow` instance containing a
|
||||
// `<webview>` with `disableguestresize`.
|
||||
|
||||
win.on('resize', () => {
|
||||
const [width, height] = win.getContentSize()
|
||||
for (let wc of webContents.getAllWebContents()) {
|
||||
// Check if `wc` belongs to a webview in the `win` window.
|
||||
if (wc.hostWebContents &&
|
||||
wc.hostWebContents.id === win.webContents.id) {
|
||||
wc.setSize({
|
||||
normal: {
|
||||
width: width,
|
||||
height: height
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
||||
```
|
||||
|
||||
## Methods
|
||||
|
||||
The `webview` tag has the following methods:
|
||||
|
||||
@@ -77,15 +77,20 @@ Whatever you choose, you will periodically have to bump the version in your `pac
|
||||
|
||||
The process is as follows:
|
||||
|
||||
1. All new major and minor releases lines begin with a `-beta.N` tag for `N >= 1`. At that point, the feature set is **locked**. That release line admits no further features, and focuses only on security and stability.
|
||||
e.g. `2.0.0-beta.1`.
|
||||
2. Bug fixes, regression fixes, and security patches can be admitted. Upon doing so, a new beta is released incrementing `N`.
|
||||
e.g. `2.0.0-beta.2`
|
||||
3. If a particular beta release is _generally regarded_ as stable, it will be re-released as a stable build, changing only the version information.
|
||||
e.g. `2.0.0`.
|
||||
4. If future bug fixes or security patches need to be made once a release is stable, they are applied and the _patch_ version is incremented accordingly
|
||||
1. All new major and minor releases lines begin with a beta series indicated by semver prerelease tags of `beta.N`, e.g. `2.0.0-beta.1`. After the first beta, subsequent beta releases must meet all of the following conditions:
|
||||
1. The change is backwards API-compatible (deprecations are allowed)
|
||||
2. The risk to meeting our stability timeline must be low.
|
||||
2. If allowed changes need to be made once a release is beta, they are applied and the prerelease tag is incremented, e.g. `2.0.0-beta.2`.
|
||||
3. If a particular beta release is _generally regarded_ as stable, it will be re-released as a stable build, changing only the version information. e.g. `2.0.0`. After the first stable, all changes must be backwards-compatible bug or security fixes.
|
||||
4. If future bug fixes or security patches need to be made once a release is stable, they are applied and the _patch_ version is incremented
|
||||
e.g. `2.0.1`.
|
||||
|
||||
Specifically, the above means:
|
||||
|
||||
1. Admitting non-breaking-API changes early in the beta cycle is okay, even if those changes have the potential to cause moderate side-affects
|
||||
2. Admitting feature-flagged changes, that do not otherwise alter existing code paths, at most points in the beta cycle is okay. Users can explicitly enable those flags in their apps.
|
||||
3. Admitting features of any sort very late in the beta cycle is 👎 without a very good reason.
|
||||
|
||||
For each major and minor bump, you should expect to see something like the following:
|
||||
|
||||
```text
|
||||
@@ -125,12 +130,7 @@ Feature flags are a common practice in Chromium, and are well-established in the
|
||||
|
||||
* it is enabled/disabled either at runtime, or build-time; we do not support the concept of a request-scoped feature flag
|
||||
* it completely segments new and old code paths; refactoring old code to support a new feature _violates_ the feature-flag contract
|
||||
* feature flags are eventually removed after the soft-branch is merged
|
||||
|
||||
We reconcile flagged code with our versioning strategy as follows:
|
||||
|
||||
1. we do not consider iterating on feature-flagged code in a stability branch; even judicious use of feature flags is not without risk
|
||||
2. you may break API contracts in feature-flagged code without bumping the major version. Flagged code does not adhere to semver
|
||||
* feature flags are eventually removed after the feature is released
|
||||
|
||||
# Semantic Commits
|
||||
|
||||
|
||||
12
electron.gyp
12
electron.gyp
@@ -4,7 +4,7 @@
|
||||
'product_name%': 'Electron',
|
||||
'company_name%': 'GitHub, Inc',
|
||||
'company_abbr%': 'github',
|
||||
'version%': '3.0.0-beta.6',
|
||||
'version%': '3.0.0-nightly.20180904',
|
||||
'js2c_input_dir': '<(SHARED_INTERMEDIATE_DIR)/js2c',
|
||||
},
|
||||
'includes': [
|
||||
@@ -340,6 +340,16 @@
|
||||
'link_settings': {
|
||||
'libraries': [ '<@(libchromiumcontent_v8_libraries)' ],
|
||||
},
|
||||
'sources': [
|
||||
'<@(lib_sources_location_provider)',
|
||||
],
|
||||
'defines': [
|
||||
# Enable fake location provider to mock geolocation
|
||||
# responses in component build. Should not be enabled
|
||||
# for release build. If you need to test with chromium's
|
||||
# location provider, remove this definition.
|
||||
'OVERRIDE_LOCATION_PROVIDER',
|
||||
],
|
||||
}],
|
||||
['OS=="win"', {
|
||||
'sources': [
|
||||
|
||||
@@ -306,6 +306,8 @@
|
||||
'atom/browser/relauncher.h',
|
||||
'atom/browser/render_process_preferences.cc',
|
||||
'atom/browser/render_process_preferences.h',
|
||||
'atom/browser/request_context_delegate.cc',
|
||||
'atom/browser/request_context_delegate.h',
|
||||
'atom/browser/session_preferences.cc',
|
||||
'atom/browser/session_preferences.h',
|
||||
'atom/browser/ui/accelerator_util.cc',
|
||||
@@ -695,6 +697,10 @@
|
||||
'chromium_src/chrome/utility/printing_handler_win.cc',
|
||||
'chromium_src/chrome/utility/printing_handler_win.h',
|
||||
],
|
||||
'lib_sources_location_provider': [
|
||||
'atom/browser/fake_location_provider.cc',
|
||||
'atom/browser/fake_location_provider.h',
|
||||
],
|
||||
'framework_sources': [
|
||||
'atom/app/atom_library_main.h',
|
||||
'atom/app/atom_library_main.mm',
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
const features = process.atomBinding('features')
|
||||
|
||||
// Browser side modules, please sort alphabetically.
|
||||
module.exports = [
|
||||
{name: 'app', file: 'app'},
|
||||
{name: 'autoUpdater', file: 'auto-updater'},
|
||||
{name: 'BoxLayout', file: 'box-layout'},
|
||||
{name: 'Button', file: 'button'},
|
||||
{name: 'BrowserView', file: 'browser-view'},
|
||||
{name: 'BrowserWindow', file: 'browser-window'},
|
||||
{name: 'contentTracing', file: 'content-tracing'},
|
||||
@@ -11,8 +11,6 @@ module.exports = [
|
||||
{name: 'globalShortcut', file: 'global-shortcut'},
|
||||
{name: 'ipcMain', file: 'ipc-main'},
|
||||
{name: 'inAppPurchase', file: 'in-app-purchase'},
|
||||
{name: 'LabelButton', file: 'label-button'},
|
||||
{name: 'LayoutManager', file: 'layout-manager'},
|
||||
{name: 'Menu', file: 'menu'},
|
||||
{name: 'MenuItem', file: 'menu-item'},
|
||||
{name: 'net', file: 'net'},
|
||||
@@ -24,7 +22,6 @@ module.exports = [
|
||||
{name: 'screen', file: 'screen'},
|
||||
{name: 'session', file: 'session'},
|
||||
{name: 'systemPreferences', file: 'system-preferences'},
|
||||
{name: 'TextField', file: 'text-field'},
|
||||
{name: 'TopLevelWindow', file: 'top-level-window'},
|
||||
{name: 'TouchBar', file: 'touch-bar'},
|
||||
{name: 'Tray', file: 'tray'},
|
||||
@@ -34,3 +31,13 @@ module.exports = [
|
||||
// The internal modules, invisible unless you know their names.
|
||||
{name: 'NavigationController', file: 'navigation-controller', private: true}
|
||||
]
|
||||
|
||||
if (features.isViewApiEnabled()) {
|
||||
module.exports.push(
|
||||
{name: 'BoxLayout', file: 'box-layout'},
|
||||
{name: 'Button', file: 'button'},
|
||||
{name: 'LabelButton', file: 'label-button'},
|
||||
{name: 'LayoutManager', file: 'layout-manager'},
|
||||
{name: 'TextField', file: 'text-field'}
|
||||
)
|
||||
}
|
||||
|
||||
@@ -352,6 +352,10 @@ class ClientRequest extends EventEmitter {
|
||||
abort () {
|
||||
this.urlRequest.cancel()
|
||||
}
|
||||
|
||||
getUploadProgress () {
|
||||
return this.urlRequest.getUploadProgress()
|
||||
}
|
||||
}
|
||||
|
||||
function writeAfterEndNT (self, error, callback) {
|
||||
|
||||
@@ -264,6 +264,12 @@ WebContents.prototype.getZoomFactor = function (callback) {
|
||||
})
|
||||
}
|
||||
|
||||
// TODO(zcbenz): Remove the stub in 4.0.
|
||||
WebContents.prototype.setSize = function () {
|
||||
console.error('The WebContents.setSize method has been removed, see',
|
||||
'https://github.com/electron/electron/issues/14120 for more.')
|
||||
}
|
||||
|
||||
// Add JavaScript wrappers for WebContents class.
|
||||
WebContents.prototype._init = function () {
|
||||
// The navigation controller.
|
||||
|
||||
@@ -26,6 +26,7 @@ const supportedWebViewEvents = [
|
||||
'did-navigate',
|
||||
'did-frame-navigate',
|
||||
'did-navigate-in-page',
|
||||
'focus-change',
|
||||
'close',
|
||||
'crashed',
|
||||
'gpu-crashed',
|
||||
@@ -322,6 +323,10 @@ ipcMain.on('ELECTRON_GUEST_VIEW_MANAGER_ATTACH_GUEST', function (event, embedder
|
||||
attachGuest(event, embedderFrameId, elementInstanceId, guestInstanceId, params)
|
||||
})
|
||||
|
||||
ipcMain.on('ELECTRON_GUEST_VIEW_MANAGER_FOCUS_CHANGE', function (event, focus, guestInstanceId) {
|
||||
event.sender.emit('focus-change', {}, focus, guestInstanceId)
|
||||
})
|
||||
|
||||
// Returns WebContents from its guest id.
|
||||
const getGuest = function (guestInstanceId) {
|
||||
const guestInstance = guestInstances[guestInstanceId]
|
||||
|
||||
@@ -27,11 +27,11 @@ const mergeOptions = function (child, parent, visited) {
|
||||
for (const key in parent) {
|
||||
if (key === 'isBrowserView') continue
|
||||
if (!hasProp.call(parent, key)) continue
|
||||
if (key in child) continue
|
||||
if (key in child && key !== 'webPreferences') continue
|
||||
|
||||
const value = parent[key]
|
||||
if (typeof value === 'object') {
|
||||
child[key] = mergeOptions({}, value, visited)
|
||||
child[key] = mergeOptions(child[key] || {}, value, visited)
|
||||
} else {
|
||||
child[key] = value
|
||||
}
|
||||
|
||||
@@ -98,9 +98,10 @@ class ObjectsRegistry {
|
||||
|
||||
// Private: Clear the storage when renderer process is destoryed.
|
||||
registerDeleteListener (webContents, contextId) {
|
||||
const processId = webContents.getProcessId()
|
||||
const listener = (event, deletedProcessId) => {
|
||||
if (deletedProcessId === processId) {
|
||||
// contextId => ${OSProcessId}-${contextCount}
|
||||
const OSProcessId = contextId.split('-')[0]
|
||||
const listener = (event, deletedProcessId, deletedOSProcessId) => {
|
||||
if (deletedOSProcessId && deletedOSProcessId.toString() === OSProcessId) {
|
||||
webContents.removeListener('render-view-deleted', listener)
|
||||
this.clear(webContents, contextId)
|
||||
}
|
||||
|
||||
@@ -25,6 +25,7 @@ var v8Util = process.atomBinding('v8_util')
|
||||
v8Util.setHiddenValue(global, 'ipc', new events.EventEmitter())
|
||||
|
||||
// Use electron module after everything is ready.
|
||||
const {ipcRenderer} = require('electron')
|
||||
|
||||
const {
|
||||
warnAboutNodeWithRemoteContent,
|
||||
@@ -184,3 +185,15 @@ window.addEventListener('load', function loadHandler () {
|
||||
|
||||
window.removeEventListener('load', loadHandler)
|
||||
})
|
||||
|
||||
// Report focus/blur events of webview to browser.
|
||||
// Note that while Chromium content APIs have observer for focus/blur, they
|
||||
// unfortunately do not work for webview.
|
||||
if (process.guestInstanceId) {
|
||||
window.addEventListener('focus', () => {
|
||||
ipcRenderer.send('ELECTRON_GUEST_VIEW_MANAGER_FOCUS_CHANGE', true, process.guestInstanceId)
|
||||
})
|
||||
window.addEventListener('blur', () => {
|
||||
ipcRenderer.send('ELECTRON_GUEST_VIEW_MANAGER_FOCUS_CHANGE', false, process.guestInstanceId)
|
||||
})
|
||||
}
|
||||
|
||||
@@ -24,6 +24,7 @@ const WEB_VIEW_EVENTS = {
|
||||
'did-navigate': ['url', 'httpResponseCode', 'httpStatusText'],
|
||||
'did-frame-navigate': ['url', 'httpResponseCode', 'httpStatusText', 'isMainFrame', 'frameProcessId', 'frameRoutingId'],
|
||||
'did-navigate-in-page': ['url', 'isMainFrame', 'frameProcessId', 'frameRoutingId'],
|
||||
'focus-change': ['focus', 'guestInstanceId'],
|
||||
'close': [],
|
||||
'crashed': [],
|
||||
'gpu-crashed': [],
|
||||
@@ -55,6 +56,8 @@ const dispatchEvent = function (webView, eventName, eventKey, ...args) {
|
||||
webView.dispatchEvent(domEvent)
|
||||
if (eventName === 'load-commit') {
|
||||
webView.onLoadCommit(domEvent)
|
||||
} else if (eventName === 'focus-change') {
|
||||
webView.onFocusChange(domEvent)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -16,6 +16,13 @@ const getNextId = function () {
|
||||
return ++nextId
|
||||
}
|
||||
|
||||
// A list of removed attributes from 3.0.
|
||||
const removedAttributes = [
|
||||
'autoresize',
|
||||
'disableguestresize',
|
||||
'guestinstance'
|
||||
]
|
||||
|
||||
// Represents the internal state of the WebView node.
|
||||
class WebViewImpl {
|
||||
constructor (webviewNode) {
|
||||
@@ -23,22 +30,38 @@ class WebViewImpl {
|
||||
v8Util.setHiddenValue(this.webviewNode, 'internal', this)
|
||||
this.elementAttached = false
|
||||
this.beforeFirstNavigation = true
|
||||
this.hasFocus = false
|
||||
|
||||
// Check for removed attributes.
|
||||
for (const attributeName of removedAttributes) {
|
||||
if (this.webviewNode.hasAttribute(attributeName)) {
|
||||
this.reportRemovedAttribute(attributeName)
|
||||
}
|
||||
}
|
||||
|
||||
// on* Event handlers.
|
||||
this.on = {}
|
||||
|
||||
// Create internal iframe element.
|
||||
this.internalElement = this.createInternalElement()
|
||||
const shadowRoot = this.webviewNode.attachShadow({mode: 'open'})
|
||||
shadowRoot.innerHTML = '<!DOCTYPE html><style type="text/css">:host { display: flex; }</style>'
|
||||
this.setupWebViewAttributes()
|
||||
this.setupFocusPropagation()
|
||||
this.viewInstanceId = getNextId()
|
||||
shadowRoot.appendChild(this.internalElement)
|
||||
|
||||
// Provide access to contentWindow.
|
||||
Object.defineProperty(this.webviewNode, 'contentWindow', {
|
||||
get: () => {
|
||||
return this.internalElement.contentWindow
|
||||
},
|
||||
enumerable: true
|
||||
})
|
||||
}
|
||||
|
||||
createInternalElement () {
|
||||
const iframeElement = document.createElement('iframe')
|
||||
iframeElement.style.width = '100%'
|
||||
iframeElement.style.height = '100%'
|
||||
iframeElement.style.flex = '1 1 auto'
|
||||
iframeElement.style.border = '0'
|
||||
v8Util.setHiddenValue(iframeElement, 'internal', this)
|
||||
return iframeElement
|
||||
@@ -76,32 +99,17 @@ class WebViewImpl {
|
||||
})
|
||||
}
|
||||
|
||||
setupFocusPropagation () {
|
||||
if (!this.webviewNode.hasAttribute('tabIndex')) {
|
||||
// <webview> needs a tabIndex in order to be focusable.
|
||||
// TODO(fsamuel): It would be nice to avoid exposing a tabIndex attribute
|
||||
// to allow <webview> to be focusable.
|
||||
// See http://crbug.com/231664.
|
||||
this.webviewNode.setAttribute('tabIndex', -1)
|
||||
}
|
||||
|
||||
// Focus the BrowserPlugin when the <webview> takes focus.
|
||||
this.webviewNode.addEventListener('focus', () => {
|
||||
this.internalElement.focus()
|
||||
})
|
||||
|
||||
// Blur the BrowserPlugin when the <webview> loses focus.
|
||||
this.webviewNode.addEventListener('blur', () => {
|
||||
this.internalElement.blur()
|
||||
})
|
||||
}
|
||||
|
||||
// This observer monitors mutations to attributes of the <webview> and
|
||||
// updates the BrowserPlugin properties accordingly. In turn, updating
|
||||
// a BrowserPlugin property will update the corresponding BrowserPlugin
|
||||
// attribute, if necessary. See BrowserPlugin::UpdateDOMAttribute for more
|
||||
// details.
|
||||
handleWebviewAttributeMutation (attributeName, oldValue, newValue) {
|
||||
if (removedAttributes.includes(attributeName)) {
|
||||
this.reportRemovedAttribute(attributeName)
|
||||
return
|
||||
}
|
||||
|
||||
if (!this.attributes[attributeName] || this.attributes[attributeName].ignoreMutation) {
|
||||
return
|
||||
}
|
||||
@@ -165,6 +173,15 @@ class WebViewImpl {
|
||||
}
|
||||
}
|
||||
|
||||
// Emits focus/blur events.
|
||||
onFocusChange () {
|
||||
const hasFocus = document.activeElement === this.webviewNode
|
||||
if (hasFocus !== this.hasFocus) {
|
||||
this.hasFocus = hasFocus
|
||||
this.dispatchEvent(new Event(hasFocus ? 'focus' : 'blur'))
|
||||
}
|
||||
}
|
||||
|
||||
onAttach (storagePartitionId) {
|
||||
return this.attributes[webViewConstants.ATTRIBUTE_PARTITION].setValue(storagePartitionId)
|
||||
}
|
||||
@@ -197,6 +214,12 @@ class WebViewImpl {
|
||||
// even documented.
|
||||
this.resizeObserver = new ResizeObserver(this.onElementResize.bind(this)).observe(this.internalElement)
|
||||
}
|
||||
|
||||
// TODO(zcbenz): Remove the warning in 4.0.
|
||||
reportRemovedAttribute (attributeName) {
|
||||
console.error(`The "${attributeName}" attribute has been removed from the <webview> tag,`,
|
||||
'see https://github.com/electron/electron/issues/14120 for more.')
|
||||
}
|
||||
}
|
||||
|
||||
// Registers <webview> custom element.
|
||||
@@ -343,6 +366,11 @@ const registerWebViewElement = function () {
|
||||
return internal.webContents
|
||||
}
|
||||
|
||||
// Focusing the webview should move page focus to the underlying iframe.
|
||||
proto.focus = function () {
|
||||
this.contentWindow.focus()
|
||||
}
|
||||
|
||||
window.WebView = webFrame.registerEmbedderCustomElement('webview', {
|
||||
prototype: proto
|
||||
})
|
||||
|
||||
@@ -1,48 +1,17 @@
|
||||
Object.defineProperties(exports, {
|
||||
ipcRenderer: {
|
||||
enumerable: true,
|
||||
get: function () {
|
||||
return require('../ipc-renderer')
|
||||
}
|
||||
},
|
||||
remote: {
|
||||
enumerable: true,
|
||||
get: function () {
|
||||
return require('../../../renderer/api/remote')
|
||||
}
|
||||
},
|
||||
webFrame: {
|
||||
enumerable: true,
|
||||
get: function () {
|
||||
return require('../../../renderer/api/web-frame')
|
||||
}
|
||||
},
|
||||
crashReporter: {
|
||||
enumerable: true,
|
||||
get: function () {
|
||||
return require('../../../common/api/crash-reporter')
|
||||
}
|
||||
},
|
||||
CallbacksRegistry: {
|
||||
get: function () {
|
||||
return require('../../../common/api/callbacks-registry')
|
||||
}
|
||||
},
|
||||
isPromise: {
|
||||
get: function () {
|
||||
return require('../../../common/api/is-promise')
|
||||
}
|
||||
},
|
||||
// XXX(alexeykuzmin): It won't be available if the Desktop Capturer
|
||||
// was disabled during build time.
|
||||
desktopCapturer: {
|
||||
get: function () {
|
||||
return require('../../../renderer/api/desktop-capturer')
|
||||
}
|
||||
},
|
||||
nativeImage: {
|
||||
get: function () {
|
||||
return require('../../../common/api/native-image')
|
||||
}
|
||||
const moduleList = require('../module-list')
|
||||
|
||||
for (const {
|
||||
name,
|
||||
load,
|
||||
enabled = true,
|
||||
private: isPrivate = false
|
||||
} of moduleList) {
|
||||
if (!enabled) {
|
||||
continue
|
||||
}
|
||||
})
|
||||
|
||||
Object.defineProperty(exports, name, {
|
||||
enumerable: !isPrivate,
|
||||
get: load
|
||||
})
|
||||
}
|
||||
|
||||
39
lib/sandboxed_renderer/api/module-list.js
Normal file
39
lib/sandboxed_renderer/api/module-list.js
Normal file
@@ -0,0 +1,39 @@
|
||||
const features = process.atomBinding('features')
|
||||
|
||||
module.exports = [
|
||||
{
|
||||
name: 'CallbacksRegistry',
|
||||
load: () => require('../../common/api/callbacks-registry'),
|
||||
private: true
|
||||
},
|
||||
{
|
||||
name: 'crashReporter',
|
||||
load: () => require('../../common/api/crash-reporter')
|
||||
},
|
||||
{
|
||||
name: 'desktopCapturer',
|
||||
load: () => require('../../renderer/api/desktop-capturer'),
|
||||
enabled: features.isDesktopCapturerEnabled()
|
||||
},
|
||||
{
|
||||
name: 'ipcRenderer',
|
||||
load: () => require('./ipc-renderer')
|
||||
},
|
||||
{
|
||||
name: 'isPromise',
|
||||
load: () => require('../../common/api/is-promise'),
|
||||
private: true
|
||||
},
|
||||
{
|
||||
name: 'nativeImage',
|
||||
load: () => require('../../common/api/native-image')
|
||||
},
|
||||
{
|
||||
name: 'remote',
|
||||
load: () => require('../../renderer/api/remote')
|
||||
},
|
||||
{
|
||||
name: 'webFrame',
|
||||
load: () => require('../../renderer/api/web-frame')
|
||||
}
|
||||
]
|
||||
@@ -1,10 +1,12 @@
|
||||
/* eslint no-eval: "off" */
|
||||
/* global binding, Buffer */
|
||||
const events = require('events')
|
||||
const electron = require('electron')
|
||||
|
||||
process.atomBinding = require('../common/atom-binding-setup')(binding.get, 'renderer')
|
||||
|
||||
// The electron module depends on process.atomBinding
|
||||
const electron = require('electron')
|
||||
|
||||
const v8Util = process.atomBinding('v8_util')
|
||||
// Expose browserify Buffer as a hidden value. This is used by C++ code to
|
||||
// deserialize Buffer instances sent from browser process.
|
||||
|
||||
2
package-lock.json
generated
2
package-lock.json
generated
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "electron",
|
||||
"version": "3.0.0-nightly.20180818",
|
||||
"version": "3.0.0-beta.8",
|
||||
"lockfileVersion": 1,
|
||||
"requires": true,
|
||||
"dependencies": {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "electron",
|
||||
"version": "3.0.0-beta.6",
|
||||
"version": "3.0.0-nightly.20180904",
|
||||
"repository": "https://github.com/electron/electron",
|
||||
"description": "Build cross platform desktop apps with JavaScript, HTML, and CSS",
|
||||
"devDependencies": {
|
||||
|
||||
@@ -169,8 +169,6 @@ def setup_libchromiumcontent(is_dev, target_arch, url,
|
||||
mkdir_p(target_dir)
|
||||
else:
|
||||
mkdir_p(DOWNLOAD_DIR)
|
||||
if is_verbose_mode():
|
||||
args += ['-v']
|
||||
if is_dev:
|
||||
subprocess.check_call([sys.executable, script] + args)
|
||||
else:
|
||||
|
||||
@@ -34,8 +34,13 @@ async function makeRequest (requestOptions, parseResponse) {
|
||||
resolve(body)
|
||||
}
|
||||
} else {
|
||||
console.error('Error occurred while requesting:', requestOptions.url)
|
||||
if (parseResponse) {
|
||||
console.log('Error: ', `(status ${res.statusCode})`, err || JSON.parse(res.body), requestOptions)
|
||||
try {
|
||||
console.log('Error: ', `(status ${res.statusCode})`, err || JSON.parse(res.body), requestOptions)
|
||||
} catch (err) {
|
||||
console.log('Error: ', `(status ${res.statusCode})`, err || res.body, requestOptions)
|
||||
}
|
||||
} else {
|
||||
console.log('Error: ', `(status ${res.statusCode})`, err || res.body, requestOptions)
|
||||
}
|
||||
|
||||
108
script/release-artifact-cleanup.js
Normal file
108
script/release-artifact-cleanup.js
Normal file
@@ -0,0 +1,108 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
if (!process.env.CI) require('dotenv-safe').load()
|
||||
require('colors')
|
||||
const args = require('minimist')(process.argv.slice(2), {
|
||||
boolean: ['tag']
|
||||
})
|
||||
const { execSync } = require('child_process')
|
||||
const { GitProcess } = require('dugite')
|
||||
|
||||
const GitHub = require('github')
|
||||
const path = require('path')
|
||||
|
||||
const github = new GitHub()
|
||||
const gitDir = path.resolve(__dirname, '..')
|
||||
|
||||
github.authenticate({
|
||||
type: 'token',
|
||||
token: process.env.ELECTRON_GITHUB_TOKEN
|
||||
})
|
||||
|
||||
function getLastBumpCommit (tag) {
|
||||
const data = execSync(`git log -n1 --grep "Bump ${tag}" --format="format:{hash: %H, message: '%s'}"`)
|
||||
return JSON.parse(data)
|
||||
}
|
||||
|
||||
async function getCurrentBranch (gitDir) {
|
||||
const gitArgs = ['rev-parse', '--abbrev-ref', 'HEAD']
|
||||
const branchDetails = await GitProcess.exec(gitArgs, gitDir)
|
||||
if (branchDetails.exitCode === 0) {
|
||||
return branchDetails.stdout.trim()
|
||||
}
|
||||
|
||||
const error = GitProcess.parseError(branchDetails.stderr)
|
||||
console.error(`Couldn't get current branch: `, error)
|
||||
process.exit(1)
|
||||
}
|
||||
|
||||
async function revertBumpCommit (tag) {
|
||||
const branch = getCurrentBranch()
|
||||
const commitToRevert = getLastBumpCommit(tag).hash
|
||||
await GitProcess.exec(['revert', commitToRevert], gitDir)
|
||||
const pushDetails = await GitProcess.exec(['push', 'origin', `HEAD:${branch}`, '--follow-tags'], gitDir)
|
||||
if (pushDetails.exitCode === 0) {
|
||||
console.log(`Successfully reverted release commit.`)
|
||||
} else {
|
||||
const error = GitProcess.parseError(pushDetails.stderr)
|
||||
console.error(`Failed to push release commit: `, error)
|
||||
process.exit(1)
|
||||
}
|
||||
}
|
||||
|
||||
async function deleteDraft (tag, targetRepo) {
|
||||
try {
|
||||
const result = await github.repos.getReleaseByTag({
|
||||
owner: 'electron',
|
||||
repo: targetRepo,
|
||||
tag
|
||||
})
|
||||
if (!result.draft) {
|
||||
console.log(`Published releases cannot be deleted.`)
|
||||
process.exit(1)
|
||||
} else {
|
||||
await github.repos.deleteRelease({
|
||||
owner: 'electron',
|
||||
repo: targetRepo,
|
||||
release_id: result.id
|
||||
})
|
||||
}
|
||||
console.log(`Successfully deleted draft with tag ${tag} from ${targetRepo}`)
|
||||
} catch (err) {
|
||||
console.error(`Couldn't delete draft with tag ${tag} from ${targetRepo}: `, err)
|
||||
process.exit(1)
|
||||
}
|
||||
}
|
||||
|
||||
async function deleteTag (tag, targetRepo) {
|
||||
try {
|
||||
await github.gitdata.deleteReference({
|
||||
owner: 'electron',
|
||||
repo: targetRepo,
|
||||
ref: tag
|
||||
})
|
||||
console.log(`Successfully deleted tag ${tag} from ${targetRepo}`)
|
||||
} catch (err) {
|
||||
console.log(`Couldn't delete tag ${tag} from ${targetRepo}: `, err)
|
||||
process.exit(1)
|
||||
}
|
||||
}
|
||||
|
||||
async function cleanReleaseArtifacts () {
|
||||
const tag = args.tag
|
||||
const lastBumpCommit = getLastBumpCommit().message
|
||||
|
||||
if (lastBumpCommit.indexOf('nightly' > 0)) {
|
||||
await deleteDraft(tag, 'nightlies')
|
||||
await deleteTag(tag, 'nightlies')
|
||||
} else {
|
||||
await deleteDraft(tag, 'electron')
|
||||
}
|
||||
|
||||
await deleteTag(tag, 'electron')
|
||||
await revertBumpCommit(tag)
|
||||
|
||||
console.log('Failed release artifact cleanup complete')
|
||||
}
|
||||
|
||||
cleanReleaseArtifacts()
|
||||
@@ -15,6 +15,21 @@ BASE_URL = 'https://electron-metadumper.herokuapp.com/?version='
|
||||
version = sys.argv[1]
|
||||
authToken = os.getenv('META_DUMPER_AUTH_HEADER')
|
||||
|
||||
def get_content(retry_count = 5):
|
||||
try:
|
||||
request = urllib2.Request(
|
||||
BASE_URL + version,
|
||||
headers={"Authorization" : authToken}
|
||||
)
|
||||
|
||||
return urllib2.urlopen(
|
||||
request
|
||||
).read()
|
||||
except Exception as e:
|
||||
if retry_count == 0:
|
||||
raise e
|
||||
return get_content(retry_count - 1)
|
||||
|
||||
def main():
|
||||
if not authToken or authToken == "":
|
||||
raise Exception("Please set META_DUMPER_AUTH_HEADER")
|
||||
@@ -23,14 +38,7 @@ def main():
|
||||
safe_mkdir(OUT_DIR)
|
||||
index_json = os.path.relpath(os.path.join(OUT_DIR, 'index.json'))
|
||||
|
||||
request = urllib2.Request(
|
||||
BASE_URL + version,
|
||||
headers={"Authorization" : authToken}
|
||||
)
|
||||
|
||||
new_content = urllib2.urlopen(
|
||||
request
|
||||
).read()
|
||||
new_content = get_content()
|
||||
|
||||
with open(index_json, "w") as f:
|
||||
f.write(new_content)
|
||||
|
||||
@@ -893,6 +893,17 @@ describe('BrowserWindow module', () => {
|
||||
})
|
||||
})
|
||||
|
||||
describe('BrowserWindow.setShape(rects)', () => {
|
||||
it('allows setting shape', () => {
|
||||
assert.doesNotThrow(() => {
|
||||
w.setShape([])
|
||||
w.setShape([{x: 0, y: 0, width: 100, height: 100}])
|
||||
w.setShape([{x: 0, y: 0, width: 100, height: 100}, {x: 0, y: 200, width: 1000, height: 100}])
|
||||
w.setShape([])
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('"useContentSize" option', () => {
|
||||
it('make window created with content size when used', () => {
|
||||
w.destroy()
|
||||
|
||||
47
spec/api-tray-spec.js
Normal file
47
spec/api-tray-spec.js
Normal file
@@ -0,0 +1,47 @@
|
||||
const {remote} = require('electron')
|
||||
const {Menu, Tray, nativeImage} = remote
|
||||
|
||||
describe('tray module', () => {
|
||||
let tray
|
||||
|
||||
beforeEach(() => {
|
||||
tray = new Tray(nativeImage.createEmpty())
|
||||
})
|
||||
|
||||
afterEach(() => {
|
||||
tray.destroy()
|
||||
tray = null
|
||||
})
|
||||
|
||||
describe('tray.setContextMenu', () => {
|
||||
it('accepts menu instance', () => {
|
||||
tray.setContextMenu(new Menu())
|
||||
})
|
||||
|
||||
it('accepts null', () => {
|
||||
tray.setContextMenu(null)
|
||||
})
|
||||
})
|
||||
|
||||
describe('tray.setImage', () => {
|
||||
it('accepts empty image', () => {
|
||||
tray.setImage(nativeImage.createEmpty())
|
||||
})
|
||||
})
|
||||
|
||||
describe('tray.setPressedImage', () => {
|
||||
it('accepts empty image', () => {
|
||||
tray.setPressedImage(nativeImage.createEmpty())
|
||||
})
|
||||
})
|
||||
|
||||
describe('tray.setTitle', () => {
|
||||
it('accepts non-empty string', () => {
|
||||
tray.setTitle('Hello World!')
|
||||
})
|
||||
|
||||
it('accepts empty string', () => {
|
||||
tray.setTitle('')
|
||||
})
|
||||
})
|
||||
})
|
||||
@@ -226,6 +226,47 @@ describe('chromium feature', () => {
|
||||
})
|
||||
})
|
||||
|
||||
describe('navigator.geolocation', () => {
|
||||
before(function () {
|
||||
if (!features.isFakeLocationProviderEnabled()) {
|
||||
return this.skip()
|
||||
}
|
||||
})
|
||||
|
||||
it('returns position when permission is granted', (done) => {
|
||||
navigator.geolocation.getCurrentPosition((position) => {
|
||||
assert(position.timestamp)
|
||||
done()
|
||||
}, (error) => {
|
||||
done(error)
|
||||
})
|
||||
})
|
||||
|
||||
it('returns error when permission is denied', (done) => {
|
||||
w = new BrowserWindow({
|
||||
show: false,
|
||||
webPreferences: {
|
||||
partition: 'geolocation-spec'
|
||||
}
|
||||
})
|
||||
w.webContents.on('ipc-message', (event, args) => {
|
||||
if (args[0] === 'success') {
|
||||
done()
|
||||
} else {
|
||||
done('unexpected response from geolocation api')
|
||||
}
|
||||
})
|
||||
w.webContents.session.setPermissionRequestHandler((wc, permission, callback) => {
|
||||
if (permission === 'geolocation') {
|
||||
callback(false)
|
||||
} else {
|
||||
callback(true)
|
||||
}
|
||||
})
|
||||
w.loadURL(`file://${fixtures}/pages/geolocation/index.html`)
|
||||
})
|
||||
})
|
||||
|
||||
describe('window.open', () => {
|
||||
it('returns a BrowserWindowProxy object', () => {
|
||||
const b = window.open('about:blank', '', 'show=no')
|
||||
|
||||
2
spec/fixtures/api/render-view-deleted.html
vendored
2
spec/fixtures/api/render-view-deleted.html
vendored
@@ -17,7 +17,7 @@
|
||||
}
|
||||
|
||||
// This should trigger a dereference and a remote getURL call should fail
|
||||
contents.emit('render-view-deleted', {}, contents.getProcessId())
|
||||
contents.emit('render-view-deleted', {}, '', contents.getOSProcessId())
|
||||
try {
|
||||
contents.getURL()
|
||||
ipcRenderer.send('error-message', 'No error thrown')
|
||||
|
||||
12
spec/fixtures/pages/geolocation/index.html
vendored
Normal file
12
spec/fixtures/pages/geolocation/index.html
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
<script>
|
||||
const ipcRenderer = require('electron').ipcRenderer;
|
||||
navigator.geolocation.getCurrentPosition((position) => {
|
||||
ipcRenderer.send(position);
|
||||
}, (error) => {
|
||||
if (error) {
|
||||
ipcRenderer.send('success')
|
||||
} else {
|
||||
ipcRenderer.send('unexpected error')
|
||||
}
|
||||
})
|
||||
</script>
|
||||
@@ -1283,6 +1283,20 @@ describe('<webview> tag', function () {
|
||||
expect(secondResizeEvent.newWidth).to.equal(newWidth)
|
||||
expect(secondResizeEvent.newHeight).to.equal(newHeight)
|
||||
})
|
||||
|
||||
it('emits focus event', async () => {
|
||||
const domReadySignal = waitForEvent(webview, 'dom-ready')
|
||||
webview.src = `file://${fixtures}/pages/a.html`
|
||||
document.body.appendChild(webview)
|
||||
|
||||
await domReadySignal
|
||||
|
||||
// If this test fails, check if webview.focus() still works.
|
||||
const focusSignal = waitForEvent(webview, 'focus')
|
||||
webview.focus()
|
||||
|
||||
await focusSignal
|
||||
})
|
||||
})
|
||||
|
||||
describe('zoom behavior', () => {
|
||||
|
||||
2
vendor/libchromiumcontent
vendored
2
vendor/libchromiumcontent
vendored
Submodule vendor/libchromiumcontent updated: 92dc0accfa...dc2e7ebd28
Reference in New Issue
Block a user