From 64369cd07fa2b90dbe4aa978bd7baf32721b1cae Mon Sep 17 00:00:00 2001 From: joshaber Date: Thu, 30 Mar 2017 17:25:44 -0400 Subject: [PATCH 001/143] Show a certificate trust panel --- atom/browser/api/atom_api_certificate_trust.h | 33 +++++++++++++ .../api/atom_api_certificate_trust_mac.mm | 48 +++++++++++++++++++ 2 files changed, 81 insertions(+) create mode 100644 atom/browser/api/atom_api_certificate_trust.h create mode 100644 atom/browser/api/atom_api_certificate_trust_mac.mm diff --git a/atom/browser/api/atom_api_certificate_trust.h b/atom/browser/api/atom_api_certificate_trust.h new file mode 100644 index 0000000000..c3e6994b3b --- /dev/null +++ b/atom/browser/api/atom_api_certificate_trust.h @@ -0,0 +1,33 @@ +// Copyright (c) 2017 GitHub, Inc. +// Use of this source code is governed by the MIT license that can be +// found in the LICENSE file. + +#ifndef ATOM_BROWSER_API_ATOM_API_CERTIFICATE_TRUST_H_ +#define ATOM_BROWSER_API_ATOM_API_CERTIFICATE_TRUST_H_ + +#include + +#include "base/callback_forward.h" + +namespace net { +class X509Certificate; +} // namespace net + +namespace atom { + +class NativeWindow; + +namespace api { + +typedef base::Callback ShowTrustCallback; + +void ShowCertificateTrustUI(atom::NativeWindow* parent_window, + const net::X509Certificate& cert, + std::string message, + const ShowTrustCallback& callback); + +} // namespace api + +} // namespace atom + +#endif // ATOM_BROWSER_API_ATOM_API_CERTIFICATE_TRUST_H_ diff --git a/atom/browser/api/atom_api_certificate_trust_mac.mm b/atom/browser/api/atom_api_certificate_trust_mac.mm new file mode 100644 index 0000000000..c0109d9f45 --- /dev/null +++ b/atom/browser/api/atom_api_certificate_trust_mac.mm @@ -0,0 +1,48 @@ +// Copyright (c) 2017 GitHub, Inc. +// Use of this source code is governed by the MIT license that can be +// found in the LICENSE file. + +#include "atom/browser/api/atom_api_certificate_trust.h" + +#import +#import +#import + +#include "atom/browser/native_window.h" +#include "base/files/file_util.h" +#include "base/mac/foundation_util.h" +#include "base/mac/mac_util.h" +#include "base/mac/scoped_cftyperef.h" +#include "base/strings/sys_string_conversions.h" +#include "net/cert/x509_certificate.h" + +namespace atom { + +namespace api { + +void ShowCertificateTrustUI(atom::NativeWindow* parent_window, + const net::X509Certificate& cert, + std::string message, + const ShowTrustCallback& callback) { + auto sec_policy = SecPolicyCreateBasicX509(); + SecTrustRef trust = nullptr; + SecTrustCreateWithCertificates(cert.CreateOSCertChainForCert(), sec_policy, &trust); + // CFRelease(sec_policy); + + NSWindow* window = parent_window ? + parent_window->GetNativeWindow() : + NULL; + + auto msg = base::SysUTF8ToNSString(message); + + SFCertificateTrustPanel *panel = [[SFCertificateTrustPanel alloc] init]; + [panel beginSheetForWindow:window modalDelegate:nil didEndSelector:NULL contextInfo:NULL trust:trust message:msg]; + + callback.Run(true); + // CFRelease(trust); + // [panel release]; +} + +} // namespace api + +} // namespace atom From 653b2d15c325638d4a9aca0cba15bb6dcc35a352 Mon Sep 17 00:00:00 2001 From: joshaber Date: Thu, 30 Mar 2017 17:25:55 -0400 Subject: [PATCH 002/143] Expose the certificate trust panel as part of app --- atom/browser/api/atom_api_app.cc | 12 ++++++++++++ atom/browser/api/atom_api_app.h | 11 +++++++++++ 2 files changed, 23 insertions(+) diff --git a/atom/browser/api/atom_api_app.cc b/atom/browser/api/atom_api_app.cc index 56a11daf69..3a8f4ef0f8 100644 --- a/atom/browser/api/atom_api_app.cc +++ b/atom/browser/api/atom_api_app.cc @@ -7,6 +7,7 @@ #include #include +#include "atom/browser/api/atom_api_certificate_trust.h" #include "atom/browser/api/atom_api_menu.h" #include "atom/browser/api/atom_api_session.h" #include "atom/browser/api/atom_api_web_contents.h" @@ -810,6 +811,16 @@ void App::OnCertificateManagerModelCreated( } #endif +#if defined(OS_MACOSX) +void App::ShowCertificateTrust(atom::NativeWindow* parent_window, + const net::X509Certificate& cert, + std::string message, + const ShowTrustCallback& callback, + mate::Arguments* args) { + ShowCertificateTrustUI(parent_window, cert, message, callback); +} +#endif + #if defined(OS_WIN) v8::Local App::GetJumpListSettings() { JumpList jump_list(Browser::Get()->GetAppUserModelID()); @@ -949,6 +960,7 @@ void App::BuildPrototype( base::Bind(&Browser::GetCurrentActivityType, browser)) .SetMethod("setAboutPanelOptions", base::Bind(&Browser::SetAboutPanelOptions, browser)) + // .SetMethod("showCertificateTrust", &App::ShowCertificateTrust) #endif #if defined(OS_WIN) .SetMethod("setUserTasks", base::Bind(&Browser::SetUserTasks, browser)) diff --git a/atom/browser/api/atom_api_app.h b/atom/browser/api/atom_api_app.h index 8b276f334d..367709cf0c 100644 --- a/atom/browser/api/atom_api_app.h +++ b/atom/browser/api/atom_api_app.h @@ -8,6 +8,7 @@ #include #include +#include "atom/browser/api/atom_api_certificate_trust.h" #include "atom/browser/api/event_emitter.h" #include "atom/browser/atom_browser_client.h" #include "atom/browser/browser.h" @@ -19,6 +20,7 @@ #include "content/public/browser/gpu_data_manager_observer.h" #include "native_mate/handle.h" #include "net/base/completion_callback.h" +#include "net/cert/x509_certificate.h" #if defined(USE_NSS_CERTS) #include "chrome/browser/certificate_manager_model.h" @@ -151,6 +153,15 @@ class App : public AtomBrowserClient::Delegate, std::unique_ptr certificate_manager_model_; #endif + +#if defined(OS_MACOSX) + void ShowCertificateTrust(atom::NativeWindow* parent_window, + const net::X509Certificate& cert, + std::string message, + const ShowTrustCallback& callback, + mate::Arguments* args); +#endif + // Tracks tasks requesting file icons. base::CancelableTaskTracker cancelable_task_tracker_; From 7b044ffe0e723c67e77ab509754655f72df7cfd8 Mon Sep 17 00:00:00 2001 From: joshaber Date: Thu, 30 Mar 2017 17:26:03 -0400 Subject: [PATCH 003/143] Compile these lovely files --- filenames.gypi | 2 ++ 1 file changed, 2 insertions(+) diff --git a/filenames.gypi b/filenames.gypi index 935d703315..f2a78ad4d4 100644 --- a/filenames.gypi +++ b/filenames.gypi @@ -103,6 +103,8 @@ 'atom/browser/api/atom_api_app.h', 'atom/browser/api/atom_api_auto_updater.cc', 'atom/browser/api/atom_api_auto_updater.h', + 'atom/browser/api/atom_api_certificate_trust_mac.mm', + 'atom/browser/api/atom_api_certificate_trust.h', 'atom/browser/api/atom_api_content_tracing.cc', 'atom/browser/api/atom_api_cookies.cc', 'atom/browser/api/atom_api_cookies.h', From edf61d41ba3a3efed0b45f80e252cdb75b154895 Mon Sep 17 00:00:00 2001 From: joshaber Date: Thu, 30 Mar 2017 17:26:11 -0400 Subject: [PATCH 004/143] Link against the Security frameworks --- electron.gyp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/electron.gyp b/electron.gyp index 78eed743cc..71c53fe6f5 100644 --- a/electron.gyp +++ b/electron.gyp @@ -549,6 +549,8 @@ '$(SDKROOT)/System/Library/Frameworks/Carbon.framework', '$(SDKROOT)/System/Library/Frameworks/QuartzCore.framework', '$(SDKROOT)/System/Library/Frameworks/Quartz.framework', + '$(SDKROOT)/System/Library/Frameworks/Security.framework', + '$(SDKROOT)/System/Library/Frameworks/SecurityInterface.framework', ], }, 'mac_bundle': 1, From 1c80102218e8a1b56886996acf192c1bc1d9151c Mon Sep 17 00:00:00 2001 From: Philip Jackson Date: Fri, 31 Mar 2017 16:42:03 +1300 Subject: [PATCH 005/143] :memo: Document passing null to Menu.setApplicationMenu [ci skip] --- docs/api/menu.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/api/menu.md b/docs/api/menu.md index 42724e1d4a..13585fef72 100644 --- a/docs/api/menu.md +++ b/docs/api/menu.md @@ -17,7 +17,8 @@ The `menu` class has the following static methods: * `menu` Menu Sets `menu` as the application menu on macOS. On Windows and Linux, the `menu` -will be set as each window's top menu. +will be set as each window's top menu. Setting it to `null` will remove the +menu bar. **Note:** This API has to be called after the `ready` event of `app` module. From deae70de4ddc063d976373f25e3eed11baadb449 Mon Sep 17 00:00:00 2001 From: joshaber Date: Fri, 31 Mar 2017 13:53:31 -0400 Subject: [PATCH 006/143] Dummy out the certificate FromV8 converter --- atom/common/native_mate_converters/net_converter.cc | 6 ++++++ atom/common/native_mate_converters/net_converter.h | 4 ++++ 2 files changed, 10 insertions(+) diff --git a/atom/common/native_mate_converters/net_converter.cc b/atom/common/native_mate_converters/net_converter.cc index 94fff2ff60..477e382fdc 100644 --- a/atom/common/native_mate_converters/net_converter.cc +++ b/atom/common/native_mate_converters/net_converter.cc @@ -73,6 +73,12 @@ v8::Local Converter>::ToV8( return dict.GetHandle(); } +bool Converter>::FromV8(v8::Isolate* isolate, + v8::Local val, + scoped_refptr* out) { + return true; +} + // static v8::Local Converter::ToV8( v8::Isolate* isolate, const net::CertPrincipal& val) { diff --git a/atom/common/native_mate_converters/net_converter.h b/atom/common/native_mate_converters/net_converter.h index 33117ca974..9e3128fdb5 100644 --- a/atom/common/native_mate_converters/net_converter.h +++ b/atom/common/native_mate_converters/net_converter.h @@ -33,6 +33,10 @@ template<> struct Converter> { static v8::Local ToV8(v8::Isolate* isolate, const scoped_refptr& val); + + static bool FromV8(v8::Isolate* isolate, + v8::Local val, + scoped_refptr* out); }; template<> From 16cc79354c5dcc8758c043185a16196d64c14bb6 Mon Sep 17 00:00:00 2001 From: joshaber Date: Fri, 31 Mar 2017 13:53:42 -0400 Subject: [PATCH 007/143] Errrrybody's a scoped_refptr now --- atom/browser/api/atom_api_app.cc | 4 ++-- atom/browser/api/atom_api_app.h | 2 +- atom/browser/api/atom_api_certificate_trust.h | 3 ++- atom/browser/api/atom_api_certificate_trust_mac.mm | 4 ++-- 4 files changed, 7 insertions(+), 6 deletions(-) diff --git a/atom/browser/api/atom_api_app.cc b/atom/browser/api/atom_api_app.cc index 3a8f4ef0f8..41e7655a66 100644 --- a/atom/browser/api/atom_api_app.cc +++ b/atom/browser/api/atom_api_app.cc @@ -813,7 +813,7 @@ void App::OnCertificateManagerModelCreated( #if defined(OS_MACOSX) void App::ShowCertificateTrust(atom::NativeWindow* parent_window, - const net::X509Certificate& cert, + const scoped_refptr& cert, std::string message, const ShowTrustCallback& callback, mate::Arguments* args) { @@ -960,7 +960,7 @@ void App::BuildPrototype( base::Bind(&Browser::GetCurrentActivityType, browser)) .SetMethod("setAboutPanelOptions", base::Bind(&Browser::SetAboutPanelOptions, browser)) - // .SetMethod("showCertificateTrust", &App::ShowCertificateTrust) + .SetMethod("showCertificateTrust", &App::ShowCertificateTrust) #endif #if defined(OS_WIN) .SetMethod("setUserTasks", base::Bind(&Browser::SetUserTasks, browser)) diff --git a/atom/browser/api/atom_api_app.h b/atom/browser/api/atom_api_app.h index 367709cf0c..19640cb848 100644 --- a/atom/browser/api/atom_api_app.h +++ b/atom/browser/api/atom_api_app.h @@ -156,7 +156,7 @@ class App : public AtomBrowserClient::Delegate, #if defined(OS_MACOSX) void ShowCertificateTrust(atom::NativeWindow* parent_window, - const net::X509Certificate& cert, + const scoped_refptr& cert, std::string message, const ShowTrustCallback& callback, mate::Arguments* args); diff --git a/atom/browser/api/atom_api_certificate_trust.h b/atom/browser/api/atom_api_certificate_trust.h index c3e6994b3b..1de7d653bb 100644 --- a/atom/browser/api/atom_api_certificate_trust.h +++ b/atom/browser/api/atom_api_certificate_trust.h @@ -8,6 +8,7 @@ #include #include "base/callback_forward.h" +#include "base/memory/ref_counted.h" namespace net { class X509Certificate; @@ -22,7 +23,7 @@ namespace api { typedef base::Callback ShowTrustCallback; void ShowCertificateTrustUI(atom::NativeWindow* parent_window, - const net::X509Certificate& cert, + const scoped_refptr& cert, std::string message, const ShowTrustCallback& callback); diff --git a/atom/browser/api/atom_api_certificate_trust_mac.mm b/atom/browser/api/atom_api_certificate_trust_mac.mm index c0109d9f45..dc12ada27f 100644 --- a/atom/browser/api/atom_api_certificate_trust_mac.mm +++ b/atom/browser/api/atom_api_certificate_trust_mac.mm @@ -21,12 +21,12 @@ namespace atom { namespace api { void ShowCertificateTrustUI(atom::NativeWindow* parent_window, - const net::X509Certificate& cert, + const scoped_refptr& cert, std::string message, const ShowTrustCallback& callback) { auto sec_policy = SecPolicyCreateBasicX509(); SecTrustRef trust = nullptr; - SecTrustCreateWithCertificates(cert.CreateOSCertChainForCert(), sec_policy, &trust); + SecTrustCreateWithCertificates(cert->CreateOSCertChainForCert(), sec_policy, &trust); // CFRelease(sec_policy); NSWindow* window = parent_window ? From 141a5ad73f2ecdc4305ef9a7572a3ae72333257e Mon Sep 17 00:00:00 2001 From: joshaber Date: Fri, 31 Mar 2017 14:16:26 -0400 Subject: [PATCH 008/143] Maybe this is a valid conversion? --- atom/common/native_mate_converters/net_converter.cc | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/atom/common/native_mate_converters/net_converter.cc b/atom/common/native_mate_converters/net_converter.cc index 477e382fdc..8e8f6c0014 100644 --- a/atom/common/native_mate_converters/net_converter.cc +++ b/atom/common/native_mate_converters/net_converter.cc @@ -73,9 +73,16 @@ v8::Local Converter>::ToV8( return dict.GetHandle(); } -bool Converter>::FromV8(v8::Isolate* isolate, - v8::Local val, - scoped_refptr* out) { +bool Converter>::FromV8( + v8::Isolate* isolate, v8::Local val, + scoped_refptr* out) { + mate::Dictionary dict; + if (!ConvertFromV8(isolate, val, &dict)) + return false; + + std::string data; + dict.Get("data", &data); + *out = net::X509Certificate::CreateFromBytes(data.c_str(), data.length()); return true; } From 302ca8669dd35121ab1a2bb5126ba6c3e48ff792 Mon Sep 17 00:00:00 2001 From: joshaber Date: Fri, 31 Mar 2017 15:44:47 -0400 Subject: [PATCH 009/143] Slightly better conversion --- atom/common/native_mate_converters/net_converter.cc | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/atom/common/native_mate_converters/net_converter.cc b/atom/common/native_mate_converters/net_converter.cc index 8e8f6c0014..59f897c8a7 100644 --- a/atom/common/native_mate_converters/net_converter.cc +++ b/atom/common/native_mate_converters/net_converter.cc @@ -82,7 +82,18 @@ bool Converter>::FromV8( std::string data; dict.Get("data", &data); - *out = net::X509Certificate::CreateFromBytes(data.c_str(), data.length()); + + auto certificate_list = net::X509Certificate::CreateCertificateListFromBytes( + data.c_str(), data.length(), + net::X509Certificate::FORMAT_SINGLE_CERTIFICATE); + if (certificate_list.empty()) + return false; + + auto certificate = certificate_list.front(); + if (!certificate) + return false; + + *out = certificate; return true; } From 69defc5166ac69bd05c8640630f1375e7968dee0 Mon Sep 17 00:00:00 2001 From: joshaber Date: Fri, 31 Mar 2017 21:27:33 -0400 Subject: [PATCH 010/143] Encode all the intermediates --- atom/common/native_mate_converters/net_converter.cc | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/atom/common/native_mate_converters/net_converter.cc b/atom/common/native_mate_converters/net_converter.cc index 59f897c8a7..5ceb23a04b 100644 --- a/atom/common/native_mate_converters/net_converter.cc +++ b/atom/common/native_mate_converters/net_converter.cc @@ -59,7 +59,8 @@ v8::Local Converter>::ToV8( net::HashValue( val->CalculateFingerprint256(val->os_cert_handle())).ToString()); - if (!val->GetIntermediateCertificates().empty()) { + auto intermediates = val->GetIntermediateCertificates(); + if (!intermediates.empty()) { net::X509Certificate::OSCertHandles issuer_intermediates( val->GetIntermediateCertificates().begin() + 1, val->GetIntermediateCertificates().end()); @@ -68,6 +69,16 @@ v8::Local Converter>::ToV8( val->GetIntermediateCertificates().front(), issuer_intermediates); dict.Set("issuerCert", issuer_cert); + + std::vector intermediates_encoded; + for (size_t i = 0; i < intermediates.size(); i++) { + auto native_cert = intermediates[i]; + std::string encoded; + net::X509Certificate::GetPEMEncoded(native_cert, &encoded); + intermediates_encoded.push_back(encoded); + } + + dict.Set("intermediates", intermediates_encoded); } return dict.GetHandle(); From bde2a597f362fd3b1b4a024367442f8d71c9bc91 Mon Sep 17 00:00:00 2001 From: joshaber Date: Fri, 31 Mar 2017 21:27:49 -0400 Subject: [PATCH 011/143] Decode all the intermediates --- .../native_mate_converters/net_converter.cc | 43 +++++++++++++++---- 1 file changed, 35 insertions(+), 8 deletions(-) diff --git a/atom/common/native_mate_converters/net_converter.cc b/atom/common/native_mate_converters/net_converter.cc index 5ceb23a04b..bfd346835b 100644 --- a/atom/common/native_mate_converters/net_converter.cc +++ b/atom/common/native_mate_converters/net_converter.cc @@ -84,6 +84,23 @@ v8::Local Converter>::ToV8( return dict.GetHandle(); } +bool CertFromData(const std::string& data, + scoped_refptr* out) { + auto cert_list = net::X509Certificate::CreateCertificateListFromBytes( + data.c_str(), data.length(), + net::X509Certificate::FORMAT_SINGLE_CERTIFICATE); + if (cert_list.empty()) + return false; + + auto leaf_cert = cert_list.front(); + if (!leaf_cert) + return false; + + *out = leaf_cert; + + return true; +} + bool Converter>::FromV8( v8::Isolate* isolate, v8::Local val, scoped_refptr* out) { @@ -93,18 +110,28 @@ bool Converter>::FromV8( std::string data; dict.Get("data", &data); - - auto certificate_list = net::X509Certificate::CreateCertificateListFromBytes( - data.c_str(), data.length(), - net::X509Certificate::FORMAT_SINGLE_CERTIFICATE); - if (certificate_list.empty()) + scoped_refptr leaf_cert; + if (!CertFromData(data, &leaf_cert)) return false; - auto certificate = certificate_list.front(); - if (!certificate) + std::vector intermediates_encoded; + dict.Get("intermediates", &intermediates_encoded); + std::vector intermediates; + for (size_t i = 0; i < intermediates_encoded.size(); i++) { + auto data = intermediates_encoded[i]; + scoped_refptr cert; + if (!CertFromData(data, &cert)) + return false; + + intermediates.push_back(cert->os_cert_handle()); + } + + auto cert = net::X509Certificate::CreateFromHandle( + leaf_cert->os_cert_handle(), intermediates); + if (!cert) return false; - *out = certificate; + *out = cert; return true; } From 4f3d3557cc244741340f12684c06d91ea5a9488b Mon Sep 17 00:00:00 2001 From: joshaber Date: Fri, 31 Mar 2017 21:51:29 -0400 Subject: [PATCH 012/143] Notify that the cert changed --- .../browser/api/atom_api_certificate_trust_mac.mm | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/atom/browser/api/atom_api_certificate_trust_mac.mm b/atom/browser/api/atom_api_certificate_trust_mac.mm index dc12ada27f..5057ef55ab 100644 --- a/atom/browser/api/atom_api_certificate_trust_mac.mm +++ b/atom/browser/api/atom_api_certificate_trust_mac.mm @@ -15,6 +15,7 @@ #include "base/mac/scoped_cftyperef.h" #include "base/strings/sys_string_conversions.h" #include "net/cert/x509_certificate.h" +#include "net/cert/cert_database.h" namespace atom { @@ -29,14 +30,20 @@ void ShowCertificateTrustUI(atom::NativeWindow* parent_window, SecTrustCreateWithCertificates(cert->CreateOSCertChainForCert(), sec_policy, &trust); // CFRelease(sec_policy); - NSWindow* window = parent_window ? - parent_window->GetNativeWindow() : - NULL; + // NSWindow* window = parent_window ? + // parent_window->GetNativeWindow() : + // NULL; auto msg = base::SysUTF8ToNSString(message); SFCertificateTrustPanel *panel = [[SFCertificateTrustPanel alloc] init]; - [panel beginSheetForWindow:window modalDelegate:nil didEndSelector:NULL contextInfo:NULL trust:trust message:msg]; + [panel runModalForTrust:trust message:msg]; + // [panel beginSheetForWindow:window modalDelegate:nil didEndSelector:NULL contextInfo:NULL trust:trust message:msg]; + + auto cert_db = net::CertDatabase::GetInstance(); + // This forces Chromium to reload the certificate since it might be trusted + // now. + cert_db->NotifyObserversCertDBChanged(cert.get()); callback.Run(true); // CFRelease(trust); From ee7389bb6ddfe5f6486f8a07c2ac1298cbbb950c Mon Sep 17 00:00:00 2001 From: joshaber Date: Fri, 31 Mar 2017 22:57:56 -0400 Subject: [PATCH 013/143] Rename to make VS happy --- atom/common/native_mate_converters/net_converter.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/atom/common/native_mate_converters/net_converter.cc b/atom/common/native_mate_converters/net_converter.cc index bfd346835b..2d3095a63e 100644 --- a/atom/common/native_mate_converters/net_converter.cc +++ b/atom/common/native_mate_converters/net_converter.cc @@ -118,9 +118,9 @@ bool Converter>::FromV8( dict.Get("intermediates", &intermediates_encoded); std::vector intermediates; for (size_t i = 0; i < intermediates_encoded.size(); i++) { - auto data = intermediates_encoded[i]; + auto intermediate_data = intermediates_encoded[i]; scoped_refptr cert; - if (!CertFromData(data, &cert)) + if (!CertFromData(intermediate_data, &cert)) return false; intermediates.push_back(cert->os_cert_handle()); From 1ed443ea294ad4a84e1100c90ea5acf3df2e29f3 Mon Sep 17 00:00:00 2001 From: joshaber Date: Mon, 3 Apr 2017 13:21:44 -0400 Subject: [PATCH 014/143] Do the callback & release dance --- .../api/atom_api_certificate_trust_mac.mm | 59 +++++++++++++------ 1 file changed, 42 insertions(+), 17 deletions(-) diff --git a/atom/browser/api/atom_api_certificate_trust_mac.mm b/atom/browser/api/atom_api_certificate_trust_mac.mm index 5057ef55ab..d767330c94 100644 --- a/atom/browser/api/atom_api_certificate_trust_mac.mm +++ b/atom/browser/api/atom_api_certificate_trust_mac.mm @@ -17,6 +17,26 @@ #include "net/cert/x509_certificate.h" #include "net/cert/cert_database.h" +@interface Trampoline : NSObject + +- (void)createPanelDidEnd:(NSWindow *)sheet + returnCode:(int)returnCode + contextInfo:(void *)contextInfo; + +@end + +@implementation Trampoline + +- (void)createPanelDidEnd:(NSWindow *)sheet + returnCode:(int)returnCode + contextInfo:(void *)contextInfo { + void (^block)(int) = (void (^)(int))contextInfo; + block(returnCode); + [(id)block autorelease]; +} + +@end + namespace atom { namespace api { @@ -26,28 +46,33 @@ void ShowCertificateTrustUI(atom::NativeWindow* parent_window, std::string message, const ShowTrustCallback& callback) { auto sec_policy = SecPolicyCreateBasicX509(); + auto cert_chain = cert->CreateOSCertChainForCert(); SecTrustRef trust = nullptr; - SecTrustCreateWithCertificates(cert->CreateOSCertChainForCert(), sec_policy, &trust); - // CFRelease(sec_policy); - - // NSWindow* window = parent_window ? - // parent_window->GetNativeWindow() : - // NULL; - - auto msg = base::SysUTF8ToNSString(message); + SecTrustCreateWithCertificates(cert_chain, sec_policy, &trust); SFCertificateTrustPanel *panel = [[SFCertificateTrustPanel alloc] init]; - [panel runModalForTrust:trust message:msg]; - // [panel beginSheetForWindow:window modalDelegate:nil didEndSelector:NULL contextInfo:NULL trust:trust message:msg]; - auto cert_db = net::CertDatabase::GetInstance(); - // This forces Chromium to reload the certificate since it might be trusted - // now. - cert_db->NotifyObserversCertDBChanged(cert.get()); + void (^callbackBlock)(int) = [^(int returnCode) { + // if (returnCode == NSFileHandlingPanelOKButton) { + auto cert_db = net::CertDatabase::GetInstance(); + // This forces Chromium to reload the certificate since it might be trusted + // now. + cert_db->NotifyObserversCertDBChanged(cert.get()); + // } - callback.Run(true); - // CFRelease(trust); - // [panel release]; + callback.Run(returnCode); + + [panel autorelease]; + CFRelease(trust); + CFRelease(cert_chain); + CFRelease(sec_policy); + } copy]; + + NSWindow* window = parent_window ? + parent_window->GetNativeWindow() : + NULL; + auto msg = base::SysUTF8ToNSString(message); + [panel beginSheetForWindow:window modalDelegate:nil didEndSelector:NULL contextInfo:callbackBlock trust:trust message:msg]; } } // namespace api From 4bbbcd093b7812b8658b6e585973d132576b0a47 Mon Sep 17 00:00:00 2001 From: joshaber Date: Mon, 3 Apr 2017 14:01:48 -0400 Subject: [PATCH 015/143] Handle the callback and cleanup properly --- .../api/atom_api_certificate_trust_mac.mm | 102 +++++++++++++----- 1 file changed, 73 insertions(+), 29 deletions(-) diff --git a/atom/browser/api/atom_api_certificate_trust_mac.mm b/atom/browser/api/atom_api_certificate_trust_mac.mm index d767330c94..7f14a72f50 100644 --- a/atom/browser/api/atom_api_certificate_trust_mac.mm +++ b/atom/browser/api/atom_api_certificate_trust_mac.mm @@ -17,22 +17,71 @@ #include "net/cert/x509_certificate.h" #include "net/cert/cert_database.h" -@interface Trampoline : NSObject +@interface TrustDelegate : NSObject { + @private + atom::api::ShowTrustCallback callback_; + SFCertificateTrustPanel* panel_; + scoped_refptr cert_; + SecTrustRef trust_; + CFArrayRef cert_chain_; + SecPolicyRef sec_policy_; +} -- (void)createPanelDidEnd:(NSWindow *)sheet +- (id)initWithCallback:(const atom::api::ShowTrustCallback&)callback + panel:(SFCertificateTrustPanel*)panel + cert:(const scoped_refptr&)cert + trust:(SecTrustRef)trust + certChain:(CFArrayRef)certChain + secPolicy:(SecPolicyRef)secPolicy; + +- (void)panelDidEnd:(NSWindow *)sheet returnCode:(int)returnCode - contextInfo:(void *)contextInfo; + contextInfo:(void*)contextInfo; @end -@implementation Trampoline +@implementation TrustDelegate -- (void)createPanelDidEnd:(NSWindow *)sheet +- (void)dealloc { + [panel_ release]; + CFRelease(trust_); + CFRelease(cert_chain_); + CFRelease(sec_policy_); + + [super dealloc]; +} + +- (id)initWithCallback:(const atom::api::ShowTrustCallback&)callback + panel:(SFCertificateTrustPanel*)panel + cert:(const scoped_refptr&)cert + trust:(SecTrustRef)trust + certChain:(CFArrayRef)certChain + secPolicy:(SecPolicyRef)secPolicy { + if ((self = [super init])) { + callback_ = callback; + panel_ = panel; + cert_ = cert; + trust_ = trust; + cert_chain_ = certChain; + sec_policy_ = secPolicy; + } + + return self; +} + +- (void)panelDidEnd:(NSWindow *)sheet returnCode:(int)returnCode - contextInfo:(void *)contextInfo { - void (^block)(int) = (void (^)(int))contextInfo; - block(returnCode); - [(id)block autorelease]; + contextInfo:(void*)contextInfo { + if (returnCode == NSFileHandlingPanelOKButton) { + auto cert_db = net::CertDatabase::GetInstance(); + // This forces Chromium to reload the certificate since it might be trusted + // now. + cert_db->NotifyObserversCertDBChanged(cert_.get()); + } + + callback_.Run(returnCode); + + [self autorelease]; } @end @@ -50,29 +99,24 @@ void ShowCertificateTrustUI(atom::NativeWindow* parent_window, SecTrustRef trust = nullptr; SecTrustCreateWithCertificates(cert_chain, sec_policy, &trust); - SFCertificateTrustPanel *panel = [[SFCertificateTrustPanel alloc] init]; - - void (^callbackBlock)(int) = [^(int returnCode) { - // if (returnCode == NSFileHandlingPanelOKButton) { - auto cert_db = net::CertDatabase::GetInstance(); - // This forces Chromium to reload the certificate since it might be trusted - // now. - cert_db->NotifyObserversCertDBChanged(cert.get()); - // } - - callback.Run(returnCode); - - [panel autorelease]; - CFRelease(trust); - CFRelease(cert_chain); - CFRelease(sec_policy); - } copy]; - NSWindow* window = parent_window ? parent_window->GetNativeWindow() : - NULL; + nil; auto msg = base::SysUTF8ToNSString(message); - [panel beginSheetForWindow:window modalDelegate:nil didEndSelector:NULL contextInfo:callbackBlock trust:trust message:msg]; + + SFCertificateTrustPanel *panel = [[SFCertificateTrustPanel alloc] init]; + auto delegate = [[TrustDelegate alloc] initWithCallback:callback + panel:panel + cert:cert + trust:trust + certChain:cert_chain + secPolicy:sec_policy]; + [panel beginSheetForWindow:window + modalDelegate:delegate + didEndSelector:@selector(panelDidEnd:returnCode:contextInfo:) + contextInfo:nil + trust:trust + message:msg]; } } // namespace api From 6e89cb9d7c8fe28ffb3148b518a070b12c657e8f Mon Sep 17 00:00:00 2001 From: joshaber Date: Mon, 3 Apr 2017 15:05:24 -0400 Subject: [PATCH 016/143] Move it into `dialog` --- atom/browser/api/atom_api_app.cc | 12 ------- atom/browser/api/atom_api_app.h | 10 ------ atom/browser/api/atom_api_certificate_trust.h | 34 ------------------- atom/browser/api/atom_api_dialog.cc | 15 ++++++++ atom/browser/ui/certificate_trust.h | 29 ++++++++++++++++ .../certificate_trust_mac.mm} | 25 ++++++-------- filenames.gypi | 4 +-- 7 files changed, 56 insertions(+), 73 deletions(-) delete mode 100644 atom/browser/api/atom_api_certificate_trust.h create mode 100644 atom/browser/ui/certificate_trust.h rename atom/browser/{api/atom_api_certificate_trust_mac.mm => ui/certificate_trust_mac.mm} (83%) diff --git a/atom/browser/api/atom_api_app.cc b/atom/browser/api/atom_api_app.cc index 41e7655a66..56a11daf69 100644 --- a/atom/browser/api/atom_api_app.cc +++ b/atom/browser/api/atom_api_app.cc @@ -7,7 +7,6 @@ #include #include -#include "atom/browser/api/atom_api_certificate_trust.h" #include "atom/browser/api/atom_api_menu.h" #include "atom/browser/api/atom_api_session.h" #include "atom/browser/api/atom_api_web_contents.h" @@ -811,16 +810,6 @@ void App::OnCertificateManagerModelCreated( } #endif -#if defined(OS_MACOSX) -void App::ShowCertificateTrust(atom::NativeWindow* parent_window, - const scoped_refptr& cert, - std::string message, - const ShowTrustCallback& callback, - mate::Arguments* args) { - ShowCertificateTrustUI(parent_window, cert, message, callback); -} -#endif - #if defined(OS_WIN) v8::Local App::GetJumpListSettings() { JumpList jump_list(Browser::Get()->GetAppUserModelID()); @@ -960,7 +949,6 @@ void App::BuildPrototype( base::Bind(&Browser::GetCurrentActivityType, browser)) .SetMethod("setAboutPanelOptions", base::Bind(&Browser::SetAboutPanelOptions, browser)) - .SetMethod("showCertificateTrust", &App::ShowCertificateTrust) #endif #if defined(OS_WIN) .SetMethod("setUserTasks", base::Bind(&Browser::SetUserTasks, browser)) diff --git a/atom/browser/api/atom_api_app.h b/atom/browser/api/atom_api_app.h index 19640cb848..f2debdf2e5 100644 --- a/atom/browser/api/atom_api_app.h +++ b/atom/browser/api/atom_api_app.h @@ -8,7 +8,6 @@ #include #include -#include "atom/browser/api/atom_api_certificate_trust.h" #include "atom/browser/api/event_emitter.h" #include "atom/browser/atom_browser_client.h" #include "atom/browser/browser.h" @@ -153,15 +152,6 @@ class App : public AtomBrowserClient::Delegate, std::unique_ptr certificate_manager_model_; #endif - -#if defined(OS_MACOSX) - void ShowCertificateTrust(atom::NativeWindow* parent_window, - const scoped_refptr& cert, - std::string message, - const ShowTrustCallback& callback, - mate::Arguments* args); -#endif - // Tracks tasks requesting file icons. base::CancelableTaskTracker cancelable_task_tracker_; diff --git a/atom/browser/api/atom_api_certificate_trust.h b/atom/browser/api/atom_api_certificate_trust.h deleted file mode 100644 index 1de7d653bb..0000000000 --- a/atom/browser/api/atom_api_certificate_trust.h +++ /dev/null @@ -1,34 +0,0 @@ -// Copyright (c) 2017 GitHub, Inc. -// Use of this source code is governed by the MIT license that can be -// found in the LICENSE file. - -#ifndef ATOM_BROWSER_API_ATOM_API_CERTIFICATE_TRUST_H_ -#define ATOM_BROWSER_API_ATOM_API_CERTIFICATE_TRUST_H_ - -#include - -#include "base/callback_forward.h" -#include "base/memory/ref_counted.h" - -namespace net { -class X509Certificate; -} // namespace net - -namespace atom { - -class NativeWindow; - -namespace api { - -typedef base::Callback ShowTrustCallback; - -void ShowCertificateTrustUI(atom::NativeWindow* parent_window, - const scoped_refptr& cert, - std::string message, - const ShowTrustCallback& callback); - -} // namespace api - -} // namespace atom - -#endif // ATOM_BROWSER_API_ATOM_API_CERTIFICATE_TRUST_H_ diff --git a/atom/browser/api/atom_api_dialog.cc b/atom/browser/api/atom_api_dialog.cc index 326834472d..310b1b233b 100644 --- a/atom/browser/api/atom_api_dialog.cc +++ b/atom/browser/api/atom_api_dialog.cc @@ -8,11 +8,13 @@ #include "atom/browser/api/atom_api_window.h" #include "atom/browser/native_window.h" +#include "atom/browser/ui/certificate_trust.h" #include "atom/browser/ui/file_dialog.h" #include "atom/browser/ui/message_box.h" #include "atom/common/native_mate_converters/callback.h" #include "atom/common/native_mate_converters/file_path_converter.h" #include "atom/common/native_mate_converters/image_converter.h" +#include "atom/common/native_mate_converters/net_converter.h" #include "native_mate/dictionary.h" #include "atom/common/node_includes.h" @@ -119,6 +121,16 @@ void ShowSaveDialog(const file_dialog::DialogSettings& settings, } } +// #if defined(OS_MACOSX) +void ShowCertificateTrust(atom::NativeWindow* parent_window, + const scoped_refptr& cert, + std::string message, + const certificate_trust::ShowTrustCallback& callback, + mate::Arguments* args) { + certificate_trust::ShowCertificateTrust(parent_window, cert, message, callback); +} +// #endif + void Initialize(v8::Local exports, v8::Local unused, v8::Local context, void* priv) { mate::Dictionary dict(context->GetIsolate(), exports); @@ -126,6 +138,9 @@ void Initialize(v8::Local exports, v8::Local unused, dict.SetMethod("showErrorBox", &atom::ShowErrorBox); dict.SetMethod("showOpenDialog", &ShowOpenDialog); dict.SetMethod("showSaveDialog", &ShowSaveDialog); +// #if defined(OS_MACOSX) + dict.SetMethod("showCertificateTrustDialog", &ShowCertificateTrust); +// #endif } } // namespace diff --git a/atom/browser/ui/certificate_trust.h b/atom/browser/ui/certificate_trust.h new file mode 100644 index 0000000000..30271edff0 --- /dev/null +++ b/atom/browser/ui/certificate_trust.h @@ -0,0 +1,29 @@ +// Copyright (c) 2017 GitHub, Inc. +// Use of this source code is governed by the MIT license that can be +// found in the LICENSE file. + +#ifndef ATOM_BROWSER_UI_CERTIFICATE_TRUST_H_ +#define ATOM_BROWSER_UI_CERTIFICATE_TRUST_H_ + +#include + +#include "base/callback_forward.h" +#include "base/memory/ref_counted.h" +#include "net/cert/x509_certificate.h" + +namespace atom { +class NativeWindow; +} // namespace atom + +namespace certificate_trust { + +typedef base::Callback ShowTrustCallback; + +void ShowCertificateTrust(atom::NativeWindow* parent_window, + const scoped_refptr& cert, + std::string message, + const ShowTrustCallback& callback); + +} // namespace certificate_trust + +#endif // ATOM_BROWSER_UI_CERTIFICATE_TRUST_H_ diff --git a/atom/browser/api/atom_api_certificate_trust_mac.mm b/atom/browser/ui/certificate_trust_mac.mm similarity index 83% rename from atom/browser/api/atom_api_certificate_trust_mac.mm rename to atom/browser/ui/certificate_trust_mac.mm index 7f14a72f50..a3774e51c3 100644 --- a/atom/browser/api/atom_api_certificate_trust_mac.mm +++ b/atom/browser/ui/certificate_trust_mac.mm @@ -2,7 +2,7 @@ // Use of this source code is governed by the MIT license that can be // found in the LICENSE file. -#include "atom/browser/api/atom_api_certificate_trust.h" +#include "atom/browser/ui/certificate_trust.h" #import #import @@ -14,12 +14,11 @@ #include "base/mac/mac_util.h" #include "base/mac/scoped_cftyperef.h" #include "base/strings/sys_string_conversions.h" -#include "net/cert/x509_certificate.h" #include "net/cert/cert_database.h" @interface TrustDelegate : NSObject { @private - atom::api::ShowTrustCallback callback_; + certificate_trust::ShowTrustCallback callback_; SFCertificateTrustPanel* panel_; scoped_refptr cert_; SecTrustRef trust_; @@ -27,7 +26,7 @@ SecPolicyRef sec_policy_; } -- (id)initWithCallback:(const atom::api::ShowTrustCallback&)callback +- (id)initWithCallback:(const certificate_trust::ShowTrustCallback&)callback panel:(SFCertificateTrustPanel*)panel cert:(const scoped_refptr&)cert trust:(SecTrustRef)trust @@ -51,7 +50,7 @@ [super dealloc]; } -- (id)initWithCallback:(const atom::api::ShowTrustCallback&)callback +- (id)initWithCallback:(const certificate_trust::ShowTrustCallback&)callback panel:(SFCertificateTrustPanel*)panel cert:(const scoped_refptr&)cert trust:(SecTrustRef)trust @@ -86,14 +85,12 @@ @end -namespace atom { +namespace certificate_trust { -namespace api { - -void ShowCertificateTrustUI(atom::NativeWindow* parent_window, - const scoped_refptr& cert, - std::string message, - const ShowTrustCallback& callback) { +void ShowCertificateTrust(atom::NativeWindow* parent_window, + const scoped_refptr& cert, + std::string message, + const ShowTrustCallback& callback) { auto sec_policy = SecPolicyCreateBasicX509(); auto cert_chain = cert->CreateOSCertChainForCert(); SecTrustRef trust = nullptr; @@ -119,6 +116,4 @@ void ShowCertificateTrustUI(atom::NativeWindow* parent_window, message:msg]; } -} // namespace api - -} // namespace atom +} // namespace certificate_trust diff --git a/filenames.gypi b/filenames.gypi index f2a78ad4d4..ff7bbaee4d 100644 --- a/filenames.gypi +++ b/filenames.gypi @@ -103,8 +103,6 @@ 'atom/browser/api/atom_api_app.h', 'atom/browser/api/atom_api_auto_updater.cc', 'atom/browser/api/atom_api_auto_updater.h', - 'atom/browser/api/atom_api_certificate_trust_mac.mm', - 'atom/browser/api/atom_api_certificate_trust.h', 'atom/browser/api/atom_api_content_tracing.cc', 'atom/browser/api/atom_api_cookies.cc', 'atom/browser/api/atom_api_cookies.h', @@ -281,6 +279,8 @@ 'atom/browser/ui/accelerator_util_views.cc', 'atom/browser/ui/atom_menu_model.cc', 'atom/browser/ui/atom_menu_model.h', + 'atom/browser/ui/certificate_trust_mac.mm', + 'atom/browser/ui/certificate_trust.h', 'atom/browser/ui/cocoa/atom_menu_controller.h', 'atom/browser/ui/cocoa/atom_menu_controller.mm', 'atom/browser/ui/cocoa/atom_touch_bar.h', From 4ffaf2cd99d44b8d143dcc2a4bf81e7a641144a0 Mon Sep 17 00:00:00 2001 From: joshaber Date: Mon, 3 Apr 2017 15:09:04 -0400 Subject: [PATCH 017/143] Remove old unnecssary change on `app` --- atom/browser/api/atom_api_app.h | 1 - 1 file changed, 1 deletion(-) diff --git a/atom/browser/api/atom_api_app.h b/atom/browser/api/atom_api_app.h index f2debdf2e5..8b276f334d 100644 --- a/atom/browser/api/atom_api_app.h +++ b/atom/browser/api/atom_api_app.h @@ -19,7 +19,6 @@ #include "content/public/browser/gpu_data_manager_observer.h" #include "native_mate/handle.h" #include "net/base/completion_callback.h" -#include "net/cert/x509_certificate.h" #if defined(USE_NSS_CERTS) #include "chrome/browser/certificate_manager_model.h" From bcecba20e6096e3b8ebeef3daa3a4397d201b6c3 Mon Sep 17 00:00:00 2001 From: joshaber Date: Mon, 3 Apr 2017 15:09:24 -0400 Subject: [PATCH 018/143] Fix indentation --- atom/browser/api/atom_api_dialog.cc | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/atom/browser/api/atom_api_dialog.cc b/atom/browser/api/atom_api_dialog.cc index 310b1b233b..6c6e49bb7f 100644 --- a/atom/browser/api/atom_api_dialog.cc +++ b/atom/browser/api/atom_api_dialog.cc @@ -123,10 +123,10 @@ void ShowSaveDialog(const file_dialog::DialogSettings& settings, // #if defined(OS_MACOSX) void ShowCertificateTrust(atom::NativeWindow* parent_window, - const scoped_refptr& cert, - std::string message, - const certificate_trust::ShowTrustCallback& callback, - mate::Arguments* args) { + const scoped_refptr& cert, + std::string message, + const certificate_trust::ShowTrustCallback& callback, + mate::Arguments* args) { certificate_trust::ShowCertificateTrust(parent_window, cert, message, callback); } // #endif From 0b7ffd094aace166dea48e9495d01335f732e97f Mon Sep 17 00:00:00 2001 From: joshaber Date: Mon, 3 Apr 2017 15:25:06 -0400 Subject: [PATCH 019/143] Expose through the actual JS API too --- lib/browser/api/dialog.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/lib/browser/api/dialog.js b/lib/browser/api/dialog.js index 834a6a6d7d..814a8a2af5 100644 --- a/lib/browser/api/dialog.js +++ b/lib/browser/api/dialog.js @@ -280,6 +280,10 @@ module.exports = { showErrorBox: function (...args) { return binding.showErrorBox(...args) + }, + + showCertificateTrustDialog: function (...args) { + return binding.showCertificateTrustDialog(...args) } } From 11f5c942ce70d85a573d2aa42701d9aa54329b35 Mon Sep 17 00:00:00 2001 From: joshaber Date: Mon, 3 Apr 2017 15:25:09 -0400 Subject: [PATCH 020/143] Conditionalize --- atom/browser/api/atom_api_dialog.cc | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/atom/browser/api/atom_api_dialog.cc b/atom/browser/api/atom_api_dialog.cc index 6c6e49bb7f..9a93ba7037 100644 --- a/atom/browser/api/atom_api_dialog.cc +++ b/atom/browser/api/atom_api_dialog.cc @@ -121,7 +121,7 @@ void ShowSaveDialog(const file_dialog::DialogSettings& settings, } } -// #if defined(OS_MACOSX) +#if defined(OS_MACOSX) void ShowCertificateTrust(atom::NativeWindow* parent_window, const scoped_refptr& cert, std::string message, @@ -129,7 +129,7 @@ void ShowCertificateTrust(atom::NativeWindow* parent_window, mate::Arguments* args) { certificate_trust::ShowCertificateTrust(parent_window, cert, message, callback); } -// #endif +#endif void Initialize(v8::Local exports, v8::Local unused, v8::Local context, void* priv) { @@ -138,9 +138,9 @@ void Initialize(v8::Local exports, v8::Local unused, dict.SetMethod("showErrorBox", &atom::ShowErrorBox); dict.SetMethod("showOpenDialog", &ShowOpenDialog); dict.SetMethod("showSaveDialog", &ShowSaveDialog); -// #if defined(OS_MACOSX) +#if defined(OS_MACOSX) dict.SetMethod("showCertificateTrustDialog", &ShowCertificateTrust); -// #endif +#endif } } // namespace From 06643e525a084816fab48eb13053d713358a5b95 Mon Sep 17 00:00:00 2001 From: joshaber Date: Mon, 3 Apr 2017 15:28:44 -0400 Subject: [PATCH 021/143] Const ref that message --- atom/browser/ui/certificate_trust.h | 2 +- atom/browser/ui/certificate_trust_mac.mm | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/atom/browser/ui/certificate_trust.h b/atom/browser/ui/certificate_trust.h index 30271edff0..085d04d103 100644 --- a/atom/browser/ui/certificate_trust.h +++ b/atom/browser/ui/certificate_trust.h @@ -21,7 +21,7 @@ typedef base::Callback ShowTrustCallback; void ShowCertificateTrust(atom::NativeWindow* parent_window, const scoped_refptr& cert, - std::string message, + const std::string& message, const ShowTrustCallback& callback); } // namespace certificate_trust diff --git a/atom/browser/ui/certificate_trust_mac.mm b/atom/browser/ui/certificate_trust_mac.mm index a3774e51c3..1e7ad5204f 100644 --- a/atom/browser/ui/certificate_trust_mac.mm +++ b/atom/browser/ui/certificate_trust_mac.mm @@ -89,7 +89,7 @@ namespace certificate_trust { void ShowCertificateTrust(atom::NativeWindow* parent_window, const scoped_refptr& cert, - std::string message, + const std::string& message, const ShowTrustCallback& callback) { auto sec_policy = SecPolicyCreateBasicX509(); auto cert_chain = cert->CreateOSCertChainForCert(); From b0ef7ddf44cc7f20f43f4d9cab88ded82e181cab Mon Sep 17 00:00:00 2001 From: joshaber Date: Mon, 3 Apr 2017 15:28:51 -0400 Subject: [PATCH 022/143] Use better iteration --- atom/common/native_mate_converters/net_converter.cc | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/atom/common/native_mate_converters/net_converter.cc b/atom/common/native_mate_converters/net_converter.cc index 2d3095a63e..305627ad5b 100644 --- a/atom/common/native_mate_converters/net_converter.cc +++ b/atom/common/native_mate_converters/net_converter.cc @@ -71,8 +71,7 @@ v8::Local Converter>::ToV8( dict.Set("issuerCert", issuer_cert); std::vector intermediates_encoded; - for (size_t i = 0; i < intermediates.size(); i++) { - auto native_cert = intermediates[i]; + for (auto& native_cert : intermediates) { std::string encoded; net::X509Certificate::GetPEMEncoded(native_cert, &encoded); intermediates_encoded.push_back(encoded); From da1b0aab3e157c063a7ffc2a94d714d8841261cb Mon Sep 17 00:00:00 2001 From: joshaber Date: Mon, 3 Apr 2017 15:39:45 -0400 Subject: [PATCH 023/143] Flesh out some docs --- docs/api/dialog.md | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/docs/api/dialog.md b/docs/api/dialog.md index 230930abd9..71224b69cd 100644 --- a/docs/api/dialog.md +++ b/docs/api/dialog.md @@ -175,6 +175,17 @@ it is usually used to report errors in early stage of startup. If called before the app `ready`event on Linux, the message will be emitted to stderr, and no GUI dialog will appear. +### `dialog.showCertificateTrustDialog(browserWindow, certificate, message, callback)` _macOS_ + +* `browserWindow` BrowserWindow +* `certificate` [Certificate](structures/certificate.md) - The certificate to trust/import. +* `message` String - The message to display to the user. +* `callback` Function + * `result` Boolean - Whether the user chose to cancel or continue. + +Displays a modal dialog that shows a message and certificate information, and +gives the user the option of trusting/importing the certificate. + ## Sheets On macOS, dialogs are presented as sheets attached to a window if you provide From b8ff4666c84c249b002cc6fd2aa95bc6b7db6f04 Mon Sep 17 00:00:00 2001 From: joshaber Date: Mon, 3 Apr 2017 15:48:47 -0400 Subject: [PATCH 024/143] Remove stale includes --- atom/browser/ui/certificate_trust_mac.mm | 5 ----- 1 file changed, 5 deletions(-) diff --git a/atom/browser/ui/certificate_trust_mac.mm b/atom/browser/ui/certificate_trust_mac.mm index 1e7ad5204f..32dc1ce91e 100644 --- a/atom/browser/ui/certificate_trust_mac.mm +++ b/atom/browser/ui/certificate_trust_mac.mm @@ -5,14 +5,9 @@ #include "atom/browser/ui/certificate_trust.h" #import -#import #import #include "atom/browser/native_window.h" -#include "base/files/file_util.h" -#include "base/mac/foundation_util.h" -#include "base/mac/mac_util.h" -#include "base/mac/scoped_cftyperef.h" #include "base/strings/sys_string_conversions.h" #include "net/cert/cert_database.h" From 74c0cbddaed65827268a9ad19b607b68cdbc245d Mon Sep 17 00:00:00 2001 From: joshaber Date: Mon, 3 Apr 2017 16:07:02 -0400 Subject: [PATCH 025/143] Linebreak to keep the linter happy --- atom/browser/api/atom_api_dialog.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/atom/browser/api/atom_api_dialog.cc b/atom/browser/api/atom_api_dialog.cc index 9a93ba7037..090f4c5d8a 100644 --- a/atom/browser/api/atom_api_dialog.cc +++ b/atom/browser/api/atom_api_dialog.cc @@ -127,7 +127,8 @@ void ShowCertificateTrust(atom::NativeWindow* parent_window, std::string message, const certificate_trust::ShowTrustCallback& callback, mate::Arguments* args) { - certificate_trust::ShowCertificateTrust(parent_window, cert, message, callback); + certificate_trust::ShowCertificateTrust(parent_window, cert, + message, callback); } #endif From 370cf815d9ae4ce85c13b7dc725a76e5651169d6 Mon Sep 17 00:00:00 2001 From: joshaber Date: Mon, 3 Apr 2017 16:27:53 -0400 Subject: [PATCH 026/143] Get rid of `intermediates` and rehydrate from `issuerCert` --- .../native_mate_converters/net_converter.cc | 37 ++++++------------- 1 file changed, 12 insertions(+), 25 deletions(-) diff --git a/atom/common/native_mate_converters/net_converter.cc b/atom/common/native_mate_converters/net_converter.cc index 305627ad5b..7453dd0097 100644 --- a/atom/common/native_mate_converters/net_converter.cc +++ b/atom/common/native_mate_converters/net_converter.cc @@ -59,8 +59,7 @@ v8::Local Converter>::ToV8( net::HashValue( val->CalculateFingerprint256(val->os_cert_handle())).ToString()); - auto intermediates = val->GetIntermediateCertificates(); - if (!intermediates.empty()) { + if (!val->GetIntermediateCertificates().empty()) { net::X509Certificate::OSCertHandles issuer_intermediates( val->GetIntermediateCertificates().begin() + 1, val->GetIntermediateCertificates().end()); @@ -69,15 +68,6 @@ v8::Local Converter>::ToV8( val->GetIntermediateCertificates().front(), issuer_intermediates); dict.Set("issuerCert", issuer_cert); - - std::vector intermediates_encoded; - for (auto& native_cert : intermediates) { - std::string encoded; - net::X509Certificate::GetPEMEncoded(native_cert, &encoded); - intermediates_encoded.push_back(encoded); - } - - dict.Set("intermediates", intermediates_encoded); } return dict.GetHandle(); @@ -113,24 +103,21 @@ bool Converter>::FromV8( if (!CertFromData(data, &leaf_cert)) return false; - std::vector intermediates_encoded; - dict.Get("intermediates", &intermediates_encoded); - std::vector intermediates; - for (size_t i = 0; i < intermediates_encoded.size(); i++) { - auto intermediate_data = intermediates_encoded[i]; - scoped_refptr cert; - if (!CertFromData(intermediate_data, &cert)) + scoped_refptr parent; + if (dict.Get("issuerCert", &parent)) { + auto parents = std::vector( + parent->GetIntermediateCertificates()); + parents.insert(parents.begin(), parent->os_cert_handle()); + auto cert = net::X509Certificate::CreateFromHandle( + leaf_cert->os_cert_handle(), parents); + if (!cert) return false; - intermediates.push_back(cert->os_cert_handle()); + *out = cert; + } else { + *out = leaf_cert; } - auto cert = net::X509Certificate::CreateFromHandle( - leaf_cert->os_cert_handle(), intermediates); - if (!cert) - return false; - - *out = cert; return true; } From 398132cfe383f3e8cbc3742011596fcd4dceaed9 Mon Sep 17 00:00:00 2001 From: joshaber Date: Mon, 3 Apr 2017 21:19:00 -0400 Subject: [PATCH 027/143] Fix file sorting --- filenames.gypi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/filenames.gypi b/filenames.gypi index ff7bbaee4d..192d953287 100644 --- a/filenames.gypi +++ b/filenames.gypi @@ -279,8 +279,8 @@ 'atom/browser/ui/accelerator_util_views.cc', 'atom/browser/ui/atom_menu_model.cc', 'atom/browser/ui/atom_menu_model.h', - 'atom/browser/ui/certificate_trust_mac.mm', 'atom/browser/ui/certificate_trust.h', + 'atom/browser/ui/certificate_trust_mac.mm', 'atom/browser/ui/cocoa/atom_menu_controller.h', 'atom/browser/ui/cocoa/atom_menu_controller.mm', 'atom/browser/ui/cocoa/atom_touch_bar.h', From b3e865a4787b8b0aa844c8466a0b8ca83649314c Mon Sep 17 00:00:00 2001 From: joshaber Date: Mon, 3 Apr 2017 21:22:14 -0400 Subject: [PATCH 028/143] Fix some style things --- atom/browser/ui/certificate_trust_mac.mm | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/atom/browser/ui/certificate_trust_mac.mm b/atom/browser/ui/certificate_trust_mac.mm index 32dc1ce91e..ad54eaa383 100644 --- a/atom/browser/ui/certificate_trust_mac.mm +++ b/atom/browser/ui/certificate_trust_mac.mm @@ -28,7 +28,7 @@ certChain:(CFArrayRef)certChain secPolicy:(SecPolicyRef)secPolicy; -- (void)panelDidEnd:(NSWindow *)sheet +- (void)panelDidEnd:(NSWindow*)sheet returnCode:(int)returnCode contextInfo:(void*)contextInfo; @@ -63,7 +63,7 @@ return self; } -- (void)panelDidEnd:(NSWindow *)sheet +- (void)panelDidEnd:(NSWindow*)sheet returnCode:(int)returnCode contextInfo:(void*)contextInfo { if (returnCode == NSFileHandlingPanelOKButton) { @@ -73,7 +73,7 @@ cert_db->NotifyObserversCertDBChanged(cert_.get()); } - callback_.Run(returnCode); + callback_.Run(returnCode == NSFileHandlingPanelOKButton ? true : false); [self autorelease]; } @@ -96,7 +96,7 @@ void ShowCertificateTrust(atom::NativeWindow* parent_window, nil; auto msg = base::SysUTF8ToNSString(message); - SFCertificateTrustPanel *panel = [[SFCertificateTrustPanel alloc] init]; + auto panel = [[SFCertificateTrustPanel alloc] init]; auto delegate = [[TrustDelegate alloc] initWithCallback:callback panel:panel cert:cert From 2badfbe04fbee7104317cffa7031b8fedf1191e8 Mon Sep 17 00:00:00 2001 From: joshaber Date: Mon, 3 Apr 2017 21:22:37 -0400 Subject: [PATCH 029/143] Remove the intermediate function --- atom/browser/api/atom_api_dialog.cc | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/atom/browser/api/atom_api_dialog.cc b/atom/browser/api/atom_api_dialog.cc index 090f4c5d8a..0105a433db 100644 --- a/atom/browser/api/atom_api_dialog.cc +++ b/atom/browser/api/atom_api_dialog.cc @@ -121,17 +121,6 @@ void ShowSaveDialog(const file_dialog::DialogSettings& settings, } } -#if defined(OS_MACOSX) -void ShowCertificateTrust(atom::NativeWindow* parent_window, - const scoped_refptr& cert, - std::string message, - const certificate_trust::ShowTrustCallback& callback, - mate::Arguments* args) { - certificate_trust::ShowCertificateTrust(parent_window, cert, - message, callback); -} -#endif - void Initialize(v8::Local exports, v8::Local unused, v8::Local context, void* priv) { mate::Dictionary dict(context->GetIsolate(), exports); @@ -140,7 +129,7 @@ void Initialize(v8::Local exports, v8::Local unused, dict.SetMethod("showOpenDialog", &ShowOpenDialog); dict.SetMethod("showSaveDialog", &ShowSaveDialog); #if defined(OS_MACOSX) - dict.SetMethod("showCertificateTrustDialog", &ShowCertificateTrust); + dict.SetMethod("showCertificateTrustDialog", &certificate_trust::ShowCertificateTrust); #endif } From e2bda3ca0f8cc1bf982815040df78cb952261e79 Mon Sep 17 00:00:00 2001 From: joshaber Date: Mon, 3 Apr 2017 21:33:21 -0400 Subject: [PATCH 030/143] Use an options object for most of the params --- docs/api/dialog.md | 7 ++++--- lib/browser/api/dialog.js | 19 +++++++++++++++++-- 2 files changed, 21 insertions(+), 5 deletions(-) diff --git a/docs/api/dialog.md b/docs/api/dialog.md index 71224b69cd..17aa7341bb 100644 --- a/docs/api/dialog.md +++ b/docs/api/dialog.md @@ -175,11 +175,12 @@ it is usually used to report errors in early stage of startup. If called before the app `ready`event on Linux, the message will be emitted to stderr, and no GUI dialog will appear. -### `dialog.showCertificateTrustDialog(browserWindow, certificate, message, callback)` _macOS_ +### `dialog.showCertificateTrustDialog(browserWindow, options, callback)` _macOS_ * `browserWindow` BrowserWindow -* `certificate` [Certificate](structures/certificate.md) - The certificate to trust/import. -* `message` String - The message to display to the user. +* `options` Object + * `certificate` [Certificate](structures/certificate.md) - The certificate to trust/import. + * `message` String - The message to display to the user. * `callback` Function * `result` Boolean - Whether the user chose to cancel or continue. diff --git a/lib/browser/api/dialog.js b/lib/browser/api/dialog.js index 814a8a2af5..908ffaf670 100644 --- a/lib/browser/api/dialog.js +++ b/lib/browser/api/dialog.js @@ -282,8 +282,23 @@ module.exports = { return binding.showErrorBox(...args) }, - showCertificateTrustDialog: function (...args) { - return binding.showCertificateTrustDialog(...args) + showCertificateTrustDialog: function (window, options, callback) { + if (options == null || typeof options !== 'object') { + throw new TypeError('options must be an object') + } + + let {certificate, message} = options + if (certificate == null || typeof options !== 'object') { + throw new TypeError('certificate must be an object') + } + + if (message == null) { + message = '' + } else if (typeof message !== 'string') { + throw new TypeError('message must be a string') + } + + return binding.showCertificateTrustDialog(window, certificate, message, callback) } } From 8d465234e40e601e215220270e5c11eec8469276 Mon Sep 17 00:00:00 2001 From: joshaber Date: Mon, 3 Apr 2017 21:40:46 -0400 Subject: [PATCH 031/143] Appease our linty overlords --- atom/browser/api/atom_api_dialog.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/atom/browser/api/atom_api_dialog.cc b/atom/browser/api/atom_api_dialog.cc index 0105a433db..4f152e3602 100644 --- a/atom/browser/api/atom_api_dialog.cc +++ b/atom/browser/api/atom_api_dialog.cc @@ -129,7 +129,8 @@ void Initialize(v8::Local exports, v8::Local unused, dict.SetMethod("showOpenDialog", &ShowOpenDialog); dict.SetMethod("showSaveDialog", &ShowSaveDialog); #if defined(OS_MACOSX) - dict.SetMethod("showCertificateTrustDialog", &certificate_trust::ShowCertificateTrust); + dict.SetMethod("showCertificateTrustDialog", + &certificate_trust::ShowCertificateTrust); #endif } From 6169ccd1e2b4595e083b7a3d38281ed4db638772 Mon Sep 17 00:00:00 2001 From: Philip Jackson Date: Tue, 4 Apr 2017 18:00:20 +1200 Subject: [PATCH 032/143] :memo: Document that setApplicationMenu(null) has no effect on macOS --- docs/api/menu.md | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/docs/api/menu.md b/docs/api/menu.md index 13585fef72..72d8164270 100644 --- a/docs/api/menu.md +++ b/docs/api/menu.md @@ -16,9 +16,11 @@ The `menu` class has the following static methods: * `menu` Menu -Sets `menu` as the application menu on macOS. On Windows and Linux, the `menu` -will be set as each window's top menu. Setting it to `null` will remove the -menu bar. +Sets `menu` as the application menu on macOS. On Windows and Linux, the +`menu` will be set as each window's top menu. + +Passing `null` will remove the menu bar on Windows and Linux but has no +effect on macOS. **Note:** This API has to be called after the `ready` event of `app` module. From 568454525db8dbbde99b240cdfd264625e10bce8 Mon Sep 17 00:00:00 2001 From: Milan Burda Date: Tue, 4 Apr 2017 00:35:39 +0200 Subject: [PATCH 033/143] Use point / size / rectangle structures consistently in API docs --- docs/api/browser-window.md | 4 +--- docs/api/desktop-capturer.md | 5 ++--- docs/api/native-image.md | 11 ++--------- docs/api/screen.md | 9 ++------- docs/api/structures/display.md | 8 ++------ docs/api/structures/point.md | 4 ++++ docs/api/structures/size.md | 4 ++++ docs/api/tray.md | 4 +--- docs/api/web-contents.md | 26 +++++++------------------- 9 files changed, 25 insertions(+), 50 deletions(-) create mode 100644 docs/api/structures/point.md create mode 100644 docs/api/structures/size.md diff --git a/docs/api/browser-window.md b/docs/api/browser-window.md index 01f5431ecf..ee46a3fa03 100644 --- a/docs/api/browser-window.md +++ b/docs/api/browser-window.md @@ -682,10 +682,8 @@ Returns `Boolean` - Whether the window is in fullscreen mode. * `aspectRatio` Float - The aspect ratio to maintain for some portion of the content view. -* `extraSize` Object (optional) - The extra size not to be included while +* `extraSize` [Size](structures/size.md) - The extra size not to be included while maintaining the aspect ratio. - * `width` Integer - * `height` Integer This will make a window maintain an aspect ratio. The extra size allows a developer to have space, specified in pixels, not included within the aspect diff --git a/docs/api/desktop-capturer.md b/docs/api/desktop-capturer.md index f552753445..00542f402f 100644 --- a/docs/api/desktop-capturer.md +++ b/docs/api/desktop-capturer.md @@ -60,9 +60,8 @@ The `desktopCapturer` module has the following methods: * `options` Object * `types` String[] - An array of Strings that lists the types of desktop sources to be captured, available types are `screen` and `window`. - * `thumbnailSize` Object (optional) - The size that the media source thumbnail should be scaled to. - * `width` Integer - Default is `150` - * `height` Integer - Default is `150` + * `thumbnailSize` [Size](structures/size.md) (optional) - The size that the media source thumbnail + should be scaled to. Default is `150` x `150`. * `callback` Function * `error` Error * `sources` [DesktopCapturerSource[]](structures/desktop-capturer-source.md) diff --git a/docs/api/native-image.md b/docs/api/native-image.md index 100fb0e1a2..da496436b3 100644 --- a/docs/api/native-image.md +++ b/docs/api/native-image.md @@ -219,10 +219,7 @@ Returns `Boolean` - Whether the image is empty. #### `image.getSize()` -Returns `Object`: - -* `width` Integer -* `height` Integer +Returns [`Size`](structures/size.md) #### `image.setTemplateImage(option)` @@ -236,11 +233,7 @@ Returns `Boolean` - Whether the image is a template image. #### `image.crop(rect)` -* `rect` Object - The area of the image to crop - * `x` Integer - * `y` Integer - * `width` Integer - * `height` Integer +* `rect` [Rectangle](structures/rectangle.md) - The area of the image to crop Returns `NativeImage` - The cropped image. diff --git a/docs/api/screen.md b/docs/api/screen.md index 9704f88134..49f0d9f55c 100644 --- a/docs/api/screen.md +++ b/docs/api/screen.md @@ -91,10 +91,7 @@ The `screen` module has the following methods: ### `screen.getCursorScreenPoint()` -Returns `Object`: - -* `x` Integer -* `y` Integer +Returns [`Point`](structures/point.md) The current absolute position of the mouse pointer. @@ -108,9 +105,7 @@ Returns [`Display[]`](structures/display.md) - An array of displays that are cur ### `screen.getDisplayNearestPoint(point)` -* `point` Object - * `x` Integer - * `y` Integer +* `point` [Point](structures/point.md) Returns [`Display`](structures/display.md) - The display nearest the specified point. diff --git a/docs/api/structures/display.md b/docs/api/structures/display.md index d702b35a1b..f5f5b9866b 100644 --- a/docs/api/structures/display.md +++ b/docs/api/structures/display.md @@ -6,13 +6,9 @@ * `scaleFactor` Number - Output device's pixel scale factor. * `touchSupport` String - Can be `available`, `unavailable`, `unknown`. * `bounds` [Rectangle](rectangle.md) -* `size` Object - * `height` Number - * `width` Number +* `size` [Size](size.md) * `workArea` [Rectangle](rectangle.md) -* `workAreaSize` Object - * `height` Number - * `width` Number +* `workAreaSize` [Size](size.md) The `Display` object represents a physical display connected to the system. A fake `Display` may exist on a headless system, or a `Display` may correspond to diff --git a/docs/api/structures/point.md b/docs/api/structures/point.md new file mode 100644 index 0000000000..69b87cbdf9 --- /dev/null +++ b/docs/api/structures/point.md @@ -0,0 +1,4 @@ +# Point Object + +* `x` Number +* `y` Number diff --git a/docs/api/structures/size.md b/docs/api/structures/size.md new file mode 100644 index 0000000000..1d9c8b1f5a --- /dev/null +++ b/docs/api/structures/size.md @@ -0,0 +1,4 @@ +# Size Object + +* `width` Number +* `height` Number diff --git a/docs/api/tray.md b/docs/api/tray.md index 0be9702986..141b24bbbf 100644 --- a/docs/api/tray.md +++ b/docs/api/tray.md @@ -219,9 +219,7 @@ Displays a tray balloon. #### `tray.popUpContextMenu([menu, position])` _macOS_ _Windows_ * `menu` Menu (optional) -* `position` Object (optional) - The pop up position. - * `x` Integer - * `y` Integer +* `position` [Point](structures/point.md) (optional) - The pop up position. Pops up the context menu of the tray icon. When `menu` is passed, the `menu` will be shown instead of the tray icon's context menu. diff --git a/docs/api/web-contents.md b/docs/api/web-contents.md index 87530234a2..98b1cbd2f2 100644 --- a/docs/api/web-contents.md +++ b/docs/api/web-contents.md @@ -375,12 +375,8 @@ Returns: * `type` String * `image` NativeImage (optional) * `scale` Float (optional) - scaling factor for the custom cursor -* `size` Object (optional) - the size of the `image` - * `width` Integer - * `height` Integer -* `hotspot` Object (optional) - coordinates of the custom cursor's hotspot - * `x` Integer - x coordinate - * `y` Integer - y coordinate +* `size` [Size](structures/size.md) (optional) - the size of the `image` +* `hotspot` [Point](structures/point.md) (optional) - coordinates of the custom cursor's hotspot Emitted when the cursor's type changes. The `type` parameter can be `default`, `crosshair`, `pointer`, `text`, `wait`, `help`, `e-resize`, `n-resize`, @@ -1067,24 +1063,16 @@ app.on('ready', () => { (default: `desktop`) * `desktop` - Desktop screen type * `mobile` - Mobile screen type - * `screenSize` Object - Set the emulated screen size (screenPosition == mobile) - * `width` Integer - Set the emulated screen width - * `height` Integer - Set the emulated screen height - * `viewPosition` Object - Position the view on the screen + * `screenSize` [Size](structures/size.md) - Set the emulated screen size (screenPosition == mobile) + * `viewPosition` [Point](structures/point.md) - Position the view on the screen (screenPosition == mobile) (default: `{x: 0, y: 0}`) - * `x` Integer - Set the x axis offset from top left corner - * `y` Integer - Set the y axis offset from top left corner * `deviceScaleFactor` Integer - Set the device scale factor (if zero defaults to original device scale factor) (default: `0`) - * `viewSize` Object - Set the emulated view size (empty means no override) - * `width` Integer - Set the emulated view width - * `height` Integer - Set the emulated view height + * `viewSize` [Size](structures/size.md) - Set the emulated view size (empty means no override) * `fitToView` Boolean - Whether emulated view should be scaled down if necessary to fit into available space (default: `false`) - * `offset` Object - Offset of the emulated view inside available space (not in - fit to view mode) (default: `{x: 0, y: 0}`) - * `x` Float - Set the x axis offset from top left corner - * `y` Float - Set the y axis offset from top left corner + * `offset` [Point](structures/point.md) - Offset of the emulated view inside available space + (not in fit to view mode) (default: `{x: 0, y: 0}`) * `scale` Float - Scale of emulated view inside available space (not in fit to view mode) (default: `1`) From 0cab8a3322450465f70e60b00178af4c8b7d0e07 Mon Sep 17 00:00:00 2001 From: joshaber Date: Tue, 4 Apr 2017 09:19:23 -0400 Subject: [PATCH 034/143] Put CertFromData in an anon namespace --- .../native_mate_converters/net_converter.cc | 38 ++++++++++--------- 1 file changed, 21 insertions(+), 17 deletions(-) diff --git a/atom/common/native_mate_converters/net_converter.cc b/atom/common/native_mate_converters/net_converter.cc index 7453dd0097..401cd5328c 100644 --- a/atom/common/native_mate_converters/net_converter.cc +++ b/atom/common/native_mate_converters/net_converter.cc @@ -26,6 +26,27 @@ namespace mate { +namespace { + +bool CertFromData(const std::string& data, + scoped_refptr* out) { + auto cert_list = net::X509Certificate::CreateCertificateListFromBytes( + data.c_str(), data.length(), + net::X509Certificate::FORMAT_SINGLE_CERTIFICATE); + if (cert_list.empty()) + return false; + + auto leaf_cert = cert_list.front(); + if (!leaf_cert) + return false; + + *out = leaf_cert; + + return true; +} + +} + // static v8::Local Converter::ToV8( v8::Isolate* isolate, const net::AuthChallengeInfo* val) { @@ -73,23 +94,6 @@ v8::Local Converter>::ToV8( return dict.GetHandle(); } -bool CertFromData(const std::string& data, - scoped_refptr* out) { - auto cert_list = net::X509Certificate::CreateCertificateListFromBytes( - data.c_str(), data.length(), - net::X509Certificate::FORMAT_SINGLE_CERTIFICATE); - if (cert_list.empty()) - return false; - - auto leaf_cert = cert_list.front(); - if (!leaf_cert) - return false; - - *out = leaf_cert; - - return true; -} - bool Converter>::FromV8( v8::Isolate* isolate, v8::Local val, scoped_refptr* out) { From 146e1ed3ce5a4e8eac8f2dfd95f9e221f90a329f Mon Sep 17 00:00:00 2001 From: joshaber Date: Tue, 4 Apr 2017 09:21:15 -0400 Subject: [PATCH 035/143] Don't pass the result through It's meaningless on macOS, at least. --- atom/browser/ui/certificate_trust.h | 2 +- atom/browser/ui/certificate_trust_mac.mm | 12 +++++------- docs/api/dialog.md | 1 - 3 files changed, 6 insertions(+), 9 deletions(-) diff --git a/atom/browser/ui/certificate_trust.h b/atom/browser/ui/certificate_trust.h index 085d04d103..7cbf31ea41 100644 --- a/atom/browser/ui/certificate_trust.h +++ b/atom/browser/ui/certificate_trust.h @@ -17,7 +17,7 @@ class NativeWindow; namespace certificate_trust { -typedef base::Callback ShowTrustCallback; +typedef base::Callback ShowTrustCallback; void ShowCertificateTrust(atom::NativeWindow* parent_window, const scoped_refptr& cert, diff --git a/atom/browser/ui/certificate_trust_mac.mm b/atom/browser/ui/certificate_trust_mac.mm index ad54eaa383..e0888dd3ea 100644 --- a/atom/browser/ui/certificate_trust_mac.mm +++ b/atom/browser/ui/certificate_trust_mac.mm @@ -66,14 +66,12 @@ - (void)panelDidEnd:(NSWindow*)sheet returnCode:(int)returnCode contextInfo:(void*)contextInfo { - if (returnCode == NSFileHandlingPanelOKButton) { - auto cert_db = net::CertDatabase::GetInstance(); - // This forces Chromium to reload the certificate since it might be trusted - // now. - cert_db->NotifyObserversCertDBChanged(cert_.get()); - } + auto cert_db = net::CertDatabase::GetInstance(); + // This forces Chromium to reload the certificate since it might be trusted + // now. + cert_db->NotifyObserversCertDBChanged(cert_.get()); - callback_.Run(returnCode == NSFileHandlingPanelOKButton ? true : false); + callback_.Run(); [self autorelease]; } diff --git a/docs/api/dialog.md b/docs/api/dialog.md index 17aa7341bb..58bbd05084 100644 --- a/docs/api/dialog.md +++ b/docs/api/dialog.md @@ -182,7 +182,6 @@ and no GUI dialog will appear. * `certificate` [Certificate](structures/certificate.md) - The certificate to trust/import. * `message` String - The message to display to the user. * `callback` Function - * `result` Boolean - Whether the user chose to cancel or continue. Displays a modal dialog that shows a message and certificate information, and gives the user the option of trusting/importing the certificate. From 736d6afe730d297f58eca96df367676d7c6b013f Mon Sep 17 00:00:00 2001 From: joshaber Date: Tue, 4 Apr 2017 09:23:30 -0400 Subject: [PATCH 036/143] As you wish linter --- atom/common/native_mate_converters/net_converter.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/atom/common/native_mate_converters/net_converter.cc b/atom/common/native_mate_converters/net_converter.cc index 401cd5328c..b78bc5b8e1 100644 --- a/atom/common/native_mate_converters/net_converter.cc +++ b/atom/common/native_mate_converters/net_converter.cc @@ -45,7 +45,7 @@ bool CertFromData(const std::string& data, return true; } -} +} // namespace // static v8::Local Converter::ToV8( From 2749ded062c820e0680d802698a67eb82c8eab51 Mon Sep 17 00:00:00 2001 From: joshaber Date: Tue, 4 Apr 2017 11:45:27 -0400 Subject: [PATCH 037/143] Fix c&p error --- lib/browser/api/dialog.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/browser/api/dialog.js b/lib/browser/api/dialog.js index 908ffaf670..215d3f25dd 100644 --- a/lib/browser/api/dialog.js +++ b/lib/browser/api/dialog.js @@ -288,7 +288,7 @@ module.exports = { } let {certificate, message} = options - if (certificate == null || typeof options !== 'object') { + if (certificate == null || typeof certificate !== 'object') { throw new TypeError('certificate must be an object') } From 2e32525e8f041056c10c908c80f55e1d56f2b426 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Tue, 4 Apr 2017 10:49:10 -0700 Subject: [PATCH 038/143] Make browser window optional --- docs/api/dialog.md | 7 +++++-- lib/browser/api/dialog.js | 4 +++- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/docs/api/dialog.md b/docs/api/dialog.md index 58bbd05084..6515a0feb9 100644 --- a/docs/api/dialog.md +++ b/docs/api/dialog.md @@ -175,9 +175,9 @@ it is usually used to report errors in early stage of startup. If called before the app `ready`event on Linux, the message will be emitted to stderr, and no GUI dialog will appear. -### `dialog.showCertificateTrustDialog(browserWindow, options, callback)` _macOS_ +### `dialog.showCertificateTrustDialog([browserWindow, ]options, callback)` _macOS_ -* `browserWindow` BrowserWindow +* `browserWindow` BrowserWindow (optional) * `options` Object * `certificate` [Certificate](structures/certificate.md) - The certificate to trust/import. * `message` String - The message to display to the user. @@ -186,6 +186,9 @@ and no GUI dialog will appear. Displays a modal dialog that shows a message and certificate information, and gives the user the option of trusting/importing the certificate. +The `browserWindow` argument allows the dialog to attach itself to a parent +window, making it modal. + ## Sheets On macOS, dialogs are presented as sheets attached to a window if you provide diff --git a/lib/browser/api/dialog.js b/lib/browser/api/dialog.js index 215d3f25dd..9644618047 100644 --- a/lib/browser/api/dialog.js +++ b/lib/browser/api/dialog.js @@ -282,7 +282,9 @@ module.exports = { return binding.showErrorBox(...args) }, - showCertificateTrustDialog: function (window, options, callback) { + showCertificateTrustDialog: function (...args) { + let [window, options, callback] = parseArgs(...args) + if (options == null || typeof options !== 'object') { throw new TypeError('options must be an object') } From 2bd47eb67262a79016edb2c9aef220ee766ba607 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Tue, 4 Apr 2017 10:49:21 -0700 Subject: [PATCH 039/143] Add specs for showCertificateTrustDialog option errors --- spec/api-dialog-spec.js | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/spec/api-dialog-spec.js b/spec/api-dialog-spec.js index 6b245c2b65..601e28ca53 100644 --- a/spec/api-dialog-spec.js +++ b/spec/api-dialog-spec.js @@ -93,4 +93,20 @@ describe('dialog module', () => { }, /Error processing argument at index 1/) }) }) + + describe('showCertificateTrustDialog', () => { + it('throws errors when the options are invalid', () => { + assert.throws(() => { + dialog.showCertificateTrustDialog() + }, /options must be an object/) + + assert.throws(() => { + dialog.showCertificateTrustDialog({}) + }, /certificate must be an object/) + + assert.throws(() => { + dialog.showCertificateTrustDialog({certificate: {}, message: false}) + }, /message must be a string/) + }) + }) }) From e5f70f90a40e1202e49df96fcc5f45a676e0bd62 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Mon, 3 Apr 2017 14:17:16 -0700 Subject: [PATCH 040/143] Add spec for remote setter with remote object --- spec/api-ipc-spec.js | 8 ++++++++ spec/fixtures/module/remote-object-set.js | 11 +++++++++++ 2 files changed, 19 insertions(+) create mode 100644 spec/fixtures/module/remote-object-set.js diff --git a/spec/api-ipc-spec.js b/spec/api-ipc-spec.js index c5e38e83e4..798c26d87a 100644 --- a/spec/api-ipc-spec.js +++ b/spec/api-ipc-spec.js @@ -199,6 +199,14 @@ describe('ipc module', function () { }, /setting error/) }) + it('can set a remote property with a remote object', function () { + const foo = remote.require(path.join(fixtures, 'module', 'remote-object-set.js')) + + assert.doesNotThrow(function () { + foo.bar = remote.getCurrentWindow() + }) + }) + it('can construct an object from its member', function () { var call = remote.require(path.join(fixtures, 'module', 'call.js')) var obj = new call.constructor() diff --git a/spec/fixtures/module/remote-object-set.js b/spec/fixtures/module/remote-object-set.js new file mode 100644 index 0000000000..5fefbf5cf3 --- /dev/null +++ b/spec/fixtures/module/remote-object-set.js @@ -0,0 +1,11 @@ +const {BrowserWindow} = require('electron') + +class Foo { + set bar (value) { + if (!(value instanceof BrowserWindow)) { + throw new Error('setting error') + } + } +} + +module.exports = new Foo() From 7065123266ec17d709348185c699d07a1f5555f1 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Mon, 3 Apr 2017 14:18:04 -0700 Subject: [PATCH 041/143] Wrap remote value being set as an arg --- lib/browser/rpc-server.js | 5 +++-- lib/renderer/api/remote.js | 3 ++- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/lib/browser/rpc-server.js b/lib/browser/rpc-server.js index 13d6f882c2..3da059079a 100644 --- a/lib/browser/rpc-server.js +++ b/lib/browser/rpc-server.js @@ -360,9 +360,10 @@ ipcMain.on('ELECTRON_BROWSER_MEMBER_CALL', function (event, id, method, args) { } }) -ipcMain.on('ELECTRON_BROWSER_MEMBER_SET', function (event, id, name, value) { +ipcMain.on('ELECTRON_BROWSER_MEMBER_SET', function (event, id, name, args) { try { - let obj = objectsRegistry.get(id) + const [value] = unwrapArgs(event.sender, args) + const obj = objectsRegistry.get(id) if (obj == null) { throwRPCError(`Cannot set property '${name}' on missing remote object ${id}`) diff --git a/lib/renderer/api/remote.js b/lib/renderer/api/remote.js index f65d61790a..5e790133d3 100644 --- a/lib/renderer/api/remote.js +++ b/lib/renderer/api/remote.js @@ -139,7 +139,8 @@ const setObjectMembers = function (ref, object, metaId, members) { // Only set setter when it is writable. if (member.writable) { descriptor.set = function (value) { - const meta = ipcRenderer.sendSync('ELECTRON_BROWSER_MEMBER_SET', metaId, member.name, value) + const args = wrapArgs([value]) + const meta = ipcRenderer.sendSync('ELECTRON_BROWSER_MEMBER_SET', metaId, member.name, args) // Meta will be non-null when a setter error occurred so parse it // to a value so it gets re-thrown. if (meta != null) { From 746f636016e2cafb8ea05d08d6632066eb30fb5a Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Mon, 3 Apr 2017 14:26:39 -0700 Subject: [PATCH 042/143] Add tests for setting remote property null/undefined --- spec/api-ipc-spec.js | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/spec/api-ipc-spec.js b/spec/api-ipc-spec.js index 798c26d87a..fb4278d180 100644 --- a/spec/api-ipc-spec.js +++ b/spec/api-ipc-spec.js @@ -175,8 +175,14 @@ describe('ipc module', function () { it('can change its properties', function () { var property = remote.require(path.join(fixtures, 'module', 'property.js')) assert.equal(property.property, 1127) + + property.property = null + assert.equal(property.property, null) + property.property = undefined + assert.equal(property.property, undefined) property.property = 1007 assert.equal(property.property, 1007) + assert.equal(property.getFunctionProperty(), 'foo-browser') property.func.property = 'bar' assert.equal(property.getFunctionProperty(), 'bar-browser') From fdd36334e5ae949ce4c92b7395a748cb46788d48 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Mon, 3 Apr 2017 14:30:21 -0700 Subject: [PATCH 043/143] Match args style of other IPC handlers --- lib/browser/rpc-server.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/browser/rpc-server.js b/lib/browser/rpc-server.js index 3da059079a..8d543f2d7d 100644 --- a/lib/browser/rpc-server.js +++ b/lib/browser/rpc-server.js @@ -362,14 +362,14 @@ ipcMain.on('ELECTRON_BROWSER_MEMBER_CALL', function (event, id, method, args) { ipcMain.on('ELECTRON_BROWSER_MEMBER_SET', function (event, id, name, args) { try { - const [value] = unwrapArgs(event.sender, args) - const obj = objectsRegistry.get(id) + args = unwrapArgs(event.sender, args) + let obj = objectsRegistry.get(id) if (obj == null) { throwRPCError(`Cannot set property '${name}' on missing remote object ${id}`) } - obj[name] = value + obj[name] = args[0] event.returnValue = null } catch (error) { event.returnValue = exceptionToMeta(error) From 4d6b0fc01b471adf7529f6e3bb60cb2a3e96759e Mon Sep 17 00:00:00 2001 From: Samuel Attard Date: Mon, 27 Mar 2017 11:22:52 +1100 Subject: [PATCH 044/143] Add a method to set the escape identifier on the touch bar --- atom/browser/api/atom_api_window.cc | 5 +++++ atom/browser/api/atom_api_window.h | 1 + atom/browser/native_window.cc | 3 +++ atom/browser/native_window.h | 1 + atom/browser/native_window_mac.h | 1 + atom/browser/native_window_mac.mm | 9 +++++++++ atom/browser/ui/cocoa/atom_touch_bar.h | 2 ++ atom/browser/ui/cocoa/atom_touch_bar.mm | 18 ++++++++++++++++++ docs/api/touch-bar.md | 13 ++++++++++++- lib/browser/api/touch-bar.js | 14 ++++++++++++++ 10 files changed, 66 insertions(+), 1 deletion(-) diff --git a/atom/browser/api/atom_api_window.cc b/atom/browser/api/atom_api_window.cc index 6748c9c0dd..f64b040827 100644 --- a/atom/browser/api/atom_api_window.cc +++ b/atom/browser/api/atom_api_window.cc @@ -853,6 +853,10 @@ void Window::RefreshTouchBarItem(const std::string& item_id) { window_->RefreshTouchBarItem(item_id); } +void Window::SetEscapeTouchBarItem(const mate::PersistentDictionary item) { + window_->SetEscapeTouchBarItem(item); +} + int32_t Window::ID() const { return weak_map_id(); } @@ -975,6 +979,7 @@ void Window::BuildPrototype(v8::Isolate* isolate, .SetMethod("setVibrancy", &Window::SetVibrancy) .SetMethod("_setTouchBarItems", &Window::SetTouchBar) .SetMethod("_refreshTouchBarItem", &Window::RefreshTouchBarItem) + .SetMethod("_setEscapeTouchBarItem", &Window::SetEscapeTouchBarItem) #if defined(OS_WIN) .SetMethod("hookWindowMessage", &Window::HookWindowMessage) .SetMethod("isWindowMessageHooked", &Window::IsWindowMessageHooked) diff --git a/atom/browser/api/atom_api_window.h b/atom/browser/api/atom_api_window.h index f30baf79d4..c7b6a37265 100644 --- a/atom/browser/api/atom_api_window.h +++ b/atom/browser/api/atom_api_window.h @@ -208,6 +208,7 @@ class Window : public mate::TrackableObject, void SetVibrancy(mate::Arguments* args); void SetTouchBar(const std::vector& items); void RefreshTouchBarItem(const std::string& item_id); + void SetEscapeTouchBarItem(const mate::PersistentDictionary item); v8::Local WebContents(v8::Isolate* isolate); diff --git a/atom/browser/native_window.cc b/atom/browser/native_window.cc index 90a823f80b..4866e4294c 100644 --- a/atom/browser/native_window.cc +++ b/atom/browser/native_window.cc @@ -347,6 +347,9 @@ void NativeWindow::SetTouchBar( void NativeWindow::RefreshTouchBarItem(const std::string& item_id) { } +void NativeWindow::SetEscapeTouchBarItem(const mate::PersistentDictionary item) { +} + void NativeWindow::FocusOnWebView() { web_contents()->GetRenderViewHost()->GetWidget()->Focus(); } diff --git a/atom/browser/native_window.h b/atom/browser/native_window.h index 941f5849a6..3de57895e5 100644 --- a/atom/browser/native_window.h +++ b/atom/browser/native_window.h @@ -174,6 +174,7 @@ class NativeWindow : public base::SupportsUserData, virtual void SetTouchBar( const std::vector& items); virtual void RefreshTouchBarItem(const std::string& item_id); + virtual void SetEscapeTouchBarItem(const mate::PersistentDictionary item); // Webview APIs. virtual void FocusOnWebView(); diff --git a/atom/browser/native_window_mac.h b/atom/browser/native_window_mac.h index bd34993fb1..80ae8895aa 100644 --- a/atom/browser/native_window_mac.h +++ b/atom/browser/native_window_mac.h @@ -103,6 +103,7 @@ class NativeWindowMac : public NativeWindow, void SetTouchBar( const std::vector& items) override; void RefreshTouchBarItem(const std::string& item_id) override; + void SetEscapeTouchBarItem(const mate::PersistentDictionary item) override; // content::RenderWidgetHost::InputEventObserver: void OnInputEvent(const blink::WebInputEvent& event) override; diff --git a/atom/browser/native_window_mac.mm b/atom/browser/native_window_mac.mm index 621e786ddc..7cbb8e2dff 100644 --- a/atom/browser/native_window_mac.mm +++ b/atom/browser/native_window_mac.mm @@ -410,6 +410,11 @@ enum { return nil; } +-(void)setEscapeTouchBarItem:(mate::PersistentDictionary)item { + if (self.touchBar && atom_touch_bar_) + [atom_touch_bar_ setEscapeTouchBarItem:item forTouchBar:self.touchBar]; +} + // NSWindow overrides. - (void)swipeWithEvent:(NSEvent *)event { @@ -1417,6 +1422,10 @@ void NativeWindowMac::RefreshTouchBarItem(const std::string& item_id) { [window_ refreshTouchBarItem:item_id]; } +void NativeWindowMac::SetEscapeTouchBarItem(const mate::PersistentDictionary item) { + [window_ setEscapeTouchBarItem:item]; +} + void NativeWindowMac::OnInputEvent(const blink::WebInputEvent& event) { switch (event.type) { case blink::WebInputEvent::GestureScrollBegin: diff --git a/atom/browser/ui/cocoa/atom_touch_bar.h b/atom/browser/ui/cocoa/atom_touch_bar.h index 29cdf79b25..8232e56f0a 100644 --- a/atom/browser/ui/cocoa/atom_touch_bar.h +++ b/atom/browser/ui/cocoa/atom_touch_bar.h @@ -31,6 +31,8 @@ - (NSTouchBar*)touchBarFromItemIdentifiers:(NSMutableArray*)items; - (NSMutableArray*)identifiersFromSettings:(const std::vector&)settings; - (void)refreshTouchBarItem:(NSTouchBar*)touchBar id:(const std::string&)item_id; +- (void)addNonDefaultTouchBarItems:(std::vector)items; +- (void)setEscapeTouchBarItem:(mate::PersistentDictionary)item forTouchBar:(NSTouchBar*)touchBar; - (NSString*)idFromIdentifier:(NSString*)identifier withPrefix:(NSString*)prefix; diff --git a/atom/browser/ui/cocoa/atom_touch_bar.mm b/atom/browser/ui/cocoa/atom_touch_bar.mm index 69926684b6..c12434467e 100644 --- a/atom/browser/ui/cocoa/atom_touch_bar.mm +++ b/atom/browser/ui/cocoa/atom_touch_bar.mm @@ -145,7 +145,25 @@ static NSString* const ImageScrubberItemIdentifier = @"scrubber.image.item"; } else if (item_type == "scrubber") { [self updateScrubber:(NSCustomTouchBarItem*)item withSettings:settings]; } +} +- (void)addNonDefaultTouchBarItems:(std::vector)items { + [self identifiersFromSettings:items]; +} + +- (void)setEscapeTouchBarItem:(mate::PersistentDictionary)item forTouchBar:(NSTouchBar*)touchBar { + std::string type; + std::string item_id; + NSTouchBarItemIdentifier identifier = nil; + if (item.Get("type", &type) && item.Get("id", &item_id)) { + identifier = [self identifierFromID:item_id type:type]; + } + if (identifier) { + [self addNonDefaultTouchBarItems:{ item }]; + touchBar.escapeKeyReplacementItemIdentifier = identifier; + } else { + touchBar.escapeKeyReplacementItemIdentifier = nil; + } } - (void)buttonAction:(id)sender { diff --git a/docs/api/touch-bar.md b/docs/api/touch-bar.md index 7eb2eb0209..d5496b8b3f 100644 --- a/docs/api/touch-bar.md +++ b/docs/api/touch-bar.md @@ -6,7 +6,7 @@ Process: [Main](../tutorial/quick-start.md#main-process) ### `new TouchBar(items)` _Experimental_ -* `items` ([TouchBarButton](touch-bar-button.md) | [TouchBarColorPicker](touch-bar-color-picker.md) | [TouchBarGroup](touch-bar-group.md) | [TouchBarLabel](touch-bar-label.md) | [TouchBarPopover](touch-bar-popover.md) | [TouchBarSlider](touch-bar-slider.md) | [TouchBarSpacer](touch-bar-spacer.md))[] +* `items` ([TouchBarButton](touch-bar-button.md) | [TouchBarColorPicker](touch-bar-color-picker.md) | [TouchBarGroup](touch-bar-group.md) | [TouchBarLabel](touch-bar-label.md) | [TouchBarPopover](touch-bar-popover.md) | [TouchBarScrubber](touch-bar-scrubber.md) | [TouchBarSegmentedControl](touch-bar-segmented-control.md) | [TouchBarSlider](touch-bar-slider.md) | [TouchBarSpacer](touch-bar-spacer.md))[] Creates a new touch bar with the specified items. Use `BrowserWindow.setTouchBar` to add the `TouchBar` to a window. @@ -14,6 +14,17 @@ Creates a new touch bar with the specified items. Use **Note:** The TouchBar API is currently experimental and may change or be removed in future Electron releases. +### Instance Methods + +The following methods are available on instances of `TouchBar`: + +#### `touchBar.replaceEscapeItem([touchBarItem])` + +* `touchBarItem` (TouchBarButton | TouchBarColorPicker | TouchBarGroup | TouchBarLabel | TouchBarPopover | TouchBarScrubber | TouchBarSegmentedControl | TouchBarSlider | TouchBarSpacer) - (Optional) The touch bar item to replace the escape button with + +Replaces the "esc" button on the touchbar with the given TouchBarItem, if `touchBarItem` is not provided or is falsey the button is reset +to the "esc" button automatically. + ## Examples Below is an example of a simple slot machine touch bar game with a button diff --git a/lib/browser/api/touch-bar.js b/lib/browser/api/touch-bar.js index 74951edbac..68cd623861 100644 --- a/lib/browser/api/touch-bar.js +++ b/lib/browser/api/touch-bar.js @@ -28,6 +28,7 @@ class TouchBar extends EventEmitter { } this.windowListeners = {} + this.windows = {} this.items = {} this.ordereredItems = [] @@ -49,6 +50,15 @@ class TouchBar extends EventEmitter { }) } + replaceEscapeItem(item) { + if (!item) item = {} + Object.keys(this.windows).forEach((windowID) => { + const window = this.windows[windowID] + window._setEscapeTouchBarItem(item) + }) + this._escape = item; + } + _addToWindow (window) { const {id} = window @@ -76,11 +86,15 @@ class TouchBar extends EventEmitter { window.removeListener('closed', removeListeners) window._touchBar = null delete this.windowListeners[id] + delete this.windows[id] } window.once('closed', removeListeners) this.windowListeners[id] = removeListeners + this.windows[id] = window; window._setTouchBarItems(this.ordereredItems) + + if (this._escape) window._setEscapeTouchBarItem(this._escape) } _removeFromWindow (window) { From 2ba937289c71b4c7f1da8d31a3d0edf4eabf0d4e Mon Sep 17 00:00:00 2001 From: Samuel Attard Date: Mon, 27 Mar 2017 11:23:48 +1100 Subject: [PATCH 045/143] Add smoke test for escape replacement --- spec/api-touch-bar-spec.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/spec/api-touch-bar-spec.js b/spec/api-touch-bar-spec.js index a8e90502f5..0c2f917821 100644 --- a/spec/api-touch-bar-spec.js +++ b/spec/api-touch-bar-spec.js @@ -56,6 +56,9 @@ describe('TouchBar module', function () { }) ]) window.setTouchBar(touchBar) + touchBar.replaceEscapeItem(new TouchBarButton({ + label: 'foo' + })) label.label = 'baz' window.setTouchBar() window.setTouchBar(new TouchBar([new TouchBarLabel({label: 'two'})])) From 60cc8620317e604401cc2c06b13530a9e9e705fa Mon Sep 17 00:00:00 2001 From: Samuel Attard Date: Wed, 29 Mar 2017 15:11:39 +1100 Subject: [PATCH 046/143] Make everything pointer like --- atom/browser/api/atom_api_window.cc | 2 +- atom/browser/api/atom_api_window.h | 2 +- atom/browser/native_window.cc | 2 +- atom/browser/native_window.h | 2 +- atom/browser/native_window_mac.h | 2 +- atom/browser/native_window_mac.mm | 4 ++-- atom/browser/ui/cocoa/atom_touch_bar.h | 4 ++-- atom/browser/ui/cocoa/atom_touch_bar.mm | 4 ++-- docs/api/touch-bar.md | 2 +- lib/browser/api/touch-bar.js | 6 +++--- 10 files changed, 15 insertions(+), 15 deletions(-) diff --git a/atom/browser/api/atom_api_window.cc b/atom/browser/api/atom_api_window.cc index f64b040827..9a4ae5850d 100644 --- a/atom/browser/api/atom_api_window.cc +++ b/atom/browser/api/atom_api_window.cc @@ -853,7 +853,7 @@ void Window::RefreshTouchBarItem(const std::string& item_id) { window_->RefreshTouchBarItem(item_id); } -void Window::SetEscapeTouchBarItem(const mate::PersistentDictionary item) { +void Window::SetEscapeTouchBarItem(const mate::PersistentDictionary& item) { window_->SetEscapeTouchBarItem(item); } diff --git a/atom/browser/api/atom_api_window.h b/atom/browser/api/atom_api_window.h index c7b6a37265..24afec354d 100644 --- a/atom/browser/api/atom_api_window.h +++ b/atom/browser/api/atom_api_window.h @@ -208,7 +208,7 @@ class Window : public mate::TrackableObject, void SetVibrancy(mate::Arguments* args); void SetTouchBar(const std::vector& items); void RefreshTouchBarItem(const std::string& item_id); - void SetEscapeTouchBarItem(const mate::PersistentDictionary item); + void SetEscapeTouchBarItem(const mate::PersistentDictionary& item); v8::Local WebContents(v8::Isolate* isolate); diff --git a/atom/browser/native_window.cc b/atom/browser/native_window.cc index 4866e4294c..413c756cdc 100644 --- a/atom/browser/native_window.cc +++ b/atom/browser/native_window.cc @@ -347,7 +347,7 @@ void NativeWindow::SetTouchBar( void NativeWindow::RefreshTouchBarItem(const std::string& item_id) { } -void NativeWindow::SetEscapeTouchBarItem(const mate::PersistentDictionary item) { +void NativeWindow::SetEscapeTouchBarItem(const mate::PersistentDictionary& item) { } void NativeWindow::FocusOnWebView() { diff --git a/atom/browser/native_window.h b/atom/browser/native_window.h index 3de57895e5..227e28c1e4 100644 --- a/atom/browser/native_window.h +++ b/atom/browser/native_window.h @@ -174,7 +174,7 @@ class NativeWindow : public base::SupportsUserData, virtual void SetTouchBar( const std::vector& items); virtual void RefreshTouchBarItem(const std::string& item_id); - virtual void SetEscapeTouchBarItem(const mate::PersistentDictionary item); + virtual void SetEscapeTouchBarItem(const mate::PersistentDictionary& item); // Webview APIs. virtual void FocusOnWebView(); diff --git a/atom/browser/native_window_mac.h b/atom/browser/native_window_mac.h index 80ae8895aa..a535cdb4be 100644 --- a/atom/browser/native_window_mac.h +++ b/atom/browser/native_window_mac.h @@ -103,7 +103,7 @@ class NativeWindowMac : public NativeWindow, void SetTouchBar( const std::vector& items) override; void RefreshTouchBarItem(const std::string& item_id) override; - void SetEscapeTouchBarItem(const mate::PersistentDictionary item) override; + void SetEscapeTouchBarItem(const mate::PersistentDictionary& item) override; // content::RenderWidgetHost::InputEventObserver: void OnInputEvent(const blink::WebInputEvent& event) override; diff --git a/atom/browser/native_window_mac.mm b/atom/browser/native_window_mac.mm index 7cbb8e2dff..438bab6e5a 100644 --- a/atom/browser/native_window_mac.mm +++ b/atom/browser/native_window_mac.mm @@ -411,7 +411,7 @@ enum { } -(void)setEscapeTouchBarItem:(mate::PersistentDictionary)item { - if (self.touchBar && atom_touch_bar_) + if (atom_touch_bar_ && self.touchBar) [atom_touch_bar_ setEscapeTouchBarItem:item forTouchBar:self.touchBar]; } @@ -1422,7 +1422,7 @@ void NativeWindowMac::RefreshTouchBarItem(const std::string& item_id) { [window_ refreshTouchBarItem:item_id]; } -void NativeWindowMac::SetEscapeTouchBarItem(const mate::PersistentDictionary item) { +void NativeWindowMac::SetEscapeTouchBarItem(const mate::PersistentDictionary& item) { [window_ setEscapeTouchBarItem:item]; } diff --git a/atom/browser/ui/cocoa/atom_touch_bar.h b/atom/browser/ui/cocoa/atom_touch_bar.h index 8232e56f0a..26662cf485 100644 --- a/atom/browser/ui/cocoa/atom_touch_bar.h +++ b/atom/browser/ui/cocoa/atom_touch_bar.h @@ -31,8 +31,8 @@ - (NSTouchBar*)touchBarFromItemIdentifiers:(NSMutableArray*)items; - (NSMutableArray*)identifiersFromSettings:(const std::vector&)settings; - (void)refreshTouchBarItem:(NSTouchBar*)touchBar id:(const std::string&)item_id; -- (void)addNonDefaultTouchBarItems:(std::vector)items; -- (void)setEscapeTouchBarItem:(mate::PersistentDictionary)item forTouchBar:(NSTouchBar*)touchBar; +- (void)addNonDefaultTouchBarItems:(const std::vector&)items; +- (void)setEscapeTouchBarItem:(const mate::PersistentDictionary&)item forTouchBar:(NSTouchBar*)touchBar; - (NSString*)idFromIdentifier:(NSString*)identifier withPrefix:(NSString*)prefix; diff --git a/atom/browser/ui/cocoa/atom_touch_bar.mm b/atom/browser/ui/cocoa/atom_touch_bar.mm index c12434467e..3a8037b1c5 100644 --- a/atom/browser/ui/cocoa/atom_touch_bar.mm +++ b/atom/browser/ui/cocoa/atom_touch_bar.mm @@ -147,11 +147,11 @@ static NSString* const ImageScrubberItemIdentifier = @"scrubber.image.item"; } } -- (void)addNonDefaultTouchBarItems:(std::vector)items { +- (void)addNonDefaultTouchBarItems:(const std::vector&)items { [self identifiersFromSettings:items]; } -- (void)setEscapeTouchBarItem:(mate::PersistentDictionary)item forTouchBar:(NSTouchBar*)touchBar { +- (void)setEscapeTouchBarItem:(const mate::PersistentDictionary&)item forTouchBar:(NSTouchBar*)touchBar { std::string type; std::string item_id; NSTouchBarItemIdentifier identifier = nil; diff --git a/docs/api/touch-bar.md b/docs/api/touch-bar.md index d5496b8b3f..54315d7977 100644 --- a/docs/api/touch-bar.md +++ b/docs/api/touch-bar.md @@ -18,7 +18,7 @@ removed in future Electron releases. The following methods are available on instances of `TouchBar`: -#### `touchBar.replaceEscapeItem([touchBarItem])` +#### `touchBar.setEscapeItem([touchBarItem])` * `touchBarItem` (TouchBarButton | TouchBarColorPicker | TouchBarGroup | TouchBarLabel | TouchBarPopover | TouchBarScrubber | TouchBarSegmentedControl | TouchBarSlider | TouchBarSpacer) - (Optional) The touch bar item to replace the escape button with diff --git a/lib/browser/api/touch-bar.js b/lib/browser/api/touch-bar.js index 68cd623861..1af18dfbe7 100644 --- a/lib/browser/api/touch-bar.js +++ b/lib/browser/api/touch-bar.js @@ -50,13 +50,13 @@ class TouchBar extends EventEmitter { }) } - replaceEscapeItem(item) { + setEscapeItem(item) { if (!item) item = {} Object.keys(this.windows).forEach((windowID) => { const window = this.windows[windowID] window._setEscapeTouchBarItem(item) }) - this._escape = item; + this._escape = item } _addToWindow (window) { @@ -90,7 +90,7 @@ class TouchBar extends EventEmitter { } window.once('closed', removeListeners) this.windowListeners[id] = removeListeners - this.windows[id] = window; + this.windows[id] = window window._setTouchBarItems(this.ordereredItems) From df0f468dea069e6a511235e4ffb02e3fe6e7f463 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Wed, 29 Mar 2017 12:41:36 -0700 Subject: [PATCH 047/143] Add escapeKeyReplacementItemIdentifier forward declaration --- atom/browser/ui/cocoa/touch_bar_forward_declarations.h | 1 + 1 file changed, 1 insertion(+) diff --git a/atom/browser/ui/cocoa/touch_bar_forward_declarations.h b/atom/browser/ui/cocoa/touch_bar_forward_declarations.h index 57d5bd7453..6fe7c820a1 100644 --- a/atom/browser/ui/cocoa/touch_bar_forward_declarations.h +++ b/atom/browser/ui/cocoa/touch_bar_forward_declarations.h @@ -55,6 +55,7 @@ static const NSTouchBarItemIdentifier NSTouchBarItemIdentifierOtherItemsProxy = @property(copy) NSArray* defaultItemIdentifiers; @property(copy, readonly) NSArray* itemIdentifiers; @property(copy, nullable) NSTouchBarItemIdentifier principalItemIdentifier; +@property(copy, nullable) NSTouchBarItemIdentifier escapeKeyReplacementItemIdentifier; @property(copy) NSSet* templateItems; @property(nullable, weak) id delegate; From d596d85288ddca1c5c9e50a26097e3ff76129762 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Wed, 29 Mar 2017 12:41:49 -0700 Subject: [PATCH 048/143] :art: --- atom/browser/native_window.cc | 3 ++- lib/browser/api/touch-bar.js | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/atom/browser/native_window.cc b/atom/browser/native_window.cc index 413c756cdc..af32a2e8a8 100644 --- a/atom/browser/native_window.cc +++ b/atom/browser/native_window.cc @@ -347,7 +347,8 @@ void NativeWindow::SetTouchBar( void NativeWindow::RefreshTouchBarItem(const std::string& item_id) { } -void NativeWindow::SetEscapeTouchBarItem(const mate::PersistentDictionary& item) { +void NativeWindow::SetEscapeTouchBarItem( + const mate::PersistentDictionary& item) { } void NativeWindow::FocusOnWebView() { diff --git a/lib/browser/api/touch-bar.js b/lib/browser/api/touch-bar.js index 1af18dfbe7..2c6b72b893 100644 --- a/lib/browser/api/touch-bar.js +++ b/lib/browser/api/touch-bar.js @@ -50,7 +50,7 @@ class TouchBar extends EventEmitter { }) } - setEscapeItem(item) { + setEscapeItem (item) { if (!item) item = {} Object.keys(this.windows).forEach((windowID) => { const window = this.windows[windowID] From 7f8e490839560c63bbf3372ef9699c1d19d3611f Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Wed, 29 Mar 2017 12:45:01 -0700 Subject: [PATCH 049/143] Take const reference --- atom/browser/native_window_mac.mm | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/atom/browser/native_window_mac.mm b/atom/browser/native_window_mac.mm index 438bab6e5a..c3ca24a3d4 100644 --- a/atom/browser/native_window_mac.mm +++ b/atom/browser/native_window_mac.mm @@ -368,6 +368,7 @@ enum { - (void)enableWindowButtonsOffset; - (void)resetTouchBar:(const std::vector&)settings; - (void)refreshTouchBarItem:(const std::string&)item_id; +- (void)setEscapeTouchBarItem:(const mate::PersistentDictionary&)item; @end @@ -410,7 +411,7 @@ enum { return nil; } --(void)setEscapeTouchBarItem:(mate::PersistentDictionary)item { +- (void)setEscapeTouchBarItem:(const mate::PersistentDictionary&)item { if (atom_touch_bar_ && self.touchBar) [atom_touch_bar_ setEscapeTouchBarItem:item forTouchBar:self.touchBar]; } From 6eacec7dc3ddddac37c5f14f41a8b9c6ec16034b Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Wed, 29 Mar 2017 12:46:33 -0700 Subject: [PATCH 050/143] replaceEscapeItem -> setEscapeItem --- spec/api-touch-bar-spec.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/api-touch-bar-spec.js b/spec/api-touch-bar-spec.js index 0c2f917821..5564556585 100644 --- a/spec/api-touch-bar-spec.js +++ b/spec/api-touch-bar-spec.js @@ -56,7 +56,7 @@ describe('TouchBar module', function () { }) ]) window.setTouchBar(touchBar) - touchBar.replaceEscapeItem(new TouchBarButton({ + touchBar.setEscapeItem(new TouchBarButton({ label: 'foo' })) label.label = 'baz' From 0501a20fe67f6ef3ba348d27bb68bc9ca3f2eb2c Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Wed, 29 Mar 2017 12:48:58 -0700 Subject: [PATCH 051/143] Clear escape item --- spec/api-touch-bar-spec.js | 1 + 1 file changed, 1 insertion(+) diff --git a/spec/api-touch-bar-spec.js b/spec/api-touch-bar-spec.js index 5564556585..465be6287f 100644 --- a/spec/api-touch-bar-spec.js +++ b/spec/api-touch-bar-spec.js @@ -62,6 +62,7 @@ describe('TouchBar module', function () { label.label = 'baz' window.setTouchBar() window.setTouchBar(new TouchBar([new TouchBarLabel({label: 'two'})])) + touchBar.setEscapeItem() }) }) }) From 591cd8d07338c69dd177e90dd222cf1112ec35ce Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Wed, 29 Mar 2017 13:11:25 -0700 Subject: [PATCH 052/143] Update window via listener when escape item changes --- lib/browser/api/touch-bar.js | 25 ++++++++++++++----------- spec/api-touch-bar-spec.js | 7 +++++++ 2 files changed, 21 insertions(+), 11 deletions(-) diff --git a/lib/browser/api/touch-bar.js b/lib/browser/api/touch-bar.js index 2c6b72b893..02e719ada7 100644 --- a/lib/browser/api/touch-bar.js +++ b/lib/browser/api/touch-bar.js @@ -28,9 +28,9 @@ class TouchBar extends EventEmitter { } this.windowListeners = {} - this.windows = {} this.items = {} this.ordereredItems = [] + this.escapeItem = {} const registerItem = (item) => { this.items[item.id] = item @@ -51,12 +51,12 @@ class TouchBar extends EventEmitter { } setEscapeItem (item) { - if (!item) item = {} - Object.keys(this.windows).forEach((windowID) => { - const window = this.windows[windowID] - window._setEscapeTouchBarItem(item) - }) - this._escape = item + if (item != null && !(item instanceof TouchBarItem)) { + throw new Error('Escape item must be an instance of TouchBarItem') + } + if (item == null) item = {} + this.escapeItem = item + this.emit('escape-item-change', item) } _addToWindow (window) { @@ -72,6 +72,11 @@ class TouchBar extends EventEmitter { } this.on('change', changeListener) + const escapeItemListener = (item) => { + window._setEscapeTouchBarItem(item) + } + this.on('escape-item-change', escapeItemListener) + const interactionListener = (event, itemID, details) => { const item = this.items[itemID] if (item != null && item.onInteraction != null) { @@ -82,19 +87,17 @@ class TouchBar extends EventEmitter { const removeListeners = () => { this.removeListener('change', changeListener) + this.removeListener('escape-item-change', escapeItemListener) window.removeListener('-touch-bar-interaction', interactionListener) window.removeListener('closed', removeListeners) window._touchBar = null delete this.windowListeners[id] - delete this.windows[id] } window.once('closed', removeListeners) this.windowListeners[id] = removeListeners - this.windows[id] = window window._setTouchBarItems(this.ordereredItems) - - if (this._escape) window._setEscapeTouchBarItem(this._escape) + window._setEscapeTouchBarItem(this.escapeItem) } _removeFromWindow (window) { diff --git a/spec/api-touch-bar-spec.js b/spec/api-touch-bar-spec.js index 465be6287f..81bf47eba3 100644 --- a/spec/api-touch-bar-spec.js +++ b/spec/api-touch-bar-spec.js @@ -20,6 +20,13 @@ describe('TouchBar module', function () { }, /Each item must be an instance of TouchBarItem/) }) + it('throws an error when an invalid escape item is set', function () { + assert.throws(() => { + const touchBar = new TouchBar([]) + touchBar.setEscapeItem('esc') + }, /Escape item must be an instance of TouchBarItem/) + }) + describe('BrowserWindow behavior', function () { let window From 21c1ddffb38cd6eededb057d6af5997727f20067 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Wed, 29 Mar 2017 13:26:52 -0700 Subject: [PATCH 053/143] Handle change and interaction events on escape items --- lib/browser/api/touch-bar.js | 24 +++++++++++++++++------- spec/api-touch-bar-spec.js | 8 +++++--- 2 files changed, 22 insertions(+), 10 deletions(-) diff --git a/lib/browser/api/touch-bar.js b/lib/browser/api/touch-bar.js index 02e719ada7..2b95616f22 100644 --- a/lib/browser/api/touch-bar.js +++ b/lib/browser/api/touch-bar.js @@ -2,6 +2,8 @@ const {EventEmitter} = require('events') let nextItemID = 1 +const DEFAULT_ESCAPE_ITEM = new EventEmitter() + class TouchBar extends EventEmitter { // Bind a touch bar to a window static _setOnWindow (touchBar, window) { @@ -30,13 +32,14 @@ class TouchBar extends EventEmitter { this.windowListeners = {} this.items = {} this.ordereredItems = [] - this.escapeItem = {} + this.escapeItem = DEFAULT_ESCAPE_ITEM + this.changeListener = (item) => { + this.emit('change', item.id, item.type) + } const registerItem = (item) => { this.items[item.id] = item - item.on('change', () => { - this.emit('change', item.id, item.type) - }) + item.on('change', this.changeListener) if (item.child instanceof TouchBar) { item.child.ordereredItems.forEach(registerItem) } @@ -54,8 +57,12 @@ class TouchBar extends EventEmitter { if (item != null && !(item instanceof TouchBarItem)) { throw new Error('Escape item must be an instance of TouchBarItem') } - if (item == null) item = {} + if (item == null) { + item = DEFAULT_ESCAPE_ITEM + } + this.escapeItem.removeListener('change', this.changeListener) this.escapeItem = item + this.escapeItem.on('change', this.changeListener) this.emit('escape-item-change', item) } @@ -78,7 +85,10 @@ class TouchBar extends EventEmitter { this.on('escape-item-change', escapeItemListener) const interactionListener = (event, itemID, details) => { - const item = this.items[itemID] + let item = this.items[itemID] + if (item == null && this.escapeItem.id === itemID) { + item = this.escapeItem + } if (item != null && item.onInteraction != null) { item.onInteraction(details) } @@ -121,7 +131,7 @@ class TouchBarItem extends EventEmitter { }, set: function (value) { this[privateName] = value - this.emit('change') + this.emit('change', this) }, enumerable: true }) diff --git a/spec/api-touch-bar-spec.js b/spec/api-touch-bar-spec.js index 81bf47eba3..aafb8c6821 100644 --- a/spec/api-touch-bar-spec.js +++ b/spec/api-touch-bar-spec.js @@ -62,11 +62,13 @@ describe('TouchBar module', function () { showArrowButtons: true }) ]) - window.setTouchBar(touchBar) - touchBar.setEscapeItem(new TouchBarButton({ + const escapeButton = new TouchBarButton({ label: 'foo' - })) + }) + window.setTouchBar(touchBar) + touchBar.setEscapeItem(escapeButton) label.label = 'baz' + escapeButton.label = 'hello' window.setTouchBar() window.setTouchBar(new TouchBar([new TouchBarLabel({label: 'two'})])) touchBar.setEscapeItem() From b24b4212c517557db34c02a378394acb12b49062 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Mon, 3 Apr 2017 09:34:55 -0700 Subject: [PATCH 054/143] Make escape item a property instead of setter --- docs/api/touch-bar.md | 13 ++++++------- lib/browser/api/touch-bar.js | 25 ++++++++++++++----------- spec/api-touch-bar-spec.js | 6 +++--- 3 files changed, 23 insertions(+), 21 deletions(-) diff --git a/docs/api/touch-bar.md b/docs/api/touch-bar.md index 54315d7977..a1d86794dd 100644 --- a/docs/api/touch-bar.md +++ b/docs/api/touch-bar.md @@ -14,16 +14,15 @@ Creates a new touch bar with the specified items. Use **Note:** The TouchBar API is currently experimental and may change or be removed in future Electron releases. -### Instance Methods +### Instance Properties -The following methods are available on instances of `TouchBar`: +The following properties are available on instances of `TouchBar`: -#### `touchBar.setEscapeItem([touchBarItem])` +#### `touchBar.escapeItem` -* `touchBarItem` (TouchBarButton | TouchBarColorPicker | TouchBarGroup | TouchBarLabel | TouchBarPopover | TouchBarScrubber | TouchBarSegmentedControl | TouchBarSlider | TouchBarSpacer) - (Optional) The touch bar item to replace the escape button with - -Replaces the "esc" button on the touchbar with the given TouchBarItem, if `touchBarItem` is not provided or is falsey the button is reset -to the "esc" button automatically. +The `TouchBarItem` that will replace the "esc" button on the touch bar when set. +Setting to `null` restores the default "esc" button. Changing this value +immediately updates the escape item in the touch bar. ## Examples diff --git a/lib/browser/api/touch-bar.js b/lib/browser/api/touch-bar.js index 2b95616f22..cd806a5562 100644 --- a/lib/browser/api/touch-bar.js +++ b/lib/browser/api/touch-bar.js @@ -2,8 +2,6 @@ const {EventEmitter} = require('events') let nextItemID = 1 -const DEFAULT_ESCAPE_ITEM = new EventEmitter() - class TouchBar extends EventEmitter { // Bind a touch bar to a window static _setOnWindow (touchBar, window) { @@ -32,7 +30,7 @@ class TouchBar extends EventEmitter { this.windowListeners = {} this.items = {} this.ordereredItems = [] - this.escapeItem = DEFAULT_ESCAPE_ITEM + this.escapeItem = null this.changeListener = (item) => { this.emit('change', item.id, item.type) } @@ -53,19 +51,24 @@ class TouchBar extends EventEmitter { }) } - setEscapeItem (item) { + set escapeItem (item) { if (item != null && !(item instanceof TouchBarItem)) { throw new Error('Escape item must be an instance of TouchBarItem') } - if (item == null) { - item = DEFAULT_ESCAPE_ITEM + if (this.escapeItem != null) { + this.escapeItem.removeListener('change', this.changeListener) + } + this._escapeItem = item + if (this.escapeItem != null) { + this.escapeItem.on('change', this.changeListener) } - this.escapeItem.removeListener('change', this.changeListener) - this.escapeItem = item - this.escapeItem.on('change', this.changeListener) this.emit('escape-item-change', item) } + get escapeItem () { + return this._escapeItem + } + _addToWindow (window) { const {id} = window @@ -80,7 +83,7 @@ class TouchBar extends EventEmitter { this.on('change', changeListener) const escapeItemListener = (item) => { - window._setEscapeTouchBarItem(item) + window._setEscapeTouchBarItem(item != null ? item : {}) } this.on('escape-item-change', escapeItemListener) @@ -107,7 +110,7 @@ class TouchBar extends EventEmitter { this.windowListeners[id] = removeListeners window._setTouchBarItems(this.ordereredItems) - window._setEscapeTouchBarItem(this.escapeItem) + escapeItemListener(this.escapeItem) } _removeFromWindow (window) { diff --git a/spec/api-touch-bar-spec.js b/spec/api-touch-bar-spec.js index aafb8c6821..3b986ba032 100644 --- a/spec/api-touch-bar-spec.js +++ b/spec/api-touch-bar-spec.js @@ -23,7 +23,7 @@ describe('TouchBar module', function () { it('throws an error when an invalid escape item is set', function () { assert.throws(() => { const touchBar = new TouchBar([]) - touchBar.setEscapeItem('esc') + touchBar.escapeItem = 'esc' }, /Escape item must be an instance of TouchBarItem/) }) @@ -66,12 +66,12 @@ describe('TouchBar module', function () { label: 'foo' }) window.setTouchBar(touchBar) - touchBar.setEscapeItem(escapeButton) + touchBar.escapeItem = escapeButton label.label = 'baz' escapeButton.label = 'hello' window.setTouchBar() window.setTouchBar(new TouchBar([new TouchBarLabel({label: 'two'})])) - touchBar.setEscapeItem() + touchBar.escapeItem = null }) }) }) From 414540bfcb28cf6c79b35616a48485f265db7378 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Mon, 3 Apr 2017 15:12:57 -0700 Subject: [PATCH 055/143] Support passing escape item to TouchBar constructor --- docs/api/touch-bar.md | 6 ++++-- lib/browser/api/touch-bar.js | 18 +++++++++++++++--- spec/api-touch-bar-spec.js | 13 +++++++++---- 3 files changed, 28 insertions(+), 9 deletions(-) diff --git a/docs/api/touch-bar.md b/docs/api/touch-bar.md index a1d86794dd..7ac578da46 100644 --- a/docs/api/touch-bar.md +++ b/docs/api/touch-bar.md @@ -4,9 +4,11 @@ Process: [Main](../tutorial/quick-start.md#main-process) -### `new TouchBar(items)` _Experimental_ +### `new TouchBar(options)` _Experimental_ -* `items` ([TouchBarButton](touch-bar-button.md) | [TouchBarColorPicker](touch-bar-color-picker.md) | [TouchBarGroup](touch-bar-group.md) | [TouchBarLabel](touch-bar-label.md) | [TouchBarPopover](touch-bar-popover.md) | [TouchBarScrubber](touch-bar-scrubber.md) | [TouchBarSegmentedControl](touch-bar-segmented-control.md) | [TouchBarSlider](touch-bar-slider.md) | [TouchBarSpacer](touch-bar-spacer.md))[] +* `options` - Object + * `items` ([TouchBarButton](touch-bar-button.md) | [TouchBarColorPicker](touch-bar-color-picker.md) | [TouchBarGroup](touch-bar-group.md) | [TouchBarLabel](touch-bar-label.md) | [TouchBarPopover](touch-bar-popover.md) | [TouchBarScrubber](touch-bar-scrubber.md) | [TouchBarSegmentedControl](touch-bar-segmented-control.md) | [TouchBarSlider](touch-bar-slider.md) | [TouchBarSpacer](touch-bar-spacer.md))[] + * `escapeItem` ([TouchBarButton](touch-bar-button.md) | [TouchBarColorPicker](touch-bar-color-picker.md) | [TouchBarGroup](touch-bar-group.md) | [TouchBarLabel](touch-bar-label.md) | [TouchBarPopover](touch-bar-popover.md) | [TouchBarScrubber](touch-bar-scrubber.md) | [TouchBarSegmentedControl](touch-bar-segmented-control.md) | [TouchBarSlider](touch-bar-slider.md) | [TouchBarSpacer](touch-bar-spacer.md)) (optional) Creates a new touch bar with the specified items. Use `BrowserWindow.setTouchBar` to add the `TouchBar` to a window. diff --git a/lib/browser/api/touch-bar.js b/lib/browser/api/touch-bar.js index cd806a5562..f9629a66ce 100644 --- a/lib/browser/api/touch-bar.js +++ b/lib/browser/api/touch-bar.js @@ -20,17 +20,29 @@ class TouchBar extends EventEmitter { touchBar._addToWindow(window) } - constructor (items) { + constructor (options) { super() + if (options == null) { + throw new Error('Must specify options object as first argument') + } + + let {items, escapeItem} = options + + // FIXME Support array as first argument, remove in 2.0 + if (Array.isArray(options)) { + items = options + escapeItem = null + } + if (!Array.isArray(items)) { - throw new Error('Must specify items array as first argument') + items = [] } this.windowListeners = {} this.items = {} this.ordereredItems = [] - this.escapeItem = null + this.escapeItem = escapeItem this.changeListener = (item) => { this.emit('change', item.id, item.type) } diff --git a/spec/api-touch-bar-spec.js b/spec/api-touch-bar-spec.js index 3b986ba032..c2d5d26c3e 100644 --- a/spec/api-touch-bar-spec.js +++ b/spec/api-touch-bar-spec.js @@ -6,23 +6,28 @@ const {TouchBarButton, TouchBarColorPicker, TouchBarGroup} = TouchBar const {TouchBarLabel, TouchBarPopover, TouchBarScrubber, TouchBarSegmentedControl, TouchBarSlider, TouchBarSpacer} = TouchBar describe('TouchBar module', function () { - it('throws an error when created without an items array', function () { + it('throws an error when created without an options object', function () { assert.throws(() => { const touchBar = new TouchBar() touchBar.toString() - }, /Must specify items array as first argument/) + }, /Must specify options object as first argument/) }) it('throws an error when created with invalid items', function () { assert.throws(() => { - const touchBar = new TouchBar([1, true, {}, []]) + const touchBar = new TouchBar({items: [1, true, {}, []]}) touchBar.toString() }, /Each item must be an instance of TouchBarItem/) }) it('throws an error when an invalid escape item is set', function () { assert.throws(() => { - const touchBar = new TouchBar([]) + const touchBar = new TouchBar({items: [], escapeItem: 'esc'}) + touchBar.toString() + }, /Escape item must be an instance of TouchBarItem/) + + assert.throws(() => { + const touchBar = new TouchBar({items: []}) touchBar.escapeItem = 'esc' }, /Escape item must be an instance of TouchBarItem/) }) From bbadeb62ac2a2c4745a4481cc3dc334abf7685d1 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Tue, 4 Apr 2017 13:12:29 -0700 Subject: [PATCH 056/143] Check that escape item is non-null before checking id --- lib/browser/api/touch-bar.js | 2 +- spec/api-touch-bar-spec.js | 12 ++++++++++++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/lib/browser/api/touch-bar.js b/lib/browser/api/touch-bar.js index f9629a66ce..327b6392fe 100644 --- a/lib/browser/api/touch-bar.js +++ b/lib/browser/api/touch-bar.js @@ -101,7 +101,7 @@ class TouchBar extends EventEmitter { const interactionListener = (event, itemID, details) => { let item = this.items[itemID] - if (item == null && this.escapeItem.id === itemID) { + if (item == null && this.escapeItem != null && this.escapeItem.id === itemID) { item = this.escapeItem } if (item != null && item.onInteraction != null) { diff --git a/spec/api-touch-bar-spec.js b/spec/api-touch-bar-spec.js index c2d5d26c3e..7080304591 100644 --- a/spec/api-touch-bar-spec.js +++ b/spec/api-touch-bar-spec.js @@ -78,5 +78,17 @@ describe('TouchBar module', function () { window.setTouchBar(new TouchBar([new TouchBarLabel({label: 'two'})])) touchBar.escapeItem = null }) + + it('calls the callback on the items when a window interaction event fires', function (done) { + const button = new TouchBarButton({ + label: 'bar', + click: () => { + done() + } + }) + const touchBar = new TouchBar({items: [button]}) + window.setTouchBar(touchBar) + window.emit('-touch-bar-interaction', {}, button.id) + }) }) }) From 74a3a34caa301cbe5390d00d2cc35fdcf2b97fa7 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Tue, 4 Apr 2017 13:14:56 -0700 Subject: [PATCH 057/143] Add spec for interaction event with escape item --- lib/browser/api/touch-bar.js | 7 ++++--- spec/api-touch-bar-spec.js | 12 ++++++++++++ 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/lib/browser/api/touch-bar.js b/lib/browser/api/touch-bar.js index 327b6392fe..1070398c75 100644 --- a/lib/browser/api/touch-bar.js +++ b/lib/browser/api/touch-bar.js @@ -39,13 +39,14 @@ class TouchBar extends EventEmitter { items = [] } + this.changeListener = (item) => { + this.emit('change', item.id, item.type) + } + this.windowListeners = {} this.items = {} this.ordereredItems = [] this.escapeItem = escapeItem - this.changeListener = (item) => { - this.emit('change', item.id, item.type) - } const registerItem = (item) => { this.items[item.id] = item diff --git a/spec/api-touch-bar-spec.js b/spec/api-touch-bar-spec.js index 7080304591..420ef3fc7b 100644 --- a/spec/api-touch-bar-spec.js +++ b/spec/api-touch-bar-spec.js @@ -90,5 +90,17 @@ describe('TouchBar module', function () { window.setTouchBar(touchBar) window.emit('-touch-bar-interaction', {}, button.id) }) + + it('calls the callback on the escape item when a window interaction event fires', function (done) { + const button = new TouchBarButton({ + label: 'bar', + click: () => { + done() + } + }) + const touchBar = new TouchBar({escapeItem: button}) + window.setTouchBar(touchBar) + window.emit('-touch-bar-interaction', {}, button.id) + }) }) }) From f05dfc74daba55603e5a4d478947617e3ec97c6f Mon Sep 17 00:00:00 2001 From: Samuel Attard Date: Mon, 27 Mar 2017 20:45:27 +1100 Subject: [PATCH 058/143] Store parent popover in popover touch bar items --- atom/browser/ui/cocoa/atom_touch_bar.mm | 10 +++++++++- lib/browser/api/touch-bar.js | 1 + 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/atom/browser/ui/cocoa/atom_touch_bar.mm b/atom/browser/ui/cocoa/atom_touch_bar.mm index 3a8037b1c5..2bd290bd9a 100644 --- a/atom/browser/ui/cocoa/atom_touch_bar.mm +++ b/atom/browser/ui/cocoa/atom_touch_bar.mm @@ -126,7 +126,15 @@ static NSString* const ImageScrubberItemIdentifier = @"scrubber.image.item"; type:item_type]; if (!identifier) return; - NSTouchBarItem* item = [touchBar itemForIdentifier:identifier]; + NSTouchBar* targetTouchBar = touchBar; + + std::string popover_id; + if (settings.Get("_popover", &popover_id)) { + NSPopoverTouchBarItem* popoverItem = [touchBar itemForIdentifier:[self identifierFromID:popover_id type:"popover"]]; + targetTouchBar = popoverItem.popoverTouchBar; + } + + NSTouchBarItem* item = [targetTouchBar itemForIdentifier:identifier]; if (!item) return; if (item_type == "button") { diff --git a/lib/browser/api/touch-bar.js b/lib/browser/api/touch-bar.js index 1070398c75..2bdbdbe2ae 100644 --- a/lib/browser/api/touch-bar.js +++ b/lib/browser/api/touch-bar.js @@ -223,6 +223,7 @@ TouchBar.TouchBarPopover = class TouchBarPopover extends TouchBarItem { if (!(this.child instanceof TouchBar)) { this.child = new TouchBar(this.child) } + this.child.ordereredItems.forEach((item) => item._popover = this.id) } } From 2fd62d090a7d50cb27a5be089bc34b1aa9c90f5c Mon Sep 17 00:00:00 2001 From: Samuel Attard Date: Mon, 27 Mar 2017 21:10:14 +1100 Subject: [PATCH 059/143] Allow items to be assigned to multiple popovers --- atom/browser/ui/cocoa/atom_touch_bar.mm | 51 ++++++++++++++----------- lib/browser/api/touch-bar.js | 5 ++- 2 files changed, 33 insertions(+), 23 deletions(-) diff --git a/atom/browser/ui/cocoa/atom_touch_bar.mm b/atom/browser/ui/cocoa/atom_touch_bar.mm index 2bd290bd9a..4b60627488 100644 --- a/atom/browser/ui/cocoa/atom_touch_bar.mm +++ b/atom/browser/ui/cocoa/atom_touch_bar.mm @@ -113,28 +113,11 @@ static NSString* const ImageScrubberItemIdentifier = @"scrubber.image.item"; return nil; } - - (void)refreshTouchBarItem:(NSTouchBar*)touchBar - id:(const std::string&)item_id { - if (![self hasItemWithID:item_id]) return; - - mate::PersistentDictionary settings = settings_[item_id]; - std::string item_type; - settings.Get("type", &item_type); - - NSTouchBarItemIdentifier identifier = [self identifierFromID:item_id - type:item_type]; - if (!identifier) return; - - NSTouchBar* targetTouchBar = touchBar; - - std::string popover_id; - if (settings.Get("_popover", &popover_id)) { - NSPopoverTouchBarItem* popoverItem = [touchBar itemForIdentifier:[self identifierFromID:popover_id type:"popover"]]; - targetTouchBar = popoverItem.popoverTouchBar; - } - - NSTouchBarItem* item = [targetTouchBar itemForIdentifier:identifier]; + id:(NSTouchBarItemIdentifier)identifier + withType:(std::string)item_type + withSettings:(mate::PersistentDictionary)settings { + NSTouchBarItem* item = [touchBar itemForIdentifier:identifier]; if (!item) return; if (item_type == "button") { @@ -143,7 +126,7 @@ static NSString* const ImageScrubberItemIdentifier = @"scrubber.image.item"; [self updateLabel:(NSCustomTouchBarItem*)item withSettings:settings]; } else if (item_type == "colorpicker") { [self updateColorPicker:(NSColorPickerTouchBarItem*)item - withSettings:settings]; + withSettings:settings]; } else if (item_type == "slider") { [self updateSlider:(NSSliderTouchBarItem*)item withSettings:settings]; } else if (item_type == "popover") { @@ -174,6 +157,30 @@ static NSString* const ImageScrubberItemIdentifier = @"scrubber.image.item"; } } +- (void)refreshTouchBarItem:(NSTouchBar*)touchBar + id:(const std::string&)item_id { + if (![self hasItemWithID:item_id]) return; + + mate::PersistentDictionary settings = settings_[item_id]; + std::string item_type; + settings.Get("type", &item_type); + + NSTouchBarItemIdentifier identifier = [self identifierFromID:item_id + type:item_type]; + if (!identifier) return; + + std::vector popover_ids; + if (settings.Get("_popover", &popover_ids)) { + for (size_t i = 0; i < popover_ids.size(); ++i) { + std::string popover_id = popover_ids[i]; + NSPopoverTouchBarItem* popoverItem = [touchBar itemForIdentifier:[self identifierFromID:popover_id type:"popover"]]; + NSTouchBar* targetTouchBar = popoverItem.popoverTouchBar; + [self refreshTouchBarItem:targetTouchBar id:identifier withType:item_type withSettings:settings]; + } + } + [self refreshTouchBarItem:touchBar id:identifier withType:item_type withSettings:settings]; +} + - (void)buttonAction:(id)sender { NSString* item_id = [NSString stringWithFormat:@"%ld", ((NSButton*)sender).tag]; window_->NotifyTouchBarItemInteraction([item_id UTF8String], diff --git a/lib/browser/api/touch-bar.js b/lib/browser/api/touch-bar.js index 2bdbdbe2ae..d0b7d54a59 100644 --- a/lib/browser/api/touch-bar.js +++ b/lib/browser/api/touch-bar.js @@ -223,7 +223,10 @@ TouchBar.TouchBarPopover = class TouchBarPopover extends TouchBarItem { if (!(this.child instanceof TouchBar)) { this.child = new TouchBar(this.child) } - this.child.ordereredItems.forEach((item) => item._popover = this.id) + this.child.ordereredItems.forEach((item) => { + item._popover = item._popover || [] + if (!item._popover.find(itemID => itemID === this.id)) item._popover.push(this.id) + }) } } From bea56bbdc8507f6f7ba250e999dc6d099f1e6d68 Mon Sep 17 00:00:00 2001 From: Samuel Attard Date: Wed, 29 Mar 2017 15:01:14 +1100 Subject: [PATCH 060/143] Update as per feedback --- atom/browser/ui/cocoa/atom_touch_bar.mm | 12 +++++------- lib/browser/api/touch-bar.js | 2 +- 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/atom/browser/ui/cocoa/atom_touch_bar.mm b/atom/browser/ui/cocoa/atom_touch_bar.mm index 4b60627488..674f572b1e 100644 --- a/atom/browser/ui/cocoa/atom_touch_bar.mm +++ b/atom/browser/ui/cocoa/atom_touch_bar.mm @@ -115,8 +115,8 @@ static NSString* const ImageScrubberItemIdentifier = @"scrubber.image.item"; - (void)refreshTouchBarItem:(NSTouchBar*)touchBar id:(NSTouchBarItemIdentifier)identifier - withType:(std::string)item_type - withSettings:(mate::PersistentDictionary)settings { + withType:(std::string)item_type + withSettings:(mate::PersistentDictionary)settings { NSTouchBarItem* item = [touchBar itemForIdentifier:identifier]; if (!item) return; @@ -126,7 +126,7 @@ static NSString* const ImageScrubberItemIdentifier = @"scrubber.image.item"; [self updateLabel:(NSCustomTouchBarItem*)item withSettings:settings]; } else if (item_type == "colorpicker") { [self updateColorPicker:(NSColorPickerTouchBarItem*)item - withSettings:settings]; + withSettings:settings]; } else if (item_type == "slider") { [self updateSlider:(NSSliderTouchBarItem*)item withSettings:settings]; } else if (item_type == "popover") { @@ -171,11 +171,9 @@ static NSString* const ImageScrubberItemIdentifier = @"scrubber.image.item"; std::vector popover_ids; if (settings.Get("_popover", &popover_ids)) { - for (size_t i = 0; i < popover_ids.size(); ++i) { - std::string popover_id = popover_ids[i]; + for (auto& popover_id : popover_ids) { NSPopoverTouchBarItem* popoverItem = [touchBar itemForIdentifier:[self identifierFromID:popover_id type:"popover"]]; - NSTouchBar* targetTouchBar = popoverItem.popoverTouchBar; - [self refreshTouchBarItem:targetTouchBar id:identifier withType:item_type withSettings:settings]; + [self refreshTouchBarItem:popoverItem.popoverTouchBar id:identifier withType:item_type withSettings:settings]; } } [self refreshTouchBarItem:touchBar id:identifier withType:item_type withSettings:settings]; diff --git a/lib/browser/api/touch-bar.js b/lib/browser/api/touch-bar.js index d0b7d54a59..1a9c3238a9 100644 --- a/lib/browser/api/touch-bar.js +++ b/lib/browser/api/touch-bar.js @@ -225,7 +225,7 @@ TouchBar.TouchBarPopover = class TouchBarPopover extends TouchBarItem { } this.child.ordereredItems.forEach((item) => { item._popover = item._popover || [] - if (!item._popover.find(itemID => itemID === this.id)) item._popover.push(this.id) + if (!item._popover.includes(this.id)) item._popover.push(this.id) }) } } From 9c73c991d726ad1decf980e4535890634cc5d964 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Mon, 3 Apr 2017 10:57:57 -0700 Subject: [PATCH 061/143] Use const references for params --- atom/browser/ui/cocoa/atom_touch_bar.mm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/atom/browser/ui/cocoa/atom_touch_bar.mm b/atom/browser/ui/cocoa/atom_touch_bar.mm index 674f572b1e..944501471c 100644 --- a/atom/browser/ui/cocoa/atom_touch_bar.mm +++ b/atom/browser/ui/cocoa/atom_touch_bar.mm @@ -115,8 +115,8 @@ static NSString* const ImageScrubberItemIdentifier = @"scrubber.image.item"; - (void)refreshTouchBarItem:(NSTouchBar*)touchBar id:(NSTouchBarItemIdentifier)identifier - withType:(std::string)item_type - withSettings:(mate::PersistentDictionary)settings { + withType:(const std::string&)item_type + withSettings:(const mate::PersistentDictionary&)settings { NSTouchBarItem* item = [touchBar itemForIdentifier:identifier]; if (!item) return; From 6a22c6645e1417de44ee2ddd6ad2dd003d9f2738 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Mon, 3 Apr 2017 11:05:16 -0700 Subject: [PATCH 062/143] Guard against missing popover identifier --- atom/browser/ui/cocoa/atom_touch_bar.mm | 25 +++++++++++++++++-------- 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/atom/browser/ui/cocoa/atom_touch_bar.mm b/atom/browser/ui/cocoa/atom_touch_bar.mm index 944501471c..a3e846df48 100644 --- a/atom/browser/ui/cocoa/atom_touch_bar.mm +++ b/atom/browser/ui/cocoa/atom_touch_bar.mm @@ -165,18 +165,27 @@ static NSString* const ImageScrubberItemIdentifier = @"scrubber.image.item"; std::string item_type; settings.Get("type", &item_type); - NSTouchBarItemIdentifier identifier = [self identifierFromID:item_id - type:item_type]; + auto identifier = [self identifierFromID:item_id type:item_type]; if (!identifier) return; std::vector popover_ids; - if (settings.Get("_popover", &popover_ids)) { - for (auto& popover_id : popover_ids) { - NSPopoverTouchBarItem* popoverItem = [touchBar itemForIdentifier:[self identifierFromID:popover_id type:"popover"]]; - [self refreshTouchBarItem:popoverItem.popoverTouchBar id:identifier withType:item_type withSettings:settings]; - } + settings.Get("_popover", &popover_ids); + for (auto& popover_id : popover_ids) { + auto popoverIdentifier = [self identifierFromID:popover_id type:"popover"]; + if (!popoverIdentifier) continue; + + NSPopoverTouchBarItem* popoverItem = + [touchBar itemForIdentifier:popoverIdentifier]; + [self refreshTouchBarItem:popoverItem.popoverTouchBar + id:identifier + withType:item_type + withSettings:settings]; } - [self refreshTouchBarItem:touchBar id:identifier withType:item_type withSettings:settings]; + + [self refreshTouchBarItem:touchBar + id:identifier + withType:item_type + withSettings:settings]; } - (void)buttonAction:(id)sender { From aa75e4562e5c3f0300429321f21fc3c9c8cea9d2 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Tue, 4 Apr 2017 20:40:43 -0700 Subject: [PATCH 063/143] Restore delivering IPC messages to utility handlers --- atom/utility/atom_content_utility_client.cc | 12 ++++++++++++ atom/utility/atom_content_utility_client.h | 2 ++ 2 files changed, 14 insertions(+) diff --git a/atom/utility/atom_content_utility_client.cc b/atom/utility/atom_content_utility_client.cc index 37fa755871..cc36293f43 100644 --- a/atom/utility/atom_content_utility_client.cc +++ b/atom/utility/atom_content_utility_client.cc @@ -19,4 +19,16 @@ AtomContentUtilityClient::AtomContentUtilityClient() { AtomContentUtilityClient::~AtomContentUtilityClient() { } +bool AtomContentUtilityClient::OnMessageReceived( + const IPC::Message& message) { +#if defined(OS_WIN) + for (auto* handler : handlers_) { + if (handler->OnMessageReceived(message)) + return true; + } +#endif + + return false; +} + } // namespace atom diff --git a/atom/utility/atom_content_utility_client.h b/atom/utility/atom_content_utility_client.h index 0edc4d5d80..b4aa7960f6 100644 --- a/atom/utility/atom_content_utility_client.h +++ b/atom/utility/atom_content_utility_client.h @@ -20,6 +20,8 @@ class AtomContentUtilityClient : public content::ContentUtilityClient { AtomContentUtilityClient(); ~AtomContentUtilityClient() override; + bool OnMessageReceived(const IPC::Message& message) override; + private: #if defined(OS_WIN) typedef ScopedVector Handlers; From b27b1c3b24b52969ba0487814fb91591b07ea7ae Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Tue, 4 Apr 2017 20:47:05 -0700 Subject: [PATCH 064/143] Append printed page to job --- chromium_src/chrome/browser/printing/print_view_manager_base.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/chromium_src/chrome/browser/printing/print_view_manager_base.cc b/chromium_src/chrome/browser/printing/print_view_manager_base.cc index bc5d3f31f0..07ec2992f3 100644 --- a/chromium_src/chrome/browser/printing/print_view_manager_base.cc +++ b/chromium_src/chrome/browser/printing/print_view_manager_base.cc @@ -159,6 +159,7 @@ void PrintViewManagerBase::OnDidPrintPage( ShouldQuitFromInnerMessageLoop(); #else + print_job_->AppendPrintedPage(params.page_number); if (metafile_must_be_valid) { bool print_text_with_gdi = document->settings().print_text_with_gdi() && From 73e3fd01eb6554e65496882cadc2aec5ba731954 Mon Sep 17 00:00:00 2001 From: Ales Pergl Date: Wed, 5 Apr 2017 14:45:46 +0200 Subject: [PATCH 065/143] Fixed a couple of failing debug checks when calling Chromium APIs --- atom/browser/browser_win.cc | 7 +++---- atom/browser/ui/views/submenu_button.cc | 6 +++--- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/atom/browser/browser_win.cc b/atom/browser/browser_win.cc index 50a9f9da33..ac0f713c88 100644 --- a/atom/browser/browser_win.cc +++ b/atom/browser/browser_win.cc @@ -61,11 +61,11 @@ bool GetProtocolLaunchPath(mate::Arguments* args, base::string16* exe) { // Read in optional args arg std::vector launch_args; if (args->GetNext(&launch_args) && !launch_args.empty()) - *exe = base::StringPrintf(L"\"%s\" %s \"%%1\"", + *exe = base::StringPrintf(L"\"%ls\" %ls \"%%1\"", exe->c_str(), base::JoinString(launch_args, L" ").c_str()); else - *exe = base::StringPrintf(L"\"%s\" \"%%1\"", exe->c_str()); + *exe = base::StringPrintf(L"\"%ls\" \"%%1\"", exe->c_str()); return true; } @@ -76,8 +76,7 @@ bool FormatCommandLineString(base::string16* exe, } if (!launch_args.empty()) { - base::string16 formatString = L"%s %s"; - *exe = base::StringPrintf(formatString.c_str(), + *exe = base::StringPrintf(L"%ls %ls", exe->c_str(), base::JoinString(launch_args, L" ").c_str()); } diff --git a/atom/browser/ui/views/submenu_button.cc b/atom/browser/ui/views/submenu_button.cc index 92f2a791cd..617dd3346d 100644 --- a/atom/browser/ui/views/submenu_button.cc +++ b/atom/browser/ui/views/submenu_button.cc @@ -23,8 +23,8 @@ SubmenuButton::SubmenuButton(const base::string16& title, menu_button_listener, false), accelerator_(0), show_underline_(false), - underline_start_(-1), - underline_end_(-1), + underline_start_(0), + underline_end_(0), text_width_(0), text_height_(0), underline_color_(SK_ColorBLACK), @@ -106,7 +106,7 @@ bool SubmenuButton::GetUnderlinePosition(const base::string16& text, void SubmenuButton::GetCharacterPosition( const base::string16& text, int index, int* pos) { - int height; + int height = 0; gfx::Canvas::SizeStringInt(text.substr(0, index), GetFontList(), pos, &height, 0, 0); } From ce1a5e3c9c5d231233035fc1b5836656d64de56c Mon Sep 17 00:00:00 2001 From: Thiago de Arruda Date: Wed, 5 Apr 2017 17:42:24 -0300 Subject: [PATCH 066/143] Fix sandboxed crashReporter for windows. - Use `path` module from browser process in sandboxed renderer. This is required because the return value of `path.join` is platform-specific, and this is an assumtion of crash-reporter.js which is shared between sandboxed and non-sandboxed renderers. - Set `process.platform` and `process.execPath` in sandboxed renderer environment. This is required to spawn the windows crash service from sandboxed renderer. - Use a single temporary directory for all crashReporter tests. This is required to make tests more deterministic across platforms(since mac's crashpad doesn't support changing the crash dump directory). Also make a few improvements/fixes to the `uploadToServer` test. --- electron.gyp | 2 + lib/sandboxed_renderer/api/exports/path.js | 1 + lib/sandboxed_renderer/init.js | 4 +- spec/api-crash-reporter-spec.js | 60 ++++++++++------------ spec/fixtures/api/crash.html | 2 +- 5 files changed, 33 insertions(+), 36 deletions(-) create mode 100644 lib/sandboxed_renderer/api/exports/path.js diff --git a/electron.gyp b/electron.gyp index ee81200974..ab7a52c3da 100644 --- a/electron.gyp +++ b/electron.gyp @@ -447,6 +447,8 @@ '-r', './lib/sandboxed_renderer/api/exports/os.js:os', '-r', + './lib/sandboxed_renderer/api/exports/path.js:path', + '-r', './lib/sandboxed_renderer/api/exports/child_process.js:child_process' ], 'isolated_args': [ diff --git a/lib/sandboxed_renderer/api/exports/path.js b/lib/sandboxed_renderer/api/exports/path.js new file mode 100644 index 0000000000..f2b2f2a77f --- /dev/null +++ b/lib/sandboxed_renderer/api/exports/path.js @@ -0,0 +1 @@ +module.exports = require('electron').remote.require('path') diff --git a/lib/sandboxed_renderer/init.js b/lib/sandboxed_renderer/init.js index 46b74ee7b0..5194f95154 100644 --- a/lib/sandboxed_renderer/init.js +++ b/lib/sandboxed_renderer/init.js @@ -27,6 +27,7 @@ const preloadModules = new Map([ ['electron', electron], ['fs', fs], ['os', require('os')], + ['path', require('path')], ['url', require('url')], ['timers', require('timers')] ]) @@ -36,8 +37,9 @@ const preloadSrc = fs.readFileSync(preloadPath).toString() // Pass different process object to the preload script(which should not have // access to things like `process.atomBinding`). const preloadProcess = new events.EventEmitter() -preloadProcess.platform = electron.remote.process.platform preloadProcess.crash = () => binding.crash() +process.platform = preloadProcess.platform = electron.remote.process.platform +process.execPath = preloadProcess.execPath = electron.remote.process.execPath process.on('exit', () => preloadProcess.emit('exit')) // This is the `require` function that will be visible to the preload script diff --git a/spec/api-crash-reporter-spec.js b/spec/api-crash-reporter-spec.js index 8a51b5ef2d..a0fde2d54f 100644 --- a/spec/api-crash-reporter-spec.js +++ b/spec/api-crash-reporter-spec.js @@ -15,24 +15,32 @@ describe('crashReporter module', function () { if (process.mas) { return } + + var originalTempDirectory = null + var tempDirectory = null + + before(function () { + tempDirectory = temp.mkdirSync('electronCrashReporterSpec-') + originalTempDirectory = app.getPath('temp') + app.setPath('temp', tempDirectory) + }) + + after(function () { + app.setPath('temp', originalTempDirectory) + }) + var fixtures = path.resolve(__dirname, 'fixtures') const generateSpecs = (description, browserWindowOpts) => { describe(description, function () { var w = null - var originalTempDirectory = null - var tempDirectory = null beforeEach(function () { w = new BrowserWindow(Object.assign({ show: false }, browserWindowOpts)) - tempDirectory = temp.mkdirSync('electronCrashReporterSpec-') - originalTempDirectory = app.getPath('temp') - app.setPath('temp', tempDirectory) }) afterEach(function () { - app.setPath('temp', originalTempDirectory) return closeWindow(w).then(function () { w = null }) }) @@ -77,13 +85,15 @@ describe('crashReporter module', function () { it('should not send minidump if uploadToServer is false', function (done) { this.timeout(120000) - if (process.platform === 'darwin') { - crashReporter.setUploadToServer(false) - } - let server let dumpFile - let crashesDir + let crashesDir = crashReporter.getCrashesDirectory() + const existingDumpFiles = new Set() + if (process.platform === 'darwin') { + // crashpad puts the dump files in the "completed" subdirectory + crashesDir = path.join(crashesDir, 'completed') + crashReporter.setUploadToServer(false) + } const testDone = (uploaded) => { if (uploaded) { return done(new Error('fail')) @@ -93,7 +103,6 @@ describe('crashReporter module', function () { crashReporter.setUploadToServer(true) } assert(fs.existsSync(dumpFile)) - fs.unlinkSync(dumpFile) done() } @@ -103,7 +112,7 @@ describe('crashReporter module', function () { if (err) { return } - const dumps = files.filter((file) => /\.dmp$/.test(file)) + const dumps = files.filter((file) => /\.dmp$/.test(file) && !existingDumpFiles.has(file)) if (!dumps.length) { return } @@ -111,34 +120,17 @@ describe('crashReporter module', function () { dumpFile = path.join(crashesDir, dumps[0]) clearInterval(pollInterval) // dump file should not be deleted when not uploading, so we wait - // 500 ms and assert it still exists in `testDone` - setTimeout(testDone, 500) + // 1s and assert it still exists in `testDone` + setTimeout(testDone, 1000) }) } - remote.ipcMain.once('set-crash-directory', (event, dir) => { - if (process.platform === 'linux') { - crashesDir = dir - } else { - crashesDir = crashReporter.getCrashesDirectory() - if (process.platform === 'darwin') { - // crashpad uses an extra subdirectory - crashesDir = path.join(crashesDir, 'completed') - } - } - - // Before starting, remove all dump files in the crash directory. - // This is required because: - // - mac crashpad not seem to allow changing the crash directory after - // the first "start" call. - // - Other tests in this suite may leave dumps there. - // - We want to verify in `testDone` that a dump file is created and - // not deleted. + remote.ipcMain.once('list-existing-dumps', (event) => { fs.readdir(crashesDir, (err, files) => { if (!err) { for (const file of files) { if (/\.dmp$/.test(file)) { - fs.unlinkSync(path.join(crashesDir, file)) + existingDumpFiles.add(file) } } } diff --git a/spec/fixtures/api/crash.html b/spec/fixtures/api/crash.html index 6f013a2c7b..6a1433a0e6 100644 --- a/spec/fixtures/api/crash.html +++ b/spec/fixtures/api/crash.html @@ -17,7 +17,7 @@ crashReporter.start({ } }); if (!uploadToServer) { - ipcRenderer.sendSync('set-crash-directory', crashReporter.getCrashesDirectory()) + ipcRenderer.sendSync('list-existing-dumps') } setImmediate(function() { process.crash(); }); From 59fe7d3dbbe539f5fcdaf5fb7cb1e33c0ffe3307 Mon Sep 17 00:00:00 2001 From: Tasuku Uno Date: Thu, 6 Apr 2017 11:38:59 +0900 Subject: [PATCH 067/143] :memo: Fix document of MimeTypedBuffer Object [ci skip] --- docs/api/structures/mime-typed-buffer.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/api/structures/mime-typed-buffer.md b/docs/api/structures/mime-typed-buffer.md index dc1a20d28f..08e5cd47a4 100644 --- a/docs/api/structures/mime-typed-buffer.md +++ b/docs/api/structures/mime-typed-buffer.md @@ -1,4 +1,4 @@ # MimeTypedBuffer Object * `mimeType` String - The mimeType of the Buffer that you are sending -* `buffer` Buffer - The actual Buffer content +* `data` Buffer - The actual Buffer content From 95e782d26cf034280af80393b49ff0494d448969 Mon Sep 17 00:00:00 2001 From: Vadim Macagon Date: Thu, 6 Apr 2017 16:04:19 +1000 Subject: [PATCH 068/143] Fix link to the Upgrading Chrome doc --- docs/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/README.md b/docs/README.md index 24b23f92a7..e36eef9dd2 100644 --- a/docs/README.md +++ b/docs/README.md @@ -103,6 +103,6 @@ an issue: * [Debug Instructions (Windows)](development/debug-instructions-windows.md) * [Setting Up Symbol Server in debugger](development/setting-up-symbol-server.md) * [Documentation Styleguide](styleguide.md) -* [Updating Chrome](development/updating-chrome.md) +* [Upgrading Chrome](development/upgrading-chrome.md) * [Chromium Development](development/chromium-development.md) * [V8 Development](development/v8-development.md) From 0eed821788197da39e658771d19ff87596de8b69 Mon Sep 17 00:00:00 2001 From: ZhangYu Date: Thu, 6 Apr 2017 15:06:02 +0800 Subject: [PATCH 069/143] Update menu.md --- docs-translations/zh-CN/api/menu.md | 185 +++++++++------------------- 1 file changed, 58 insertions(+), 127 deletions(-) diff --git a/docs-translations/zh-CN/api/menu.md b/docs-translations/zh-CN/api/menu.md index 5d31d62f1a..ebccfe5ee9 100644 --- a/docs-translations/zh-CN/api/menu.md +++ b/docs-translations/zh-CN/api/menu.md @@ -19,6 +19,8 @@ 在 macOS 上设置应用菜单 `menu`。 在 windows 和 linux,是为每个窗口都在其顶部设置菜单 `menu`。 +设置为 `null` 时,将在 Windows 和 Linux 上删除菜单条,但在 macOS 系统中无效。 + **注意:** 这个API必须在 `app` 模块的 `ready` 事件后调用。 #### `Menu.getApplicationMenu()` @@ -29,7 +31,7 @@ * `action` String -发送 `action` 给应用的第一个响应器.这个用来模仿 Cocoa 菜单的默认行为,通常你只需要使用 `MenuItem` 的属性 `role`. +发送 `action` 给应用的第一个响应器.这个用来模仿 Cocoa 菜单的默认行为,通常你只需要使用 [`MenuItem`](menu-item.md) 的属性 [`role`](menu-item.md#roles). 查看更多 macOS 的原生 action [macOS Cocoa Event Handling Guide](https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/EventOverview/EventArchitecture/EventArchitecture.html#//apple_ref/doc/uid/10000060i-CH3-SW7) . @@ -47,15 +49,23 @@ `menu` 对象有如下实例方法 -#### `menu.popup([browserWindow, x, y, positioningItem])` +#### `menu.popup([browserWindow, options])` -* `browserWindow` BrowserWindow (可选) - 默认为 `null`. -* `x` Number (可选) - 默认为 -1. -* `y` Number (**必须** 如果x设置了) - 默认为 -1. -* `positioningItem` Number (可选) _macOS_ - 在指定坐标鼠标位置下面的菜单项的索引. 默认为 +* `browserWindow` BrowserWindow (可选) - 默认为当前激活的窗口. +* `options` Object (可选) + * `x` Number (可选) - 默认为当前光标所在的位置. + * `y` Number (**必须** 如果x设置了) - 默认为当前光标所在的位置. + * `async` Boolean (可选) - 设置为 `true` 时,调用这个方法会立即返回。设置为 `false` 时,当菜单被选择或者被关闭时才会返回。默认为 `false`。 + * `positioningItem` Number (可选) _macOS_ - 指定坐标鼠标位置下面的菜单项的索引. 默认为 -1. -在 `browserWindow` 中弹出 context menu .你可以选择性地提供指定的 `x, y` 来设置菜单应该放在哪里,否则它将默认地放在当前鼠标的位置. +在 `browserWindow` 中弹出菜单. + +#### `menu.closePopup([browserWindow])` + +* `browserWindow` BrowserWindow (可选) - 默认为当前激活的窗口. + +在 `browserWindow` 关闭菜单. #### `menu.append(menuItem)` @@ -95,76 +105,36 @@ const template = [ { label: 'Edit', submenu: [ - { - role: 'undo' - }, - { - role: 'redo' - }, - { - type: 'separator' - }, - { - role: 'cut' - }, - { - role: 'copy' - }, - { - role: 'paste' - }, - { - role: 'pasteandmatchstyle' - }, - { - role: 'delete' - }, - { - role: 'selectall' - } + {role: 'undo'}, + {role: 'redo'}, + {type: 'separator'}, + {role: 'cut'}, + {role: 'copy'}, + {role: 'paste'}, + {role: 'pasteandmatchstyle'}, + {role: 'delete'}, + {role: 'selectall'} ] }, { label: 'View', submenu: [ - { - role: 'reload' - }, - { - role: 'forcereload' - }, - { - role: 'toggledevtools' - }, - { - type: 'separator' - }, - { - role: 'resetzoom' - }, - { - role: 'zoomin' - }, - { - role: 'zoomout' - }, - { - type: 'separator' - }, - { - role: 'togglefullscreen' - } + {role: 'reload'}, + {role: 'forcereload'}, + {role: 'toggledevtools'}, + {type: 'separator'}, + {role: 'resetzoom'}, + {role: 'zoomin'}, + {role: 'zoomout'}, + {type: 'separator'}, + {role: 'togglefullscreen'} ] }, { role: 'window', submenu: [ - { - role: 'minimize' - }, - { - role: 'close' - } + {role: 'minimize'}, + {role: 'close'} ] }, { @@ -182,76 +152,37 @@ if (process.platform === 'darwin') { template.unshift({ label: app.getName(), submenu: [ - { - role: 'about' - }, - { - type: 'separator' - }, - { - role: 'services', - submenu: [] - }, - { - type: 'separator' - }, - { - role: 'hide' - }, - { - role: 'hideothers' - }, - { - role: 'unhide' - }, - { - type: 'separator' - }, - { - role: 'quit' - } + {role: 'about'}, + {type: 'separator'}, + {role: 'services', submenu: []}, + {type: 'separator'}, + {role: 'hide'}, + {role: 'hideothers'}, + {role: 'unhide'}, + {type: 'separator'}, + {role: 'quit'} ] }) - // Edit menu. + + // Edit menu template[1].submenu.push( - { - type: 'separator' - }, + {type: 'separator'}, { label: 'Speech', submenu: [ - { - role: 'startspeaking' - }, - { - role: 'stopspeaking' - } + {role: 'startspeaking'}, + {role: 'stopspeaking'} ] } ) - // Window menu. + + // Window menu template[3].submenu = [ - { - label: 'Close', - accelerator: 'CmdOrCtrl+W', - role: 'close' - }, - { - label: 'Minimize', - accelerator: 'CmdOrCtrl+M', - role: 'minimize' - }, - { - label: 'Zoom', - role: 'zoom' - }, - { - type: 'separator' - }, - { - label: 'Bring All to Front', - role: 'front' - } + {role: 'close'}, + {role: 'minimize'}, + {role: 'zoom'}, + {type: 'separator'}, + {role: 'front'} ] } From c305517957eb68ca7d42ff0dbd50a61c5ab4b596 Mon Sep 17 00:00:00 2001 From: ZhangYu Date: Thu, 6 Apr 2017 15:06:46 +0800 Subject: [PATCH 070/143] Update menu-item.md --- docs-translations/zh-CN/api/menu-item.md | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/docs-translations/zh-CN/api/menu-item.md b/docs-translations/zh-CN/api/menu-item.md index c2091674a5..75c3b935fd 100644 --- a/docs-translations/zh-CN/api/menu-item.md +++ b/docs-translations/zh-CN/api/menu-item.md @@ -15,26 +15,24 @@ * `menuItem` MenuItem * `browserWindow` BrowserWindow * `event` Event - * `role` String (可选) - 定义菜单项的行为,在指定 `click` 属性时将会被忽略。 - * `type` String (可选) - 取值 `normal`, `separator`, `submenu`, `checkbox` or `radio`。 + * `role` String (可选) - 定义菜单项的行为,在指定 `click` 属性时将会被忽略。参见 [roles](#roles). + * `type` String (可选) - 取值 `normal`, `separator`, `submenu`, `checkbox` 或 `radio`。 * `label` String - (可选) * `sublabel` String - (可选) * `accelerator` [Accelerator](accelerator.md) (可选) * `icon` ([NativeImage](native-image.md) | String) (可选) * `enabled` Boolean (可选) - 如果为 false,菜单项将显示为灰色不可点击。 - unclickable. * `visible` Boolean (可选) - 如果为 false,菜单项将完全隐藏。 * `checked` Boolean (可选) - 只为 `checkbox` 或 `radio` 类型的菜单项。 * `submenu` (MenuItemConstructorOptions[] | Menu) (可选) - 应当作为 `submenu` 菜单项的特定类型,当它作为 `type: 'submenu'` 菜单项的特定类型时可以忽略。如果它的值不是 `Menu`,将自动转为 `Menu.buildFromTemplate`。 - * `id` String (可选) - 标志一个菜单的唯一性。如果被定义使用,它将被用作这个菜单项的参考位置属性。 + * `id` String (可选) - 菜单的唯一标识。如果被定义使用,它将被用作这个菜单项的参考位置属性。 * `position` String (可选) - 定义菜单的具体指定位置信息。 -在创建菜单项时,如果有匹配的方法,建议指定 `role` 属性, -而不是试图手动实现在一个 `click` 函数中的行为。 -内置的 `role` 行为将提供最好的原生体验。 +### Roles +Roles 允许菜单项有预定义的行为。最好为每个菜单项指定一个行为,而不是自己实现一个 `click` 函数中的行为。内置的 `role` 行为将提供最好的原生体验。 + +当使用 `role` 时,`label` 和 `accelerator` 的值是可选的,会针对每个平台设置默认值。 -当使用 `role' 时,`label' 和 `accelerator` 是可选的,默认为 -到每个平台的适当值。 `role`属性值可以为: @@ -56,6 +54,8 @@ * `resetzoom` - 将对焦页面的缩放级别重置为原始大小 * `zoomin` - 将聚焦页面缩小10% * `zoomout` - 将聚焦页面放大10% +* `editMenu` - 完整的默认 "Edit" 编辑菜单(拷贝,黏贴,等) +* `windowMenu` - 完整的默认 "Window" 窗口菜单(最小化,关闭,等) 在 macOS 上,`role` 还可以有以下值: From a7d9230497a9dbeed0cf57aaaf4583f4434169b8 Mon Sep 17 00:00:00 2001 From: ZhangYu Date: Thu, 6 Apr 2017 17:29:06 +0800 Subject: [PATCH 071/143] Update accelerator.md --- docs-translations/zh-CN/api/accelerator.md | 25 +++++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) diff --git a/docs-translations/zh-CN/api/accelerator.md b/docs-translations/zh-CN/api/accelerator.md index 0b1e2cd3f4..0e6d44b742 100644 --- a/docs-translations/zh-CN/api/accelerator.md +++ b/docs-translations/zh-CN/api/accelerator.md @@ -4,15 +4,30 @@ 例如: -* `Command+A` -* `Ctrl+Shift+Z` +* `CommandOrControl+A` +* `CommandOrControl+Shift+Z` + +快捷键使用 [`globalShortcut`](global-shortcut.md)里的 [`register`](global-shortcut.md#globalshortcutregisteraccelerator-callback) 方法注册 + +```javascript +const {app, globalShortcut} = require('electron') + +app.on('ready', () => { + // Register a 'CommandOrControl+Y' shortcut listener. + globalShortcut.register('CommandOrControl+Y', () => { + // Do stuff when Y and either Command/Control is pressed. + }) +}) +``` ## 运行平台相关的提示 在 Linux 和 Windows 上,`Command` 键并不存在,因此我们通常用 `CommandOrControl` 来表示“在 macOS 下为 `Command` 键,但在 Linux 和 Windows 下为 `Control` 键。 -`Super` 键是指 Linux 和 Windows 上的 `Windows` 键,但是在 macOS 下为 `Command` 键。 +使用 `Alt` 键 代替 `Option`。`Option` 键只在 macOS 系统上存在,而 `Alt` 键在任何系统上都有效。 + +`Super` 键是指 Linux 和 Windows 上的 `Windows` 键,但是在 macOS 下为 `Cmd` 键。 ## 可用的功能按键 @@ -20,6 +35,8 @@ Linux 和 Windows 下为 `Control` 键。 * `Control`(缩写为 `Ctrl`) * `CommandOrControl`(缩写为 `CmdOrCtrl`) * `Alt` +* `Option` +* `AltGr` * `Shift` * `Super` @@ -31,6 +48,7 @@ Linux 和 Windows 下为 `Control` 键。 * 类似与 `~`、`!`、`@`、`#`、`$` 的标点符号。 * `Plus` * `Space` +* `Tab` * `Backspace` * `Delete` * `Insert` @@ -41,3 +59,4 @@ Linux 和 Windows 下为 `Control` 键。 * `Escape`(缩写为 `Esc`) * `VolumeUp`、`VolumeDown` 和 `VolumeMute` * `MediaNextTrack`、`MediaPreviousTrack`、`MediaStop` 和 `MediaPlayPause` +* `PrintScreen` From 7f28b7a151ee8b5c9ccd197d7d92535f3b909788 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Thu, 6 Apr 2017 09:47:33 -0700 Subject: [PATCH 072/143] Add failing spec for fork --eval message bug --- spec/node-spec.js | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/spec/node-spec.js b/spec/node-spec.js index 98db1efeb0..07f562f7c9 100644 --- a/spec/node-spec.js +++ b/spec/node-spec.js @@ -91,6 +91,16 @@ describe('node feature', function () { done() }) }) + + it('works when sending message to a forked process using the --eval argument', function (done) { + const source = "process.on('message', function (msg) { process.send(msg) })" + const forked = ChildProcess.fork('--eval', [source]) + forked.on('message', (message) => { + assert.equal(message, 'hello') + done() + }) + forked.send('hello') + }) }) describe('child_process.spawn', function () { From c3798be9b8e0508e821c9b5ea5db1ac72cac7ba3 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Thu, 6 Apr 2017 09:48:04 -0700 Subject: [PATCH 073/143] Upgrade node for fork --eval cherry pick fix --- vendor/node | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vendor/node b/vendor/node index a6663598aa..3fe90cfcf5 160000 --- a/vendor/node +++ b/vendor/node @@ -1 +1 @@ -Subproject commit a6663598aa78832e7955cb93c51a098eac787abb +Subproject commit 3fe90cfcf54dd946980e59daf550a7cdb2317c8f From 588f699d56aef20ea94ed34f3283bc61bd28ee17 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Thu, 6 Apr 2017 09:52:52 -0700 Subject: [PATCH 074/143] :art: --- spec/node-spec.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/spec/node-spec.js b/spec/node-spec.js index 07f562f7c9..8f1d7163bb 100644 --- a/spec/node-spec.js +++ b/spec/node-spec.js @@ -92,10 +92,10 @@ describe('node feature', function () { }) }) - it('works when sending message to a forked process using the --eval argument', function (done) { - const source = "process.on('message', function (msg) { process.send(msg) })" + it('works when sending a message to a process forked with the --eval argument', function (done) { + const source = "process.on('message', (message) => { process.send(message) })" const forked = ChildProcess.fork('--eval', [source]) - forked.on('message', (message) => { + forked.once('message', (message) => { assert.equal(message, 'hello') done() }) From ad0a22af23b37a826999c9ac3cf66eb002767e10 Mon Sep 17 00:00:00 2001 From: ZhangYu Date: Fri, 7 Apr 2017 10:03:21 +0800 Subject: [PATCH 075/143] Update README.md --- docs-translations/zh-CN/README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docs-translations/zh-CN/README.md b/docs-translations/zh-CN/README.md index 8d1fd8500d..706738d60d 100644 --- a/docs-translations/zh-CN/README.md +++ b/docs-translations/zh-CN/README.md @@ -26,6 +26,7 @@ * [使用 Widevine CDM 插件](tutorial/using-widevine-cdm-plugin.md) * [通过自动化持续集成系统(CI)进行测试 (Travis, Jenkins)](tutorial/testing-on-headless-ci.md) * [离屏渲染](tutorial/offscreen-rendering.md) +* [快捷键](tutorial/keyboard-shortcuts.md) ## 教程 @@ -96,3 +97,6 @@ * [调试步骤 (Windows)](development/debug-instructions-windows.md) * [在调试中使用 Symbol Server](development/setting-up-symbol-server.md) * [文档风格指南](styleguide.md) +* [升级 Chrome](development/upgrading-chrome.md) +* [Chromium 开发](development/chromium-development.md) +* [V8 开发](development/v8-development.md) From a6f5c35fa64d7d0ce6ea80985e5db5185b2ba733 Mon Sep 17 00:00:00 2001 From: ZhangYu Date: Fri, 7 Apr 2017 10:10:12 +0800 Subject: [PATCH 076/143] Create bluetooth-device.md --- docs-translations/zh-CN/api/structures/bluetooth-device.md | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 docs-translations/zh-CN/api/structures/bluetooth-device.md diff --git a/docs-translations/zh-CN/api/structures/bluetooth-device.md b/docs-translations/zh-CN/api/structures/bluetooth-device.md new file mode 100644 index 0000000000..2fa0c799a1 --- /dev/null +++ b/docs-translations/zh-CN/api/structures/bluetooth-device.md @@ -0,0 +1,4 @@ +# 蓝牙设备 Object + +* `deviceName` String +* `deviceId` String From 202b8e40c4a114e3ea10aa509401dedc22c736e1 Mon Sep 17 00:00:00 2001 From: ZhangYu Date: Fri, 7 Apr 2017 10:14:51 +0800 Subject: [PATCH 077/143] Create certificate-principal.md --- .../zh-CN/api/structures/certificate-principal.md | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 docs-translations/zh-CN/api/structures/certificate-principal.md diff --git a/docs-translations/zh-CN/api/structures/certificate-principal.md b/docs-translations/zh-CN/api/structures/certificate-principal.md new file mode 100644 index 0000000000..f4184e8faf --- /dev/null +++ b/docs-translations/zh-CN/api/structures/certificate-principal.md @@ -0,0 +1,8 @@ +# CertificatePrincipal Object + +* `commonName` String - 通用名 +* `organizations` String[] - 组织名 +* `organizationUnits` String[] - 组织单位名称 +* `locality` String - 地区 +* `state` String - 州或省 +* `country` String - 国家或地区 From 5986d36059d68b02e5fecb1caeeeb90989df5ba8 Mon Sep 17 00:00:00 2001 From: ZhangYu Date: Fri, 7 Apr 2017 10:16:32 +0800 Subject: [PATCH 078/143] Create certificate.md --- .../zh-CN/api/structures/certificate.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 docs-translations/zh-CN/api/structures/certificate.md diff --git a/docs-translations/zh-CN/api/structures/certificate.md b/docs-translations/zh-CN/api/structures/certificate.md new file mode 100644 index 0000000000..546cefb42d --- /dev/null +++ b/docs-translations/zh-CN/api/structures/certificate.md @@ -0,0 +1,12 @@ +# Certificate Object 证书对象 + +* `data` String - PEM encoded data +* `issuer` [CertificatePrincipal](certificate-principal.md) - Issuer principal +* `issuerName` String - Issuer's Common Name +* `issuerCert` Certificate - Issuer certificate (if not self-signed) +* `subject` [CertificatePrincipal](certificate-principal.md) - Subject principal +* `subjectName` String - Subject's Common Name +* `serialNumber` String - Hex value represented string +* `validStart` Number - Start date of the certificate being valid in seconds +* `validExpiry` Number - End date of the certificate being valid in seconds +* `fingerprint` String - Fingerprint of the certificate From 9e33f2efeb65850f6b791f4969de6aa2d1a9900a Mon Sep 17 00:00:00 2001 From: ZhangYu Date: Fri, 7 Apr 2017 10:24:11 +0800 Subject: [PATCH 079/143] Create cookie.md --- docs-translations/zh-CN/api/structures/cookie.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 docs-translations/zh-CN/api/structures/cookie.md diff --git a/docs-translations/zh-CN/api/structures/cookie.md b/docs-translations/zh-CN/api/structures/cookie.md new file mode 100644 index 0000000000..79f21e1080 --- /dev/null +++ b/docs-translations/zh-CN/api/structures/cookie.md @@ -0,0 +1,12 @@ +# Cookie Object + +* `name` String - cookie 的名称. +* `value` String - cookie 的值. +* `domain` String (optional) - cookie 的域名. +* `hostOnly` Boolean (optional) - cookie 的类型是否为 host-only. +* `path` String (optional) - cookie 的路径. +* `secure` Boolean (optional) - cookie 是否标记为安全. +* `httpOnly` Boolean (optional) - cookie 是否只标记为 HTTP. +* `session` Boolean (optional) - cookie 是否是一个 session cookie, 还是一个带有过期时间的持续 cookie. +* `expirationDate` Double (optional) - cookie 距离 UNIX 时间戳的过期时间,数值为秒。不需要提供给 session + cookies. From 6a4e7225e2b967e1526a0fc630831f4a88611dbb Mon Sep 17 00:00:00 2001 From: ZhangYu Date: Fri, 7 Apr 2017 10:25:22 +0800 Subject: [PATCH 080/143] Create crash-report.md --- docs-translations/zh-CN/api/structures/crash-report.md | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 docs-translations/zh-CN/api/structures/crash-report.md diff --git a/docs-translations/zh-CN/api/structures/crash-report.md b/docs-translations/zh-CN/api/structures/crash-report.md new file mode 100644 index 0000000000..f16b5acdb6 --- /dev/null +++ b/docs-translations/zh-CN/api/structures/crash-report.md @@ -0,0 +1,4 @@ +# 崩溃报告的对象 + +* `date` String +* `ID` Integer From e811f809b54daf5cf36f5cde9d7dc7ad5bb78509 Mon Sep 17 00:00:00 2001 From: ZhangYu Date: Fri, 7 Apr 2017 10:36:50 +0800 Subject: [PATCH 081/143] Create desktop-capturer-source.md --- .../zh-CN/api/structures/desktop-capturer-source.md | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 docs-translations/zh-CN/api/structures/desktop-capturer-source.md diff --git a/docs-translations/zh-CN/api/structures/desktop-capturer-source.md b/docs-translations/zh-CN/api/structures/desktop-capturer-source.md new file mode 100644 index 0000000000..1ab3db1741 --- /dev/null +++ b/docs-translations/zh-CN/api/structures/desktop-capturer-source.md @@ -0,0 +1,7 @@ +# DesktopCapturerSource Object + +* `id` String - 窗口或者屏幕的标识符,当调用 [`navigator.webkitGetUserMedia`] 时可以被当成 `chromeMediaSourceId` 使用。 +标识符的格式为`window:XX` 或 `screen:XX`,`XX` 是一个随机生成的数字. +* `name` String - 窗口的来源将被命名为 `Entire Screen` 或 `Screen `,而窗口来源的名字将会和窗口的标题匹配. +* `thumbnail` [NativeImage](../native-image.md) - 缩略图. **注:** 通过 `desktopCapturer.getSources` 方法, +不能保证缩略图的大小与 `options` 中指定的 `thumbnailSize` 相同。实际大小取决于窗口或者屏幕的比例。 From 27a45009b3f5b6e6a5c7a1a5595b7735b87f6123 Mon Sep 17 00:00:00 2001 From: ZhangYu Date: Fri, 7 Apr 2017 10:40:47 +0800 Subject: [PATCH 082/143] Create display.md --- docs-translations/zh-CN/api/structures/display.md | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 docs-translations/zh-CN/api/structures/display.md diff --git a/docs-translations/zh-CN/api/structures/display.md b/docs-translations/zh-CN/api/structures/display.md new file mode 100644 index 0000000000..f5f5b9866b --- /dev/null +++ b/docs-translations/zh-CN/api/structures/display.md @@ -0,0 +1,15 @@ +# Display Object + +* `id` Number - Unique identifier associated with the display. +* `rotation` Number - Can be 0, 90, 180, 270, represents screen rotation in + clock-wise degrees. +* `scaleFactor` Number - Output device's pixel scale factor. +* `touchSupport` String - Can be `available`, `unavailable`, `unknown`. +* `bounds` [Rectangle](rectangle.md) +* `size` [Size](size.md) +* `workArea` [Rectangle](rectangle.md) +* `workAreaSize` [Size](size.md) + +The `Display` object represents a physical display connected to the system. A +fake `Display` may exist on a headless system, or a `Display` may correspond to +a remote, virtual display. From 1fb0a5f0da6e3e6a1238d174c63de527d752a4c2 Mon Sep 17 00:00:00 2001 From: ZhangYu Date: Fri, 7 Apr 2017 10:42:04 +0800 Subject: [PATCH 083/143] Create file-filter.md --- docs-translations/zh-CN/api/structures/file-filter.md | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 docs-translations/zh-CN/api/structures/file-filter.md diff --git a/docs-translations/zh-CN/api/structures/file-filter.md b/docs-translations/zh-CN/api/structures/file-filter.md new file mode 100644 index 0000000000..014350a60f --- /dev/null +++ b/docs-translations/zh-CN/api/structures/file-filter.md @@ -0,0 +1,4 @@ +# FileFilter Object + +* `name` String +* `extensions` String[] From 913644504c703e4a5e4a4eb1c14463ada0409d18 Mon Sep 17 00:00:00 2001 From: ZhangYu Date: Fri, 7 Apr 2017 10:42:39 +0800 Subject: [PATCH 084/143] Create jump-list-category.md --- .../api/structures/jump-list-category.md | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 docs-translations/zh-CN/api/structures/jump-list-category.md diff --git a/docs-translations/zh-CN/api/structures/jump-list-category.md b/docs-translations/zh-CN/api/structures/jump-list-category.md new file mode 100644 index 0000000000..07627e78c9 --- /dev/null +++ b/docs-translations/zh-CN/api/structures/jump-list-category.md @@ -0,0 +1,21 @@ +# JumpListCategory Object + +* `type` String (optional) - One of the following: + * `tasks` - Items in this category will be placed into the standard `Tasks` + category. There can be only one such category, and it will always be + displayed at the bottom of the Jump List. + * `frequent` - Displays a list of files frequently opened by the app, the + name of the category and its items are set by Windows. + * `recent` - Displays a list of files recently opened by the app, the name + of the category and its items are set by Windows. Items may be added to + this category indirectly using `app.addRecentDocument(path)`. + * `custom` - Displays tasks or file links, `name` must be set by the app. +* `name` String (optional) - Must be set if `type` is `custom`, otherwise it should be + omitted. +* `items` JumpListItem[] (optional) - Array of [`JumpListItem`](jump-list-item.md) objects if `type` is `tasks` or + `custom`, otherwise it should be omitted. + +**Note:** If a `JumpListCategory` object has neither the `type` nor the `name` +property set then its `type` is assumed to be `tasks`. If the `name` property +is set but the `type` property is omitted then the `type` is assumed to be +`custom`. From aa3703021118e066dc3c83efc663ff6acaa74728 Mon Sep 17 00:00:00 2001 From: ZhangYu Date: Fri, 7 Apr 2017 10:43:05 +0800 Subject: [PATCH 085/143] Create jump-list-item.md --- .../zh-CN/api/structures/jump-list-item.md | 28 +++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 docs-translations/zh-CN/api/structures/jump-list-item.md diff --git a/docs-translations/zh-CN/api/structures/jump-list-item.md b/docs-translations/zh-CN/api/structures/jump-list-item.md new file mode 100644 index 0000000000..f17d72e0a4 --- /dev/null +++ b/docs-translations/zh-CN/api/structures/jump-list-item.md @@ -0,0 +1,28 @@ +# JumpListItem Object + +* `type` String (optional) - One of the following: + * `task` - A task will launch an app with specific arguments. + * `separator` - Can be used to separate items in the standard `Tasks` + category. + * `file` - A file link will open a file using the app that created the + Jump List, for this to work the app must be registered as a handler for + the file type (though it doesn't have to be the default handler). +* `path` String (optional) - Path of the file to open, should only be set if `type` is + `file`. +* `program` String (optional) - Path of the program to execute, usually you should + specify `process.execPath` which opens the current program. Should only be + set if `type` is `task`. +* `args` String (optional) - The command line arguments when `program` is executed. Should + only be set if `type` is `task`. +* `title` String (optional) - The text to be displayed for the item in the Jump List. + Should only be set if `type` is `task`. +* `description` String (optional) - Description of the task (displayed in a tooltip). + Should only be set if `type` is `task`. +* `iconPath` String (optional) - The absolute path to an icon to be displayed in a + Jump List, which can be an arbitrary resource file that contains an icon + (e.g. `.ico`, `.exe`, `.dll`). You can usually specify `process.execPath` to + show the program icon. +* `iconIndex` Number (optional) - The index of the icon in the resource file. If a + resource file contains multiple icons this value can be used to specify the + zero-based index of the icon that should be displayed for this task. If a + resource file contains only one icon, this property should be set to zero. From 32ee0f05e39b8104008db186d23db35c682a3b4a Mon Sep 17 00:00:00 2001 From: ZhangYu Date: Fri, 7 Apr 2017 10:43:51 +0800 Subject: [PATCH 086/143] Create memory-usage-details.md --- .../zh-CN/api/structures/memory-usage-details.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 docs-translations/zh-CN/api/structures/memory-usage-details.md diff --git a/docs-translations/zh-CN/api/structures/memory-usage-details.md b/docs-translations/zh-CN/api/structures/memory-usage-details.md new file mode 100644 index 0000000000..d77e07dedf --- /dev/null +++ b/docs-translations/zh-CN/api/structures/memory-usage-details.md @@ -0,0 +1,5 @@ +# MemoryUsageDetails Object + +* `count` Number +* `size` Number +* `liveSize` Number From b117f14c2ad8d9dddfa6daf33e94f29f1fb46803 Mon Sep 17 00:00:00 2001 From: ZhangYu Date: Fri, 7 Apr 2017 10:44:09 +0800 Subject: [PATCH 087/143] Create mime-typed-buffer.md --- docs-translations/zh-CN/api/structures/mime-typed-buffer.md | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 docs-translations/zh-CN/api/structures/mime-typed-buffer.md diff --git a/docs-translations/zh-CN/api/structures/mime-typed-buffer.md b/docs-translations/zh-CN/api/structures/mime-typed-buffer.md new file mode 100644 index 0000000000..08e5cd47a4 --- /dev/null +++ b/docs-translations/zh-CN/api/structures/mime-typed-buffer.md @@ -0,0 +1,4 @@ +# MimeTypedBuffer Object + +* `mimeType` String - The mimeType of the Buffer that you are sending +* `data` Buffer - The actual Buffer content From 30fe4a6f2bb2219ced8b2eb763780c9c89bad997 Mon Sep 17 00:00:00 2001 From: ZhangYu Date: Fri, 7 Apr 2017 10:44:26 +0800 Subject: [PATCH 088/143] Create point.md --- docs-translations/zh-CN/api/structures/point.md | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 docs-translations/zh-CN/api/structures/point.md diff --git a/docs-translations/zh-CN/api/structures/point.md b/docs-translations/zh-CN/api/structures/point.md new file mode 100644 index 0000000000..69b87cbdf9 --- /dev/null +++ b/docs-translations/zh-CN/api/structures/point.md @@ -0,0 +1,4 @@ +# Point Object + +* `x` Number +* `y` Number From 7a552da192600094bd3f03e552488b975b9df99a Mon Sep 17 00:00:00 2001 From: ZhangYu Date: Fri, 7 Apr 2017 10:44:41 +0800 Subject: [PATCH 089/143] Create rectangle.md --- docs-translations/zh-CN/api/structures/rectangle.md | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 docs-translations/zh-CN/api/structures/rectangle.md diff --git a/docs-translations/zh-CN/api/structures/rectangle.md b/docs-translations/zh-CN/api/structures/rectangle.md new file mode 100644 index 0000000000..0cd000699e --- /dev/null +++ b/docs-translations/zh-CN/api/structures/rectangle.md @@ -0,0 +1,6 @@ +# Rectangle Object + +* `x` Number - The x coordinate of the origin of the rectangle +* `y` Number - The y coordinate of the origin of the rectangle +* `width` Number +* `height` Number From 6e36ec77701c6494f835b56edb7e118260718fa6 Mon Sep 17 00:00:00 2001 From: ZhangYu Date: Fri, 7 Apr 2017 10:45:00 +0800 Subject: [PATCH 090/143] Create remove-client-certificate.md --- .../zh-CN/api/structures/remove-client-certificate.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 docs-translations/zh-CN/api/structures/remove-client-certificate.md diff --git a/docs-translations/zh-CN/api/structures/remove-client-certificate.md b/docs-translations/zh-CN/api/structures/remove-client-certificate.md new file mode 100644 index 0000000000..7ec853f163 --- /dev/null +++ b/docs-translations/zh-CN/api/structures/remove-client-certificate.md @@ -0,0 +1,5 @@ +# RemoveClientCertificate Object + +* `type` String - `clientCertificate`. +* `origin` String - Origin of the server whose associated client certificate + must be removed from the cache. From bffec5e68e4dea24bd4dde168334a406752d7d0f Mon Sep 17 00:00:00 2001 From: ZhangYu Date: Fri, 7 Apr 2017 10:45:19 +0800 Subject: [PATCH 091/143] Create remove-password.md --- .../zh-CN/api/structures/remove-password.md | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 docs-translations/zh-CN/api/structures/remove-password.md diff --git a/docs-translations/zh-CN/api/structures/remove-password.md b/docs-translations/zh-CN/api/structures/remove-password.md new file mode 100644 index 0000000000..28a9ed8ae1 --- /dev/null +++ b/docs-translations/zh-CN/api/structures/remove-password.md @@ -0,0 +1,15 @@ +# RemovePassword Object + +* `type` String - `password`. +* `origin` String (optional) - When provided, the authentication info + related to the origin will only be removed otherwise the entire cache + will be cleared. +* `scheme` String (optional) - Scheme of the authentication. + Can be `basic`, `digest`, `ntlm`, `negotiate`. Must be provided if + removing by `origin`. +* `realm` String (optional) - Realm of the authentication. Must be provided if + removing by `origin`. +* `username` String (optional) - Credentials of the authentication. Must be + provided if removing by `origin`. +* `password` String (optional) - Credentials of the authentication. Must be + provided if removing by `origin`. From 826932199b7f961bd7ce5e375b97f77e47103afb Mon Sep 17 00:00:00 2001 From: ZhangYu Date: Fri, 7 Apr 2017 10:45:36 +0800 Subject: [PATCH 092/143] Create scrubber-item.md --- docs-translations/zh-CN/api/structures/scrubber-item.md | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 docs-translations/zh-CN/api/structures/scrubber-item.md diff --git a/docs-translations/zh-CN/api/structures/scrubber-item.md b/docs-translations/zh-CN/api/structures/scrubber-item.md new file mode 100644 index 0000000000..0dd3c4ff0f --- /dev/null +++ b/docs-translations/zh-CN/api/structures/scrubber-item.md @@ -0,0 +1,4 @@ +# ScrubberItem Object + +* `label` String - (Optional) The text to appear in this item +* `icon` NativeImage - (Optional) The image to appear in this item From 3475387d9cf2d32d457418e6ec7d0c661618db52 Mon Sep 17 00:00:00 2001 From: ZhangYu Date: Fri, 7 Apr 2017 10:45:50 +0800 Subject: [PATCH 093/143] Create segmented-control-segment.md --- .../zh-CN/api/structures/segmented-control-segment.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 docs-translations/zh-CN/api/structures/segmented-control-segment.md diff --git a/docs-translations/zh-CN/api/structures/segmented-control-segment.md b/docs-translations/zh-CN/api/structures/segmented-control-segment.md new file mode 100644 index 0000000000..ae01a07f32 --- /dev/null +++ b/docs-translations/zh-CN/api/structures/segmented-control-segment.md @@ -0,0 +1,5 @@ +# SegmentedControlSegment Object + +* `label` String - (Optional) The text to appear in this segment +* `icon` NativeImage - (Optional) The image to appear in this segment +* `enabled` Boolean - (Optional) Whether this segment is selectable. Default: true From e8f030af150bba60bc45197569cfd698cf3bbc04 Mon Sep 17 00:00:00 2001 From: ZhangYu Date: Fri, 7 Apr 2017 10:46:04 +0800 Subject: [PATCH 094/143] Create shortcut-details.md --- .../zh-CN/api/structures/shortcut-details.md | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 docs-translations/zh-CN/api/structures/shortcut-details.md diff --git a/docs-translations/zh-CN/api/structures/shortcut-details.md b/docs-translations/zh-CN/api/structures/shortcut-details.md new file mode 100644 index 0000000000..e7b272d099 --- /dev/null +++ b/docs-translations/zh-CN/api/structures/shortcut-details.md @@ -0,0 +1,15 @@ +# ShortcutDetails Object + +* `target` String - The target to launch from this shortcut. +* `cwd` String (optional) - The working directory. Default is empty. +* `args` String (optional) - The arguments to be applied to `target` when +launching from this shortcut. Default is empty. +* `description` String (optional) - The description of the shortcut. Default +is empty. +* `icon` String (optional) - The path to the icon, can be a DLL or EXE. `icon` +and `iconIndex` have to be set together. Default is empty, which uses the +target's icon. +* `iconIndex` Number (optional) - The resource ID of icon when `icon` is a +DLL or EXE. Default is 0. +* `appUserModelId` String (optional) - The Application User Model ID. Default +is empty. From 39111b9e34fbebf0db9e1d5fb15e024fec166199 Mon Sep 17 00:00:00 2001 From: ZhangYu Date: Fri, 7 Apr 2017 10:46:19 +0800 Subject: [PATCH 095/143] Create size.md --- docs-translations/zh-CN/api/structures/size.md | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 docs-translations/zh-CN/api/structures/size.md diff --git a/docs-translations/zh-CN/api/structures/size.md b/docs-translations/zh-CN/api/structures/size.md new file mode 100644 index 0000000000..1d9c8b1f5a --- /dev/null +++ b/docs-translations/zh-CN/api/structures/size.md @@ -0,0 +1,4 @@ +# Size Object + +* `width` Number +* `height` Number From a584785254b3cd5c1c840575acb613c7be81b3e4 Mon Sep 17 00:00:00 2001 From: ZhangYu Date: Fri, 7 Apr 2017 10:46:34 +0800 Subject: [PATCH 096/143] Create task.md --- docs-translations/zh-CN/api/structures/task.md | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 docs-translations/zh-CN/api/structures/task.md diff --git a/docs-translations/zh-CN/api/structures/task.md b/docs-translations/zh-CN/api/structures/task.md new file mode 100644 index 0000000000..61a28de879 --- /dev/null +++ b/docs-translations/zh-CN/api/structures/task.md @@ -0,0 +1,14 @@ +# Task Object + +* `program` String - Path of the program to execute, usually you should + specify `process.execPath` which opens the current program. +* `arguments` String - The command line arguments when `program` is + executed. +* `title` String - The string to be displayed in a JumpList. +* `description` String - Description of this task. +* `iconPath` String - The absolute path to an icon to be displayed in a + JumpList, which can be an arbitrary resource file that contains an icon. You + can usually specify `process.execPath` to show the icon of the program. +* `iconIndex` Number - The icon index in the icon file. If an icon file + consists of two or more icons, set this value to identify the icon. If an + icon file consists of one icon, this value is 0. From 3ba8a7516a187d521a7dc6341f64e204d1ec73ac Mon Sep 17 00:00:00 2001 From: ZhangYu Date: Fri, 7 Apr 2017 10:46:53 +0800 Subject: [PATCH 097/143] Create thumbar-button.md --- .../zh-CN/api/structures/thumbar-button.md | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 docs-translations/zh-CN/api/structures/thumbar-button.md diff --git a/docs-translations/zh-CN/api/structures/thumbar-button.md b/docs-translations/zh-CN/api/structures/thumbar-button.md new file mode 100644 index 0000000000..259195852a --- /dev/null +++ b/docs-translations/zh-CN/api/structures/thumbar-button.md @@ -0,0 +1,21 @@ +# ThumbarButton Object + +* `icon` [NativeImage](../native-image.md) - The icon showing in thumbnail + toolbar. +* `click` Function +* `tooltip` String (optional) - The text of the button's tooltip. +* `flags` String[] (optional) - Control specific states and behaviors of the + button. By default, it is `['enabled']`. + +The `flags` is an array that can include following `String`s: + +* `enabled` - The button is active and available to the user. +* `disabled` - The button is disabled. It is present, but has a visual state + indicating it will not respond to user action. +* `dismissonclick` - When the button is clicked, the thumbnail window closes + immediately. +* `nobackground` - Do not draw a button border, use only the image. +* `hidden` - The button is not shown to the user. +* `noninteractive` - The button is enabled but not interactive; no pressed + button state is drawn. This value is intended for instances where the button + is used in a notification. From 6b44692b0d51f07ab5d6db5c43b1035ca1620a42 Mon Sep 17 00:00:00 2001 From: ZhangYu Date: Fri, 7 Apr 2017 10:47:09 +0800 Subject: [PATCH 098/143] Create upload-blob.md --- docs-translations/zh-CN/api/structures/upload-blob.md | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 docs-translations/zh-CN/api/structures/upload-blob.md diff --git a/docs-translations/zh-CN/api/structures/upload-blob.md b/docs-translations/zh-CN/api/structures/upload-blob.md new file mode 100644 index 0000000000..be93cacb49 --- /dev/null +++ b/docs-translations/zh-CN/api/structures/upload-blob.md @@ -0,0 +1,4 @@ +# UploadBlob Object + +* `type` String - `blob`. +* `blobUUID` String - UUID of blob data to upload. From 05d59185b29c8784b1e529924b82b7edcd2ab1da Mon Sep 17 00:00:00 2001 From: ZhangYu Date: Fri, 7 Apr 2017 10:47:23 +0800 Subject: [PATCH 099/143] Create upload-data.md --- docs-translations/zh-CN/api/structures/upload-data.md | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 docs-translations/zh-CN/api/structures/upload-data.md diff --git a/docs-translations/zh-CN/api/structures/upload-data.md b/docs-translations/zh-CN/api/structures/upload-data.md new file mode 100644 index 0000000000..8e5c07725a --- /dev/null +++ b/docs-translations/zh-CN/api/structures/upload-data.md @@ -0,0 +1,6 @@ +# UploadData Object + +* `bytes` Buffer - Content being sent. +* `file` String - Path of file being uploaded. +* `blobUUID` String - UUID of blob data. Use [ses.getBlobData](../session.md#sesgetblobdataidentifier-callback) method + to retrieve the data. From 6089456c84da83d9c78edf92255373176e78d47f Mon Sep 17 00:00:00 2001 From: ZhangYu Date: Fri, 7 Apr 2017 10:47:37 +0800 Subject: [PATCH 100/143] Create upload-file-system.md --- .../zh-CN/api/structures/upload-file-system.md | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 docs-translations/zh-CN/api/structures/upload-file-system.md diff --git a/docs-translations/zh-CN/api/structures/upload-file-system.md b/docs-translations/zh-CN/api/structures/upload-file-system.md new file mode 100644 index 0000000000..d62b0a8ba7 --- /dev/null +++ b/docs-translations/zh-CN/api/structures/upload-file-system.md @@ -0,0 +1,9 @@ +# UploadFileSystem Object + +* `type` String - `fileSystem`. +* `filsSystemURL` String - FileSystem url to read data for upload. +* `offset` Integer - Defaults to `0`. +* `length` Integer - Number of bytes to read from `offset`. + Defaults to `0`. +* `modificationTime` Double - Last Modification time in + number of seconds sine the UNIX epoch. From ca584fcaf911ab7b4c8ac47dc2fe87b33d70a011 Mon Sep 17 00:00:00 2001 From: ZhangYu Date: Fri, 7 Apr 2017 10:47:52 +0800 Subject: [PATCH 101/143] Create upload-file.md --- docs-translations/zh-CN/api/structures/upload-file.md | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 docs-translations/zh-CN/api/structures/upload-file.md diff --git a/docs-translations/zh-CN/api/structures/upload-file.md b/docs-translations/zh-CN/api/structures/upload-file.md new file mode 100644 index 0000000000..8a21973014 --- /dev/null +++ b/docs-translations/zh-CN/api/structures/upload-file.md @@ -0,0 +1,9 @@ +# UploadFile Object + +* `type` String - `file`. +* `filePath` String - Path of file to be uploaded. +* `offset` Integer - Defaults to `0`. +* `length` Integer - Number of bytes to read from `offset`. + Defaults to `0`. +* `modificationTime` Double - Last Modification time in + number of seconds sine the UNIX epoch. From b6481fde142d45c6c802dd6e15f8267976660b29 Mon Sep 17 00:00:00 2001 From: ZhangYu Date: Fri, 7 Apr 2017 10:48:07 +0800 Subject: [PATCH 102/143] Create upload-raw-data.md --- docs-translations/zh-CN/api/structures/upload-raw-data.md | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 docs-translations/zh-CN/api/structures/upload-raw-data.md diff --git a/docs-translations/zh-CN/api/structures/upload-raw-data.md b/docs-translations/zh-CN/api/structures/upload-raw-data.md new file mode 100644 index 0000000000..4fe162311f --- /dev/null +++ b/docs-translations/zh-CN/api/structures/upload-raw-data.md @@ -0,0 +1,4 @@ +# UploadRawData Object + +* `type` String - `rawData`. +* `bytes` Buffer - Data to be uploaded. From 8a324a9375d7affd5ae44049182c9df11e613400 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Fri, 7 Apr 2017 09:01:28 -0700 Subject: [PATCH 103/143] Bump v1.6.6 --- atom/browser/resources/mac/Info.plist | 4 ++-- atom/browser/resources/win/atom.rc | 8 ++++---- atom/common/atom_version.h | 2 +- electron.gyp | 2 +- package.json | 2 +- 5 files changed, 9 insertions(+), 9 deletions(-) diff --git a/atom/browser/resources/mac/Info.plist b/atom/browser/resources/mac/Info.plist index 6fc30bf6a3..5509969014 100644 --- a/atom/browser/resources/mac/Info.plist +++ b/atom/browser/resources/mac/Info.plist @@ -17,9 +17,9 @@ CFBundleIconFile electron.icns CFBundleVersion - 1.6.5 + 1.6.6 CFBundleShortVersionString - 1.6.5 + 1.6.6 LSApplicationCategoryType public.app-category.developer-tools LSMinimumSystemVersion diff --git a/atom/browser/resources/win/atom.rc b/atom/browser/resources/win/atom.rc index 34879fe41e..d572d20ada 100644 --- a/atom/browser/resources/win/atom.rc +++ b/atom/browser/resources/win/atom.rc @@ -56,8 +56,8 @@ END // VS_VERSION_INFO VERSIONINFO - FILEVERSION 1,6,5,0 - PRODUCTVERSION 1,6,5,0 + FILEVERSION 1,6,6,0 + PRODUCTVERSION 1,6,6,0 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -74,12 +74,12 @@ BEGIN BEGIN VALUE "CompanyName", "GitHub, Inc." VALUE "FileDescription", "Electron" - VALUE "FileVersion", "1.6.5" + VALUE "FileVersion", "1.6.6" VALUE "InternalName", "electron.exe" VALUE "LegalCopyright", "Copyright (C) 2015 GitHub, Inc. All rights reserved." VALUE "OriginalFilename", "electron.exe" VALUE "ProductName", "Electron" - VALUE "ProductVersion", "1.6.5" + VALUE "ProductVersion", "1.6.6" VALUE "SquirrelAwareVersion", "1" END END diff --git a/atom/common/atom_version.h b/atom/common/atom_version.h index 1054a3dc9f..3afa163b90 100644 --- a/atom/common/atom_version.h +++ b/atom/common/atom_version.h @@ -7,7 +7,7 @@ #define ATOM_MAJOR_VERSION 1 #define ATOM_MINOR_VERSION 6 -#define ATOM_PATCH_VERSION 5 +#define ATOM_PATCH_VERSION 6 #define ATOM_VERSION_IS_RELEASE 1 diff --git a/electron.gyp b/electron.gyp index ee81200974..e6dd08bdfb 100644 --- a/electron.gyp +++ b/electron.gyp @@ -4,7 +4,7 @@ 'product_name%': 'Electron', 'company_name%': 'GitHub, Inc', 'company_abbr%': 'github', - 'version%': '1.6.5', + 'version%': '1.6.6', 'js2c_input_dir': '<(SHARED_INTERMEDIATE_DIR)/js2c', }, 'includes': [ diff --git a/package.json b/package.json index 015be4a12e..c34a27e275 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "electron", - "version": "1.6.5", + "version": "1.6.6", "devDependencies": { "asar": "^0.11.0", "browserify": "^13.1.0", From e2e9e8ae2434e9deff2bb5ecdd7cb9136678b447 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Fri, 7 Apr 2017 16:42:01 -0700 Subject: [PATCH 104/143] Wait until server closes in afterEach --- spec/api-net-spec.js | 76 +++++++++++++++----------------------------- 1 file changed, 26 insertions(+), 50 deletions(-) diff --git a/spec/api-net-spec.js b/spec/api-net-spec.js index dc024553a8..a5c3df8210 100644 --- a/spec/api-net-spec.js +++ b/spec/api-net-spec.js @@ -26,22 +26,34 @@ const kOneKiloByte = 1024 const kOneMegaByte = kOneKiloByte * kOneKiloByte describe('net module', function () { - describe('HTTP basics', function () { - let server - beforeEach(function (done) { - server = http.createServer() - server.listen(0, '127.0.0.1', function () { - server.url = 'http://127.0.0.1:' + server.address().port - done() + let server + const connections = new Set() + + beforeEach(function (done) { + server = http.createServer() + server.listen(0, '127.0.0.1', function () { + server.url = `http://127.0.0.1:${server.address().port}` + done() + }) + server.on('connection', (connection) => { + connections.add(connection) + connection.once('close', () => { + connections.delete(connection) }) }) + }) - afterEach(function () { - server.close(function () { - }) + afterEach(function (done) { + for (const connection of connections) { + connection.destroy() + } + server.close(function () { server = null + done() }) + }) + describe('HTTP basics', function () { it('should be able to issue a basic GET request', function (done) { const requestUrl = '/requestUrl' server.on('request', function (request, response) { @@ -224,19 +236,7 @@ describe('net module', function () { }) describe('ClientRequest API', function () { - let server - beforeEach(function (done) { - server = http.createServer() - server.listen(0, '127.0.0.1', function () { - server.url = 'http://127.0.0.1:' + server.address().port - done() - }) - }) - afterEach(function () { - server.close(function () { - }) - server = null session.defaultSession.webRequest.onBeforeRequest(null) }) @@ -1363,21 +1363,8 @@ describe('net module', function () { urlRequest.end() }) }) + describe('IncomingMessage API', function () { - let server - beforeEach(function (done) { - server = http.createServer() - server.listen(0, '127.0.0.1', function () { - server.url = 'http://127.0.0.1:' + server.address().port - done() - }) - }) - - afterEach(function () { - server.close() - server = null - }) - it('response object should implement the IncomingMessage API', function (done) { const requestUrl = '/requestUrl' const customHeaderName = 'Some-Custom-Header-Name' @@ -1544,21 +1531,8 @@ describe('net module', function () { urlRequest.end() }) }) + describe('Stability and performance', function (done) { - let server - beforeEach(function (done) { - server = http.createServer() - server.listen(0, '127.0.0.1', function () { - server.url = 'http://127.0.0.1:' + server.address().port - done() - }) - }) - - afterEach(function () { - server.close() - server = null - }) - it('should free unreferenced, never-started request objects without crash', function (done) { const requestUrl = '/requestUrl' ipcRenderer.once('api-net-spec-done', function () { @@ -1574,6 +1548,7 @@ describe('net module', function () { }) `) }) + it('should not collect on-going requests without crash', function (done) { const requestUrl = '/requestUrl' server.on('request', function (request, response) { @@ -1615,6 +1590,7 @@ describe('net module', function () { urlRequest.end() `) }) + it('should collect unreferenced, ended requests without crash', function (done) { const requestUrl = '/requestUrl' server.on('request', function (request, response) { From 91ee0ea7405d81bcfbbac913db7ec8f0d0106c75 Mon Sep 17 00:00:00 2001 From: Thiago de Arruda Date: Fri, 31 Mar 2017 10:01:33 -0300 Subject: [PATCH 105/143] Move AtomRenderFrameObserver into a separate module. Also move SetupMainWorldOverrides into the AtomRendererClient class(since the code there is specific to AtomRendererClient). --- atom/renderer/atom_render_frame_observer.cc | 84 +++++++++++ atom/renderer/atom_render_frame_observer.h | 53 +++++++ atom/renderer/atom_renderer_client.cc | 157 +++++--------------- atom/renderer/atom_renderer_client.h | 1 + filenames.gypi | 2 + 5 files changed, 175 insertions(+), 122 deletions(-) create mode 100644 atom/renderer/atom_render_frame_observer.cc create mode 100644 atom/renderer/atom_render_frame_observer.h diff --git a/atom/renderer/atom_render_frame_observer.cc b/atom/renderer/atom_render_frame_observer.cc new file mode 100644 index 0000000000..4a2b493d51 --- /dev/null +++ b/atom/renderer/atom_render_frame_observer.cc @@ -0,0 +1,84 @@ +// Copyright (c) 2017 GitHub, Inc. +// Use of this source code is governed by the MIT license that can be +// found in the LICENSE file. + +#include "atom/renderer/atom_render_frame_observer.h" + +#include "content/public/renderer/render_frame.h" +#include "third_party/WebKit/public/web/WebDocument.h" +#include "third_party/WebKit/public/web/WebLocalFrame.h" +#include "third_party/WebKit/public/web/WebScriptSource.h" + +namespace atom { + +AtomRenderFrameObserver::AtomRenderFrameObserver( + content::RenderFrame* frame, + AtomRendererClient* renderer_client) + : content::RenderFrameObserver(frame), + render_frame_(frame), + renderer_client_(renderer_client) {} + +void AtomRenderFrameObserver::DidClearWindowObject() { + renderer_client_->DidClearWindowObject(render_frame_); +} + +void AtomRenderFrameObserver::DidCreateScriptContext( + v8::Handle context, + int extension_group, + int world_id) { + if (ShouldNotifyClient(world_id)) + renderer_client_->DidCreateScriptContext(context, render_frame_); + + if (renderer_client_->isolated_world() && IsMainWorld(world_id) + && render_frame_->IsMainFrame()) { + CreateIsolatedWorldContext(); + renderer_client_->SetupMainWorldOverrides(context); + } +} + +void AtomRenderFrameObserver::WillReleaseScriptContext( + v8::Local context, + int world_id) { + if (ShouldNotifyClient(world_id)) + renderer_client_->WillReleaseScriptContext(context, render_frame_); +} + +void AtomRenderFrameObserver::OnDestruct() { + delete this; +} + +void AtomRenderFrameObserver::CreateIsolatedWorldContext() { + auto frame = render_frame_->GetWebFrame(); + + // This maps to the name shown in the context combo box in the Console tab + // of the dev tools. + frame->setIsolatedWorldHumanReadableName( + World::ISOLATED_WORLD, + blink::WebString::fromUTF8("Electron Isolated Context")); + + // Setup document's origin policy in isolated world + frame->setIsolatedWorldSecurityOrigin( + World::ISOLATED_WORLD, frame->document().getSecurityOrigin()); + + // Create initial script context in isolated world + blink::WebScriptSource source("void 0"); + frame->executeScriptInIsolatedWorld( + World::ISOLATED_WORLD, &source, 1, ExtensionGroup::MAIN_GROUP); +} + +bool AtomRenderFrameObserver::IsMainWorld(int world_id) { + return world_id == World::MAIN_WORLD; +} + +bool AtomRenderFrameObserver::IsIsolatedWorld(int world_id) { + return world_id == World::ISOLATED_WORLD; +} + +bool AtomRenderFrameObserver::ShouldNotifyClient(int world_id) { + if (renderer_client_->isolated_world() && render_frame_->IsMainFrame()) + return IsIsolatedWorld(world_id); + else + return IsMainWorld(world_id); +} + +} // namespace atom diff --git a/atom/renderer/atom_render_frame_observer.h b/atom/renderer/atom_render_frame_observer.h new file mode 100644 index 0000000000..3705667c66 --- /dev/null +++ b/atom/renderer/atom_render_frame_observer.h @@ -0,0 +1,53 @@ +// Copyright (c) 2017 GitHub, Inc. +// Use of this source code is governed by the MIT license that can be +// found in the LICENSE file. + +#ifndef ATOM_RENDERER_ATOM_RENDER_FRAME_OBSERVER_H_ +#define ATOM_RENDERER_ATOM_RENDER_FRAME_OBSERVER_H_ + +#include "atom/renderer/atom_renderer_client.h" +#include "content/public/renderer/render_frame_observer.h" + +namespace atom { + +enum World { + MAIN_WORLD = 0, + // Use a high number far away from 0 to not collide with any other world + // IDs created internally by Chrome. + ISOLATED_WORLD = 999 +}; + +enum ExtensionGroup { + MAIN_GROUP = 1 +}; + +// Helper class to forward the messages to the client. +class AtomRenderFrameObserver : public content::RenderFrameObserver { + public: + AtomRenderFrameObserver(content::RenderFrame* frame, + AtomRendererClient* renderer_client); + + // content::RenderFrameObserver: + void DidClearWindowObject() override; + void DidCreateScriptContext(v8::Handle context, + int extension_group, + int world_id) override; + void WillReleaseScriptContext(v8::Local context, + int world_id) override; + void OnDestruct() override; + + private: + bool ShouldNotifyClient(int world_id); + void CreateIsolatedWorldContext(); + bool IsMainWorld(int world_id); + bool IsIsolatedWorld(int world_id); + + content::RenderFrame* render_frame_; + AtomRendererClient* renderer_client_; + + DISALLOW_COPY_AND_ASSIGN(AtomRenderFrameObserver); +}; + +} // namespace atom + +#endif // ATOM_RENDERER_ATOM_RENDER_FRAME_OBSERVER_H_ diff --git a/atom/renderer/atom_renderer_client.cc b/atom/renderer/atom_renderer_client.cc index 9d015b4f22..6137593e80 100644 --- a/atom/renderer/atom_renderer_client.cc +++ b/atom/renderer/atom_renderer_client.cc @@ -16,12 +16,12 @@ #include "atom/common/node_bindings.h" #include "atom/common/options_switches.h" #include "atom/renderer/api/atom_api_renderer_ipc.h" +#include "atom/renderer/atom_render_frame_observer.h" #include "atom/renderer/atom_render_view_observer.h" #include "atom/renderer/node_array_buffer_bridge.h" #include "atom/renderer/web_worker_observer.h" #include "base/command_line.h" #include "content/public/renderer/render_frame.h" -#include "content/public/renderer/render_frame_observer.h" #include "native_mate/dictionary.h" #include "third_party/WebKit/public/web/WebDocument.h" #include "third_party/WebKit/public/web/WebLocalFrame.h" @@ -33,127 +33,6 @@ namespace atom { namespace { -enum World { - MAIN_WORLD = 0, - // Use a high number far away from 0 to not collide with any other world - // IDs created internally by Chrome. - ISOLATED_WORLD = 999 -}; - -enum ExtensionGroup { - MAIN_GROUP = 1 -}; - -// Helper class to forward the messages to the client. -class AtomRenderFrameObserver : public content::RenderFrameObserver { - public: - AtomRenderFrameObserver(content::RenderFrame* frame, - AtomRendererClient* renderer_client) - : content::RenderFrameObserver(frame), - render_frame_(frame), - renderer_client_(renderer_client) {} - - // content::RenderFrameObserver: - void DidClearWindowObject() override { - renderer_client_->DidClearWindowObject(render_frame_); - } - - void CreateIsolatedWorldContext() { - auto frame = render_frame_->GetWebFrame(); - - // This maps to the name shown in the context combo box in the Console tab - // of the dev tools. - frame->setIsolatedWorldHumanReadableName( - World::ISOLATED_WORLD, - blink::WebString::fromUTF8("Electron Isolated Context")); - - // Setup document's origin policy in isolated world - frame->setIsolatedWorldSecurityOrigin( - World::ISOLATED_WORLD, frame->document().getSecurityOrigin()); - - // Create initial script context in isolated world - blink::WebScriptSource source("void 0"); - frame->executeScriptInIsolatedWorld( - World::ISOLATED_WORLD, &source, 1, ExtensionGroup::MAIN_GROUP); - } - - void SetupMainWorldOverrides(v8::Handle context) { - // Setup window overrides in the main world context - v8::Isolate* isolate = context->GetIsolate(); - - // Wrap the bundle into a function that receives the binding object as - // an argument. - std::string bundle(node::isolated_bundle_data, - node::isolated_bundle_data + sizeof(node::isolated_bundle_data)); - std::string wrapper = "(function (binding, require) {\n" + bundle + "\n})"; - auto script = v8::Script::Compile( - mate::ConvertToV8(isolate, wrapper)->ToString()); - auto func = v8::Handle::Cast( - script->Run(context).ToLocalChecked()); - - auto binding = v8::Object::New(isolate); - api::Initialize(binding, v8::Null(isolate), context, nullptr); - - // Pass in CLI flags needed to setup window - base::CommandLine* command_line = base::CommandLine::ForCurrentProcess(); - mate::Dictionary dict(isolate, binding); - if (command_line->HasSwitch(switches::kGuestInstanceID)) - dict.Set(options::kGuestInstanceID, - command_line->GetSwitchValueASCII(switches::kGuestInstanceID)); - if (command_line->HasSwitch(switches::kOpenerID)) - dict.Set(options::kOpenerID, - command_line->GetSwitchValueASCII(switches::kOpenerID)); - dict.Set("hiddenPage", command_line->HasSwitch(switches::kHiddenPage)); - - v8::Local args[] = { binding }; - ignore_result(func->Call(context, v8::Null(isolate), 1, args)); - } - - bool IsMainWorld(int world_id) { - return world_id == World::MAIN_WORLD; - } - - bool IsIsolatedWorld(int world_id) { - return world_id == World::ISOLATED_WORLD; - } - - bool ShouldNotifyClient(int world_id) { - if (renderer_client_->isolated_world() && render_frame_->IsMainFrame()) - return IsIsolatedWorld(world_id); - else - return IsMainWorld(world_id); - } - - void DidCreateScriptContext(v8::Handle context, - int extension_group, - int world_id) override { - if (ShouldNotifyClient(world_id)) - renderer_client_->DidCreateScriptContext(context, render_frame_); - - if (renderer_client_->isolated_world() && IsMainWorld(world_id) - && render_frame_->IsMainFrame()) { - CreateIsolatedWorldContext(); - SetupMainWorldOverrides(context); - } - } - - void WillReleaseScriptContext(v8::Local context, - int world_id) override { - if (ShouldNotifyClient(world_id)) - renderer_client_->WillReleaseScriptContext(context, render_frame_); - } - - void OnDestruct() override { - delete this; - } - - private: - content::RenderFrame* render_frame_; - AtomRendererClient* renderer_client_; - - DISALLOW_COPY_AND_ASSIGN(AtomRenderFrameObserver); -}; - bool IsDevToolsExtension(content::RenderFrame* render_frame) { return static_cast(render_frame->GetWebFrame()->document().url()) .SchemeIs("chrome-extension"); @@ -307,4 +186,38 @@ v8::Local AtomRendererClient::GetContext( return frame->mainWorldScriptContext(); } +void AtomRendererClient::SetupMainWorldOverrides( + v8::Handle context) { + // Setup window overrides in the main world context + v8::Isolate* isolate = context->GetIsolate(); + + // Wrap the bundle into a function that receives the binding object as + // an argument. + std::string bundle(node::isolated_bundle_data, + node::isolated_bundle_data + sizeof(node::isolated_bundle_data)); + std::string wrapper = "(function (binding, require) {\n" + bundle + "\n})"; + auto script = v8::Script::Compile( + mate::ConvertToV8(isolate, wrapper)->ToString()); + auto func = v8::Handle::Cast( + script->Run(context).ToLocalChecked()); + + auto binding = v8::Object::New(isolate); + api::Initialize(binding, v8::Null(isolate), context, nullptr); + + // Pass in CLI flags needed to setup window + base::CommandLine* command_line = base::CommandLine::ForCurrentProcess(); + mate::Dictionary dict(isolate, binding); + if (command_line->HasSwitch(switches::kGuestInstanceID)) + dict.Set(options::kGuestInstanceID, + command_line->GetSwitchValueASCII(switches::kGuestInstanceID)); + if (command_line->HasSwitch(switches::kOpenerID)) + dict.Set(options::kOpenerID, + command_line->GetSwitchValueASCII(switches::kOpenerID)); + dict.Set("hiddenPage", command_line->HasSwitch(switches::kHiddenPage)); + + v8::Local args[] = { binding }; + ignore_result(func->Call(context, v8::Null(isolate), 1, args)); +} + + } // namespace atom diff --git a/atom/renderer/atom_renderer_client.h b/atom/renderer/atom_renderer_client.h index 5a1141d103..4e45df15d9 100644 --- a/atom/renderer/atom_renderer_client.h +++ b/atom/renderer/atom_renderer_client.h @@ -29,6 +29,7 @@ class AtomRendererClient : public RendererClientBase { // Get the context that the Electron API is running in. v8::Local GetContext( blink::WebFrame* frame, v8::Isolate* isolate); + void SetupMainWorldOverrides(v8::Handle context); bool isolated_world() { return isolated_world_; } private: diff --git a/filenames.gypi b/filenames.gypi index 192d953287..ec9c68241c 100644 --- a/filenames.gypi +++ b/filenames.gypi @@ -468,6 +468,8 @@ 'atom/renderer/api/atom_api_spell_check_client.h', 'atom/renderer/api/atom_api_web_frame.cc', 'atom/renderer/api/atom_api_web_frame.h', + 'atom/renderer/atom_render_frame_observer.cc', + 'atom/renderer/atom_render_frame_observer.h', 'atom/renderer/atom_render_view_observer.cc', 'atom/renderer/atom_render_view_observer.h', 'atom/renderer/atom_renderer_client.cc', From 0227254774eff00f72b578b44f52ff0c12524671 Mon Sep 17 00:00:00 2001 From: Thiago de Arruda Date: Sat, 8 Apr 2017 10:43:19 -0300 Subject: [PATCH 106/143] Move DidClearWindowObject into RendererClientBase. Also adapt AtomSandboxedRenderFrameObserver to forward DidClearWindowObject to RendererClientBase. --- atom/renderer/atom_renderer_client.cc | 7 ------- atom/renderer/atom_renderer_client.h | 1 - atom/renderer/atom_sandboxed_renderer_client.cc | 4 +--- atom/renderer/renderer_client_base.cc | 7 +++++++ atom/renderer/renderer_client_base.h | 2 ++ 5 files changed, 10 insertions(+), 11 deletions(-) diff --git a/atom/renderer/atom_renderer_client.cc b/atom/renderer/atom_renderer_client.cc index 6137593e80..519b043389 100644 --- a/atom/renderer/atom_renderer_client.cc +++ b/atom/renderer/atom_renderer_client.cc @@ -25,7 +25,6 @@ #include "native_mate/dictionary.h" #include "third_party/WebKit/public/web/WebDocument.h" #include "third_party/WebKit/public/web/WebLocalFrame.h" -#include "third_party/WebKit/public/web/WebScriptSource.h" #include "atom/common/node_includes.h" @@ -68,12 +67,6 @@ void AtomRendererClient::RenderViewCreated(content::RenderView* render_view) { RendererClientBase::RenderViewCreated(render_view); } -void AtomRendererClient::DidClearWindowObject( - content::RenderFrame* render_frame) { - // Make sure every page will get a script context created. - render_frame->GetWebFrame()->executeScript(blink::WebScriptSource("void 0")); -} - void AtomRendererClient::RunScriptsAtDocumentStart( content::RenderFrame* render_frame) { // Inform the document start pharse. diff --git a/atom/renderer/atom_renderer_client.h b/atom/renderer/atom_renderer_client.h index 4e45df15d9..01787fdc10 100644 --- a/atom/renderer/atom_renderer_client.h +++ b/atom/renderer/atom_renderer_client.h @@ -20,7 +20,6 @@ class AtomRendererClient : public RendererClientBase { AtomRendererClient(); virtual ~AtomRendererClient(); - void DidClearWindowObject(content::RenderFrame* render_frame); void DidCreateScriptContext( v8::Handle context, content::RenderFrame* render_frame); void WillReleaseScriptContext( diff --git a/atom/renderer/atom_sandboxed_renderer_client.cc b/atom/renderer/atom_sandboxed_renderer_client.cc index 80f8cae713..9eb11c8304 100644 --- a/atom/renderer/atom_sandboxed_renderer_client.cc +++ b/atom/renderer/atom_sandboxed_renderer_client.cc @@ -100,9 +100,7 @@ class AtomSandboxedRenderFrameObserver : public content::RenderFrameObserver { // content::RenderFrameObserver: void DidClearWindowObject() override { - // Make sure every page will get a script context created. - render_frame_->GetWebFrame()->executeScript( - blink::WebScriptSource("void 0")); + renderer_client_->DidClearWindowObject(render_frame_); } void DidCreateScriptContext(v8::Handle context, diff --git a/atom/renderer/renderer_client_base.cc b/atom/renderer/renderer_client_base.cc index 3ee72b3c0d..6cb6cb9b95 100644 --- a/atom/renderer/renderer_client_base.cc +++ b/atom/renderer/renderer_client_base.cc @@ -27,6 +27,7 @@ #include "third_party/WebKit/public/web/WebFrameWidget.h" #include "third_party/WebKit/public/web/WebKit.h" #include "third_party/WebKit/public/web/WebPluginParams.h" +#include "third_party/WebKit/public/web/WebScriptSource.h" #include "third_party/WebKit/public/web/WebSecurityPolicy.h" #if defined(OS_MACOSX) @@ -151,6 +152,12 @@ void RendererClientBase::RenderViewCreated(content::RenderView* render_view) { } } +void RendererClientBase::DidClearWindowObject( + content::RenderFrame* render_frame) { + // Make sure every page will get a script context created. + render_frame->GetWebFrame()->executeScript(blink::WebScriptSource("void 0")); +} + blink::WebSpeechSynthesizer* RendererClientBase::OverrideSpeechSynthesizer( blink::WebSpeechSynthesizerClient* client) { return new TtsDispatcher(client); diff --git a/atom/renderer/renderer_client_base.h b/atom/renderer/renderer_client_base.h index 3a91255c60..167eefaa8e 100644 --- a/atom/renderer/renderer_client_base.h +++ b/atom/renderer/renderer_client_base.h @@ -19,6 +19,8 @@ class RendererClientBase : public content::ContentRendererClient { RendererClientBase(); virtual ~RendererClientBase(); + virtual void DidClearWindowObject(content::RenderFrame* render_frame); + protected: void AddRenderBindings(v8::Isolate* isolate, v8::Local binding_object); From f751335bf9e8b08741ba23f9225b7b83e23a5c8a Mon Sep 17 00:00:00 2001 From: Thiago de Arruda Date: Sat, 8 Apr 2017 10:58:13 -0300 Subject: [PATCH 107/143] Make DidCreateScriptContext/WillReleaseScriptContext pure virtual. --- atom/renderer/atom_renderer_client.h | 13 ++++++++----- atom/renderer/atom_sandboxed_renderer_client.h | 11 +++++++---- atom/renderer/renderer_client_base.h | 4 ++++ 3 files changed, 19 insertions(+), 9 deletions(-) diff --git a/atom/renderer/atom_renderer_client.h b/atom/renderer/atom_renderer_client.h index 01787fdc10..4feca84816 100644 --- a/atom/renderer/atom_renderer_client.h +++ b/atom/renderer/atom_renderer_client.h @@ -20,17 +20,20 @@ class AtomRendererClient : public RendererClientBase { AtomRendererClient(); virtual ~AtomRendererClient(); - void DidCreateScriptContext( - v8::Handle context, content::RenderFrame* render_frame); - void WillReleaseScriptContext( - v8::Handle context, content::RenderFrame* render_frame); - // Get the context that the Electron API is running in. v8::Local GetContext( blink::WebFrame* frame, v8::Isolate* isolate); void SetupMainWorldOverrides(v8::Handle context); bool isolated_world() { return isolated_world_; } + // atom::RendererClientBase: + void DidCreateScriptContext( + v8::Handle context, + content::RenderFrame* render_frame) override; + void WillReleaseScriptContext( + v8::Handle context, + content::RenderFrame* render_frame) override; + private: enum NodeIntegration { ALL, diff --git a/atom/renderer/atom_sandboxed_renderer_client.h b/atom/renderer/atom_sandboxed_renderer_client.h index 5e0614c9c9..c6f8a23577 100644 --- a/atom/renderer/atom_sandboxed_renderer_client.h +++ b/atom/renderer/atom_sandboxed_renderer_client.h @@ -16,13 +16,16 @@ class AtomSandboxedRendererClient : public RendererClientBase { AtomSandboxedRendererClient(); virtual ~AtomSandboxedRendererClient(); - void DidCreateScriptContext( - v8::Handle context, content::RenderFrame* render_frame); - void WillReleaseScriptContext( - v8::Handle context, content::RenderFrame* render_frame); void InvokeIpcCallback(v8::Handle context, const std::string& callback_name, std::vector> args); + // atom::RendererClientBase: + void DidCreateScriptContext( + v8::Handle context, + content::RenderFrame* render_frame) override; + void WillReleaseScriptContext( + v8::Handle context, + content::RenderFrame* render_frame) override; // content::ContentRendererClient: void RenderFrameCreated(content::RenderFrame*) override; void RenderViewCreated(content::RenderView*) override; diff --git a/atom/renderer/renderer_client_base.h b/atom/renderer/renderer_client_base.h index 167eefaa8e..804e214cbb 100644 --- a/atom/renderer/renderer_client_base.h +++ b/atom/renderer/renderer_client_base.h @@ -19,6 +19,10 @@ class RendererClientBase : public content::ContentRendererClient { RendererClientBase(); virtual ~RendererClientBase(); + virtual void DidCreateScriptContext( + v8::Handle context, content::RenderFrame* render_frame) = 0; + virtual void WillReleaseScriptContext( + v8::Handle context, content::RenderFrame* render_frame) = 0; virtual void DidClearWindowObject(content::RenderFrame* render_frame); protected: From ef07e25f9d93f94f93638dd1c1b2b530ee5196ac Mon Sep 17 00:00:00 2001 From: Thiago de Arruda Date: Sat, 8 Apr 2017 11:12:18 -0300 Subject: [PATCH 108/143] Make SetupMainWorldOverrides/isolated_world pure virtual. Also implement stubs in AtomSandboxedRendererClient. --- atom/renderer/atom_renderer_client.h | 4 ++-- atom/renderer/atom_sandboxed_renderer_client.h | 2 ++ atom/renderer/renderer_client_base.h | 2 ++ 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/atom/renderer/atom_renderer_client.h b/atom/renderer/atom_renderer_client.h index 4feca84816..3feaff4528 100644 --- a/atom/renderer/atom_renderer_client.h +++ b/atom/renderer/atom_renderer_client.h @@ -23,8 +23,6 @@ class AtomRendererClient : public RendererClientBase { // Get the context that the Electron API is running in. v8::Local GetContext( blink::WebFrame* frame, v8::Isolate* isolate); - void SetupMainWorldOverrides(v8::Handle context); - bool isolated_world() { return isolated_world_; } // atom::RendererClientBase: void DidCreateScriptContext( @@ -33,6 +31,8 @@ class AtomRendererClient : public RendererClientBase { void WillReleaseScriptContext( v8::Handle context, content::RenderFrame* render_frame) override; + void SetupMainWorldOverrides(v8::Handle context) override; + bool isolated_world() override { return isolated_world_; } private: enum NodeIntegration { diff --git a/atom/renderer/atom_sandboxed_renderer_client.h b/atom/renderer/atom_sandboxed_renderer_client.h index c6f8a23577..a8eae0ba84 100644 --- a/atom/renderer/atom_sandboxed_renderer_client.h +++ b/atom/renderer/atom_sandboxed_renderer_client.h @@ -26,6 +26,8 @@ class AtomSandboxedRendererClient : public RendererClientBase { void WillReleaseScriptContext( v8::Handle context, content::RenderFrame* render_frame) override; + void SetupMainWorldOverrides(v8::Handle context) override { } + bool isolated_world() override { return false; } // content::ContentRendererClient: void RenderFrameCreated(content::RenderFrame*) override; void RenderViewCreated(content::RenderView*) override; diff --git a/atom/renderer/renderer_client_base.h b/atom/renderer/renderer_client_base.h index 804e214cbb..c8958de904 100644 --- a/atom/renderer/renderer_client_base.h +++ b/atom/renderer/renderer_client_base.h @@ -24,6 +24,8 @@ class RendererClientBase : public content::ContentRendererClient { virtual void WillReleaseScriptContext( v8::Handle context, content::RenderFrame* render_frame) = 0; virtual void DidClearWindowObject(content::RenderFrame* render_frame); + virtual void SetupMainWorldOverrides(v8::Handle context) = 0; + virtual bool isolated_world() = 0; protected: void AddRenderBindings(v8::Isolate* isolate, From 72781e38c8f9d0efef13142c50c5c69a3437dc98 Mon Sep 17 00:00:00 2001 From: Thiago de Arruda Date: Sat, 8 Apr 2017 11:27:19 -0300 Subject: [PATCH 109/143] Change AtomRenderFrameObserver.renderer_client_ type to RendererClientBase. --- atom/renderer/atom_render_frame_observer.cc | 2 +- atom/renderer/atom_render_frame_observer.h | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/atom/renderer/atom_render_frame_observer.cc b/atom/renderer/atom_render_frame_observer.cc index 4a2b493d51..d9a41a48d4 100644 --- a/atom/renderer/atom_render_frame_observer.cc +++ b/atom/renderer/atom_render_frame_observer.cc @@ -13,7 +13,7 @@ namespace atom { AtomRenderFrameObserver::AtomRenderFrameObserver( content::RenderFrame* frame, - AtomRendererClient* renderer_client) + RendererClientBase* renderer_client) : content::RenderFrameObserver(frame), render_frame_(frame), renderer_client_(renderer_client) {} diff --git a/atom/renderer/atom_render_frame_observer.h b/atom/renderer/atom_render_frame_observer.h index 3705667c66..51cb21b3b0 100644 --- a/atom/renderer/atom_render_frame_observer.h +++ b/atom/renderer/atom_render_frame_observer.h @@ -5,7 +5,7 @@ #ifndef ATOM_RENDERER_ATOM_RENDER_FRAME_OBSERVER_H_ #define ATOM_RENDERER_ATOM_RENDER_FRAME_OBSERVER_H_ -#include "atom/renderer/atom_renderer_client.h" +#include "atom/renderer/renderer_client_base.h" #include "content/public/renderer/render_frame_observer.h" namespace atom { @@ -25,7 +25,7 @@ enum ExtensionGroup { class AtomRenderFrameObserver : public content::RenderFrameObserver { public: AtomRenderFrameObserver(content::RenderFrame* frame, - AtomRendererClient* renderer_client); + RendererClientBase* renderer_client); // content::RenderFrameObserver: void DidClearWindowObject() override; @@ -43,7 +43,7 @@ class AtomRenderFrameObserver : public content::RenderFrameObserver { bool IsIsolatedWorld(int world_id); content::RenderFrame* render_frame_; - AtomRendererClient* renderer_client_; + RendererClientBase* renderer_client_; DISALLOW_COPY_AND_ASSIGN(AtomRenderFrameObserver); }; From 039aaba75860dc191d79d86dae05d67225fd5dd7 Mon Sep 17 00:00:00 2001 From: Thiago de Arruda Date: Sat, 8 Apr 2017 11:54:58 -0300 Subject: [PATCH 110/143] Move AtomRenderFrameObserver creation to RendererClientBase. Also remove AtomSandboxedRenderFrameObserver class. --- atom/renderer/atom_renderer_client.cc | 1 - .../atom_sandboxed_renderer_client.cc | 44 ------------------- atom/renderer/renderer_client_base.cc | 2 + 3 files changed, 2 insertions(+), 45 deletions(-) diff --git a/atom/renderer/atom_renderer_client.cc b/atom/renderer/atom_renderer_client.cc index 519b043389..5dafe084ce 100644 --- a/atom/renderer/atom_renderer_client.cc +++ b/atom/renderer/atom_renderer_client.cc @@ -58,7 +58,6 @@ void AtomRendererClient::RenderThreadStarted() { void AtomRendererClient::RenderFrameCreated( content::RenderFrame* render_frame) { - new AtomRenderFrameObserver(render_frame, this); RendererClientBase::RenderFrameCreated(render_frame); } diff --git a/atom/renderer/atom_sandboxed_renderer_client.cc b/atom/renderer/atom_sandboxed_renderer_client.cc index 9eb11c8304..4fe9bd449d 100644 --- a/atom/renderer/atom_sandboxed_renderer_client.cc +++ b/atom/renderer/atom_sandboxed_renderer_client.cc @@ -20,7 +20,6 @@ #include "base/command_line.h" #include "chrome/renderer/printing/print_web_view_helper.h" #include "content/public/renderer/render_frame.h" -#include "content/public/renderer/render_frame_observer.h" #include "content/public/renderer/render_view.h" #include "content/public/renderer/render_view_observer.h" #include "ipc/ipc_message_macros.h" @@ -89,48 +88,6 @@ void InitializeBindings(v8::Local binding, b.SetMethod("crash", AtomBindings::Crash); } -class AtomSandboxedRenderFrameObserver : public content::RenderFrameObserver { - public: - AtomSandboxedRenderFrameObserver(content::RenderFrame* frame, - AtomSandboxedRendererClient* renderer_client) - : content::RenderFrameObserver(frame), - render_frame_(frame), - world_id_(-1), - renderer_client_(renderer_client) {} - - // content::RenderFrameObserver: - void DidClearWindowObject() override { - renderer_client_->DidClearWindowObject(render_frame_); - } - - void DidCreateScriptContext(v8::Handle context, - int extension_group, - int world_id) override { - if (world_id_ != -1 && world_id_ != world_id) - return; - world_id_ = world_id; - renderer_client_->DidCreateScriptContext(context, render_frame_); - } - - void WillReleaseScriptContext(v8::Local context, - int world_id) override { - if (world_id_ != world_id) - return; - renderer_client_->WillReleaseScriptContext(context, render_frame_); - } - - void OnDestruct() override { - delete this; - } - - private: - content::RenderFrame* render_frame_; - int world_id_; - AtomSandboxedRendererClient* renderer_client_; - - DISALLOW_COPY_AND_ASSIGN(AtomSandboxedRenderFrameObserver); -}; - class AtomSandboxedRenderViewObserver : public AtomRenderViewObserver { public: AtomSandboxedRenderViewObserver(content::RenderView* render_view, @@ -179,7 +136,6 @@ AtomSandboxedRendererClient::~AtomSandboxedRendererClient() { void AtomSandboxedRendererClient::RenderFrameCreated( content::RenderFrame* render_frame) { - new AtomSandboxedRenderFrameObserver(render_frame, this); RendererClientBase::RenderFrameCreated(render_frame); } diff --git a/atom/renderer/renderer_client_base.cc b/atom/renderer/renderer_client_base.cc index 6cb6cb9b95..09a4c3c0c8 100644 --- a/atom/renderer/renderer_client_base.cc +++ b/atom/renderer/renderer_client_base.cc @@ -11,6 +11,7 @@ #include "atom/common/color_util.h" #include "atom/common/native_mate_converters/value_converter.h" #include "atom/common/options_switches.h" +#include "atom/renderer/atom_render_frame_observer.h" #include "atom/renderer/content_settings_observer.h" #include "atom/renderer/guest_view_container.h" #include "atom/renderer/preferences_manager.h" @@ -112,6 +113,7 @@ void RendererClientBase::RenderThreadStarted() { void RendererClientBase::RenderFrameCreated( content::RenderFrame* render_frame) { + new AtomRenderFrameObserver(render_frame, this); new PepperHelper(render_frame); new ContentSettingsObserver(render_frame); new printing::PrintWebViewHelper(render_frame); From b7b7f28c5a896a5a5113ec6c70d910e3da099428 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Sat, 8 Apr 2017 18:50:55 -0700 Subject: [PATCH 111/143] Link properties to class docs --- docs/api/session.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/api/session.md b/docs/api/session.md index 7c7831c8ac..e85f5a246f 100644 --- a/docs/api/session.md +++ b/docs/api/session.md @@ -388,15 +388,15 @@ The following properties are available on instances of `Session`: #### `ses.cookies` -A Cookies object for this session. +A [Cookies](cookies.md) object for this session. #### `ses.webRequest` -A WebRequest object for this session. +A [WebRequest](web-request.md) object for this session. #### `ses.protocol` -A Protocol object (an instance of [protocol](protocol.md) module) for this session. +A [Protocol](protocol.md) object for this session. ```javascript const {app, session} = require('electron') From 6a729f90e569e2441ba70ac907fb101e57af8027 Mon Sep 17 00:00:00 2001 From: "Mustafa C. Izol" Date: Mon, 10 Apr 2017 00:47:00 +0200 Subject: [PATCH 112/143] add translation files for application-distrubution and supported platforms --- docs-translations/tr-TR/README.md | 4 +- .../tutorial/application-distribution.md | 178 ++++++++++++++++++ .../tr-TR/tutorial/supported-platforms.md | 29 +++ 3 files changed, 209 insertions(+), 2 deletions(-) create mode 100644 docs-translations/tr-TR/tutorial/application-distribution.md create mode 100644 docs-translations/tr-TR/tutorial/supported-platforms.md diff --git a/docs-translations/tr-TR/README.md b/docs-translations/tr-TR/README.md index d9d8a1bdce..494433ee5a 100644 --- a/docs-translations/tr-TR/README.md +++ b/docs-translations/tr-TR/README.md @@ -9,8 +9,8 @@ Bir problem(issue) bildirmeden önce sıkça sorulan sorulara göz atın: ## Klavuzlar -* [Desteklenen Platformlar ](https://github.com/electron/electron/tree/master/docs/tutorial/supported-platforms.md) -* [Uygulama Dağıtımı](https://github.com/electron/electron/tree/master/docs/tutorial/application-distribution.md) +* [Desteklenen Platformlar ](tutorial/supported-platforms.md) +* [Uygulama Dağıtımı](tutorial/application-distribution.md) * [Mac Uygulama Mağazası Başvuru Klavuzu](https://github.com/electron/electron/tree/master/docs/tutorial/mac-app-store-submission-guide.md) * [Uygulama Paketleme](https://github.com/electron/electron/tree/master/docs/tutorial/application-packaging.md) * [Native Node Modüllerini Kullanma](https://github.com/electron/electron/tree/master/docs/tutorial/using-native-node-modules.md) diff --git a/docs-translations/tr-TR/tutorial/application-distribution.md b/docs-translations/tr-TR/tutorial/application-distribution.md new file mode 100644 index 0000000000..319f8af787 --- /dev/null +++ b/docs-translations/tr-TR/tutorial/application-distribution.md @@ -0,0 +1,178 @@ +# Application Distribution + +Electron uygulamanızı dağıtmak için önce Electron nun [prebuilt mimarilerini] +(https://github.com/electron/electron/releases) indirmeniz gerekmektedir. +Sonrasında, uygulamanızın bulundugu klasör `app` şeklinde isimlendirilmeli ve +Electron kaynaklar klasörüne aşagıda gösterildiği gibi yerleştirilmelidir. +Unutmayın, Electronun prebuilt mimarileri aşağıdaki örneklerde `electron/` +şeklinde belirtilmiştir. + + +MacOS da: + +```text +electron/Electron.app/Contents/Resources/app/ +├── package.json +├── main.js +└── index.html +``` + +Windows ve Linux da: + +```text +electron/resources/app +├── package.json +├── main.js +└── index.html +``` + +Ardından `Electron.app` (veya `electron` Linux'da, `electron.exe` Windows'da) şeklinde çalıstırın, +ve Electron uygulama şeklinde çalışacaktır. +`electron` klasörü son kullanıcıya aktaracağınız dağıtımınız olacaktır. + +## Uygulamanın bir dosya şeklinde paketlenmesi + +Tüm kaynak kodlarını kopyalama yoluyla uygulamanızı dağıtmak haricinde, +uygulamanızı [asar](https://github.com/electron/asar) ile arşiv haline getirerek, +kaynak kodlarınızın kullanıcılar tarafından görülmesini engelliye bilirsiniz. + +`app` klasörü yerine `asar` arşiv dosyası kullanmak için, arşiv dosyanızı `app.asar` +şeklinde isimlendirmeniz gerekiyor, ve bu dosyayı Electron'nun kaynak klasörüne aşağıdaki +gibi yerleştirmelisiniz. Böylelikle Electron arşivi okuyup ondan başlayacaktır. + + +MacOS'da: + +```text +electron/Electron.app/Contents/Resources/ +└── app.asar +``` + +Windows ve Linux'da: + +```text +electron/resources/ +└── app.asar +``` + +Daha fazla bilgi için [Application packaging](application-packaging.md). + +## İndirilen mimarileri yeniden adlandırma + +Uygulamanızı Electron ile paketledikten sonra ve kullanıcılara uygulamanızı dağıtmadan önce +adını değiştirmek isteye bilirsiniz. + +### Windows + +`electron.exe` istediğiniz şekilde yeniden adlandırabilirsiniz. Icon ve diğer +bilgileri bu gibi araçlar [rcedit](https://github.com/atom/rcedit) ile düzenleye bilirsiniz. + +### macOS + +`Electron.app`'i istediğiniz şekilde yeniden adlandırabilirsiniz, ve aşağıdaki dosyalarda +`CFBundleDisplayName`, `CFBundleIdentifier` ve `CFBundleName` kısımlarınıda düzenlemelisiniz. + +* `Electron.app/Contents/Info.plist` +* `Electron.app/Contents/Frameworks/Electron Helper.app/Contents/Info.plist` + +Görev yöneticisinde `Electron Helper` şeklinde göstermek yerine, +isterseniz helper uygulamasınında adını değiştire bilirsiniz, +ancak dosyanın adını açılabilir olduğundan emin olun. + +Yeniden adlandırılmış uygulamanın klasör yapısı bu şekilde görünecektir: + +``` +MyApp.app/Contents +├── Info.plist +├── MacOS/ +│   └── MyApp +└── Frameworks/ + ├── MyApp Helper EH.app + | ├── Info.plist + | └── MacOS/ + |    └── MyApp Helper EH + ├── MyApp Helper NP.app + | ├── Info.plist + | └── MacOS/ + |    └── MyApp Helper NP + └── MyApp Helper.app + ├── Info.plist + └── MacOS/ +    └── MyApp Helper +``` + +### Linux + +`electron` dosyasını istediğiniz şekilde yeniden adlandırabilirsiniz. + +## Paketleme Araçları + +Uygulamanızı manuel şekilde paketlemek dışında, üçüncü parti +paketleme araçlarıylada otomatik olarak ayni şekilde paketliye bilirsiniz: + +* [electron-builder](https://github.com/electron-userland/electron-builder) +* [electron-packager](https://github.com/electron-userland/electron-packager) + +## Kaynaktan yeniden kurulum yoluyla isim değişikliği + +Ürün adını değiştirip, kaynaktan kurulum yoluylada Electron'nun adını değiştirmek mümkün. +Bunun için `atom.gyp` dosyasını yeniden modifiye edip, tekrardan temiz bir kurulum yapmalısınız. + +### grunt-build-atom-shell + +Manuel olarak Electron kodlarını kontrol edip tekrar kurulum yapmak biraz zor olabilir, +bu yüzden tüm bu işlemleri otomatik olarak gerçekleştirecek bir Grunt görevi oluşturuldu: +[grunt-build-atom-shell](https://github.com/paulcbetts/grunt-build-atom-shell). + +Bu görev otomatik olarak `.gyp` dosyasını düzenleyecek, kaynaktan kurulumu gerçekleştirecek, +sonrasında ise uygulamanızın doğal Node modüllerini, yeni yürütülebilen isim ile eşleştirmek icin +tekrardan kuracaktır. + +### Özel bir Electron kopyası oluşturma + +Electron'un size ait bir kopyasını oluşturmak, neredeyse uygulamanızı kurmak için hiç ihtiyacınız +olmayacak bir işlemdir, "Production Level" uygulamalarda buna dahildir. +`electron-packager` veya `electron-builder` gibi araçlar kullanarak yukarıda ki işlemleri +gerçekleştirmeksizin, "Rebrand" Electron işlemini uygulaya bilirsiniz. + +Eğer kendinize ait yüklenemiyen veya resmi versiyondan red edilmiş, +direk olarak Electron a paketlediğiniz C++ kodunuz var ise, +öncelikle Electron'un bir kopyasını oluşturmalısınız. +Electron'nun destekleyicileri olarak, senaryonuzun çalışmasını çok isteriz, +bu yüzden lütfen yapacağınız değişiklikleri Electron'nun resmi versiyonuna +entegre etmeye calışın, bu sizin için daha kolay olacaktır, ve yardimlarınız +için cok minnettar olacağız. + +#### surf-build İle Özel Dağıtım oluşturulması + +1. Npm yoluyla [Surf](https://github.com/surf-build/surf) yükleyin: + `npm install -g surf-build@latest` + + +2. Yeni bir S3 bucket ve aşağıdakı boş klasör yapısını oluşturun: + + ``` + - atom-shell/ + - symbols/ + - dist/ + ``` + +3. Aşağıdaki Ortam Değişkenlerini ayarlayın: + + * `ELECTRON_GITHUB_TOKEN` - GitHub üzerinden dağıtım oluşturan token + * `ELECTRON_S3_ACCESS_KEY`, `ELECTRON_S3_BUCKET`, `ELECTRON_S3_SECRET_KEY` - + node.js bağlantılarını ve sembollerini yükleyeceğiniz yer + * `ELECTRON_RELEASE` - `true` şeklinde ayarlayın ve yükleme işlemi çalışacaktır, + yapmamanız halinde, `surf-build` sadece CI-type kontrolü yapacak, + tüm pull isteklerine uygun hale getirecektir. + * `CI` - `true` olarak ayarlayın yoksa çalışmayacaktır. + * `GITHUB_TOKEN` - bununla aynı şekilde ayarlayın `ELECTRON_GITHUB_TOKEN` + * `SURF_TEMP` - Windowsda ki 'path too long' sorunundan kaçınmak için `C:\Temp` şeklinde ayarlayın + * `TARGET_ARCH` - `ia32` veya `x64` şeklinde ayarlayın + +4. `script/upload.py` dosyasında ki `ELECTRON_REPO` kısmını, kendi kopyanız ile değiştirmek _zorundasınız_, + özellikle eğer bir Electron proper destekleyicisi iseniz. + +5. `surf-build -r https://github.com/MYORG/electron -s YOUR_COMMIT -n 'surf-PLATFORM-ARCH'` + +6. Kurulum bitene kadar uzunca bekleyin. diff --git a/docs-translations/tr-TR/tutorial/supported-platforms.md b/docs-translations/tr-TR/tutorial/supported-platforms.md new file mode 100644 index 0000000000..4cc131b103 --- /dev/null +++ b/docs-translations/tr-TR/tutorial/supported-platforms.md @@ -0,0 +1,29 @@ +# Desteklenen platformlar + +Aşağıdaki platformlar Electron tarafından desteklenmektedir: + +### macOS + +MacOS için sadece 64bit mimariler sağlanmakta olup, desteklenen minimum macOS versiyonu 10.9 dur. + +### Windows + +Windows 7 ve gelişmiş versiyonlar desteklenmektedir, eski işletim sistemleri desteklenmemektedir +(ve çalışmayacaktır). + +Windows `ia32` (`x86`) ve `x64` (`amd64`) mimarileri desteklenmektedir. +Unutmayın, `ARM` mimarisi al₺tında çalışan Windows işletim sistemleri şuan için desteklenmemektedir. + +### Linux + +Electron `ia32` (`i686`) ve `x64` (`amd64`) Prebuilt mimarileri Ubuntu 12.04 üzerinde kurulmuştur, +`arm` mimarisi ARM v7 ye karşılık olarak, hard-float ABI ve NEON Debian Wheezy ile kurulmuştur. + +Prebuilt +Prebuilt mimarisi ancak Electron'nun yapı platformu ile bağlantılı olan kütüphaneleri içeren dağıtımlar ile çalışır. +Bu yüzden sadece Ubuntu 12.04 üzerinde çalışması garanti ediliyor, fakat aşagidaki platformlarında +Electron Prebuilt mimarisini çalıştıra bileceği doğrulanmıştır. + +* Ubuntu 12.04 ve sonrası +* Fedora 21 +* Debian 8 From 34beb52edb49f9e6b64dc834524ac15cd09d695d Mon Sep 17 00:00:00 2001 From: "Mustafa C. Izol" Date: Mon, 10 Apr 2017 01:23:14 +0200 Subject: [PATCH 113/143] fix link to electron faq --- docs-translations/tr-TR/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs-translations/tr-TR/README.md b/docs-translations/tr-TR/README.md index 494433ee5a..a3487d298a 100644 --- a/docs-translations/tr-TR/README.md +++ b/docs-translations/tr-TR/README.md @@ -5,7 +5,7 @@ Eğer öyleyse, atom.io üzerinden [mevcut sürümler](https://electron.atom.io/ ## SSS(Sıkça Sorulan Sorular) Bir problem(issue) bildirmeden önce sıkça sorulan sorulara göz atın: -* [Electron SSS](https://github.com/electron/electron/tree/master/docs/faq/electron-faq.md) +* [Electron SSS](https://github.com/electron/electron/blob/master/docs/faq.md) ## Klavuzlar From 613c835eec62df8acde4287c9edbe009817c0687 Mon Sep 17 00:00:00 2001 From: "Mustafa C. Izol" Date: Mon, 10 Apr 2017 02:10:52 +0200 Subject: [PATCH 114/143] add turkish readme file --- docs-translations/tr-TR/project/README.md | 85 +++++++++++++++++++++++ 1 file changed, 85 insertions(+) create mode 100644 docs-translations/tr-TR/project/README.md diff --git a/docs-translations/tr-TR/project/README.md b/docs-translations/tr-TR/project/README.md new file mode 100644 index 0000000000..d5be777393 --- /dev/null +++ b/docs-translations/tr-TR/project/README.md @@ -0,0 +1,85 @@ +[![Electron Logo](https://electron.atom.io/images/electron-logo.svg)](https://electron.atom.io/) + +[![Travis Build Status](https://travis-ci.org/electron/electron.svg?branch=master)](https://travis-ci.org/electron/electron) +[![AppVeyor Build Status](https://ci.appveyor.com/api/projects/status/bc56v83355fi3369/branch/master?svg=true)](https://ci.appveyor.com/project/electron-bot/electron/branch/master) +[![devDependency Status](https://david-dm.org/electron/electron/dev-status.svg)](https://david-dm.org/electron/electron?type=dev) +[![Join the Electron Community on Slack](http://atom-slack.herokuapp.com/badge.svg)](http://atom-slack.herokuapp.com/) + +:memo: Mevcut çeviriler: [Korean](https://github.com/electron/electron/tree/master/docs-translations/ko-KR/project/README.md) | [Simplified Chinese](https://github.com/electron/electron/tree/master/docs-translations/zh-CN/project/README.md) | [Brazilian Portuguese](https://github.com/electron/electron/tree/master/docs-translations/pt-BR/project/README.md) | [Traditional Chinese](https://github.com/electron/electron/tree/master/docs-translations/zh-TW/project/README.md) | [Spanish](https://github.com/electron/electron/tree/master/docs-translations/es/project/README.md)| [Turkish](https://github.com/electron/electron/tree/master/docs-translations/tr-TR/project/README.md) + +Electron framework JavaScript, HTML ve CSS kullanarak çapraz platform +masaüstü uygulamaları yazmanıza yarar. Electron [Node.js](https://nodejs.org/) ile geliştirilmiş; +[Atom editor](https://github.com/atom/atom) ve birçok uygulama [apps](https://electron.atom.io/apps) tarafından kullanılmaktadir. + +Önemli duyurular için Twitter da [@ElectronJS](https://twitter.com/electronjs) adresini takip edin. + +Bu proje katılımcı sözleşmesine bağlıdır. Katılarak, +bu kodun sürdürülebilir olduğunu üstlenmeniz beklenmekte. +Lütfen uygun olmayan davranışları electron@github.com'a rapor edin. + +## Downloads + +Electron prebuilt mimarisini yüklemek için, +[`npm`](https://docs.npmjs.com/): + +```sh +# Development dependency olarak yükleyin +npm install electron --save-dev + +# `electron` komutunu global olarak $PATH'a yükleyin +npm install electron -g +``` + +Prebuilt mimarileri, debug sembolleri, ve fazlası için +[releases page](https://github.com/electron/electron/releases) sayfasını ziyaret edin. + +### Mirrors + +- [China](https://npm.taobao.org/mirrors/electron) + +## Dokümantasyon + +Klavuz ve API referansları [docs](https://github.com/electron/electron/tree/master/docs) klasöründe bulunabilir. +Aynı zamanda nasıl kurulum gerçekleştirileceği ve Electron'un gelişimine nasıl katılacağınızı +açıklayan dosyalar içermektedir. + +## Dökümantasyon Çevirileri + +- [Brazilian Portuguese](https://github.com/electron/electron/tree/master/docs-translations/pt-BR) +- [Korean](https://github.com/electron/electron/tree/master/docs-translations/ko-KR) +- [Japanese](https://github.com/electron/electron/tree/master/docs-translations/jp) +- [Spanish](https://github.com/electron/electron/tree/master/docs-translations/es) +- [Simplified Chinese](https://github.com/electron/electron/tree/master/docs-translations/zh-CN) +- [Traditional Chinese](https://github.com/electron/electron/tree/master/docs-translations/zh-TW) +- [Turkish](https://github.com/electron/electron/tree/master/docs-translations/tr-TR) +- [Thai](https://github.com/electron/electron/tree/master/docs-Translations/th-TH) +- [Ukrainian](https://github.com/electron/electron/tree/master/docs-translations/uk-UA) +- [Russian](https://github.com/electron/electron/tree/master/docs-translations/ru-RU) +- [French](https://github.com/electron/electron/tree/master/docs-translations/fr-FR) + +## Hızlı Başlangıç + +Minimal Electron uygulamasını calışırken görmek için [`electron/electron-quick-start`](https://github.com/electron/electron-quick-start) +repository'ni klonla ve çalıştır. + +## Topluluk + +Asağıdaki sayfalardan sorular sorabilir ve topluluk ile etkileşime geçebilirsiniz: + +- [`electron`](http://discuss.atom.io/c/electron) Atom forumundaki kategoriler +- `#atom-shell` Freenode kanal'ı +- [`Atom`](http://atom-slack.herokuapp.com/) Slack kanal'ı +- [`electron-br`](https://electron-br.slack.com) *(Brazilian Portuguese)* +- [`electron-kr`](http://www.meetup.com/electron-kr/) *(Korean)* +- [`electron-jp`](https://electron-jp.slack.com) *(Japanese)* +- [`electron-tr`](http://www.meetup.com/Electron-JS-Istanbul/) *(Turkish)* +- [`electron-id`](https://electron-id.slack.com) *(Indonesia)* + +Topluluk tarafından sağlanan örnek uygulamaları, aracları ve kaynaklara ulaşmak için +[awesome-electron](https://github.com/sindresorhus/awesome-electron) sayfasını ziyaret et. + +## Lisans + +[MIT](https://github.com/electron/electron/blob/master/LICENSE) + +Electron veya Github logolarını kullandığınızda, [GitHub logo guidelines](https://github.com/logos) sayfasını okuduğunuzdan emin olun. From 8f46137fda20aa98486f62e1ff776f261b46ea97 Mon Sep 17 00:00:00 2001 From: Milan Burda Date: Mon, 10 Apr 2017 02:12:15 +0200 Subject: [PATCH 115/143] Fix session.setPermissionRequestHandler webContents argument type --- docs/api/session.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/api/session.md b/docs/api/session.md index 7c7831c8ac..64c526c304 100644 --- a/docs/api/session.md +++ b/docs/api/session.md @@ -287,7 +287,7 @@ win.webContents.session.setCertificateVerifyProc((request, callback) => { #### `ses.setPermissionRequestHandler(handler)` * `handler` Function - * `webContents` Object - [WebContents](web-contents.md) requesting the permission. + * `webContents` [WebContents](web-contents.md) - WebContents requesting the permission. * `permission` String - Enum of 'media', 'geolocation', 'notifications', 'midiSysex', 'pointerLock', 'fullscreen', 'openExternal'. * `callback` Function From 475620119efd4b5a1cfc1c0ff1af003e753d41b7 Mon Sep 17 00:00:00 2001 From: "Mustafa C. Izol" Date: Mon, 10 Apr 2017 02:12:53 +0200 Subject: [PATCH 116/143] add turkish translation link to readme --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index b8f55c19bd..8a682bb727 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,7 @@ [![devDependency Status](https://david-dm.org/electron/electron/dev-status.svg)](https://david-dm.org/electron/electron?type=dev) [![Join the Electron Community on Slack](http://atom-slack.herokuapp.com/badge.svg)](http://atom-slack.herokuapp.com/) -:memo: Available Translations: [Korean](https://github.com/electron/electron/tree/master/docs-translations/ko-KR/project/README.md) | [Simplified Chinese](https://github.com/electron/electron/tree/master/docs-translations/zh-CN/project/README.md) | [Brazilian Portuguese](https://github.com/electron/electron/tree/master/docs-translations/pt-BR/project/README.md) | [Traditional Chinese](https://github.com/electron/electron/tree/master/docs-translations/zh-TW/project/README.md) | [Spanish](https://github.com/electron/electron/tree/master/docs-translations/es/project/README.md) +:memo: Available Translations: [Korean](https://github.com/electron/electron/tree/master/docs-translations/ko-KR/project/README.md) | [Simplified Chinese](https://github.com/electron/electron/tree/master/docs-translations/zh-CN/project/README.md) | [Brazilian Portuguese](https://github.com/electron/electron/tree/master/docs-translations/pt-BR/project/README.md) | [Traditional Chinese](https://github.com/electron/electron/tree/master/docs-translations/zh-TW/project/README.md) | [Spanish](https://github.com/electron/electron/tree/master/docs-translations/es/project/README.md) | [Turkish](https://github.com/electron/electron/tree/master/docs-translations/tr-TR/project/README.md) The Electron framework lets you write cross-platform desktop applications using JavaScript, HTML and CSS. It is based on [Node.js](https://nodejs.org/) and From fa0de5c2b4f861a7fb2494fc505daec562b2c4ff Mon Sep 17 00:00:00 2001 From: Milan Burda Date: Mon, 10 Apr 2017 02:18:36 +0200 Subject: [PATCH 117/143] Define filter argument type for WebRequest methods --- docs/api/web-request.md | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/docs/api/web-request.md b/docs/api/web-request.md index 6da98d81f1..a271add9da 100644 --- a/docs/api/web-request.md +++ b/docs/api/web-request.md @@ -42,6 +42,8 @@ The following methods are available on instances of `WebRequest`: #### `webRequest.onBeforeRequest([filter, ]listener)` * `filter` Object + * `urls` String[] - Array of URL patterns that will be used to filter out the + requests that do not match the URL patterns. * `listener` Function * `details` Object * `id` Integer @@ -66,6 +68,8 @@ The `callback` has to be called with an `response` object. #### `webRequest.onBeforeSendHeaders([filter, ]listener)` * `filter` Object + * `urls` String[] - Array of URL patterns that will be used to filter out the + requests that do not match the URL patterns. * `listener` Function The `listener` will be called with `listener(details, callback)` before sending @@ -90,6 +94,8 @@ The `callback` has to be called with an `response` object. #### `webRequest.onSendHeaders([filter, ]listener)` * `filter` Object + * `urls` String[] - Array of URL patterns that will be used to filter out the + requests that do not match the URL patterns. * `listener` Function * `details` Object * `id` Integer @@ -106,6 +112,8 @@ response are visible by the time this listener is fired. #### `webRequest.onHeadersReceived([filter, ]listener)` * `filter` Object + * `urls` String[] - Array of URL patterns that will be used to filter out the + requests that do not match the URL patterns. * `listener` Function The `listener` will be called with `listener(details, callback)` when HTTP @@ -134,6 +142,8 @@ The `callback` has to be called with an `response` object. #### `webRequest.onResponseStarted([filter, ]listener)` * `filter` Object + * `urls` String[] - Array of URL patterns that will be used to filter out the + requests that do not match the URL patterns. * `listener` Function * `details` Object * `id` Integer @@ -154,6 +164,8 @@ and response headers are available. #### `webRequest.onBeforeRedirect([filter, ]listener)` * `filter` Object + * `urls` String[] - Array of URL patterns that will be used to filter out the + requests that do not match the URL patterns. * `listener` Function * `details` Object * `id` String @@ -174,6 +186,8 @@ redirect is about to occur. #### `webRequest.onCompleted([filter, ]listener)` * `filter` Object + * `urls` String[] - Array of URL patterns that will be used to filter out the + requests that do not match the URL patterns. * `listener` Function * `details` Object * `id` Integer @@ -192,6 +206,8 @@ completed. #### `webRequest.onErrorOccurred([filter, ]listener)` * `filter` Object + * `urls` String[] - Array of URL patterns that will be used to filter out the + requests that do not match the URL patterns. * `listener` Function * `details` Object * `id` Integer From 0ce983363bfd841275d7adb3d281f25340444459 Mon Sep 17 00:00:00 2001 From: Hum4n01d Date: Sun, 9 Apr 2017 23:05:56 -0700 Subject: [PATCH 118/143] Add information about dragging not working with Dev tools open --- docs/api/frameless-window.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/api/frameless-window.md b/docs/api/frameless-window.md index 3ef5cdc93e..8fbbae10f6 100644 --- a/docs/api/frameless-window.md +++ b/docs/api/frameless-window.md @@ -98,6 +98,8 @@ By default, the frameless window is non-draggable. Apps need to specify `-webkit-app-region: no-drag` to exclude the non-draggable area from the draggable region. Note that only rectangular shapes are currently supported. +Note: `-webkit-app-region: drag` is known to have problems while the developer tools are open. See this [Github issue](https://github.com/electron/electron/issues/3647) for more information including a workaround. + To make the whole window draggable, you can add `-webkit-app-region: drag` as `body`'s style: From d3953f72802f68a45b18b9902be4d604cab9015f Mon Sep 17 00:00:00 2001 From: Catalin Fratila Date: Mon, 10 Apr 2017 16:41:16 +0200 Subject: [PATCH 119/143] #9128: Removed unused dll from distribution. --- docs-translations/ko-KR/tutorial/windows-store-guide.md | 3 +-- docs-translations/zh-CN/tutorial/windows-store-guide.md | 3 +-- docs/tutorial/windows-store-guide.md | 3 +-- electron.gyp | 1 - script/create-dist.py | 1 - 5 files changed, 3 insertions(+), 8 deletions(-) diff --git a/docs-translations/ko-KR/tutorial/windows-store-guide.md b/docs-translations/ko-KR/tutorial/windows-store-guide.md index 34d36d6bc5..23a4bbc32f 100644 --- a/docs-translations/ko-KR/tutorial/windows-store-guide.md +++ b/docs-translations/ko-KR/tutorial/windows-store-guide.md @@ -67,8 +67,7 @@ npm install -g electron-windows-store │ └── atom.asar ├── snapshot_blob.bin ├── squirrel.exe -├── ui_resources_200_percent.pak -└── xinput1_3.dll +└── ui_resources_200_percent.pak ``` ## `electron-windows-store` 실행하기 diff --git a/docs-translations/zh-CN/tutorial/windows-store-guide.md b/docs-translations/zh-CN/tutorial/windows-store-guide.md index 67cd39e5a5..a34f40d2ee 100644 --- a/docs-translations/zh-CN/tutorial/windows-store-guide.md +++ b/docs-translations/zh-CN/tutorial/windows-store-guide.md @@ -49,8 +49,7 @@ npm install -g electron-windows-store │   └── atom.asar ├── snapshot_blob.bin ├── squirrel.exe -├── ui_resources_200_percent.pak -└── xinput1_3.dll +└── ui_resources_200_percent.pak ``` ## 步骤 2: 运行 electron-windows-store diff --git a/docs/tutorial/windows-store-guide.md b/docs/tutorial/windows-store-guide.md index 4cca798aec..abf9643181 100644 --- a/docs/tutorial/windows-store-guide.md +++ b/docs/tutorial/windows-store-guide.md @@ -69,8 +69,7 @@ The output should look roughly like this: │   └── atom.asar ├── snapshot_blob.bin ├── squirrel.exe -├── ui_resources_200_percent.pak -└── xinput1_3.dll +└── ui_resources_200_percent.pak ``` ## Step 2: Running electron-windows-store diff --git a/electron.gyp b/electron.gyp index e6dd08bdfb..8456a337e1 100644 --- a/electron.gyp +++ b/electron.gyp @@ -159,7 +159,6 @@ '<(libchromiumcontent_dir)/natives_blob.bin', '<(libchromiumcontent_dir)/snapshot_blob.bin', 'external_binaries/d3dcompiler_47.dll', - 'external_binaries/xinput1_3.dll', ], }, ], diff --git a/script/create-dist.py b/script/create-dist.py index 3d4b62624e..27032400f3 100755 --- a/script/create-dist.py +++ b/script/create-dist.py @@ -43,7 +43,6 @@ TARGET_BINARIES = { 'content_resources_200_percent.pak', 'ui_resources_200_percent.pak', 'views_resources_200_percent.pak', - 'xinput1_3.dll', 'natives_blob.bin', 'snapshot_blob.bin', ], From 676f02e0016a69a47343dd82966808bb2beefe59 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Mon, 10 Apr 2017 08:17:55 -0700 Subject: [PATCH 120/143] Tweak GitHub spelling --- docs/api/frameless-window.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/api/frameless-window.md b/docs/api/frameless-window.md index 8fbbae10f6..4f091ec6c3 100644 --- a/docs/api/frameless-window.md +++ b/docs/api/frameless-window.md @@ -98,7 +98,7 @@ By default, the frameless window is non-draggable. Apps need to specify `-webkit-app-region: no-drag` to exclude the non-draggable area from the draggable region. Note that only rectangular shapes are currently supported. -Note: `-webkit-app-region: drag` is known to have problems while the developer tools are open. See this [Github issue](https://github.com/electron/electron/issues/3647) for more information including a workaround. +Note: `-webkit-app-region: drag` is known to have problems while the developer tools are open. See this [GitHub issue](https://github.com/electron/electron/issues/3647) for more information including a workaround. To make the whole window draggable, you can add `-webkit-app-region: drag` as `body`'s style: From 2c6ef95923b71786f1d84e6105af64e199c144ae Mon Sep 17 00:00:00 2001 From: Mustafa Date: Mon, 10 Apr 2017 18:41:52 +0200 Subject: [PATCH 121/143] add electron slack channel for turkish community --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 8a682bb727..213580a5e2 100644 --- a/README.md +++ b/README.md @@ -75,7 +75,7 @@ forums - [`electron-br`](https://electron-br.slack.com) *(Brazilian Portuguese)* - [`electron-kr`](http://www.meetup.com/electron-kr/) *(Korean)* - [`electron-jp`](https://electron-jp.slack.com) *(Japanese)* -- [`electron-tr`](http://www.meetup.com/Electron-JS-Istanbul/) *(Turkish)* +- [`electron-tr`](https://electron-tr.slack.com) *(Turkish)* - [`electron-id`](https://electron-id.slack.com) *(Indonesia)* Check out [awesome-electron](https://github.com/sindresorhus/awesome-electron) From c59ef0efc5473b7fa3210c65199a608d4b22fa93 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Tue, 11 Apr 2017 15:17:15 +0900 Subject: [PATCH 122/143] Enable per-monitor DPI --- atom/browser/resources/win/atom.manifest | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/atom/browser/resources/win/atom.manifest b/atom/browser/resources/win/atom.manifest index 64c07ded17..7608ffb20f 100644 --- a/atom/browser/resources/win/atom.manifest +++ b/atom/browser/resources/win/atom.manifest @@ -32,7 +32,7 @@ - true + true/pm true From 29c68182df5d25d46911aecfac161f895861638c Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Thu, 6 Apr 2017 15:42:37 -0700 Subject: [PATCH 123/143] Always set NSScrollViewRubberbanding scroll bounce pref --- atom/renderer/renderer_client_base.cc | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/atom/renderer/renderer_client_base.cc b/atom/renderer/renderer_client_base.cc index 3ee72b3c0d..4d8bc6bebe 100644 --- a/atom/renderer/renderer_client_base.cc +++ b/atom/renderer/renderer_client_base.cc @@ -96,16 +96,14 @@ void RendererClientBase::RenderThreadStarted() { #endif #if defined(OS_MACOSX) - // Disable rubber banding by default. base::CommandLine* command_line = base::CommandLine::ForCurrentProcess(); - if (!command_line->HasSwitch(switches::kScrollBounce)) { - base::ScopedCFTypeRef key( - base::SysUTF8ToCFStringRef("NSScrollViewRubberbanding")); - base::ScopedCFTypeRef value( - base::SysUTF8ToCFStringRef("false")); - CFPreferencesSetAppValue(key, value, kCFPreferencesCurrentApplication); - CFPreferencesAppSynchronize(kCFPreferencesCurrentApplication); - } + bool scroll_bounce = command_line->HasSwitch(switches::kScrollBounce); + base::ScopedCFTypeRef rubber_banding_key( + base::SysUTF8ToCFStringRef("NSScrollViewRubberbanding")); + CFPreferencesSetAppValue(rubber_banding_key, + scroll_bounce ? kCFBooleanTrue : kCFBooleanFalse, + kCFPreferencesCurrentApplication); + CFPreferencesAppSynchronize(kCFPreferencesCurrentApplication); #endif } From bfb93881916578f73bf48c929ceb73a1b3b95710 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Thu, 6 Apr 2017 15:02:32 -0700 Subject: [PATCH 124/143] Add failing spec for app.exit with >2 windows --- spec/api-app-spec.js | 10 ++++++++++ .../api/exit-closes-all-windows-app/main.js | 19 +++++++++++++++++++ .../exit-closes-all-windows-app/package.json | 4 ++++ 3 files changed, 33 insertions(+) create mode 100644 spec/fixtures/api/exit-closes-all-windows-app/main.js create mode 100644 spec/fixtures/api/exit-closes-all-windows-app/package.json diff --git a/spec/api-app-spec.js b/spec/api-app-spec.js index 301d6ae4bf..9a9b4334bc 100644 --- a/spec/api-app-spec.js +++ b/spec/api-app-spec.js @@ -137,6 +137,16 @@ describe('app module', function () { done() }) }) + + it('closes all windows', function (done) { + var appPath = path.join(__dirname, 'fixtures', 'api', 'exit-closes-all-windows-app') + var electronPath = remote.getGlobal('process').execPath + appProcess = ChildProcess.spawn(electronPath, [appPath]) + appProcess.on('close', function (code) { + assert.equal(code, 123) + done() + }) + }) }) describe('app.relaunch', function () { diff --git a/spec/fixtures/api/exit-closes-all-windows-app/main.js b/spec/fixtures/api/exit-closes-all-windows-app/main.js new file mode 100644 index 0000000000..c97d8d1f19 --- /dev/null +++ b/spec/fixtures/api/exit-closes-all-windows-app/main.js @@ -0,0 +1,19 @@ +const {app, BrowserWindow} = require('electron') + +const windows = [] + +function createWindow (id) { + const window = new BrowserWindow({show: false}) + window.loadURL(`data:,window${id}`) + windows.push(window) +} + +app.once('ready', () => { + for (let i = 1; i <= 5; i++) { + createWindow(i) + } + + setImmediate(function () { + app.exit(123) + }) +}) diff --git a/spec/fixtures/api/exit-closes-all-windows-app/package.json b/spec/fixtures/api/exit-closes-all-windows-app/package.json new file mode 100644 index 0000000000..ae52532315 --- /dev/null +++ b/spec/fixtures/api/exit-closes-all-windows-app/package.json @@ -0,0 +1,4 @@ +{ + "name": "electron-exit-closes-all-windows", + "main": "main.js" +} From 8311aa667c0bc637e9cf7ba72b1a8d32ee706991 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Thu, 6 Apr 2017 14:25:22 -0700 Subject: [PATCH 125/143] Add DestroyAllWindows helper that uses vector copy --- atom/browser/browser.cc | 3 +-- atom/browser/window_list.cc | 7 +++++++ atom/browser/window_list.h | 3 +++ 3 files changed, 11 insertions(+), 2 deletions(-) diff --git a/atom/browser/browser.cc b/atom/browser/browser.cc index b18ab7b70f..1df1f316c1 100644 --- a/atom/browser/browser.cc +++ b/atom/browser/browser.cc @@ -71,8 +71,7 @@ void Browser::Exit(mate::Arguments* args) { } else { // Unlike Quit(), we do not ask to close window, but destroy the window // without asking. - for (NativeWindow* window : *window_list) - window->CloseContents(nullptr); // e.g. Destroy() + atom::WindowList::DestroyAllWindows(); } } } diff --git a/atom/browser/window_list.cc b/atom/browser/window_list.cc index d627f6d120..bcf4a9f1e2 100644 --- a/atom/browser/window_list.cc +++ b/atom/browser/window_list.cc @@ -76,6 +76,13 @@ void WindowList::CloseAllWindows() { window->Close(); } +// static +void WindowList::DestroyAllWindows() { + WindowVector windows = GetInstance()->windows_; + for (const auto& window : windows) + window->CloseContents(nullptr); // e.g. Destroy() +} + WindowList::WindowList() { } diff --git a/atom/browser/window_list.h b/atom/browser/window_list.h index d9b307352e..557a7969e5 100644 --- a/atom/browser/window_list.h +++ b/atom/browser/window_list.h @@ -51,6 +51,9 @@ class WindowList { // Closes all windows. static void CloseAllWindows(); + // Destroy all windows. + static void DestroyAllWindows(); + private: WindowList(); ~WindowList(); From 0883a9f96606cb54fd29693eab5d1ec3c573f7f6 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Thu, 6 Apr 2017 14:37:39 -0700 Subject: [PATCH 126/143] Use CloseAllWindows helper --- atom/browser/api/atom_api_auto_updater.cc | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/atom/browser/api/atom_api_auto_updater.cc b/atom/browser/api/atom_api_auto_updater.cc index 276d889006..60bbcbda04 100644 --- a/atom/browser/api/atom_api_auto_updater.cc +++ b/atom/browser/api/atom_api_auto_updater.cc @@ -95,8 +95,7 @@ void AutoUpdater::QuitAndInstall() { // Otherwise do the restart after all windows have been closed. window_list->AddObserver(this); - for (NativeWindow* window : *window_list) - window->Close(); + WindowList::CloseAllWindows(); } // static From da5d7d72b034c4bd7f7b1dbdd2d4f6f4c8cd0fb6 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Thu, 6 Apr 2017 14:43:37 -0700 Subject: [PATCH 127/143] Add GetWindows helper that returns a vector --- atom/browser/browser_linux.cc | 4 +--- atom/browser/browser_mac.mm | 5 ++--- atom/browser/native_window.cc | 3 +-- atom/browser/window_list.cc | 5 +++++ atom/browser/window_list.h | 15 ++------------- 5 files changed, 11 insertions(+), 21 deletions(-) diff --git a/atom/browser/browser_linux.cc b/atom/browser/browser_linux.cc index 4dd799dfaf..f569040a21 100644 --- a/atom/browser/browser_linux.cc +++ b/atom/browser/browser_linux.cc @@ -16,9 +16,7 @@ namespace atom { void Browser::Focus() { // Focus on the first visible window. - WindowList* list = WindowList::GetInstance(); - for (WindowList::iterator iter = list->begin(); iter != list->end(); ++iter) { - NativeWindow* window = *iter; + for (const auto& window : WindowList::GetWindows()) { if (window->IsVisible()) { window->Focus(true); break; diff --git a/atom/browser/browser_mac.mm b/atom/browser/browser_mac.mm index 51604e377c..38a0a003d9 100644 --- a/atom/browser/browser_mac.mm +++ b/atom/browser/browser_mac.mm @@ -204,9 +204,8 @@ std::string Browser::DockGetBadgeText() { } void Browser::DockHide() { - WindowList* list = WindowList::GetInstance(); - for (WindowList::iterator it = list->begin(); it != list->end(); ++it) - [(*it)->GetNativeWindow() setCanHide:NO]; + for (const auto& window : WindowList::GetWindows()) + [window->GetNativeWindow() setCanHide:NO]; ProcessSerialNumber psn = { 0, kCurrentProcess }; TransformProcessType(&psn, kProcessTransformToUIElementApplication); diff --git a/atom/browser/native_window.cc b/atom/browser/native_window.cc index af32a2e8a8..316cc8dc2e 100644 --- a/atom/browser/native_window.cc +++ b/atom/browser/native_window.cc @@ -104,8 +104,7 @@ NativeWindow::~NativeWindow() { // static NativeWindow* NativeWindow::FromWebContents( content::WebContents* web_contents) { - WindowList& window_list = *WindowList::GetInstance(); - for (NativeWindow* window : window_list) { + for (const auto& window : WindowList::GetWindows()) { if (window->web_contents() == web_contents) return window; } diff --git a/atom/browser/window_list.cc b/atom/browser/window_list.cc index bcf4a9f1e2..8fa2ed6743 100644 --- a/atom/browser/window_list.cc +++ b/atom/browser/window_list.cc @@ -26,6 +26,11 @@ WindowList* WindowList::GetInstance() { return instance_; } +// static +WindowList::WindowVector WindowList::GetWindows() { + return GetInstance()->windows_; +} + // static void WindowList::AddWindow(NativeWindow* window) { DCHECK(window); diff --git a/atom/browser/window_list.h b/atom/browser/window_list.h index 557a7969e5..81ff5de105 100644 --- a/atom/browser/window_list.h +++ b/atom/browser/window_list.h @@ -19,24 +19,13 @@ class WindowListObserver; class WindowList { public: typedef std::vector WindowVector; - typedef WindowVector::iterator iterator; - typedef WindowVector::const_iterator const_iterator; - - // Windows are added to the list before they have constructed windows, - // so the |window()| member function may return NULL. - const_iterator begin() const { return windows_.begin(); } - const_iterator end() const { return windows_.end(); } - - iterator begin() { return windows_.begin(); } - iterator end() { return windows_.end(); } bool empty() const { return windows_.empty(); } - size_t size() const { return windows_.size(); } - - NativeWindow* get(size_t index) const { return windows_[index]; } static WindowList* GetInstance(); + static WindowVector GetWindows(); + // Adds or removes |window| from the list it is associated with. static void AddWindow(NativeWindow* window); static void RemoveWindow(NativeWindow* window); From e7b679ead64045846aa457a6af8bd251ffe239e3 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Thu, 6 Apr 2017 14:48:58 -0700 Subject: [PATCH 128/143] Add IsEmpty helper and remove GetInstance public usage --- atom/browser/api/atom_api_auto_updater.cc | 5 ++--- atom/browser/browser.cc | 10 ++++------ atom/browser/window_list.cc | 5 +++++ atom/browser/window_list.h | 7 +++---- 4 files changed, 14 insertions(+), 13 deletions(-) diff --git a/atom/browser/api/atom_api_auto_updater.cc b/atom/browser/api/atom_api_auto_updater.cc index 60bbcbda04..ea3024191e 100644 --- a/atom/browser/api/atom_api_auto_updater.cc +++ b/atom/browser/api/atom_api_auto_updater.cc @@ -87,14 +87,13 @@ void AutoUpdater::SetFeedURL(const std::string& url, mate::Arguments* args) { void AutoUpdater::QuitAndInstall() { // If we don't have any window then quitAndInstall immediately. - WindowList* window_list = WindowList::GetInstance(); - if (window_list->empty()) { + if (WindowList::IsEmpty()) { auto_updater::AutoUpdater::QuitAndInstall(); return; } // Otherwise do the restart after all windows have been closed. - window_list->AddObserver(this); + WindowList::AddObserver(this); WindowList::CloseAllWindows(); } diff --git a/atom/browser/browser.cc b/atom/browser/browser.cc index 1df1f316c1..b2900a326f 100644 --- a/atom/browser/browser.cc +++ b/atom/browser/browser.cc @@ -43,11 +43,10 @@ void Browser::Quit() { if (!is_quiting_) return; - atom::WindowList* window_list = atom::WindowList::GetInstance(); - if (window_list->empty()) + if (atom::WindowList::IsEmpty()) NotifyAndShutdown(); - - window_list->CloseAllWindows(); + else + atom::WindowList::CloseAllWindows(); } void Browser::Exit(mate::Arguments* args) { @@ -65,8 +64,7 @@ void Browser::Exit(mate::Arguments* args) { is_exiting_ = true; // Must destroy windows before quitting, otherwise bad things can happen. - atom::WindowList* window_list = atom::WindowList::GetInstance(); - if (window_list->empty()) { + if (atom::WindowList::IsEmpty()) { Shutdown(); } else { // Unlike Quit(), we do not ask to close window, but destroy the window diff --git a/atom/browser/window_list.cc b/atom/browser/window_list.cc index 8fa2ed6743..374389e0a7 100644 --- a/atom/browser/window_list.cc +++ b/atom/browser/window_list.cc @@ -31,6 +31,11 @@ WindowList::WindowVector WindowList::GetWindows() { return GetInstance()->windows_; } +// static +bool WindowList::IsEmpty() { + return GetInstance()->windows_.empty(); +} + // static void WindowList::AddWindow(NativeWindow* window) { DCHECK(window); diff --git a/atom/browser/window_list.h b/atom/browser/window_list.h index 81ff5de105..e336c8073d 100644 --- a/atom/browser/window_list.h +++ b/atom/browser/window_list.h @@ -20,11 +20,8 @@ class WindowList { public: typedef std::vector WindowVector; - bool empty() const { return windows_.empty(); } - - static WindowList* GetInstance(); - static WindowVector GetWindows(); + static bool IsEmpty(); // Adds or removes |window| from the list it is associated with. static void AddWindow(NativeWindow* window); @@ -44,6 +41,8 @@ class WindowList { static void DestroyAllWindows(); private: + static WindowList* GetInstance(); + WindowList(); ~WindowList(); From 4f26424ace569e25dd35f21f9ef09895b84df0f4 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Tue, 11 Apr 2017 16:53:24 -0700 Subject: [PATCH 129/143] Upgrade brightray for Windows 7 notifications --- vendor/brightray | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vendor/brightray b/vendor/brightray index baccc07794..28d713bb2a 160000 --- a/vendor/brightray +++ b/vendor/brightray @@ -1 +1 @@ -Subproject commit baccc077948f504c6a6db58e855fd33938b2b625 +Subproject commit 28d713bb2a82ba690a21d62522ecd7bad09caba8 From 8b9f7e5b00187a1fc608c883fdfdbae9727f1729 Mon Sep 17 00:00:00 2001 From: Birunthan Mohanathas Date: Tue, 11 Apr 2017 20:47:30 +0300 Subject: [PATCH 130/143] Implement initial, experimental BrowserView API Right now, `` is the only way to embed additional content in a `BrowserWindow`. Unfortunately `` suffers from a [number of problems](https://github.com/electron/electron/issues?utf8=%E2%9C%93&q=is%3Aissue%20is%3Aopen%20label%3Awebview%20). To make matters worse, many of these are upstream Chromium bugs instead of Electron-specific bugs. For us at [Figma](https://www.figma.com), the main issue is very slow performance. Despite the upstream improvements to `` through the OOPIF work, it is probable that there will continue to be ``-specific bugs in the future. Therefore, this introduces a `` alternative to called `BrowserView`, which... - is a thin wrapper around `api::WebContents` (so bugs in `BrowserView` will likely also be bugs in `BrowserWindow` web contents) - is instantiated in the main process like `BrowserWindow` (and unlike ``, which lives in the DOM of a `BrowserWindow` web contents) - needs to be added to a `BrowserWindow` to display something on the screen This implements the most basic API. The API is expected to evolve and change in the near future and has consequently been marked as experimental. Please do not use this API in production unless you are prepared to deal with breaking changes. In the future, we will want to change the API to support multiple `BrowserView`s per window. We will also want to consider z-ordering auto-resizing, and possibly even nested views. --- atom/browser/api/atom_api_browser_view.cc | 128 +++++++++++++++++++ atom/browser/api/atom_api_browser_view.h | 70 ++++++++++ atom/browser/api/atom_api_web_contents.cc | 11 +- atom/browser/api/atom_api_web_contents.h | 9 +- atom/browser/api/atom_api_window.cc | 29 ++++- atom/browser/api/atom_api_window.h | 3 + atom/browser/common_web_contents_delegate.cc | 9 +- atom/browser/native_browser_view.cc | 18 +++ atom/browser/native_browser_view.h | 51 ++++++++ atom/browser/native_browser_view_mac.h | 29 +++++ atom/browser/native_browser_view_mac.mm | 40 ++++++ atom/browser/native_browser_view_views.cc | 36 ++++++ atom/browser/native_browser_view_views.h | 27 ++++ atom/browser/native_window.h | 3 + atom/browser/native_window_mac.h | 3 + atom/browser/native_window_mac.mm | 24 +++- atom/browser/native_window_views.cc | 16 +++ atom/browser/native_window_views.h | 3 + atom/common/node_bindings.cc | 5 +- docs/api/browser-view.md | 62 +++++++++ docs/api/browser-window.md | 7 + filenames.gypi | 25 ++-- lib/browser/api/browser-view.js | 8 ++ lib/browser/api/module-list.js | 1 + spec/api-browser-view-spec.js | 71 ++++++++++ 25 files changed, 665 insertions(+), 23 deletions(-) create mode 100644 atom/browser/api/atom_api_browser_view.cc create mode 100644 atom/browser/api/atom_api_browser_view.h create mode 100644 atom/browser/native_browser_view.cc create mode 100644 atom/browser/native_browser_view.h create mode 100644 atom/browser/native_browser_view_mac.h create mode 100644 atom/browser/native_browser_view_mac.mm create mode 100644 atom/browser/native_browser_view_views.cc create mode 100644 atom/browser/native_browser_view_views.h create mode 100644 docs/api/browser-view.md create mode 100644 lib/browser/api/browser-view.js create mode 100644 spec/api-browser-view-spec.js diff --git a/atom/browser/api/atom_api_browser_view.cc b/atom/browser/api/atom_api_browser_view.cc new file mode 100644 index 0000000000..67533e645d --- /dev/null +++ b/atom/browser/api/atom_api_browser_view.cc @@ -0,0 +1,128 @@ +// Copyright (c) 2017 GitHub, Inc. +// Use of this source code is governed by the MIT license that can be +// found in the LICENSE file. + +#include "atom/browser/api/atom_api_browser_view.h" + +#include "atom/browser/api/atom_api_web_contents.h" +#include "atom/browser/browser.h" +#include "atom/browser/native_browser_view.h" +#include "atom/common/color_util.h" +#include "atom/common/native_mate_converters/gfx_converter.h" +#include "atom/common/native_mate_converters/value_converter.h" +#include "atom/common/node_includes.h" +#include "atom/common/options_switches.h" +#include "native_mate/constructor.h" +#include "native_mate/dictionary.h" +#include "ui/gfx/geometry/rect.h" + +namespace atom { + +namespace api { + +BrowserView::BrowserView(v8::Isolate* isolate, + v8::Local wrapper, + const mate::Dictionary& options) + : api_web_contents_(nullptr) { + Init(isolate, wrapper, options); +} + +void BrowserView::Init(v8::Isolate* isolate, + v8::Local wrapper, + const mate::Dictionary& options) { + mate::Dictionary web_preferences = mate::Dictionary::CreateEmpty(isolate); + options.Get(options::kWebPreferences, &web_preferences); + web_preferences.Set("isBrowserView", true); + mate::Handle web_contents = + WebContents::Create(isolate, web_preferences); + + web_contents_.Reset(isolate, web_contents.ToV8()); + api_web_contents_ = web_contents.get(); + + view_.reset(NativeBrowserView::Create( + api_web_contents_->managed_web_contents()->GetView())); + + InitWith(isolate, wrapper); +} + +BrowserView::~BrowserView() { + api_web_contents_->DestroyWebContents(); +} + +// static +mate::WrappableBase* BrowserView::New(mate::Arguments* args) { + if (!Browser::Get()->is_ready()) { + args->ThrowError("Cannot create BrowserView before app is ready"); + return nullptr; + } + + if (args->Length() > 1) { + args->ThrowError("Too many arguments"); + return nullptr; + } + + mate::Dictionary options; + if (!(args->Length() == 1 && args->GetNext(&options))) { + options = mate::Dictionary::CreateEmpty(args->isolate()); + } + + return new BrowserView(args->isolate(), args->GetThis(), options); +} + +int32_t BrowserView::ID() const { + return weak_map_id(); +} + +void BrowserView::SetBounds(const gfx::Rect& bounds) { + view_->SetBounds(bounds); +} + +void BrowserView::SetBackgroundColor(const std::string& color_name) { + view_->SetBackgroundColor(ParseHexColor(color_name)); +} + +v8::Local BrowserView::WebContents() { + if (web_contents_.IsEmpty()) { + return v8::Null(isolate()); + } + + return v8::Local::New(isolate(), web_contents_); +} + +// static +void BrowserView::BuildPrototype(v8::Isolate* isolate, + v8::Local prototype) { + prototype->SetClassName(mate::StringToV8(isolate, "BrowserView")); + mate::ObjectTemplateBuilder(isolate, prototype->PrototypeTemplate()) + .MakeDestroyable() + .SetMethod("setBounds", &BrowserView::SetBounds) + .SetMethod("setBackgroundColor", &BrowserView::SetBackgroundColor) + .SetProperty("webContents", &BrowserView::WebContents) + .SetProperty("id", &BrowserView::ID); +} + +} // namespace api + +} // namespace atom + +namespace { + +using atom::api::BrowserView; + +void Initialize(v8::Local exports, + v8::Local unused, + v8::Local context, + void* priv) { + v8::Isolate* isolate = context->GetIsolate(); + BrowserView::SetConstructor(isolate, base::Bind(&BrowserView::New)); + + mate::Dictionary browser_view( + isolate, BrowserView::GetConstructor(isolate)->GetFunction()); + + mate::Dictionary dict(isolate, exports); + dict.Set("BrowserView", browser_view); +} + +} // namespace + +NODE_MODULE_CONTEXT_AWARE_BUILTIN(atom_browser_browser_view, Initialize) diff --git a/atom/browser/api/atom_api_browser_view.h b/atom/browser/api/atom_api_browser_view.h new file mode 100644 index 0000000000..875d842898 --- /dev/null +++ b/atom/browser/api/atom_api_browser_view.h @@ -0,0 +1,70 @@ +// Copyright (c) 2017 GitHub, Inc. +// Use of this source code is governed by the MIT license that can be +// found in the LICENSE file. + +#ifndef ATOM_BROWSER_API_ATOM_API_BROWSER_VIEW_H_ +#define ATOM_BROWSER_API_ATOM_API_BROWSER_VIEW_H_ + +#include +#include + +#include "atom/browser/api/trackable_object.h" +#include "native_mate/handle.h" + +namespace gfx { +class Rect; +} + +namespace mate { +class Arguments; +class Dictionary; +} // namespace mate + +namespace atom { + +class NativeBrowserView; + +namespace api { + +class WebContents; + +class BrowserView : public mate::TrackableObject { + public: + static mate::WrappableBase* New(mate::Arguments* args); + + static void BuildPrototype(v8::Isolate* isolate, + v8::Local prototype); + + NativeBrowserView* view() const { return view_.get(); } + + int32_t ID() const; + + protected: + BrowserView(v8::Isolate* isolate, + v8::Local wrapper, + const mate::Dictionary& options); + ~BrowserView() override; + + private: + void Init(v8::Isolate* isolate, + v8::Local wrapper, + const mate::Dictionary& options); + + void SetBounds(const gfx::Rect& bounds); + void SetBackgroundColor(const std::string& color_name); + + v8::Local WebContents(); + + v8::Global web_contents_; + class WebContents* api_web_contents_; + + std::unique_ptr view_; + + DISALLOW_COPY_AND_ASSIGN(BrowserView); +}; + +} // namespace api + +} // namespace atom + +#endif // ATOM_BROWSER_API_ATOM_API_BROWSER_VIEW_H_ diff --git a/atom/browser/api/atom_api_web_contents.cc b/atom/browser/api/atom_api_web_contents.cc index 9390777f9c..d3e7bae2e4 100644 --- a/atom/browser/api/atom_api_web_contents.cc +++ b/atom/browser/api/atom_api_web_contents.cc @@ -188,6 +188,7 @@ struct Converter { switch (val) { case Type::BACKGROUND_PAGE: type = "backgroundPage"; break; case Type::BROWSER_WINDOW: type = "window"; break; + case Type::BROWSER_VIEW: type = "browserView"; break; case Type::REMOTE: type = "remote"; break; case Type::WEB_VIEW: type = "webview"; break; case Type::OFF_SCREEN: type = "offscreen"; break; @@ -202,10 +203,12 @@ struct Converter { std::string type; if (!ConvertFromV8(isolate, val, &type)) return false; - if (type == "webview") { - *out = Type::WEB_VIEW; - } else if (type == "backgroundPage") { + if (type == "backgroundPage") { *out = Type::BACKGROUND_PAGE; + } else if (type == "browserView") { + *out = Type::BROWSER_VIEW; + } else if (type == "webview") { + *out = Type::WEB_VIEW; } else if (type == "offscreen") { *out = Type::OFF_SCREEN; } else { @@ -306,6 +309,8 @@ WebContents::WebContents(v8::Isolate* isolate, const mate::Dictionary& options) type_ = WEB_VIEW; else if (options.Get("isBackgroundPage", &b) && b) type_ = BACKGROUND_PAGE; + else if (options.Get("isBrowserView", &b) && b) + type_ = BROWSER_VIEW; else if (options.Get("offscreen", &b) && b) type_ = OFF_SCREEN; diff --git a/atom/browser/api/atom_api_web_contents.h b/atom/browser/api/atom_api_web_contents.h index c289503b43..1301ed15f7 100644 --- a/atom/browser/api/atom_api_web_contents.h +++ b/atom/browser/api/atom_api_web_contents.h @@ -53,10 +53,11 @@ class WebContents : public mate::TrackableObject, public: enum Type { BACKGROUND_PAGE, // A DevTools extension background page. - BROWSER_WINDOW, // Used by BrowserWindow. - REMOTE, // Thin wrap around an existing WebContents. - WEB_VIEW, // Used by . - OFF_SCREEN, // Used for offscreen rendering + BROWSER_WINDOW, // Used by BrowserWindow. + BROWSER_VIEW, // Used by BrowserView. + REMOTE, // Thin wrap around an existing WebContents. + WEB_VIEW, // Used by . + OFF_SCREEN, // Used for offscreen rendering }; // For node.js callback function type: function(error, buffer) diff --git a/atom/browser/api/atom_api_window.cc b/atom/browser/api/atom_api_window.cc index 9a4ae5850d..c670762491 100644 --- a/atom/browser/api/atom_api_window.cc +++ b/atom/browser/api/atom_api_window.cc @@ -5,6 +5,7 @@ #include "atom/browser/api/atom_api_window.h" #include "atom/common/native_mate_converters/value_converter.h" +#include "atom/browser/api/atom_api_browser_view.h" #include "atom/browser/api/atom_api_menu.h" #include "atom/browser/api/atom_api_web_contents.h" #include "atom/browser/browser.h" @@ -816,6 +817,25 @@ std::vector> Window::GetChildWindows() const { return child_windows_.Values(isolate()); } +v8::Local Window::GetBrowserView() const { + if (browser_view_.IsEmpty()) { + return v8::Null(isolate()); + } + + return v8::Local::New(isolate(), browser_view_); +} + +void Window::SetBrowserView(v8::Local value) { + mate::Handle browser_view; + if (value->IsNull()) { + window_->SetBrowserView(nullptr); + browser_view_.Reset(); + } else if (mate::ConvertFromV8(isolate(), value, &browser_view)) { + window_->SetBrowserView(browser_view->view()); + browser_view_.Reset(isolate(), value); + } +} + bool Window::IsModal() const { return window_->is_modal(); } @@ -862,10 +882,11 @@ int32_t Window::ID() const { } v8::Local Window::WebContents(v8::Isolate* isolate) { - if (web_contents_.IsEmpty()) + if (web_contents_.IsEmpty()) { return v8::Null(isolate); - else - return v8::Local::New(isolate, web_contents_); + } + + return v8::Local::New(isolate, web_contents_); } void Window::RemoveFromParentChildWindows() { @@ -910,6 +931,8 @@ void Window::BuildPrototype(v8::Isolate* isolate, #endif .SetMethod("getParentWindow", &Window::GetParentWindow) .SetMethod("getChildWindows", &Window::GetChildWindows) + .SetMethod("getBrowserView", &Window::GetBrowserView) + .SetMethod("setBrowserView", &Window::SetBrowserView) .SetMethod("isModal", &Window::IsModal) .SetMethod("getNativeWindowHandle", &Window::GetNativeWindowHandle) .SetMethod("getBounds", &Window::GetBounds) diff --git a/atom/browser/api/atom_api_window.h b/atom/browser/api/atom_api_window.h index 24afec354d..d464af58ea 100644 --- a/atom/browser/api/atom_api_window.h +++ b/atom/browser/api/atom_api_window.h @@ -180,6 +180,8 @@ class Window : public mate::TrackableObject, void SetParentWindow(v8::Local value, mate::Arguments* args); v8::Local GetParentWindow() const; std::vector> GetChildWindows() const; + v8::Local GetBrowserView() const; + void SetBrowserView(v8::Local value); bool IsModal() const; v8::Local GetNativeWindowHandle(); @@ -220,6 +222,7 @@ class Window : public mate::TrackableObject, MessageCallbackMap messages_callback_map_; #endif + v8::Global browser_view_; v8::Global web_contents_; v8::Global menu_; v8::Global parent_window_; diff --git a/atom/browser/common_web_contents_delegate.cc b/atom/browser/common_web_contents_delegate.cc index f7f9e46250..a10f959dce 100644 --- a/atom/browser/common_web_contents_delegate.cc +++ b/atom/browser/common_web_contents_delegate.cc @@ -178,9 +178,14 @@ void CommonWebContentsDelegate::SetOwnerWindow(NativeWindow* owner_window) { void CommonWebContentsDelegate::SetOwnerWindow( content::WebContents* web_contents, NativeWindow* owner_window) { - owner_window_ = owner_window->GetWeakPtr(); + owner_window_ = owner_window ? owner_window->GetWeakPtr() : nullptr; NativeWindowRelay* relay = new NativeWindowRelay(owner_window_); - web_contents->SetUserData(relay->key, relay); + if (owner_window) { + web_contents->SetUserData(relay->key, relay); + } else { + web_contents->RemoveUserData(relay->key); + delete relay; + } } void CommonWebContentsDelegate::ResetManagedWebContents() { diff --git a/atom/browser/native_browser_view.cc b/atom/browser/native_browser_view.cc new file mode 100644 index 0000000000..949e5e9ec9 --- /dev/null +++ b/atom/browser/native_browser_view.cc @@ -0,0 +1,18 @@ +// Copyright (c) 2017 GitHub, Inc. +// Use of this source code is governed by the MIT license that can be +// found in the LICENSE file. + +#include "atom/browser/native_browser_view.h" + +#include "atom/browser/api/atom_api_web_contents.h" +#include "brightray/browser/inspectable_web_contents_view.h" + +namespace atom { + +NativeBrowserView::NativeBrowserView( + brightray::InspectableWebContentsView* web_contents_view) + : web_contents_view_(web_contents_view) {} + +NativeBrowserView::~NativeBrowserView() {} + +} // namespace atom diff --git a/atom/browser/native_browser_view.h b/atom/browser/native_browser_view.h new file mode 100644 index 0000000000..f9af80f65e --- /dev/null +++ b/atom/browser/native_browser_view.h @@ -0,0 +1,51 @@ +// Copyright (c) 2017 GitHub, Inc. +// Use of this source code is governed by the MIT license that can be +// found in the LICENSE file. + +#ifndef ATOM_BROWSER_NATIVE_BROWSER_VIEW_H_ +#define ATOM_BROWSER_NATIVE_BROWSER_VIEW_H_ + +#include "base/macros.h" +#include "third_party/skia/include/core/SkColor.h" + +namespace brightray { +class InspectableWebContentsView; +} + +namespace gfx { +class Rect; +} + +namespace atom { + +namespace api { +class WebContents; +} + +class NativeBrowserView { + public: + virtual ~NativeBrowserView(); + + static NativeBrowserView* Create( + brightray::InspectableWebContentsView* web_contents_view); + + brightray::InspectableWebContentsView* GetInspectableWebContentsView() { + return web_contents_view_; + } + + virtual void SetBounds(const gfx::Rect& bounds) = 0; + virtual void SetBackgroundColor(SkColor color) = 0; + + protected: + explicit NativeBrowserView( + brightray::InspectableWebContentsView* web_contents_view); + + brightray::InspectableWebContentsView* web_contents_view_; + + private: + DISALLOW_COPY_AND_ASSIGN(NativeBrowserView); +}; + +} // namespace atom + +#endif // ATOM_BROWSER_NATIVE_BROWSER_VIEW_H_ diff --git a/atom/browser/native_browser_view_mac.h b/atom/browser/native_browser_view_mac.h new file mode 100644 index 0000000000..3053a098fc --- /dev/null +++ b/atom/browser/native_browser_view_mac.h @@ -0,0 +1,29 @@ +// Copyright (c) 2017 GitHub, Inc. +// Use of this source code is governed by the MIT license that can be +// found in the LICENSE file. + +#ifndef ATOM_BROWSER_NATIVE_BROWSER_VIEW_MAC_H_ +#define ATOM_BROWSER_NATIVE_BROWSER_VIEW_MAC_H_ + +#import + +#include "atom/browser/native_browser_view.h" + +namespace atom { + +class NativeBrowserViewMac : public NativeBrowserView { + public: + explicit NativeBrowserViewMac( + brightray::InspectableWebContentsView* web_contents_view); + ~NativeBrowserViewMac() override; + + void SetBounds(const gfx::Rect& bounds) override; + void SetBackgroundColor(SkColor color) override; + + private: + DISALLOW_COPY_AND_ASSIGN(NativeBrowserViewMac); +}; + +} // namespace atom + +#endif // ATOM_BROWSER_NATIVE_BROWSER_VIEW_MAC_H_ diff --git a/atom/browser/native_browser_view_mac.mm b/atom/browser/native_browser_view_mac.mm new file mode 100644 index 0000000000..73a36cd347 --- /dev/null +++ b/atom/browser/native_browser_view_mac.mm @@ -0,0 +1,40 @@ +// Copyright (c) 2017 GitHub, Inc. +// Use of this source code is governed by the MIT license that can be +// found in the LICENSE file. + +#include "atom/browser/native_browser_view_mac.h" + +#include "brightray/browser/inspectable_web_contents_view.h" +#include "skia/ext/skia_utils_mac.h" +#include "ui/gfx/geometry/rect.h" + +namespace atom { + +NativeBrowserViewMac::NativeBrowserViewMac( + brightray::InspectableWebContentsView* web_contents_view) + : NativeBrowserView(web_contents_view) {} + +NativeBrowserViewMac::~NativeBrowserViewMac() {} + +void NativeBrowserViewMac::SetBounds(const gfx::Rect& bounds) { + auto* view = GetInspectableWebContentsView()->GetNativeView(); + auto* superview = view.superview; + const auto superview_height = superview ? superview.frame.size.height : 0; + view.frame = + NSMakeRect(bounds.x(), superview_height - bounds.y() - bounds.height(), + bounds.width(), bounds.height()); +} + +void NativeBrowserViewMac::SetBackgroundColor(SkColor color) { + auto* view = GetInspectableWebContentsView()->GetNativeView(); + view.wantsLayer = YES; + view.layer.backgroundColor = skia::CGColorCreateFromSkColor(color); +} + +// static +NativeBrowserView* NativeBrowserView::Create( + brightray::InspectableWebContentsView* web_contents_view) { + return new NativeBrowserViewMac(web_contents_view); +} + +} // namespace atom diff --git a/atom/browser/native_browser_view_views.cc b/atom/browser/native_browser_view_views.cc new file mode 100644 index 0000000000..08a8123bca --- /dev/null +++ b/atom/browser/native_browser_view_views.cc @@ -0,0 +1,36 @@ +// Copyright (c) 2017 GitHub, Inc. +// Use of this source code is governed by the MIT license that can be +// found in the LICENSE file. + +#include "atom/browser/native_browser_view_views.h" + +#include "brightray/browser/inspectable_web_contents_view.h" +#include "ui/gfx/geometry/rect.h" +#include "ui/views/background.h" +#include "ui/views/view.h" + +namespace atom { + +NativeBrowserViewViews::NativeBrowserViewViews( + brightray::InspectableWebContentsView* web_contents_view) + : NativeBrowserView(web_contents_view) {} + +NativeBrowserViewViews::~NativeBrowserViewViews() {} + +void NativeBrowserViewViews::SetBounds(const gfx::Rect& bounds) { + auto* view = GetInspectableWebContentsView()->GetView(); + view->SetBoundsRect(bounds); +} + +void NativeBrowserViewViews::SetBackgroundColor(SkColor color) { + auto* view = GetInspectableWebContentsView()->GetView(); + view->set_background(views::Background::CreateSolidBackground(color)); +} + +// static +NativeBrowserView* NativeBrowserView::Create( + brightray::InspectableWebContentsView* web_contents_view) { + return new NativeBrowserViewViews(web_contents_view); +} + +} // namespace atom diff --git a/atom/browser/native_browser_view_views.h b/atom/browser/native_browser_view_views.h new file mode 100644 index 0000000000..ecfc6989df --- /dev/null +++ b/atom/browser/native_browser_view_views.h @@ -0,0 +1,27 @@ +// Copyright (c) 2017 GitHub, Inc. +// Use of this source code is governed by the MIT license that can be +// found in the LICENSE file. + +#ifndef ATOM_BROWSER_NATIVE_BROWSER_VIEW_VIEWS_H_ +#define ATOM_BROWSER_NATIVE_BROWSER_VIEW_VIEWS_H_ + +#include "atom/browser/native_browser_view.h" + +namespace atom { + +class NativeBrowserViewViews : public NativeBrowserView { + public: + explicit NativeBrowserViewViews( + brightray::InspectableWebContentsView* web_contents_view); + ~NativeBrowserViewViews() override; + + void SetBounds(const gfx::Rect& bounds) override; + void SetBackgroundColor(SkColor color) override; + + private: + DISALLOW_COPY_AND_ASSIGN(NativeBrowserViewViews); +}; + +} // namespace atom + +#endif // ATOM_BROWSER_NATIVE_BROWSER_VIEW_VIEWS_H_ diff --git a/atom/browser/native_window.h b/atom/browser/native_window.h index 227e28c1e4..56702daef6 100644 --- a/atom/browser/native_window.h +++ b/atom/browser/native_window.h @@ -47,6 +47,8 @@ class Dictionary; namespace atom { +class NativeBrowserView; + struct DraggableRegion; class NativeWindow : public base::SupportsUserData, @@ -144,6 +146,7 @@ class NativeWindow : public base::SupportsUserData, virtual void SetFocusable(bool focusable); virtual void SetMenu(AtomMenuModel* menu); virtual void SetParentWindow(NativeWindow* parent); + virtual void SetBrowserView(NativeBrowserView* browser_view) = 0; virtual gfx::NativeWindow GetNativeWindow() = 0; virtual gfx::AcceleratedWidget GetAcceleratedWidget() = 0; diff --git a/atom/browser/native_window_mac.h b/atom/browser/native_window_mac.h index a535cdb4be..af0f157eca 100644 --- a/atom/browser/native_window_mac.h +++ b/atom/browser/native_window_mac.h @@ -87,6 +87,7 @@ class NativeWindowMac : public NativeWindow, bool IsDocumentEdited() override; void SetIgnoreMouseEvents(bool ignore) override; void SetContentProtection(bool enable) override; + void SetBrowserView(NativeBrowserView* browser_view) override; void SetParentWindow(NativeWindow* parent) override; gfx::NativeWindow GetNativeWindow() override; gfx::AcceleratedWidget GetAcceleratedWidget() override; @@ -164,6 +165,8 @@ class NativeWindowMac : public NativeWindow, // The view that will fill the whole frameless window. base::scoped_nsobject content_view_; + NativeBrowserView* browser_view_; + std::vector draggable_regions_; bool is_kiosk_; diff --git a/atom/browser/native_window_mac.mm b/atom/browser/native_window_mac.mm index c3ca24a3d4..b695f8eafa 100644 --- a/atom/browser/native_window_mac.mm +++ b/atom/browser/native_window_mac.mm @@ -7,6 +7,7 @@ #include #include +#include "atom/browser/native_browser_view_mac.h" #include "atom/browser/ui/cocoa/atom_touch_bar.h" #include "atom/browser/window_list.h" #include "atom/common/color_util.h" @@ -19,9 +20,9 @@ #include "brightray/browser/inspectable_web_contents_view.h" #include "brightray/browser/mac/event_dispatching_window.h" #include "content/public/browser/browser_accessibility_state.h" -#include "content/public/browser/web_contents.h" #include "content/public/browser/render_view_host.h" #include "content/public/browser/render_widget_host_view.h" +#include "content/public/browser/web_contents.h" #include "native_mate/dictionary.h" #include "skia/ext/skia_utils_mac.h" #include "third_party/skia/include/core/SkRegion.h" @@ -671,6 +672,7 @@ NativeWindowMac::NativeWindowMac( const mate::Dictionary& options, NativeWindow* parent) : NativeWindow(web_contents, options, parent), + browser_view_(nullptr), is_kiosk_(false), was_fullscreen_(false), zoom_to_page_width_(false), @@ -1269,6 +1271,26 @@ void NativeWindowMac::SetContentProtection(bool enable) { : NSWindowSharingReadOnly]; } +void NativeWindowMac::SetBrowserView(NativeBrowserView* browser_view) { + if (browser_view_) { + [browser_view_->GetInspectableWebContentsView()->GetNativeView() + removeFromSuperview]; + browser_view_ = nullptr; + } + + if (!browser_view) { + return; + } + + browser_view_ = browser_view; + auto* native_view = + browser_view->GetInspectableWebContentsView()->GetNativeView(); + [[window_ contentView] addSubview:native_view + positioned:NSWindowAbove + relativeTo:nil]; + native_view.hidden = NO; +} + void NativeWindowMac::SetParentWindow(NativeWindow* parent) { if (is_modal()) return; diff --git a/atom/browser/native_window_views.cc b/atom/browser/native_window_views.cc index b0722cbc4a..68e210a625 100644 --- a/atom/browser/native_window_views.cc +++ b/atom/browser/native_window_views.cc @@ -7,6 +7,7 @@ #include #include +#include "atom/browser/native_browser_view.h" #include "atom/browser/ui/views/menu_bar.h" #include "atom/browser/ui/views/menu_layout.h" #include "atom/browser/window_list.h" @@ -135,6 +136,7 @@ NativeWindowViews::NativeWindowViews( : NativeWindow(web_contents, options, parent), window_(new views::Widget), web_view_(inspectable_web_contents()->GetView()->GetView()), + browser_view_(nullptr), menu_bar_autohide_(false), menu_bar_visible_(false), menu_bar_alt_pressed_(false), @@ -881,6 +883,20 @@ void NativeWindowViews::SetMenu(AtomMenuModel* menu_model) { Layout(); } +void NativeWindowViews::SetBrowserView(NativeBrowserView* browser_view) { + if (browser_view_) { + RemoveChildView(browser_view_->GetInspectableWebContentsView()->GetView()); + browser_view_ = nullptr; + } + + if (!browser_view) { + return; + } + + browser_view_ = browser_view; + AddChildView(browser_view->GetInspectableWebContentsView()->GetView()); +} + void NativeWindowViews::SetParentWindow(NativeWindow* parent) { NativeWindow::SetParentWindow(parent); diff --git a/atom/browser/native_window_views.h b/atom/browser/native_window_views.h index a7f02fb272..cf605a0231 100644 --- a/atom/browser/native_window_views.h +++ b/atom/browser/native_window_views.h @@ -104,6 +104,7 @@ class NativeWindowViews : public NativeWindow, void SetContentProtection(bool enable) override; void SetFocusable(bool focusable) override; void SetMenu(AtomMenuModel* menu_model) override; + void SetBrowserView(NativeBrowserView* browser_view) override; void SetParentWindow(NativeWindow* parent) override; gfx::NativeWindow GetNativeWindow() override; void SetOverlayIcon(const gfx::Image& overlay, @@ -189,6 +190,8 @@ class NativeWindowViews : public NativeWindow, std::unique_ptr window_; views::View* web_view_; // Managed by inspectable_web_contents_. + NativeBrowserView* browser_view_; + std::unique_ptr menu_bar_; bool menu_bar_autohide_; bool menu_bar_visible_; diff --git a/atom/common/node_bindings.cc b/atom/common/node_bindings.cc index f4696773da..ae757b1da8 100644 --- a/atom/common/node_bindings.cc +++ b/atom/common/node_bindings.cc @@ -33,17 +33,18 @@ // Electron's builtin modules. REFERENCE_MODULE(atom_browser_app); REFERENCE_MODULE(atom_browser_auto_updater); +REFERENCE_MODULE(atom_browser_browser_view); REFERENCE_MODULE(atom_browser_content_tracing); -REFERENCE_MODULE(atom_browser_dialog); REFERENCE_MODULE(atom_browser_debugger); REFERENCE_MODULE(atom_browser_desktop_capturer); +REFERENCE_MODULE(atom_browser_dialog); REFERENCE_MODULE(atom_browser_download_item); +REFERENCE_MODULE(atom_browser_global_shortcut); REFERENCE_MODULE(atom_browser_menu); REFERENCE_MODULE(atom_browser_net); REFERENCE_MODULE(atom_browser_power_monitor); REFERENCE_MODULE(atom_browser_power_save_blocker); REFERENCE_MODULE(atom_browser_protocol); -REFERENCE_MODULE(atom_browser_global_shortcut); REFERENCE_MODULE(atom_browser_render_process_preferences); REFERENCE_MODULE(atom_browser_session); REFERENCE_MODULE(atom_browser_system_preferences); diff --git a/docs/api/browser-view.md b/docs/api/browser-view.md new file mode 100644 index 0000000000..1fa518fdd7 --- /dev/null +++ b/docs/api/browser-view.md @@ -0,0 +1,62 @@ +## Class: BrowserView + +> Create and control views. + +**Note:** The BrowserView API is currently experimental and may change or be +removed in future Electron releases. + +Process: [Main](../glossary.md#main-process) + +A `BrowserView` can be used to embed additional web content into a +`BrowserWindow`. It is like a child window, except that it is positioned +relative to its owning window. It is meant to be an alternative to the +`webview` tag. + +## Example + +```javascript +// In the main process. +const {BrowserView, BrowserWindow} = require('electron') + +let win = new BrowserWindow({width: 800, height: 600}) +win.on('closed', () => { + win = null +}) + +let view = new BrowserView() +win.addChildView(view) +view.setBounds(0, 0, 300, 300) +view.webContents.loadURL('https://electron.atom.io') +``` + +### `new BrowserView([options])` _Experimental_ + +* `options` Object (optional) + * `webPreferences` Object (optional) - See [BrowserWindow](browser-window.md). + +### Instance Properties + +Objects created with `new BrowserView` have the following properties: + +#### `view.webContents` _Experimental_ + +A [`webContents`](web-contents.md) object owned by this view. + +#### `win.id` _Experimental_ + +A `Integer` representing the unique ID of the view. + +### Instance Methods + +Objects created with `new BrowserWindow` have the following instance methods: + +#### `win.setBounds(bounds)` _Experimental_ + +* `bounds` [Rectangle](structures/rectangle.md) + +Resizes and moves the view to the supplied bounds relative to the window. + +#### `win.setBackgroundColor(color)` _Experimental_ + +* `color` String - Color in `#aarrggbb` or `#argb` form. The alpha channel is + optional. diff --git a/docs/api/browser-window.md b/docs/api/browser-window.md index ee46a3fa03..2c720fdfac 100644 --- a/docs/api/browser-window.md +++ b/docs/api/browser-window.md @@ -1289,6 +1289,13 @@ machine has a touch bar and is running on macOS 10.12.1+. **Note:** The TouchBar API is currently experimental and may change or be removed in future Electron releases. +#### `win.setBrowserView(browserView)` _Experimental_ + +* `browserView` [BrowserView](browser-view.md) + +**Note:** The BrowserView API is currently experimental and may change or be +removed in future Electron releases. + [blink-feature-string]: https://cs.chromium.org/chromium/src/third_party/WebKit/Source/platform/RuntimeEnabledFeatures.json5?l=62 [quick-look]: https://en.wikipedia.org/wiki/Quick_Look [vibrancy-docs]: https://developer.apple.com/reference/appkit/nsvisualeffectview?language=objc diff --git a/filenames.gypi b/filenames.gypi index ec9c68241c..f9fa4227ea 100644 --- a/filenames.gypi +++ b/filenames.gypi @@ -13,23 +13,24 @@ 'lib/browser/api/auto-updater/auto-updater-native.js', 'lib/browser/api/auto-updater/auto-updater-win.js', 'lib/browser/api/auto-updater/squirrel-update-win.js', + 'lib/browser/api/browser-view.js', 'lib/browser/api/browser-window.js', 'lib/browser/api/content-tracing.js', 'lib/browser/api/dialog.js', 'lib/browser/api/exports/electron.js', 'lib/browser/api/global-shortcut.js', 'lib/browser/api/ipc-main.js', - 'lib/browser/api/menu.js', - 'lib/browser/api/menu-item.js', 'lib/browser/api/menu-item-roles.js', + 'lib/browser/api/menu-item.js', + 'lib/browser/api/menu.js', 'lib/browser/api/module-list.js', 'lib/browser/api/navigation-controller.js', 'lib/browser/api/net.js', 'lib/browser/api/power-monitor.js', 'lib/browser/api/power-save-blocker.js', 'lib/browser/api/protocol.js', - 'lib/browser/api/session.js', 'lib/browser/api/screen.js', + 'lib/browser/api/session.js', 'lib/browser/api/system-preferences.js', 'lib/browser/api/touch-bar.js', 'lib/browser/api/tray.js', @@ -103,6 +104,8 @@ 'atom/browser/api/atom_api_app.h', 'atom/browser/api/atom_api_auto_updater.cc', 'atom/browser/api/atom_api_auto_updater.h', + 'atom/browser/api/atom_api_browser_view.cc', + 'atom/browser/api/atom_api_browser_view.h', 'atom/browser/api/atom_api_content_tracing.cc', 'atom/browser/api/atom_api_cookies.cc', 'atom/browser/api/atom_api_cookies.h', @@ -110,27 +113,27 @@ 'atom/browser/api/atom_api_debugger.h', 'atom/browser/api/atom_api_desktop_capturer.cc', 'atom/browser/api/atom_api_desktop_capturer.h', + 'atom/browser/api/atom_api_dialog.cc', 'atom/browser/api/atom_api_download_item.cc', 'atom/browser/api/atom_api_download_item.h', - 'atom/browser/api/atom_api_dialog.cc', 'atom/browser/api/atom_api_global_shortcut.cc', 'atom/browser/api/atom_api_global_shortcut.h', 'atom/browser/api/atom_api_menu.cc', 'atom/browser/api/atom_api_menu.h', - 'atom/browser/api/atom_api_menu_views.cc', - 'atom/browser/api/atom_api_menu_views.h', 'atom/browser/api/atom_api_menu_mac.h', 'atom/browser/api/atom_api_menu_mac.mm', + 'atom/browser/api/atom_api_menu_views.cc', + 'atom/browser/api/atom_api_menu_views.h', 'atom/browser/api/atom_api_net.cc', 'atom/browser/api/atom_api_net.h', 'atom/browser/api/atom_api_power_monitor.cc', 'atom/browser/api/atom_api_power_monitor.h', 'atom/browser/api/atom_api_power_save_blocker.cc', 'atom/browser/api/atom_api_power_save_blocker.h', - 'atom/browser/api/atom_api_render_process_preferences.cc', - 'atom/browser/api/atom_api_render_process_preferences.h', 'atom/browser/api/atom_api_protocol.cc', 'atom/browser/api/atom_api_protocol.h', + 'atom/browser/api/atom_api_render_process_preferences.cc', + 'atom/browser/api/atom_api_render_process_preferences.h', 'atom/browser/api/atom_api_screen.cc', 'atom/browser/api/atom_api_screen.h', 'atom/browser/api/atom_api_session.cc', @@ -216,6 +219,12 @@ 'atom/browser/mac/atom_application_delegate.mm', 'atom/browser/mac/dict_util.h', 'atom/browser/mac/dict_util.mm', + 'atom/browser/native_browser_view.cc', + 'atom/browser/native_browser_view.h', + 'atom/browser/native_browser_view_mac.h', + 'atom/browser/native_browser_view_mac.mm', + 'atom/browser/native_browser_view_views.h', + 'atom/browser/native_browser_view_views.cc', 'atom/browser/native_window.cc', 'atom/browser/native_window.h', 'atom/browser/native_window_views_win.cc', diff --git a/lib/browser/api/browser-view.js b/lib/browser/api/browser-view.js new file mode 100644 index 0000000000..60023fef92 --- /dev/null +++ b/lib/browser/api/browser-view.js @@ -0,0 +1,8 @@ +'use strict' + +const {EventEmitter} = require('events') +const {BrowserView} = process.atomBinding('browser_view') + +Object.setPrototypeOf(BrowserView.prototype, EventEmitter.prototype) + +module.exports = BrowserView diff --git a/lib/browser/api/module-list.js b/lib/browser/api/module-list.js index 3274f0b6d4..64b2829064 100644 --- a/lib/browser/api/module-list.js +++ b/lib/browser/api/module-list.js @@ -2,6 +2,7 @@ module.exports = [ {name: 'app', file: 'app'}, {name: 'autoUpdater', file: 'auto-updater'}, + {name: 'BrowserView', file: 'browser-view'}, {name: 'BrowserWindow', file: 'browser-window'}, {name: 'contentTracing', file: 'content-tracing'}, {name: 'dialog', file: 'dialog'}, diff --git a/spec/api-browser-view-spec.js b/spec/api-browser-view-spec.js new file mode 100644 index 0000000000..d4ab02a417 --- /dev/null +++ b/spec/api-browser-view-spec.js @@ -0,0 +1,71 @@ +'use strict' + +const assert = require('assert') +const {closeWindow} = require('./window-helpers') + +const {remote} = require('electron') +const {BrowserView, BrowserWindow} = remote + +describe('View module', function () { + var w = null + + beforeEach(function () { + w = new BrowserWindow({ + show: false, + width: 400, + height: 400, + webPreferences: { + backgroundThrottling: false + } + }) + }) + + afterEach(function () { + return closeWindow(w).then(function () { w = null }) + }) + + describe('BrowserView.setBackgroundColor()', function () { + it('does not throw for valid args', function () { + const view = new BrowserView() + view.setBackgroundColor('#000') + }) + + it('throws for invalid args', function () { + const view = new BrowserView() + assert.throws(function () { + view.setBackgroundColor(null) + }, /conversion failure/) + }) + }) + + describe('BrowserView.setBounds()', function () { + it('does not throw for valid args', function () { + const view = new BrowserView() + view.setBounds({ x: 0, y: 0, width: 1, height: 1 }) + }) + + it('throws for invalid args', function () { + const view = new BrowserView() + assert.throws(function () { + view.setBounds(null) + }, /conversion failure/) + assert.throws(function () { + view.setBounds({}) + }, /conversion failure/) + }) + }) + + describe('BrowserWindow.setBrowserView()', function () { + it('does not throw for valid args', function () { + const view = new BrowserView() + w.setBrowserView(view) + }) + + it('does not throw if called multiple times with same view', function () { + const view = new BrowserView() + w.setBrowserView(view) + w.setBrowserView(view) + w.setBrowserView(view) + }) + }) +}) From 638eae10807f41013b4efbf58f1706786ea7000c Mon Sep 17 00:00:00 2001 From: Birunthan Mohanathas Date: Wed, 12 Apr 2017 14:00:00 +0300 Subject: [PATCH 131/143] Remove MenuLayout in favor of NativeWindowViews::Layout --- atom/browser/native_window_views.cc | 43 +++++++++++-- atom/browser/native_window_views.h | 1 + atom/browser/ui/views/menu_layout.cc | 91 ---------------------------- atom/browser/ui/views/menu_layout.h | 36 ----------- filenames.gypi | 2 - 5 files changed, 40 insertions(+), 133 deletions(-) delete mode 100644 atom/browser/ui/views/menu_layout.cc delete mode 100644 atom/browser/ui/views/menu_layout.h diff --git a/atom/browser/native_window_views.cc b/atom/browser/native_window_views.cc index 68e210a625..8f5072931b 100644 --- a/atom/browser/native_window_views.cc +++ b/atom/browser/native_window_views.cc @@ -9,7 +9,6 @@ #include "atom/browser/native_browser_view.h" #include "atom/browser/ui/views/menu_bar.h" -#include "atom/browser/ui/views/menu_layout.h" #include "atom/browser/window_list.h" #include "atom/common/color_util.h" #include "atom/common/draggable_region.h" @@ -71,6 +70,20 @@ const int kMenuBarHeight = 25; #endif #if defined(OS_WIN) +gfx::Rect SubtractBorderSize(gfx::Rect bounds) { + gfx::Point borderSize = gfx::Point( + GetSystemMetrics(SM_CXSIZEFRAME) - 1, // width + GetSystemMetrics(SM_CYSIZEFRAME) - 1); // height + gfx::Point dpiAdjustedSize = + display::win::ScreenWin::ScreenToDIPPoint(borderSize); + + bounds.set_x(bounds.x() + dpiAdjustedSize.x()); + bounds.set_y(bounds.y() + dpiAdjustedSize.y()); + bounds.set_width(bounds.width() - 2 * dpiAdjustedSize.x()); + bounds.set_height(bounds.height() - 2 * dpiAdjustedSize.y()); + return bounds; +} + void FlipWindowStyle(HWND handle, bool on, DWORD flag) { DWORD style = ::GetWindowLong(handle, GWL_STYLE); if (on) @@ -276,9 +289,6 @@ NativeWindowViews::NativeWindowViews( SetWindowType(GetAcceleratedWidget(), window_type); #endif - // Add web view. - SetLayoutManager(new MenuLayout(this, kMenuBarHeight)); - AddChildView(web_view_); #if defined(OS_WIN) @@ -1264,6 +1274,31 @@ void NativeWindowViews::HandleKeyboardEvent( } } +void NativeWindowViews::Layout() { +#if defined(OS_WIN) + // Reserve border space for maximized frameless window so we won't have the + // content go outside of screen. + if (!has_frame() && IsMaximized()) { + gfx::Rect bounds = SubtractBorderSize(GetContentsBounds()); + web_view_->SetBoundsRect(bounds); + return; + } +#endif + + const auto size = GetContentsBounds().size(); + const auto menu_bar_bounds = + menu_bar_ ? gfx::Rect(0, 0, size.width(), kMenuBarHeight) : gfx::Rect(); + if (menu_bar_) { + menu_bar_->SetBoundsRect(menu_bar_bounds); + } + + if (web_view_) { + web_view_->SetBoundsRect( + gfx::Rect(0, menu_bar_bounds.height(), size.width(), + size.height() - menu_bar_bounds.height())); + } +} + gfx::Size NativeWindowViews::GetMinimumSize() { return NativeWindow::GetMinimumSize(); } diff --git a/atom/browser/native_window_views.h b/atom/browser/native_window_views.h index cf605a0231..276cd4adde 100644 --- a/atom/browser/native_window_views.h +++ b/atom/browser/native_window_views.h @@ -177,6 +177,7 @@ class NativeWindowViews : public NativeWindow, const content::NativeWebKeyboardEvent& event) override; // views::View: + void Layout() override; gfx::Size GetMinimumSize() override; gfx::Size GetMaximumSize() override; bool AcceleratorPressed(const ui::Accelerator& accelerator) override; diff --git a/atom/browser/ui/views/menu_layout.cc b/atom/browser/ui/views/menu_layout.cc deleted file mode 100644 index d70a4655a1..0000000000 --- a/atom/browser/ui/views/menu_layout.cc +++ /dev/null @@ -1,91 +0,0 @@ -// Copyright (c) 2014 GitHub, Inc. -// Use of this source code is governed by the MIT license that can be -// found in the LICENSE file. - -#include "atom/browser/ui/views/menu_layout.h" - -#if defined(OS_WIN) -#include "atom/browser/native_window_views.h" -#include "ui/display/win/screen_win.h" -#endif - -namespace atom { - -namespace { - -#if defined(OS_WIN) -gfx::Rect SubtractBorderSize(gfx::Rect bounds) { - gfx::Point borderSize = gfx::Point( - GetSystemMetrics(SM_CXSIZEFRAME) - 1, // width - GetSystemMetrics(SM_CYSIZEFRAME) - 1); // height - gfx::Point dpiAdjustedSize = - display::win::ScreenWin::ScreenToDIPPoint(borderSize); - - bounds.set_x(bounds.x() + dpiAdjustedSize.x()); - bounds.set_y(bounds.y() + dpiAdjustedSize.y()); - bounds.set_width(bounds.width() - 2 * dpiAdjustedSize.x()); - bounds.set_height(bounds.height() - 2 * dpiAdjustedSize.y()); - return bounds; -} -#endif - -} // namespace - -MenuLayout::MenuLayout(NativeWindowViews* window, int menu_height) - : window_(window), - menu_height_(menu_height) { -} - -MenuLayout::~MenuLayout() { -} - -void MenuLayout::Layout(views::View* host) { -#if defined(OS_WIN) - // Reserve border space for maximized frameless window so we won't have the - // content go outside of screen. - if (!window_->has_frame() && window_->IsMaximized()) { - gfx::Rect bounds = SubtractBorderSize(host->GetContentsBounds()); - host->child_at(0)->SetBoundsRect(bounds); - return; - } -#endif - - if (!HasMenu(host)) { - views::FillLayout::Layout(host); - return; - } - - gfx::Size size = host->GetContentsBounds().size(); - gfx::Rect menu_Bar_bounds = gfx::Rect(0, 0, size.width(), menu_height_); - gfx::Rect web_view_bounds = gfx::Rect( - 0, menu_height_, size.width(), size.height() - menu_height_); - - views::View* web_view = host->child_at(0); - views::View* menu_bar = host->child_at(1); - web_view->SetBoundsRect(web_view_bounds); - menu_bar->SetBoundsRect(menu_Bar_bounds); -} - -gfx::Size MenuLayout::GetPreferredSize(const views::View* host) const { - gfx::Size size = views::FillLayout::GetPreferredSize(host); - if (!HasMenu(host)) - return size; - - size.set_height(size.height() + menu_height_); - return size; -} - -int MenuLayout::GetPreferredHeightForWidth( - const views::View* host, int width) const { - int height = views::FillLayout::GetPreferredHeightForWidth(host, width); - if (!HasMenu(host)) - return height; - - return height + menu_height_; -} - -bool MenuLayout::HasMenu(const views::View* host) const { - return host->child_count() == 2; -} - -} // namespace atom diff --git a/atom/browser/ui/views/menu_layout.h b/atom/browser/ui/views/menu_layout.h deleted file mode 100644 index 0a8464a1d4..0000000000 --- a/atom/browser/ui/views/menu_layout.h +++ /dev/null @@ -1,36 +0,0 @@ -// Copyright (c) 2014 GitHub, Inc. -// Use of this source code is governed by the MIT license that can be -// found in the LICENSE file. - -#ifndef ATOM_BROWSER_UI_VIEWS_MENU_LAYOUT_H_ -#define ATOM_BROWSER_UI_VIEWS_MENU_LAYOUT_H_ - -#include "ui/views/layout/fill_layout.h" - -namespace atom { - -class NativeWindowViews; - -class MenuLayout : public views::FillLayout { - public: - MenuLayout(NativeWindowViews* window, int menu_height); - virtual ~MenuLayout(); - - // views::LayoutManager: - void Layout(views::View* host) override; - gfx::Size GetPreferredSize(const views::View* host) const override; - int GetPreferredHeightForWidth( - const views::View* host, int width) const override; - - private: - bool HasMenu(const views::View* host) const; - - NativeWindowViews* window_; - int menu_height_; - - DISALLOW_COPY_AND_ASSIGN(MenuLayout); -}; - -} // namespace atom - -#endif // ATOM_BROWSER_UI_VIEWS_MENU_LAYOUT_H_ diff --git a/filenames.gypi b/filenames.gypi index f9fa4227ea..8f14b29883 100644 --- a/filenames.gypi +++ b/filenames.gypi @@ -322,8 +322,6 @@ 'atom/browser/ui/views/menu_bar.h', 'atom/browser/ui/views/menu_delegate.cc', 'atom/browser/ui/views/menu_delegate.h', - 'atom/browser/ui/views/menu_layout.cc', - 'atom/browser/ui/views/menu_layout.h', 'atom/browser/ui/views/menu_model_adapter.cc', 'atom/browser/ui/views/menu_model_adapter.h', 'atom/browser/ui/views/native_frame_view.cc', From 06fcf2c19df127078320656dcb2a0a4500f61b8a Mon Sep 17 00:00:00 2001 From: Birunthan Mohanathas Date: Wed, 12 Apr 2017 14:40:31 +0300 Subject: [PATCH 132/143] Add support for BrowserView autoresizing --- atom/browser/api/atom_api_browser_view.cc | 34 +++++++++++++++++++++++ atom/browser/api/atom_api_browser_view.h | 2 ++ atom/browser/native_browser_view.h | 6 ++++ atom/browser/native_browser_view_mac.h | 1 + atom/browser/native_browser_view_mac.mm | 22 ++++++++++++++- atom/browser/native_browser_view_views.h | 6 ++++ atom/browser/native_window_views.cc | 31 +++++++++++++++++++-- docs/api/browser-view.md | 8 ++++++ spec/api-browser-view-spec.js | 15 ++++++++++ 9 files changed, 121 insertions(+), 4 deletions(-) diff --git a/atom/browser/api/atom_api_browser_view.cc b/atom/browser/api/atom_api_browser_view.cc index 67533e645d..dc17fce9e9 100644 --- a/atom/browser/api/atom_api_browser_view.cc +++ b/atom/browser/api/atom_api_browser_view.cc @@ -16,6 +16,35 @@ #include "native_mate/dictionary.h" #include "ui/gfx/geometry/rect.h" +namespace mate { + +template <> +struct Converter { + static bool FromV8(v8::Isolate* isolate, + v8::Local val, + atom::AutoResizeFlags* auto_resize_flags) { + mate::Dictionary params; + if (!ConvertFromV8(isolate, val, ¶ms)) { + return false; + } + + uint8_t flags = 0; + bool width = false; + if (params.Get("width", &width) && width) { + flags |= atom::kAutoResizeWidth; + } + bool height = false; + if (params.Get("height", &height) && height) { + flags |= atom::kAutoResizeHeight; + } + + *auto_resize_flags = static_cast(flags); + return true; + } +}; + +} // namespace mate + namespace atom { namespace api { @@ -73,6 +102,10 @@ int32_t BrowserView::ID() const { return weak_map_id(); } +void BrowserView::SetAutoResize(AutoResizeFlags flags) { + view_->SetAutoResizeFlags(flags); +} + void BrowserView::SetBounds(const gfx::Rect& bounds) { view_->SetBounds(bounds); } @@ -95,6 +128,7 @@ void BrowserView::BuildPrototype(v8::Isolate* isolate, prototype->SetClassName(mate::StringToV8(isolate, "BrowserView")); mate::ObjectTemplateBuilder(isolate, prototype->PrototypeTemplate()) .MakeDestroyable() + .SetMethod("setAutoResize", &BrowserView::SetAutoResize) .SetMethod("setBounds", &BrowserView::SetBounds) .SetMethod("setBackgroundColor", &BrowserView::SetBackgroundColor) .SetProperty("webContents", &BrowserView::WebContents) diff --git a/atom/browser/api/atom_api_browser_view.h b/atom/browser/api/atom_api_browser_view.h index 875d842898..7531cfcc4a 100644 --- a/atom/browser/api/atom_api_browser_view.h +++ b/atom/browser/api/atom_api_browser_view.h @@ -9,6 +9,7 @@ #include #include "atom/browser/api/trackable_object.h" +#include "atom/browser/native_browser_view.h" #include "native_mate/handle.h" namespace gfx { @@ -50,6 +51,7 @@ class BrowserView : public mate::TrackableObject { v8::Local wrapper, const mate::Dictionary& options); + void SetAutoResize(AutoResizeFlags flags); void SetBounds(const gfx::Rect& bounds); void SetBackgroundColor(const std::string& color_name); diff --git a/atom/browser/native_browser_view.h b/atom/browser/native_browser_view.h index f9af80f65e..4216cc1e34 100644 --- a/atom/browser/native_browser_view.h +++ b/atom/browser/native_browser_view.h @@ -22,6 +22,11 @@ namespace api { class WebContents; } +enum AutoResizeFlags { + kAutoResizeWidth = 0x1, + kAutoResizeHeight = 0x2, +}; + class NativeBrowserView { public: virtual ~NativeBrowserView(); @@ -33,6 +38,7 @@ class NativeBrowserView { return web_contents_view_; } + virtual void SetAutoResizeFlags(uint8_t flags) = 0; virtual void SetBounds(const gfx::Rect& bounds) = 0; virtual void SetBackgroundColor(SkColor color) = 0; diff --git a/atom/browser/native_browser_view_mac.h b/atom/browser/native_browser_view_mac.h index 3053a098fc..4e7aa429ce 100644 --- a/atom/browser/native_browser_view_mac.h +++ b/atom/browser/native_browser_view_mac.h @@ -17,6 +17,7 @@ class NativeBrowserViewMac : public NativeBrowserView { brightray::InspectableWebContentsView* web_contents_view); ~NativeBrowserViewMac() override; + void SetAutoResizeFlags(uint8_t flags) override; void SetBounds(const gfx::Rect& bounds) override; void SetBackgroundColor(SkColor color) override; diff --git a/atom/browser/native_browser_view_mac.mm b/atom/browser/native_browser_view_mac.mm index 73a36cd347..2ce2adc1f4 100644 --- a/atom/browser/native_browser_view_mac.mm +++ b/atom/browser/native_browser_view_mac.mm @@ -8,14 +8,34 @@ #include "skia/ext/skia_utils_mac.h" #include "ui/gfx/geometry/rect.h" +// Match view::Views behavior where the view sticks to the top-left origin. +const NSAutoresizingMaskOptions kDefaultAutoResizingMask = + NSViewMaxXMargin | NSViewMinYMargin; + namespace atom { NativeBrowserViewMac::NativeBrowserViewMac( brightray::InspectableWebContentsView* web_contents_view) - : NativeBrowserView(web_contents_view) {} + : NativeBrowserView(web_contents_view) { + auto* view = GetInspectableWebContentsView()->GetNativeView(); + view.autoresizingMask = kDefaultAutoResizingMask; +} NativeBrowserViewMac::~NativeBrowserViewMac() {} +void NativeBrowserViewMac::SetAutoResizeFlags(uint8_t flags) { + NSAutoresizingMaskOptions autoresizing_mask = kDefaultAutoResizingMask; + if (flags & kAutoResizeWidth) { + autoresizing_mask |= NSViewWidthSizable; + } + if (flags & kAutoResizeHeight) { + autoresizing_mask |= NSViewHeightSizable; + } + + auto* view = GetInspectableWebContentsView()->GetNativeView(); + view.autoresizingMask = autoresizing_mask; +} + void NativeBrowserViewMac::SetBounds(const gfx::Rect& bounds) { auto* view = GetInspectableWebContentsView()->GetNativeView(); auto* superview = view.superview; diff --git a/atom/browser/native_browser_view_views.h b/atom/browser/native_browser_view_views.h index ecfc6989df..5dcda13447 100644 --- a/atom/browser/native_browser_view_views.h +++ b/atom/browser/native_browser_view_views.h @@ -15,10 +15,16 @@ class NativeBrowserViewViews : public NativeBrowserView { brightray::InspectableWebContentsView* web_contents_view); ~NativeBrowserViewViews() override; + uint8_t GetAutoResizeFlags() { return auto_resize_flags_; } + void SetAutoResizeFlags(uint8_t flags) override { + auto_resize_flags_ = flags; + } void SetBounds(const gfx::Rect& bounds) override; void SetBackgroundColor(SkColor color) override; private: + uint8_t auto_resize_flags_; + DISALLOW_COPY_AND_ASSIGN(NativeBrowserViewViews); }; diff --git a/atom/browser/native_window_views.cc b/atom/browser/native_window_views.cc index 8f5072931b..615c848daa 100644 --- a/atom/browser/native_window_views.cc +++ b/atom/browser/native_window_views.cc @@ -7,7 +7,7 @@ #include #include -#include "atom/browser/native_browser_view.h" +#include "atom/browser/native_browser_view_views.h" #include "atom/browser/ui/views/menu_bar.h" #include "atom/browser/window_list.h" #include "atom/common/color_util.h" @@ -895,7 +895,8 @@ void NativeWindowViews::SetMenu(AtomMenuModel* menu_model) { void NativeWindowViews::SetBrowserView(NativeBrowserView* browser_view) { if (browser_view_) { - RemoveChildView(browser_view_->GetInspectableWebContentsView()->GetView()); + web_view_->RemoveChildView( + browser_view_->GetInspectableWebContentsView()->GetView()); browser_view_ = nullptr; } @@ -903,8 +904,11 @@ void NativeWindowViews::SetBrowserView(NativeBrowserView* browser_view) { return; } + // Add as child of the main web view to avoid (0, 0) origin from overlapping + // with menu bar. browser_view_ = browser_view; - AddChildView(browser_view->GetInspectableWebContentsView()->GetView()); + web_view_->AddChildView( + browser_view->GetInspectableWebContentsView()->GetView()); } void NativeWindowViews::SetParentWindow(NativeWindow* parent) { @@ -1292,11 +1296,32 @@ void NativeWindowViews::Layout() { menu_bar_->SetBoundsRect(menu_bar_bounds); } + const auto old_web_view_size = web_view_ ? web_view_->size() : gfx::Size(); if (web_view_) { web_view_->SetBoundsRect( gfx::Rect(0, menu_bar_bounds.height(), size.width(), size.height() - menu_bar_bounds.height())); } + const auto new_web_view_size = web_view_ ? web_view_->size() : gfx::Size(); + + if (browser_view_) { + const auto flags = static_cast(browser_view_) + ->GetAutoResizeFlags(); + int width_delta = 0; + int height_delta = 0; + if (flags & kAutoResizeWidth) { + width_delta = new_web_view_size.width() - old_web_view_size.width(); + } + if (flags & kAutoResizeHeight) { + height_delta = new_web_view_size.height() - old_web_view_size.height(); + } + + auto* view = browser_view_->GetInspectableWebContentsView()->GetView(); + auto new_view_size = view->size(); + new_view_size.set_width(new_view_size.width() + width_delta); + new_view_size.set_height(new_view_size.height() + height_delta); + view->SetSize(new_view_size); + } } gfx::Size NativeWindowViews::GetMinimumSize() { diff --git a/docs/api/browser-view.md b/docs/api/browser-view.md index 1fa518fdd7..c6d8fb5904 100644 --- a/docs/api/browser-view.md +++ b/docs/api/browser-view.md @@ -50,6 +50,14 @@ A `Integer` representing the unique ID of the view. Objects created with `new BrowserWindow` have the following instance methods: +#### `win.setAutoResize(options)` _Experimental_ + +* `options` Object + * `width`: If `true`, the view's width will grow and shrink together with + the window. `false` by default. + * `height`: If `true`, the view's height will grow and shrink together with + the window. `false` by default. + #### `win.setBounds(bounds)` _Experimental_ * `bounds` [Rectangle](structures/rectangle.md) diff --git a/spec/api-browser-view-spec.js b/spec/api-browser-view-spec.js index d4ab02a417..fc138b0b6f 100644 --- a/spec/api-browser-view-spec.js +++ b/spec/api-browser-view-spec.js @@ -38,6 +38,21 @@ describe('View module', function () { }) }) + describe('BrowserView.setAutoResize()', function () { + it('does not throw for valid args', function () { + const view = new BrowserView() + view.setAutoResize({}) + view.setAutoResize({ width: true, height: false }) + }) + + it('throws for invalid args', function () { + const view = new BrowserView() + assert.throws(function () { + view.setAutoResize(null) + }, /conversion failure/) + }) + }) + describe('BrowserView.setBounds()', function () { it('does not throw for valid args', function () { const view = new BrowserView() From ccdeb4746ec25555b11709b19742e1f1b7fe7cb8 Mon Sep 17 00:00:00 2001 From: Birunthan Mohanathas Date: Thu, 13 Apr 2017 00:52:07 +0300 Subject: [PATCH 133/143] Destroy BrowserViews after each test --- spec/api-browser-view-spec.js | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/spec/api-browser-view-spec.js b/spec/api-browser-view-spec.js index fc138b0b6f..3ccb9502c2 100644 --- a/spec/api-browser-view-spec.js +++ b/spec/api-browser-view-spec.js @@ -8,6 +8,7 @@ const {BrowserView, BrowserWindow} = remote describe('View module', function () { var w = null + var view = null beforeEach(function () { w = new BrowserWindow({ @@ -21,17 +22,22 @@ describe('View module', function () { }) afterEach(function () { + if (view) { + view.destroy() + view = null + } + return closeWindow(w).then(function () { w = null }) }) describe('BrowserView.setBackgroundColor()', function () { it('does not throw for valid args', function () { - const view = new BrowserView() + view = new BrowserView() view.setBackgroundColor('#000') }) it('throws for invalid args', function () { - const view = new BrowserView() + view = new BrowserView() assert.throws(function () { view.setBackgroundColor(null) }, /conversion failure/) @@ -40,13 +46,13 @@ describe('View module', function () { describe('BrowserView.setAutoResize()', function () { it('does not throw for valid args', function () { - const view = new BrowserView() + view = new BrowserView() view.setAutoResize({}) view.setAutoResize({ width: true, height: false }) }) it('throws for invalid args', function () { - const view = new BrowserView() + view = new BrowserView() assert.throws(function () { view.setAutoResize(null) }, /conversion failure/) @@ -55,12 +61,12 @@ describe('View module', function () { describe('BrowserView.setBounds()', function () { it('does not throw for valid args', function () { - const view = new BrowserView() + view = new BrowserView() view.setBounds({ x: 0, y: 0, width: 1, height: 1 }) }) it('throws for invalid args', function () { - const view = new BrowserView() + view = new BrowserView() assert.throws(function () { view.setBounds(null) }, /conversion failure/) @@ -72,12 +78,12 @@ describe('View module', function () { describe('BrowserWindow.setBrowserView()', function () { it('does not throw for valid args', function () { - const view = new BrowserView() + view = new BrowserView() w.setBrowserView(view) }) it('does not throw if called multiple times with same view', function () { - const view = new BrowserView() + view = new BrowserView() w.setBrowserView(view) w.setBrowserView(view) w.setBrowserView(view) From 000aedf2e796788f5375b5a26752e7c645b1f2b9 Mon Sep 17 00:00:00 2001 From: Birunthan Mohanathas Date: Thu, 13 Apr 2017 01:05:19 +0300 Subject: [PATCH 134/143] Avoid insecure nodeIntegration in example --- docs/api/browser-view.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/docs/api/browser-view.md b/docs/api/browser-view.md index c6d8fb5904..3b7e6f9b9b 100644 --- a/docs/api/browser-view.md +++ b/docs/api/browser-view.md @@ -23,7 +23,11 @@ win.on('closed', () => { win = null }) -let view = new BrowserView() +let view = new BrowserView({ + webPreferences: { + nodeIntegration: false + } +}) win.addChildView(view) view.setBounds(0, 0, 300, 300) view.webContents.loadURL('https://electron.atom.io') From fe8726d77556616d407644fabe94c82e6ac82710 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Tue, 11 Apr 2017 13:08:15 -0700 Subject: [PATCH 135/143] Use Chrome default client inset handling --- atom/browser/native_window_views.cc | 24 ------------------- atom/browser/ui/views/win_frame_view.cc | 1 - .../win/atom_desktop_window_tree_host_win.cc | 8 ------- .../win/atom_desktop_window_tree_host_win.h | 1 - electron.gyp | 7 +++++- 5 files changed, 6 insertions(+), 35 deletions(-) diff --git a/atom/browser/native_window_views.cc b/atom/browser/native_window_views.cc index 615c848daa..690a47ecec 100644 --- a/atom/browser/native_window_views.cc +++ b/atom/browser/native_window_views.cc @@ -70,20 +70,6 @@ const int kMenuBarHeight = 25; #endif #if defined(OS_WIN) -gfx::Rect SubtractBorderSize(gfx::Rect bounds) { - gfx::Point borderSize = gfx::Point( - GetSystemMetrics(SM_CXSIZEFRAME) - 1, // width - GetSystemMetrics(SM_CYSIZEFRAME) - 1); // height - gfx::Point dpiAdjustedSize = - display::win::ScreenWin::ScreenToDIPPoint(borderSize); - - bounds.set_x(bounds.x() + dpiAdjustedSize.x()); - bounds.set_y(bounds.y() + dpiAdjustedSize.y()); - bounds.set_width(bounds.width() - 2 * dpiAdjustedSize.x()); - bounds.set_height(bounds.height() - 2 * dpiAdjustedSize.y()); - return bounds; -} - void FlipWindowStyle(HWND handle, bool on, DWORD flag) { DWORD style = ::GetWindowLong(handle, GWL_STYLE); if (on) @@ -1279,16 +1265,6 @@ void NativeWindowViews::HandleKeyboardEvent( } void NativeWindowViews::Layout() { -#if defined(OS_WIN) - // Reserve border space for maximized frameless window so we won't have the - // content go outside of screen. - if (!has_frame() && IsMaximized()) { - gfx::Rect bounds = SubtractBorderSize(GetContentsBounds()); - web_view_->SetBoundsRect(bounds); - return; - } -#endif - const auto size = GetContentsBounds().size(); const auto menu_bar_bounds = menu_bar_ ? gfx::Rect(0, 0, size.width(), kMenuBarHeight) : gfx::Rect(); diff --git a/atom/browser/ui/views/win_frame_view.cc b/atom/browser/ui/views/win_frame_view.cc index fca7cb2334..3908a2774e 100644 --- a/atom/browser/ui/views/win_frame_view.cc +++ b/atom/browser/ui/views/win_frame_view.cc @@ -23,7 +23,6 @@ WinFrameView::WinFrameView() { WinFrameView::~WinFrameView() { } - gfx::Rect WinFrameView::GetWindowBoundsForClientBounds( const gfx::Rect& client_bounds) const { return views::GetWindowBoundsForClientBounds( diff --git a/atom/browser/ui/win/atom_desktop_window_tree_host_win.cc b/atom/browser/ui/win/atom_desktop_window_tree_host_win.cc index 9cc2ef9e8d..84a6d9aa3e 100644 --- a/atom/browser/ui/win/atom_desktop_window_tree_host_win.cc +++ b/atom/browser/ui/win/atom_desktop_window_tree_host_win.cc @@ -25,12 +25,4 @@ bool AtomDesktopWindowTreeHostWin::PreHandleMSG( return delegate_->PreHandleMSG(message, w_param, l_param, result); } -/** Override the client area inset - * Returning true forces a border of 0 for frameless windows - */ -bool AtomDesktopWindowTreeHostWin::GetClientAreaInsets( - gfx::Insets* insets) const { - return !HasFrame(); -} - } // namespace atom diff --git a/atom/browser/ui/win/atom_desktop_window_tree_host_win.h b/atom/browser/ui/win/atom_desktop_window_tree_host_win.h index 2df70547c5..47e4cb6aed 100644 --- a/atom/browser/ui/win/atom_desktop_window_tree_host_win.h +++ b/atom/browser/ui/win/atom_desktop_window_tree_host_win.h @@ -27,7 +27,6 @@ class AtomDesktopWindowTreeHostWin : public views::DesktopWindowTreeHostWin { protected: bool PreHandleMSG( UINT message, WPARAM w_param, LPARAM l_param, LRESULT* result) override; - bool GetClientAreaInsets(gfx::Insets* insets) const override; private: MessageHandlerDelegate* delegate_; // weak ref diff --git a/electron.gyp b/electron.gyp index 7775907380..6a54c38999 100644 --- a/electron.gyp +++ b/electron.gyp @@ -126,7 +126,12 @@ 'VCManifestTool': { 'EmbedManifest': 'true', 'AdditionalManifestFiles': 'atom/browser/resources/win/atom.manifest', - } + }, + 'VCLinkerTool': { + 'AdditionalOptions': [ + "/SUBSYSTEM:WINDOWS,5.02" + ], + }, }, 'copies': [ { From 1a75bf8fb9c6e2298202c7eed3d1fc9154982d4f Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Tue, 11 Apr 2017 14:35:09 -0700 Subject: [PATCH 136/143] Add comment to subsystem linker option --- electron.gyp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/electron.gyp b/electron.gyp index 6a54c38999..c3f632c9eb 100644 --- a/electron.gyp +++ b/electron.gyp @@ -129,6 +129,8 @@ }, 'VCLinkerTool': { 'AdditionalOptions': [ + # Chrome builds with this minimum environment which changes the + # values returned from APIs like GetSystemMetrics(SM_CXSIZEFRAME) "/SUBSYSTEM:WINDOWS,5.02" ], }, From 4ca4eb01d412185921ea5fa09636642410047a6f Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Tue, 11 Apr 2017 14:44:22 -0700 Subject: [PATCH 137/143] Use MinimumRequiredVersion instead of argument --- electron.gyp | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/electron.gyp b/electron.gyp index c3f632c9eb..6070b84d38 100644 --- a/electron.gyp +++ b/electron.gyp @@ -128,11 +128,9 @@ 'AdditionalManifestFiles': 'atom/browser/resources/win/atom.manifest', }, 'VCLinkerTool': { - 'AdditionalOptions': [ - # Chrome builds with this minimum environment which changes the - # values returned from APIs like GetSystemMetrics(SM_CXSIZEFRAME) - "/SUBSYSTEM:WINDOWS,5.02" - ], + # Chrome builds with this minimum environment which changes the + # values returned from APIs like GetSystemMetrics(SM_CXSIZEFRAME) + 'MinimumRequiredVersion': '5.02' }, }, 'copies': [ From 108f246d89dc928095b8ea6447ce42d6ad73a23a Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Tue, 11 Apr 2017 14:54:34 -0700 Subject: [PATCH 138/143] Add SubSystem setting --- electron.gyp | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/electron.gyp b/electron.gyp index 6070b84d38..8c3718b1cd 100644 --- a/electron.gyp +++ b/electron.gyp @@ -128,9 +128,14 @@ 'AdditionalManifestFiles': 'atom/browser/resources/win/atom.manifest', }, 'VCLinkerTool': { - # Chrome builds with this minimum environment which changes the - # values returned from APIs like GetSystemMetrics(SM_CXSIZEFRAME) - 'MinimumRequiredVersion': '5.02' + # Chrome builds with this minimum environment which makes e.g. + # GetSystemMetrics(SM_CXSIZEFRAME) return Windows XP/2003 + # compatible metrics. See: https://crbug.com/361720 + # + # The following two settings translate to a linker flag + # of /SUBSYSTEM:WINDOWS,5.02 + 'MinimumRequiredVersion': '5.02', + 'SubSystem': '2', }, }, 'copies': [ From e7d71000eea11c6ec77f657e1ff5c2a2b813d126 Mon Sep 17 00:00:00 2001 From: Birunthan Mohanathas Date: Thu, 13 Apr 2017 21:36:48 +0300 Subject: [PATCH 139/143] Fix missing warning icon with dialog.showMessageBox() on macOS Fixes #9183. --- atom/browser/ui/message_box_mac.mm | 10 +++++++--- docs/api/dialog.md | 5 +++-- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/atom/browser/ui/message_box_mac.mm b/atom/browser/ui/message_box_mac.mm index 3550e47cf8..f752f2945c 100644 --- a/atom/browser/ui/message_box_mac.mm +++ b/atom/browser/ui/message_box_mac.mm @@ -71,10 +71,14 @@ NSAlert* CreateNSAlert(NativeWindow* parent_window, switch (type) { case MESSAGE_BOX_TYPE_INFORMATION: - [alert setAlertStyle:NSInformationalAlertStyle]; + alert.alertStyle = NSInformationalAlertStyle; break; case MESSAGE_BOX_TYPE_WARNING: - [alert setAlertStyle:NSWarningAlertStyle]; + case MESSAGE_BOX_TYPE_ERROR: + // NSWarningAlertStyle shows the app icon while NSCriticalAlertStyle + // shows a warning icon with an app icon badge. Since there is no + // error variant, lets just use NSCriticalAlertStyle. + alert.alertStyle = NSCriticalAlertStyle; break; default: break; @@ -192,7 +196,7 @@ void ShowErrorBox(const base::string16& title, const base::string16& content) { NSAlert* alert = [[NSAlert alloc] init]; [alert setMessageText:base::SysUTF16ToNSString(title)]; [alert setInformativeText:base::SysUTF16ToNSString(content)]; - [alert setAlertStyle:NSWarningAlertStyle]; + [alert setAlertStyle:NSCriticalAlertStyle]; [alert runModal]; [alert release]; } diff --git a/docs/api/dialog.md b/docs/api/dialog.md index 51760c2d59..615e3b2c6f 100644 --- a/docs/api/dialog.md +++ b/docs/api/dialog.md @@ -115,8 +115,9 @@ will be passed via `callback(filename)` * `browserWindow` BrowserWindow (optional) * `options` Object * `type` String (optional) - Can be `"none"`, `"info"`, `"error"`, `"question"` or - `"warning"`. On Windows, "question" displays the same icon as "info", unless - you set an icon using the "icon" option. + `"warning"`. On Windows, `"question"` displays the same icon as `"info"`, unless + you set an icon using the `"icon"` option. On macOS, both `"warning"` and + `"error"` display the same warning icon. * `buttons` String[] (optional) - Array of texts for buttons. On Windows, an empty array will result in one button labeled "OK". * `defaultId` Integer (optional) - Index of the button in the buttons array which will From dc914fdb288754cafd9b4fc176222d62179027d8 Mon Sep 17 00:00:00 2001 From: Birunthan Mohanathas Date: Sun, 16 Apr 2017 18:00:51 +0300 Subject: [PATCH 140/143] Update Brightray for electron/brightray#289 This fixes #9197. --- vendor/brightray | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vendor/brightray b/vendor/brightray index 28d713bb2a..909c492654 160000 --- a/vendor/brightray +++ b/vendor/brightray @@ -1 +1 @@ -Subproject commit 28d713bb2a82ba690a21d62522ecd7bad09caba8 +Subproject commit 909c49265493bd095c27cefd999567be2107899a From dcf6c52f51bcf3635bd97238a851f73cda1d7b40 Mon Sep 17 00:00:00 2001 From: Birunthan Mohanathas Date: Mon, 17 Apr 2017 12:29:42 +0300 Subject: [PATCH 141/143] Actually hide menubar area when menu is autohidden This was a regression introduced in 638eae10. --- atom/browser/native_window_views.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/atom/browser/native_window_views.cc b/atom/browser/native_window_views.cc index 690a47ecec..7e6f23947c 100644 --- a/atom/browser/native_window_views.cc +++ b/atom/browser/native_window_views.cc @@ -1267,7 +1267,8 @@ void NativeWindowViews::HandleKeyboardEvent( void NativeWindowViews::Layout() { const auto size = GetContentsBounds().size(); const auto menu_bar_bounds = - menu_bar_ ? gfx::Rect(0, 0, size.width(), kMenuBarHeight) : gfx::Rect(); + menu_bar_visible_ ? gfx::Rect(0, 0, size.width(), kMenuBarHeight) + : gfx::Rect(); if (menu_bar_) { menu_bar_->SetBoundsRect(menu_bar_bounds); } From 4a7125d9f831b47993e2e7b16e64f55cf78f7f78 Mon Sep 17 00:00:00 2001 From: Birunthan Mohanathas Date: Mon, 17 Apr 2017 23:21:43 +0300 Subject: [PATCH 142/143] Update libcc for electron/libchromiumcontent#285 This fixes non-client area DPI scaling on recent Windows 10 versions. See discussion in #8786. --- script/lib/config.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/script/lib/config.py b/script/lib/config.py index d033d8a41c..5818571089 100644 --- a/script/lib/config.py +++ b/script/lib/config.py @@ -9,7 +9,7 @@ import sys BASE_URL = os.getenv('LIBCHROMIUMCONTENT_MIRROR') or \ 'https://s3.amazonaws.com/github-janky-artifacts/libchromiumcontent' LIBCHROMIUMCONTENT_COMMIT = os.getenv('LIBCHROMIUMCONTENT_COMMIT') or \ - '8d551064d2b3d11f89ce8d5c4610f34e0408bad8' + '4a0e32606e52c12c50c2e3a0973d015d8cdff494' PLATFORM = { 'cygwin': 'win32', From 3bcf5e0e9f0862d62fdd9e937225e9137300d98e Mon Sep 17 00:00:00 2001 From: Birunthan Mohanathas Date: Tue, 18 Apr 2017 11:51:38 +0300 Subject: [PATCH 143/143] Fix OverrideSiteInstanceForNavigation() signature --- atom/browser/atom_browser_client.cc | 1 + atom/browser/atom_browser_client.h | 1 + 2 files changed, 2 insertions(+) diff --git a/atom/browser/atom_browser_client.cc b/atom/browser/atom_browser_client.cc index d0bbf4ad53..9b096ae8ae 100644 --- a/atom/browser/atom_browser_client.cc +++ b/atom/browser/atom_browser_client.cc @@ -172,6 +172,7 @@ std::string AtomBrowserClient::GetApplicationLocale() { } void AtomBrowserClient::OverrideSiteInstanceForNavigation( + content::RenderFrameHost* render_frame_host, content::BrowserContext* browser_context, content::SiteInstance* current_instance, const GURL& url, diff --git a/atom/browser/atom_browser_client.h b/atom/browser/atom_browser_client.h index c2a7d5edd0..70573d6eee 100644 --- a/atom/browser/atom_browser_client.h +++ b/atom/browser/atom_browser_client.h @@ -54,6 +54,7 @@ class AtomBrowserClient : public brightray::BrowserClient, content::WebPreferences* prefs) override; std::string GetApplicationLocale() override; void OverrideSiteInstanceForNavigation( + content::RenderFrameHost* render_frame_host, content::BrowserContext* browser_context, content::SiteInstance* current_instance, const GURL& dest_url,