Merge remote-tracking branch 'refs/remotes/atom/master'
This commit is contained in:
		
				commit
				
					
						6058c7e14d
					
				
			
		
					 25 changed files with 317 additions and 271 deletions
				
			
		| 
						 | 
				
			
			@ -17,6 +17,7 @@
 | 
			
		|||
#include "atom/common/native_mate_converters/callback.h"
 | 
			
		||||
#include "atom/common/native_mate_converters/net_converter.h"
 | 
			
		||||
#include "atom/common/native_mate_converters/file_path_converter.h"
 | 
			
		||||
#include "atom/common/native_mate_converters/gurl_converter.h"
 | 
			
		||||
#include "atom/common/node_includes.h"
 | 
			
		||||
#include "atom/common/options_switches.h"
 | 
			
		||||
#include "base/command_line.h"
 | 
			
		||||
| 
						 | 
				
			
			@ -27,6 +28,7 @@
 | 
			
		|||
#include "chrome/common/chrome_paths.h"
 | 
			
		||||
#include "content/public/browser/client_certificate_delegate.h"
 | 
			
		||||
#include "content/public/browser/gpu_data_manager.h"
 | 
			
		||||
#include "content/public/browser/render_frame_host.h"
 | 
			
		||||
#include "content/public/common/content_switches.h"
 | 
			
		||||
#include "native_mate/dictionary.h"
 | 
			
		||||
#include "native_mate/object_template_builder.h"
 | 
			
		||||
| 
						 | 
				
			
			@ -154,11 +156,14 @@ void PassLoginInformation(scoped_refptr<LoginHandler> login_handler,
 | 
			
		|||
}  // namespace
 | 
			
		||||
 | 
			
		||||
App::App() {
 | 
			
		||||
  static_cast<AtomBrowserClient*>(AtomBrowserClient::Get())->set_delegate(this);
 | 
			
		||||
  Browser::Get()->AddObserver(this);
 | 
			
		||||
  content::GpuDataManager::GetInstance()->AddObserver(this);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
App::~App() {
 | 
			
		||||
  static_cast<AtomBrowserClient*>(AtomBrowserClient::Get())->set_delegate(
 | 
			
		||||
      nullptr);
 | 
			
		||||
  Browser::Get()->RemoveObserver(this);
 | 
			
		||||
  content::GpuDataManager::GetInstance()->RemoveObserver(this);
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -212,15 +217,59 @@ void App::OnFinishLaunching() {
 | 
			
		|||
  Emit("ready");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void App::OnSelectCertificate(
 | 
			
		||||
void App::OnLogin(LoginHandler* login_handler) {
 | 
			
		||||
  v8::Locker locker(isolate());
 | 
			
		||||
  v8::HandleScope handle_scope(isolate());
 | 
			
		||||
  bool prevent_default = Emit(
 | 
			
		||||
      "login",
 | 
			
		||||
      WebContents::CreateFrom(isolate(), login_handler->GetWebContents()),
 | 
			
		||||
      login_handler->request(),
 | 
			
		||||
      login_handler->auth_info(),
 | 
			
		||||
      base::Bind(&PassLoginInformation, make_scoped_refptr(login_handler)));
 | 
			
		||||
 | 
			
		||||
  // Default behavior is to always cancel the auth.
 | 
			
		||||
  if (!prevent_default)
 | 
			
		||||
    login_handler->CancelAuth();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void App::AllowCertificateError(
 | 
			
		||||
    int pid,
 | 
			
		||||
    int fid,
 | 
			
		||||
    int cert_error,
 | 
			
		||||
    const net::SSLInfo& ssl_info,
 | 
			
		||||
    const GURL& request_url,
 | 
			
		||||
    content::ResourceType resource_type,
 | 
			
		||||
    bool overridable,
 | 
			
		||||
    bool strict_enforcement,
 | 
			
		||||
    bool expired_previous_decision,
 | 
			
		||||
    const base::Callback<void(bool)>& callback,
 | 
			
		||||
    content::CertificateRequestResultType* request) {
 | 
			
		||||
  auto rfh = content::RenderFrameHost::FromID(pid, fid);
 | 
			
		||||
  auto web_contents = content::WebContents::FromRenderFrameHost(rfh);
 | 
			
		||||
 | 
			
		||||
  v8::Locker locker(isolate());
 | 
			
		||||
  v8::HandleScope handle_scope(isolate());
 | 
			
		||||
  bool prevent_default = Emit("certificate-error",
 | 
			
		||||
                              WebContents::CreateFrom(isolate(), web_contents),
 | 
			
		||||
                              request_url,
 | 
			
		||||
                              net::ErrorToString(cert_error),
 | 
			
		||||
                              ssl_info.cert,
 | 
			
		||||
                              callback);
 | 
			
		||||
 | 
			
		||||
  // Deny the certificate by default.
 | 
			
		||||
  if (!prevent_default)
 | 
			
		||||
    *request = content::CERTIFICATE_REQUEST_RESULT_TYPE_DENY;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void App::SelectClientCertificate(
 | 
			
		||||
    content::WebContents* web_contents,
 | 
			
		||||
    net::SSLCertRequestInfo* cert_request_info,
 | 
			
		||||
    scoped_ptr<content::ClientCertificateDelegate> delegate) {
 | 
			
		||||
  std::shared_ptr<content::ClientCertificateDelegate>
 | 
			
		||||
      shared_delegate(delegate.release());
 | 
			
		||||
  bool prevent_default =
 | 
			
		||||
      Emit("select-certificate",
 | 
			
		||||
           api::WebContents::CreateFrom(isolate(), web_contents),
 | 
			
		||||
      Emit("select-client-certificate",
 | 
			
		||||
           WebContents::CreateFrom(isolate(), web_contents),
 | 
			
		||||
           cert_request_info->host_and_port.ToString(),
 | 
			
		||||
           cert_request_info->client_certs,
 | 
			
		||||
           base::Bind(&OnClientCertificateSelected,
 | 
			
		||||
| 
						 | 
				
			
			@ -233,31 +282,6 @@ void App::OnSelectCertificate(
 | 
			
		|||
        cert_request_info->client_certs[0].get());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void App::OnLogin(LoginHandler* login_handler) {
 | 
			
		||||
  // Convert the args explicitly since they will be passed for twice.
 | 
			
		||||
  v8::Locker locker(isolate());
 | 
			
		||||
  v8::HandleScope handle_scope(isolate());
 | 
			
		||||
  auto web_contents =
 | 
			
		||||
      WebContents::CreateFrom(isolate(), login_handler->GetWebContents());
 | 
			
		||||
  auto request = mate::ConvertToV8(isolate(), login_handler->request());
 | 
			
		||||
  auto auth_info = mate::ConvertToV8(isolate(), login_handler->auth_info());
 | 
			
		||||
  auto callback = mate::ConvertToV8(
 | 
			
		||||
      isolate(),
 | 
			
		||||
      base::Bind(&PassLoginInformation, make_scoped_refptr(login_handler)));
 | 
			
		||||
 | 
			
		||||
  bool prevent_default =
 | 
			
		||||
      Emit("login", web_contents, request, auth_info, callback);
 | 
			
		||||
 | 
			
		||||
  // Also pass it to WebContents.
 | 
			
		||||
  if (!prevent_default)
 | 
			
		||||
    prevent_default =
 | 
			
		||||
        web_contents->Emit("login", request, auth_info, callback);
 | 
			
		||||
 | 
			
		||||
  // Default behavior is to always cancel the auth.
 | 
			
		||||
  if (!prevent_default)
 | 
			
		||||
    login_handler->CancelAuth();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void App::OnGpuProcessCrashed(base::TerminationStatus exit_code) {
 | 
			
		||||
  Emit("gpu-process-crashed");
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -8,6 +8,7 @@
 | 
			
		|||
#include <string>
 | 
			
		||||
 | 
			
		||||
#include "atom/browser/api/event_emitter.h"
 | 
			
		||||
#include "atom/browser/atom_browser_client.h"
 | 
			
		||||
#include "atom/browser/browser_observer.h"
 | 
			
		||||
#include "atom/common/native_mate_converters/callback.h"
 | 
			
		||||
#include "chrome/browser/process_singleton.h"
 | 
			
		||||
| 
						 | 
				
			
			@ -26,7 +27,8 @@ namespace atom {
 | 
			
		|||
 | 
			
		||||
namespace api {
 | 
			
		||||
 | 
			
		||||
class App : public mate::EventEmitter,
 | 
			
		||||
class App : public AtomBrowserClient::Delegate,
 | 
			
		||||
            public mate::EventEmitter,
 | 
			
		||||
            public BrowserObserver,
 | 
			
		||||
            public content::GpuDataManagerObserver {
 | 
			
		||||
 public:
 | 
			
		||||
| 
						 | 
				
			
			@ -46,11 +48,25 @@ class App : public mate::EventEmitter,
 | 
			
		|||
  void OnActivate(bool has_visible_windows) override;
 | 
			
		||||
  void OnWillFinishLaunching() override;
 | 
			
		||||
  void OnFinishLaunching() override;
 | 
			
		||||
  void OnSelectCertificate(
 | 
			
		||||
  void OnLogin(LoginHandler* login_handler) override;
 | 
			
		||||
 | 
			
		||||
  // content::ContentBrowserClient:
 | 
			
		||||
  void AllowCertificateError(
 | 
			
		||||
      int render_process_id,
 | 
			
		||||
      int render_frame_id,
 | 
			
		||||
      int cert_error,
 | 
			
		||||
      const net::SSLInfo& ssl_info,
 | 
			
		||||
      const GURL& request_url,
 | 
			
		||||
      content::ResourceType resource_type,
 | 
			
		||||
      bool overridable,
 | 
			
		||||
      bool strict_enforcement,
 | 
			
		||||
      bool expired_previous_decision,
 | 
			
		||||
      const base::Callback<void(bool)>& callback,
 | 
			
		||||
      content::CertificateRequestResultType* request) override;
 | 
			
		||||
  void SelectClientCertificate(
 | 
			
		||||
      content::WebContents* web_contents,
 | 
			
		||||
      net::SSLCertRequestInfo* cert_request_info,
 | 
			
		||||
      scoped_ptr<content::ClientCertificateDelegate> delegate) override;
 | 
			
		||||
  void OnLogin(LoginHandler* login_handler) override;
 | 
			
		||||
 | 
			
		||||
  // content::GpuDataManagerObserver:
 | 
			
		||||
  void OnGpuProcessCrashed(base::TerminationStatus exit_code) override;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -13,6 +13,7 @@
 | 
			
		|||
#include "atom/browser/api/save_page_handler.h"
 | 
			
		||||
#include "atom/browser/atom_browser_context.h"
 | 
			
		||||
#include "atom/browser/atom_browser_main_parts.h"
 | 
			
		||||
#include "atom/browser/net/atom_cert_verifier.h"
 | 
			
		||||
#include "atom/common/native_mate_converters/callback.h"
 | 
			
		||||
#include "atom/common/native_mate_converters/gurl_converter.h"
 | 
			
		||||
#include "atom/common/native_mate_converters/file_path_converter.h"
 | 
			
		||||
| 
						 | 
				
			
			@ -238,18 +239,11 @@ void SetProxyInIO(net::URLRequestContextGetter* getter,
 | 
			
		|||
  RunCallbackInUI(callback);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void PassVerificationResult(
 | 
			
		||||
    scoped_refptr<AtomCertVerifier::CertVerifyRequest> request,
 | 
			
		||||
    bool success) {
 | 
			
		||||
  request->ContinueWithResult(success ? net::OK : net::ERR_FAILED);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
}  // namespace
 | 
			
		||||
 | 
			
		||||
Session::Session(AtomBrowserContext* browser_context)
 | 
			
		||||
    : browser_context_(browser_context) {
 | 
			
		||||
  AttachAsUserData(browser_context);
 | 
			
		||||
  browser_context->cert_verifier()->SetDelegate(this);
 | 
			
		||||
 | 
			
		||||
  // Observe DownloadManger to get download notifications.
 | 
			
		||||
  content::BrowserContext::GetDownloadManager(browser_context)->
 | 
			
		||||
| 
						 | 
				
			
			@ -262,19 +256,6 @@ Session::~Session() {
 | 
			
		|||
  Destroy();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void Session::RequestCertVerification(
 | 
			
		||||
    const scoped_refptr<AtomCertVerifier::CertVerifyRequest>& request) {
 | 
			
		||||
  bool prevent_default = Emit(
 | 
			
		||||
      "untrusted-certificate",
 | 
			
		||||
      request->args().hostname,
 | 
			
		||||
      request->args().cert,
 | 
			
		||||
      base::Bind(&PassVerificationResult, request));
 | 
			
		||||
 | 
			
		||||
  if (!prevent_default)
 | 
			
		||||
    // Tell the request to use the result of default verifier.
 | 
			
		||||
    request->ContinueWithResult(net::ERR_IO_PENDING);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void Session::OnDownloadCreated(content::DownloadManager* manager,
 | 
			
		||||
                                content::DownloadItem* item) {
 | 
			
		||||
  auto web_contents = item->GetWebContents();
 | 
			
		||||
| 
						 | 
				
			
			@ -295,7 +276,6 @@ bool Session::IsDestroyed() const {
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
void Session::Destroy() {
 | 
			
		||||
  browser_context_->cert_verifier()->SetDelegate(nullptr);
 | 
			
		||||
  browser_context_ = nullptr;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -377,6 +357,17 @@ void Session::DisableNetworkEmulation() {
 | 
			
		|||
                 base::Passed(&conditions)));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void Session::SetCertVerifyProc(v8::Local<v8::Value> val,
 | 
			
		||||
                                mate::Arguments* args) {
 | 
			
		||||
  AtomCertVerifier::VerifyProc proc;
 | 
			
		||||
  if (!(val->IsNull() || mate::ConvertFromV8(args->isolate(), val, &proc))) {
 | 
			
		||||
    args->ThrowError("Must pass null or function");
 | 
			
		||||
    return;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  browser_context_->cert_verifier()->SetVerifyProc(proc);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
v8::Local<v8::Value> Session::Cookies(v8::Isolate* isolate) {
 | 
			
		||||
  if (cookies_.IsEmpty()) {
 | 
			
		||||
    auto handle = atom::api::Cookies::Create(isolate, browser_context());
 | 
			
		||||
| 
						 | 
				
			
			@ -395,6 +386,7 @@ mate::ObjectTemplateBuilder Session::GetObjectTemplateBuilder(
 | 
			
		|||
      .SetMethod("setDownloadPath", &Session::SetDownloadPath)
 | 
			
		||||
      .SetMethod("enableNetworkEmulation", &Session::EnableNetworkEmulation)
 | 
			
		||||
      .SetMethod("disableNetworkEmulation", &Session::DisableNetworkEmulation)
 | 
			
		||||
      .SetMethod("setCertificateVerifyProc", &Session::SetCertVerifyProc)
 | 
			
		||||
      .SetProperty("cookies", &Session::Cookies);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -8,7 +8,6 @@
 | 
			
		|||
#include <string>
 | 
			
		||||
 | 
			
		||||
#include "atom/browser/api/trackable_object.h"
 | 
			
		||||
#include "atom/browser/net/atom_cert_verifier.h"
 | 
			
		||||
#include "content/public/browser/download_manager.h"
 | 
			
		||||
#include "native_mate/handle.h"
 | 
			
		||||
#include "net/base/completion_callback.h"
 | 
			
		||||
| 
						 | 
				
			
			@ -35,7 +34,6 @@ class AtomBrowserContext;
 | 
			
		|||
namespace api {
 | 
			
		||||
 | 
			
		||||
class Session: public mate::TrackableObject<Session>,
 | 
			
		||||
               public AtomCertVerifier::Delegate,
 | 
			
		||||
               public content::DownloadManager::Observer {
 | 
			
		||||
 public:
 | 
			
		||||
  using ResolveProxyCallback = base::Callback<void(std::string)>;
 | 
			
		||||
| 
						 | 
				
			
			@ -54,10 +52,6 @@ class Session: public mate::TrackableObject<Session>,
 | 
			
		|||
  explicit Session(AtomBrowserContext* browser_context);
 | 
			
		||||
  ~Session();
 | 
			
		||||
 | 
			
		||||
  // AtomCertVerifier::Delegate:
 | 
			
		||||
  void RequestCertVerification(
 | 
			
		||||
      const scoped_refptr<AtomCertVerifier::CertVerifyRequest>&) override;
 | 
			
		||||
 | 
			
		||||
  // content::DownloadManager::Observer:
 | 
			
		||||
  void OnDownloadCreated(content::DownloadManager* manager,
 | 
			
		||||
                         content::DownloadItem* item) override;
 | 
			
		||||
| 
						 | 
				
			
			@ -78,6 +72,7 @@ class Session: public mate::TrackableObject<Session>,
 | 
			
		|||
  void SetDownloadPath(const base::FilePath& path);
 | 
			
		||||
  void EnableNetworkEmulation(const mate::Dictionary& options);
 | 
			
		||||
  void DisableNetworkEmulation();
 | 
			
		||||
  void SetCertVerifyProc(v8::Local<v8::Value> proc, mate::Arguments* args);
 | 
			
		||||
  v8::Local<v8::Value> Cookies(v8::Isolate* isolate);
 | 
			
		||||
 | 
			
		||||
  // Cached object for cookies API.
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -38,6 +38,12 @@ app.getAppPath = ->
 | 
			
		|||
# Helpers.
 | 
			
		||||
app.resolveProxy = (url, callback) -> @defaultSession.resolveProxy url, callback
 | 
			
		||||
 | 
			
		||||
# Routes the events to webContents.
 | 
			
		||||
for name in ['login', 'certificate-error', 'select-client-certificate']
 | 
			
		||||
  do (name) ->
 | 
			
		||||
    app.on name, (event, webContents, args...) ->
 | 
			
		||||
      webContents.emit name, event, args...
 | 
			
		||||
 | 
			
		||||
# Deprecated.
 | 
			
		||||
{deprecate} = electron
 | 
			
		||||
app.getHomeDir = deprecate 'app.getHomeDir', 'app.getPath', ->
 | 
			
		||||
| 
						 | 
				
			
			@ -52,6 +58,7 @@ deprecate.event app, 'finish-launching', 'ready', ->
 | 
			
		|||
    @emit 'finish-launching'
 | 
			
		||||
deprecate.event app, 'activate-with-no-open-windows', 'activate', (event, hasVisibleWindows) ->
 | 
			
		||||
  @emit 'activate-with-no-open-windows' if not hasVisibleWindows
 | 
			
		||||
deprecate.event app, 'select-certificate', 'select-client-certificate'
 | 
			
		||||
 | 
			
		||||
# Wrappers for native classes.
 | 
			
		||||
wrapSession = (session) ->
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -14,7 +14,6 @@
 | 
			
		|||
#include "atom/browser/atom_quota_permission_context.h"
 | 
			
		||||
#include "atom/browser/atom_resource_dispatcher_host_delegate.h"
 | 
			
		||||
#include "atom/browser/atom_speech_recognition_manager_delegate.h"
 | 
			
		||||
#include "atom/browser/browser.h"
 | 
			
		||||
#include "atom/browser/native_window.h"
 | 
			
		||||
#include "atom/browser/web_contents_preferences.h"
 | 
			
		||||
#include "atom/browser/window_list.h"
 | 
			
		||||
| 
						 | 
				
			
			@ -88,7 +87,7 @@ void AtomBrowserClient::SetCustomSchemes(
 | 
			
		|||
  g_custom_schemes = JoinString(schemes, ',');
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
AtomBrowserClient::AtomBrowserClient() {
 | 
			
		||||
AtomBrowserClient::AtomBrowserClient() : delegate_(nullptr) {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
AtomBrowserClient::~AtomBrowserClient() {
 | 
			
		||||
| 
						 | 
				
			
			@ -208,6 +207,26 @@ content::QuotaPermissionContext*
 | 
			
		|||
  return new AtomQuotaPermissionContext;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void AtomBrowserClient::AllowCertificateError(
 | 
			
		||||
    int render_process_id,
 | 
			
		||||
    int render_frame_id,
 | 
			
		||||
    int cert_error,
 | 
			
		||||
    const net::SSLInfo& ssl_info,
 | 
			
		||||
    const GURL& request_url,
 | 
			
		||||
    content::ResourceType resource_type,
 | 
			
		||||
    bool overridable,
 | 
			
		||||
    bool strict_enforcement,
 | 
			
		||||
    bool expired_previous_decision,
 | 
			
		||||
    const base::Callback<void(bool)>& callback,
 | 
			
		||||
    content::CertificateRequestResultType* request) {
 | 
			
		||||
  if (delegate_) {
 | 
			
		||||
    delegate_->AllowCertificateError(
 | 
			
		||||
        render_process_id, render_frame_id, cert_error, ssl_info, request_url,
 | 
			
		||||
        resource_type, overridable, strict_enforcement,
 | 
			
		||||
        expired_previous_decision, callback, request);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void AtomBrowserClient::SelectClientCertificate(
 | 
			
		||||
    content::WebContents* web_contents,
 | 
			
		||||
    net::SSLCertRequestInfo* cert_request_info,
 | 
			
		||||
| 
						 | 
				
			
			@ -222,10 +241,10 @@ void AtomBrowserClient::SelectClientCertificate(
 | 
			
		|||
    return;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  if (!cert_request_info->client_certs.empty())
 | 
			
		||||
    Browser::Get()->ClientCertificateSelector(web_contents,
 | 
			
		||||
                                              cert_request_info,
 | 
			
		||||
                                              delegate.Pass());
 | 
			
		||||
  if (!cert_request_info->client_certs.empty() && delegate_) {
 | 
			
		||||
    delegate_->SelectClientCertificate(
 | 
			
		||||
        web_contents, cert_request_info, delegate.Pass());
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void AtomBrowserClient::ResourceDispatcherHostCreated() {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -31,6 +31,9 @@ class AtomBrowserClient : public brightray::BrowserClient,
 | 
			
		|||
  AtomBrowserClient();
 | 
			
		||||
  virtual ~AtomBrowserClient();
 | 
			
		||||
 | 
			
		||||
  using Delegate = content::ContentBrowserClient;
 | 
			
		||||
  void set_delegate(Delegate* delegate) { delegate_ = delegate; }
 | 
			
		||||
 | 
			
		||||
  // Don't force renderer process to restart for once.
 | 
			
		||||
  static void SuppressRendererProcessRestartForOnce();
 | 
			
		||||
  // Custom schemes to be registered to standard.
 | 
			
		||||
| 
						 | 
				
			
			@ -54,6 +57,18 @@ class AtomBrowserClient : public brightray::BrowserClient,
 | 
			
		|||
                                      int child_process_id) override;
 | 
			
		||||
  void DidCreatePpapiPlugin(content::BrowserPpapiHost* browser_host) override;
 | 
			
		||||
  content::QuotaPermissionContext* CreateQuotaPermissionContext() override;
 | 
			
		||||
  void AllowCertificateError(
 | 
			
		||||
      int render_process_id,
 | 
			
		||||
      int render_frame_id,
 | 
			
		||||
      int cert_error,
 | 
			
		||||
      const net::SSLInfo& ssl_info,
 | 
			
		||||
      const GURL& request_url,
 | 
			
		||||
      content::ResourceType resource_type,
 | 
			
		||||
      bool overridable,
 | 
			
		||||
      bool strict_enforcement,
 | 
			
		||||
      bool expired_previous_decision,
 | 
			
		||||
      const base::Callback<void(bool)>& callback,
 | 
			
		||||
      content::CertificateRequestResultType* request) override;
 | 
			
		||||
  void SelectClientCertificate(
 | 
			
		||||
      content::WebContents* web_contents,
 | 
			
		||||
      net::SSLCertRequestInfo* cert_request_info,
 | 
			
		||||
| 
						 | 
				
			
			@ -74,6 +89,8 @@ class AtomBrowserClient : public brightray::BrowserClient,
 | 
			
		|||
  scoped_ptr<AtomResourceDispatcherHostDelegate>
 | 
			
		||||
      resource_dispatcher_host_delegate_;
 | 
			
		||||
 | 
			
		||||
  Delegate* delegate_;
 | 
			
		||||
 | 
			
		||||
  DISALLOW_COPY_AND_ASSIGN(AtomBrowserClient);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -10,8 +10,6 @@
 | 
			
		|||
#include "atom/browser/native_window.h"
 | 
			
		||||
#include "atom/browser/window_list.h"
 | 
			
		||||
#include "base/message_loop/message_loop.h"
 | 
			
		||||
#include "content/public/browser/client_certificate_delegate.h"
 | 
			
		||||
#include "net/ssl/ssl_cert_request_info.h"
 | 
			
		||||
 | 
			
		||||
namespace atom {
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -141,17 +139,6 @@ void Browser::DidFinishLaunching() {
 | 
			
		|||
  FOR_EACH_OBSERVER(BrowserObserver, observers_, OnFinishLaunching());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void Browser::ClientCertificateSelector(
 | 
			
		||||
    content::WebContents* web_contents,
 | 
			
		||||
    net::SSLCertRequestInfo* cert_request_info,
 | 
			
		||||
    scoped_ptr<content::ClientCertificateDelegate> delegate) {
 | 
			
		||||
  FOR_EACH_OBSERVER(BrowserObserver,
 | 
			
		||||
                    observers_,
 | 
			
		||||
                    OnSelectCertificate(web_contents,
 | 
			
		||||
                                        cert_request_info,
 | 
			
		||||
                                        delegate.Pass()));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void Browser::RequestLogin(LoginHandler* login_handler) {
 | 
			
		||||
  FOR_EACH_OBSERVER(BrowserObserver, observers_, OnLogin(login_handler));
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -126,12 +126,6 @@ class Browser : public WindowListObserver {
 | 
			
		|||
  void WillFinishLaunching();
 | 
			
		||||
  void DidFinishLaunching();
 | 
			
		||||
 | 
			
		||||
  // Called when client certificate is required.
 | 
			
		||||
  void ClientCertificateSelector(
 | 
			
		||||
      content::WebContents* web_contents,
 | 
			
		||||
      net::SSLCertRequestInfo* cert_request_info,
 | 
			
		||||
      scoped_ptr<content::ClientCertificateDelegate> delegate);
 | 
			
		||||
 | 
			
		||||
  // Request basic auth login.
 | 
			
		||||
  void RequestLogin(LoginHandler* login_handler);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -7,17 +7,6 @@
 | 
			
		|||
 | 
			
		||||
#include <string>
 | 
			
		||||
 | 
			
		||||
#include "base/memory/scoped_ptr.h"
 | 
			
		||||
#include "content/public/browser/client_certificate_delegate.h"
 | 
			
		||||
 | 
			
		||||
namespace content {
 | 
			
		||||
class WebContents;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
namespace net {
 | 
			
		||||
class SSLCertRequestInfo;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
namespace atom {
 | 
			
		||||
 | 
			
		||||
class LoginHandler;
 | 
			
		||||
| 
						 | 
				
			
			@ -53,12 +42,6 @@ class BrowserObserver {
 | 
			
		|||
  virtual void OnWillFinishLaunching() {}
 | 
			
		||||
  virtual void OnFinishLaunching() {}
 | 
			
		||||
 | 
			
		||||
  // The browser requires client certificate.
 | 
			
		||||
  virtual void OnSelectCertificate(
 | 
			
		||||
      content::WebContents* web_contents,
 | 
			
		||||
      net::SSLCertRequestInfo* cert_request_info,
 | 
			
		||||
      scoped_ptr<content::ClientCertificateDelegate> delegate) {}
 | 
			
		||||
 | 
			
		||||
  // The browser requests HTTP login.
 | 
			
		||||
  virtual void OnLogin(LoginHandler* login_handler) {}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -106,13 +106,25 @@ unwrapArgs = (sender, args) ->
 | 
			
		|||
# Call a function and send reply asynchronously if it's a an asynchronous
 | 
			
		||||
# style function and the caller didn't pass a callback.
 | 
			
		||||
callFunction = (event, func, caller, args) ->
 | 
			
		||||
  if v8Util.getHiddenValue(func, 'asynchronous') and typeof args[args.length - 1] isnt 'function'
 | 
			
		||||
    args.push (ret) ->
 | 
			
		||||
  funcMarkedAsync = v8Util.getHiddenValue(func, 'asynchronous')
 | 
			
		||||
  funcPassedCallback = args[args.length - 1] is 'function'
 | 
			
		||||
 | 
			
		||||
  try
 | 
			
		||||
    if funcMarkedAsync and not funcPassedCallback
 | 
			
		||||
      args.push (ret) ->
 | 
			
		||||
        event.returnValue = valueToMeta event.sender, ret, true
 | 
			
		||||
      func.apply caller, args
 | 
			
		||||
    else
 | 
			
		||||
      ret = func.apply caller, args
 | 
			
		||||
      event.returnValue = valueToMeta event.sender, ret, true
 | 
			
		||||
    func.apply caller, args
 | 
			
		||||
  else
 | 
			
		||||
    ret = func.apply caller, args
 | 
			
		||||
    event.returnValue = valueToMeta event.sender, ret, true
 | 
			
		||||
  catch e
 | 
			
		||||
    # Catch functions thrown further down in function invocation and wrap
 | 
			
		||||
    # them with the function name so it's easier to trace things like
 | 
			
		||||
    # `Error processing argument -1.`
 | 
			
		||||
    funcName = func.name ? "anonymous"
 | 
			
		||||
    throw new Error("Could not call remote function `#{funcName}`.
 | 
			
		||||
                     Check that the function signature is correct.
 | 
			
		||||
                     Underlying error: #{e.message}")
 | 
			
		||||
 | 
			
		||||
# Send by BrowserWindow when its render view is deleted.
 | 
			
		||||
process.on 'ATOM_BROWSER_RELEASE_RENDER_VIEW', (id) ->
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -15,30 +15,31 @@ using content::BrowserThread;
 | 
			
		|||
 | 
			
		||||
namespace atom {
 | 
			
		||||
 | 
			
		||||
AtomCertVerifier::CertVerifyRequest::~CertVerifyRequest() {
 | 
			
		||||
}
 | 
			
		||||
namespace {
 | 
			
		||||
 | 
			
		||||
void AtomCertVerifier::CertVerifyRequest::ContinueWithResult(int result) {
 | 
			
		||||
  DCHECK_CURRENTLY_ON(BrowserThread::UI);
 | 
			
		||||
 | 
			
		||||
  if (handled_)
 | 
			
		||||
    return;
 | 
			
		||||
 | 
			
		||||
  handled_ = true;
 | 
			
		||||
void OnResult(
 | 
			
		||||
    net::CertVerifyResult* verify_result,
 | 
			
		||||
    const net::CompletionCallback& callback,
 | 
			
		||||
    bool result) {
 | 
			
		||||
  BrowserThread::PostTask(
 | 
			
		||||
      BrowserThread::IO, FROM_HERE,
 | 
			
		||||
      base::Bind(args_.callback,
 | 
			
		||||
                 result == net::ERR_IO_PENDING ? result_ : result));
 | 
			
		||||
      base::Bind(callback, result ? net::OK : net::ERR_FAILED));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
}  // namespace
 | 
			
		||||
 | 
			
		||||
AtomCertVerifier::AtomCertVerifier()
 | 
			
		||||
    : delegate_(nullptr) {
 | 
			
		||||
  default_cert_verifier_.reset(net::CertVerifier::CreateDefault());
 | 
			
		||||
    : default_cert_verifier_(net::CertVerifier::CreateDefault()) {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
AtomCertVerifier::~AtomCertVerifier() {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void AtomCertVerifier::SetVerifyProc(const VerifyProc& proc) {
 | 
			
		||||
  base::AutoLock auto_lock(lock_);
 | 
			
		||||
  verify_proc_ = proc;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int AtomCertVerifier::Verify(
 | 
			
		||||
    net::X509Certificate* cert,
 | 
			
		||||
    const std::string& hostname,
 | 
			
		||||
| 
						 | 
				
			
			@ -51,45 +52,26 @@ int AtomCertVerifier::Verify(
 | 
			
		|||
    const net::BoundNetLog& net_log) {
 | 
			
		||||
  DCHECK_CURRENTLY_ON(BrowserThread::IO);
 | 
			
		||||
 | 
			
		||||
  if (callback.is_null() || !verify_result || hostname.empty() || !delegate_)
 | 
			
		||||
    return net::ERR_INVALID_ARGUMENT;
 | 
			
		||||
 | 
			
		||||
  VerifyArgs args = { cert, hostname, callback };
 | 
			
		||||
  int result = default_cert_verifier_->Verify(
 | 
			
		||||
      cert, hostname, ocsp_response, flags, crl_set, verify_result,
 | 
			
		||||
      base::Bind(&AtomCertVerifier::OnDefaultVerificationResult,
 | 
			
		||||
                 base::Unretained(this), args),
 | 
			
		||||
      out_req, net_log);
 | 
			
		||||
  if (result != net::OK && result != net::ERR_IO_PENDING) {
 | 
			
		||||
    // The default verifier fails immediately.
 | 
			
		||||
    VerifyCertificateFromDelegate(args, result);
 | 
			
		||||
    return net::ERR_IO_PENDING;
 | 
			
		||||
  VerifyProc proc;
 | 
			
		||||
  {
 | 
			
		||||
    base::AutoLock auto_lock(lock_);
 | 
			
		||||
    proc = verify_proc_;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  return result;
 | 
			
		||||
  if (proc.is_null())
 | 
			
		||||
    return default_cert_verifier_->Verify(
 | 
			
		||||
        cert, hostname, ocsp_response, flags, crl_set, verify_result, callback,
 | 
			
		||||
        out_req, net_log);
 | 
			
		||||
 | 
			
		||||
  BrowserThread::PostTask(
 | 
			
		||||
      BrowserThread::UI, FROM_HERE,
 | 
			
		||||
      base::Bind(proc, hostname, make_scoped_refptr(cert),
 | 
			
		||||
                 base::Bind(OnResult, verify_result, callback)));
 | 
			
		||||
  return net::ERR_IO_PENDING;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool AtomCertVerifier::SupportsOCSPStapling() {
 | 
			
		||||
  return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void AtomCertVerifier::VerifyCertificateFromDelegate(
 | 
			
		||||
    const VerifyArgs& args, int result) {
 | 
			
		||||
  CertVerifyRequest* request = new CertVerifyRequest(this, result, args);
 | 
			
		||||
  BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
 | 
			
		||||
                          base::Bind(&Delegate::RequestCertVerification,
 | 
			
		||||
                                     base::Unretained(delegate_),
 | 
			
		||||
                                     make_scoped_refptr(request)));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void AtomCertVerifier::OnDefaultVerificationResult(
 | 
			
		||||
    const VerifyArgs& args, int result) {
 | 
			
		||||
  if (result == net::OK) {
 | 
			
		||||
    args.callback.Run(result);
 | 
			
		||||
    return;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  VerifyCertificateFromDelegate(args, result);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
}  // namespace atom
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -8,61 +8,22 @@
 | 
			
		|||
#include <string>
 | 
			
		||||
 | 
			
		||||
#include "base/memory/ref_counted.h"
 | 
			
		||||
#include "base/synchronization/lock.h"
 | 
			
		||||
#include "net/cert/cert_verifier.h"
 | 
			
		||||
 | 
			
		||||
namespace atom {
 | 
			
		||||
 | 
			
		||||
class AtomCertVerifier : public net::CertVerifier {
 | 
			
		||||
 public:
 | 
			
		||||
  struct VerifyArgs {
 | 
			
		||||
    scoped_refptr<net::X509Certificate> cert;
 | 
			
		||||
    const std::string& hostname;
 | 
			
		||||
    net::CompletionCallback callback;
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  class CertVerifyRequest
 | 
			
		||||
      : public base::RefCountedThreadSafe<CertVerifyRequest> {
 | 
			
		||||
   public:
 | 
			
		||||
    CertVerifyRequest(AtomCertVerifier* cert_verifier,
 | 
			
		||||
                      int result,
 | 
			
		||||
                      const VerifyArgs& args)
 | 
			
		||||
        : cert_verifier_(cert_verifier),
 | 
			
		||||
          result_(result),
 | 
			
		||||
          args_(args),
 | 
			
		||||
          handled_(false) {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void ContinueWithResult(int result);
 | 
			
		||||
 | 
			
		||||
    const VerifyArgs& args() const { return args_; }
 | 
			
		||||
 | 
			
		||||
   private:
 | 
			
		||||
    friend class base::RefCountedThreadSafe<CertVerifyRequest>;
 | 
			
		||||
    ~CertVerifyRequest();
 | 
			
		||||
 | 
			
		||||
    AtomCertVerifier* cert_verifier_;
 | 
			
		||||
    int result_;
 | 
			
		||||
    VerifyArgs args_;
 | 
			
		||||
    bool handled_;
 | 
			
		||||
 | 
			
		||||
    DISALLOW_COPY_AND_ASSIGN(CertVerifyRequest);
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  class Delegate {
 | 
			
		||||
   public:
 | 
			
		||||
    virtual ~Delegate() {}
 | 
			
		||||
 | 
			
		||||
    // Called on UI thread.
 | 
			
		||||
    virtual void RequestCertVerification(
 | 
			
		||||
        const scoped_refptr<CertVerifyRequest>& request) {}
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  AtomCertVerifier();
 | 
			
		||||
  virtual ~AtomCertVerifier();
 | 
			
		||||
 | 
			
		||||
  void SetDelegate(Delegate* delegate) {
 | 
			
		||||
    delegate_ = delegate;
 | 
			
		||||
  }
 | 
			
		||||
  using VerifyProc =
 | 
			
		||||
      base::Callback<void(const std::string& hostname,
 | 
			
		||||
                          scoped_refptr<net::X509Certificate>,
 | 
			
		||||
                          const base::Callback<void(bool)>&)>;
 | 
			
		||||
 | 
			
		||||
  void SetVerifyProc(const VerifyProc& proc);
 | 
			
		||||
 | 
			
		||||
 protected:
 | 
			
		||||
  // net::CertVerifier:
 | 
			
		||||
| 
						 | 
				
			
			@ -78,12 +39,8 @@ class AtomCertVerifier : public net::CertVerifier {
 | 
			
		|||
  bool SupportsOCSPStapling() override;
 | 
			
		||||
 | 
			
		||||
 private:
 | 
			
		||||
  friend class CertVerifyRequest;
 | 
			
		||||
 | 
			
		||||
  void VerifyCertificateFromDelegate(const VerifyArgs& args, int result);
 | 
			
		||||
  void OnDefaultVerificationResult(const VerifyArgs& args, int result);
 | 
			
		||||
 | 
			
		||||
  Delegate* delegate_;
 | 
			
		||||
  base::Lock lock_;
 | 
			
		||||
  VerifyProc verify_proc_;
 | 
			
		||||
  scoped_ptr<net::CertVerifier> default_cert_verifier_;
 | 
			
		||||
 | 
			
		||||
  DISALLOW_COPY_AND_ASSIGN(AtomCertVerifier);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -40,15 +40,9 @@ const CGFloat kVerticalTitleMargin = 2;
 | 
			
		|||
  trayIcon_ = icon;
 | 
			
		||||
  isHighlightEnable_ = YES;
 | 
			
		||||
 | 
			
		||||
  // Get the initial size.
 | 
			
		||||
  NSStatusBar* statusBar = [NSStatusBar systemStatusBar];
 | 
			
		||||
  NSRect frame = NSMakeRect(0, 0, [self fullWidth], [statusBar thickness]);
 | 
			
		||||
 | 
			
		||||
  if ((self = [super initWithFrame:frame])) {
 | 
			
		||||
  if ((self = [super initWithFrame: CGRectZero])) {
 | 
			
		||||
    // Setup the image view.
 | 
			
		||||
    NSRect iconFrame = frame;
 | 
			
		||||
    iconFrame.size.width = [self iconWidth];
 | 
			
		||||
    image_view_.reset([[NSImageView alloc] initWithFrame:iconFrame]);
 | 
			
		||||
    image_view_.reset([[NSImageView alloc] initWithFrame: CGRectZero]);
 | 
			
		||||
    [image_view_ setImageScaling:NSImageScaleNone];
 | 
			
		||||
    [image_view_ setImageAlignment:NSImageAlignCenter];
 | 
			
		||||
    [self addSubview:image_view_];
 | 
			
		||||
| 
						 | 
				
			
			@ -56,17 +50,27 @@ const CGFloat kVerticalTitleMargin = 2;
 | 
			
		|||
    // Unregister image_view_ as a dragged destination, allows its parent view
 | 
			
		||||
    // (StatusItemView) handle dragging events.
 | 
			
		||||
    [image_view_ unregisterDraggedTypes];
 | 
			
		||||
    NSArray* types = [NSArray arrayWithObjects:NSFilenamesPboardType, nil];
 | 
			
		||||
    [self registerForDraggedTypes:types];
 | 
			
		||||
    [self registerForDraggedTypes: @[NSFilenamesPboardType]];
 | 
			
		||||
 | 
			
		||||
    // Create the status item.
 | 
			
		||||
    statusItem_.reset([[[NSStatusBar systemStatusBar]
 | 
			
		||||
                        statusItemWithLength:NSWidth(frame)] retain]);
 | 
			
		||||
    NSStatusItem * item = [[NSStatusBar systemStatusBar]
 | 
			
		||||
                            statusItemWithLength:NSVariableStatusItemLength];
 | 
			
		||||
    statusItem_.reset([item retain]);
 | 
			
		||||
    [statusItem_ setView:self];
 | 
			
		||||
 | 
			
		||||
    // Finalize setup by sizing our views
 | 
			
		||||
    [self updateDimensions];
 | 
			
		||||
  }
 | 
			
		||||
  return self;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (void)updateDimensions {
 | 
			
		||||
  NSStatusBar * bar = [NSStatusBar systemStatusBar];
 | 
			
		||||
  [image_view_ setFrame: NSMakeRect(0, 0, [self iconWidth], [bar thickness])];
 | 
			
		||||
  [self setFrame: NSMakeRect(0, 0, [self fullWidth], [bar thickness])];
 | 
			
		||||
  [self setNeedsDisplay:YES];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (void)removeItem {
 | 
			
		||||
  [[NSStatusBar systemStatusBar] removeStatusItem:statusItem_];
 | 
			
		||||
  statusItem_.reset();
 | 
			
		||||
| 
						 | 
				
			
			@ -81,9 +85,7 @@ const CGFloat kVerticalTitleMargin = 2;
 | 
			
		|||
  // Draw background.
 | 
			
		||||
  BOOL highlight = [self shouldHighlight];
 | 
			
		||||
  CGFloat thickness = [[statusItem_ statusBar] thickness];
 | 
			
		||||
  NSRect statusItemBounds = NSMakeRect(0, 0, [statusItem_ length], thickness);
 | 
			
		||||
  [statusItem_ drawStatusBarBackgroundInRect:statusItemBounds
 | 
			
		||||
                               withHighlight:highlight];
 | 
			
		||||
  [statusItem_ drawStatusBarBackgroundInRect:self.bounds withHighlight:highlight];
 | 
			
		||||
 | 
			
		||||
  // Make use of NSImageView to draw the image, which can correctly draw
 | 
			
		||||
  // template image under dark menu bar.
 | 
			
		||||
| 
						 | 
				
			
			@ -157,10 +159,10 @@ const CGFloat kVerticalTitleMargin = 2;
 | 
			
		|||
  NSColor* foregroundColor = highlight ?
 | 
			
		||||
      [NSColor whiteColor] :
 | 
			
		||||
      [NSColor colorWithRed:0.265625 green:0.25390625 blue:0.234375 alpha:1.0];
 | 
			
		||||
  return [NSDictionary dictionaryWithObjectsAndKeys:
 | 
			
		||||
             font, NSFontAttributeName,
 | 
			
		||||
             foregroundColor, NSForegroundColorAttributeName,
 | 
			
		||||
             nil];
 | 
			
		||||
  return @{
 | 
			
		||||
    NSFontAttributeName: font,
 | 
			
		||||
    NSForegroundColorAttributeName: foregroundColor
 | 
			
		||||
  };
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (NSDictionary*)titleAttributes {
 | 
			
		||||
| 
						 | 
				
			
			@ -169,7 +171,7 @@ const CGFloat kVerticalTitleMargin = 2;
 | 
			
		|||
 | 
			
		||||
- (void)setImage:(NSImage*)image {
 | 
			
		||||
  image_.reset([image copy]);
 | 
			
		||||
  [self setNeedsDisplay:YES];
 | 
			
		||||
  [self updateDimensions];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (void)setAlternateImage:(NSImage*)image {
 | 
			
		||||
| 
						 | 
				
			
			@ -181,12 +183,12 @@ const CGFloat kVerticalTitleMargin = 2;
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
- (void)setTitle:(NSString*)title {
 | 
			
		||||
  if (title.length > 0)
 | 
			
		||||
  if (title.length > 0) {
 | 
			
		||||
    title_.reset([title copy]);
 | 
			
		||||
  else
 | 
			
		||||
  } else {
 | 
			
		||||
    title_.reset();
 | 
			
		||||
  [statusItem_ setLength:[self fullWidth]];
 | 
			
		||||
  [self setNeedsDisplay:YES];
 | 
			
		||||
  }
 | 
			
		||||
  [self updateDimensions];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (void)setMenuController:(AtomMenuController*)menu {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -2,7 +2,7 @@
 | 
			
		|||
 | 
			
		||||
## Introducción
 | 
			
		||||
 | 
			
		||||
Electron permite la creación de aplicaciones de escritorio utilizando JavaScript puro, a través de un runtime con APIs nativas. Puedes verlo como una variante de io.js, enfocado en aplicaciones de escritorio, en vez de servidores web. 
 | 
			
		||||
Electron permite la creación de aplicaciones de escritorio utilizando JavaScript puro, a través de un runtime con APIs nativas. Puedes verlo como una variante de io.js, enfocado en aplicaciones de escritorio, en vez de servidores web.
 | 
			
		||||
 | 
			
		||||
Esto no significa que Electron sea un binding de librerías GUI para JavaScript.
 | 
			
		||||
Electron utiliza páginas web como su GUI, por lo cual puedes verlo como un navegador Chromium mínimo,
 | 
			
		||||
| 
						 | 
				
			
			@ -94,7 +94,7 @@ app.on('ready', function() {
 | 
			
		|||
  mainWindow = new BrowserWindow({width: 800, height: 600});
 | 
			
		||||
 | 
			
		||||
  // cargar el index.html de nuestra aplicación.
 | 
			
		||||
  mainWindow.loadUrl('file://' + __dirname + '/index.html');
 | 
			
		||||
  mainWindow.loadURL('file://' + __dirname + '/index.html');
 | 
			
		||||
 | 
			
		||||
  // Desplegar devtools.
 | 
			
		||||
  mainWindow.openDevTools();
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -74,7 +74,7 @@ app.on('ready', function() {
 | 
			
		|||
  mainWindow = new BrowserWindow({width: 800, height: 600});
 | 
			
		||||
 | 
			
		||||
  // and load the index.html of the app.
 | 
			
		||||
  mainWindow.loadUrl('file://' + __dirname + '/index.html');
 | 
			
		||||
  mainWindow.loadURL('file://' + __dirname + '/index.html');
 | 
			
		||||
 | 
			
		||||
  // Open the devtools.
 | 
			
		||||
  mainWindow.openDevTools();
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -5,13 +5,13 @@ um runtime com APIs ricas e nativas. Você pode ver isso como uma variação do
 | 
			
		|||
runtime do io.js que é focado em aplicações desktop em vez de web servers.
 | 
			
		||||
 | 
			
		||||
Isso não significa que o Electron é uma ligação em JavaScript para blibliotécas
 | 
			
		||||
de interface gráfica (GUI). Em vez disso, Electron usa páginas web como 
 | 
			
		||||
de interface gráfica (GUI). Em vez disso, Electron usa páginas web como
 | 
			
		||||
interface gráfica, então você pode ver isso também como um navegador Chromium
 | 
			
		||||
mínimo, controlado por JavaScript.
 | 
			
		||||
 | 
			
		||||
### Processo Principal
 | 
			
		||||
 | 
			
		||||
No Electron, o processo que executa o script principal (main) do `package.json` 
 | 
			
		||||
No Electron, o processo que executa o script principal (main) do `package.json`
 | 
			
		||||
é chamado __processo principal__. O script que roda no processo principal pode
 | 
			
		||||
mostrar uma GUI criando páginas web.
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -38,7 +38,7 @@ correspondentes. Cada processo renderizador é isolado e toma conta de sua
 | 
			
		|||
respectiva página web.
 | 
			
		||||
 | 
			
		||||
Nas páginas web, chamar APIs nativas relacionadas à GUI não é permitido porque
 | 
			
		||||
gerênciar recursos de GUI em páginas web é muito perigoso e torna fácil o vazamento de 
 | 
			
		||||
gerênciar recursos de GUI em páginas web é muito perigoso e torna fácil o vazamento de
 | 
			
		||||
recursos. Se você quer realizar operações com GUI em páginas web, o processo
 | 
			
		||||
renderizador da página web deve se comunicar com o processo principal para requisitar
 | 
			
		||||
que o processo principal realize estas operações.
 | 
			
		||||
| 
						 | 
				
			
			@ -71,7 +71,7 @@ com isso:
 | 
			
		|||
}
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
__Nota__: Se o campo `main` não estiver presente no `package.jso`, o Electron irá 
 | 
			
		||||
__Nota__: Se o campo `main` não estiver presente no `package.jso`, o Electron irá
 | 
			
		||||
tentar carregar um `index.js`
 | 
			
		||||
 | 
			
		||||
O `main.js` deve criar as janelas e os manipuladores de eventos do sistema, um típico
 | 
			
		||||
| 
						 | 
				
			
			@ -85,7 +85,7 @@ var BrowserWindow = require('browser-window');  // Módulo para criar uma janela
 | 
			
		|||
require('crash-reporter').start();
 | 
			
		||||
 | 
			
		||||
// Mantenha uma referência global para o objeto window, se você não o fizer,
 | 
			
		||||
// a janela será fechada automaticamente quando o objeto JavaScript for 
 | 
			
		||||
// a janela será fechada automaticamente quando o objeto JavaScript for
 | 
			
		||||
// coletado pelo garbage collector.
 | 
			
		||||
var mainWindow = null;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -106,7 +106,7 @@ app.on('ready', function() {
 | 
			
		|||
  mainWindow = new BrowserWindow({width: 800, height: 600});
 | 
			
		||||
 | 
			
		||||
  // e carrega o index.html do app.
 | 
			
		||||
  mainWindow.loadUrl('file://' + __dirname + '/index.html');
 | 
			
		||||
  mainWindow.loadURL('file://' + __dirname + '/index.html');
 | 
			
		||||
 | 
			
		||||
  // Abre os DevTools.
 | 
			
		||||
  mainWindow.openDevTools();
 | 
			
		||||
| 
						 | 
				
			
			@ -187,6 +187,6 @@ $ ./Electron.app/Contents/MacOS/Electron your-app/
 | 
			
		|||
 | 
			
		||||
### Executar como uma distribuição
 | 
			
		||||
 | 
			
		||||
Depois de terminar seu app, você pode criar uma distribuição seguindo o guia 
 | 
			
		||||
Depois de terminar seu app, você pode criar uma distribuição seguindo o guia
 | 
			
		||||
[Application Distribution](./application-distribution.md) e então executar o app
 | 
			
		||||
empacotado.
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -68,7 +68,7 @@ app.on('ready', function() {
 | 
			
		|||
  mainWindow = new BrowserWindow({width: 800, height: 600});
 | 
			
		||||
 | 
			
		||||
  // 加载应用的 index.html
 | 
			
		||||
  mainWindow.loadUrl('file://' + __dirname + '/index.html');
 | 
			
		||||
  mainWindow.loadURL('file://' + __dirname + '/index.html');
 | 
			
		||||
 | 
			
		||||
  // 打开开发工具
 | 
			
		||||
  mainWindow.openDevTools();
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -85,7 +85,7 @@ app.on('ready', function() {
 | 
			
		|||
  mainWindow = new BrowserWindow({width: 800, height: 600});
 | 
			
		||||
 | 
			
		||||
  // 載入應用程式的 index.html
 | 
			
		||||
  mainWindow.loadUrl('file://' + __dirname + '/index.html');
 | 
			
		||||
  mainWindow.loadURL('file://' + __dirname + '/index.html');
 | 
			
		||||
 | 
			
		||||
  // 打開開發者工具
 | 
			
		||||
  mainWindow.webContents.openDevTools();
 | 
			
		||||
| 
						 | 
				
			
			@ -174,4 +174,4 @@ $ git clone https://github.com/atom/electron-quick-start
 | 
			
		|||
$ cd electron-quick-start
 | 
			
		||||
# Install dependencies and run the app
 | 
			
		||||
$ npm install && npm start
 | 
			
		||||
```
 | 
			
		||||
```
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -131,7 +131,36 @@ Returns:
 | 
			
		|||
 | 
			
		||||
Emitted when a new [browserWindow](browser-window.md) is created.
 | 
			
		||||
 | 
			
		||||
### Event: 'select-certificate'
 | 
			
		||||
### Event: 'certificate-error'
 | 
			
		||||
 | 
			
		||||
Returns:
 | 
			
		||||
 | 
			
		||||
* `event` Event
 | 
			
		||||
* `webContents` [WebContents](web-contents.md)
 | 
			
		||||
* `url` URL
 | 
			
		||||
* `error` String - The error code
 | 
			
		||||
* `certificate` Object
 | 
			
		||||
  * `data` Buffer - PEM encoded data
 | 
			
		||||
  * `issuerName` String
 | 
			
		||||
* `callback` Function
 | 
			
		||||
 | 
			
		||||
Emitted when failed to verify the `certificate` for `url`, to trust the
 | 
			
		||||
certificate you should prevent the default behavior with
 | 
			
		||||
`event.preventDefault()` and call `callback(true)`.
 | 
			
		||||
 | 
			
		||||
```javascript
 | 
			
		||||
session.on('certificate-error', function(event, webContents, url, error, certificate, callback) {
 | 
			
		||||
  if (url == "https://github.com") {
 | 
			
		||||
    // Verification logic.
 | 
			
		||||
    event.preventDefault();
 | 
			
		||||
    callback(true);
 | 
			
		||||
  } else {
 | 
			
		||||
    callback(false);
 | 
			
		||||
  }
 | 
			
		||||
});
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
### Event: 'select-client-certificate'
 | 
			
		||||
 | 
			
		||||
Returns:
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -151,7 +180,7 @@ and `callback` needs to be called with an entry filtered from the list. Using
 | 
			
		|||
certificate from the store.
 | 
			
		||||
 | 
			
		||||
```javascript
 | 
			
		||||
app.on('select-certificate', function(event, host, url, list, callback) {
 | 
			
		||||
app.on('select-client-certificate', function(event, webContents, url, list, callback) {
 | 
			
		||||
  event.preventDefault();
 | 
			
		||||
  callback(list[0]);
 | 
			
		||||
})
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -232,7 +232,7 @@ Emitted when the window enters full screen state triggered by html api.
 | 
			
		|||
 | 
			
		||||
Emitted when the window leaves full screen state triggered by html api.
 | 
			
		||||
 | 
			
		||||
### Event: 'app-command':
 | 
			
		||||
### Event: 'app-command' _Windows_
 | 
			
		||||
 | 
			
		||||
Emitted when an [App Command](https://msdn.microsoft.com/en-us/library/windows/desktop/ms646275(v=vs.85).aspx)
 | 
			
		||||
is invoked. These are typically related to keyboard media keys or browser
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -103,7 +103,7 @@ Registers a protocol of `scheme` that will send a `String` as a response. The
 | 
			
		|||
 | 
			
		||||
Registers a protocol of `scheme` that will send an HTTP request as a response.
 | 
			
		||||
The `callback` should be called with an object that has the `url`, `method`,
 | 
			
		||||
`referer`, and `session` properties.
 | 
			
		||||
`referrer`, and `session` properties.
 | 
			
		||||
 | 
			
		||||
By default the HTTP request will reuse the current session. If you want the
 | 
			
		||||
request to have a different session you should set `session` to `null`.
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -34,31 +34,6 @@ session.on('will-download', function(event, item, webContents) {
 | 
			
		|||
});
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
### Event: 'untrusted-certificate'
 | 
			
		||||
 | 
			
		||||
* `event` Event
 | 
			
		||||
* `hostname` String
 | 
			
		||||
* `certificate` Object
 | 
			
		||||
  * `data` Buffer - PEM encoded data
 | 
			
		||||
  * `issuerName` String
 | 
			
		||||
* `callback` Function
 | 
			
		||||
 | 
			
		||||
Emitted when failed to verify the `certificate` for `hostname`, to trust the
 | 
			
		||||
certificate you should prevent the default behavior with
 | 
			
		||||
`event.preventDefault()` and call `callback(true)`.
 | 
			
		||||
 | 
			
		||||
```js
 | 
			
		||||
session.on('verify-certificate', function(event, hostname, certificate, callback) {
 | 
			
		||||
  if (hostname == "github.com") {
 | 
			
		||||
    // Verification logic.
 | 
			
		||||
    event.preventDefault();
 | 
			
		||||
    callback(true);
 | 
			
		||||
  } else {
 | 
			
		||||
    callback(false);
 | 
			
		||||
  }
 | 
			
		||||
});
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
## Methods
 | 
			
		||||
 | 
			
		||||
The `session` object has the following methods:
 | 
			
		||||
| 
						 | 
				
			
			@ -245,3 +220,24 @@ window.webContents.session.enableNetworkEmulation({offline: true});
 | 
			
		|||
 | 
			
		||||
Disables any network emulation already active for the `session`. Resets to
 | 
			
		||||
the original network configuration.
 | 
			
		||||
 | 
			
		||||
### `session.setCertificateVerifyProc(proc)`
 | 
			
		||||
 | 
			
		||||
* `proc` Function
 | 
			
		||||
 | 
			
		||||
Sets the certificate verify proc for `session`, the `proc` will be called with
 | 
			
		||||
`proc(hostname, certificate, callback)` whenever a server certificate
 | 
			
		||||
verification is requested. Calling `callback(true)` accepts the certificate,
 | 
			
		||||
calling `callback(false)` rejects it.
 | 
			
		||||
 | 
			
		||||
Calling `setCertificateVerifyProc(null)` will revert back to default certificate
 | 
			
		||||
verify proc.
 | 
			
		||||
 | 
			
		||||
```javascript
 | 
			
		||||
myWindow.webContents.session.setCertificateVerifyProc(function(hostname, cert, callback) {
 | 
			
		||||
  if (hostname == 'github.com')
 | 
			
		||||
    callback(true);
 | 
			
		||||
  else
 | 
			
		||||
    callback(false);
 | 
			
		||||
});
 | 
			
		||||
```
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -175,7 +175,8 @@ Sets the title displayed aside of the tray icon in the status bar.
 | 
			
		|||
 | 
			
		||||
* `highlight` Boolean
 | 
			
		||||
 | 
			
		||||
Sets whether the tray icon is highlighted when it is clicked.
 | 
			
		||||
Sets whether the tray icon's background becomes highlighted (in blue)
 | 
			
		||||
when the tray icon is clicked. Defaults to true.
 | 
			
		||||
 | 
			
		||||
### `Tray.displayBalloon(options)` _Windows_
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -167,6 +167,39 @@ Emitted when DevTools is closed.
 | 
			
		|||
 | 
			
		||||
Emitted when DevTools is focused / opened.
 | 
			
		||||
 | 
			
		||||
### Event: 'certificate-error'
 | 
			
		||||
 | 
			
		||||
Returns:
 | 
			
		||||
 | 
			
		||||
* `event` Event
 | 
			
		||||
* `url` URL
 | 
			
		||||
* `error` String - The error code
 | 
			
		||||
* `certificate` Object
 | 
			
		||||
  * `data` Buffer - PEM encoded data
 | 
			
		||||
  * `issuerName` String
 | 
			
		||||
* `callback` Function
 | 
			
		||||
 | 
			
		||||
Emitted when failed to verify the `certificate` for `url`.
 | 
			
		||||
 | 
			
		||||
The usage is the same with [the `certificate-error` event of
 | 
			
		||||
`app`](app.md#event-certificate-error).
 | 
			
		||||
 | 
			
		||||
### Event: 'select-client-certificate'
 | 
			
		||||
 | 
			
		||||
Returns:
 | 
			
		||||
 | 
			
		||||
* `event` Event
 | 
			
		||||
* `url` URL
 | 
			
		||||
* `certificateList` [Objects]
 | 
			
		||||
  * `data` Buffer - PEM encoded data
 | 
			
		||||
  * `issuerName` String - Issuer's Common Name
 | 
			
		||||
* `callback` Function
 | 
			
		||||
 | 
			
		||||
Emitted when a client certificate is requested.
 | 
			
		||||
 | 
			
		||||
The usage is the same with [the `select-client-certificate` event of
 | 
			
		||||
`app`](app.md#event-select-client-certificate).
 | 
			
		||||
 | 
			
		||||
### Event: 'login'
 | 
			
		||||
 | 
			
		||||
Returns:
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue