From e90961ac4f0d9731e882e02ef77869ed99aaf4e0 Mon Sep 17 00:00:00 2001 From: Matias Insaurralde Date: Wed, 28 Oct 2015 03:19:19 -0300 Subject: [PATCH 001/249] Creating supported-platforms.md --- .../es/tutorial/supported-platforms.md | 30 +++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 docs-translations/es/tutorial/supported-platforms.md diff --git a/docs-translations/es/tutorial/supported-platforms.md b/docs-translations/es/tutorial/supported-platforms.md new file mode 100644 index 000000000000..95ccc267722d --- /dev/null +++ b/docs-translations/es/tutorial/supported-platforms.md @@ -0,0 +1,30 @@ +# Plataformas soportadas + +Las siguientes plataformas son soportadas por Electron: + +### OS X + +Sólo se proveen binarios de 64 bit para OS X. +La versión mínima soportada es OS X 10.8. + +### Windows + +Windows 7 y posteriores son soportados, las versiones antiguas no son soportadas (y no funcionan). + +Se proveen binarios para las arquitecturas `x86` y `amd64` (x64). +Nota: La versión para `ARM` de Windows no está soportada aún. + +### Linux + +Los binarios preconstruidos para `ia32`(`i686`) y `x64`(`amd64`) son construidos sobre +Ubuntu 12.04, el binario para `arm` es construido sobre ARM v7 con la ABI hard-float +y NEON para Debian Wheezy. + +La posibilidad de que un binario preconstruido se ejecute en una distribución determinada +depende de las librerías contra las que fue enlazado Electron. +Por ahora sólo se garantiza la ejecución en Ubuntu 12.04, aunque también se ha verificado +el funcionamiento de los binarios preconstruidos en las siguientes plataformas: + +* Ubuntu 12.04 and later +* Fedora 21 +* Debian 8 From 0c5fe03999919f97395229d3e9414686770d5cf0 Mon Sep 17 00:00:00 2001 From: Antoine Pairet Date: Wed, 28 Oct 2015 11:40:01 +0100 Subject: [PATCH 002/249] Fix module types available in the renderer process The doc previously stated `only GUI-unrelated` modules are available to the renderer process. I think it should be `only GUI-related` --- docs/api/remote.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/api/remote.md b/docs/api/remote.md index 55893c65f1c4..14805923562c 100644 --- a/docs/api/remote.md +++ b/docs/api/remote.md @@ -3,7 +3,7 @@ The `remote` module provides a simple way to do inter-process communication (IPC) between the renderer process (web page) and the main process. -In Electron, only GUI-unrelated modules are available in the renderer process. +In Electron, only GUI-related modules are available in the renderer process. Without the `remote` module, users who want to call a main process API in the renderer process will have to explicitly send inter-process messages to the main process. With the `remote` module, you can invoke methods of the From 5fd310c75f1f08ac772181f31ba9972b0ea7385e Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Wed, 28 Oct 2015 19:43:05 +0800 Subject: [PATCH 003/249] Add converter for LPARAM --- atom/browser/api/atom_api_window.cc | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/atom/browser/api/atom_api_window.cc b/atom/browser/api/atom_api_window.cc index 45b57f5307be..5d0a501629f8 100644 --- a/atom/browser/api/atom_api_window.cc +++ b/atom/browser/api/atom_api_window.cc @@ -42,6 +42,14 @@ struct Converter { } }; +template<> +struct Converter { + static v8::Local ToV8(v8::Isolate* isolate, + LPARAM val) { + return ConvertToV8(isolate, static_cast(val)); + } +}; + } // namespace mate #endif From b86267aa3bc51b895e6bb18579bd447e7cfa0d93 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Wed, 28 Oct 2015 19:51:24 +0800 Subject: [PATCH 004/249] Use uint64_t instead of LPARAM LPARAM is defined to differnt types on differnt machines with different SDKs, so there is no way to represent it on all platforms safely, using uint64_t seems to be the only safe choice. --- atom/browser/api/atom_api_window.cc | 10 +--------- atom/browser/api/atom_api_window.h | 5 ++--- atom/browser/native_window.cc | 5 +++-- atom/browser/native_window_observer.h | 2 +- 4 files changed, 7 insertions(+), 15 deletions(-) diff --git a/atom/browser/api/atom_api_window.cc b/atom/browser/api/atom_api_window.cc index 5d0a501629f8..077dffe0bc5c 100644 --- a/atom/browser/api/atom_api_window.cc +++ b/atom/browser/api/atom_api_window.cc @@ -42,14 +42,6 @@ struct Converter { } }; -template<> -struct Converter { - static v8::Local ToV8(v8::Isolate* isolate, - LPARAM val) { - return ConvertToV8(isolate, static_cast(val)); - } -}; - } // namespace mate #endif @@ -198,7 +190,7 @@ void Window::OnExecuteWindowsCommand(const std::string& command_name) { } #if defined(OS_WIN) -void Window::OnWindowMessage(UINT message, WPARAM w_param, LPARAM l_param) { +void Window::OnWindowMessage(UINT message, WPARAM w_param, uint64_t l_param) { if (IsWindowMessageHooked(message)) { messages_callback_map_[message].Run(w_param, l_param); } diff --git a/atom/browser/api/atom_api_window.h b/atom/browser/api/atom_api_window.h index 870f8e134216..f4bc4cdba01a 100644 --- a/atom/browser/api/atom_api_window.h +++ b/atom/browser/api/atom_api_window.h @@ -77,8 +77,7 @@ class Window : public mate::TrackableObject, void OnExecuteWindowsCommand(const std::string& command_name) override; #if defined(OS_WIN) - void OnWindowMessage(UINT message, WPARAM w_param, - LPARAM l_param) override; + void OnWindowMessage(UINT message, WPARAM w_param, uint64_t l_param) override; #endif // mate::Wrappable: @@ -150,7 +149,7 @@ class Window : public mate::TrackableObject, void SetAspectRatio(double aspect_ratio, mate::Arguments* args); #if defined(OS_WIN) - typedef base::Callback MessageCallback; + typedef base::Callback MessageCallback; typedef std::map MessageCallbackMap; MessageCallbackMap messages_callback_map_; diff --git a/atom/browser/native_window.cc b/atom/browser/native_window.cc index e3abed473e7d..6e38f4028745 100644 --- a/atom/browser/native_window.cc +++ b/atom/browser/native_window.cc @@ -467,8 +467,9 @@ void NativeWindow::NotifyWindowExecuteWindowsCommand( #if defined(OS_WIN) void NativeWindow::NotifyWindowMessage(UINT message, WPARAM w_param, LPARAM l_param) { - FOR_EACH_OBSERVER(NativeWindowObserver, observers_, - OnWindowMessage(message, w_param, l_param)); + FOR_EACH_OBSERVER( + NativeWindowObserver, observers_, + OnWindowMessage(message, w_param, static_cast(l_param))); } #endif diff --git a/atom/browser/native_window_observer.h b/atom/browser/native_window_observer.h index 54004a300d94..240a7277fa09 100644 --- a/atom/browser/native_window_observer.h +++ b/atom/browser/native_window_observer.h @@ -61,7 +61,7 @@ class NativeWindowObserver { // Called when window message received #if defined(OS_WIN) - virtual void OnWindowMessage(UINT message, WPARAM w_param, LPARAM l_param) {} + virtual void OnWindowMessage(UINT message, WPARAM wparam, uint64_t lparam) {} #endif // Called when renderer is hung. From 9df89cf79b7679b73f6c4b43c853a07076ddf9ac Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Wed, 28 Oct 2015 15:34:41 +0800 Subject: [PATCH 005/249] Add dummy LoginHandler --- .../atom_resource_dispatcher_host_delegate.cc | 8 ++++ .../atom_resource_dispatcher_host_delegate.h | 3 ++ atom/browser/login_handler.cc | 22 ++++++++++ atom/browser/login_handler.h | 43 +++++++++++++++++++ filenames.gypi | 2 + 5 files changed, 78 insertions(+) create mode 100644 atom/browser/login_handler.cc create mode 100644 atom/browser/login_handler.h diff --git a/atom/browser/atom_resource_dispatcher_host_delegate.cc b/atom/browser/atom_resource_dispatcher_host_delegate.cc index 46904d2ff99d..aaba1f31045b 100644 --- a/atom/browser/atom_resource_dispatcher_host_delegate.cc +++ b/atom/browser/atom_resource_dispatcher_host_delegate.cc @@ -4,6 +4,7 @@ #include "atom/browser/atom_resource_dispatcher_host_delegate.h" +#include "atom/browser/login_handler.h" #include "atom/common/platform_util.h" #include "content/public/browser/browser_thread.h" #include "net/base/escape.h" @@ -29,4 +30,11 @@ bool AtomResourceDispatcherHostDelegate::HandleExternalProtocol( return true; } +content::ResourceDispatcherHostLoginDelegate* +AtomResourceDispatcherHostDelegate::CreateLoginDelegate( + net::AuthChallengeInfo* auth_info, + net::URLRequest* request) { + return new LoginHandler(auth_info, request); +} + } // namespace atom diff --git a/atom/browser/atom_resource_dispatcher_host_delegate.h b/atom/browser/atom_resource_dispatcher_host_delegate.h index 876554f0f964..a90b366bc75b 100644 --- a/atom/browser/atom_resource_dispatcher_host_delegate.h +++ b/atom/browser/atom_resource_dispatcher_host_delegate.h @@ -21,6 +21,9 @@ class AtomResourceDispatcherHostDelegate bool is_main_frame, ui::PageTransition transition, bool has_user_gesture) override; + content::ResourceDispatcherHostLoginDelegate* CreateLoginDelegate( + net::AuthChallengeInfo* auth_info, + net::URLRequest* request) override; }; } // namespace atom diff --git a/atom/browser/login_handler.cc b/atom/browser/login_handler.cc new file mode 100644 index 000000000000..1980cc133abc --- /dev/null +++ b/atom/browser/login_handler.cc @@ -0,0 +1,22 @@ +// Copyright (c) 2015 GitHub, Inc. +// Use of this source code is governed by the MIT license that can be +// found in the LICENSE file. + +#include "atom/browser/login_handler.h" + +#include "net/base/auth.h" + +namespace atom { + +LoginHandler::LoginHandler(net::AuthChallengeInfo* auth_info, + net::URLRequest* request) + : auth_info_(auth_info), request_(request), weak_factory_(this) { +} + +LoginHandler::~LoginHandler() { +} + +void LoginHandler::OnRequestCancelled() { +} + +} // namespace atom diff --git a/atom/browser/login_handler.h b/atom/browser/login_handler.h new file mode 100644 index 000000000000..421e2e43837d --- /dev/null +++ b/atom/browser/login_handler.h @@ -0,0 +1,43 @@ +// Copyright (c) 2015 GitHub, Inc. +// Use of this source code is governed by the MIT license that can be +// found in the LICENSE file. + +#ifndef ATOM_BROWSER_LOGIN_HANDLER_H_ +#define ATOM_BROWSER_LOGIN_HANDLER_H_ + +#include "base/memory/weak_ptr.h" +#include "content/public/browser/resource_dispatcher_host_login_delegate.h" + +namespace net { +class AuthChallengeInfo; +class URLRequest; +} + +namespace atom { + +class LoginHandler : public content::ResourceDispatcherHostLoginDelegate { + public: + LoginHandler(net::AuthChallengeInfo* auth_info, net::URLRequest* request); + + protected: + ~LoginHandler() override; + + // content::ResourceDispatcherHostLoginDelegate: + void OnRequestCancelled() override; + + private: + // Who/where/what asked for the authentication. + scoped_refptr auth_info_; + + // The request that wants login data. + // This should only be accessed on the IO loop. + net::URLRequest* request_; + + base::WeakPtrFactory weak_factory_; + + DISALLOW_COPY_AND_ASSIGN(LoginHandler); +}; + +} // namespace atom + +#endif // ATOM_BROWSER_LOGIN_HANDLER_H_ diff --git a/filenames.gypi b/filenames.gypi index e6d180d652e1..a294a1e8083f 100644 --- a/filenames.gypi +++ b/filenames.gypi @@ -150,6 +150,8 @@ 'atom/browser/common_web_contents_delegate.h', 'atom/browser/javascript_environment.cc', 'atom/browser/javascript_environment.h', + 'atom/browser/login_handler.cc', + 'atom/browser/login_handler.h', 'atom/browser/mac/atom_application.h', 'atom/browser/mac/atom_application.mm', 'atom/browser/mac/atom_application_delegate.h', From 3881ad1c4b49db71a24b6ed2e1208ce6e954e1c0 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Wed, 28 Oct 2015 17:36:01 +0800 Subject: [PATCH 006/249] Don't leak FunctionTemplate when converting C++ callback --- .../common/native_mate_converters/callback.cc | 62 +++++++++++++++++++ atom/common/native_mate_converters/callback.h | 33 +++++++++- filenames.gypi | 1 + 3 files changed, 94 insertions(+), 2 deletions(-) create mode 100644 atom/common/native_mate_converters/callback.cc diff --git a/atom/common/native_mate_converters/callback.cc b/atom/common/native_mate_converters/callback.cc new file mode 100644 index 000000000000..0be90f63e757 --- /dev/null +++ b/atom/common/native_mate_converters/callback.cc @@ -0,0 +1,62 @@ +// Copyright (c) 2015 GitHub, Inc. All rights reserved. +// Use of this source code is governed by the MIT license that can be +// found in the LICENSE file. + +#include "atom/common/native_mate_converters/callback.h" + +namespace mate { + +namespace internal { + +namespace { + +struct TranslaterHolder { + Translater translater; +}; + +// Cached JavaScript version of |CallTranslater|. +v8::Persistent g_call_translater; + +void CallTranslater(v8::Local external, mate::Arguments* args) { + TranslaterHolder* holder = static_cast(external->Value()); + holder->translater.Run(args); +} + +// func.bind(func, arg1). +// NB(zcbenz): Using C++11 version crashes VS. +v8::Local BindFunctionWith(v8::Isolate* isolate, + v8::Local context, + v8::Local func, + v8::Local arg1) { + v8::MaybeLocal bind = func->Get(mate::StringToV8(isolate, "bind")); + CHECK(!bind.IsEmpty()); + v8::Local bind_func = + v8::Local::Cast(bind.ToLocalChecked()); + v8::Local converted[] = { func, arg1 }; + return bind_func->Call( + context, func, arraysize(converted), converted).ToLocalChecked(); +} + +} // namespace + +v8::Local CreateFunctionFromTranslater( + v8::Isolate* isolate, const Translater& translater) { + // The FunctionTemplate is cached. + if (g_call_translater.IsEmpty()) + g_call_translater.Reset( + isolate, + mate::CreateFunctionTemplate(isolate, base::Bind(&CallTranslater))); + + v8::Local call_translater = + v8::Local::New(isolate, g_call_translater); + TranslaterHolder* holder = new TranslaterHolder; + holder->translater = translater; + return BindFunctionWith(isolate, + isolate->GetCurrentContext(), + call_translater->GetFunction(), + v8::External::New(isolate, holder)); +} + +} // namespace internal + +} // namespace mate diff --git a/atom/common/native_mate_converters/callback.h b/atom/common/native_mate_converters/callback.h index 68ea911fe143..4349b9997b25 100644 --- a/atom/common/native_mate_converters/callback.h +++ b/atom/common/native_mate_converters/callback.h @@ -20,6 +20,7 @@ namespace internal { typedef scoped_refptr > SafeV8Function; +// Helper to invoke a V8 function with C++ parameters. template struct V8FunctionInvoker {}; @@ -81,13 +82,41 @@ struct V8FunctionInvoker { } }; +// Helper to pass a C++ funtion to JavaScript. +using Translater = base::Callback; +v8::Local CreateFunctionFromTranslater( + v8::Isolate* isolate, const Translater& translater); + +// Calls callback with Arguments. +template +struct NativeFunctionInvoker {}; + +template +struct NativeFunctionInvoker { + static void Go(base::Callback val, Arguments* args) { + using Indices = typename IndicesGenerator::type; + Invoker invoker(args, 0); + if (invoker.IsOK()) + invoker.DispatchToCallback(val); + } +}; + +// Create a static function that accepts generic callback. +template +Translater ConvertToTranslater(const base::Callback& val) { + return base::Bind(&NativeFunctionInvoker::Go, val); +} + } // namespace internal template struct Converter > { static v8::Local ToV8(v8::Isolate* isolate, - const base::Callback& val) { - return CreateFunctionTemplate(isolate, val)->GetFunction(); + const base::Callback& val) { + // We don't use CreateFunctionTemplate here because it creates a new + // FunctionTemplate everytime, which is cached by V8 and causes leaks. + internal::Translater translater = internal::ConvertToTranslater(val); + return internal::CreateFunctionFromTranslater(isolate, translater); } static bool FromV8(v8::Isolate* isolate, v8::Local val, diff --git a/filenames.gypi b/filenames.gypi index a294a1e8083f..65bf6b79a2c2 100644 --- a/filenames.gypi +++ b/filenames.gypi @@ -304,6 +304,7 @@ 'atom/common/native_mate_converters/accelerator_converter.h', 'atom/common/native_mate_converters/blink_converter.cc', 'atom/common/native_mate_converters/blink_converter.h', + 'atom/common/native_mate_converters/callback.cc', 'atom/common/native_mate_converters/callback.h', 'atom/common/native_mate_converters/file_path_converter.h', 'atom/common/native_mate_converters/gfx_converter.cc', From 5d8a31c1401bccf21bac1d50c111871f292258e7 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Wed, 28 Oct 2015 18:19:36 +0800 Subject: [PATCH 007/249] spec: Return early on error --- spec/api-protocol-spec.coffee | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/spec/api-protocol-spec.coffee b/spec/api-protocol-spec.coffee index 02fd8d5e402a..8990f8029ee1 100644 --- a/spec/api-protocol-spec.coffee +++ b/spec/api-protocol-spec.coffee @@ -26,6 +26,7 @@ describe 'protocol module', -> callback(text) callback() protocol.registerStringProtocol protocolName, doubleHandler, (error) -> + return done(error) if error $.ajax url: "#{protocolName}://fake-host" success: (data) -> @@ -36,6 +37,7 @@ describe 'protocol module', -> it 'sends error when callback is called with nothing', (done) -> protocol.registerBufferProtocol protocolName, emptyHandler, (error) -> + return done(error) if error $.ajax url: "#{protocolName}://fake-host" success: (data) -> @@ -48,6 +50,7 @@ describe 'protocol module', -> handler = (request, callback) -> setImmediate -> callback(text) protocol.registerStringProtocol protocolName, handler, (error) -> + return done(error) if error $.ajax url: "#{protocolName}://fake-host" success: (data) -> @@ -66,6 +69,7 @@ describe 'protocol module', -> it 'sends string as response', (done) -> handler = (request, callback) -> callback(text) protocol.registerStringProtocol protocolName, handler, (error) -> + return done(error) if error $.ajax url: "#{protocolName}://fake-host" success: (data) -> @@ -77,6 +81,7 @@ describe 'protocol module', -> it 'sends object as response', (done) -> handler = (request, callback) -> callback(data: text, mimeType: 'text/html') protocol.registerStringProtocol protocolName, handler, (error) -> + return done(error) if error $.ajax url: "#{protocolName}://fake-host" success: (data, statux, request) -> @@ -88,6 +93,7 @@ describe 'protocol module', -> it 'fails when sending object other than string', (done) -> handler = (request, callback) -> callback(new Date) protocol.registerBufferProtocol protocolName, handler, (error) -> + return done(error) if error $.ajax url: "#{protocolName}://fake-host" success: (data) -> @@ -102,6 +108,7 @@ describe 'protocol module', -> it 'sends Buffer as response', (done) -> handler = (request, callback) -> callback(buffer) protocol.registerBufferProtocol protocolName, handler, (error) -> + return done(error) if error $.ajax url: "#{protocolName}://fake-host" success: (data) -> @@ -113,6 +120,7 @@ describe 'protocol module', -> it 'sends object as response', (done) -> handler = (request, callback) -> callback(data: buffer, mimeType: 'text/html') protocol.registerBufferProtocol protocolName, handler, (error) -> + return done(error) if error $.ajax url: "#{protocolName}://fake-host" success: (data, statux, request) -> @@ -124,6 +132,7 @@ describe 'protocol module', -> it 'fails when sending string', (done) -> handler = (request, callback) -> callback(text) protocol.registerBufferProtocol protocolName, handler, (error) -> + return done(error) if error $.ajax url: "#{protocolName}://fake-host" success: (data) -> @@ -142,6 +151,7 @@ describe 'protocol module', -> it 'sends file path as response', (done) -> handler = (request, callback) -> callback(filePath) protocol.registerFileProtocol protocolName, handler, (error) -> + return done(error) if error $.ajax url: "#{protocolName}://fake-host" success: (data) -> @@ -153,6 +163,7 @@ describe 'protocol module', -> it 'sends object as response', (done) -> handler = (request, callback) -> callback(path: filePath) protocol.registerFileProtocol protocolName, handler, (error) -> + return done(error) if error $.ajax url: "#{protocolName}://fake-host" success: (data, statux, request) -> @@ -164,6 +175,7 @@ describe 'protocol module', -> it 'can send normal file', (done) -> handler = (request, callback) -> callback(normalPath) protocol.registerFileProtocol protocolName, handler, (error) -> + return done(error) if error $.ajax url: "#{protocolName}://fake-host" success: (data) -> @@ -176,6 +188,7 @@ describe 'protocol module', -> fakeFilePath = path.join __dirname, 'fixtures', 'asar', 'a.asar', 'not-exist' handler = (request, callback) -> callback(fakeFilePath) protocol.registerBufferProtocol protocolName, handler, (error) -> + return done(error) if error $.ajax url: "#{protocolName}://fake-host" success: (data) -> @@ -187,6 +200,7 @@ describe 'protocol module', -> it 'fails when sending unsupported content', (done) -> handler = (request, callback) -> callback(new Date) protocol.registerBufferProtocol protocolName, handler, (error) -> + return done(error) if error $.ajax url: "#{protocolName}://fake-host" success: (data) -> @@ -206,6 +220,7 @@ describe 'protocol module', -> url = "http://127.0.0.1:#{port}" handler = (request, callback) -> callback({url}) protocol.registerHttpProtocol protocolName, handler, (error) -> + return done(error) if error $.ajax url: "#{protocolName}://fake-host" success: (data) -> @@ -217,6 +232,7 @@ describe 'protocol module', -> it 'fails when sending invalid url', (done) -> handler = (request, callback) -> callback({url: 'url'}) protocol.registerHttpProtocol protocolName, handler, (error) -> + return done(error) if error $.ajax url: "#{protocolName}://fake-host" success: (data) -> @@ -228,6 +244,7 @@ describe 'protocol module', -> it 'fails when sending unsupported content', (done) -> handler = (request, callback) -> callback(new Date) protocol.registerHttpProtocol protocolName, handler, (error) -> + return done(error) if error $.ajax url: "#{protocolName}://fake-host" success: (data) -> @@ -288,6 +305,7 @@ describe 'protocol module', -> callback(text) callback() protocol.interceptStringProtocol 'http', doubleHandler, (error) -> + return done(error) if error $.ajax url: 'http://fake-host' success: (data) -> @@ -298,6 +316,7 @@ describe 'protocol module', -> it 'sends error when callback is called with nothing', (done) -> protocol.interceptBufferProtocol 'http', emptyHandler, (error) -> + return done(error) if error $.ajax url: 'http://fake-host' success: (data) -> @@ -310,6 +329,7 @@ describe 'protocol module', -> it 'can intercept http protocol', (done) -> handler = (request, callback) -> callback(text) protocol.interceptStringProtocol 'http', handler, (error) -> + return done(error) if error $.ajax url: 'http://fake-host' success: (data) -> @@ -322,6 +342,7 @@ describe 'protocol module', -> handler = (request, callback) -> callback({mimeType: 'application/json', data: '{"value": 1}'}) protocol.interceptStringProtocol 'http', handler, (error) -> + return done(error) if error $.ajax url: 'http://fake-host' success: (data) -> @@ -335,6 +356,7 @@ describe 'protocol module', -> it 'can intercept http protocol', (done) -> handler = (request, callback) -> callback(new Buffer(text)) protocol.interceptBufferProtocol 'http', handler, (error) -> + return done(error) if error $.ajax url: 'http://fake-host' success: (data) -> From 984774773670fbbcf58f7bbed07cc3138a0a5cf1 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Wed, 28 Oct 2015 18:25:55 +0800 Subject: [PATCH 008/249] Use the callback converter in JsAsker --- atom/browser/net/js_asker.cc | 69 +++++------------------------------- 1 file changed, 9 insertions(+), 60 deletions(-) diff --git a/atom/browser/net/js_asker.cc b/atom/browser/net/js_asker.cc index d838ae39638f..444124b24b61 100644 --- a/atom/browser/net/js_asker.cc +++ b/atom/browser/net/js_asker.cc @@ -8,7 +8,6 @@ #include "atom/common/native_mate_converters/callback.h" #include "atom/common/native_mate_converters/v8_value_converter.h" -#include "native_mate/function_template.h" namespace atom { @@ -16,18 +15,12 @@ namespace internal { namespace { -struct CallbackHolder { - ResponseCallback callback; -}; - -// Cached JavaScript version of |HandlerCallback|. -v8::Persistent g_handler_callback_; - // The callback which is passed to |handler|. -void HandlerCallback(v8::Isolate* isolate, - v8::Local external, +void HandlerCallback(const ResponseCallback& callback, v8::Local state, mate::Arguments* args) { + v8::Isolate* isolate = args->isolate(); + // Check if the callback has already been called. v8::Local called_symbol = mate::StringToSymbol(isolate, "called"); if (state->Has(called_symbol)) @@ -36,14 +29,11 @@ void HandlerCallback(v8::Isolate* isolate, state->Set(called_symbol, v8::Boolean::New(isolate, true)); // If there is no argument passed then we failed. - scoped_ptr holder( - static_cast(external->Value())); - CHECK(holder); v8::Local value; if (!args->GetNext(&value)) { content::BrowserThread::PostTask( content::BrowserThread::IO, FROM_HERE, - base::Bind(holder->callback, false, nullptr)); + base::Bind(callback, false, nullptr)); return; } @@ -53,42 +43,7 @@ void HandlerCallback(v8::Isolate* isolate, scoped_ptr options(converter.FromV8Value(value, context)); content::BrowserThread::PostTask( content::BrowserThread::IO, FROM_HERE, - base::Bind(holder->callback, true, base::Passed(&options))); -} - -// func.bind(func, arg1, arg2). -// NB(zcbenz): Using C++11 version crashes VS. -v8::Local BindFunctionWith(v8::Isolate* isolate, - v8::Local context, - v8::Local func, - v8::Local arg1, - v8::Local arg2) { - v8::MaybeLocal bind = func->Get(mate::StringToV8(isolate, "bind")); - CHECK(!bind.IsEmpty()); - v8::Local bind_func = - v8::Local::Cast(bind.ToLocalChecked()); - v8::Local converted[] = { func, arg1, arg2 }; - return bind_func->Call( - context, func, arraysize(converted), converted).ToLocalChecked(); -} - -// Generate the callback that will be passed to |handler|. -v8::MaybeLocal GenerateCallback(v8::Isolate* isolate, - v8::Local context, - const ResponseCallback& callback) { - // The FunctionTemplate is cached. - if (g_handler_callback_.IsEmpty()) - g_handler_callback_.Reset( - isolate, - mate::CreateFunctionTemplate(isolate, base::Bind(&HandlerCallback))); - - v8::Local handler_callback = - v8::Local::New(isolate, g_handler_callback_); - CallbackHolder* holder = new CallbackHolder; - holder->callback = callback; - return BindFunctionWith(isolate, context, handler_callback->GetFunction(), - v8::External::New(isolate, holder), - v8::Object::New(isolate)); + base::Bind(callback, true, base::Passed(&options))); } } // namespace @@ -102,16 +57,10 @@ void AskForOptions(v8::Isolate* isolate, v8::HandleScope handle_scope(isolate); v8::Local context = isolate->GetCurrentContext(); v8::Context::Scope context_scope(context); - // We don't convert the callback to C++ directly because creating - // FunctionTemplate will cause memory leak since V8 never releases it. So we - // have to create the function object in JavaScript to work around it. - v8::MaybeLocal wrapped_callback = GenerateCallback( - isolate, context, callback); - if (wrapped_callback.IsEmpty()) { - callback.Run(false, nullptr); - return; - } - handler.Run(request, wrapped_callback.ToLocalChecked()); + v8::Local state = v8::Object::New(isolate); + handler.Run(request, + mate::ConvertToV8(isolate, + base::Bind(&HandlerCallback, callback, state))); } bool IsErrorOptions(base::Value* value, int* error) { From 54dad72d922d203e70878803dc9b75ead2ce3600 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Wed, 28 Oct 2015 18:32:21 +0800 Subject: [PATCH 009/249] Don't leak TranslaterHolder --- atom/common/native_mate_converters/callback.cc | 9 +++++---- atom/common/native_mate_converters/callback.h | 11 +++-------- 2 files changed, 8 insertions(+), 12 deletions(-) diff --git a/atom/common/native_mate_converters/callback.cc b/atom/common/native_mate_converters/callback.cc index 0be90f63e757..dbfa3b4babef 100644 --- a/atom/common/native_mate_converters/callback.cc +++ b/atom/common/native_mate_converters/callback.cc @@ -4,21 +4,22 @@ #include "atom/common/native_mate_converters/callback.h" +#include "native_mate/wrappable.h" + namespace mate { namespace internal { namespace { -struct TranslaterHolder { +struct TranslaterHolder : public Wrappable { Translater translater; }; // Cached JavaScript version of |CallTranslater|. v8::Persistent g_call_translater; -void CallTranslater(v8::Local external, mate::Arguments* args) { - TranslaterHolder* holder = static_cast(external->Value()); +void CallTranslater(TranslaterHolder* holder, mate::Arguments* args) { holder->translater.Run(args); } @@ -54,7 +55,7 @@ v8::Local CreateFunctionFromTranslater( return BindFunctionWith(isolate, isolate->GetCurrentContext(), call_translater->GetFunction(), - v8::External::New(isolate, holder)); + holder->GetWrapper(isolate)); } } // namespace internal diff --git a/atom/common/native_mate_converters/callback.h b/atom/common/native_mate_converters/callback.h index 4349b9997b25..228fc0d3bb1d 100644 --- a/atom/common/native_mate_converters/callback.h +++ b/atom/common/native_mate_converters/callback.h @@ -101,21 +101,16 @@ struct NativeFunctionInvoker { } }; -// Create a static function that accepts generic callback. -template -Translater ConvertToTranslater(const base::Callback& val) { - return base::Bind(&NativeFunctionInvoker::Go, val); -} - } // namespace internal template -struct Converter > { +struct Converter> { static v8::Local ToV8(v8::Isolate* isolate, const base::Callback& val) { // We don't use CreateFunctionTemplate here because it creates a new // FunctionTemplate everytime, which is cached by V8 and causes leaks. - internal::Translater translater = internal::ConvertToTranslater(val); + internal::Translater translater = base::Bind( + &internal::NativeFunctionInvoker::Go, val); return internal::CreateFunctionFromTranslater(isolate, translater); } static bool FromV8(v8::Isolate* isolate, From d05255179a6b451041472354066f847384dfe787 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Wed, 28 Oct 2015 19:34:01 +0800 Subject: [PATCH 010/249] Add login event for "app" module --- atom/browser/api/atom_api_app.cc | 25 +++++++++++--- atom/browser/api/atom_api_app.h | 1 + atom/browser/browser.cc | 4 +++ atom/browser/browser.h | 5 +++ atom/browser/browser_observer.h | 5 +++ atom/browser/login_handler.cc | 59 +++++++++++++++++++++++++++++++- atom/browser/login_handler.h | 15 ++++++-- 7 files changed, 106 insertions(+), 8 deletions(-) diff --git a/atom/browser/api/atom_api_app.cc b/atom/browser/api/atom_api_app.cc index c79dea9f7c5c..436d76fb9022 100644 --- a/atom/browser/api/atom_api_app.cc +++ b/atom/browser/api/atom_api_app.cc @@ -13,10 +13,11 @@ #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" #include "atom/browser/atom_browser_context.h" #include "atom/browser/atom_browser_main_parts.h" #include "atom/browser/browser.h" -#include "atom/browser/api/atom_api_web_contents.h" +#include "atom/browser/login_handler.h" #include "atom/common/native_mate_converters/callback.h" #include "atom/common/native_mate_converters/file_path_converter.h" #include "atom/common/node_includes.h" @@ -132,8 +133,6 @@ void OnClientCertificateSelected( v8::Isolate* isolate, std::shared_ptr delegate, mate::Arguments* args) { - v8::Locker locker(isolate); - v8::HandleScope handle_scope(isolate); mate::Dictionary cert_data; if (!(args->Length() == 1 && args->GetNext(&cert_data))) { args->ThrowError(); @@ -147,10 +146,18 @@ void OnClientCertificateSelected( net::X509Certificate::CreateCertificateListFromBytes( encoded_data.data(), encoded_data.size(), net::X509Certificate::FORMAT_AUTO); - delegate->ContinueWithCertificate(certs[0].get()); } +void PassLoginInformation(scoped_refptr login_handler, + mate::Arguments* args) { + base::string16 username, password; + if (args->GetNext(&username) && args->GetNext(&password)) + login_handler->Login(username, password); + else + login_handler->CancelAuth(); +} + } // namespace App::App() { @@ -233,6 +240,16 @@ void App::OnSelectCertificate( cert_request_info->client_certs[0].get()); } +void App::OnLogin(LoginHandler* login_handler) { + bool prevent_default = + Emit("login", base::Bind(&PassLoginInformation, + make_scoped_refptr(login_handler))); + + // Default behavior is to alwasy cancel the auth. + if (!prevent_default) + login_handler->CancelAuth(); +} + void App::OnGpuProcessCrashed(base::TerminationStatus exit_code) { Emit("gpu-process-crashed"); } diff --git a/atom/browser/api/atom_api_app.h b/atom/browser/api/atom_api_app.h index 94cd9bbc68f9..63cda4447e32 100644 --- a/atom/browser/api/atom_api_app.h +++ b/atom/browser/api/atom_api_app.h @@ -50,6 +50,7 @@ class App : public mate::EventEmitter, content::WebContents* web_contents, net::SSLCertRequestInfo* cert_request_info, scoped_ptr delegate) override; + void OnLogin(LoginHandler* login_handler) override; // content::GpuDataManagerObserver: void OnGpuProcessCrashed(base::TerminationStatus exit_code) override; diff --git a/atom/browser/browser.cc b/atom/browser/browser.cc index 79ebe91a87e6..739921fda90f 100644 --- a/atom/browser/browser.cc +++ b/atom/browser/browser.cc @@ -134,6 +134,10 @@ void Browser::ClientCertificateSelector( delegate.Pass())); } +void Browser::RequestLogin(LoginHandler* login_handler) { + FOR_EACH_OBSERVER(BrowserObserver, observers_, OnLogin(login_handler)); +} + void Browser::NotifyAndShutdown() { if (is_shutdown_) return; diff --git a/atom/browser/browser.h b/atom/browser/browser.h index bae281d4d370..8719e18f3140 100644 --- a/atom/browser/browser.h +++ b/atom/browser/browser.h @@ -29,6 +29,8 @@ class MenuModel; namespace atom { +class LoginHandler; + // This class is used for control application-wide operations. class Browser : public WindowListObserver { public: @@ -122,6 +124,9 @@ class Browser : public WindowListObserver { net::SSLCertRequestInfo* cert_request_info, scoped_ptr delegate); + // Request basic auth login. + void RequestLogin(LoginHandler* login_handler); + void AddObserver(BrowserObserver* obs) { observers_.AddObserver(obs); } diff --git a/atom/browser/browser_observer.h b/atom/browser/browser_observer.h index 45e86e620f84..7dccbfbac3c5 100644 --- a/atom/browser/browser_observer.h +++ b/atom/browser/browser_observer.h @@ -20,6 +20,8 @@ class SSLCertRequestInfo; namespace atom { +class LoginHandler; + class BrowserObserver { public: // The browser is about to close all windows. @@ -57,6 +59,9 @@ class BrowserObserver { net::SSLCertRequestInfo* cert_request_info, scoped_ptr delegate) {} + // The browser requests HTTP login. + virtual void OnLogin(LoginHandler* login_handler) {} + protected: virtual ~BrowserObserver() {} }; diff --git a/atom/browser/login_handler.cc b/atom/browser/login_handler.cc index 1980cc133abc..ededcd0c8513 100644 --- a/atom/browser/login_handler.cc +++ b/atom/browser/login_handler.cc @@ -4,19 +4,76 @@ #include "atom/browser/login_handler.h" +#include "atom/browser/browser.h" +#include "content/public/browser/browser_thread.h" +#include "content/public/browser/resource_dispatcher_host.h" #include "net/base/auth.h" +#include "net/url_request/url_request.h" + +using content::BrowserThread; namespace atom { +namespace { + +// Helper to remove the ref from an net::URLRequest to the LoginHandler. +// Should only be called from the IO thread, since it accesses an +// net::URLRequest. +void ResetLoginHandlerForRequest(net::URLRequest* request) { + content::ResourceDispatcherHost::Get()->ClearLoginDelegateForRequest(request); +} + +} // namespace + LoginHandler::LoginHandler(net::AuthChallengeInfo* auth_info, net::URLRequest* request) - : auth_info_(auth_info), request_(request), weak_factory_(this) { + : auth_info_(auth_info), request_(request) { + BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, + base::Bind(&Browser::RequestLogin, + base::Unretained(Browser::Get()), + make_scoped_refptr(this))); } LoginHandler::~LoginHandler() { } +void LoginHandler::Login(const base::string16& username, + const base::string16& password) { + DCHECK_CURRENTLY_ON(BrowserThread::UI); + BrowserThread::PostTask( + BrowserThread::IO, FROM_HERE, + base::Bind(&LoginHandler::DoLogin, this, username, password)); +} + +void LoginHandler::CancelAuth() { + DCHECK_CURRENTLY_ON(BrowserThread::UI); + BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, + base::Bind(&LoginHandler::DoCancelAuth, this)); +} + void LoginHandler::OnRequestCancelled() { + request_ = nullptr; +} + +void LoginHandler::DoCancelAuth() { + DCHECK_CURRENTLY_ON(BrowserThread::IO); + + if (request_) { + request_->CancelAuth(); + // Verify that CancelAuth doesn't destroy the request via our delegate. + DCHECK(request_ != nullptr); + ResetLoginHandlerForRequest(request_); + } +} + +void LoginHandler::DoLogin(const base::string16& username, + const base::string16& password) { + DCHECK_CURRENTLY_ON(BrowserThread::IO); + + if (request_) { + request_->SetAuth(net::AuthCredentials(username, password)); + ResetLoginHandlerForRequest(request_); + } } } // namespace atom diff --git a/atom/browser/login_handler.h b/atom/browser/login_handler.h index 421e2e43837d..077e4b6cf950 100644 --- a/atom/browser/login_handler.h +++ b/atom/browser/login_handler.h @@ -5,7 +5,7 @@ #ifndef ATOM_BROWSER_LOGIN_HANDLER_H_ #define ATOM_BROWSER_LOGIN_HANDLER_H_ -#include "base/memory/weak_ptr.h" +#include "base/strings/string16.h" #include "content/public/browser/resource_dispatcher_host_login_delegate.h" namespace net { @@ -15,10 +15,17 @@ class URLRequest; namespace atom { +// Handles the HTTP basic auth, must be created on IO thread. class LoginHandler : public content::ResourceDispatcherHostLoginDelegate { public: LoginHandler(net::AuthChallengeInfo* auth_info, net::URLRequest* request); + // The auth is cancelled, must be called on UI thread. + void CancelAuth(); + + // Login with |username| and |password|, must be called on UI thread. + void Login(const base::string16& username, const base::string16& password); + protected: ~LoginHandler() override; @@ -26,6 +33,10 @@ class LoginHandler : public content::ResourceDispatcherHostLoginDelegate { void OnRequestCancelled() override; private: + // Must be called on IO thread. + void DoCancelAuth(); + void DoLogin(const base::string16& username, const base::string16& password); + // Who/where/what asked for the authentication. scoped_refptr auth_info_; @@ -33,8 +44,6 @@ class LoginHandler : public content::ResourceDispatcherHostLoginDelegate { // This should only be accessed on the IO loop. net::URLRequest* request_; - base::WeakPtrFactory weak_factory_; - DISALLOW_COPY_AND_ASSIGN(LoginHandler); }; From 131531219e172f70d374f315b7301a7c2b1e93f9 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Wed, 28 Oct 2015 20:13:06 +0800 Subject: [PATCH 011/249] Pass auth_info and request in "login" event --- atom/browser/api/atom_api_app.cc | 7 ++-- atom/browser/api/atom_api_protocol.cc | 17 +--------- atom/browser/login_handler.h | 3 ++ .../content_converter.cc | 34 +++++++++++++++++++ .../content_converter.h | 31 +++++++++++++++++ filenames.gypi | 2 ++ 6 files changed, 75 insertions(+), 19 deletions(-) create mode 100644 atom/common/native_mate_converters/content_converter.cc create mode 100644 atom/common/native_mate_converters/content_converter.h diff --git a/atom/browser/api/atom_api_app.cc b/atom/browser/api/atom_api_app.cc index 436d76fb9022..db1f99352309 100644 --- a/atom/browser/api/atom_api_app.cc +++ b/atom/browser/api/atom_api_app.cc @@ -19,6 +19,7 @@ #include "atom/browser/browser.h" #include "atom/browser/login_handler.h" #include "atom/common/native_mate_converters/callback.h" +#include "atom/common/native_mate_converters/content_converter.h" #include "atom/common/native_mate_converters/file_path_converter.h" #include "atom/common/node_includes.h" #include "atom/common/options_switches.h" @@ -241,9 +242,9 @@ void App::OnSelectCertificate( } void App::OnLogin(LoginHandler* login_handler) { - bool prevent_default = - Emit("login", base::Bind(&PassLoginInformation, - make_scoped_refptr(login_handler))); + bool prevent_default = Emit( + "login", login_handler->request(), login_handler->auth_info(), + base::Bind(&PassLoginInformation, make_scoped_refptr(login_handler))); // Default behavior is to alwasy cancel the auth. if (!prevent_default) diff --git a/atom/browser/api/atom_api_protocol.cc b/atom/browser/api/atom_api_protocol.cc index 661ab1b5cbdd..f6cc6d796557 100644 --- a/atom/browser/api/atom_api_protocol.cc +++ b/atom/browser/api/atom_api_protocol.cc @@ -12,27 +12,12 @@ #include "atom/browser/net/url_request_fetch_job.h" #include "atom/browser/net/url_request_string_job.h" #include "atom/common/native_mate_converters/callback.h" +#include "atom/common/native_mate_converters/content_converter.h" #include "atom/common/node_includes.h" #include "native_mate/dictionary.h" using content::BrowserThread; -namespace mate { - -template<> -struct Converter { - static v8::Local ToV8(v8::Isolate* isolate, - const net::URLRequest* val) { - return mate::ObjectTemplateBuilder(isolate) - .SetValue("method", val->method()) - .SetValue("url", val->url().spec()) - .SetValue("referrer", val->referrer()) - .Build()->NewInstance(); - } -}; - -} // namespace mate - namespace atom { namespace api { diff --git a/atom/browser/login_handler.h b/atom/browser/login_handler.h index 077e4b6cf950..60e0a7a5298d 100644 --- a/atom/browser/login_handler.h +++ b/atom/browser/login_handler.h @@ -26,6 +26,9 @@ class LoginHandler : public content::ResourceDispatcherHostLoginDelegate { // Login with |username| and |password|, must be called on UI thread. void Login(const base::string16& username, const base::string16& password); + const net::AuthChallengeInfo* auth_info() const { return auth_info_.get(); } + const net::URLRequest* request() const { return request_; } + protected: ~LoginHandler() override; diff --git a/atom/common/native_mate_converters/content_converter.cc b/atom/common/native_mate_converters/content_converter.cc new file mode 100644 index 000000000000..0ab9f272041e --- /dev/null +++ b/atom/common/native_mate_converters/content_converter.cc @@ -0,0 +1,34 @@ +// Copyright (c) 2015 GitHub, Inc. +// Use of this source code is governed by the MIT license that can be +// found in the LICENSE file. + +#include "atom/common/native_mate_converters/content_converter.h" + +#include "native_mate/dictionary.h" +#include "net/url_request/url_request.h" + +namespace mate { + +// static +v8::Local Converter::ToV8( + v8::Isolate* isolate, const net::URLRequest* val) { + mate::Dictionary dict = mate::Dictionary::CreateEmpty(isolate); + dict.Set("method", val->method()); + dict.Set("url", val->url().spec()); + dict.Set("referrer", val->referrer()); + return mate::ConvertToV8(isolate, dict); +}; + +// static +v8::Local Converter::ToV8( + v8::Isolate* isolate, const net::AuthChallengeInfo* val) { + mate::Dictionary dict = mate::Dictionary::CreateEmpty(isolate); + dict.Set("isProxy", val->is_proxy); + dict.Set("scheme", val->scheme); + dict.Set("host", val->challenger.host()); + dict.Set("port", static_cast(val->challenger.port())); + dict.Set("realm", val->realm); + return mate::ConvertToV8(isolate, dict); +}; + +} // namespace mate diff --git a/atom/common/native_mate_converters/content_converter.h b/atom/common/native_mate_converters/content_converter.h new file mode 100644 index 000000000000..0d4d5fe2cce0 --- /dev/null +++ b/atom/common/native_mate_converters/content_converter.h @@ -0,0 +1,31 @@ +// Copyright (c) 2015 GitHub, Inc. +// Use of this source code is governed by the MIT license that can be +// found in the LICENSE file. + +#ifndef ATOM_COMMON_NATIVE_MATE_CONVERTERS_CONTENT_CONVERTER_H_ +#define ATOM_COMMON_NATIVE_MATE_CONVERTERS_CONTENT_CONVERTER_H_ + +#include "native_mate/converter.h" + +namespace net { +class AuthChallengeInfo; +class URLRequest; +} + +namespace mate { + +template<> +struct Converter { + static v8::Local ToV8(v8::Isolate* isolate, + const net::URLRequest* val); +}; + +template<> +struct Converter { + static v8::Local ToV8(v8::Isolate* isolate, + const net::AuthChallengeInfo* val); +}; + +} // namespace mate + +#endif // ATOM_COMMON_NATIVE_MATE_CONVERTERS_CONTENT_CONVERTER_H_ diff --git a/filenames.gypi b/filenames.gypi index 65bf6b79a2c2..f66485edd19d 100644 --- a/filenames.gypi +++ b/filenames.gypi @@ -306,6 +306,8 @@ 'atom/common/native_mate_converters/blink_converter.h', 'atom/common/native_mate_converters/callback.cc', 'atom/common/native_mate_converters/callback.h', + 'atom/common/native_mate_converters/content_converter.cc', + 'atom/common/native_mate_converters/content_converter.h', 'atom/common/native_mate_converters/file_path_converter.h', 'atom/common/native_mate_converters/gfx_converter.cc', 'atom/common/native_mate_converters/gfx_converter.h', From 4eac6b31b15c0a5df839be3c2f4238eef065b453 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Wed, 28 Oct 2015 20:21:56 +0800 Subject: [PATCH 012/249] Also pass "webContents" in "login" event --- atom/browser/api/atom_api_app.cc | 1 + atom/browser/login_handler.cc | 18 +++++++++++++++++- atom/browser/login_handler.h | 12 ++++++++++++ .../content_converter.cc | 4 ++-- 4 files changed, 32 insertions(+), 3 deletions(-) diff --git a/atom/browser/api/atom_api_app.cc b/atom/browser/api/atom_api_app.cc index db1f99352309..5380d52ad693 100644 --- a/atom/browser/api/atom_api_app.cc +++ b/atom/browser/api/atom_api_app.cc @@ -244,6 +244,7 @@ void App::OnSelectCertificate( void App::OnLogin(LoginHandler* login_handler) { bool prevent_default = Emit( "login", login_handler->request(), login_handler->auth_info(), + api::WebContents::CreateFrom(isolate(), login_handler->GetWebContents()), base::Bind(&PassLoginInformation, make_scoped_refptr(login_handler))); // Default behavior is to alwasy cancel the auth. diff --git a/atom/browser/login_handler.cc b/atom/browser/login_handler.cc index ededcd0c8513..ca6e5de57df0 100644 --- a/atom/browser/login_handler.cc +++ b/atom/browser/login_handler.cc @@ -6,7 +6,10 @@ #include "atom/browser/browser.h" #include "content/public/browser/browser_thread.h" +#include "content/public/browser/render_frame_host.h" #include "content/public/browser/resource_dispatcher_host.h" +#include "content/public/browser/resource_request_info.h" +#include "content/public/browser/web_contents.h" #include "net/base/auth.h" #include "net/url_request/url_request.h" @@ -27,7 +30,12 @@ void ResetLoginHandlerForRequest(net::URLRequest* request) { LoginHandler::LoginHandler(net::AuthChallengeInfo* auth_info, net::URLRequest* request) - : auth_info_(auth_info), request_(request) { + : auth_info_(auth_info), + request_(request), + render_process_host_id_(0), + render_frame_id_(0) { + content::ResourceRequestInfo::ForRequest(request_)->GetAssociatedRenderFrame( + &render_process_host_id_, &render_frame_id_); BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, base::Bind(&Browser::RequestLogin, base::Unretained(Browser::Get()), @@ -37,6 +45,14 @@ LoginHandler::LoginHandler(net::AuthChallengeInfo* auth_info, LoginHandler::~LoginHandler() { } +content::WebContents* LoginHandler::GetWebContents() const { + DCHECK_CURRENTLY_ON(BrowserThread::UI); + + content::RenderFrameHost* rfh = content::RenderFrameHost::FromID( + render_process_host_id_, render_frame_id_); + return content::WebContents::FromRenderFrameHost(rfh); +} + void LoginHandler::Login(const base::string16& username, const base::string16& password) { DCHECK_CURRENTLY_ON(BrowserThread::UI); diff --git a/atom/browser/login_handler.h b/atom/browser/login_handler.h index 60e0a7a5298d..899bc8ca450e 100644 --- a/atom/browser/login_handler.h +++ b/atom/browser/login_handler.h @@ -8,6 +8,10 @@ #include "base/strings/string16.h" #include "content/public/browser/resource_dispatcher_host_login_delegate.h" +namespace content { +class WebContents; +} + namespace net { class AuthChallengeInfo; class URLRequest; @@ -20,6 +24,10 @@ class LoginHandler : public content::ResourceDispatcherHostLoginDelegate { public: LoginHandler(net::AuthChallengeInfo* auth_info, net::URLRequest* request); + // Returns the WebContents associated with the request, must be called on UI + // thread. + content::WebContents* GetWebContents() const; + // The auth is cancelled, must be called on UI thread. void CancelAuth(); @@ -47,6 +55,10 @@ class LoginHandler : public content::ResourceDispatcherHostLoginDelegate { // This should only be accessed on the IO loop. net::URLRequest* request_; + // Cached from the net::URLRequest, in case it goes NULL on us. + int render_process_host_id_; + int render_frame_id_; + DISALLOW_COPY_AND_ASSIGN(LoginHandler); }; diff --git a/atom/common/native_mate_converters/content_converter.cc b/atom/common/native_mate_converters/content_converter.cc index 0ab9f272041e..b6f3a2c1cc03 100644 --- a/atom/common/native_mate_converters/content_converter.cc +++ b/atom/common/native_mate_converters/content_converter.cc @@ -17,7 +17,7 @@ v8::Local Converter::ToV8( dict.Set("url", val->url().spec()); dict.Set("referrer", val->referrer()); return mate::ConvertToV8(isolate, dict); -}; +} // static v8::Local Converter::ToV8( @@ -29,6 +29,6 @@ v8::Local Converter::ToV8( dict.Set("port", static_cast(val->challenger.port())); dict.Set("realm", val->realm); return mate::ConvertToV8(isolate, dict); -}; +} } // namespace mate From f40a3f72d72dc9659dce0208abd298f4253a183a Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Wed, 28 Oct 2015 20:44:46 +0800 Subject: [PATCH 013/249] Converted callback can only be called for once --- atom/browser/net/js_asker.cc | 16 ++-------- .../common/native_mate_converters/callback.cc | 29 ++++++++++++++----- spec/api-protocol-spec.coffee | 12 +++++--- 3 files changed, 32 insertions(+), 25 deletions(-) diff --git a/atom/browser/net/js_asker.cc b/atom/browser/net/js_asker.cc index 444124b24b61..8f0d1d2b9577 100644 --- a/atom/browser/net/js_asker.cc +++ b/atom/browser/net/js_asker.cc @@ -16,18 +16,7 @@ namespace internal { namespace { // The callback which is passed to |handler|. -void HandlerCallback(const ResponseCallback& callback, - v8::Local state, - mate::Arguments* args) { - v8::Isolate* isolate = args->isolate(); - - // Check if the callback has already been called. - v8::Local called_symbol = mate::StringToSymbol(isolate, "called"); - if (state->Has(called_symbol)) - return; // no nothing - else - state->Set(called_symbol, v8::Boolean::New(isolate, true)); - +void HandlerCallback(const ResponseCallback& callback, mate::Arguments* args) { // If there is no argument passed then we failed. v8::Local value; if (!args->GetNext(&value)) { @@ -57,10 +46,9 @@ void AskForOptions(v8::Isolate* isolate, v8::HandleScope handle_scope(isolate); v8::Local context = isolate->GetCurrentContext(); v8::Context::Scope context_scope(context); - v8::Local state = v8::Object::New(isolate); handler.Run(request, mate::ConvertToV8(isolate, - base::Bind(&HandlerCallback, callback, state))); + base::Bind(&HandlerCallback, callback))); } bool IsErrorOptions(base::Value* value, int* error) { diff --git a/atom/common/native_mate_converters/callback.cc b/atom/common/native_mate_converters/callback.cc index dbfa3b4babef..3bcb748689fb 100644 --- a/atom/common/native_mate_converters/callback.cc +++ b/atom/common/native_mate_converters/callback.cc @@ -4,23 +4,36 @@ #include "atom/common/native_mate_converters/callback.h" -#include "native_mate/wrappable.h" - namespace mate { namespace internal { namespace { -struct TranslaterHolder : public Wrappable { +struct TranslaterHolder { Translater translater; }; // Cached JavaScript version of |CallTranslater|. v8::Persistent g_call_translater; -void CallTranslater(TranslaterHolder* holder, mate::Arguments* args) { +void CallTranslater(v8::Local external, + v8::Local state, + mate::Arguments* args) { + v8::Isolate* isolate = args->isolate(); + + // Check if the callback has already been called. + v8::Local called_symbol = mate::StringToSymbol(isolate, "called"); + if (state->Has(called_symbol)) { + args->ThrowError("callback can only be called for once"); + return; + } else { + state->Set(called_symbol, v8::Boolean::New(isolate, true)); + } + + TranslaterHolder* holder = static_cast(external->Value()); holder->translater.Run(args); + delete holder; } // func.bind(func, arg1). @@ -28,12 +41,13 @@ void CallTranslater(TranslaterHolder* holder, mate::Arguments* args) { v8::Local BindFunctionWith(v8::Isolate* isolate, v8::Local context, v8::Local func, - v8::Local arg1) { + v8::Local arg1, + v8::Local arg2) { v8::MaybeLocal bind = func->Get(mate::StringToV8(isolate, "bind")); CHECK(!bind.IsEmpty()); v8::Local bind_func = v8::Local::Cast(bind.ToLocalChecked()); - v8::Local converted[] = { func, arg1 }; + v8::Local converted[] = { func, arg1, arg2 }; return bind_func->Call( context, func, arraysize(converted), converted).ToLocalChecked(); } @@ -55,7 +69,8 @@ v8::Local CreateFunctionFromTranslater( return BindFunctionWith(isolate, isolate->GetCurrentContext(), call_translater->GetFunction(), - holder->GetWrapper(isolate)); + v8::External::New(isolate, holder), + v8::Object::New(isolate)); } } // namespace internal diff --git a/spec/api-protocol-spec.coffee b/spec/api-protocol-spec.coffee index 8990f8029ee1..4ac7786b057b 100644 --- a/spec/api-protocol-spec.coffee +++ b/spec/api-protocol-spec.coffee @@ -23,8 +23,10 @@ describe 'protocol module', -> it 'does not crash when handler is called twice', (done) -> doubleHandler = (request, callback) -> - callback(text) - callback() + try + callback(text) + callback() + catch protocol.registerStringProtocol protocolName, doubleHandler, (error) -> return done(error) if error $.ajax @@ -302,8 +304,10 @@ describe 'protocol module', -> it 'does not crash when handler is called twice', (done) -> doubleHandler = (request, callback) -> - callback(text) - callback() + try + callback(text) + callback() + catch protocol.interceptStringProtocol 'http', doubleHandler, (error) -> return done(error) if error $.ajax From 569e87035add289e89a80e1aa74363dd85a964c0 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Wed, 28 Oct 2015 21:00:39 +0800 Subject: [PATCH 014/249] Also emit "login" on WebContents --- atom/browser/api/atom_api_app.cc | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/atom/browser/api/atom_api_app.cc b/atom/browser/api/atom_api_app.cc index 5380d52ad693..21a553e4d1d5 100644 --- a/atom/browser/api/atom_api_app.cc +++ b/atom/browser/api/atom_api_app.cc @@ -242,12 +242,26 @@ void App::OnSelectCertificate( } void App::OnLogin(LoginHandler* login_handler) { - bool prevent_default = Emit( - "login", login_handler->request(), login_handler->auth_info(), - api::WebContents::CreateFrom(isolate(), login_handler->GetWebContents()), + // 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))); - // Default behavior is to alwasy cancel the auth. + 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(); } From 862c3187f58daae649d9c360147025e9f5909279 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Wed, 28 Oct 2015 21:14:00 +0800 Subject: [PATCH 015/249] docs: login event --- docs/api/app.md | 47 +++++++++++++++++++++++++++++++++------- docs/api/web-contents.md | 21 ++++++++++++++++++ 2 files changed, 60 insertions(+), 8 deletions(-) diff --git a/docs/api/app.md b/docs/api/app.md index bb1509b68688..dbb46698f926 100644 --- a/docs/api/app.md +++ b/docs/api/app.md @@ -133,18 +133,23 @@ Emitted when a new [browserWindow](browser-window.md) is created. ### Event: 'select-certificate' -Emitted when a client certificate is requested. - Returns: * `event` Event -* `webContents` [WebContents](browser-window.md#class-webcontents) -* `url` String +* `webContents` [WebContents](web-contents.md) +* `url` URL * `certificateList` [Objects] * `data` PEM encoded data * `issuerName` Issuer's Common Name * `callback` Function +Emitted when a client certificate is requested. + +The `url` corresponds to the navigation entry requesting the client certificate +and `callback` needs to be called with an entry filtered from the list. Using +`event.preventDefault()` prevents the application from using the first +certificate from the store. + ```javascript app.on('select-certificate', function(event, host, url, list, callback) { event.preventDefault(); @@ -152,10 +157,36 @@ app.on('select-certificate', function(event, host, url, list, callback) { }) ``` -The `url` corresponds to the navigation entry requesting the client certificate -and `callback` needs to be called with an entry filtered from the list. Using -`event.preventDefault()` prevents the application from using the first -certificate from the store. +### Event: 'login' + +Returns: + +* `event` Event +* `webContents` [WebContents](web-contents.md) +* `request` Object + * `method` String + * `url` URL + * `referrer` URL +* `authInfo` Object + * `isProxy` Boolean + * `scheme` String + * `host` String + * `port` Integer + * `realm` String +* `callback` Function + +Emitted when `webContents` wants to do basic auth. + +The default behavior is to cancel all authentications, to override this you +should prevent the default behavior with `event.preventDefault()` and call +`callback(username, password)` with the credentials. + +```javascript +app.on('login', function(event, webContents, request, authInfo, callback) { + event.preventDefault(); + callback('username', 'secret'); +}) +``` ### Event: 'gpu-process-crashed' diff --git a/docs/api/web-contents.md b/docs/api/web-contents.md index 3113356e34b4..52a06b87edb1 100644 --- a/docs/api/web-contents.md +++ b/docs/api/web-contents.md @@ -167,6 +167,27 @@ Emitted when DevTools is closed. Emitted when DevTools is focused / opened. +### Event: 'login' + +Returns: + +* `event` Event +* `request` Object + * `method` String + * `url` URL + * `referrer` URL +* `authInfo` Object + * `isProxy` Boolean + * `scheme` String + * `host` String + * `port` Integer + * `realm` String +* `callback` Function + +Emitted when `webContents` wants to do basic auth. + +The usage is the same with [the `login` event of `app`](app.md#event-login). + ## Instance Methods The `webContents` object has the following instance methods: From 51ba37440d9008ed4a0cb5293ec15d3331367017 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Wed, 28 Oct 2015 21:20:08 +0800 Subject: [PATCH 016/249] Guard against multiple calls of auth --- atom/browser/login_handler.cc | 16 +++++++++++++++- atom/browser/login_handler.h | 9 +++++++++ 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/atom/browser/login_handler.cc b/atom/browser/login_handler.cc index ca6e5de57df0..7a1a77cc2b13 100644 --- a/atom/browser/login_handler.cc +++ b/atom/browser/login_handler.cc @@ -30,7 +30,8 @@ void ResetLoginHandlerForRequest(net::URLRequest* request) { LoginHandler::LoginHandler(net::AuthChallengeInfo* auth_info, net::URLRequest* request) - : auth_info_(auth_info), + : handled_auth_(false), + auth_info_(auth_info), request_(request), render_process_host_id_(0), render_frame_id_(0) { @@ -56,6 +57,8 @@ content::WebContents* LoginHandler::GetWebContents() const { void LoginHandler::Login(const base::string16& username, const base::string16& password) { DCHECK_CURRENTLY_ON(BrowserThread::UI); + if (TestAndSetAuthHandled()) + return; BrowserThread::PostTask( BrowserThread::IO, FROM_HERE, base::Bind(&LoginHandler::DoLogin, this, username, password)); @@ -63,14 +66,25 @@ void LoginHandler::Login(const base::string16& username, void LoginHandler::CancelAuth() { DCHECK_CURRENTLY_ON(BrowserThread::UI); + if (TestAndSetAuthHandled()) + return; BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, base::Bind(&LoginHandler::DoCancelAuth, this)); } void LoginHandler::OnRequestCancelled() { + TestAndSetAuthHandled(); request_ = nullptr; } +// Marks authentication as handled and returns the previous handled state. +bool LoginHandler::TestAndSetAuthHandled() { + base::AutoLock lock(handled_auth_lock_); + bool was_handled = handled_auth_; + handled_auth_ = true; + return was_handled; +} + void LoginHandler::DoCancelAuth() { DCHECK_CURRENTLY_ON(BrowserThread::IO); diff --git a/atom/browser/login_handler.h b/atom/browser/login_handler.h index 899bc8ca450e..52ec1abf5b1a 100644 --- a/atom/browser/login_handler.h +++ b/atom/browser/login_handler.h @@ -6,6 +6,7 @@ #define ATOM_BROWSER_LOGIN_HANDLER_H_ #include "base/strings/string16.h" +#include "base/synchronization/lock.h" #include "content/public/browser/resource_dispatcher_host_login_delegate.h" namespace content { @@ -48,6 +49,14 @@ class LoginHandler : public content::ResourceDispatcherHostLoginDelegate { void DoCancelAuth(); void DoLogin(const base::string16& username, const base::string16& password); + // Marks authentication as handled and returns the previous handled + // state. + bool TestAndSetAuthHandled(); + + // True if we've handled auth (Login or CancelAuth has been called). + bool handled_auth_; + mutable base::Lock handled_auth_lock_; + // Who/where/what asked for the authentication. scoped_refptr auth_info_; From 974b5005bcf21055280b5a1caf8563fb9a572b69 Mon Sep 17 00:00:00 2001 From: Antoine Pairet Date: Wed, 28 Oct 2015 14:28:30 +0100 Subject: [PATCH 017/249] Update from @jlord --- docs/api/remote.md | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/docs/api/remote.md b/docs/api/remote.md index 14805923562c..aa7114e278ee 100644 --- a/docs/api/remote.md +++ b/docs/api/remote.md @@ -3,12 +3,7 @@ The `remote` module provides a simple way to do inter-process communication (IPC) between the renderer process (web page) and the main process. -In Electron, only GUI-related modules are available in the renderer process. -Without the `remote` module, users who want to call a main process API in -the renderer process will have to explicitly send inter-process messages -to the main process. With the `remote` module, you can invoke methods of the -main process object without explicitly sending inter-process messages, similar -to Java's [RMI](http://en.wikipedia.org/wiki/Java_remote_method_invocation). +In Electron, GUI-related modules (such as `dialog`, `menu` etc.) are only available in the main process, not in the renderer process. In order to use them from the render process, the ipc module is necessary to send inter-process messages to the main process. With the `remote` module, you can invoke methods of the main process object without explicitly sending inter-process messages, similar to Java's [RMI](http://en.wikipedia.org/wiki/Java_remote_method_invocation). An example of creating a browser window from a renderer process: From 4efff0800716262d69f24494ef4cff38358746d8 Mon Sep 17 00:00:00 2001 From: Antoine Pairet Date: Wed, 28 Oct 2015 17:55:18 +0100 Subject: [PATCH 018/249] Fix comments from @jlord --- docs/api/remote.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/api/remote.md b/docs/api/remote.md index aa7114e278ee..d80312c8e1a5 100644 --- a/docs/api/remote.md +++ b/docs/api/remote.md @@ -3,7 +3,7 @@ The `remote` module provides a simple way to do inter-process communication (IPC) between the renderer process (web page) and the main process. -In Electron, GUI-related modules (such as `dialog`, `menu` etc.) are only available in the main process, not in the renderer process. In order to use them from the render process, the ipc module is necessary to send inter-process messages to the main process. With the `remote` module, you can invoke methods of the main process object without explicitly sending inter-process messages, similar to Java's [RMI](http://en.wikipedia.org/wiki/Java_remote_method_invocation). +In Electron, GUI-related modules (such as `dialog`, `menu` etc.) are only available in the main process, not in the renderer process. In order to use them from the renderer process, the `ipc` module is necessary to send inter-process messages to the main process. With the `remote` module, you can invoke methods of the main process object without explicitly sending inter-process messages, similar to Java's [RMI](http://en.wikipedia.org/wiki/Java_remote_method_invocation). An example of creating a browser window from a renderer process: From 16eafdb0ce1bf1dd9a4f8590d15f2837515e2634 Mon Sep 17 00:00:00 2001 From: taemu Date: Thu, 29 Oct 2015 03:22:08 +0900 Subject: [PATCH 019/249] Fix remove boolean parameter at IsSwitchEnabled function --- atom/renderer/atom_renderer_client.cc | 38 ++++++++++----------------- 1 file changed, 14 insertions(+), 24 deletions(-) diff --git a/atom/renderer/atom_renderer_client.cc b/atom/renderer/atom_renderer_client.cc index 10dd2541b9cf..362b0b8026a7 100644 --- a/atom/renderer/atom_renderer_client.cc +++ b/atom/renderer/atom_renderer_client.cc @@ -39,16 +39,8 @@ namespace atom { namespace { bool IsSwitchEnabled(base::CommandLine* command_line, - const char* switch_string, - bool* enabled) { - std::string value = command_line->GetSwitchValueASCII(switch_string); - if (value == "true") - *enabled = true; - else if (value == "false") - *enabled = false; - else - return false; - return true; + const char* switch_string) { + return command_line->GetSwitchValueASCII(switch_string) == "true"; } // Helper class to forward the messages to the client. @@ -216,10 +208,8 @@ bool AtomRendererClient::ShouldOverridePageVisibilityState( const content::RenderFrame* render_frame, blink::WebPageVisibilityState* override_state) { base::CommandLine* command_line = base::CommandLine::ForCurrentProcess(); - bool b; - if (IsSwitchEnabled(command_line, switches::kPageVisibility, &b) - && b) { + if (IsSwitchEnabled(command_line, switches::kPageVisibility)) { *override_state = blink::WebPageVisibilityStateVisible; return true; } @@ -229,17 +219,17 @@ bool AtomRendererClient::ShouldOverridePageVisibilityState( void AtomRendererClient::EnableWebRuntimeFeatures() { base::CommandLine* command_line = base::CommandLine::ForCurrentProcess(); - bool b; - if (IsSwitchEnabled(command_line, switches::kExperimentalFeatures, &b)) - blink::WebRuntimeFeatures::enableExperimentalFeatures(b); - if (IsSwitchEnabled(command_line, switches::kExperimentalCanvasFeatures, &b)) - blink::WebRuntimeFeatures::enableExperimentalCanvasFeatures(b); - if (IsSwitchEnabled(command_line, switches::kOverlayScrollbars, &b)) - blink::WebRuntimeFeatures::enableOverlayScrollbars(b); - if (IsSwitchEnabled(command_line, switches::kOverlayFullscreenVideo, &b)) - blink::WebRuntimeFeatures::enableOverlayFullscreenVideo(b); - if (IsSwitchEnabled(command_line, switches::kSharedWorker, &b)) - blink::WebRuntimeFeatures::enableSharedWorker(b); + + if (IsSwitchEnabled(command_line, switches::kExperimentalFeatures)) + blink::WebRuntimeFeatures::enableExperimentalFeatures(true); + if (IsSwitchEnabled(command_line, switches::kExperimentalCanvasFeatures)) + blink::WebRuntimeFeatures::enableExperimentalCanvasFeatures(true); + if (IsSwitchEnabled(command_line, switches::kOverlayScrollbars)) + blink::WebRuntimeFeatures::enableOverlayScrollbars(true); + if (IsSwitchEnabled(command_line, switches::kOverlayFullscreenVideo)) + blink::WebRuntimeFeatures::enableOverlayFullscreenVideo(true); + if (IsSwitchEnabled(command_line, switches::kSharedWorker)) + blink::WebRuntimeFeatures::enableSharedWorker(true); } } // namespace atom From 2ac40cc28eb7160cc5493311f3945de3b90ace70 Mon Sep 17 00:00:00 2001 From: Omri Litov Date: Wed, 28 Oct 2015 21:30:52 +0200 Subject: [PATCH 020/249] Added .idea to .gitignore --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 0c6f4cb79dd0..b8a221c9e52f 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ .DS_Store +/.idea/ /build/ /dist/ /external_binaries/ From f22837523f1dd67b2eafd7f2e75a7ff185906f3c Mon Sep 17 00:00:00 2001 From: Omri Litov Date: Wed, 28 Oct 2015 21:54:50 +0200 Subject: [PATCH 021/249] Use WPARAM as uint64_t and LPARAM as int64_t --- atom/browser/api/atom_api_window.cc | 2 +- atom/browser/api/atom_api_window.h | 3 ++- atom/browser/native_window.cc | 3 ++- atom/browser/native_window_observer.h | 2 +- 4 files changed, 6 insertions(+), 4 deletions(-) diff --git a/atom/browser/api/atom_api_window.cc b/atom/browser/api/atom_api_window.cc index 077dffe0bc5c..bf0d0fad721c 100644 --- a/atom/browser/api/atom_api_window.cc +++ b/atom/browser/api/atom_api_window.cc @@ -190,7 +190,7 @@ void Window::OnExecuteWindowsCommand(const std::string& command_name) { } #if defined(OS_WIN) -void Window::OnWindowMessage(UINT message, WPARAM w_param, uint64_t l_param) { +void Window::OnWindowMessage(UINT message, uint64_t w_param, int64_t l_param) { if (IsWindowMessageHooked(message)) { messages_callback_map_[message].Run(w_param, l_param); } diff --git a/atom/browser/api/atom_api_window.h b/atom/browser/api/atom_api_window.h index f4bc4cdba01a..ea86150ae1e3 100644 --- a/atom/browser/api/atom_api_window.h +++ b/atom/browser/api/atom_api_window.h @@ -77,7 +77,8 @@ class Window : public mate::TrackableObject, void OnExecuteWindowsCommand(const std::string& command_name) override; #if defined(OS_WIN) - void OnWindowMessage(UINT message, WPARAM w_param, uint64_t l_param) override; + void OnWindowMessage(UINT message, uint64_t w_param, + int64_t l_param) override; #endif // mate::Wrappable: diff --git a/atom/browser/native_window.cc b/atom/browser/native_window.cc index 6e38f4028745..a1b6f95c3ac9 100644 --- a/atom/browser/native_window.cc +++ b/atom/browser/native_window.cc @@ -469,7 +469,8 @@ void NativeWindow::NotifyWindowMessage(UINT message, WPARAM w_param, LPARAM l_param) { FOR_EACH_OBSERVER( NativeWindowObserver, observers_, - OnWindowMessage(message, w_param, static_cast(l_param))); + OnWindowMessage(message, static_cast(w_param), + static_cast(l_param))); } #endif diff --git a/atom/browser/native_window_observer.h b/atom/browser/native_window_observer.h index 240a7277fa09..559d5f72a804 100644 --- a/atom/browser/native_window_observer.h +++ b/atom/browser/native_window_observer.h @@ -61,7 +61,7 @@ class NativeWindowObserver { // Called when window message received #if defined(OS_WIN) - virtual void OnWindowMessage(UINT message, WPARAM wparam, uint64_t lparam) {} + virtual void OnWindowMessage(UINT message, uint64_t wparam, int64_t lparam) {} #endif // Called when renderer is hung. From ef038257d194611852d13d057b88dd0ed814bc3f Mon Sep 17 00:00:00 2001 From: Omri Litov Date: Thu, 29 Oct 2015 03:00:44 +0200 Subject: [PATCH 022/249] Returns buffer instead of WPARAM and LPARAM --- atom/browser/api/atom_api_window.cc | 16 ++++++++++++++-- atom/browser/api/atom_api_window.h | 9 ++++++--- atom/browser/native_window.cc | 4 ++-- atom/browser/native_window_observer.h | 2 +- 4 files changed, 23 insertions(+), 8 deletions(-) diff --git a/atom/browser/api/atom_api_window.cc b/atom/browser/api/atom_api_window.cc index bf0d0fad721c..352b9284cf45 100644 --- a/atom/browser/api/atom_api_window.cc +++ b/atom/browser/api/atom_api_window.cc @@ -190,9 +190,21 @@ void Window::OnExecuteWindowsCommand(const std::string& command_name) { } #if defined(OS_WIN) -void Window::OnWindowMessage(UINT message, uint64_t w_param, int64_t l_param) { +v8::Local Window::ToBuffer(void* val, int size) { + auto buffer = node::Buffer::New(isolate(), static_cast(val), size); + + if (buffer.IsEmpty()) { + return v8::Null(isolate()); + } else { + return buffer.ToLocalChecked(); + } +} + +void Window::OnWindowMessage(UINT message, WPARAM w_param, LPARAM l_param) { if (IsWindowMessageHooked(message)) { - messages_callback_map_[message].Run(w_param, l_param); + messages_callback_map_[message].Run( + ToBuffer(static_cast(&w_param), sizeof(WPARAM)), + ToBuffer(static_cast(&l_param), sizeof(LPARAM))); } } #endif diff --git a/atom/browser/api/atom_api_window.h b/atom/browser/api/atom_api_window.h index ea86150ae1e3..ffbd9b63b40a 100644 --- a/atom/browser/api/atom_api_window.h +++ b/atom/browser/api/atom_api_window.h @@ -77,8 +77,8 @@ class Window : public mate::TrackableObject, void OnExecuteWindowsCommand(const std::string& command_name) override; #if defined(OS_WIN) - void OnWindowMessage(UINT message, uint64_t w_param, - int64_t l_param) override; + void OnWindowMessage(UINT message, WPARAM w_param, + LPARAM l_param) override; #endif // mate::Wrappable: @@ -150,7 +150,10 @@ class Window : public mate::TrackableObject, void SetAspectRatio(double aspect_ratio, mate::Arguments* args); #if defined(OS_WIN) - typedef base::Callback MessageCallback; + v8::Local ToBuffer(void* val, int size); + + typedef base::Callback, + v8::Local)> MessageCallback; typedef std::map MessageCallbackMap; MessageCallbackMap messages_callback_map_; diff --git a/atom/browser/native_window.cc b/atom/browser/native_window.cc index a1b6f95c3ac9..bf400dc8c74e 100644 --- a/atom/browser/native_window.cc +++ b/atom/browser/native_window.cc @@ -469,8 +469,8 @@ void NativeWindow::NotifyWindowMessage(UINT message, WPARAM w_param, LPARAM l_param) { FOR_EACH_OBSERVER( NativeWindowObserver, observers_, - OnWindowMessage(message, static_cast(w_param), - static_cast(l_param))); + OnWindowMessage(message, w_param, + l_param)); } #endif diff --git a/atom/browser/native_window_observer.h b/atom/browser/native_window_observer.h index 559d5f72a804..a76f314129f6 100644 --- a/atom/browser/native_window_observer.h +++ b/atom/browser/native_window_observer.h @@ -61,7 +61,7 @@ class NativeWindowObserver { // Called when window message received #if defined(OS_WIN) - virtual void OnWindowMessage(UINT message, uint64_t wparam, int64_t lparam) {} + virtual void OnWindowMessage(UINT message, WPARAM wparam, LPARAM lparam) {} #endif // Called when renderer is hung. From 917b33dbe7f9bfac3f668dd386f67f737b0d0c6e Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Thu, 29 Oct 2015 10:53:48 +0800 Subject: [PATCH 023/249] Small code cleanup --- atom/browser/api/atom_api_window.cc | 24 ++++++++++++------------ atom/browser/api/atom_api_window.h | 15 +++++++-------- atom/browser/native_window.cc | 10 ++++------ atom/browser/native_window_observer.h | 2 +- 4 files changed, 24 insertions(+), 27 deletions(-) diff --git a/atom/browser/api/atom_api_window.cc b/atom/browser/api/atom_api_window.cc index 352b9284cf45..497b5a6930ff 100644 --- a/atom/browser/api/atom_api_window.cc +++ b/atom/browser/api/atom_api_window.cc @@ -60,6 +60,16 @@ void OnCapturePageDone( callback.Run(gfx::Image::CreateFrom1xBitmap(bitmap)); } +#if defined(OS_WIN) +v8::Local ToBuffer(v8::Isolate* isolate, void* val, int size) { + auto buffer = node::Buffer::New(isolate, static_cast(val), size); + if (buffer.IsEmpty()) + return v8::Null(isolate); + else + return buffer.ToLocalChecked(); +} +#endif + } // namespace @@ -190,21 +200,11 @@ void Window::OnExecuteWindowsCommand(const std::string& command_name) { } #if defined(OS_WIN) -v8::Local Window::ToBuffer(void* val, int size) { - auto buffer = node::Buffer::New(isolate(), static_cast(val), size); - - if (buffer.IsEmpty()) { - return v8::Null(isolate()); - } else { - return buffer.ToLocalChecked(); - } -} - void Window::OnWindowMessage(UINT message, WPARAM w_param, LPARAM l_param) { if (IsWindowMessageHooked(message)) { messages_callback_map_[message].Run( - ToBuffer(static_cast(&w_param), sizeof(WPARAM)), - ToBuffer(static_cast(&l_param), sizeof(LPARAM))); + ToBuffer(isolate(), static_cast(&w_param), sizeof(WPARAM)), + ToBuffer(isolate(), static_cast(&l_param), sizeof(LPARAM))); } } #endif diff --git a/atom/browser/api/atom_api_window.h b/atom/browser/api/atom_api_window.h index ffbd9b63b40a..1c582551cc93 100644 --- a/atom/browser/api/atom_api_window.h +++ b/atom/browser/api/atom_api_window.h @@ -77,8 +77,7 @@ class Window : public mate::TrackableObject, void OnExecuteWindowsCommand(const std::string& command_name) override; #if defined(OS_WIN) - void OnWindowMessage(UINT message, WPARAM w_param, - LPARAM l_param) override; + void OnWindowMessage(UINT message, WPARAM w_param, LPARAM l_param) override; #endif // mate::Wrappable: @@ -150,15 +149,10 @@ class Window : public mate::TrackableObject, void SetAspectRatio(double aspect_ratio, mate::Arguments* args); #if defined(OS_WIN) - v8::Local ToBuffer(void* val, int size); - typedef base::Callback, v8::Local)> MessageCallback; - typedef std::map MessageCallbackMap; - MessageCallbackMap messages_callback_map_; - bool HookWindowMessage(UINT message, - const MessageCallback& callback); + bool HookWindowMessage(UINT message, const MessageCallback& callback); bool IsWindowMessageHooked(UINT message); void UnhookWindowMessage(UINT message); void UnhookAllWindowMessages(); @@ -174,6 +168,11 @@ class Window : public mate::TrackableObject, int32_t ID() const; v8::Local WebContents(v8::Isolate* isolate); +#if defined(OS_WIN) + typedef std::map MessageCallbackMap; + MessageCallbackMap messages_callback_map_; +#endif + v8::Global web_contents_; v8::Global menu_; diff --git a/atom/browser/native_window.cc b/atom/browser/native_window.cc index bf400dc8c74e..8027fdfa4c1c 100644 --- a/atom/browser/native_window.cc +++ b/atom/browser/native_window.cc @@ -465,12 +465,10 @@ void NativeWindow::NotifyWindowExecuteWindowsCommand( } #if defined(OS_WIN) -void NativeWindow::NotifyWindowMessage(UINT message, WPARAM w_param, - LPARAM l_param) { - FOR_EACH_OBSERVER( - NativeWindowObserver, observers_, - OnWindowMessage(message, w_param, - l_param)); +void NativeWindow::NotifyWindowMessage( + UINT message, WPARAM w_param, LPARAM l_param) { + FOR_EACH_OBSERVER(NativeWindowObserver, observers_, + OnWindowMessage(message, w_param, l_param)); } #endif diff --git a/atom/browser/native_window_observer.h b/atom/browser/native_window_observer.h index a76f314129f6..54004a300d94 100644 --- a/atom/browser/native_window_observer.h +++ b/atom/browser/native_window_observer.h @@ -61,7 +61,7 @@ class NativeWindowObserver { // Called when window message received #if defined(OS_WIN) - virtual void OnWindowMessage(UINT message, WPARAM wparam, LPARAM lparam) {} + virtual void OnWindowMessage(UINT message, WPARAM w_param, LPARAM l_param) {} #endif // Called when renderer is hung. From c7372f8f9311d297cca1d87a5b8ce2b82683bd1c Mon Sep 17 00:00:00 2001 From: Plusb Preco Date: Thu, 29 Oct 2015 14:18:07 +0900 Subject: [PATCH 024/249] Update as upstream --- docs-translations/ko-KR/api/app.md | 44 ++++++++++++++++++++++----- docs-translations/ko-KR/api/remote.md | 8 ++--- 2 files changed, 40 insertions(+), 12 deletions(-) diff --git a/docs-translations/ko-KR/api/app.md b/docs-translations/ko-KR/api/app.md index d1263d00abc3..a443d1252f8e 100644 --- a/docs-translations/ko-KR/api/app.md +++ b/docs-translations/ko-KR/api/app.md @@ -134,18 +134,22 @@ Returns: ### Event: 'select-certificate' -사용자 인증이 요청되었을 때 발생하는 이벤트 입니다. - Returns: * `event` Event -* `webContents` [WebContents](browser-window.md#class-webcontents) -* `url` String +* `webContents` [WebContents](web-contents.md) +* `url` URL * `certificateList` [Objects] * `data` PEM으로 인코딩된 데이터 * `issuerName` 발급자의 공통 이름 * `callback` Function +사용자 인증이 요청되었을 때 발생하는 이벤트 입니다. + +`url`은 클라이언트 인증서를 요청하는 탐색 항목에 해당합니다. +그리고 `callback`은 목록에서 필터링된 항목과 함께 호출될 필요가 있습니다. +이 이벤트에서의 `event.preventDefault()` 호출은 초기 인증 때 저장된 데이터를 사용하는 것을 막습니다. + ```javascript app.on('select-certificate', function(event, host, url, list, callback) { event.preventDefault(); @@ -153,12 +157,36 @@ app.on('select-certificate', function(event, host, url, list, callback) { }) ``` -`url`에 대한 +### Event: 'login' -`url`은 클라이언트 인증서를 요청하는 탐색 항목에 해당합니다. -그리고 `callback`은 목록에서 필터링된 항목과 함께 호출될 필요가 있습니다. +Returns: -이 이벤트에서의 `event.preventDefault()` 호출은 초기 인증에 사용한 저장된 데이터를 사용하는 것을 막습니다. +* `event` Event +* `webContents` [WebContents](web-contents.md) +* `request` Object + * `method` String + * `url` URL + * `referrer` URL +* `authInfo` Object + * `isProxy` Boolean + * `scheme` String + * `host` String + * `port` Integer + * `realm` String +* `callback` Function + +`webContents`가 기본 인증을 요청할 때 발생하는 이벤트입니다. + +기본 동작은 인증 요청을 모두 취소시킵니다. +동작을 새로 정의하려면 반드시 `event.preventDefault()`를 호출한 후 +`callback(username, password)` 형태의 콜백을 호출하여 인증을 처리해야 합니다. + +```javascript +app.on('login', function(event, webContents, request, authInfo, callback) { + event.preventDefault(); + callback('username', 'secret'); +}) +``` ### Event: 'gpu-process-crashed' diff --git a/docs-translations/ko-KR/api/remote.md b/docs-translations/ko-KR/api/remote.md index 756acd429a1b..462c99263961 100644 --- a/docs-translations/ko-KR/api/remote.md +++ b/docs-translations/ko-KR/api/remote.md @@ -2,10 +2,10 @@ `remote` 모듈은 메인 프로세스와 랜더러 프로세스(웹 페이지) 사이의 inter-process (IPC) 통신을 간단하게 추상화 한 모듈입니다. -Electron의 랜더러 프로세스에선 GUI와 관련 없는 모듈만 사용할 수 있습니다. -기본적으로 랜더러 프로세스에서 메인 프로세스의 API를 사용하려면 메인 프로세스와 inter-process 통신을 해야 합니다. -하지만 `remote` 모듈을 사용하면 따로 inter-process 통신을 하지 않고 직접 명시적으로 모듈을 사용할 수 있습니다. -Java의 [RMI](http://en.wikipedia.org/wiki/Java_remote_method_invocation)와 개념이 비슷합니다. +Electron의 메인 프로세스에선 GUI와 관련 있는(`dialog`, `menu`등) 모듈만 사용할 수 있습니다. +랜더러 프로세스에서 이러한 모듈들을 사용하려면 `ipc` 모듈을 통해 메인 프로세스와 inter-process 통신을 해야합니다. +또한, `remote` 모듈을 사용하면 inter-process 통신을 하지 않고도 간단한 메서드를 통해 직접 메인 프로세스의 모듈과 메서드를 사용할 수 있습니다. +이 개념은 Java의 [RMI](http://en.wikipedia.org/wiki/Java_remote_method_invocation)와 비슷합니다. 다음 예제는 랜더러 프로세스에서 브라우저 창을 만드는 예제입니다: From b8cc2e1649edfc39e6c08e457979d84dc8144efd Mon Sep 17 00:00:00 2001 From: Plusb Preco Date: Thu, 29 Oct 2015 14:22:00 +0900 Subject: [PATCH 025/249] Remove extra spaces --- docs/api/app.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/api/app.md b/docs/api/app.md index dbb46698f926..204155cfa053 100644 --- a/docs/api/app.md +++ b/docs/api/app.md @@ -178,7 +178,7 @@ Returns: Emitted when `webContents` wants to do basic auth. The default behavior is to cancel all authentications, to override this you -should prevent the default behavior with `event.preventDefault()` and call +should prevent the default behavior with `event.preventDefault()` and call `callback(username, password)` with the credentials. ```javascript From 62d15953ffea6932622c771daba56b408a311fee Mon Sep 17 00:00:00 2001 From: Robo Date: Wed, 28 Oct 2015 03:45:46 +0530 Subject: [PATCH 026/249] remote: track listeners for browser side --- atom/browser/lib/rpc-server.coffee | 7 +++++++ atom/common/api/lib/callbacks-registry.coffee | 4 ++++ spec/api-ipc-spec.coffee | 13 +++++++++++++ 3 files changed, 24 insertions(+) diff --git a/atom/browser/lib/rpc-server.coffee b/atom/browser/lib/rpc-server.coffee index 6b1f95a841ab..c4d91830b5f1 100644 --- a/atom/browser/lib/rpc-server.coffee +++ b/atom/browser/lib/rpc-server.coffee @@ -3,6 +3,9 @@ path = require 'path' objectsRegistry = require './objects-registry.js' v8Util = process.atomBinding 'v8_util' +# caches callback with their registry ID. +rendererCallbacks = {} + # Convert a real value into meta data. valueToMeta = (sender, value, optimizeSimpleObject=false) -> meta = type: typeof value @@ -74,6 +77,8 @@ unwrapArgs = (sender, args) -> objectsRegistry.once "clear-#{sender.getId()}", -> rendererReleased = true + return rendererCallbacks[meta.id] if rendererCallbacks[meta.id]? + ret = -> if rendererReleased throw new Error("Attempting to call a function in a renderer window @@ -81,7 +86,9 @@ unwrapArgs = (sender, args) -> sender.send 'ATOM_RENDERER_CALLBACK', meta.id, valueToMeta(sender, arguments) v8Util.setDestructor ret, -> return if rendererReleased + delete rendererCallbacks[meta.id] sender.send 'ATOM_RENDERER_RELEASE_CALLBACK', meta.id + rendererCallbacks[meta.id] = ret ret else throw new TypeError("Unknown type: #{meta.type}") diff --git a/atom/common/api/lib/callbacks-registry.coffee b/atom/common/api/lib/callbacks-registry.coffee index d4c37f087b1e..5151640b2b80 100644 --- a/atom/common/api/lib/callbacks-registry.coffee +++ b/atom/common/api/lib/callbacks-registry.coffee @@ -7,6 +7,10 @@ class CallbacksRegistry add: (callback) -> id = ++@nextId + for id,value of @callbacks + if value == callback + return id + # Capture the location of the function and put it in the ID string, # so that release errors can be tracked down easily. regexp = /at (.*)/gi diff --git a/spec/api-ipc-spec.coffee b/spec/api-ipc-spec.coffee index 142f06c00ff3..1155aa73e83d 100644 --- a/spec/api-ipc-spec.coffee +++ b/spec/api-ipc-spec.coffee @@ -88,3 +88,16 @@ describe 'ipc module', -> w.destroy() done() w.loadUrl 'file://' + path.join(fixtures, 'api', 'send-sync-message.html') + + describe 'remote listeners', -> + it 'can be added and removed correctly', -> + count = 0 + w = new BrowserWindow(show: false) + listener = () -> + count += 1 + w.removeListener 'blur', listener + w.on 'blur', listener + w.emit 'blur' + w.emit 'blur' + assert.equal count, 1 + w.destroy() From eae7c840b7ce8a954c67efb60553102dcde9f106 Mon Sep 17 00:00:00 2001 From: Robo Date: Wed, 28 Oct 2015 21:29:46 +0530 Subject: [PATCH 027/249] use idweakmap for holding callbacks in browser --- atom/browser/lib/rpc-server.coffee | 13 ++++---- atom/common/api/atom_api_v8_util.cc | 8 +++++ atom/common/api/lib/callbacks-registry.coffee | 12 ++++---- atom/common/id_weak_map.cc | 30 +++++++++++++++++++ atom/common/id_weak_map.h | 11 ++++++- atom/renderer/api/lib/remote.coffee | 2 +- 6 files changed, 63 insertions(+), 13 deletions(-) diff --git a/atom/browser/lib/rpc-server.coffee b/atom/browser/lib/rpc-server.coffee index c4d91830b5f1..13c8ceb16e03 100644 --- a/atom/browser/lib/rpc-server.coffee +++ b/atom/browser/lib/rpc-server.coffee @@ -3,8 +3,8 @@ path = require 'path' objectsRegistry = require './objects-registry.js' v8Util = process.atomBinding 'v8_util' -# caches callback with their registry ID. -rendererCallbacks = {} +# weak refereence to callback with their registry ID. +rendererCallbacks = v8Util.createWeakMap() # Convert a real value into meta data. valueToMeta = (sender, value, optimizeSimpleObject=false) -> @@ -77,18 +77,19 @@ unwrapArgs = (sender, args) -> objectsRegistry.once "clear-#{sender.getId()}", -> rendererReleased = true - return rendererCallbacks[meta.id] if rendererCallbacks[meta.id]? + if rendererCallbacks.has(meta.id) + return rendererCallbacks.get(meta.id) ret = -> if rendererReleased throw new Error("Attempting to call a function in a renderer window - that has been closed or released. Function provided here: #{meta.id}.") + that has been closed or released. Function provided here: #{meta.location}.") sender.send 'ATOM_RENDERER_CALLBACK', meta.id, valueToMeta(sender, arguments) v8Util.setDestructor ret, -> return if rendererReleased - delete rendererCallbacks[meta.id] + rendererCallbacks.remove meta.id sender.send 'ATOM_RENDERER_RELEASE_CALLBACK', meta.id - rendererCallbacks[meta.id] = ret + rendererCallbacks.set meta.id, ret ret else throw new TypeError("Unknown type: #{meta.type}") diff --git a/atom/common/api/atom_api_v8_util.cc b/atom/common/api/atom_api_v8_util.cc index bba3399a8dbd..4a321f84d80e 100644 --- a/atom/common/api/atom_api_v8_util.cc +++ b/atom/common/api/atom_api_v8_util.cc @@ -3,7 +3,9 @@ // found in the LICENSE file. #include "atom/common/api/object_life_monitor.h" +#include "atom/common/id_weak_map.h" #include "atom/common/node_includes.h" +#include "native_mate/handle.h" #include "native_mate/dictionary.h" #include "v8/include/v8-profiler.h" @@ -46,6 +48,11 @@ void TakeHeapSnapshot(v8::Isolate* isolate) { isolate->GetHeapProfiler()->TakeHeapSnapshot(); } +mate::Handle CreateWeakMap(v8::Isolate* isolate) { + auto handle = mate::CreateHandle(isolate, new atom::IDWeakMap); + return handle; +} + void Initialize(v8::Local exports, v8::Local unused, v8::Local context, void* priv) { mate::Dictionary dict(context->GetIsolate(), exports); @@ -56,6 +63,7 @@ void Initialize(v8::Local exports, v8::Local unused, dict.SetMethod("getObjectHash", &GetObjectHash); dict.SetMethod("setDestructor", &SetDestructor); dict.SetMethod("takeHeapSnapshot", &TakeHeapSnapshot); + dict.SetMethod("createWeakMap", &CreateWeakMap); } } // namespace diff --git a/atom/common/api/lib/callbacks-registry.coffee b/atom/common/api/lib/callbacks-registry.coffee index 5151640b2b80..b777f7a462df 100644 --- a/atom/common/api/lib/callbacks-registry.coffee +++ b/atom/common/api/lib/callbacks-registry.coffee @@ -1,3 +1,5 @@ +v8Util = process.atomBinding 'v8_util' + module.exports = class CallbacksRegistry constructor: -> @@ -7,10 +9,6 @@ class CallbacksRegistry add: (callback) -> id = ++@nextId - for id,value of @callbacks - if value == callback - return id - # Capture the location of the function and put it in the ID string, # so that release errors can be tracked down easily. regexp = /at (.*)/gi @@ -21,10 +19,14 @@ class CallbacksRegistry continue if location.indexOf('(native)') isnt -1 continue if location.indexOf('atom.asar') isnt -1 [x, filenameAndLine] = /([^/^\)]*)\)?$/gi.exec(location) - id = "#{filenameAndLine} (#{id})" break + if v8Util.getHiddenValue(callback, 'metaId')? + return v8Util.getHiddenValue(callback, 'metaId') + @callbacks[id] = callback + v8Util.setHiddenValue callback, 'metaId', id + v8Util.setHiddenValue callback, 'location', filenameAndLine id get: (id) -> diff --git a/atom/common/id_weak_map.cc b/atom/common/id_weak_map.cc index c5c4b60cac5c..3d7e1513597c 100644 --- a/atom/common/id_weak_map.cc +++ b/atom/common/id_weak_map.cc @@ -8,6 +8,18 @@ #include "native_mate/converter.h" +namespace mate { + +template +struct Converter> { + static v8::Local ToV8(v8::Isolate* isolate, + v8::MaybeLocal val) { + return ConvertToV8(isolate, val.ToLocalChecked()); + } +}; + +} // namespace mate + namespace atom { namespace { @@ -41,6 +53,15 @@ int32_t IDWeakMap::Add(v8::Isolate* isolate, v8::Local object) { return id; } +void IDWeakMap::Set(v8::Isolate* isolate, + int32_t id, + v8::Local object) { + auto global = make_linked_ptr(new v8::Global(isolate, object)); + ObjectKey* key = new ObjectKey(id, this); + global->SetWeak(key, OnObjectGC, v8::WeakCallbackType::kParameter); + map_[id] = global; +} + v8::MaybeLocal IDWeakMap::Get(v8::Isolate* isolate, int32_t id) { auto iter = map_.find(id); if (iter == map_.end()) @@ -85,4 +106,13 @@ int32_t IDWeakMap::GetNextID() { return ++next_id_; } +mate::ObjectTemplateBuilder IDWeakMap::GetObjectTemplateBuilder( + v8::Isolate* isolate) { + return mate::ObjectTemplateBuilder(isolate) + .SetMethod("set", &IDWeakMap::Set) + .SetMethod("get", &IDWeakMap::Get) + .SetMethod("has", &IDWeakMap::Has) + .SetMethod("remove", &IDWeakMap::Remove); +} + } // namespace atom diff --git a/atom/common/id_weak_map.h b/atom/common/id_weak_map.h index 9fe71ebb616f..c291f76a430e 100644 --- a/atom/common/id_weak_map.h +++ b/atom/common/id_weak_map.h @@ -9,12 +9,14 @@ #include #include "base/memory/linked_ptr.h" +#include "native_mate/object_template_builder.h" +#include "native_mate/wrappable.h" #include "v8/include/v8.h" namespace atom { // Like ES6's WeakMap, but the key is Integer and the value is Weak Pointer. -class IDWeakMap { +class IDWeakMap : public mate::Wrappable { public: IDWeakMap(); ~IDWeakMap(); @@ -22,6 +24,9 @@ class IDWeakMap { // Adds |object| to WeakMap and returns its allocated |id|. int32_t Add(v8::Isolate* isolate, v8::Local object); + // Sets the object to WeakMap with the given |id|. + void Set(v8::Isolate* isolate, int32_t id, v8::Local object); + // Gets the object from WeakMap by its |id|. v8::MaybeLocal Get(v8::Isolate* isolate, int32_t id); @@ -40,6 +45,10 @@ class IDWeakMap { // Clears the weak map. void Clear(); + protected: + mate::ObjectTemplateBuilder GetObjectTemplateBuilder( + v8::Isolate* isolate) override; + private: // Returns next available ID. int32_t GetNextID(); diff --git a/atom/renderer/api/lib/remote.coffee b/atom/renderer/api/lib/remote.coffee index 8a5565f06562..b5a3a694ee37 100644 --- a/atom/renderer/api/lib/remote.coffee +++ b/atom/renderer/api/lib/remote.coffee @@ -33,7 +33,7 @@ wrapArgs = (args, visited=[]) -> else if typeof value is 'function' and v8Util.getHiddenValue value, 'returnValue' type: 'function-with-return-value', value: valueToMeta(value()) else if typeof value is 'function' - type: 'function', id: callbacksRegistry.add(value) + type: 'function', id: callbacksRegistry.add(value), location: v8Util.getHiddenValue value, 'location' else type: 'value', value: value From ac4df34ecd8a306e5cf71fd6696fae4362f3e515 Mon Sep 17 00:00:00 2001 From: Robo Date: Thu, 29 Oct 2015 16:27:30 +0530 Subject: [PATCH 028/249] create binding to idweakmap --- atom/browser/lib/rpc-server.coffee | 11 ++-- atom/common/api/atom_api_v8_util.cc | 7 --- atom/common/api/atom_api_weak_map.cc | 79 ++++++++++++++++++++++++++++ atom/common/api/atom_api_weak_map.h | 46 ++++++++++++++++ atom/common/id_weak_map.cc | 21 -------- atom/common/id_weak_map.h | 8 +-- atom/common/node_bindings.cc | 1 + filenames.gypi | 2 + 8 files changed, 135 insertions(+), 40 deletions(-) create mode 100644 atom/common/api/atom_api_weak_map.cc create mode 100644 atom/common/api/atom_api_weak_map.h diff --git a/atom/browser/lib/rpc-server.coffee b/atom/browser/lib/rpc-server.coffee index 13c8ceb16e03..3a4f896da5ec 100644 --- a/atom/browser/lib/rpc-server.coffee +++ b/atom/browser/lib/rpc-server.coffee @@ -2,9 +2,10 @@ ipc = require 'ipc' path = require 'path' objectsRegistry = require './objects-registry.js' v8Util = process.atomBinding 'v8_util' +WeakMap = process.atomBinding('weak_map').WeakMap -# weak refereence to callback with their registry ID. -rendererCallbacks = v8Util.createWeakMap() +# Weak reference to callback with their registry ID. +rendererCallbacks = new WeakMap() # Convert a real value into meta data. valueToMeta = (sender, value, optimizeSimpleObject=false) -> @@ -73,13 +74,13 @@ unwrapArgs = (sender, args) -> returnValue = metaToValue meta.value -> returnValue when 'function' + if rendererCallbacks.has(meta.id) + return rendererCallbacks.get(meta.id) + rendererReleased = false objectsRegistry.once "clear-#{sender.getId()}", -> rendererReleased = true - if rendererCallbacks.has(meta.id) - return rendererCallbacks.get(meta.id) - ret = -> if rendererReleased throw new Error("Attempting to call a function in a renderer window diff --git a/atom/common/api/atom_api_v8_util.cc b/atom/common/api/atom_api_v8_util.cc index 4a321f84d80e..1c8c8c9f7e09 100644 --- a/atom/common/api/atom_api_v8_util.cc +++ b/atom/common/api/atom_api_v8_util.cc @@ -5,7 +5,6 @@ #include "atom/common/api/object_life_monitor.h" #include "atom/common/id_weak_map.h" #include "atom/common/node_includes.h" -#include "native_mate/handle.h" #include "native_mate/dictionary.h" #include "v8/include/v8-profiler.h" @@ -48,11 +47,6 @@ void TakeHeapSnapshot(v8::Isolate* isolate) { isolate->GetHeapProfiler()->TakeHeapSnapshot(); } -mate::Handle CreateWeakMap(v8::Isolate* isolate) { - auto handle = mate::CreateHandle(isolate, new atom::IDWeakMap); - return handle; -} - void Initialize(v8::Local exports, v8::Local unused, v8::Local context, void* priv) { mate::Dictionary dict(context->GetIsolate(), exports); @@ -63,7 +57,6 @@ void Initialize(v8::Local exports, v8::Local unused, dict.SetMethod("getObjectHash", &GetObjectHash); dict.SetMethod("setDestructor", &SetDestructor); dict.SetMethod("takeHeapSnapshot", &TakeHeapSnapshot); - dict.SetMethod("createWeakMap", &CreateWeakMap); } } // namespace diff --git a/atom/common/api/atom_api_weak_map.cc b/atom/common/api/atom_api_weak_map.cc new file mode 100644 index 000000000000..6cc75c43c927 --- /dev/null +++ b/atom/common/api/atom_api_weak_map.cc @@ -0,0 +1,79 @@ +// Copyright (c) 2015 GitHub, Inc. +// Use of this source code is governed by the MIT license that can be +// found in the LICENSE file. + +#include "atom/common/api/atom_api_weak_map.h" + +#include "atom/common/node_includes.h" +#include "native_mate/constructor.h" +#include "native_mate/dictionary.h" + +namespace atom { + +namespace api { + +WeakMap::WeakMap() { + id_weak_map_.reset(new atom::IDWeakMap); +} + +WeakMap::~WeakMap() { +} + +void WeakMap::Set(v8::Isolate* isolate, + int32_t id, + v8::Local object) { + id_weak_map_->Set(isolate, id, object); +} + +v8::Local WeakMap::Get(v8::Isolate* isolate, int32_t id) { + return id_weak_map_->Get(isolate, id).ToLocalChecked(); +} + +bool WeakMap::Has(int32_t id) { + return id_weak_map_->Has(id); +} + +void WeakMap::Remove(int32_t id) { + id_weak_map_->Remove(id); +} + +bool WeakMap::IsDestroyed() const { + return !id_weak_map_; +} + +// static +void WeakMap::BuildPrototype(v8::Isolate* isolate, + v8::Local prototype) { + mate::ObjectTemplateBuilder(isolate, prototype) + .SetMethod("set", &WeakMap::Set) + .SetMethod("get", &WeakMap::Get) + .SetMethod("has", &WeakMap::Has) + .SetMethod("remove", &WeakMap::Remove); +} + +// static +mate::Wrappable* WeakMap::Create(v8::Isolate* isolate) { + return new WeakMap; +} + +} // namespace api + +} // namespace atom + +namespace { + +using atom::api::WeakMap; + +void Initialize(v8::Local exports, v8::Local unused, + v8::Local context, void* priv) { + v8::Isolate* isolate = context->GetIsolate(); + v8::Local constructor = mate::CreateConstructor( + isolate, "WeakMap", base::Bind(&WeakMap::Create)); + mate::Dictionary weak_map(isolate, constructor); + mate::Dictionary dict(isolate, exports); + dict.Set("WeakMap", weak_map); +} + +} // namespace + +NODE_MODULE_CONTEXT_AWARE_BUILTIN(atom_common_weak_map, Initialize) diff --git a/atom/common/api/atom_api_weak_map.h b/atom/common/api/atom_api_weak_map.h new file mode 100644 index 000000000000..7c747e1a384e --- /dev/null +++ b/atom/common/api/atom_api_weak_map.h @@ -0,0 +1,46 @@ +// Copyright (c) 2015 GitHub, Inc. +// Use of this source code is governed by the MIT license that can be +// found in the LICENSE file. + +#ifndef ATOM_COMMON_API_ATOM_API_WEAK_MAP_H_ +#define ATOM_COMMON_API_ATOM_API_WEAK_MAP_H_ + +#include "atom/common/id_weak_map.h" +#include "native_mate/object_template_builder.h" +#include "native_mate/handle.h" + +namespace atom { + +namespace api { + +class WeakMap : public mate::Wrappable { + public: + static mate::Wrappable* Create(v8::Isolate* isolate); + + static void BuildPrototype(v8::Isolate* isolate, + v8::Local prototype); + + protected: + WeakMap(); + virtual ~WeakMap(); + + // mate::Wrappable: + bool IsDestroyed() const override; + + private: + // Api for IDWeakMap. + void Set(v8::Isolate* isolate, int32_t id, v8::Local object); + v8::Local Get(v8::Isolate* isolate, int32_t id); + bool Has(int32_t id); + void Remove(int32_t id); + + scoped_ptr id_weak_map_; + + DISALLOW_COPY_AND_ASSIGN(WeakMap); +}; + +} // namespace api + +} // namespace atom + +#endif // ATOM_COMMON_API_ATOM_API_WEAK_MAP_H_ diff --git a/atom/common/id_weak_map.cc b/atom/common/id_weak_map.cc index 3d7e1513597c..7fda009e0ee1 100644 --- a/atom/common/id_weak_map.cc +++ b/atom/common/id_weak_map.cc @@ -8,18 +8,6 @@ #include "native_mate/converter.h" -namespace mate { - -template -struct Converter> { - static v8::Local ToV8(v8::Isolate* isolate, - v8::MaybeLocal val) { - return ConvertToV8(isolate, val.ToLocalChecked()); - } -}; - -} // namespace mate - namespace atom { namespace { @@ -106,13 +94,4 @@ int32_t IDWeakMap::GetNextID() { return ++next_id_; } -mate::ObjectTemplateBuilder IDWeakMap::GetObjectTemplateBuilder( - v8::Isolate* isolate) { - return mate::ObjectTemplateBuilder(isolate) - .SetMethod("set", &IDWeakMap::Set) - .SetMethod("get", &IDWeakMap::Get) - .SetMethod("has", &IDWeakMap::Has) - .SetMethod("remove", &IDWeakMap::Remove); -} - } // namespace atom diff --git a/atom/common/id_weak_map.h b/atom/common/id_weak_map.h index c291f76a430e..688e85cd0cce 100644 --- a/atom/common/id_weak_map.h +++ b/atom/common/id_weak_map.h @@ -9,14 +9,12 @@ #include #include "base/memory/linked_ptr.h" -#include "native_mate/object_template_builder.h" -#include "native_mate/wrappable.h" #include "v8/include/v8.h" namespace atom { // Like ES6's WeakMap, but the key is Integer and the value is Weak Pointer. -class IDWeakMap : public mate::Wrappable { +class IDWeakMap { public: IDWeakMap(); ~IDWeakMap(); @@ -45,10 +43,6 @@ class IDWeakMap : public mate::Wrappable { // Clears the weak map. void Clear(); - protected: - mate::ObjectTemplateBuilder GetObjectTemplateBuilder( - v8::Isolate* isolate) override; - private: // Returns next available ID. int32_t GetNextID(); diff --git a/atom/common/node_bindings.cc b/atom/common/node_bindings.cc index 2da68854ad14..b6fcdb82f819 100644 --- a/atom/common/node_bindings.cc +++ b/atom/common/node_bindings.cc @@ -52,6 +52,7 @@ REFERENCE_MODULE(atom_common_native_image); REFERENCE_MODULE(atom_common_screen); REFERENCE_MODULE(atom_common_shell); REFERENCE_MODULE(atom_common_v8_util); +REFERENCE_MODULE(atom_common_weak_map); REFERENCE_MODULE(atom_renderer_ipc); REFERENCE_MODULE(atom_renderer_web_frame); #undef REFERENCE_MODULE diff --git a/filenames.gypi b/filenames.gypi index f66485edd19d..0f5b794a0361 100644 --- a/filenames.gypi +++ b/filenames.gypi @@ -260,6 +260,8 @@ 'atom/common/api/atom_api_native_image_mac.mm', 'atom/common/api/atom_api_shell.cc', 'atom/common/api/atom_api_v8_util.cc', + 'atom/common/api/atom_api_weak_map.cc', + 'atom/common/api/atom_api_weak_map.h', 'atom/common/api/atom_bindings.cc', 'atom/common/api/atom_bindings.h', 'atom/common/api/event_emitter_caller.cc', From 3a154ab8ead41151977ef857490610a895f5ee87 Mon Sep 17 00:00:00 2001 From: Robo Date: Thu, 29 Oct 2015 16:52:12 +0530 Subject: [PATCH 029/249] add line and column values to callback id --- atom/browser/lib/rpc-server.coffee | 4 +- atom/common/api/atom_api_id_weak_map.cc | 79 +++++++++++++++++++ ..._api_weak_map.h => atom_api_id_weak_map.h} | 16 ++-- atom/common/api/atom_api_v8_util.cc | 1 - atom/common/api/atom_api_weak_map.cc | 79 ------------------- atom/common/api/lib/callbacks-registry.coffee | 8 +- atom/common/node_bindings.cc | 2 +- filenames.gypi | 4 +- 8 files changed, 97 insertions(+), 96 deletions(-) create mode 100644 atom/common/api/atom_api_id_weak_map.cc rename atom/common/api/{atom_api_weak_map.h => atom_api_id_weak_map.h} (72%) delete mode 100644 atom/common/api/atom_api_weak_map.cc diff --git a/atom/browser/lib/rpc-server.coffee b/atom/browser/lib/rpc-server.coffee index 3a4f896da5ec..40e1b0e46ac7 100644 --- a/atom/browser/lib/rpc-server.coffee +++ b/atom/browser/lib/rpc-server.coffee @@ -2,10 +2,10 @@ ipc = require 'ipc' path = require 'path' objectsRegistry = require './objects-registry.js' v8Util = process.atomBinding 'v8_util' -WeakMap = process.atomBinding('weak_map').WeakMap +IDWeakMap = process.atomBinding('id_weak_map').IDWeakMap # Weak reference to callback with their registry ID. -rendererCallbacks = new WeakMap() +rendererCallbacks = new IDWeakMap() # Convert a real value into meta data. valueToMeta = (sender, value, optimizeSimpleObject=false) -> diff --git a/atom/common/api/atom_api_id_weak_map.cc b/atom/common/api/atom_api_id_weak_map.cc new file mode 100644 index 000000000000..bdc298fa0c49 --- /dev/null +++ b/atom/common/api/atom_api_id_weak_map.cc @@ -0,0 +1,79 @@ +// Copyright (c) 2015 GitHub, Inc. +// Use of this source code is governed by the MIT license that can be +// found in the LICENSE file. + +#include "atom/common/api/atom_api_id_weak_map.h" + +#include "atom/common/node_includes.h" +#include "native_mate/constructor.h" +#include "native_mate/dictionary.h" + +namespace atom { + +namespace api { + +IDWeakMap::IDWeakMap() { + id_weak_map_.reset(new atom::IDWeakMap); +} + +IDWeakMap::~IDWeakMap() { +} + +void IDWeakMap::Set(v8::Isolate* isolate, + int32_t id, + v8::Local object) { + id_weak_map_->Set(isolate, id, object); +} + +v8::Local IDWeakMap::Get(v8::Isolate* isolate, int32_t id) { + return id_weak_map_->Get(isolate, id).ToLocalChecked(); +} + +bool IDWeakMap::Has(int32_t id) { + return id_weak_map_->Has(id); +} + +void IDWeakMap::Remove(int32_t id) { + id_weak_map_->Remove(id); +} + +bool IDWeakMap::IsDestroyed() const { + return !id_weak_map_; +} + +// static +void IDWeakMap::BuildPrototype(v8::Isolate* isolate, + v8::Local prototype) { + mate::ObjectTemplateBuilder(isolate, prototype) + .SetMethod("set", &IDWeakMap::Set) + .SetMethod("get", &IDWeakMap::Get) + .SetMethod("has", &IDWeakMap::Has) + .SetMethod("remove", &IDWeakMap::Remove); +} + +// static +mate::Wrappable* IDWeakMap::Create(v8::Isolate* isolate) { + return new IDWeakMap; +} + +} // namespace api + +} // namespace atom + +namespace { + +using atom::api::IDWeakMap; + +void Initialize(v8::Local exports, v8::Local unused, + v8::Local context, void* priv) { + v8::Isolate* isolate = context->GetIsolate(); + v8::Local constructor = mate::CreateConstructor( + isolate, "IDWeakMap", base::Bind(&IDWeakMap::Create)); + mate::Dictionary id_weak_map(isolate, constructor); + mate::Dictionary dict(isolate, exports); + dict.Set("IDWeakMap", id_weak_map); +} + +} // namespace + +NODE_MODULE_CONTEXT_AWARE_BUILTIN(atom_common_id_weak_map, Initialize) diff --git a/atom/common/api/atom_api_weak_map.h b/atom/common/api/atom_api_id_weak_map.h similarity index 72% rename from atom/common/api/atom_api_weak_map.h rename to atom/common/api/atom_api_id_weak_map.h index 7c747e1a384e..3acdddc9c75f 100644 --- a/atom/common/api/atom_api_weak_map.h +++ b/atom/common/api/atom_api_id_weak_map.h @@ -2,8 +2,8 @@ // Use of this source code is governed by the MIT license that can be // found in the LICENSE file. -#ifndef ATOM_COMMON_API_ATOM_API_WEAK_MAP_H_ -#define ATOM_COMMON_API_ATOM_API_WEAK_MAP_H_ +#ifndef ATOM_COMMON_API_ATOM_API_ID_WEAK_MAP_H_ +#define ATOM_COMMON_API_ATOM_API_ID_WEAK_MAP_H_ #include "atom/common/id_weak_map.h" #include "native_mate/object_template_builder.h" @@ -13,7 +13,7 @@ namespace atom { namespace api { -class WeakMap : public mate::Wrappable { +class IDWeakMap : public mate::Wrappable { public: static mate::Wrappable* Create(v8::Isolate* isolate); @@ -21,8 +21,8 @@ class WeakMap : public mate::Wrappable { v8::Local prototype); protected: - WeakMap(); - virtual ~WeakMap(); + IDWeakMap(); + virtual ~IDWeakMap(); // mate::Wrappable: bool IsDestroyed() const override; @@ -34,13 +34,13 @@ class WeakMap : public mate::Wrappable { bool Has(int32_t id); void Remove(int32_t id); - scoped_ptr id_weak_map_; + scoped_ptr id_weak_map_; - DISALLOW_COPY_AND_ASSIGN(WeakMap); + DISALLOW_COPY_AND_ASSIGN(IDWeakMap); }; } // namespace api } // namespace atom -#endif // ATOM_COMMON_API_ATOM_API_WEAK_MAP_H_ +#endif // ATOM_COMMON_API_ATOM_API_ID_WEAK_MAP_H_ diff --git a/atom/common/api/atom_api_v8_util.cc b/atom/common/api/atom_api_v8_util.cc index 1c8c8c9f7e09..bba3399a8dbd 100644 --- a/atom/common/api/atom_api_v8_util.cc +++ b/atom/common/api/atom_api_v8_util.cc @@ -3,7 +3,6 @@ // found in the LICENSE file. #include "atom/common/api/object_life_monitor.h" -#include "atom/common/id_weak_map.h" #include "atom/common/node_includes.h" #include "native_mate/dictionary.h" #include "v8/include/v8-profiler.h" diff --git a/atom/common/api/atom_api_weak_map.cc b/atom/common/api/atom_api_weak_map.cc deleted file mode 100644 index 6cc75c43c927..000000000000 --- a/atom/common/api/atom_api_weak_map.cc +++ /dev/null @@ -1,79 +0,0 @@ -// Copyright (c) 2015 GitHub, Inc. -// Use of this source code is governed by the MIT license that can be -// found in the LICENSE file. - -#include "atom/common/api/atom_api_weak_map.h" - -#include "atom/common/node_includes.h" -#include "native_mate/constructor.h" -#include "native_mate/dictionary.h" - -namespace atom { - -namespace api { - -WeakMap::WeakMap() { - id_weak_map_.reset(new atom::IDWeakMap); -} - -WeakMap::~WeakMap() { -} - -void WeakMap::Set(v8::Isolate* isolate, - int32_t id, - v8::Local object) { - id_weak_map_->Set(isolate, id, object); -} - -v8::Local WeakMap::Get(v8::Isolate* isolate, int32_t id) { - return id_weak_map_->Get(isolate, id).ToLocalChecked(); -} - -bool WeakMap::Has(int32_t id) { - return id_weak_map_->Has(id); -} - -void WeakMap::Remove(int32_t id) { - id_weak_map_->Remove(id); -} - -bool WeakMap::IsDestroyed() const { - return !id_weak_map_; -} - -// static -void WeakMap::BuildPrototype(v8::Isolate* isolate, - v8::Local prototype) { - mate::ObjectTemplateBuilder(isolate, prototype) - .SetMethod("set", &WeakMap::Set) - .SetMethod("get", &WeakMap::Get) - .SetMethod("has", &WeakMap::Has) - .SetMethod("remove", &WeakMap::Remove); -} - -// static -mate::Wrappable* WeakMap::Create(v8::Isolate* isolate) { - return new WeakMap; -} - -} // namespace api - -} // namespace atom - -namespace { - -using atom::api::WeakMap; - -void Initialize(v8::Local exports, v8::Local unused, - v8::Local context, void* priv) { - v8::Isolate* isolate = context->GetIsolate(); - v8::Local constructor = mate::CreateConstructor( - isolate, "WeakMap", base::Bind(&WeakMap::Create)); - mate::Dictionary weak_map(isolate, constructor); - mate::Dictionary dict(isolate, exports); - dict.Set("WeakMap", weak_map); -} - -} // namespace - -NODE_MODULE_CONTEXT_AWARE_BUILTIN(atom_common_weak_map, Initialize) diff --git a/atom/common/api/lib/callbacks-registry.coffee b/atom/common/api/lib/callbacks-registry.coffee index b777f7a462df..57f5d0343dc2 100644 --- a/atom/common/api/lib/callbacks-registry.coffee +++ b/atom/common/api/lib/callbacks-registry.coffee @@ -7,6 +7,9 @@ class CallbacksRegistry @callbacks = {} add: (callback) -> + if v8Util.getHiddenValue(callback, 'metaId')? + return v8Util.getHiddenValue(callback, 'metaId') + id = ++@nextId # Capture the location of the function and put it in the ID string, @@ -19,11 +22,10 @@ class CallbacksRegistry continue if location.indexOf('(native)') isnt -1 continue if location.indexOf('atom.asar') isnt -1 [x, filenameAndLine] = /([^/^\)]*)\)?$/gi.exec(location) + [x, line, column] = /(\d+):(\d+)/g.exec(filenameAndLine) + id += parseInt(line) + parseInt(column) break - if v8Util.getHiddenValue(callback, 'metaId')? - return v8Util.getHiddenValue(callback, 'metaId') - @callbacks[id] = callback v8Util.setHiddenValue callback, 'metaId', id v8Util.setHiddenValue callback, 'location', filenameAndLine diff --git a/atom/common/node_bindings.cc b/atom/common/node_bindings.cc index b6fcdb82f819..10da202da70d 100644 --- a/atom/common/node_bindings.cc +++ b/atom/common/node_bindings.cc @@ -48,11 +48,11 @@ REFERENCE_MODULE(atom_browser_window); REFERENCE_MODULE(atom_common_asar); REFERENCE_MODULE(atom_common_clipboard); REFERENCE_MODULE(atom_common_crash_reporter); +REFERENCE_MODULE(atom_common_id_weak_map); REFERENCE_MODULE(atom_common_native_image); REFERENCE_MODULE(atom_common_screen); REFERENCE_MODULE(atom_common_shell); REFERENCE_MODULE(atom_common_v8_util); -REFERENCE_MODULE(atom_common_weak_map); REFERENCE_MODULE(atom_renderer_ipc); REFERENCE_MODULE(atom_renderer_web_frame); #undef REFERENCE_MODULE diff --git a/filenames.gypi b/filenames.gypi index 0f5b794a0361..ba739764f492 100644 --- a/filenames.gypi +++ b/filenames.gypi @@ -255,13 +255,13 @@ 'atom/common/api/atom_api_asar.cc', 'atom/common/api/atom_api_clipboard.cc', 'atom/common/api/atom_api_crash_reporter.cc', + 'atom/common/api/atom_api_id_weak_map.cc', + 'atom/common/api/atom_api_id_weak_map.h', 'atom/common/api/atom_api_native_image.cc', 'atom/common/api/atom_api_native_image.h', 'atom/common/api/atom_api_native_image_mac.mm', 'atom/common/api/atom_api_shell.cc', 'atom/common/api/atom_api_v8_util.cc', - 'atom/common/api/atom_api_weak_map.cc', - 'atom/common/api/atom_api_weak_map.h', 'atom/common/api/atom_bindings.cc', 'atom/common/api/atom_bindings.h', 'atom/common/api/event_emitter_caller.cc', From 8cd8495df7f55f5c46e155a97dff9dcf7e99a861 Mon Sep 17 00:00:00 2001 From: Simon Knight Date: Fri, 30 Oct 2015 16:10:46 +1030 Subject: [PATCH 030/249] fix capital I -> i in isDocumentEdited Uncaught Exception: TypeError: mainWindow.IsDocumentEdited is not a function --- docs/api/browser-window.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/api/browser-window.md b/docs/api/browser-window.md index d7bf5be374d4..fbac6b10863b 100644 --- a/docs/api/browser-window.md +++ b/docs/api/browser-window.md @@ -594,7 +594,7 @@ Returns the pathname of the file the window represents. Specifies whether the window’s document has been edited, and the icon in title bar will become grey when set to `true`. -### `win.IsDocumentEdited()` _OS X_ +### `win.isDocumentEdited()` _OS X_ Whether the window's document has been edited. From 21a7c459d821266331660f82f76efcd5adf661e0 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Fri, 30 Oct 2015 13:12:20 +0800 Subject: [PATCH 031/249] Bump v0.34.2 --- atom.gyp | 2 +- atom/browser/resources/mac/Info.plist | 4 ++-- atom/browser/resources/win/atom.rc | 8 ++++---- atom/common/atom_version.h | 2 +- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/atom.gyp b/atom.gyp index d4b4f67b6310..7b88df4d8013 100644 --- a/atom.gyp +++ b/atom.gyp @@ -4,7 +4,7 @@ 'product_name%': 'Electron', 'company_name%': 'GitHub, Inc', 'company_abbr%': 'github', - 'version%': '0.34.1', + 'version%': '0.34.2', }, 'includes': [ 'filenames.gypi', diff --git a/atom/browser/resources/mac/Info.plist b/atom/browser/resources/mac/Info.plist index aff46850004f..a703c01a766c 100644 --- a/atom/browser/resources/mac/Info.plist +++ b/atom/browser/resources/mac/Info.plist @@ -17,9 +17,9 @@ CFBundleIconFile atom.icns CFBundleVersion - 0.34.1 + 0.34.2 CFBundleShortVersionString - 0.34.1 + 0.34.2 LSApplicationCategoryType public.app-category.developer-tools LSMinimumSystemVersion diff --git a/atom/browser/resources/win/atom.rc b/atom/browser/resources/win/atom.rc index 3adf196e8ba5..8401e1d7d09e 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 0,34,1,0 - PRODUCTVERSION 0,34,1,0 + FILEVERSION 0,34,2,0 + PRODUCTVERSION 0,34,2,0 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -74,12 +74,12 @@ BEGIN BEGIN VALUE "CompanyName", "GitHub, Inc." VALUE "FileDescription", "Electron" - VALUE "FileVersion", "0.34.1" + VALUE "FileVersion", "0.34.2" VALUE "InternalName", "electron.exe" VALUE "LegalCopyright", "Copyright (C) 2015 GitHub, Inc. All rights reserved." VALUE "OriginalFilename", "electron.exe" VALUE "ProductName", "Electron" - VALUE "ProductVersion", "0.34.1" + VALUE "ProductVersion", "0.34.2" VALUE "SquirrelAwareVersion", "1" END END diff --git a/atom/common/atom_version.h b/atom/common/atom_version.h index 1f8b8dec714f..5b1dc4ab44a6 100644 --- a/atom/common/atom_version.h +++ b/atom/common/atom_version.h @@ -7,7 +7,7 @@ #define ATOM_MAJOR_VERSION 0 #define ATOM_MINOR_VERSION 34 -#define ATOM_PATCH_VERSION 1 +#define ATOM_PATCH_VERSION 2 #define ATOM_VERSION_IS_RELEASE 1 From 9c6987742103c1a2984ac9be2d3ddeb1e0c2070f Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Fri, 30 Oct 2015 10:30:08 +0100 Subject: [PATCH 032/249] Allow v8 to optimize fs.readFileSync --- atom/common/lib/asar.coffee | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/atom/common/lib/asar.coffee b/atom/common/lib/asar.coffee index d2a7799fa694..e7f845bba928 100644 --- a/atom/common/lib/asar.coffee +++ b/atom/common/lib/asar.coffee @@ -254,7 +254,8 @@ exports.wrapFsWithAsar = (fs) -> openSync = fs.openSync readFileSync = fs.readFileSync - fs.readFileSync = (p, options) -> + fs.readFileSync = (p, opts) -> + options = opts # this allows v8 to optimize this function [isAsar, asarPath, filePath] = splitPath p return readFileSync.apply this, arguments unless isAsar From 95ef73ebc16ed2b1592e5602a8756bddb9b4759e Mon Sep 17 00:00:00 2001 From: "Michael J. Zoidl" Date: Fri, 30 Oct 2015 12:17:30 +0100 Subject: [PATCH 033/249] Update autoUpdater api docs The event `quitAndUpdate` event changed to `quitAndInstall` --- docs/api/auto-updater.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/api/auto-updater.md b/docs/api/auto-updater.md index 7649f0f10489..972f93ea5922 100644 --- a/docs/api/auto-updater.md +++ b/docs/api/auto-updater.md @@ -82,7 +82,7 @@ once it is set. Asks the server whether there is an update. You must call `setFeedUrl` before using this API. -### `autoUpdater.quitAndUpdate()` +### `autoUpdater.quitAndInstall()` Restarts the app and install the update after it has been downloaded. It should only be called after `update-downloaded` has been emitted. From 2c59f4567e2e1b707b0e5493188f0106801837e4 Mon Sep 17 00:00:00 2001 From: Robo Date: Fri, 30 Oct 2015 08:34:40 +0530 Subject: [PATCH 034/249] use webcontents id to identify callbacks --- atom/browser/lib/rpc-server.coffee | 15 ++++++++++++--- atom/common/api/atom_api_id_weak_map.cc | 4 ++-- atom/common/api/atom_api_id_weak_map.h | 4 ++-- atom/common/api/lib/callbacks-registry.coffee | 2 -- atom/common/id_weak_map.cc | 15 ++++++--------- atom/common/id_weak_map.h | 6 +++--- 6 files changed, 25 insertions(+), 21 deletions(-) diff --git a/atom/browser/lib/rpc-server.coffee b/atom/browser/lib/rpc-server.coffee index 40e1b0e46ac7..eb97c721396f 100644 --- a/atom/browser/lib/rpc-server.coffee +++ b/atom/browser/lib/rpc-server.coffee @@ -4,8 +4,8 @@ objectsRegistry = require './objects-registry.js' v8Util = process.atomBinding 'v8_util' IDWeakMap = process.atomBinding('id_weak_map').IDWeakMap -# Weak reference to callback with their registry ID. -rendererCallbacks = new IDWeakMap() +# Object mapping from webcontents id to their renderer callbacks weakmap. +rendererRegistry = {} # Convert a real value into meta data. valueToMeta = (sender, value, optimizeSimpleObject=false) -> @@ -74,11 +74,18 @@ unwrapArgs = (sender, args) -> returnValue = metaToValue meta.value -> returnValue when 'function' + webContentsId = sender.getId() + rendererCallbacks = rendererRegistry[webContentsId] + if not rendererCallbacks? + # Weak reference to callbacks with their ID + rendererCallbacks = new IDWeakMap() + rendererRegistry[webContentsId] = rendererCallbacks + if rendererCallbacks.has(meta.id) return rendererCallbacks.get(meta.id) rendererReleased = false - objectsRegistry.once "clear-#{sender.getId()}", -> + objectsRegistry.once "clear-#{webContentsId}", -> rendererReleased = true ret = -> @@ -109,6 +116,8 @@ callFunction = (event, func, caller, args) -> # Send by BrowserWindow when its render view is deleted. process.on 'ATOM_BROWSER_RELEASE_RENDER_VIEW', (id) -> + if rendererRegistry.id? + delete rendererRegistry.id objectsRegistry.clear id ipc.on 'ATOM_BROWSER_REQUIRE', (event, module) -> diff --git a/atom/common/api/atom_api_id_weak_map.cc b/atom/common/api/atom_api_id_weak_map.cc index bdc298fa0c49..8c17e8330ccc 100644 --- a/atom/common/api/atom_api_id_weak_map.cc +++ b/atom/common/api/atom_api_id_weak_map.cc @@ -12,11 +12,11 @@ namespace atom { namespace api { -IDWeakMap::IDWeakMap() { - id_weak_map_.reset(new atom::IDWeakMap); +IDWeakMap::IDWeakMap() : id_weak_map_(new atom::IDWeakMap) { } IDWeakMap::~IDWeakMap() { + id_weak_map_ = nullptr; } void IDWeakMap::Set(v8::Isolate* isolate, diff --git a/atom/common/api/atom_api_id_weak_map.h b/atom/common/api/atom_api_id_weak_map.h index 3acdddc9c75f..4a2f8e397a80 100644 --- a/atom/common/api/atom_api_id_weak_map.h +++ b/atom/common/api/atom_api_id_weak_map.h @@ -22,7 +22,7 @@ class IDWeakMap : public mate::Wrappable { protected: IDWeakMap(); - virtual ~IDWeakMap(); + ~IDWeakMap(); // mate::Wrappable: bool IsDestroyed() const override; @@ -34,7 +34,7 @@ class IDWeakMap : public mate::Wrappable { bool Has(int32_t id); void Remove(int32_t id); - scoped_ptr id_weak_map_; + atom::IDWeakMap* id_weak_map_; DISALLOW_COPY_AND_ASSIGN(IDWeakMap); }; diff --git a/atom/common/api/lib/callbacks-registry.coffee b/atom/common/api/lib/callbacks-registry.coffee index 57f5d0343dc2..001ecae14a61 100644 --- a/atom/common/api/lib/callbacks-registry.coffee +++ b/atom/common/api/lib/callbacks-registry.coffee @@ -22,8 +22,6 @@ class CallbacksRegistry continue if location.indexOf('(native)') isnt -1 continue if location.indexOf('atom.asar') isnt -1 [x, filenameAndLine] = /([^/^\)]*)\)?$/gi.exec(location) - [x, line, column] = /(\d+):(\d+)/g.exec(filenameAndLine) - id += parseInt(line) + parseInt(column) break @callbacks[id] = callback diff --git a/atom/common/id_weak_map.cc b/atom/common/id_weak_map.cc index 7fda009e0ee1..a78dcbceba53 100644 --- a/atom/common/id_weak_map.cc +++ b/atom/common/id_weak_map.cc @@ -32,15 +32,6 @@ IDWeakMap::IDWeakMap() : next_id_(0) { IDWeakMap::~IDWeakMap() { } -int32_t IDWeakMap::Add(v8::Isolate* isolate, v8::Local object) { - int32_t id = GetNextID(); - auto global = make_linked_ptr(new v8::Global(isolate, object)); - ObjectKey* key = new ObjectKey(id, this); - global->SetWeak(key, OnObjectGC, v8::WeakCallbackType::kParameter); - map_[id] = global; - return id; -} - void IDWeakMap::Set(v8::Isolate* isolate, int32_t id, v8::Local object) { @@ -50,6 +41,12 @@ void IDWeakMap::Set(v8::Isolate* isolate, map_[id] = global; } +int32_t IDWeakMap::Add(v8::Isolate* isolate, v8::Local object) { + int32_t id = GetNextID(); + Set(isolate, id, object); + return id; +} + v8::MaybeLocal IDWeakMap::Get(v8::Isolate* isolate, int32_t id) { auto iter = map_.find(id); if (iter == map_.end()) diff --git a/atom/common/id_weak_map.h b/atom/common/id_weak_map.h index 688e85cd0cce..72c64c6ae5d4 100644 --- a/atom/common/id_weak_map.h +++ b/atom/common/id_weak_map.h @@ -19,12 +19,12 @@ class IDWeakMap { IDWeakMap(); ~IDWeakMap(); - // Adds |object| to WeakMap and returns its allocated |id|. - int32_t Add(v8::Isolate* isolate, v8::Local object); - // Sets the object to WeakMap with the given |id|. void Set(v8::Isolate* isolate, int32_t id, v8::Local object); + // Adds |object| to WeakMap and returns its allocated |id|. + int32_t Add(v8::Isolate* isolate, v8::Local object); + // Gets the object from WeakMap by its |id|. v8::MaybeLocal Get(v8::Isolate* isolate, int32_t id); From aa9872035657720354bbf914082156f436d01c42 Mon Sep 17 00:00:00 2001 From: Eric Poulsen Date: Fri, 30 Oct 2015 14:46:18 -0700 Subject: [PATCH 035/249] Update dialog.md Clarification of showErrorBox behavior on Linux if called before app `ready` event. --- docs/api/dialog.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/api/dialog.md b/docs/api/dialog.md index 0fadfa37f80c..a665f7aa081d 100644 --- a/docs/api/dialog.md +++ b/docs/api/dialog.md @@ -114,4 +114,5 @@ will be passed via `callback(response)`. Displays a modal dialog that shows an error message. This API can be called safely before the `ready` event the `app` module emits, -it is usually used to report errors in early stage of startup. +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. From a957ea1ed9b0628a9ab1eed93fdad277e8d40d25 Mon Sep 17 00:00:00 2001 From: bureken Date: Sat, 31 Oct 2015 05:30:18 +0300 Subject: [PATCH 036/249] Replace Mac with OS X --- README.md | 2 +- docs-translations/es/tutorial/using-pepper-flash-plugin.md | 2 +- docs-translations/pt-BR/tutorial/using-pepper-flash-plugin.md | 2 +- docs/tutorial/using-pepper-flash-plugin.md | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index dd03f7099e10..8fb9128d9c10 100644 --- a/README.md +++ b/README.md @@ -20,7 +20,7 @@ unacceptable behavior to atom@github.com. ## Downloads -Prebuilt binaries and debug symbols of Electron for Linux, Windows and Mac can +Prebuilt binaries and debug symbols of Electron for Linux, Windows and OS X can be found on the [releases](https://github.com/atom/electron/releases) page. You can also use [`npm`](https://docs.npmjs.com/) to install prebuilt electron diff --git a/docs-translations/es/tutorial/using-pepper-flash-plugin.md b/docs-translations/es/tutorial/using-pepper-flash-plugin.md index fbb2b6f83aa0..53d2d024c1d1 100644 --- a/docs-translations/es/tutorial/using-pepper-flash-plugin.md +++ b/docs-translations/es/tutorial/using-pepper-flash-plugin.md @@ -31,7 +31,7 @@ app.on('window-all-closed', function() { // Specify flash path. // On Windows, it might be /path/to/pepflashplayer.dll -// On Mac, /path/to/PepperFlashPlayer.plugin +// On OS X, /path/to/PepperFlashPlayer.plugin // On Linux, /path/to/libpepflashplayer.so app.commandLine.appendSwitch('ppapi-flash-path', '/path/to/libpepflashplayer.so'); diff --git a/docs-translations/pt-BR/tutorial/using-pepper-flash-plugin.md b/docs-translations/pt-BR/tutorial/using-pepper-flash-plugin.md index a92f61c78e28..dfcca01a5c7e 100644 --- a/docs-translations/pt-BR/tutorial/using-pepper-flash-plugin.md +++ b/docs-translations/pt-BR/tutorial/using-pepper-flash-plugin.md @@ -39,7 +39,7 @@ app.on('window-all-closed', function() { // Epecifica o caminho do flash. // No Windows, deve ser /path/to/pepflashplayer.dll -// No Mac, /path/to/PepperFlashPlayer.plugin +// No OS X, /path/to/PepperFlashPlayer.plugin // No Linux, /path/to/libpepflashplayer.so app.commandLine.appendSwitch('ppapi-flash-path', '/path/to/libpepflashplayer.so'); diff --git a/docs/tutorial/using-pepper-flash-plugin.md b/docs/tutorial/using-pepper-flash-plugin.md index 5c8820c2fad4..9321798ffca4 100644 --- a/docs/tutorial/using-pepper-flash-plugin.md +++ b/docs/tutorial/using-pepper-flash-plugin.md @@ -38,7 +38,7 @@ app.on('window-all-closed', function() { // Specify flash path. // On Windows, it might be /path/to/pepflashplayer.dll -// On Mac, /path/to/PepperFlashPlayer.plugin +// On OS X, /path/to/PepperFlashPlayer.plugin // On Linux, /path/to/libpepflashplayer.so app.commandLine.appendSwitch('ppapi-flash-path', '/path/to/libpepflashplayer.so'); From db3cd1af36a4b54a4f7d2296db88deb78a8316bc Mon Sep 17 00:00:00 2001 From: Jesus David Rojas Date: Fri, 30 Oct 2015 14:30:39 -0430 Subject: [PATCH 037/249] =?UTF-8?q?Translate=20"Diferencias=20T=C3=A9cnica?= =?UTF-8?q?s=20con=20NW.js"?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs-translations/es/README.md | 2 +- .../development/atom-shell-vs-node-webkit.md | 34 +++++++++++++++++++ 2 files changed, 35 insertions(+), 1 deletion(-) create mode 100644 docs-translations/es/development/atom-shell-vs-node-webkit.md diff --git a/docs-translations/es/README.md b/docs-translations/es/README.md index 687dff4bde2d..ee2c52b98f85 100644 --- a/docs-translations/es/README.md +++ b/docs-translations/es/README.md @@ -63,7 +63,7 @@ * [Guía de Estilo](development/coding-style.md) * [Estructura de los directorios del Código Fuente](development/source-code-directory-structure.md) -* [Diferencias Técnicas con NW.js (anteriormente conocido como node-webkit)](../../development/atom-shell-vs-node-webkit.md) +* [Diferencias Técnicas con NW.js (anteriormente conocido como node-webkit)](development/atom-shell-vs-node-webkit.md) * [Repaso del Sistema de Compilación](../../development/build-system-overview.md) * [Instrucciones de Compilación (Mac)](../../development/build-instructions-osx.md) * [Instrucciones de Compilación (Windows)](../../development/build-instructions-windows.md) diff --git a/docs-translations/es/development/atom-shell-vs-node-webkit.md b/docs-translations/es/development/atom-shell-vs-node-webkit.md new file mode 100644 index 000000000000..4072976a2ff4 --- /dev/null +++ b/docs-translations/es/development/atom-shell-vs-node-webkit.md @@ -0,0 +1,34 @@ +#Diferencias Técnicas entre Electron y NW.js (anteriormente conocido como node-webkit) + +**Nota:Electron se llamaba antes Atom Shell.** + +Como NW.js, Electron proporciona una plataforma para escribir aplicaciones de escritorio con JavaScript y HTML y tiene la integración de nodo para permitir el acceso al sistema de bajo nivel de las páginas web. + +Pero también hay diferencias fundamentales entre los dos proyectos que hacen a Electron un producto totalmente independiente de NW.js: + +**1. Ingreso a la aplicación** + +En NW.js el principal punto de ingreso de una aplicación es una página web. Usted especifica una página principal de URL en el `package.json` y se abre en una ventana del navegador como ventana principal de la aplicación. + +En Electron, el punto de ingreso es un script de JavaScript. En lugar de proporcionar una dirección URL directamente, usted crea manualmente una ventana del navegador y carga un archivo HTML utilizando la API. También es necesario escuchar a los eventos de la ventana para decidir cuándo salir de la aplicación. + +Electron funciona más como el tiempo de ejecución(Runtime) de Node.js. Las Api's de Electron son de bajo nivel asi que puede usarlo para las pruebas del navegador en lugar de usar [PhantomJS.](http://phantomjs.org/) + +**2.Construir un sistema** + +Con el fin de evitar la complejidad de la construcción de todo Chromium, Electron utiliza `libchromiumcontent` para acceder a al contenido Chromium's API. `libchromiumcontent` es solo una liberia compartida que incluye el módulo de contenido de Chromium y todas sus dependencias. Los usuarios no necesitan una máquina potente para construir con Electron. + +**3.Integración de Node** + +In NW.js, the Node integration in web pages requires patching Chromium to work, while in Electron we chose a different way to integrate the libuv loop with each platform's message loop to avoid hacking Chromium. See the node_bindings code for how that was done. + +En NW.js, la integración de Node en las páginas web requiere parchear Chromium para que funcione, mientras que en Electron elegimos una manera diferente para integrar el cilco libuv con cada ciclo de mensaje de las plataformas para evitar el hacking en Chromium. Ver el código `node_bindings` de cómo se hizo. + + +**4. Multi-contexto** + +Si usted es un usuario experimentado NW.js, usted debe estar familiarizado con el concepto de contexto Node y el contexto web. Estos conceptos fueron inventados debido a la forma cómo se implementó NW.js. + +Mediante el uso de la característica [multi-contexto](http://strongloop.com/strongblog/whats-new-node-js-v0-12-multiple-context-execution/) de Node, Electron no introduce un nuevo contexto JavaScript en páginas web.Resultados de búsqueda + + From cb91d4487b2e961503f3e8e01dcc207f2ba58b7e Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Sat, 31 Oct 2015 15:00:06 +0800 Subject: [PATCH 038/249] Clean up the code handling renderer callback --- atom/browser/lib/rpc-server.coffee | 26 +++++++------------ atom/common/api/atom_api_id_weak_map.cc | 18 ++++++------- atom/common/api/atom_api_id_weak_map.h | 6 ++--- atom/common/api/lib/callbacks-registry.coffee | 7 ++--- 4 files changed, 24 insertions(+), 33 deletions(-) diff --git a/atom/browser/lib/rpc-server.coffee b/atom/browser/lib/rpc-server.coffee index eb97c721396f..24ece2205cac 100644 --- a/atom/browser/lib/rpc-server.coffee +++ b/atom/browser/lib/rpc-server.coffee @@ -4,9 +4,6 @@ objectsRegistry = require './objects-registry.js' v8Util = process.atomBinding 'v8_util' IDWeakMap = process.atomBinding('id_weak_map').IDWeakMap -# Object mapping from webcontents id to their renderer callbacks weakmap. -rendererRegistry = {} - # Convert a real value into meta data. valueToMeta = (sender, value, optimizeSimpleObject=false) -> meta = type: typeof value @@ -74,18 +71,15 @@ unwrapArgs = (sender, args) -> returnValue = metaToValue meta.value -> returnValue when 'function' - webContentsId = sender.getId() - rendererCallbacks = rendererRegistry[webContentsId] - if not rendererCallbacks? - # Weak reference to callbacks with their ID - rendererCallbacks = new IDWeakMap() - rendererRegistry[webContentsId] = rendererCallbacks - - if rendererCallbacks.has(meta.id) - return rendererCallbacks.get(meta.id) + # Cache the callbacks in renderer. + unless sender.callbacks + sender.callbacks = new IDWeakMap + sender.on 'render-view-deleted', -> + sender.callbacks.clear() + return sender.callbacks.get meta.id if sender.callbacks.has meta.id rendererReleased = false - objectsRegistry.once "clear-#{webContentsId}", -> + objectsRegistry.once "clear-#{sender.getId()}", -> rendererReleased = true ret = -> @@ -95,9 +89,9 @@ unwrapArgs = (sender, args) -> sender.send 'ATOM_RENDERER_CALLBACK', meta.id, valueToMeta(sender, arguments) v8Util.setDestructor ret, -> return if rendererReleased - rendererCallbacks.remove meta.id + sender.callbacks.remove meta.id sender.send 'ATOM_RENDERER_RELEASE_CALLBACK', meta.id - rendererCallbacks.set meta.id, ret + sender.callbacks.set meta.id, ret ret else throw new TypeError("Unknown type: #{meta.type}") @@ -116,8 +110,6 @@ callFunction = (event, func, caller, args) -> # Send by BrowserWindow when its render view is deleted. process.on 'ATOM_BROWSER_RELEASE_RENDER_VIEW', (id) -> - if rendererRegistry.id? - delete rendererRegistry.id objectsRegistry.clear id ipc.on 'ATOM_BROWSER_REQUIRE', (event, module) -> diff --git a/atom/common/api/atom_api_id_weak_map.cc b/atom/common/api/atom_api_id_weak_map.cc index 8c17e8330ccc..f32e33682dff 100644 --- a/atom/common/api/atom_api_id_weak_map.cc +++ b/atom/common/api/atom_api_id_weak_map.cc @@ -12,33 +12,32 @@ namespace atom { namespace api { -IDWeakMap::IDWeakMap() : id_weak_map_(new atom::IDWeakMap) { +IDWeakMap::IDWeakMap() { } IDWeakMap::~IDWeakMap() { - id_weak_map_ = nullptr; } void IDWeakMap::Set(v8::Isolate* isolate, int32_t id, v8::Local object) { - id_weak_map_->Set(isolate, id, object); + id_weak_map_.Set(isolate, id, object); } v8::Local IDWeakMap::Get(v8::Isolate* isolate, int32_t id) { - return id_weak_map_->Get(isolate, id).ToLocalChecked(); + return id_weak_map_.Get(isolate, id).ToLocalChecked(); } bool IDWeakMap::Has(int32_t id) { - return id_weak_map_->Has(id); + return id_weak_map_.Has(id); } void IDWeakMap::Remove(int32_t id) { - id_weak_map_->Remove(id); + id_weak_map_.Remove(id); } -bool IDWeakMap::IsDestroyed() const { - return !id_weak_map_; +void IDWeakMap::Clear() { + id_weak_map_.Clear(); } // static @@ -48,7 +47,8 @@ void IDWeakMap::BuildPrototype(v8::Isolate* isolate, .SetMethod("set", &IDWeakMap::Set) .SetMethod("get", &IDWeakMap::Get) .SetMethod("has", &IDWeakMap::Has) - .SetMethod("remove", &IDWeakMap::Remove); + .SetMethod("remove", &IDWeakMap::Remove) + .SetMethod("clear", &IDWeakMap::Clear); } // static diff --git a/atom/common/api/atom_api_id_weak_map.h b/atom/common/api/atom_api_id_weak_map.h index 4a2f8e397a80..0cf656f455bc 100644 --- a/atom/common/api/atom_api_id_weak_map.h +++ b/atom/common/api/atom_api_id_weak_map.h @@ -24,17 +24,15 @@ class IDWeakMap : public mate::Wrappable { IDWeakMap(); ~IDWeakMap(); - // mate::Wrappable: - bool IsDestroyed() const override; - private: // Api for IDWeakMap. void Set(v8::Isolate* isolate, int32_t id, v8::Local object); v8::Local Get(v8::Isolate* isolate, int32_t id); bool Has(int32_t id); void Remove(int32_t id); + void Clear(); - atom::IDWeakMap* id_weak_map_; + atom::IDWeakMap id_weak_map_; DISALLOW_COPY_AND_ASSIGN(IDWeakMap); }; diff --git a/atom/common/api/lib/callbacks-registry.coffee b/atom/common/api/lib/callbacks-registry.coffee index 001ecae14a61..c546df34f9a8 100644 --- a/atom/common/api/lib/callbacks-registry.coffee +++ b/atom/common/api/lib/callbacks-registry.coffee @@ -7,8 +7,9 @@ class CallbacksRegistry @callbacks = {} add: (callback) -> - if v8Util.getHiddenValue(callback, 'metaId')? - return v8Util.getHiddenValue(callback, 'metaId') + # The callback is already added. + id = v8Util.getHiddenValue callback, 'callbackId' + return id if id? id = ++@nextId @@ -25,7 +26,7 @@ class CallbacksRegistry break @callbacks[id] = callback - v8Util.setHiddenValue callback, 'metaId', id + v8Util.setHiddenValue callback, 'callbackId', id v8Util.setHiddenValue callback, 'location', filenameAndLine id From 6a02586176cb5d8c483fff73c075b5cac20d9341 Mon Sep 17 00:00:00 2001 From: Paul Betts Date: Sat, 31 Oct 2015 08:57:04 -0700 Subject: [PATCH 039/249] Add Windows version of running cmd --- docs/tutorial/using-native-node-modules.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/docs/tutorial/using-native-node-modules.md b/docs/tutorial/using-native-node-modules.md index 6954fc64b1a1..2defedd74183 100644 --- a/docs/tutorial/using-native-node-modules.md +++ b/docs/tutorial/using-native-node-modules.md @@ -33,6 +33,9 @@ npm install --save-dev electron-rebuild # Every time you run "npm install", run this ./node_modules/.bin/electron-rebuild + +# On Windows if you have trouble, try: +.\node_modules\.bin\electron-rebuild.cmd ``` ### The npm Way From c969052f1256643fd746e5320f7cfdad8d9a3f27 Mon Sep 17 00:00:00 2001 From: Robo Date: Sat, 31 Oct 2015 19:09:07 +0530 Subject: [PATCH 040/249] browser: handle flash context menu --- atom/browser/api/atom_api_app.cc | 2 +- atom/browser/api/atom_api_protocol.cc | 2 +- atom/browser/api/atom_api_web_contents.cc | 20 ++++++++ atom/browser/api/atom_api_web_contents.h | 7 +++ atom/browser/api/lib/web-contents.coffee | 41 +++++++++++++++++ .../content_converter.cc | 46 +++++++++++++------ .../content_converter.h | 14 +++--- .../native_mate_converters/net_converter.cc | 34 ++++++++++++++ .../native_mate_converters/net_converter.h | 31 +++++++++++++ filenames.gypi | 2 + 10 files changed, 177 insertions(+), 22 deletions(-) create mode 100644 atom/common/native_mate_converters/net_converter.cc create mode 100644 atom/common/native_mate_converters/net_converter.h diff --git a/atom/browser/api/atom_api_app.cc b/atom/browser/api/atom_api_app.cc index 21a553e4d1d5..bd49f9fddc05 100644 --- a/atom/browser/api/atom_api_app.cc +++ b/atom/browser/api/atom_api_app.cc @@ -19,7 +19,7 @@ #include "atom/browser/browser.h" #include "atom/browser/login_handler.h" #include "atom/common/native_mate_converters/callback.h" -#include "atom/common/native_mate_converters/content_converter.h" +#include "atom/common/native_mate_converters/net_converter.h" #include "atom/common/native_mate_converters/file_path_converter.h" #include "atom/common/node_includes.h" #include "atom/common/options_switches.h" diff --git a/atom/browser/api/atom_api_protocol.cc b/atom/browser/api/atom_api_protocol.cc index f6cc6d796557..e76f26f0d4f5 100644 --- a/atom/browser/api/atom_api_protocol.cc +++ b/atom/browser/api/atom_api_protocol.cc @@ -12,7 +12,7 @@ #include "atom/browser/net/url_request_fetch_job.h" #include "atom/browser/net/url_request_string_job.h" #include "atom/common/native_mate_converters/callback.h" -#include "atom/common/native_mate_converters/content_converter.h" +#include "atom/common/native_mate_converters/net_converter.h" #include "atom/common/node_includes.h" #include "native_mate/dictionary.h" diff --git a/atom/browser/api/atom_api_web_contents.cc b/atom/browser/api/atom_api_web_contents.cc index 900c3e65a376..fa40296f57d8 100644 --- a/atom/browser/api/atom_api_web_contents.cc +++ b/atom/browser/api/atom_api_web_contents.cc @@ -18,6 +18,7 @@ #include "atom/common/api/event_emitter_caller.h" #include "atom/common/native_mate_converters/blink_converter.h" #include "atom/common/native_mate_converters/callback.h" +#include "atom/common/native_mate_converters/content_converter.h" #include "atom/common/native_mate_converters/file_path_converter.h" #include "atom/common/native_mate_converters/gfx_converter.h" #include "atom/common/native_mate_converters/gurl_converter.h" @@ -404,6 +405,12 @@ void WebContents::RendererResponsive(content::WebContents* source) { owner_window()->RendererResponsive(source); } +bool WebContents::HandleContextMenu(const content::ContextMenuParams& params) { + context_menu_context_ = params.custom_context; + Emit("-context-menu", params); + return true; +} + void WebContents::BeforeUnloadFired(const base::TimeTicks& proceed_time) { // Do nothing, we override this method just to avoid compilation error since // there are two virtual functions named BeforeUnloadFired. @@ -840,6 +847,15 @@ void WebContents::RemoveWorkSpace(mate::Arguments* args, DevToolsRemoveFileSystem(path); } +void WebContents::ExecuteContextMenuCommand(int action) { + web_contents()->ExecuteCustomContextMenuCommand(action, + context_menu_context_); +} + +void WebContents::NotifyContextMenuClosed() { + web_contents()->NotifyContextMenuClosed(context_menu_context_); +} + void WebContents::Undo() { web_contents()->Undo(); } @@ -1051,6 +1067,10 @@ mate::ObjectTemplateBuilder WebContents::GetObjectTemplateBuilder( .SetMethod("_printToPDF", &WebContents::PrintToPDF) .SetMethod("addWorkSpace", &WebContents::AddWorkSpace) .SetMethod("removeWorkSpace", &WebContents::RemoveWorkSpace) + .SetMethod("_executeContextMenuCommand", + &WebContents::ExecuteContextMenuCommand) + .SetMethod("_notifyContextMenuClosed", + &WebContents::NotifyContextMenuClosed) .SetProperty("session", &WebContents::Session, true) .SetProperty("devToolsWebContents", &WebContents::DevToolsWebContents, true) diff --git a/atom/browser/api/atom_api_web_contents.h b/atom/browser/api/atom_api_web_contents.h index 7fa8951106b2..5a55ad2abd7a 100644 --- a/atom/browser/api/atom_api_web_contents.h +++ b/atom/browser/api/atom_api_web_contents.h @@ -13,6 +13,7 @@ #include "atom/browser/api/trackable_object.h" #include "atom/browser/common_web_contents_delegate.h" #include "content/public/browser/web_contents_observer.h" +#include "content/public/common/context_menu_params.h" #include "content/public/common/favicon_url.h" #include "native_mate/handle.h" #include "ui/gfx/image/image.h" @@ -92,6 +93,8 @@ class WebContents : public mate::TrackableObject, void SetAudioMuted(bool muted); bool IsAudioMuted(); void Print(mate::Arguments* args); + void ExecuteContextMenuCommand(int action); + void NotifyContextMenuClosed(); // Print current page as PDF. void PrintToPDF(const base::DictionaryValue& setting, @@ -189,6 +192,7 @@ class WebContents : public mate::TrackableObject, void ExitFullscreenModeForTab(content::WebContents* source) override; void RendererUnresponsive(content::WebContents* source) override; void RendererResponsive(content::WebContents* source) override; + bool HandleContextMenu(const content::ContextMenuParams& params) override; // content::WebContentsObserver: void BeforeUnloadFired(const base::TimeTicks& proceed_time) override; @@ -255,6 +259,9 @@ class WebContents : public mate::TrackableObject, // embedders' zoom level change. void OnZoomLevelChanged(double level); + // Recent unhandled context menu context. + content::CustomContextMenuContext context_menu_context_; + v8::Global session_; v8::Global devtools_web_contents_; diff --git a/atom/browser/api/lib/web-contents.coffee b/atom/browser/api/lib/web-contents.coffee index 3a2abfb5155f..afe70323f0a5 100644 --- a/atom/browser/api/lib/web-contents.coffee +++ b/atom/browser/api/lib/web-contents.coffee @@ -1,4 +1,5 @@ EventEmitter = require('events').EventEmitter +Menu = require './menu' NavigationController = require './navigation-controller' binding = process.atomBinding 'web_contents' ipc = require 'ipc' @@ -34,6 +35,36 @@ PDFPageSize = width_microns: 279400 custom_display_name: "Tabloid" +clickHandler = (action) -> + @_executeContextMenuCommand action + +convertToMenuTemplate = (items, handler) -> + template = [] + for item in items + do (item) -> + transformed = + if item.type is 'submenu' + type: 'submenu' + label: item.label + enabled: item.enabled + submenu: convertToMenuTemplate item.subItems, handler + else if item.type is 'separator' + type: 'separator' + else if item.type is 'checkbox' + type: 'checkbox' + label: item.label + enabled: item.enabled + checked: item.checked + else + type: 'normal' + label: item.label + enabled: item.enabled + if item.id? + transformed.click = -> + handler item.id + template.push transformed + template + wrapWebContents = (webContents) -> # webContents is an EventEmitter. webContents.__proto__ = EventEmitter.prototype @@ -65,6 +96,16 @@ wrapWebContents = (webContents) -> Object.defineProperty event, 'returnValue', set: (value) -> event.sendReply JSON.stringify(value) ipc.emit channel, event, args... + # Handle context menu action request from renderer widget. + webContents.on '-context-menu', (event, params) -> + if params.isPepperMenu + template = convertToMenuTemplate(params.menuItems, clickHandler.bind(webContents)) + menu = Menu.buildFromTemplate template + # The menu is expected to show asynchronously. + setImmediate -> + menu.popup params.x, params.y + webContents._notifyContextMenuClosed() + webContents.printToPDF = (options, callback) -> printingSetting = pageRage: [] diff --git a/atom/common/native_mate_converters/content_converter.cc b/atom/common/native_mate_converters/content_converter.cc index b6f3a2c1cc03..2318e7d8e837 100644 --- a/atom/common/native_mate_converters/content_converter.cc +++ b/atom/common/native_mate_converters/content_converter.cc @@ -4,30 +4,50 @@ #include "atom/common/native_mate_converters/content_converter.h" +#include "atom/common/native_mate_converters/string16_converter.h" +#include "content/public/common/context_menu_params.h" +#include "content/public/common/menu_item.h" #include "native_mate/dictionary.h" -#include "net/url_request/url_request.h" namespace mate { +template<> +struct Converter { + static v8::Local ToV8(v8::Isolate* isolate, + const content::MenuItem::Type& val) { + switch (val) { + case content::MenuItem::CHECKABLE_OPTION: + return StringToV8(isolate, "checkbox"); + case content::MenuItem::SEPARATOR: + return StringToV8(isolate, "separator"); + case content::MenuItem::SUBMENU: + return StringToV8(isolate, "submenu"); + default: + return StringToV8(isolate, "normal"); + } + } +}; + // static -v8::Local Converter::ToV8( - v8::Isolate* isolate, const net::URLRequest* val) { +v8::Local Converter::ToV8( + v8::Isolate* isolate, const content::MenuItem& val) { mate::Dictionary dict = mate::Dictionary::CreateEmpty(isolate); - dict.Set("method", val->method()); - dict.Set("url", val->url().spec()); - dict.Set("referrer", val->referrer()); + dict.Set("id", val.action); + dict.Set("type", val.type); + dict.Set("label", val.label); + dict.Set("enabled", val.enabled); + dict.Set("checked", val.checked); return mate::ConvertToV8(isolate, dict); } // static -v8::Local Converter::ToV8( - v8::Isolate* isolate, const net::AuthChallengeInfo* val) { +v8::Local Converter::ToV8( + v8::Isolate* isolate, const content::ContextMenuParams& val) { mate::Dictionary dict = mate::Dictionary::CreateEmpty(isolate); - dict.Set("isProxy", val->is_proxy); - dict.Set("scheme", val->scheme); - dict.Set("host", val->challenger.host()); - dict.Set("port", static_cast(val->challenger.port())); - dict.Set("realm", val->realm); + dict.Set("x", val.x); + dict.Set("y", val.y); + dict.Set("isPepperMenu", val.custom_context.is_pepper_menu); + dict.Set("menuItems", val.custom_items); return mate::ConvertToV8(isolate, dict); } diff --git a/atom/common/native_mate_converters/content_converter.h b/atom/common/native_mate_converters/content_converter.h index 0d4d5fe2cce0..5cca2b38b251 100644 --- a/atom/common/native_mate_converters/content_converter.h +++ b/atom/common/native_mate_converters/content_converter.h @@ -7,23 +7,23 @@ #include "native_mate/converter.h" -namespace net { -class AuthChallengeInfo; -class URLRequest; +namespace content { +struct ContextMenuParams; +struct MenuItem; } namespace mate { template<> -struct Converter { +struct Converter { static v8::Local ToV8(v8::Isolate* isolate, - const net::URLRequest* val); + const content::MenuItem& val); }; template<> -struct Converter { +struct Converter { static v8::Local ToV8(v8::Isolate* isolate, - const net::AuthChallengeInfo* val); + const content::ContextMenuParams& val); }; } // namespace mate diff --git a/atom/common/native_mate_converters/net_converter.cc b/atom/common/native_mate_converters/net_converter.cc new file mode 100644 index 000000000000..4796d962660a --- /dev/null +++ b/atom/common/native_mate_converters/net_converter.cc @@ -0,0 +1,34 @@ +// Copyright (c) 2015 GitHub, Inc. +// Use of this source code is governed by the MIT license that can be +// found in the LICENSE file. + +#include "atom/common/native_mate_converters/net_converter.h" + +#include "native_mate/dictionary.h" +#include "net/url_request/url_request.h" + +namespace mate { + +// static +v8::Local Converter::ToV8( + v8::Isolate* isolate, const net::URLRequest* val) { + mate::Dictionary dict = mate::Dictionary::CreateEmpty(isolate); + dict.Set("method", val->method()); + dict.Set("url", val->url().spec()); + dict.Set("referrer", val->referrer()); + return mate::ConvertToV8(isolate, dict); +} + +// static +v8::Local Converter::ToV8( + v8::Isolate* isolate, const net::AuthChallengeInfo* val) { + mate::Dictionary dict = mate::Dictionary::CreateEmpty(isolate); + dict.Set("isProxy", val->is_proxy); + dict.Set("scheme", val->scheme); + dict.Set("host", val->challenger.host()); + dict.Set("port", static_cast(val->challenger.port())); + dict.Set("realm", val->realm); + return mate::ConvertToV8(isolate, dict); +} + +} // namespace mate diff --git a/atom/common/native_mate_converters/net_converter.h b/atom/common/native_mate_converters/net_converter.h new file mode 100644 index 000000000000..352c613eaabb --- /dev/null +++ b/atom/common/native_mate_converters/net_converter.h @@ -0,0 +1,31 @@ +// Copyright (c) 2015 GitHub, Inc. +// Use of this source code is governed by the MIT license that can be +// found in the LICENSE file. + +#ifndef ATOM_COMMON_NATIVE_MATE_CONVERTERS_NET_CONVERTER_H_ +#define ATOM_COMMON_NATIVE_MATE_CONVERTERS_NET_CONVERTER_H_ + +#include "native_mate/converter.h" + +namespace net { +class AuthChallengeInfo; +class URLRequest; +} + +namespace mate { + +template<> +struct Converter { + static v8::Local ToV8(v8::Isolate* isolate, + const net::URLRequest* val); +}; + +template<> +struct Converter { + static v8::Local ToV8(v8::Isolate* isolate, + const net::AuthChallengeInfo* val); +}; + +} // namespace mate + +#endif // ATOM_COMMON_NATIVE_MATE_CONVERTERS_NET_CONVERTER_H_ diff --git a/filenames.gypi b/filenames.gypi index ba739764f492..0e70347309c0 100644 --- a/filenames.gypi +++ b/filenames.gypi @@ -316,6 +316,8 @@ 'atom/common/native_mate_converters/gurl_converter.h', 'atom/common/native_mate_converters/image_converter.cc', 'atom/common/native_mate_converters/image_converter.h', + 'atom/common/native_mate_converters/net_converter.cc', + 'atom/common/native_mate_converters/net_converter.h', 'atom/common/native_mate_converters/string16_converter.h', 'atom/common/native_mate_converters/v8_value_converter.cc', 'atom/common/native_mate_converters/v8_value_converter.h', From 5b49655d1fc7af269e77dc13a07edc89b09930b6 Mon Sep 17 00:00:00 2001 From: Eric Poulsen Date: Sat, 31 Oct 2015 16:04:01 -0700 Subject: [PATCH 041/249] Update dialog.md --- docs/api/dialog.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/docs/api/dialog.md b/docs/api/dialog.md index a665f7aa081d..6acfb79884e3 100644 --- a/docs/api/dialog.md +++ b/docs/api/dialog.md @@ -114,5 +114,6 @@ will be passed via `callback(response)`. Displays a modal dialog that shows an error message. This API can be called safely before the `ready` event the `app` module emits, -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. +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. From bbb5aef5d268c4f64801c8f96c1bf3e18a9cf836 Mon Sep 17 00:00:00 2001 From: Max Claus Nunes Date: Sat, 31 Oct 2015 21:20:54 -0200 Subject: [PATCH 042/249] Improve error handling from remote This way copy all properties available in the error object and keep the real stack trace --- atom/browser/lib/rpc-server.coffee | 9 ++++++++- atom/renderer/api/lib/remote.coffee | 13 ++++++++++++- 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/atom/browser/lib/rpc-server.coffee b/atom/browser/lib/rpc-server.coffee index 24ece2205cac..953436e16f37 100644 --- a/atom/browser/lib/rpc-server.coffee +++ b/atom/browser/lib/rpc-server.coffee @@ -40,7 +40,7 @@ valueToMeta = (sender, value, optimizeSimpleObject=false) -> else if meta.type is 'promise' meta.then = valueToMeta(sender, value.then.bind(value)) else if meta.type is 'error' - meta.message = value.message + meta = errorValueToMeta(value, meta) else if meta.type is 'date' meta.value = value.getTime() else @@ -49,6 +49,13 @@ valueToMeta = (sender, value, optimizeSimpleObject=false) -> meta +# Convert Error into meta data. +errorValueToMeta = (err, meta) -> + Object.getOwnPropertyNames(err).reduce((obj, key) -> + obj[key] = err[key] + obj + , meta) + # Convert Error into meta data. exceptionToMeta = (error) -> type: 'exception', message: error.message, stack: (error.stack || error) diff --git a/atom/renderer/api/lib/remote.coffee b/atom/renderer/api/lib/remote.coffee index b5a3a694ee37..d01027e27de0 100644 --- a/atom/renderer/api/lib/remote.coffee +++ b/atom/renderer/api/lib/remote.coffee @@ -46,7 +46,7 @@ metaToValue = (meta) -> when 'array' then (metaToValue(el) for el in meta.members) when 'buffer' then new Buffer(meta.value) when 'promise' then Promise.resolve(then: metaToValue(meta.then)) - when 'error' then new Error(meta.message) + when 'error' then metaToError(meta) when 'date' then new Date(meta.value) when 'exception' throw new Error("#{meta.message}\n#{meta.stack}") @@ -110,6 +110,17 @@ metaToValue = (meta) -> ret +# Convert meta data from browser into Error. +metaToError = (meta) -> + Object.getOwnPropertyNames(meta).reduce((error, prop) -> + Object.defineProperty(error, prop, { + get: -> meta[prop], + enumerable: false, + configurable: false + }) + error + , new Error()) + # Browser calls a callback in renderer. ipc.on 'ATOM_RENDERER_CALLBACK', (id, args) -> callbacksRegistry.apply id, metaToValue(args) From d097082baf74d64c861c3585aeb936b3767e285c Mon Sep 17 00:00:00 2001 From: Greg Gamel Date: Sat, 31 Oct 2015 21:25:07 -0500 Subject: [PATCH 043/249] Update auto-updater.md to improve readability Fix minor grammatical mistakes, correct sentence structures, and improve readability. --- docs/api/auto-updater.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/docs/api/auto-updater.md b/docs/api/auto-updater.md index 972f93ea5922..bda1d46bb094 100644 --- a/docs/api/auto-updater.md +++ b/docs/api/auto-updater.md @@ -4,27 +4,27 @@ This module provides an interface for the `Squirrel` auto-updater framework. ## Platform notices -Though `autoUpdater` provides an uniform API for different platforms, there are +Though `autoUpdater` provides a uniform API for different platforms, there are still some subtle differences on each platform. ### OS X -On OS X the `autoUpdater` module is built upon [Squirrel.Mac][squirrel-mac], you +On OS X, the `autoUpdater` module is built upon [Squirrel.Mac][squirrel-mac], meaning you don't need any special setup to make it work. For server-side requirements, you can read [Server Support][server-support]. ### Windows -On Windows you have to install your app into user's machine before you can use -the auto-updater, it is recommended to use [grunt-electron-installer][installer] +On Windows, you have to install your app into a user's machine before you can use +the auto-updater, so it is recommended to use [grunt-electron-installer][installer] module to generate a Windows installer. -The server-side setup is also different from OS X, you can read the documents of +The server-side setup is also different from OS X. You can read the documents of [Squirrel.Windows][squirrel-windows] to get more details. ### Linux -There is not built-in support for auto-updater on Linux, it is recommended to +There is not built-in support for auto-updater on Linux, so it is recommended to use the distribution's package manager to update your app. ## Events @@ -84,7 +84,7 @@ using this API. ### `autoUpdater.quitAndInstall()` -Restarts the app and install the update after it has been downloaded. It should +Restarts the app and installs the update after it has been downloaded. It should only be called after `update-downloaded` has been emitted. [squirrel-mac]: https://github.com/Squirrel/Squirrel.Mac From f7108af36b63e1e968b5551a891c9660e5a59a6a Mon Sep 17 00:00:00 2001 From: Jesus David Rojas Date: Fri, 30 Oct 2015 14:30:39 -0430 Subject: [PATCH 044/249] Spanish translations of the documents --- docs-translations/es/README.md | 6 +- .../development/build-instructions-linux.md | 96 +++++++++++++++++++ .../es/development/build-instructions-osx.md | 48 ++++++++++ .../es/development/build-system-overview.md | 35 +++++++ 4 files changed, 182 insertions(+), 3 deletions(-) create mode 100644 docs-translations/es/development/build-instructions-linux.md create mode 100644 docs-translations/es/development/build-instructions-osx.md create mode 100644 docs-translations/es/development/build-system-overview.md diff --git a/docs-translations/es/README.md b/docs-translations/es/README.md index ee2c52b98f85..e69e76b1c4c7 100644 --- a/docs-translations/es/README.md +++ b/docs-translations/es/README.md @@ -64,8 +64,8 @@ * [Guía de Estilo](development/coding-style.md) * [Estructura de los directorios del Código Fuente](development/source-code-directory-structure.md) * [Diferencias Técnicas con NW.js (anteriormente conocido como node-webkit)](development/atom-shell-vs-node-webkit.md) -* [Repaso del Sistema de Compilación](../../development/build-system-overview.md) -* [Instrucciones de Compilación (Mac)](../../development/build-instructions-osx.md) +* [Repaso del Sistema de Compilación](development/build-system-overview.md) +* [Instrucciones de Compilación (Mac)](development/build-instructions-osx.md) * [Instrucciones de Compilación (Windows)](../../development/build-instructions-windows.md) -* [Instrucciones de Compilación (Linux)](../../development/build-instructions-linux.md) +* [Instrucciones de Compilación (Linux)](development/build-instructions-linux.md) * [Configurando un Servidor de Símbolos en el depurador](../../development/setting-up-symbol-server.md) diff --git a/docs-translations/es/development/build-instructions-linux.md b/docs-translations/es/development/build-instructions-linux.md new file mode 100644 index 000000000000..28ad828fa709 --- /dev/null +++ b/docs-translations/es/development/build-instructions-linux.md @@ -0,0 +1,96 @@ +#Instrucciones de Compilación (Linux) + +Siga las siguientes pautas para la construcción de Electron en Linux. +#Requisitos previos + + * Python 2.7.x. Algunas distribuciones como CentOS siguen utilizando Python 2.6.x por lo que puede que tenga que comprobar su versión de Python con `Python -V`. + * Node.js v0.12.x. Hay varias formas de instalar Node. Puede descargar el código fuente de Node.js y compilar desde las fuentes. Si lo hace, permite la instalación de Node en el directorio personal como usuario estándar. O intentar de repositorios como NodeSource. + * Clang 3.4 o mayor. + * Cabeceras de desarrollo de GTK + y libnotify. + +En Ubuntu, instalar las siguientes bibliotecas: + +`$ sudo apt-get install build-essential clang libdbus-1-dev libgtk2.0-dev \ + libnotify-dev libgnome-keyring-dev libgconf2-dev \ + libasound2-dev libcap-dev libcups2-dev libxtst-dev \ + libxss1 libnss3-dev gcc-multilib g++-multilib` + +En Fedora, instale las siguientes bibliotecas: + +`$ sudo yum install clang dbus-devel gtk2-devel libnotify-devel libgnome-keyring-devel \ + xorg-x11-server-utils libcap-devel cups-devel libXtst-devel \ + alsa-lib-devel libXrandr-devel GConf2-devel nss-devel` + +Otras distribuciones pueden ofrecer paquetes similares para la instalación, a través de gestores de paquetes como el pacman. O puede compilarlo a partir del código fuente. + +#Si utiliza máquinas virtuales para la construcción + +Si usted planea construir Electron en una máquina virtual, necesitará un dispositivo de al menos 25 gigabytes de tamaño. + +#Obteniendo el codigo + +`$ git clone https://github.com/atom/electron.git` + +#Bootstrapping (Arranque) + +The bootstrap script will download all necessary build dependencies and create the build project files. You must have Python 2.7.x for the script to succeed. Downloading certain files can take a long time. Notice that we are using ninja to build Electron so there is no Makefile generated. + +El script de bootstrap descargará todas las dependencias necesarias para construcción y creara los archivos del proyecto de construcción. Debe tener Python 2.7.x para que la secuencia de comandos tenga éxito. La descarga de determinados archivos puede llevar mucho tiempo. Nótese que estamos usando`ninja` para construir Electron por lo que no hay `Makefile` generado. + + $ cd electron + $ ./script/bootstrap.py -v + +#compilación cruzada + +Si usted quiere construir para un `arm` objetivo también debe instalar las siguientes dependencias: + +`$ sudo apt-get install libc6-dev-armhf-cross linux-libc-dev-armhf-cross \ g++-arm-linux-gnueabihf` + +And to cross compile for arm or ia32 targets, you should pass the --target_arch parameter to the bootstrap.py script: +cruzar y compilar para `arm` o `ia32` objetivos, debe pasar el parámetro `--target_arch` al script `bootstrap.py`: +`$ ./script/bootstrap.py -v --target_arch=arm` + +#Construcción + +Si a usted le gustaría construir dos objetivos de `Release` y `Debug`: + + `$ ./script/build.py` + + +Este script causará que el ejecutable de Electron se muy grande para ser colocado en el directorio `out / R`. El tamaño del archivo es de más de 1,3 gigabytes. Esto sucede porque el binario de destino lanzamiento contiene los símbolos de depuración. Para reducir el tamaño de archivo, ejecute el script `create-dist.py`: + +`$ ./script/create-dist.py` + +This will put a working distribution with much smaller file sizes in the dist directory. After running the create-dist.py script, you may want to remove the 1.3+ gigabyte binary which is still in out/R. + +Esto pondrá una distribución a trabajar con tamaños de archivo mucho más pequeños en el directorio `dist`. Después de ejecutar el script create-dist.py, es posible que desee quitar el binario 1.3+ gigabyte que todavía está en `out/R`. + +También se puede construir sólo el objetivo `Debug`: +`$ ./script/build.py -c D` + +Después de la construcción está hecho, usted puede encontrar el `Electron` de depuración binario bajo `out / D`. + +#Limpieza + +Para limpiar los archivos de creación: + +`$ ./script/clean.py` + +#Solución de problemas +Asegúrese de que ha instalado todas las dependencias de construcción. + +#Error al cargar bibliotecas compartidas: libtinfo.so.5 + +Prebulit clang will try to link to libtinfo.so.5. Depending on the host architecture, symlink to appropriate libncurses: +preconstruir `clang` intentará enlazar a `libtinfo.so.5`. Dependiendo de la arquitectura anfitrión, enlace simbólico apropiado a `libncurses` : + +`$ sudo ln -s /usr/lib/libncurses.so.5 /usr/lib/libtinfo.so.5` + +#Pruebas +Pon a prueba tus cambios que ajustan al estilo de codificación proyecto mediante: + +`$ ./script/cpplint.py` + +prueba de funcionalidad utilizando: + +`$ ./script/test.py` diff --git a/docs-translations/es/development/build-instructions-osx.md b/docs-translations/es/development/build-instructions-osx.md new file mode 100644 index 000000000000..6e2d7b7f392e --- /dev/null +++ b/docs-translations/es/development/build-instructions-osx.md @@ -0,0 +1,48 @@ +#Instrucciones de Compilación (Mac) +Siga las siguientes pautas para la construcción de Electron en OS X. + +#Requisitos previos + + `OS X >= 10.8` + `Xcode >= 5.1` + `node.js (external)` + + +Si está utilizando Python descargado de Homebrew, también es necesario instalar los siguientes módulos de python: + `pyobjc` + +#Obtener el Código + +`$ git clone https://github.com/atom/electron.git` + +#Bootstrapping (arranque) + +The bootstrap script will download all necessary build dependencies and create the build project files. Notice that we're using ninja to build Electron so there is no Xcode project generated. + +El script de bootstrap descargará todas las dependencias de construcción necesarias y creara los archivos del proyecto de compilación. notemos que estamos usando `ninja` para construir Electron por lo que no hay un proyecto de Xcode generado. + +`$ cd electron` +`$ ./script/bootstrap.py -v` + +#Construcción +Construir ambos objetivos de `Release` y `Debug`: + +`$ ./script/build.py` + +También sólo se puede construir el objetivo de `Debug`: +`$ ./script/build.py -c D` + +Después de la construcción está hecho, usted puede encontrar `Electron.app` bajo `out / D.` + +#Soporte de 32bit + +Electron sólo puede construirse para un objetivo de 64 bits en OS X y no hay un plan para apoyar a 32 bit OS X en el futuro. + +#Pruebas + +Pon a prueba tus cambios ajustandose al estilo de codificación del proyecto mediante: +`$ ./script/cpplint.py` + +Prueba la funcionalidad usando: + +`$ ./script/test.py` diff --git a/docs-translations/es/development/build-system-overview.md b/docs-translations/es/development/build-system-overview.md new file mode 100644 index 000000000000..1e6a42da84bf --- /dev/null +++ b/docs-translations/es/development/build-system-overview.md @@ -0,0 +1,35 @@ +#Repaso del Sistema de construcción +Electron utiliza `gyp` para la generación de proyectos y` ninja` para la contrucción. Las Configuraciones del proyecto se pueden encontrar en los archivos `.gypi` y `.gyp `. + +#Archivos Gyp +los siguientes archivos `gyp` contienen las principales reglas para la contrucción en electron: + + * `atom.gyp` define en si como se compila en Electron. + * `common.gypi` ajusta las configuraciones de generación de Node para construir junto con Chromium. + * `vendor/brightray/brightray.gyp` define cómo se construye `brightray` e incluye las configuraciones predeterminadas para linkear con Chromium. + * `vendor/brightray/brightray.gypi` incluye configuraciones de generación generales sobre la construcción. + +#Construir un componente +Desde Chromium es un proyecto bastante largo, la etapa de enlace final puede tomar pocos minutos, lo que hace que sea difícil para el desarrollo. Con el fin de resolver esto, Chromium introdujo el "componente de construcción", que se basa en construir cada componente como una libreria compartida por separado, haciendo que se enlace muy rápido, pero sacrificando el tamaño del archivo y el rendimiento. + +En Electron tomamos un enfoque muy similar: para versiones de `Debug` (depuración), el binario será linkeado a una versión de la libreria compartida de los componentes de Chromium para lograr un tiempo de enlace rápido; para versiones de `Release` (lanzamiento), el binario será linkeado a las versiones de las librerias estáticas, por lo que puede tener es posible tener un mejor tamaño binario y rendimiento. + +#Bootstrapping minimo (minimo arranque) +Todos los binarios pre-compilados de Chromium (`libchromiumcontent`) son descargados al ejecutar el script de arranque. Por defecto ambas librerias estáticas y librerias compartidas se descargarán y el tamaño final debe estar entre 800 MB y 2 GB dependiendo de la plataforma. + +Por defecto, `libchromiumcontent` se descarga de Amazon Web Services. Si se establece la variable de entorno `LIBCHROMIUMCONTENT_MIRROR`, el bootstrap script se descargará de ella. `libchromiumcontent-qiniu-mirror` es un espejo para el` libchromiumcontent`. Si tiene problemas para acceder a AWS, puede cambiar la dirección de descarga a la misma a través de `exportación LIBCHROMIUMCONTENT_MIRROR = http: // 7xk3d2.dl1.z0.glb.clouddn.com /` + +Si sólo desea construir en Electron rápidamente para pruebas o desarrollo, puede descargar sólo las versiones de librerias compartidas pasando el parámetro `--dev`: + +`$ ./script/bootstrap.py --dev` +`$ ./script/build.py -c D` + +#generación de proyecto de dos frases +Los enlaces de Electron con diferentes conjuntos de librerias en versiones `Release` y `Debug`. `gyp`, sin embargo, no es compatible con la configuración de los diferentes ajustes de enlace para diferentes configuraciones. + +Para evitar que Electron utilice una variable de `gyp` `libchromiumcontent_component` para controlar qué configuraciones de enlace usar y sólo generar un objetivo cuando se ejecute `gyp`. + +#Nombres de destino +A diferencia de la mayoría de los proyectos que utilizan `Release` y `Debug` como nombres de destino, Electron utiliza `R` y `D` en su lugar. Esto se debe a `gyp` bloquea aleatoriamente si sólo hay una configuración de `Release` o `Debug` definidas, y Electron sólo tiene que generar un objetivo a la vez como se ha indicado anteriormente. + +Esto sólo afecta a los desarrolladores, si usted está construyendo Electron para rebranding no se ven afectados. From 647a0c4e2b40a69da5a6153374a2f0ccac03fc1f Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Mon, 2 Nov 2015 20:28:01 +0800 Subject: [PATCH 045/249] Code cleanup for remote module --- atom/browser/lib/rpc-server.coffee | 16 ++++++---------- atom/renderer/api/lib/remote.coffee | 19 ++++++++----------- 2 files changed, 14 insertions(+), 21 deletions(-) diff --git a/atom/browser/lib/rpc-server.coffee b/atom/browser/lib/rpc-server.coffee index 953436e16f37..ae4b161674bd 100644 --- a/atom/browser/lib/rpc-server.coffee +++ b/atom/browser/lib/rpc-server.coffee @@ -33,14 +33,13 @@ valueToMeta = (sender, value, optimizeSimpleObject=false) -> # it. meta.id = objectsRegistry.add sender.getId(), value - meta.members = [] - meta.members.push {name: prop, type: typeof field} for prop, field of value + meta.members = ({name, type: typeof field} for name, field of value) else if meta.type is 'buffer' meta.value = Array::slice.call value, 0 else if meta.type is 'promise' - meta.then = valueToMeta(sender, value.then.bind(value)) + meta.then = valueToMeta sender, value.then.bind(value) else if meta.type is 'error' - meta = errorValueToMeta(value, meta) + meta.members = plainObjectToMeta value else if meta.type is 'date' meta.value = value.getTime() else @@ -49,12 +48,9 @@ valueToMeta = (sender, value, optimizeSimpleObject=false) -> meta -# Convert Error into meta data. -errorValueToMeta = (err, meta) -> - Object.getOwnPropertyNames(err).reduce((obj, key) -> - obj[key] = err[key] - obj - , meta) +# Convert object to meta by value. +plainObjectToMeta = (obj) -> + Object.getOwnPropertyNames(obj).map (name) -> {name, value: obj[name]} # Convert Error into meta data. exceptionToMeta = (error) -> diff --git a/atom/renderer/api/lib/remote.coffee b/atom/renderer/api/lib/remote.coffee index d01027e27de0..2de14d541527 100644 --- a/atom/renderer/api/lib/remote.coffee +++ b/atom/renderer/api/lib/remote.coffee @@ -46,7 +46,7 @@ metaToValue = (meta) -> when 'array' then (metaToValue(el) for el in meta.members) when 'buffer' then new Buffer(meta.value) when 'promise' then Promise.resolve(then: metaToValue(meta.then)) - when 'error' then metaToError(meta) + when 'error' then metaToPlainObject meta when 'date' then new Date(meta.value) when 'exception' throw new Error("#{meta.message}\n#{meta.stack}") @@ -110,16 +110,13 @@ metaToValue = (meta) -> ret -# Convert meta data from browser into Error. -metaToError = (meta) -> - Object.getOwnPropertyNames(meta).reduce((error, prop) -> - Object.defineProperty(error, prop, { - get: -> meta[prop], - enumerable: false, - configurable: false - }) - error - , new Error()) +# Construct a plain object from the meta. +metaToPlainObject = (meta) -> + obj = switch meta.type + when 'error' then new Error + else {} + obj[name] = value for {name, value} in meta.members + obj # Browser calls a callback in renderer. ipc.on 'ATOM_RENDERER_CALLBACK', (id, args) -> From 4804d6b79b07f61d983d70c5c898b251d9e7a39a Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Mon, 2 Nov 2015 21:07:48 +0800 Subject: [PATCH 046/249] Update native-mate --- vendor/native_mate | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vendor/native_mate b/vendor/native_mate index b7387da0854b..21cda4e7fcff 160000 --- a/vendor/native_mate +++ b/vendor/native_mate @@ -1 +1 @@ -Subproject commit b7387da0854b20d376fdae0d93a01f83d080668d +Subproject commit 21cda4e7fcff592f33f989c1fea575658281711d From f7c0418bd8f2163d08ab359c993d01fd59f45bf0 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Mon, 2 Nov 2015 21:19:00 +0800 Subject: [PATCH 047/249] Ignore case for type of savePage --- atom/browser/api/atom_api_web_contents.cc | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/atom/browser/api/atom_api_web_contents.cc b/atom/browser/api/atom_api_web_contents.cc index 900c3e65a376..295948995528 100644 --- a/atom/browser/api/atom_api_web_contents.cc +++ b/atom/browser/api/atom_api_web_contents.cc @@ -169,11 +169,12 @@ struct Converter { std::string save_type; if (!ConvertFromV8(isolate, val, &save_type)) return false; - if (save_type == "HTMLOnly") { + save_type = base::StringToLowerASCII(save_type); + if (save_type == "htmlonly") { *out = content::SAVE_PAGE_TYPE_AS_ONLY_HTML; - } else if (save_type == "HTMLComplete") { + } else if (save_type == "htmlcomplete") { *out = content::SAVE_PAGE_TYPE_AS_COMPLETE_HTML; - } else if (save_type == "MHTML") { + } else if (save_type == "mhtml") { *out = content::SAVE_PAGE_TYPE_AS_MHTML; } else { return false; From 9236adfbf57946e554c09f90760bb666dbf6e1e1 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Mon, 2 Nov 2015 23:28:45 +0800 Subject: [PATCH 048/249] Translate menu template directly in C++ --- atom/browser/api/atom_api_web_contents.cc | 21 +--- atom/browser/api/atom_api_web_contents.h | 6 - atom/browser/api/lib/web-contents.coffee | 43 +------ .../content_converter.cc | 112 ++++++++++++------ .../content_converter.h | 16 ++- 5 files changed, 100 insertions(+), 98 deletions(-) diff --git a/atom/browser/api/atom_api_web_contents.cc b/atom/browser/api/atom_api_web_contents.cc index 5ffa37e95d44..c329b257a290 100644 --- a/atom/browser/api/atom_api_web_contents.cc +++ b/atom/browser/api/atom_api_web_contents.cc @@ -47,6 +47,7 @@ #include "content/public/browser/storage_partition.h" #include "content/public/browser/site_instance.h" #include "content/public/browser/web_contents.h" +#include "content/public/common/context_menu_params.h" #include "native_mate/dictionary.h" #include "native_mate/object_template_builder.h" #include "net/http/http_response_headers.h" @@ -407,8 +408,11 @@ void WebContents::RendererResponsive(content::WebContents* source) { } bool WebContents::HandleContextMenu(const content::ContextMenuParams& params) { - context_menu_context_ = params.custom_context; - Emit("-context-menu", params); + if (!params.custom_context.is_pepper_menu) + return false; + + Emit("pepper-context-menu", std::make_pair(params, web_contents())); + web_contents()->NotifyContextMenuClosed(params.custom_context); return true; } @@ -848,15 +852,6 @@ void WebContents::RemoveWorkSpace(mate::Arguments* args, DevToolsRemoveFileSystem(path); } -void WebContents::ExecuteContextMenuCommand(int action) { - web_contents()->ExecuteCustomContextMenuCommand(action, - context_menu_context_); -} - -void WebContents::NotifyContextMenuClosed() { - web_contents()->NotifyContextMenuClosed(context_menu_context_); -} - void WebContents::Undo() { web_contents()->Undo(); } @@ -1068,10 +1063,6 @@ mate::ObjectTemplateBuilder WebContents::GetObjectTemplateBuilder( .SetMethod("_printToPDF", &WebContents::PrintToPDF) .SetMethod("addWorkSpace", &WebContents::AddWorkSpace) .SetMethod("removeWorkSpace", &WebContents::RemoveWorkSpace) - .SetMethod("_executeContextMenuCommand", - &WebContents::ExecuteContextMenuCommand) - .SetMethod("_notifyContextMenuClosed", - &WebContents::NotifyContextMenuClosed) .SetProperty("session", &WebContents::Session, true) .SetProperty("devToolsWebContents", &WebContents::DevToolsWebContents, true) diff --git a/atom/browser/api/atom_api_web_contents.h b/atom/browser/api/atom_api_web_contents.h index 5a55ad2abd7a..ae231cd3c61d 100644 --- a/atom/browser/api/atom_api_web_contents.h +++ b/atom/browser/api/atom_api_web_contents.h @@ -13,7 +13,6 @@ #include "atom/browser/api/trackable_object.h" #include "atom/browser/common_web_contents_delegate.h" #include "content/public/browser/web_contents_observer.h" -#include "content/public/common/context_menu_params.h" #include "content/public/common/favicon_url.h" #include "native_mate/handle.h" #include "ui/gfx/image/image.h" @@ -93,8 +92,6 @@ class WebContents : public mate::TrackableObject, void SetAudioMuted(bool muted); bool IsAudioMuted(); void Print(mate::Arguments* args); - void ExecuteContextMenuCommand(int action); - void NotifyContextMenuClosed(); // Print current page as PDF. void PrintToPDF(const base::DictionaryValue& setting, @@ -259,9 +256,6 @@ class WebContents : public mate::TrackableObject, // embedders' zoom level change. void OnZoomLevelChanged(double level); - // Recent unhandled context menu context. - content::CustomContextMenuContext context_menu_context_; - v8::Global session_; v8::Global devtools_web_contents_; diff --git a/atom/browser/api/lib/web-contents.coffee b/atom/browser/api/lib/web-contents.coffee index afe70323f0a5..eab9f1967158 100644 --- a/atom/browser/api/lib/web-contents.coffee +++ b/atom/browser/api/lib/web-contents.coffee @@ -35,36 +35,6 @@ PDFPageSize = width_microns: 279400 custom_display_name: "Tabloid" -clickHandler = (action) -> - @_executeContextMenuCommand action - -convertToMenuTemplate = (items, handler) -> - template = [] - for item in items - do (item) -> - transformed = - if item.type is 'submenu' - type: 'submenu' - label: item.label - enabled: item.enabled - submenu: convertToMenuTemplate item.subItems, handler - else if item.type is 'separator' - type: 'separator' - else if item.type is 'checkbox' - type: 'checkbox' - label: item.label - enabled: item.enabled - checked: item.checked - else - type: 'normal' - label: item.label - enabled: item.enabled - if item.id? - transformed.click = -> - handler item.id - template.push transformed - template - wrapWebContents = (webContents) -> # webContents is an EventEmitter. webContents.__proto__ = EventEmitter.prototype @@ -96,15 +66,10 @@ wrapWebContents = (webContents) -> Object.defineProperty event, 'returnValue', set: (value) -> event.sendReply JSON.stringify(value) ipc.emit channel, event, args... - # Handle context menu action request from renderer widget. - webContents.on '-context-menu', (event, params) -> - if params.isPepperMenu - template = convertToMenuTemplate(params.menuItems, clickHandler.bind(webContents)) - menu = Menu.buildFromTemplate template - # The menu is expected to show asynchronously. - setImmediate -> - menu.popup params.x, params.y - webContents._notifyContextMenuClosed() + # Handle context menu action request from pepper plugin. + webContents.on 'pepper-context-menu', (event, params) -> + menu = Menu.buildFromTemplate params.menu + menu.popup params.x, params.y webContents.printToPDF = (options, callback) -> printingSetting = diff --git a/atom/common/native_mate_converters/content_converter.cc b/atom/common/native_mate_converters/content_converter.cc index 2318e7d8e837..15a57dea5fb8 100644 --- a/atom/common/native_mate_converters/content_converter.cc +++ b/atom/common/native_mate_converters/content_converter.cc @@ -4,50 +4,96 @@ #include "atom/common/native_mate_converters/content_converter.h" +#include + +#include "atom/common/native_mate_converters/callback.h" #include "atom/common/native_mate_converters/string16_converter.h" +#include "content/public/browser/web_contents.h" #include "content/public/common/context_menu_params.h" -#include "content/public/common/menu_item.h" #include "native_mate/dictionary.h" +namespace { + +void ExecuteCommand(content::WebContents* web_contents, + int action, + const content::CustomContextMenuContext& context) { + web_contents->ExecuteCustomContextMenuCommand(action, context); +} + +// Forward declaration for nested recursive call. +v8::Local MenuToV8(v8::Isolate* isolate, + content::WebContents* web_contents, + const content::CustomContextMenuContext& context, + const std::vector& menu); + +v8::Local MenuItemToV8( + v8::Isolate* isolate, + content::WebContents* web_contents, + const content::CustomContextMenuContext& context, + const content::MenuItem& item) { + mate::Dictionary v8_item = mate::Dictionary::CreateEmpty(isolate); + switch (item.type) { + case content::MenuItem::CHECKABLE_OPTION: + case content::MenuItem::GROUP: + v8_item.Set("checked", item.checked); + case content::MenuItem::OPTION: + case content::MenuItem::SUBMENU: + v8_item.Set("label", item.label); + v8_item.Set("enabled", item.enabled); + default: + v8_item.Set("type", item.type); + } + if (item.type == content::MenuItem::SUBMENU) + v8_item.Set("submenu", + MenuToV8(isolate, web_contents, context, item.submenu)); + else if (item.action > 0) + v8_item.Set("click", + base::Bind(ExecuteCommand, web_contents, item.action, context)); + return v8_item.GetHandle(); +} + +v8::Local MenuToV8(v8::Isolate* isolate, + content::WebContents* web_contents, + const content::CustomContextMenuContext& context, + const std::vector& menu) { + std::vector> v8_menu; + for (const auto& menu_item : menu) + v8_menu.push_back(MenuItemToV8(isolate, web_contents, context, menu_item)); + return mate::ConvertToV8(isolate, v8_menu); +} + +} // namespace + namespace mate { -template<> -struct Converter { - static v8::Local ToV8(v8::Isolate* isolate, - const content::MenuItem::Type& val) { - switch (val) { - case content::MenuItem::CHECKABLE_OPTION: - return StringToV8(isolate, "checkbox"); - case content::MenuItem::SEPARATOR: - return StringToV8(isolate, "separator"); - case content::MenuItem::SUBMENU: - return StringToV8(isolate, "submenu"); - default: - return StringToV8(isolate, "normal"); - } - } -}; - // static -v8::Local Converter::ToV8( - v8::Isolate* isolate, const content::MenuItem& val) { - mate::Dictionary dict = mate::Dictionary::CreateEmpty(isolate); - dict.Set("id", val.action); - dict.Set("type", val.type); - dict.Set("label", val.label); - dict.Set("enabled", val.enabled); - dict.Set("checked", val.checked); - return mate::ConvertToV8(isolate, dict); +v8::Local Converter::ToV8( + v8::Isolate* isolate, const content::MenuItem::Type& val) { + switch (val) { + case content::MenuItem::CHECKABLE_OPTION: + return StringToV8(isolate, "checkbox"); + case content::MenuItem::GROUP: + return StringToV8(isolate, "radio"); + case content::MenuItem::SEPARATOR: + return StringToV8(isolate, "separator"); + case content::MenuItem::SUBMENU: + return StringToV8(isolate, "submenu"); + case content::MenuItem::OPTION: + default: + return StringToV8(isolate, "normal"); + } } // static -v8::Local Converter::ToV8( - v8::Isolate* isolate, const content::ContextMenuParams& val) { +v8::Local Converter::ToV8( + v8::Isolate* isolate, const ContextMenuParamsWithWebContents& val) { + const auto& params = val.first; mate::Dictionary dict = mate::Dictionary::CreateEmpty(isolate); - dict.Set("x", val.x); - dict.Set("y", val.y); - dict.Set("isPepperMenu", val.custom_context.is_pepper_menu); - dict.Set("menuItems", val.custom_items); + dict.Set("x", params.x); + dict.Set("y", params.y); + if (params.custom_context.is_pepper_menu) + dict.Set("menu", MenuToV8(isolate, val.second, params.custom_context, + params.custom_items)); return mate::ConvertToV8(isolate, dict); } diff --git a/atom/common/native_mate_converters/content_converter.h b/atom/common/native_mate_converters/content_converter.h index 5cca2b38b251..7edee24fa142 100644 --- a/atom/common/native_mate_converters/content_converter.h +++ b/atom/common/native_mate_converters/content_converter.h @@ -5,25 +5,31 @@ #ifndef ATOM_COMMON_NATIVE_MATE_CONVERTERS_CONTENT_CONVERTER_H_ #define ATOM_COMMON_NATIVE_MATE_CONVERTERS_CONTENT_CONVERTER_H_ +#include + +#include "content/public/common/menu_item.h" #include "native_mate/converter.h" namespace content { struct ContextMenuParams; -struct MenuItem; +class WebContents; } +using ContextMenuParamsWithWebContents = + std::pair; + namespace mate { template<> -struct Converter { +struct Converter { static v8::Local ToV8(v8::Isolate* isolate, - const content::MenuItem& val); + const content::MenuItem::Type& val); }; template<> -struct Converter { +struct Converter { static v8::Local ToV8(v8::Isolate* isolate, - const content::ContextMenuParams& val); + const ContextMenuParamsWithWebContents& val); }; } // namespace mate From d332f2ab1c5eb555ea47345e9badc869dd337dcd Mon Sep 17 00:00:00 2001 From: frankenbot Date: Mon, 2 Nov 2015 21:16:12 -0800 Subject: [PATCH 049/249] Update redirects --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 8fb9128d9c10..f8e1f2909ef6 100644 --- a/README.md +++ b/README.md @@ -7,14 +7,14 @@ :zap: *Formerly known as Atom Shell* :zap: 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 +using JavaScript, HTML and CSS. It is based on [Node.js](https://nodejs.org/en/) and [Chromium](http://www.chromium.org) and is used in the [Atom editor](https://github.com/atom/atom). Follow [@ElectronJS](https://twitter.com/electronjs) on Twitter for important announcements. -This project adheres to the [Contributor Covenant 1.2](http://contributor-covenant.org/version/1/2/0). +This project adheres to the [Contributor Covenant 1.2](http://contributor-covenant.org/version/1/2/0/). By participating, you are expected to uphold this code. Please report unacceptable behavior to atom@github.com. @@ -62,7 +62,7 @@ repository to see a minimal Electron app in action. You can ask questions and interact with the community in the following locations: -- [`electron`](http://discuss.atom.io/category/electron) category on the Atom +- [`electron`](http://discuss.atom.io/c/electron) category on the Atom forums - `#atom-shell` channel on Freenode - [`Atom`](http://atom-slack.herokuapp.com/) channel on Slack From 7c7a7b96de198b1dff7d35334079d229ea372c6e Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Tue, 3 Nov 2015 14:55:43 +0800 Subject: [PATCH 050/249] win: Do not set app user model id by default When user drags exe file into taskbar directly the pinned icon will not has an app user model id, so if we set app user model id in the application two icons will show in the taskbar. For apps installed with a installer it is not a problem since the shortcut icon will be created with app user model id, but we should also keep the ability to make portable apps work out of box. Fix #3303. --- atom/browser/browser.cc | 4 ---- atom/browser/browser.h | 9 +++++++-- atom/browser/browser_win.cc | 18 ++++++++++++------ 3 files changed, 19 insertions(+), 12 deletions(-) diff --git a/atom/browser/browser.cc b/atom/browser/browser.cc index 739921fda90f..e80cb4e60e20 100644 --- a/atom/browser/browser.cc +++ b/atom/browser/browser.cc @@ -89,10 +89,6 @@ std::string Browser::GetName() const { void Browser::SetName(const std::string& name) { name_override_ = name; - -#if defined(OS_WIN) - SetAppUserModelID(name); -#endif } bool Browser::OpenFile(const std::string& file_path) { diff --git a/atom/browser/browser.h b/atom/browser/browser.h index 8719e18f3140..0500e317755b 100644 --- a/atom/browser/browser.h +++ b/atom/browser/browser.h @@ -100,8 +100,13 @@ class Browser : public WindowListObserver { // Add a custom task to jump list. void SetUserTasks(const std::vector& tasks); - // Set the application user model ID, called when "SetName" is called. - void SetAppUserModelID(const std::string& name); + // Set the application user model ID. + void SetAppUserModelID(const base::string16& name); + + // Returns the application user model ID, if there isn't one, then create + // one from app's name. + // The returned string managed by Browser, and should not be modified. + PCWSTR GetAppUserModelID(); #endif // Tell the application to open a file. diff --git a/atom/browser/browser_win.cc b/atom/browser/browser_win.cc index b861af945421..0e5ce8e2d955 100644 --- a/atom/browser/browser_win.cc +++ b/atom/browser/browser_win.cc @@ -56,7 +56,7 @@ void Browser::AddRecentDocument(const base::FilePath& path) { if (SUCCEEDED(hr)) { SHARDAPPIDINFO info; info.psi = item; - info.pszAppID = app_user_model_id_.c_str(); + info.pszAppID = GetAppUserModelID(); SHAddToRecentDocs(SHARD_APPIDINFO, &info); } } @@ -66,7 +66,7 @@ void Browser::ClearRecentDocuments() { if (FAILED(destinations.CoCreateInstance(CLSID_ApplicationDestinations, NULL, CLSCTX_INPROC_SERVER))) return; - if (FAILED(destinations->SetAppID(app_user_model_id_.c_str()))) + if (FAILED(destinations->SetAppID(GetAppUserModelID()))) return; destinations->RemoveAllDestinations(); } @@ -75,7 +75,7 @@ void Browser::SetUserTasks(const std::vector& tasks) { CComPtr destinations; if (FAILED(destinations.CoCreateInstance(CLSID_DestinationList))) return; - if (FAILED(destinations->SetAppID(app_user_model_id_.c_str()))) + if (FAILED(destinations->SetAppID(GetAppUserModelID()))) return; // Start a transaction that updates the JumpList of this application. @@ -117,12 +117,18 @@ void Browser::SetUserTasks(const std::vector& tasks) { destinations->CommitList(); } -void Browser::SetAppUserModelID(const std::string& name) { - app_user_model_id_ = base::string16(L"electron.app."); - app_user_model_id_ += base::UTF8ToUTF16(name); +void Browser::SetAppUserModelID(const base::string16& name) { + app_user_model_id_ = name; SetCurrentProcessExplicitAppUserModelID(app_user_model_id_.c_str()); } +PCWSTR Browser::GetAppUserModelID() { + if (app_user_model_id_.empty()) + SetAppUserModelID(base::UTF8ToUTF16(GetName())); + + return app_user_model_id_.c_str(); +} + std::string Browser::GetExecutableFileVersion() const { base::FilePath path; if (PathService::Get(base::FILE_EXE, &path)) { From 9047f81835d5e4d0c69d0c1634e17f68f4209601 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Tue, 3 Nov 2015 15:09:31 +0800 Subject: [PATCH 051/249] win: Set app user model ID in one place Fix #3297. Fix #2573. --- atom/browser/api/atom_api_app.cc | 14 ++------------ atom/browser/api/atom_api_app.h | 1 - atom/browser/browser.h | 6 +++--- atom/browser/browser_linux.cc | 3 +++ atom/browser/browser_mac.mm | 3 +++ atom/browser/browser_win.cc | 10 +++++----- 6 files changed, 16 insertions(+), 21 deletions(-) diff --git a/atom/browser/api/atom_api_app.cc b/atom/browser/api/atom_api_app.cc index bd49f9fddc05..04ed06e0138f 100644 --- a/atom/browser/api/atom_api_app.cc +++ b/atom/browser/api/atom_api_app.cc @@ -7,10 +7,6 @@ #include #include -#if defined(OS_WIN) -#include -#endif - #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" @@ -299,13 +295,6 @@ void App::SetDesktopName(const std::string& desktop_name) { #endif } -void App::SetAppUserModelId(const std::string& app_id) { -#if defined(OS_WIN) - base::string16 app_id_utf16 = base::UTF8ToUTF16(app_id); - SetCurrentProcessExplicitAppUserModelID(app_id_utf16.c_str()); -#endif -} - void App::AllowNTLMCredentialsForAllDomains(bool should_allow) { auto browser_context = static_cast( AtomBrowserMainParts::Get()->browser_context()); @@ -360,6 +349,8 @@ mate::ObjectTemplateBuilder App::GetObjectTemplateBuilder( base::Bind(&Browser::AddRecentDocument, browser)) .SetMethod("clearRecentDocuments", base::Bind(&Browser::ClearRecentDocuments, browser)) + .SetMethod("setAppUserModelId", + base::Bind(&Browser::SetAppUserModelID, browser)) #if defined(OS_WIN) .SetMethod("setUserTasks", base::Bind(&Browser::SetUserTasks, browser)) @@ -367,7 +358,6 @@ mate::ObjectTemplateBuilder App::GetObjectTemplateBuilder( .SetMethod("setPath", &App::SetPath) .SetMethod("getPath", &App::GetPath) .SetMethod("setDesktopName", &App::SetDesktopName) - .SetMethod("setAppUserModelId", &App::SetAppUserModelId) .SetMethod("allowNTLMCredentialsForAllDomains", &App::AllowNTLMCredentialsForAllDomains) .SetMethod("getLocale", &App::GetLocale) diff --git a/atom/browser/api/atom_api_app.h b/atom/browser/api/atom_api_app.h index 63cda4447e32..683093d886c9 100644 --- a/atom/browser/api/atom_api_app.h +++ b/atom/browser/api/atom_api_app.h @@ -67,7 +67,6 @@ class App : public mate::EventEmitter, const base::FilePath& path); void SetDesktopName(const std::string& desktop_name); - void SetAppUserModelId(const std::string& app_id); void AllowNTLMCredentialsForAllDomains(bool should_allow); bool MakeSingleInstance( const ProcessSingleton::NotificationCallback& callback); diff --git a/atom/browser/browser.h b/atom/browser/browser.h index 0500e317755b..9f27816c5807 100644 --- a/atom/browser/browser.h +++ b/atom/browser/browser.h @@ -66,6 +66,9 @@ class Browser : public WindowListObserver { // Clear the recent documents list. void ClearRecentDocuments(); + // Set the application user model ID. + void SetAppUserModelID(const base::string16& name); + #if defined(OS_MACOSX) // Bounce the dock icon. enum BounceType { @@ -100,9 +103,6 @@ class Browser : public WindowListObserver { // Add a custom task to jump list. void SetUserTasks(const std::vector& tasks); - // Set the application user model ID. - void SetAppUserModelID(const base::string16& name); - // Returns the application user model ID, if there isn't one, then create // one from app's name. // The returned string managed by Browser, and should not be modified. diff --git a/atom/browser/browser_linux.cc b/atom/browser/browser_linux.cc index ea8fb7c10c5d..25cb9a0a2385 100644 --- a/atom/browser/browser_linux.cc +++ b/atom/browser/browser_linux.cc @@ -31,6 +31,9 @@ void Browser::AddRecentDocument(const base::FilePath& path) { void Browser::ClearRecentDocuments() { } +void Browser::SetAppUserModelID(const base::string16& name) { +} + std::string Browser::GetExecutableFileVersion() const { return brightray::GetApplicationVersion(); } diff --git a/atom/browser/browser_mac.mm b/atom/browser/browser_mac.mm index 2353aa6c42c3..6589057c2c6c 100644 --- a/atom/browser/browser_mac.mm +++ b/atom/browser/browser_mac.mm @@ -26,6 +26,9 @@ void Browser::AddRecentDocument(const base::FilePath& path) { void Browser::ClearRecentDocuments() { } +void Browser::SetAppUserModelID(const base::string16& name) { +} + std::string Browser::GetExecutableFileVersion() const { return brightray::GetApplicationVersion(); } diff --git a/atom/browser/browser_win.cc b/atom/browser/browser_win.cc index 0e5ce8e2d955..a2725b17c1f7 100644 --- a/atom/browser/browser_win.cc +++ b/atom/browser/browser_win.cc @@ -71,6 +71,11 @@ void Browser::ClearRecentDocuments() { destinations->RemoveAllDestinations(); } +void Browser::SetAppUserModelID(const base::string16& name) { + app_user_model_id_ = name; + SetCurrentProcessExplicitAppUserModelID(app_user_model_id_.c_str()); +} + void Browser::SetUserTasks(const std::vector& tasks) { CComPtr destinations; if (FAILED(destinations.CoCreateInstance(CLSID_DestinationList))) @@ -117,11 +122,6 @@ void Browser::SetUserTasks(const std::vector& tasks) { destinations->CommitList(); } -void Browser::SetAppUserModelID(const base::string16& name) { - app_user_model_id_ = name; - SetCurrentProcessExplicitAppUserModelID(app_user_model_id_.c_str()); -} - PCWSTR Browser::GetAppUserModelID() { if (app_user_model_id_.empty()) SetAppUserModelID(base::UTF8ToUTF16(GetName())); From 7b47b70c9e4dbf5edf1208e902e4a6ce27b4799e Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Tue, 3 Nov 2015 15:16:45 +0800 Subject: [PATCH 052/249] Fix building on POSIX --- atom/browser/browser.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/atom/browser/browser.h b/atom/browser/browser.h index 9f27816c5807..447a526de6df 100644 --- a/atom/browser/browser.h +++ b/atom/browser/browser.h @@ -11,12 +11,12 @@ #include "base/basictypes.h" #include "base/compiler_specific.h" #include "base/observer_list.h" +#include "base/strings/string16.h" #include "atom/browser/browser_observer.h" #include "atom/browser/window_list_observer.h" #if defined(OS_WIN) #include "base/files/file_path.h" -#include "base/strings/string16.h" #endif namespace base { From 8a3268b70c9eacf32a347831a509bec1122e7e19 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Tue, 3 Nov 2015 15:30:54 +0800 Subject: [PATCH 053/249] docs: Add notes for working together with Squirrel --- docs/api/auto-updater.md | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/docs/api/auto-updater.md b/docs/api/auto-updater.md index bda1d46bb094..eb0ea3752995 100644 --- a/docs/api/auto-updater.md +++ b/docs/api/auto-updater.md @@ -9,15 +9,22 @@ still some subtle differences on each platform. ### OS X -On OS X, the `autoUpdater` module is built upon [Squirrel.Mac][squirrel-mac], meaning you -don't need any special setup to make it work. For server-side requirements, you -can read [Server Support][server-support]. +On OS X, the `autoUpdater` module is built upon [Squirrel.Mac][squirrel-mac], +meaning you don't need any special setup to make it work. For server-side +requirements, you can read [Server Support][server-support]. ### Windows -On Windows, you have to install your app into a user's machine before you can use -the auto-updater, so it is recommended to use [grunt-electron-installer][installer] -module to generate a Windows installer. +On Windows, you have to install your app into a user's machine before you can +use the auto-updater, so it is recommended to use +[grunt-electron-installer][installer] module to generate a Windows installer. + +The installer generated with Squirrel will create a shortcut icon with an +[Application User Model ID][app-user-model-id] in the format of +`com.squirrel.PACKAGE_ID.YOUR_EXE_WITHOUT_DOT_EXE`, examples are +`com.squirrel.slack.Slack` and `com.squirrel.code.Code`. You have to use the +same ID for your app with `app.setAppUserModelId` API, otherwise Windows will +not be able to pin your app properly in task bar. The server-side setup is also different from OS X. You can read the documents of [Squirrel.Windows][squirrel-windows] to get more details. @@ -84,10 +91,11 @@ using this API. ### `autoUpdater.quitAndInstall()` -Restarts the app and installs the update after it has been downloaded. It should -only be called after `update-downloaded` has been emitted. +Restarts the app and installs the update after it has been downloaded. It +should only be called after `update-downloaded` has been emitted. [squirrel-mac]: https://github.com/Squirrel/Squirrel.Mac [server-support]: https://github.com/Squirrel/Squirrel.Mac#server-support [squirrel-windows]: https://github.com/Squirrel/Squirrel.Windows [installer]: https://github.com/atom/grunt-electron-installer +[app-user-model-id]: https://msdn.microsoft.com/en-us/library/windows/desktop/dd378459(v=vs.85).aspx From 726910df39a94d1ac5fee432644cf732f19ee317 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Tue, 3 Nov 2015 15:36:44 +0800 Subject: [PATCH 054/249] docs: app.setAppUserModelId --- docs/api/app.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/docs/api/app.md b/docs/api/app.md index 204155cfa053..00aade7c54ab 100644 --- a/docs/api/app.md +++ b/docs/api/app.md @@ -375,6 +375,12 @@ app.on('ready', function() { }); ``` +### `app.setAppUserModelId(id)` _Windows_ + +* `id` String + +Changes the [Application User Model ID][app-user-model-id] to `id`. + ### `app.commandLine.appendSwitch(switch[, value])` Append a switch (with optional `value`) to Chromium's command line. @@ -435,3 +441,4 @@ Sets the application's [dock menu][dock-menu]. [dock-menu]:https://developer.apple.com/library/mac/documentation/Carbon/Conceptual/customizing_docktile/concepts/dockconcepts.html#//apple_ref/doc/uid/TP30000986-CH2-TPXREF103 [tasks]:http://msdn.microsoft.com/en-us/library/windows/desktop/dd378460(v=vs.85).aspx#tasks +[app-user-model-id]: https://msdn.microsoft.com/en-us/library/windows/desktop/dd378459(v=vs.85).aspx From 1b165559f550f7dc421683d345b032e71e070e04 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Tue, 3 Nov 2015 15:49:37 +0800 Subject: [PATCH 055/249] win: Use electron.app.$1 as default user model id This is to keep compatibility with old apps that don't set app user model id explicitly. --- atom/browser/browser_win.cc | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/atom/browser/browser_win.cc b/atom/browser/browser_win.cc index a2725b17c1f7..ce36d56b620c 100644 --- a/atom/browser/browser_win.cc +++ b/atom/browser/browser_win.cc @@ -15,6 +15,7 @@ #include "base/files/file_path.h" #include "base/memory/scoped_ptr.h" #include "base/path_service.h" +#include "base/strings/string_util.h" #include "base/strings/stringprintf.h" #include "base/strings/utf_string_conversions.h" #include "base/win/win_util.h" @@ -25,6 +26,8 @@ namespace atom { namespace { +const wchar_t kAppUserModelIDFormat[] = L"electron.app.$1"; + BOOL CALLBACK WindowsEnumerationHandler(HWND hwnd, LPARAM param) { DWORD target_process_id = *reinterpret_cast(param); DWORD process_id = 0; @@ -123,8 +126,10 @@ void Browser::SetUserTasks(const std::vector& tasks) { } PCWSTR Browser::GetAppUserModelID() { - if (app_user_model_id_.empty()) - SetAppUserModelID(base::UTF8ToUTF16(GetName())); + if (app_user_model_id_.empty()) { + SetAppUserModelID(ReplaceStringPlaceholders( + kAppUserModelIDFormat, base::UTF8ToUTF16(GetName()), nullptr)); + } return app_user_model_id_.c_str(); } From 8c989c4630d66138777849c56768ee66148f7dbe Mon Sep 17 00:00:00 2001 From: frankenbot Date: Tue, 3 Nov 2015 09:13:48 -0800 Subject: [PATCH 056/249] Update nodejs url --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index f8e1f2909ef6..beb96b4e5c2a 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ :zap: *Formerly known as Atom Shell* :zap: The Electron framework lets you write cross-platform desktop applications -using JavaScript, HTML and CSS. It is based on [Node.js](https://nodejs.org/en/) and +using JavaScript, HTML and CSS. It is based on [Node.js](https://nodejs.org/) and [Chromium](http://www.chromium.org) and is used in the [Atom editor](https://github.com/atom/atom). From 7c41f0e0e30977ed6a3f37ee0e524d7c75544c2d Mon Sep 17 00:00:00 2001 From: Joao Moreno Date: Tue, 3 Nov 2015 16:12:01 -0800 Subject: [PATCH 057/249] remove kDisableLegacyIntermediateWindow switch set --- atom/app/atom_main_delegate.cc | 7 ------- 1 file changed, 7 deletions(-) diff --git a/atom/app/atom_main_delegate.cc b/atom/app/atom_main_delegate.cc index e4ac7cfc0a99..3bc1ac497082 100644 --- a/atom/app/atom_main_delegate.cc +++ b/atom/app/atom_main_delegate.cc @@ -102,13 +102,6 @@ void AtomMainDelegate::PreSandboxStartup() { if (!IsBrowserProcess(command_line)) return; -#if defined(OS_WIN) - // Disable the LegacyRenderWidgetHostHWND, it made frameless windows unable - // to move and resize. We may consider enabling it again after upgraded to - // Chrome 38, which should have fixed the problem. - command_line->AppendSwitch(switches::kDisableLegacyIntermediateWindow); -#endif - // Disable renderer sandbox for most of node's functions. command_line->AppendSwitch(switches::kNoSandbox); From 4013b652ff1e0cab465b2319b6521be799a825f4 Mon Sep 17 00:00:00 2001 From: mgarciaisaia Date: Wed, 4 Nov 2015 01:09:05 -0300 Subject: [PATCH 058/249] :checkered_flag::bug: Buffer overflows in tooltips Fixes #3290. --- atom/browser/ui/win/notify_icon.cc | 6 +++--- atom/browser/ui/win/taskbar_host.cc | 3 ++- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/atom/browser/ui/win/notify_icon.cc b/atom/browser/ui/win/notify_icon.cc index c88d4c810ef8..b2ca4bceedd1 100644 --- a/atom/browser/ui/win/notify_icon.cc +++ b/atom/browser/ui/win/notify_icon.cc @@ -113,7 +113,7 @@ void NotifyIcon::SetToolTip(const std::string& tool_tip) { NOTIFYICONDATA icon_data; InitIconData(&icon_data); icon_data.uFlags |= NIF_TIP; - wcscpy_s(icon_data.szTip, base::UTF8ToUTF16(tool_tip).c_str()); + wcsncpy_s(icon_data.szTip, base::UTF8ToUTF16(tool_tip).c_str(), _TRUNCATE); BOOL result = Shell_NotifyIcon(NIM_MODIFY, &icon_data); if (!result) LOG(WARNING) << "Unable to set tooltip for status tray icon"; @@ -126,8 +126,8 @@ void NotifyIcon::DisplayBalloon(const gfx::Image& icon, InitIconData(&icon_data); icon_data.uFlags |= NIF_INFO; icon_data.dwInfoFlags = NIIF_INFO; - wcscpy_s(icon_data.szInfoTitle, title.c_str()); - wcscpy_s(icon_data.szInfo, contents.c_str()); + wcsncpy_s(icon_data.szInfoTitle, title.c_str(), _TRUNCATE); + wcsncpy_s(icon_data.szInfo, contents.c_str(), _TRUNCATE); icon_data.uTimeout = 0; base::win::Version win_version = base::win::GetVersion(); diff --git a/atom/browser/ui/win/taskbar_host.cc b/atom/browser/ui/win/taskbar_host.cc index a8e6ff2926cd..0d250829110f 100644 --- a/atom/browser/ui/win/taskbar_host.cc +++ b/atom/browser/ui/win/taskbar_host.cc @@ -97,7 +97,8 @@ bool TaskbarHost::SetThumbarButtons( // Set tooltip. if (!button.tooltip.empty()) { thumb_button.dwMask |= THB_TOOLTIP; - wcscpy_s(thumb_button.szTip, base::UTF8ToUTF16(button.tooltip).c_str()); + wcsncpy_s(thumb_button.szTip, base::UTF8ToUTF16(button.tooltip).c_str(), + _TRUNCATE); } // Save callback. From 96cc5485cb0f94d4a40e37a20c1c76c6a39c9fdc Mon Sep 17 00:00:00 2001 From: Plusb Preco Date: Wed, 4 Nov 2015 17:47:14 +0900 Subject: [PATCH 059/249] Update as upstream --- docs-translations/ko-KR/api/app.md | 7 +++++++ docs-translations/ko-KR/api/auto-updater.md | 11 +++++++++-- .../ko-KR/tutorial/using-native-node-modules.md | 3 +++ 3 files changed, 19 insertions(+), 2 deletions(-) diff --git a/docs-translations/ko-KR/api/app.md b/docs-translations/ko-KR/api/app.md index a443d1252f8e..26235fbe444b 100644 --- a/docs-translations/ko-KR/api/app.md +++ b/docs-translations/ko-KR/api/app.md @@ -362,6 +362,12 @@ app.on('ready', function() { }); ``` +### `app.setAppUserModelId(id)` _Windows_ + +* `id` String + +[Application User Model ID][app-user-model-id]를 `id`로 변경합니다. + ### `app.commandLine.appendSwitch(switch[, value])` Chrominum의 명령줄에 스위치를 추가합니다. `value`는 추가적인 값을 뜻하며 옵션입니다. @@ -418,3 +424,4 @@ dock 아이콘을 표시합니다. [dock-menu]:https://developer.apple.com/library/mac/documentation/Carbon/Conceptual/customizing_docktile/concepts/dockconcepts.html#//apple_ref/doc/uid/TP30000986-CH2-TPXREF103 [tasks]:http://msdn.microsoft.com/en-us/library/windows/desktop/dd378460(v=vs.85).aspx#tasks +[app-user-model-id]: https://msdn.microsoft.com/en-us/library/windows/desktop/dd378459(v=vs.85).aspx diff --git a/docs-translations/ko-KR/api/auto-updater.md b/docs-translations/ko-KR/api/auto-updater.md index b940bb536181..f12d04042ef2 100644 --- a/docs-translations/ko-KR/api/auto-updater.md +++ b/docs-translations/ko-KR/api/auto-updater.md @@ -15,7 +15,13 @@ OS X에선 `auto-updater` 모듈이 [Squirrel.Mac][squirrel-mac]를 기반으로 ### Windows Windows에선 `auto-updater` 모듈을 사용하기 전에 어플리케이션을 사용자의 장치에 설치해야 합니다. -[grunt-electron-installer][installer]를 사용하여 어플리케이션 셋업을 만드는 것을 권장합니다. +[grunt-electron-installer][installer]를 사용하여 어플리케이션 인스톨러를 만드는 것을 권장합니다. + +Squirrel로 생성된 인스톨러는 [Application User Model ID][app-user-model-id]와 함께 +`com.squirrel.PACKAGE_ID.YOUR_EXE_WITHOUT_DOT_EXE`으로 형식화된 바로가기 아이콘을 생성합니다. +`com.squirrel.slack.Slack` 과 `com.squirrel.code.Code`가 그 예시입니다. +`app.setAppUserModelId` API를 통해 어플리케이션 ID를 동일하게 유지해야 합니다. +그렇지 않으면 Windows 작업 표시줄에 어플리케이션을 고정할 때 제대로 적용되지 않을 수 있습니다. 서버 사이드 요구 사항 또한 OS X와 다르게 적용됩니다. 자세한 내용은 [Squirrel.Windows][squirrel-windows]를 참고하세요. @@ -74,7 +80,7 @@ Returns: 서버에 새로운 업데이트가 있는지 요청을 보내 확인합니다. API를 사용하기 전에 `setFeedUrl`를 호출해야 합니다. -### `autoUpdater.quitAndUpdate()` +### `autoUpdater.quitAndInstall()` 어플리케이션을 다시 시작하고 다운로드된 업데이트를 설치합니다. 이 메서드는 `update-downloaded` 이벤트가 발생한 이후에만 사용할 수 있습니다. @@ -83,3 +89,4 @@ Returns: [server-support]: https://github.com/Squirrel/Squirrel.Mac#server-support [squirrel-windows]: https://github.com/Squirrel/Squirrel.Windows [installer]: https://github.com/atom/grunt-electron-installer +[app-user-model-id]: https://msdn.microsoft.com/en-us/library/windows/desktop/dd378459(v=vs.85).aspx diff --git a/docs-translations/ko-KR/tutorial/using-native-node-modules.md b/docs-translations/ko-KR/tutorial/using-native-node-modules.md index 0691fefc864d..45c4811aa1a1 100644 --- a/docs-translations/ko-KR/tutorial/using-native-node-modules.md +++ b/docs-translations/ko-KR/tutorial/using-native-node-modules.md @@ -29,6 +29,9 @@ npm install --save-dev electron-rebuild # 필요한 네이티브 모듈을 `npm install`로 설치한 후 다음 명령을 실행하세요: ./node_modules/.bin/electron-rebuild + +# Windows에서 문제가 발생하면 다음 명령을 대신 실행하세요: +.\node_modules\.bin\electron-rebuild.cmd ``` ### `npm`을 이용한 방법 From 441cc3e57ea926a9cc2b27f5d6e8a67b7abe2de3 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Wed, 4 Nov 2015 16:50:19 +0800 Subject: [PATCH 060/249] Style fix --- atom/browser/api/lib/app.coffee | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/atom/browser/api/lib/app.coffee b/atom/browser/api/lib/app.coffee index 18c80dc2b1f4..cc676df0dd5a 100644 --- a/atom/browser/api/lib/app.coffee +++ b/atom/browser/api/lib/app.coffee @@ -11,14 +11,14 @@ wrapSession = (session) -> # session is an Event Emitter. session.__proto__ = EventEmitter.prototype -wrapDownloadItem = (download_item) -> - # download_item is an Event Emitter. - download_item.__proto__ = EventEmitter.prototype +wrapDownloadItem = (downloadItem) -> + # downloadItem is an Event Emitter. + downloadItem.__proto__ = EventEmitter.prototype # Be compatible with old APIs. - download_item.url = download_item.getUrl() - download_item.filename = download_item.getFilename() - download_item.mimeType = download_item.getMimeType() - download_item.hasUserGesture = download_item.hasUserGesture() + downloadItem.url = downloadItem.getUrl() + downloadItem.filename = downloadItem.getFilename() + downloadItem.mimeType = downloadItem.getMimeType() + downloadItem.hasUserGesture = downloadItem.hasUserGesture() app.setApplicationMenu = (menu) -> require('menu').setApplicationMenu menu @@ -57,7 +57,7 @@ app.setDataPath = (path) -> @setPath 'userData', path app.resolveProxy = -> @defaultSession.resolveProxy.apply @defaultSession, arguments app.on 'activate', (event, hasVisibleWindows) -> @emit 'activate-with-no-open-windows' if not hasVisibleWindows -# Session wrapper. +# Wrappers for native classes. sessionBindings._setWrapSession wrapSession process.once 'exit', sessionBindings._clearWrapSession From 75f49477ca4e2d25c6dfb4d19440325d84d5a3b5 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Wed, 4 Nov 2015 16:54:36 +0800 Subject: [PATCH 061/249] Cleanup wrapper function when app has done quitting The app may still do something when quitting, we need to make sure the wrapper function is still there at that time. --- atom/browser/api/atom_api_download_item.cc | 22 +++++++++++++--------- atom/browser/api/atom_api_session.cc | 16 ++++++++++------ atom/browser/api/atom_api_web_contents.cc | 13 ++++++++----- atom/browser/api/lib/app.coffee | 3 --- atom/browser/api/lib/web-contents.coffee | 1 - 5 files changed, 31 insertions(+), 24 deletions(-) diff --git a/atom/browser/api/atom_api_download_item.cc b/atom/browser/api/atom_api_download_item.cc index ec4dcd84b285..691cfbfef594 100644 --- a/atom/browser/api/atom_api_download_item.cc +++ b/atom/browser/api/atom_api_download_item.cc @@ -6,6 +6,7 @@ #include +#include "atom/browser/atom_browser_main_parts.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/gurl_converter.h" @@ -159,14 +160,6 @@ mate::ObjectTemplateBuilder DownloadItem::GetObjectTemplateBuilder( .SetMethod("setSavePath", &DownloadItem::SetSavePath); } -void SetWrapDownloadItem(const WrapDownloadItemCallback& callback) { - g_wrap_download_item = callback; -} - -void ClearWrapDownloadItem() { - g_wrap_download_item.Reset(); -} - // static mate::Handle DownloadItem::Create( v8::Isolate* isolate, content::DownloadItem* item) { @@ -182,6 +175,18 @@ void* DownloadItem::UserDataKey() { return &kDownloadItemSavePathKey; } +void ClearWrapDownloadItem() { + g_wrap_download_item.Reset(); +} + +void SetWrapDownloadItem(const WrapDownloadItemCallback& callback) { + g_wrap_download_item = callback; + + // Cleanup the wrapper on exit. + atom::AtomBrowserMainParts::Get()->RegisterDestructionCallback( + base::Bind(ClearWrapDownloadItem)); +} + } // namespace api } // namespace atom @@ -193,7 +198,6 @@ void Initialize(v8::Local exports, v8::Local unused, v8::Isolate* isolate = context->GetIsolate(); mate::Dictionary dict(isolate, exports); dict.SetMethod("_setWrapDownloadItem", &atom::api::SetWrapDownloadItem); - dict.SetMethod("_clearWrapDownloadItem", &atom::api::ClearWrapDownloadItem); } } // namespace diff --git a/atom/browser/api/atom_api_session.cc b/atom/browser/api/atom_api_session.cc index 5bb96710f226..0ec9c05ed84e 100644 --- a/atom/browser/api/atom_api_session.cc +++ b/atom/browser/api/atom_api_session.cc @@ -9,9 +9,10 @@ #include "atom/browser/api/atom_api_cookies.h" #include "atom/browser/api/atom_api_download_item.h" -#include "atom/browser/atom_browser_context.h" #include "atom/browser/api/atom_api_web_contents.h" #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/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" @@ -395,14 +396,18 @@ mate::Handle Session::FromPartition( static_cast(browser_context.get())); } -void SetWrapSession(const WrapSessionCallback& callback) { - g_wrap_session = callback; -} - void ClearWrapSession() { g_wrap_session.Reset(); } +void SetWrapSession(const WrapSessionCallback& callback) { + g_wrap_session = callback; + + // Cleanup the wrapper on exit. + atom::AtomBrowserMainParts::Get()->RegisterDestructionCallback( + base::Bind(ClearWrapSession)); +} + } // namespace api } // namespace atom @@ -415,7 +420,6 @@ void Initialize(v8::Local exports, v8::Local unused, mate::Dictionary dict(isolate, exports); dict.SetMethod("fromPartition", &atom::api::Session::FromPartition); dict.SetMethod("_setWrapSession", &atom::api::SetWrapSession); - dict.SetMethod("_clearWrapSession", &atom::api::ClearWrapSession); } } // namespace diff --git a/atom/browser/api/atom_api_web_contents.cc b/atom/browser/api/atom_api_web_contents.cc index c329b257a290..5165877d1670 100644 --- a/atom/browser/api/atom_api_web_contents.cc +++ b/atom/browser/api/atom_api_web_contents.cc @@ -1124,14 +1124,18 @@ mate::Handle WebContents::Create( return handle; } -void SetWrapWebContents(const WrapWebContentsCallback& callback) { - g_wrap_web_contents = callback; -} - void ClearWrapWebContents() { g_wrap_web_contents.Reset(); } +void SetWrapWebContents(const WrapWebContentsCallback& callback) { + g_wrap_web_contents = callback; + + // Cleanup the wrapper on exit. + atom::AtomBrowserMainParts::Get()->RegisterDestructionCallback( + base::Bind(ClearWrapWebContents)); +} + } // namespace api } // namespace atom @@ -1145,7 +1149,6 @@ void Initialize(v8::Local exports, v8::Local unused, mate::Dictionary dict(isolate, exports); dict.SetMethod("create", &atom::api::WebContents::Create); dict.SetMethod("_setWrapWebContents", &atom::api::SetWrapWebContents); - dict.SetMethod("_clearWrapWebContents", &atom::api::ClearWrapWebContents); } } // namespace diff --git a/atom/browser/api/lib/app.coffee b/atom/browser/api/lib/app.coffee index cc676df0dd5a..ba68076177ae 100644 --- a/atom/browser/api/lib/app.coffee +++ b/atom/browser/api/lib/app.coffee @@ -59,10 +59,7 @@ app.on 'activate', (event, hasVisibleWindows) -> @emit 'activate-with-no-open-wi # Wrappers for native classes. sessionBindings._setWrapSession wrapSession -process.once 'exit', sessionBindings._clearWrapSession - downloadItemBindings._setWrapDownloadItem wrapDownloadItem -process.once 'exit', downloadItemBindings._clearWrapDownloadItem # Only one App object pemitted. module.exports = app diff --git a/atom/browser/api/lib/web-contents.coffee b/atom/browser/api/lib/web-contents.coffee index eab9f1967158..331a561189d7 100644 --- a/atom/browser/api/lib/web-contents.coffee +++ b/atom/browser/api/lib/web-contents.coffee @@ -112,7 +112,6 @@ wrapWebContents = (webContents) -> @_printToPDF printingSetting, callback binding._setWrapWebContents wrapWebContents -process.once 'exit', binding._clearWrapWebContents module.exports.create = (options={}) -> binding.create(options) From 84410a7e1c1a053220333e374b1445bd9d2259ff Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Wed, 4 Nov 2015 17:23:27 +0800 Subject: [PATCH 062/249] mac: Destroy the app delegate before running destruction callbacks Otherwise users might be able to access wrapper functions after they are destroyed. --- atom/browser/atom_browser_main_parts.cc | 4 ++++ atom/browser/atom_browser_main_parts.h | 5 ++++- atom/browser/atom_browser_main_parts_mac.mm | 2 +- 3 files changed, 9 insertions(+), 2 deletions(-) diff --git a/atom/browser/atom_browser_main_parts.cc b/atom/browser/atom_browser_main_parts.cc index 5fae5bfdbedd..f6d1070e875d 100644 --- a/atom/browser/atom_browser_main_parts.cc +++ b/atom/browser/atom_browser_main_parts.cc @@ -128,6 +128,10 @@ void AtomBrowserMainParts::PostMainMessageLoopStart() { void AtomBrowserMainParts::PostMainMessageLoopRun() { brightray::BrowserMainParts::PostMainMessageLoopRun(); +#if defined(OS_MACOSX) + FreeAppDelegate(); +#endif + // Make sure destruction callbacks are called before message loop is // destroyed, otherwise some objects that need to be deleted on IO thread // won't be freed. diff --git a/atom/browser/atom_browser_main_parts.h b/atom/browser/atom_browser_main_parts.h index 65b142157dc1..360b1cba1169 100644 --- a/atom/browser/atom_browser_main_parts.h +++ b/atom/browser/atom_browser_main_parts.h @@ -46,7 +46,6 @@ class AtomBrowserMainParts : public brightray::BrowserMainParts { void PostMainMessageLoopRun() override; #if defined(OS_MACOSX) void PreMainMessageLoopStart() override; - void PostDestroyThreads() override; #endif private: @@ -56,6 +55,10 @@ class AtomBrowserMainParts : public brightray::BrowserMainParts { void HandleShutdownSignals(); #endif +#if defined(OS_MACOSX) + void FreeAppDelegate(); +#endif + // A fake BrowserProcess object that used to feed the source code from chrome. scoped_ptr fake_browser_process_; diff --git a/atom/browser/atom_browser_main_parts_mac.mm b/atom/browser/atom_browser_main_parts_mac.mm index 1de07dfc0e44..42e3100f490e 100644 --- a/atom/browser/atom_browser_main_parts_mac.mm +++ b/atom/browser/atom_browser_main_parts_mac.mm @@ -34,7 +34,7 @@ void AtomBrowserMainParts::PreMainMessageLoopStart() { setObject:@"NO" forKey:@"NSTreatUnknownArgumentsAsOpen"]; } -void AtomBrowserMainParts::PostDestroyThreads() { +void AtomBrowserMainParts::FreeAppDelegate() { [[NSApp delegate] release]; [NSApp setDelegate:nil]; } From 07c55f321fd5baf8dc5c8646d171f6de90d7f165 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Wed, 4 Nov 2015 17:31:10 +0800 Subject: [PATCH 063/249] Destroy JS env immediately after running destruction callbacks --- atom/browser/atom_browser_main_parts.cc | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/atom/browser/atom_browser_main_parts.cc b/atom/browser/atom_browser_main_parts.cc index f6d1070e875d..041c9bfc8fbe 100644 --- a/atom/browser/atom_browser_main_parts.cc +++ b/atom/browser/atom_browser_main_parts.cc @@ -137,6 +137,14 @@ void AtomBrowserMainParts::PostMainMessageLoopRun() { // won't be freed. for (const auto& callback : destruction_callbacks_) callback.Run(); + + // Destroy JavaScript environment immediately after running destruction + // callbacks. + gc_timer_.Stop(); + node_debugger_.reset(); + atom_bindings_.reset(); + node_bindings_.reset(); + js_env_.reset(); } } // namespace atom From d56b34de3b9e3065f1b4aa8facdd78a840bb1acc Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Wed, 4 Nov 2015 18:21:03 +0800 Subject: [PATCH 064/249] Make sure all native resources get freed on exit --- atom/browser/api/atom_api_global_shortcut.cc | 3 +++ atom/browser/api/atom_api_global_shortcut.h | 9 ++++++--- atom/browser/api/atom_api_menu.cc | 8 ++++++++ atom/browser/api/atom_api_menu.h | 10 +++++++--- atom/browser/api/atom_api_menu_mac.h | 1 + atom/browser/api/atom_api_menu_mac.mm | 5 +++++ atom/browser/api/atom_api_power_monitor.cc | 3 +++ atom/browser/api/atom_api_power_monitor.h | 9 ++++++--- atom/browser/api/atom_api_power_save_blocker.cc | 5 +++++ atom/browser/api/atom_api_power_save_blocker.h | 10 ++++++---- atom/browser/api/atom_api_tray.h | 10 ++++++---- 11 files changed, 56 insertions(+), 17 deletions(-) diff --git a/atom/browser/api/atom_api_global_shortcut.cc b/atom/browser/api/atom_api_global_shortcut.cc index f5a03e4abf90..6ab4fa4b6186 100644 --- a/atom/browser/api/atom_api_global_shortcut.cc +++ b/atom/browser/api/atom_api_global_shortcut.cc @@ -23,6 +23,9 @@ GlobalShortcut::GlobalShortcut() { } GlobalShortcut::~GlobalShortcut() { +} + +void GlobalShortcut::Destroy() { UnregisterAll(); } diff --git a/atom/browser/api/atom_api_global_shortcut.h b/atom/browser/api/atom_api_global_shortcut.h index 15cd3d4e0edb..93eb7853ae0d 100644 --- a/atom/browser/api/atom_api_global_shortcut.h +++ b/atom/browser/api/atom_api_global_shortcut.h @@ -8,9 +8,9 @@ #include #include +#include "atom/browser/api/trackable_object.h" #include "base/callback.h" #include "chrome/browser/extensions/global_shortcut_listener.h" -#include "native_mate/wrappable.h" #include "native_mate/handle.h" #include "ui/base/accelerators/accelerator.h" @@ -19,13 +19,16 @@ namespace atom { namespace api { class GlobalShortcut : public extensions::GlobalShortcutListener::Observer, - public mate::Wrappable { + public mate::TrackableObject { public: static mate::Handle Create(v8::Isolate* isolate); protected: GlobalShortcut(); - virtual ~GlobalShortcut(); + ~GlobalShortcut() override; + + // mate::TrackableObject: + void Destroy() override; // mate::Wrappable implementations: mate::ObjectTemplateBuilder GetObjectTemplateBuilder( diff --git a/atom/browser/api/atom_api_menu.cc b/atom/browser/api/atom_api_menu.cc index 9bd724a9612e..1f16a428da01 100644 --- a/atom/browser/api/atom_api_menu.cc +++ b/atom/browser/api/atom_api_menu.cc @@ -27,6 +27,14 @@ Menu::Menu() Menu::~Menu() { } +void Menu::Destroy() { + model_.reset(); +} + +bool Menu::IsDestroyed() const { + return !model_; +} + void Menu::AfterInit(v8::Isolate* isolate) { mate::Dictionary wrappable(isolate, GetWrapper(isolate)); mate::Dictionary delegate; diff --git a/atom/browser/api/atom_api_menu.h b/atom/browser/api/atom_api_menu.h index 0d93c0d46be6..545dd18e386c 100644 --- a/atom/browser/api/atom_api_menu.h +++ b/atom/browser/api/atom_api_menu.h @@ -8,16 +8,16 @@ #include #include "atom/browser/api/atom_api_window.h" +#include "atom/browser/api/trackable_object.h" #include "atom/browser/ui/atom_menu_model.h" #include "base/callback.h" #include "base/memory/scoped_ptr.h" -#include "native_mate/wrappable.h" namespace atom { namespace api { -class Menu : public mate::Wrappable, +class Menu : public mate::TrackableObject, public AtomMenuModel::Delegate { public: static mate::Wrappable* Create(); @@ -37,9 +37,13 @@ class Menu : public mate::Wrappable, protected: Menu(); - virtual ~Menu(); + ~Menu() override; + + // mate::TrackableObject: + void Destroy() override; // mate::Wrappable: + bool IsDestroyed() const override; void AfterInit(v8::Isolate* isolate) override; // ui::SimpleMenuModel::Delegate: diff --git a/atom/browser/api/atom_api_menu_mac.h b/atom/browser/api/atom_api_menu_mac.h index 5a086776a639..baa2aff349e1 100644 --- a/atom/browser/api/atom_api_menu_mac.h +++ b/atom/browser/api/atom_api_menu_mac.h @@ -19,6 +19,7 @@ class MenuMac : public Menu { protected: MenuMac(); + void Destroy() override; void Popup(Window* window) override; void PopupAt(Window* window, int x, int y) override; diff --git a/atom/browser/api/atom_api_menu_mac.mm b/atom/browser/api/atom_api_menu_mac.mm index 071753218d6a..5936e0439f4f 100644 --- a/atom/browser/api/atom_api_menu_mac.mm +++ b/atom/browser/api/atom_api_menu_mac.mm @@ -18,6 +18,11 @@ namespace api { MenuMac::MenuMac() { } +void MenuMac::Destroy() { + menu_controller_.reset(); + Menu::Destroy(); +} + void MenuMac::Popup(Window* window) { NativeWindow* native_window = window->window(); if (!native_window) diff --git a/atom/browser/api/atom_api_power_monitor.cc b/atom/browser/api/atom_api_power_monitor.cc index 31b35e10cea8..eeb9475c2847 100644 --- a/atom/browser/api/atom_api_power_monitor.cc +++ b/atom/browser/api/atom_api_power_monitor.cc @@ -19,6 +19,9 @@ PowerMonitor::PowerMonitor() { } PowerMonitor::~PowerMonitor() { +} + +void PowerMonitor::Destroy() { base::PowerMonitor::Get()->RemoveObserver(this); } diff --git a/atom/browser/api/atom_api_power_monitor.h b/atom/browser/api/atom_api_power_monitor.h index dcf0906b437f..9303b3ab288f 100644 --- a/atom/browser/api/atom_api_power_monitor.h +++ b/atom/browser/api/atom_api_power_monitor.h @@ -5,7 +5,7 @@ #ifndef ATOM_BROWSER_API_ATOM_API_POWER_MONITOR_H_ #define ATOM_BROWSER_API_ATOM_API_POWER_MONITOR_H_ -#include "atom/browser/api/event_emitter.h" +#include "atom/browser/api/trackable_object.h" #include "base/compiler_specific.h" #include "base/power_monitor/power_observer.h" #include "native_mate/handle.h" @@ -14,14 +14,17 @@ namespace atom { namespace api { -class PowerMonitor : public mate::EventEmitter, +class PowerMonitor : public mate::TrackableObject, public base::PowerObserver { public: static v8::Local Create(v8::Isolate* isolate); protected: PowerMonitor(); - virtual ~PowerMonitor(); + ~PowerMonitor() override; + + // mate::TrackableObject: + void Destroy() override; // base::PowerObserver implementations: void OnPowerStateChange(bool on_battery_power) override; diff --git a/atom/browser/api/atom_api_power_save_blocker.cc b/atom/browser/api/atom_api_power_save_blocker.cc index 58983e6c846a..f77979ae417f 100644 --- a/atom/browser/api/atom_api_power_save_blocker.cc +++ b/atom/browser/api/atom_api_power_save_blocker.cc @@ -45,6 +45,11 @@ PowerSaveBlocker::PowerSaveBlocker() PowerSaveBlocker::~PowerSaveBlocker() { } +void PowerSaveBlocker::Destroy() { + power_save_blocker_types_.clear(); + power_save_blocker_.reset(); +} + void PowerSaveBlocker::UpdatePowerSaveBlocker() { if (power_save_blocker_types_.empty()) { power_save_blocker_.reset(); diff --git a/atom/browser/api/atom_api_power_save_blocker.h b/atom/browser/api/atom_api_power_save_blocker.h index 9861f2b0f7cd..e7ce97878ffb 100644 --- a/atom/browser/api/atom_api_power_save_blocker.h +++ b/atom/browser/api/atom_api_power_save_blocker.h @@ -7,10 +7,10 @@ #include +#include "atom/browser/api/trackable_object.h" #include "base/memory/scoped_ptr.h" #include "content/public/browser/power_save_blocker.h" #include "native_mate/handle.h" -#include "native_mate/wrappable.h" namespace mate { class Dictionary; @@ -20,13 +20,16 @@ namespace atom { namespace api { -class PowerSaveBlocker : public mate::Wrappable { +class PowerSaveBlocker : public mate::TrackableObject { public: static mate::Handle Create(v8::Isolate* isolate); protected: PowerSaveBlocker(); - virtual ~PowerSaveBlocker(); + ~PowerSaveBlocker() override; + + // mate::TrackableObject: + void Destroy() override; // mate::Wrappable implementations: mate::ObjectTemplateBuilder GetObjectTemplateBuilder( @@ -48,7 +51,6 @@ class PowerSaveBlocker : public mate::Wrappable { std::map; PowerSaveBlockerTypeMap power_save_blocker_types_; - DISALLOW_COPY_AND_ASSIGN(PowerSaveBlocker); }; diff --git a/atom/browser/api/atom_api_tray.h b/atom/browser/api/atom_api_tray.h index dc9302597cf3..9a423f61764f 100644 --- a/atom/browser/api/atom_api_tray.h +++ b/atom/browser/api/atom_api_tray.h @@ -8,7 +8,7 @@ #include #include -#include "atom/browser/api/event_emitter.h" +#include "atom/browser/api/trackable_object.h" #include "atom/browser/ui/tray_icon_observer.h" #include "base/memory/scoped_ptr.h" @@ -29,7 +29,7 @@ namespace api { class Menu; -class Tray : public mate::EventEmitter, +class Tray : public mate::TrackableObject, public TrayIconObserver { public: static mate::Wrappable* New(v8::Isolate* isolate, const gfx::Image& image); @@ -39,7 +39,7 @@ class Tray : public mate::EventEmitter, protected: explicit Tray(const gfx::Image& image); - virtual ~Tray(); + ~Tray() override; // TrayIconObserver: void OnClicked(const gfx::Rect& bounds, int modifiers) override; @@ -53,7 +53,9 @@ class Tray : public mate::EventEmitter, // mate::Wrappable: bool IsDestroyed() const override; - void Destroy(); + // mate::TrackableObject: + void Destroy() override; + void SetImage(mate::Arguments* args, const gfx::Image& image); void SetPressedImage(mate::Arguments* args, const gfx::Image& image); void SetToolTip(mate::Arguments* args, const std::string& tool_tip); From e4f74bb87ed246609b473920ab6cbd7a0e78d44a Mon Sep 17 00:00:00 2001 From: Kevin Simper Date: Tue, 3 Nov 2015 16:11:29 +0100 Subject: [PATCH 065/249] Update devtools-extension with a note about it not working --- docs/tutorial/devtools-extension.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/tutorial/devtools-extension.md b/docs/tutorial/devtools-extension.md index 20ba7031d8ad..8a2144be6966 100644 --- a/docs/tutorial/devtools-extension.md +++ b/docs/tutorial/devtools-extension.md @@ -8,6 +8,8 @@ the `BrowserWindow.addDevToolsExtension` API to load them. The loaded extensions will be remembered so you don't need to call the API every time when creating a window. +** NOTE: React DevTools does not work, follow the issue here https://github.com/atom/electron/issues/915 ** + For example, to use the [React DevTools Extension](https://github.com/facebook/react-devtools) , first you need to download its source code: From 4ce840d8e6c155f1465c286c87ac6edd63b2eb6f Mon Sep 17 00:00:00 2001 From: Ryan Molden Date: Wed, 4 Nov 2015 11:42:35 -0800 Subject: [PATCH 066/249] Re-enable accessibility in Electron on Windows In conjunction with commit 7c41f0e. --- atom/browser/native_window_views_win.cc | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/atom/browser/native_window_views_win.cc b/atom/browser/native_window_views_win.cc index d49683acb3cf..02ebd2ef32fc 100644 --- a/atom/browser/native_window_views_win.cc +++ b/atom/browser/native_window_views_win.cc @@ -3,6 +3,7 @@ // found in the LICENSE file. #include "atom/browser/native_window_views.h" +#include "content/public/browser/browser_accessibility_state.h" namespace atom { @@ -83,6 +84,20 @@ bool NativeWindowViews::PreHandleMSG( NotifyWindowMessage(message, w_param, l_param); switch (message) { + // Screen readers send WM_GETOBJECT in order to get the accessibility + // object, so take this opportunity to push Chromium into accessible + // mode if it isn't already, always say we didn't handle the message + // because we still want Chromium to handle returning the actual + // accessibility object. + case WM_GETOBJECT: { + const DWORD obj_id = static_cast(l_param); + if (obj_id == OBJID_CLIENT) { + const auto axState = content::BrowserAccessibilityState::GetInstance(); + if (axState && !axState->IsAccessibleBrowser()) + axState->OnScreenReaderDetected(); + } + return false; + } case WM_COMMAND: // Handle thumbar button click message. if (HIWORD(w_param) == THBN_CLICKED) From 4ff5ce4d6d4b8104c1dfca2b95f15ab847a2a3ed Mon Sep 17 00:00:00 2001 From: Tyler Gibson Date: Wed, 4 Nov 2015 13:40:12 -0800 Subject: [PATCH 067/249] Fixing MoveItemToTrash behavior in Windows Modifying MoveItemToTrash for Windows to actually verify file can be moved to a drive's recycle bin before attempting to delete it. PR: #3337. --- atom/common/platform_util_win.cc | 212 +++++++++++++++++++++++++++---- 1 file changed, 188 insertions(+), 24 deletions(-) diff --git a/atom/common/platform_util_win.cc b/atom/common/platform_util_win.cc index 09ac5aca48f2..2ef8a0528088 100644 --- a/atom/common/platform_util_win.cc +++ b/atom/common/platform_util_win.cc @@ -5,7 +5,9 @@ #include "atom/common/platform_util.h" #include +#include #include +#include #include #include #include @@ -19,6 +21,7 @@ #include "base/strings/utf_string_conversions.h" #include "base/win/registry.h" #include "base/win/scoped_co_mem.h" +#include "base/win/scoped_com_initializer.h" #include "base/win/scoped_comptr.h" #include "base/win/windows_version.h" #include "url/gurl.h" @@ -42,6 +45,159 @@ bool ValidateShellCommandForScheme(const std::string& scheme) { return true; } +// Required COM implementation of IFileOperationProgressSink so we can +// precheck files before deletion to make sure they can be move to the +// Recycle Bin. +class DeleteFileProgressSink : public IFileOperationProgressSink { + public: + DeleteFileProgressSink(); + + private: + ULONG STDMETHODCALLTYPE AddRef(void); + ULONG STDMETHODCALLTYPE Release(void); + HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, LPVOID* ppvObj); + HRESULT STDMETHODCALLTYPE StartOperations(void); + HRESULT STDMETHODCALLTYPE FinishOperations(HRESULT); + HRESULT STDMETHODCALLTYPE PreRenameItem( + DWORD, IShellItem*, LPCWSTR); + HRESULT STDMETHODCALLTYPE PostRenameItem( + DWORD, IShellItem*, LPCWSTR, HRESULT, IShellItem*); + HRESULT STDMETHODCALLTYPE PreMoveItem( + DWORD, IShellItem*, IShellItem*, LPCWSTR); + HRESULT STDMETHODCALLTYPE PostMoveItem( + DWORD, IShellItem*, IShellItem*, LPCWSTR, HRESULT, IShellItem*); + HRESULT STDMETHODCALLTYPE PreCopyItem( + DWORD, IShellItem*, IShellItem*, LPCWSTR); + HRESULT STDMETHODCALLTYPE PostCopyItem( + DWORD, IShellItem*, IShellItem*, LPCWSTR, HRESULT, IShellItem*); + HRESULT STDMETHODCALLTYPE PreDeleteItem(DWORD, IShellItem*); + HRESULT STDMETHODCALLTYPE PostDeleteItem( + DWORD, IShellItem*, HRESULT, IShellItem*); + HRESULT STDMETHODCALLTYPE PreNewItem( + DWORD, IShellItem*, LPCWSTR); + HRESULT STDMETHODCALLTYPE PostNewItem( + DWORD, IShellItem*, LPCWSTR, LPCWSTR, DWORD, HRESULT, IShellItem*); + HRESULT STDMETHODCALLTYPE UpdateProgress(UINT, UINT); + HRESULT STDMETHODCALLTYPE ResetTimer(void); + HRESULT STDMETHODCALLTYPE PauseTimer(void); + HRESULT STDMETHODCALLTYPE ResumeTimer(void); + + ULONG m_cRef; +}; + +DeleteFileProgressSink::DeleteFileProgressSink() { + m_cRef = 0; +} + +HRESULT DeleteFileProgressSink::PreDeleteItem(DWORD dwFlags, IShellItem*) { + if (!(dwFlags & TSF_DELETE_RECYCLE_IF_POSSIBLE)) { + // TSF_DELETE_RECYCLE_IF_POSSIBLE will not be set for items that cannot be + // recycled. In this case, we abort the delete operation. This bubbles + // up and stops the Delete in IFileOperation. + return E_ABORT; + } + // Returns S_OK if successful, or an error value otherwise. In the case of an + // error value, the delete operation and all subsequent operations pending + // from the call to IFileOperation are canceled. + return S_OK; +} + +HRESULT DeleteFileProgressSink::QueryInterface(REFIID riid, LPVOID* ppvObj) { + // Always set out parameter to NULL, validating it first. + if (!ppvObj) + return E_INVALIDARG; + *ppvObj = nullptr; + if (riid == IID_IUnknown || riid == IID_IFileOperationProgressSink) { + // Increment the reference count and return the pointer. + *ppvObj = reinterpret_cast(this); + AddRef(); + return NOERROR; + } + return E_NOINTERFACE; +} + +ULONG DeleteFileProgressSink::AddRef() { + InterlockedIncrement(&m_cRef); + return m_cRef; +} + +ULONG DeleteFileProgressSink::Release() { + // Decrement the object's internal counter. + ULONG ulRefCount = InterlockedDecrement(&m_cRef); + if (0 == m_cRef) { + delete this; + } + return ulRefCount; +} + +HRESULT DeleteFileProgressSink::StartOperations() { + return S_OK; +} + +HRESULT DeleteFileProgressSink::FinishOperations(HRESULT) { + return S_OK; +} + +HRESULT DeleteFileProgressSink::PreRenameItem(DWORD, IShellItem*, LPCWSTR) { + return S_OK; +} + +HRESULT DeleteFileProgressSink::PostRenameItem( + DWORD, IShellItem*, __RPC__in_string LPCWSTR, HRESULT, IShellItem*) { + return E_NOTIMPL; +} + +HRESULT DeleteFileProgressSink::PreMoveItem( + DWORD, IShellItem*, IShellItem*, LPCWSTR) { + return E_NOTIMPL; +} + +HRESULT DeleteFileProgressSink::PostMoveItem( + DWORD, IShellItem*, IShellItem*, LPCWSTR, HRESULT, IShellItem*) { + return E_NOTIMPL; +} + +HRESULT DeleteFileProgressSink::PreCopyItem( + DWORD, IShellItem*, IShellItem*, LPCWSTR) { + return E_NOTIMPL; +} + +HRESULT DeleteFileProgressSink::PostCopyItem( + DWORD, IShellItem*, IShellItem*, LPCWSTR, HRESULT, IShellItem*) { + return E_NOTIMPL; +} + +HRESULT DeleteFileProgressSink::PostDeleteItem( + DWORD, IShellItem*, HRESULT, IShellItem*) { + return S_OK; +} + +HRESULT DeleteFileProgressSink::PreNewItem( + DWORD dwFlags, IShellItem*, LPCWSTR) { + return E_NOTIMPL; +} + +HRESULT DeleteFileProgressSink::PostNewItem( + DWORD, IShellItem*, LPCWSTR, LPCWSTR, DWORD, HRESULT, IShellItem*) { + return E_NOTIMPL; +} + +HRESULT DeleteFileProgressSink::UpdateProgress(UINT, UINT) { + return S_OK; +} + +HRESULT DeleteFileProgressSink::ResetTimer() { + return S_OK; +} + +HRESULT DeleteFileProgressSink::PauseTimer() { + return S_OK; +} + +HRESULT DeleteFileProgressSink::ResumeTimer() { + return S_OK; +} + } // namespace namespace platform_util { @@ -170,32 +326,40 @@ bool OpenExternal(const GURL& url) { } bool MoveItemToTrash(const base::FilePath& path) { - // SHFILEOPSTRUCT wants the path to be terminated with two NULLs, - // so we have to use wcscpy because wcscpy_s writes non-NULLs - // into the rest of the buffer. - wchar_t double_terminated_path[MAX_PATH + 1] = {0}; -#pragma warning(suppress:4996) // don't complain about wcscpy deprecation - wcscpy(double_terminated_path, path.value().c_str()); - - SHFILEOPSTRUCT file_operation = {0}; - file_operation.wFunc = FO_DELETE; - file_operation.pFrom = double_terminated_path; - file_operation.fFlags = FOF_ALLOWUNDO | FOF_SILENT | FOF_NOCONFIRMATION; - int err = SHFileOperation(&file_operation); - - // Since we're passing flags to the operation telling it to be silent, - // it's possible for the operation to be aborted/cancelled without err - // being set (although MSDN doesn't give any scenarios for how this can - // happen). See MSDN for SHFileOperation and SHFILEOPTSTRUCT. - if (file_operation.fAnyOperationsAborted) + base::win::ScopedCOMInitializer com_initializer; + if (!com_initializer.succeeded()) return false; - // Some versions of Windows return ERROR_FILE_NOT_FOUND (0x2) when deleting - // an empty directory and some return 0x402 when they should be returning - // ERROR_FILE_NOT_FOUND. MSDN says Vista and up won't return 0x402. Windows 7 - // can return DE_INVALIDFILES (0x7C) for nonexistent directories. - return (err == 0 || err == ERROR_FILE_NOT_FOUND || err == 0x402 || - err == 0x7C); + base::win::ScopedComPtr pfo; + if (FAILED(pfo.CreateInstance(CLSID_FileOperation))) + return false; + + // Elevation prompt enabled for UAC protected files. This overrides the + // SILENT, NO_UI and NOERRORUI flags. + if (FAILED(pfo->SetOperationFlags(FOF_NO_UI | + FOF_ALLOWUNDO | + FOF_NOERRORUI | + FOF_SILENT | + FOFX_SHOWELEVATIONPROMPT | + FOFX_RECYCLEONDELETE))) + return false; + + // Create an IShellItem from the supplied source path. + base::win::ScopedComPtr delete_item; + if (FAILED(SHCreateItemFromParsingName(path.value().c_str(), + NULL, + IID_PPV_ARGS(delete_item.Receive())))) + return false; + + base::win::ScopedComPtr delete_sink( + new DeleteFileProgressSink); + if (!delete_sink) + return false; + + // Processes the queued command DeleteItem. This will trigger + // the DeleteFileProgressSink to check for Recycle Bin. + return SUCCEEDED(pfo->DeleteItem(delete_item.get(), delete_sink.get())) && + SUCCEEDED(pfo->PerformOperations()); } void Beep() { From 47649ffd179a67cd9e5462856da8ca94c92915d2 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Thu, 5 Nov 2015 20:47:27 +0800 Subject: [PATCH 068/249] win: Fix calling showItemInFolder in renderer process --- atom/common/api/lib/shell.coffee | 4 ---- atom/common/platform_util_win.cc | 4 ++++ 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/atom/common/api/lib/shell.coffee b/atom/common/api/lib/shell.coffee index bd7109e34518..5fb935bacd21 100644 --- a/atom/common/api/lib/shell.coffee +++ b/atom/common/api/lib/shell.coffee @@ -1,5 +1 @@ module.exports = process.atomBinding 'shell' - -if process.platform is 'win32' and process.type is 'renderer' - module.exports.showItemInFolder = (item) -> - require('remote').require('shell').showItemInFolder item diff --git a/atom/common/platform_util_win.cc b/atom/common/platform_util_win.cc index 2ef8a0528088..87f45e5cb2d4 100644 --- a/atom/common/platform_util_win.cc +++ b/atom/common/platform_util_win.cc @@ -203,6 +203,10 @@ HRESULT DeleteFileProgressSink::ResumeTimer() { namespace platform_util { void ShowItemInFolder(const base::FilePath& full_path) { + base::win::ScopedCOMInitializer com_initializer; + if (!com_initializer.succeeded()) + return; + base::FilePath dir = full_path.DirName().AsEndingWithSeparator(); // ParseDisplayName will fail if the directory is "C:", it must be "C:\\". if (dir.empty()) From 2505ebb9a60714bcfcba8545fa6f2051574bc053 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Thu, 5 Nov 2015 22:00:40 +0800 Subject: [PATCH 069/249] win: Guard against failure of RtlAddFunctionTable On some machines this call will fail and CHECK will abort the application. --- .../crash_reporter/crash_reporter_win.cc | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/atom/common/crash_reporter/crash_reporter_win.cc b/atom/common/crash_reporter/crash_reporter_win.cc index 78bd196f6cce..240c229ca4b6 100644 --- a/atom/common/crash_reporter/crash_reporter_win.cc +++ b/atom/common/crash_reporter/crash_reporter_win.cc @@ -80,7 +80,7 @@ struct ExceptionHandlerRecord { unsigned char thunk[12]; }; -void RegisterNonABICompliantCodeRange(void* start, size_t size_in_bytes) { +bool RegisterNonABICompliantCodeRange(void* start, size_t size_in_bytes) { ExceptionHandlerRecord* record = reinterpret_cast(start); @@ -117,17 +117,17 @@ void RegisterNonABICompliantCodeRange(void* start, size_t size_in_bytes) { // Protect reserved page against modifications. DWORD old_protect; - CHECK(VirtualProtect( - start, sizeof(ExceptionHandlerRecord), PAGE_EXECUTE_READ, &old_protect)); - CHECK(RtlAddFunctionTable( - &record->runtime_function, 1, reinterpret_cast(start))); + return VirtualProtect(start, sizeof(ExceptionHandlerRecord), + PAGE_EXECUTE_READ, &old_protect) && + RtlAddFunctionTable(&record->runtime_function, 1, + reinterpret_cast(start)); } void UnregisterNonABICompliantCodeRange(void* start) { ExceptionHandlerRecord* record = reinterpret_cast(start); - CHECK(RtlDeleteFunctionTable(&record->runtime_function)); + RtlDeleteFunctionTable(&record->runtime_function); } #endif // _WIN64 @@ -184,6 +184,7 @@ void CrashReporterWin::InitBreakpad(const std::string& product_name, LOG(ERROR) << "Cannot initialize out-of-process crash handler"; #ifdef _WIN64 + bool registered = false; // Hook up V8 to breakpad. { // gin::Debug::SetCodeRangeCreatedCallback only runs the callback when @@ -192,9 +193,10 @@ void CrashReporterWin::InitBreakpad(const std::string& product_name, size_t size = 0; v8::Isolate::GetCurrent()->GetCodeRange(&code_range, &size); if (code_range && size) - RegisterNonABICompliantCodeRange(code_range, size); + registered = RegisterNonABICompliantCodeRange(code_range, size); } - gin::Debug::SetCodeRangeDeletedCallback(UnregisterNonABICompliantCodeRange); + if (registered) + gin::Debug::SetCodeRangeDeletedCallback(UnregisterNonABICompliantCodeRange); #endif } From 818892d474fce15c2aa9819561e5bd9986a80d1c Mon Sep 17 00:00:00 2001 From: Nishanth Shanmugham Date: Thu, 5 Nov 2015 18:45:43 -0600 Subject: [PATCH 070/249] Tray: Add drag-entered and drag-exited events --- atom/browser/api/atom_api_tray.cc | 8 ++++++++ atom/browser/api/atom_api_tray.h | 2 ++ atom/browser/ui/tray_icon.cc | 8 ++++++++ atom/browser/ui/tray_icon.h | 2 ++ atom/browser/ui/tray_icon_cocoa.mm | 5 +++++ atom/browser/ui/tray_icon_observer.h | 2 ++ 6 files changed, 27 insertions(+) diff --git a/atom/browser/api/atom_api_tray.cc b/atom/browser/api/atom_api_tray.cc index 0f5829e19c14..5381c77c3793 100644 --- a/atom/browser/api/atom_api_tray.cc +++ b/atom/browser/api/atom_api_tray.cc @@ -78,6 +78,14 @@ void Tray::OnDropFiles(const std::vector& files) { Emit("drop-files", files); } +void Tray::OnDragEntered() { + Emit("drag-entered"); +} + +void Tray::OnDragExited() { + Emit("drag-exited"); +} + bool Tray::IsDestroyed() const { return !tray_icon_; } diff --git a/atom/browser/api/atom_api_tray.h b/atom/browser/api/atom_api_tray.h index 9a423f61764f..b26796bccedc 100644 --- a/atom/browser/api/atom_api_tray.h +++ b/atom/browser/api/atom_api_tray.h @@ -49,6 +49,8 @@ class Tray : public mate::TrackableObject, void OnBalloonClicked() override; void OnBalloonClosed() override; void OnDropFiles(const std::vector& files) override; + void OnDragEntered() override; + void OnDragExited() override; // mate::Wrappable: bool IsDestroyed() const override; diff --git a/atom/browser/ui/tray_icon.cc b/atom/browser/ui/tray_icon.cc index d2c6bc1b2597..bc69b6e72759 100644 --- a/atom/browser/ui/tray_icon.cc +++ b/atom/browser/ui/tray_icon.cc @@ -59,4 +59,12 @@ void TrayIcon::NotifyDropFiles(const std::vector& files) { FOR_EACH_OBSERVER(TrayIconObserver, observers_, OnDropFiles(files)); } +void TrayIcon::NotifyDragEntered() { + FOR_EACH_OBSERVER(TrayIconObserver, observers_, OnDragEntered()); +} + +void TrayIcon::NotifyDragExited() { + FOR_EACH_OBSERVER(TrayIconObserver, observers_, OnDragExited()); +} + } // namespace atom diff --git a/atom/browser/ui/tray_icon.h b/atom/browser/ui/tray_icon.h index 539fe04f4bb6..bff3057bf612 100644 --- a/atom/browser/ui/tray_icon.h +++ b/atom/browser/ui/tray_icon.h @@ -62,6 +62,8 @@ class TrayIcon { void NotifyRightClicked(const gfx::Rect& bounds = gfx::Rect(), int modifiers = 0); void NotifyDropFiles(const std::vector& files); + void TrayIcon::NotifyDragEntered(); + void TrayIcon::NotifyDragExited(); protected: TrayIcon(); diff --git a/atom/browser/ui/tray_icon_cocoa.mm b/atom/browser/ui/tray_icon_cocoa.mm index 34ca4e9a9112..40505a64d8cd 100644 --- a/atom/browser/ui/tray_icon_cocoa.mm +++ b/atom/browser/ui/tray_icon_cocoa.mm @@ -254,9 +254,14 @@ const CGFloat kVerticalTitleMargin = 2; } - (NSDragOperation)draggingEntered:(id )sender { + trayIcon_->NotifyDragEntered(); return NSDragOperationCopy; } +- (void)draggingExited:(id )sender { + trayIcon_->NotifyDragExited(); +} + - (BOOL)performDragOperation:(id )sender { NSPasteboard* pboard = [sender draggingPasteboard]; diff --git a/atom/browser/ui/tray_icon_observer.h b/atom/browser/ui/tray_icon_observer.h index fa8090d7d6c5..e9a8bd33f1d3 100644 --- a/atom/browser/ui/tray_icon_observer.h +++ b/atom/browser/ui/tray_icon_observer.h @@ -23,6 +23,8 @@ class TrayIconObserver { virtual void OnBalloonClosed() {} virtual void OnRightClicked(const gfx::Rect& bounds, int modifiers) {} virtual void OnDropFiles(const std::vector& files) {} + virtual void OnDragEntered() {} + virtual void OnDragExited() {} protected: virtual ~TrayIconObserver() {} From ee783a13ad7553855f3789dc743d75ad08a01685 Mon Sep 17 00:00:00 2001 From: Nishanth Shanmugham Date: Thu, 5 Nov 2015 18:49:34 -0600 Subject: [PATCH 071/249] docs: Add Tray drag-entered and drag-exited events --- docs/api/tray.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/docs/api/tray.md b/docs/api/tray.md index 528705acb325..5d187fc5b88c 100644 --- a/docs/api/tray.md +++ b/docs/api/tray.md @@ -119,6 +119,14 @@ closes it. Emitted when dragged files are dropped in the tray icon. +### Event: 'drag-entered' _OS X_ + +Emitted when a drag operation enters the tray icon. + +### Event: 'drag-exited' _OS X_ + +Emitted when a drag operation exits the tray icon. + ## Methods The `Tray` module has the following methods: From 8a296f82a09ffb59f84562d8e2e5b96c19c626c6 Mon Sep 17 00:00:00 2001 From: Nishanth Shanmugham Date: Thu, 5 Nov 2015 19:02:24 -0600 Subject: [PATCH 072/249] Tray: Remove extra qualification in header --- atom/browser/ui/tray_icon.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/atom/browser/ui/tray_icon.h b/atom/browser/ui/tray_icon.h index bff3057bf612..b63d3c48c262 100644 --- a/atom/browser/ui/tray_icon.h +++ b/atom/browser/ui/tray_icon.h @@ -62,8 +62,8 @@ class TrayIcon { void NotifyRightClicked(const gfx::Rect& bounds = gfx::Rect(), int modifiers = 0); void NotifyDropFiles(const std::vector& files); - void TrayIcon::NotifyDragEntered(); - void TrayIcon::NotifyDragExited(); + void NotifyDragEntered(); + void NotifyDragExited(); protected: TrayIcon(); From 0e950e6d26789bbf1725e1bb0872eae0b2cc5073 Mon Sep 17 00:00:00 2001 From: Plusb Preco Date: Fri, 6 Nov 2015 10:52:55 +0900 Subject: [PATCH 073/249] Update as upstream --- docs-translations/ko-KR/tutorial/devtools-extension.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/docs-translations/ko-KR/tutorial/devtools-extension.md b/docs-translations/ko-KR/tutorial/devtools-extension.md index 966431dd72b8..659c769dde34 100644 --- a/docs-translations/ko-KR/tutorial/devtools-extension.md +++ b/docs-translations/ko-KR/tutorial/devtools-extension.md @@ -5,7 +5,9 @@ 개발자 콘솔 확장 기능은 간단하게 사용할 확장 기능 플러그인의 소스 코드를 다운로드한 후 `BrowserWindow.addDevToolsExtension` API를 이용하여 어플리케이션 내에 로드할 수 있습니다. 한가지 주의할 점은 확장 기능 사용시 창이 생성될 때 마다 일일이 해당 API를 호출할 필요는 없습니다. -예시로 [React DevTools Extension](https://github.com/facebook/react-devtools)을 사용합니다. +** 주의: 현재 React DevTools은 작동하지 않습니다. https://github.com/atom/electron/issues/915 이슈를 참고하세요! ** + +다음 예제는 [React DevTools Extension](https://github.com/facebook/react-devtools)을 사용합니다. 먼저 소스코드를 다운로드 받습니다: @@ -15,8 +17,7 @@ $ git clone --recursive https://github.com/facebook/react-devtools.git ``` [`react-devtools/shells/chrome/Readme.md`](https://github.com/facebook/react-devtools/blob/master/shells/chrome/Readme.md) -가이드를 통해 확장 기능을 개발하는 방법을 알아볼 수 있습니다. - +를 통해 확장 기능을 개발하는 방법을 알아볼 수 있습니다. 그리고 개발자 콘솔에서 다음 코드를 입력하면 확장 기능을 로드할 수 있습니다: From 863199348f8a07cdff4dfa23fea0598ddb3dcf2b Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Fri, 6 Nov 2015 18:27:13 +0800 Subject: [PATCH 074/249] Make process.exit() quit gracefully Instead of abrupting the whole program immediately, we should close all windows and release all native resources gracefully on exit. This avoids possible crashes. Fix #3350. --- atom/browser/api/atom_api_app.cc | 1 + atom/browser/api/lib/app.coffee | 1 - atom/browser/atom_browser_main_parts.cc | 14 ++++++++++++++ atom/browser/atom_browser_main_parts.h | 7 +++++++ atom/browser/browser.cc | 22 ++++++++++++++++++++++ atom/browser/browser.h | 3 +++ atom/browser/lib/init.coffee | 3 +++ docs/api/app.md | 9 +++++++++ 8 files changed, 59 insertions(+), 1 deletion(-) diff --git a/atom/browser/api/atom_api_app.cc b/atom/browser/api/atom_api_app.cc index 04ed06e0138f..1c5c2c04f145 100644 --- a/atom/browser/api/atom_api_app.cc +++ b/atom/browser/api/atom_api_app.cc @@ -339,6 +339,7 @@ mate::ObjectTemplateBuilder App::GetObjectTemplateBuilder( auto browser = base::Unretained(Browser::Get()); return mate::ObjectTemplateBuilder(isolate) .SetMethod("quit", base::Bind(&Browser::Quit, browser)) + .SetMethod("exit", base::Bind(&Browser::Exit, browser)) .SetMethod("focus", base::Bind(&Browser::Focus, browser)) .SetMethod("getVersion", base::Bind(&Browser::GetVersion, browser)) .SetMethod("setVersion", base::Bind(&Browser::SetVersion, browser)) diff --git a/atom/browser/api/lib/app.coffee b/atom/browser/api/lib/app.coffee index ba68076177ae..4df7aef10bdf 100644 --- a/atom/browser/api/lib/app.coffee +++ b/atom/browser/api/lib/app.coffee @@ -50,7 +50,6 @@ app.getAppPath = -> # Be compatible with old API. app.once 'ready', -> @emit 'finish-launching' app.terminate = app.quit -app.exit = process.exit app.getHomeDir = -> @getPath 'home' app.getDataPath = -> @getPath 'userData' app.setDataPath = (path) -> @setPath 'userData', path diff --git a/atom/browser/atom_browser_main_parts.cc b/atom/browser/atom_browser_main_parts.cc index 041c9bfc8fbe..0a8c16ca223f 100644 --- a/atom/browser/atom_browser_main_parts.cc +++ b/atom/browser/atom_browser_main_parts.cc @@ -30,6 +30,7 @@ AtomBrowserMainParts* AtomBrowserMainParts::self_ = NULL; AtomBrowserMainParts::AtomBrowserMainParts() : fake_browser_process_(new BrowserProcess), + exit_code_(nullptr), browser_(new Browser), node_bindings_(NodeBindings::Create(true)), atom_bindings_(new AtomBindings), @@ -47,6 +48,14 @@ AtomBrowserMainParts* AtomBrowserMainParts::Get() { return self_; } +bool AtomBrowserMainParts::SetExitCode(int code) { + if (!exit_code_) + return false; + + *exit_code_ = code; + return true; +} + void AtomBrowserMainParts::RegisterDestructionCallback( const base::Closure& callback) { destruction_callbacks_.push_back(callback); @@ -118,6 +127,11 @@ void AtomBrowserMainParts::PreMainMessageLoopRun() { #endif } +bool AtomBrowserMainParts::MainMessageLoopRun(int* result_code) { + exit_code_ = result_code; + return brightray::BrowserMainParts::MainMessageLoopRun(result_code); +} + void AtomBrowserMainParts::PostMainMessageLoopStart() { brightray::BrowserMainParts::PostMainMessageLoopStart(); #if defined(OS_POSIX) diff --git a/atom/browser/atom_browser_main_parts.h b/atom/browser/atom_browser_main_parts.h index 360b1cba1169..bb4b204669fd 100644 --- a/atom/browser/atom_browser_main_parts.h +++ b/atom/browser/atom_browser_main_parts.h @@ -31,6 +31,9 @@ class AtomBrowserMainParts : public brightray::BrowserMainParts { static AtomBrowserMainParts* Get(); + // Sets the exit code, will fail if the the message loop is not ready. + bool SetExitCode(int code); + // Register a callback that should be destroyed before JavaScript environment // gets destroyed. void RegisterDestructionCallback(const base::Closure& callback); @@ -42,6 +45,7 @@ class AtomBrowserMainParts : public brightray::BrowserMainParts { void PreEarlyInitialization() override; void PostEarlyInitialization() override; void PreMainMessageLoopRun() override; + bool MainMessageLoopRun(int* result_code) override; void PostMainMessageLoopStart() override; void PostMainMessageLoopRun() override; #if defined(OS_MACOSX) @@ -66,6 +70,9 @@ class AtomBrowserMainParts : public brightray::BrowserMainParts { // with a task runner that will post all work to main loop. scoped_refptr bridge_task_runner_; + // Pointer to exit code. + int* exit_code_; + scoped_ptr browser_; scoped_ptr js_env_; scoped_ptr node_bindings_; diff --git a/atom/browser/browser.cc b/atom/browser/browser.cc index e80cb4e60e20..57741786520d 100644 --- a/atom/browser/browser.cc +++ b/atom/browser/browser.cc @@ -7,6 +7,7 @@ #include #include "atom/browser/atom_browser_main_parts.h" +#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" @@ -45,6 +46,27 @@ void Browser::Quit() { window_list->CloseAllWindows(); } +void Browser::Exit(int code) { + if (!AtomBrowserMainParts::Get()->SetExitCode(code)) { + // Message loop is not ready, quit directly. + exit(code); + } else { + // Prepare to quit when all windows have been closed.. + is_quiting_ = true; + + // Must destroy windows before quitting, otherwise bad things can happen. + atom::WindowList* window_list = atom::WindowList::GetInstance(); + if (window_list->size() == 0) { + NotifyAndShutdown(); + } 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() + } + } +} + void Browser::Shutdown() { if (is_shutdown_) return; diff --git a/atom/browser/browser.h b/atom/browser/browser.h index 447a526de6df..e20db080b67a 100644 --- a/atom/browser/browser.h +++ b/atom/browser/browser.h @@ -42,6 +42,9 @@ class Browser : public WindowListObserver { // Try to close all windows and quit the application. void Quit(); + // Exit the application immediately and set exit code. + void Exit(int code); + // Cleanup everything and shutdown the application gracefully. void Shutdown(); diff --git a/atom/browser/lib/init.coffee b/atom/browser/lib/init.coffee index 9f92d700c73a..80d2da31b705 100644 --- a/atom/browser/lib/init.coffee +++ b/atom/browser/lib/init.coffee @@ -53,6 +53,9 @@ app = require 'app' app.on 'quit', -> process.emit 'exit' +# Map process.exit to app.exit, which quits gracefully. +process.exit = app.exit + # Load the RPC server. require './rpc-server' diff --git a/docs/api/app.md b/docs/api/app.md index 00aade7c54ab..fdb9f9980592 100644 --- a/docs/api/app.md +++ b/docs/api/app.md @@ -208,6 +208,15 @@ This method guarantees that all `beforeunload` and `unload` event handlers are correctly executed. It is possible that a window cancels the quitting by returning `false` in the `beforeunload` event handler. +### `app.exit(exitCode)` + +* `exitCode` Integer + +Exits immediately with `exitCode`. + +All windows will be closed immediately without asking user and the `before-quit` +and `will-quit` events will not be emitted. + ### `app.getAppPath()` Returns the current application directory. From acf4372cf7d8a07a9c55763ac2bb726e962aa251 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Fri, 6 Nov 2015 18:51:34 +0800 Subject: [PATCH 075/249] win: Add ELECTRON_DEFAULT_ERROR_MODE env It is useful to help debugging crashes without opening debugger. --- atom/common/node_bindings.cc | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/atom/common/node_bindings.cc b/atom/common/node_bindings.cc index 10da202da70d..dbd0bd8d96ee 100644 --- a/atom/common/node_bindings.cc +++ b/atom/common/node_bindings.cc @@ -14,6 +14,7 @@ #include "atom/common/node_includes.h" #include "base/command_line.h" #include "base/base_paths.h" +#include "base/environment.h" #include "base/files/file_path.h" #include "base/message_loop/message_loop.h" #include "base/path_service.h" @@ -141,6 +142,14 @@ void NodeBindings::Initialize() { // Init node. // (we assume node::Init would not modify the parameters under embedded mode). node::Init(nullptr, nullptr, nullptr, nullptr); + +#if defined(OS_WIN) + // uv_init overrides error mode to suppress the default crash dialog, bring + // it back if user wants to show it. + scoped_ptr env(base::Environment::Create()); + if (env->HasVar("ELECTRON_DEFAULT_ERROR_MODE")) + SetErrorMode(0); +#endif } node::Environment* NodeBindings::CreateEnvironment( From d70706f8765033138f4e19eef8c6ef723b217bc6 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Fri, 6 Nov 2015 20:23:41 +0800 Subject: [PATCH 076/249] Make sure handles of callbacks are releases on exit Some callbacks are stored in native resources that not managed by JavaScript, so when those resources are destroyed the JavaScript context may already be destroyed, and releasing callbacks then would result in crash. --- .../common/native_mate_converters/callback.cc | 29 +++++++++++ atom/common/native_mate_converters/callback.h | 48 ++++++++++++++----- 2 files changed, 66 insertions(+), 11 deletions(-) diff --git a/atom/common/native_mate_converters/callback.cc b/atom/common/native_mate_converters/callback.cc index 3bcb748689fb..87faa3df3cd5 100644 --- a/atom/common/native_mate_converters/callback.cc +++ b/atom/common/native_mate_converters/callback.cc @@ -4,6 +4,8 @@ #include "atom/common/native_mate_converters/callback.h" +#include "atom/browser/atom_browser_main_parts.h" + namespace mate { namespace internal { @@ -54,6 +56,33 @@ v8::Local BindFunctionWith(v8::Isolate* isolate, } // namespace +SafeV8Function::SafeV8Function(v8::Isolate* isolate, v8::Local value) + : v8_function_(new RefCountedPersistent(isolate, value)), + weak_factory_(this) { + Init(); +} + +SafeV8Function::SafeV8Function(const SafeV8Function& other) + : v8_function_(other.v8_function_), + weak_factory_(this) { + Init(); +} + +v8::Local SafeV8Function::NewHandle() const { + return v8_function_->NewHandle(); +} + +void SafeV8Function::Init() { + if (Locker::IsBrowserProcess() && atom::AtomBrowserMainParts::Get()) + atom::AtomBrowserMainParts::Get()->RegisterDestructionCallback( + base::Bind(&SafeV8Function::FreeHandle, weak_factory_.GetWeakPtr())); +} + +void SafeV8Function::FreeHandle() { + Locker locker(v8_function_->isolate()); + v8_function_ = nullptr; +} + v8::Local CreateFunctionFromTranslater( v8::Isolate* isolate, const Translater& translater) { // The FunctionTemplate is cached. diff --git a/atom/common/native_mate_converters/callback.h b/atom/common/native_mate_converters/callback.h index 228fc0d3bb1d..5dd9d3cec9b1 100644 --- a/atom/common/native_mate_converters/callback.h +++ b/atom/common/native_mate_converters/callback.h @@ -10,6 +10,7 @@ #include "atom/common/api/locker.h" #include "base/bind.h" #include "base/callback.h" +#include "base/memory/weak_ptr.h" #include "native_mate/function_template.h" #include "native_mate/scoped_persistent.h" #include "third_party/WebKit/public/web/WebScopedMicrotaskSuppression.h" @@ -18,7 +19,24 @@ namespace mate { namespace internal { -typedef scoped_refptr > SafeV8Function; +// Manages the V8 function with RAII, and automatically cleans the handle when +// JavaScript context is destroyed, even when the class is not destroyed. +class SafeV8Function { + public: + SafeV8Function(v8::Isolate* isolate, v8::Local value); + SafeV8Function(const SafeV8Function& other); + + bool is_alive() const { return v8_function_.get(); } + + v8::Local NewHandle() const; + + private: + void Init(); + void FreeHandle(); + + scoped_refptr> v8_function_; + base::WeakPtrFactory weak_factory_; +}; // Helper to invoke a V8 function with C++ parameters. template @@ -26,14 +44,17 @@ struct V8FunctionInvoker {}; template struct V8FunctionInvoker(ArgTypes...)> { - static v8::Local Go(v8::Isolate* isolate, SafeV8Function function, + static v8::Local Go(v8::Isolate* isolate, + const SafeV8Function& function, ArgTypes... raw) { Locker locker(isolate); v8::EscapableHandleScope handle_scope(isolate); + if (!function.is_alive()) + return v8::Null(isolate); scoped_ptr script_scope( Locker::IsBrowserProcess() ? nullptr : new blink::WebScopedRunV8Script(isolate)); - v8::Local holder = function->NewHandle(); + v8::Local holder = function.NewHandle(); v8::Local context = holder->CreationContext(); v8::Context::Scope context_scope(context); std::vector> args = { ConvertToV8(isolate, raw)... }; @@ -44,14 +65,17 @@ struct V8FunctionInvoker(ArgTypes...)> { template struct V8FunctionInvoker { - static void Go(v8::Isolate* isolate, SafeV8Function function, + static void Go(v8::Isolate* isolate, + const SafeV8Function& function, ArgTypes... raw) { Locker locker(isolate); v8::HandleScope handle_scope(isolate); + if (!function.is_alive()) + return; scoped_ptr script_scope( Locker::IsBrowserProcess() ? nullptr : new blink::WebScopedRunV8Script(isolate)); - v8::Local holder = function->NewHandle(); + v8::Local holder = function.NewHandle(); v8::Local context = holder->CreationContext(); v8::Context::Scope context_scope(context); std::vector> args = { ConvertToV8(isolate, raw)... }; @@ -61,17 +85,20 @@ struct V8FunctionInvoker { template struct V8FunctionInvoker { - static ReturnType Go(v8::Isolate* isolate, SafeV8Function function, + static ReturnType Go(v8::Isolate* isolate, + const SafeV8Function& function, ArgTypes... raw) { Locker locker(isolate); v8::HandleScope handle_scope(isolate); + ReturnType ret = ReturnType(); + if (!function.is_alive()) + return ret; scoped_ptr script_scope( Locker::IsBrowserProcess() ? nullptr : new blink::WebScopedRunV8Script(isolate)); - v8::Local holder = function->NewHandle(); + v8::Local holder = function.NewHandle(); v8::Local context = holder->CreationContext(); v8::Context::Scope context_scope(context); - ReturnType ret = ReturnType(); std::vector> args = { ConvertToV8(isolate, raw)... }; v8::Local result; auto maybe_result = @@ -119,9 +146,8 @@ struct Converter> { if (!val->IsFunction()) return false; - internal::SafeV8Function function( - new RefCountedPersistent(isolate, val)); - *out = base::Bind(&internal::V8FunctionInvoker::Go, isolate, function); + *out = base::Bind(&internal::V8FunctionInvoker::Go, + isolate, internal::SafeV8Function(isolate, val)); return true; } }; From c4ee8c1b1f8d335931f6a8fdce6a37ecab2e3d07 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Fri, 6 Nov 2015 21:00:38 +0800 Subject: [PATCH 077/249] spec: Fix refreshing on Windows --- spec/api-crash-reporter-spec.coffee | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/spec/api-crash-reporter-spec.coffee b/spec/api-crash-reporter-spec.coffee index 9aedb0c8ea1e..618adaaf9dec 100644 --- a/spec/api-crash-reporter-spec.coffee +++ b/spec/api-crash-reporter-spec.coffee @@ -53,5 +53,6 @@ describe 'crash-reporter module', -> protocol: 'file' pathname: path.join fixtures, 'api', 'crash.html' search: "?port=#{port}" - crashReporter.start {'submitUrl': 'http://127.0.0.1:' + port} + if process.platform is 'darwin' + crashReporter.start {'submitUrl': 'http://127.0.0.1:' + port} w.loadUrl url From 312a79165be96dcde56e6f7d270f0ff7d4c65a76 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Fri, 6 Nov 2015 21:37:37 +0800 Subject: [PATCH 078/249] Bump v0.34.3 --- atom.gyp | 2 +- atom/browser/resources/mac/Info.plist | 4 ++-- atom/browser/resources/win/atom.rc | 8 ++++---- atom/common/atom_version.h | 2 +- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/atom.gyp b/atom.gyp index 7b88df4d8013..a57b7dbf58f8 100644 --- a/atom.gyp +++ b/atom.gyp @@ -4,7 +4,7 @@ 'product_name%': 'Electron', 'company_name%': 'GitHub, Inc', 'company_abbr%': 'github', - 'version%': '0.34.2', + 'version%': '0.34.3', }, 'includes': [ 'filenames.gypi', diff --git a/atom/browser/resources/mac/Info.plist b/atom/browser/resources/mac/Info.plist index a703c01a766c..a7df1a582e08 100644 --- a/atom/browser/resources/mac/Info.plist +++ b/atom/browser/resources/mac/Info.plist @@ -17,9 +17,9 @@ CFBundleIconFile atom.icns CFBundleVersion - 0.34.2 + 0.34.3 CFBundleShortVersionString - 0.34.2 + 0.34.3 LSApplicationCategoryType public.app-category.developer-tools LSMinimumSystemVersion diff --git a/atom/browser/resources/win/atom.rc b/atom/browser/resources/win/atom.rc index 8401e1d7d09e..d3ebfaa8e0d9 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 0,34,2,0 - PRODUCTVERSION 0,34,2,0 + FILEVERSION 0,34,3,0 + PRODUCTVERSION 0,34,3,0 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -74,12 +74,12 @@ BEGIN BEGIN VALUE "CompanyName", "GitHub, Inc." VALUE "FileDescription", "Electron" - VALUE "FileVersion", "0.34.2" + VALUE "FileVersion", "0.34.3" VALUE "InternalName", "electron.exe" VALUE "LegalCopyright", "Copyright (C) 2015 GitHub, Inc. All rights reserved." VALUE "OriginalFilename", "electron.exe" VALUE "ProductName", "Electron" - VALUE "ProductVersion", "0.34.2" + VALUE "ProductVersion", "0.34.3" VALUE "SquirrelAwareVersion", "1" END END diff --git a/atom/common/atom_version.h b/atom/common/atom_version.h index 5b1dc4ab44a6..b879da3066d4 100644 --- a/atom/common/atom_version.h +++ b/atom/common/atom_version.h @@ -7,7 +7,7 @@ #define ATOM_MAJOR_VERSION 0 #define ATOM_MINOR_VERSION 34 -#define ATOM_PATCH_VERSION 2 +#define ATOM_PATCH_VERSION 3 #define ATOM_VERSION_IS_RELEASE 1 From 3465095c493f765bad2843c57c9af129222c94fa Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Sat, 7 Nov 2015 12:12:17 +0800 Subject: [PATCH 079/249] Update brightray for #3357 --- vendor/brightray | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vendor/brightray b/vendor/brightray index 49a86c123f4c..98b3eb04d85a 160000 --- a/vendor/brightray +++ b/vendor/brightray @@ -1 +1 @@ -Subproject commit 49a86c123f4cc43f4dca886ded612104a8a1fec6 +Subproject commit 98b3eb04d85a8a70b8d9f29477437061c2e77a83 From 09169ed4026aa674d49e1be5898a3895a4b6b089 Mon Sep 17 00:00:00 2001 From: tejaspathak Date: Sun, 8 Nov 2015 16:18:22 +0900 Subject: [PATCH 080/249] Add option to build local libchromiumcontent - Currently libchromiumcontent is downloaded by default. - Now developer can choose to provide local libchromiumcontent src, shared and static path --- script/bootstrap.py | 40 +++++++++++++++++++++++++++++++++++++--- 1 file changed, 37 insertions(+), 3 deletions(-) diff --git a/script/bootstrap.py b/script/bootstrap.py index d5ad41a61c59..81da2810eccb 100755 --- a/script/bootstrap.py +++ b/script/bootstrap.py @@ -26,6 +26,23 @@ def main(): os.chdir(SOURCE_ROOT) args = parse_args() + if (args.libcc_source_path != None and + args.libcc_shared_library_path != None and + args.libcc_static_library_path != None): + if (not os.path.isdir(args.libcc_source_path)): + print "Error: Directory does not exist:", args.libcc_source_path + sys.exit(0) + elif (not os.path.isdir(args.libcc_shared_library_path)): + print "Error: Directory does not exist:", args.libcc_shared_library_path + sys.exit(0) + elif (not os.path.isdir(args.libcc_static_library_path)): + print "Error: Directory does not exist:", args.libcc_static_library_path + sys.exit(0) + elif (args.libcc_source_path != None or + args.libcc_shared_library_path != None or + args.libcc_static_library_path != None): + print "Error: All options of libchromiumcontent are required OR let electron choose it" + sys.exit(0) if not args.yes and PLATFORM != 'win32': check_root() if args.verbose: @@ -39,7 +56,10 @@ def main(): update_submodules() setup_python_libs() update_node_modules('.') - bootstrap_brightray(args.dev, args.url, args.target_arch) + bootstrap_brightray(args.dev, args.url, args.target_arch, + args.libcc_source_path, + args.libcc_shared_library_path, + args.libcc_static_library_path) if args.target_arch in ['arm', 'ia32'] and PLATFORM == 'linux': download_sysroot(args.target_arch) @@ -69,6 +89,12 @@ def parse_args(): 'prompts.') parser.add_argument('--target_arch', default=get_target_arch(), help='Manually specify the arch to build for') + parser.add_argument('--libcc_source_path', required=False, + help='The source path of libchromiumcontent. NOTE: All options of libchromiumcontent are required OR let electron choose it') + parser.add_argument('--libcc_shared_library_path', required=False, + help='The shared library path of libchromiumcontent. NOTE: All options of libchromiumcontent are required OR let electron choose it') + parser.add_argument('--libcc_static_library_path', required=False, + help='The static library path of libchromiumcontent. NOTE: All options of libchromiumcontent are required OR let electron choose it') return parser.parse_args() @@ -91,15 +117,23 @@ def setup_python_libs(): execute_stdout([sys.executable, 'setup.py', 'build']) -def bootstrap_brightray(is_dev, url, target_arch): +def bootstrap_brightray(is_dev, url, target_arch, libcc_source_path, + libcc_shared_library_path, + libcc_static_library_path): bootstrap = os.path.join(VENDOR_DIR, 'brightray', 'script', 'bootstrap') args = [ '--commit', LIBCHROMIUMCONTENT_COMMIT, '--target_arch', target_arch, - url, + url ] if is_dev: args = ['--dev'] + args + if (libcc_source_path != None and + libcc_shared_library_path != None and + libcc_static_library_path != None): + args = args + ['--libcc_source_path', libcc_source_path, + '--libcc_shared_library_path', libcc_shared_library_path, + '--libcc_static_library_path', libcc_static_library_path] execute_stdout([sys.executable, bootstrap] + args) From ae2b004db747aec9edcd8a911991428867eee059 Mon Sep 17 00:00:00 2001 From: tejaspathak Date: Sun, 8 Nov 2015 17:41:16 +0900 Subject: [PATCH 081/249] Fix pylint errors --- script/bootstrap.py | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/script/bootstrap.py b/script/bootstrap.py index 81da2810eccb..c9a3b32ed49c 100755 --- a/script/bootstrap.py +++ b/script/bootstrap.py @@ -41,7 +41,8 @@ def main(): elif (args.libcc_source_path != None or args.libcc_shared_library_path != None or args.libcc_static_library_path != None): - print "Error: All options of libchromiumcontent are required OR let electron choose it" + print "Error: All options of libchromiumcontent are required OR let " \ + "electron choose it" sys.exit(0) if not args.yes and PLATFORM != 'win32': check_root() @@ -90,11 +91,17 @@ def parse_args(): parser.add_argument('--target_arch', default=get_target_arch(), help='Manually specify the arch to build for') parser.add_argument('--libcc_source_path', required=False, - help='The source path of libchromiumcontent. NOTE: All options of libchromiumcontent are required OR let electron choose it') + help='The source path of libchromiumcontent. ' \ + 'NOTE: All options of libchromiumcontent are ' + 'required OR let electron choose it') parser.add_argument('--libcc_shared_library_path', required=False, - help='The shared library path of libchromiumcontent. NOTE: All options of libchromiumcontent are required OR let electron choose it') + help='The shared library path of libchromiumcontent. ' \ + 'NOTE: All options of libchromiumcontent are ' \ + 'required OR let electron choose it') parser.add_argument('--libcc_static_library_path', required=False, - help='The static library path of libchromiumcontent. NOTE: All options of libchromiumcontent are required OR let electron choose it') + help='The static library path of libchromiumcontent. ' \ + 'NOTE: All options of libchromiumcontent are ' \ + 'required OR let electron choose it') return parser.parse_args() From 429723c8a9a913907295759063de4bacb62331ef Mon Sep 17 00:00:00 2001 From: Plusb Preco Date: Mon, 9 Nov 2015 07:48:40 +0900 Subject: [PATCH 082/249] Update as upstream --- docs-translations/ko-KR/api/app.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/docs-translations/ko-KR/api/app.md b/docs-translations/ko-KR/api/app.md index 26235fbe444b..f5e8e8d96b96 100644 --- a/docs-translations/ko-KR/api/app.md +++ b/docs-translations/ko-KR/api/app.md @@ -206,6 +206,14 @@ GPU가 작동하던 중 크래시가 일어났을 때 발생하는 이벤트입 이 함수는 모든 `beforeunload`와 `unload` 이벤트 핸들러가 제대로 실행됨을 보장합니다. `beforeunload` 이벤트 핸들러에서 `false`를 반환했을 때 윈도우창 종료가 취소 될 수 있습니다. +### `app.exit(exitCode)` + +* `exitCode` Integer + +`exitCode`와 함께 어플리케이션을 즉시 종료합니다. + +모든 윈도우창은 사용자의 동의 여부에 상관없이 즉시 종료되며 `before-quit` 이벤트와 `will-quit` 이벤트가 발생하지 않습니다. + ### `app.getAppPath()` 현재 어플리케이션의 디렉터리를 반환합니다. From 5e3b8d51e490bcd3468fac71779e4ac3be484c24 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Mon, 9 Nov 2015 11:42:37 +0800 Subject: [PATCH 083/249] docs: Fix typo --- docs/tutorial/mac-app-store-submission-guide.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/tutorial/mac-app-store-submission-guide.md b/docs/tutorial/mac-app-store-submission-guide.md index 113185918803..4dc6f900a167 100644 --- a/docs/tutorial/mac-app-store-submission-guide.md +++ b/docs/tutorial/mac-app-store-submission-guide.md @@ -77,10 +77,10 @@ codesign --deep -fs "$APP_KEY" --entitlements child.plist "$FRAMEWORKS_PATH/$APP codesign --deep -fs "$APP_KEY" --entitlements child.plist "$FRAMEWORKS_PATH/$APP Helper EH.app/" codesign --deep -fs "$APP_KEY" --entitlements child.plist "$FRAMEWORKS_PATH/$APP Helper NP.app/" codesign -fs "$APP_KEY" --entitlements parent.plist "$APP_PATH" -productbuild --component "$APP_PATH" /Applications --sign "$INSTALLER_KEY" "$APP_PATH" +productbuild --component "$APP_PATH" /Applications --sign "$INSTALLER_KEY" "$RESULT_PATH" ``` -If you are new to app sandboxing under OS X, you should also read through +If you are new to app sandboxing under OS X, you should also read through Apple's [Enabling App Sandbox][enable-app-sandbox] to have a basic idea, then add keys for the permissions needed by your app to the entitlements files. From 13b917dd953dc7ac7ce6b9751c6c0ac68bfa88eb Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Mon, 9 Nov 2015 16:38:51 +0800 Subject: [PATCH 084/249] Update brightray for atom/electron#3310 --- vendor/brightray | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vendor/brightray b/vendor/brightray index 98b3eb04d85a..3773af58a204 160000 --- a/vendor/brightray +++ b/vendor/brightray @@ -1 +1 @@ -Subproject commit 98b3eb04d85a8a70b8d9f29477437061c2e77a83 +Subproject commit 3773af58a204c5899cc811d58f831466549277bf From a23ffd7a1bb815a1120c37e162705734bb4f827b Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Mon, 9 Nov 2015 18:24:32 +0800 Subject: [PATCH 085/249] Rely on "download" script for argument verification --- script/bootstrap.py | 41 +++++++++-------------------------------- vendor/brightray | 2 +- 2 files changed, 10 insertions(+), 33 deletions(-) diff --git a/script/bootstrap.py b/script/bootstrap.py index c9a3b32ed49c..ef48c1f8023f 100755 --- a/script/bootstrap.py +++ b/script/bootstrap.py @@ -26,24 +26,6 @@ def main(): os.chdir(SOURCE_ROOT) args = parse_args() - if (args.libcc_source_path != None and - args.libcc_shared_library_path != None and - args.libcc_static_library_path != None): - if (not os.path.isdir(args.libcc_source_path)): - print "Error: Directory does not exist:", args.libcc_source_path - sys.exit(0) - elif (not os.path.isdir(args.libcc_shared_library_path)): - print "Error: Directory does not exist:", args.libcc_shared_library_path - sys.exit(0) - elif (not os.path.isdir(args.libcc_static_library_path)): - print "Error: Directory does not exist:", args.libcc_static_library_path - sys.exit(0) - elif (args.libcc_source_path != None or - args.libcc_shared_library_path != None or - args.libcc_static_library_path != None): - print "Error: All options of libchromiumcontent are required OR let " \ - "electron choose it" - sys.exit(0) if not args.yes and PLATFORM != 'win32': check_root() if args.verbose: @@ -58,8 +40,7 @@ def main(): setup_python_libs() update_node_modules('.') bootstrap_brightray(args.dev, args.url, args.target_arch, - args.libcc_source_path, - args.libcc_shared_library_path, + args.libcc_source_path, args.libcc_shared_library_path, args.libcc_static_library_path) if args.target_arch in ['arm', 'ia32'] and PLATFORM == 'linux': @@ -91,17 +72,13 @@ def parse_args(): parser.add_argument('--target_arch', default=get_target_arch(), help='Manually specify the arch to build for') parser.add_argument('--libcc_source_path', required=False, - help='The source path of libchromiumcontent. ' \ - 'NOTE: All options of libchromiumcontent are ' - 'required OR let electron choose it') + help='The source path of libchromiumcontent. ' \ + 'NOTE: All options of libchromiumcontent are ' \ + 'required OR let electron choose it') parser.add_argument('--libcc_shared_library_path', required=False, - help='The shared library path of libchromiumcontent. ' \ - 'NOTE: All options of libchromiumcontent are ' \ - 'required OR let electron choose it') + help='The shared library path of libchromiumcontent.') parser.add_argument('--libcc_static_library_path', required=False, - help='The static library path of libchromiumcontent. ' \ - 'NOTE: All options of libchromiumcontent are ' \ - 'required OR let electron choose it') + help='The static library path of libchromiumcontent.') return parser.parse_args() @@ -138,9 +115,9 @@ def bootstrap_brightray(is_dev, url, target_arch, libcc_source_path, if (libcc_source_path != None and libcc_shared_library_path != None and libcc_static_library_path != None): - args = args + ['--libcc_source_path', libcc_source_path, - '--libcc_shared_library_path', libcc_shared_library_path, - '--libcc_static_library_path', libcc_static_library_path] + args += ['--libcc_source_path', libcc_source_path, + '--libcc_shared_library_path', libcc_shared_library_path, + '--libcc_static_library_path', libcc_static_library_path] execute_stdout([sys.executable, bootstrap] + args) diff --git a/vendor/brightray b/vendor/brightray index 3773af58a204..80543fe2b0fc 160000 --- a/vendor/brightray +++ b/vendor/brightray @@ -1 +1 @@ -Subproject commit 3773af58a204c5899cc811d58f831466549277bf +Subproject commit 80543fe2b0fc04b5096b1ba7ebb9553431d8dfc0 From 89ff62b1b566c58c0854e4d254475c434da87998 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Mon, 9 Nov 2015 18:09:22 +0800 Subject: [PATCH 086/249] Add "deprecate" module --- atom/common/api/lib/deprecate.coffee | 62 ++++++++++++++++++++++++++++ filenames.gypi | 1 + 2 files changed, 63 insertions(+) create mode 100644 atom/common/api/lib/deprecate.coffee diff --git a/atom/common/api/lib/deprecate.coffee b/atom/common/api/lib/deprecate.coffee new file mode 100644 index 000000000000..070a9feb6aab --- /dev/null +++ b/atom/common/api/lib/deprecate.coffee @@ -0,0 +1,62 @@ +# Deprecate a method. +deprecate = (oldName, newName, fn) -> + warned = false + -> + unless warned or process.noDeprecation + warned = true + deprecate.warn oldName, newName + fn.apply this, arguments + +# The method is renamed. +deprecate.rename = (object, oldName, newName) -> + warned = false + newMethod = -> + unless warned or process.noDeprecation + warned = true + deprecate.warn oldName, newName + this[newName].apply this, arguments + if typeof object is 'function' + object.prototype[oldName] = newMethod + else + object[oldName] = newMethod + +# Forward the method to member. +deprecate.member = (object, method, member) -> + warned = false + object.prototype[method] = -> + unless warned or process.noDeprecation + warned = true + deprecate.warn method, "#{member}.#{method}" + this[member][method].apply this[member], arguments + +# Deprecate a property. +deprecate.property = (object, property, method) -> + Object.defineProperty object, property, + get: -> + warned = false + unless warned or process.noDeprecation + warned = true + deprecate.warn "#{property} property", "#{method} method" + this[method]() + +# Deprecate an event. +deprecate.event = (emitter, oldName, newName, fn) -> + warned = false + emitter.on newName, -> + if @listenerCount(oldName) > 0 # there is listeners for old API. + unless warned or process.noDeprecation + warned = true + deprecate.warn "'#{oldName}' event", "'#{newName}' event" + fn.apply this, arguments + +# Print deprecate warning. +deprecate.warn = (oldName, newName) -> + message = "#{oldName} is deprecated. Use #{newName} instead." + if process.throwDeprecation + throw new Error(message) + else if process.traceDeprecation + console.trace message + else + console.warn "(electron) #{message}" + +module.exports = deprecate diff --git a/filenames.gypi b/filenames.gypi index 0e70347309c0..b39362bd1cd4 100644 --- a/filenames.gypi +++ b/filenames.gypi @@ -37,6 +37,7 @@ 'atom/common/api/lib/callbacks-registry.coffee', 'atom/common/api/lib/clipboard.coffee', 'atom/common/api/lib/crash-reporter.coffee', + 'atom/common/api/lib/deprecate.coffee', 'atom/common/api/lib/native-image.coffee', 'atom/common/api/lib/shell.coffee', 'atom/common/lib/init.coffee', From f0bd28ca8d3e362abcc600447784afb0ed0c22b1 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Mon, 9 Nov 2015 19:07:55 +0800 Subject: [PATCH 087/249] Do not turn off deprecation notice by default It is v4 now, people should be punished if they are still using deprecated Node.js APIs. --- atom/common/api/atom_bindings.cc | 3 --- 1 file changed, 3 deletions(-) diff --git a/atom/common/api/atom_bindings.cc b/atom/common/api/atom_bindings.cc index 60052a7216d0..a000f6fc743a 100644 --- a/atom/common/api/atom_bindings.cc +++ b/atom/common/api/atom_bindings.cc @@ -69,9 +69,6 @@ void AtomBindings::BindTo(v8::Isolate* isolate, dict.SetMethod("activateUvLoop", base::Bind(&AtomBindings::ActivateUVLoop, base::Unretained(this))); - // Do not warn about deprecated APIs. - dict.Set("noDeprecation", true); - #if defined(MAS_BUILD) dict.Set("mas", true); #endif From 91c4ed26fc9e0ed2792abd2bf594dd0d2e4bb336 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Mon, 9 Nov 2015 21:18:57 +0800 Subject: [PATCH 088/249] Print warnings for deprecated APIs --- atom/browser/api/lib/app.coffee | 50 +++++++++++++--------- atom/browser/api/lib/atom-delegate.coffee | 6 --- atom/browser/api/lib/browser-window.coffee | 41 +++++++++--------- atom/browser/lib/chrome-extension.coffee | 2 +- atom/renderer/api/lib/ipc.coffee | 6 ++- filenames.gypi | 1 - 6 files changed, 55 insertions(+), 51 deletions(-) delete mode 100644 atom/browser/api/lib/atom-delegate.coffee diff --git a/atom/browser/api/lib/app.coffee b/atom/browser/api/lib/app.coffee index 4df7aef10bdf..b5025a3a4fee 100644 --- a/atom/browser/api/lib/app.coffee +++ b/atom/browser/api/lib/app.coffee @@ -1,3 +1,4 @@ +deprecate = require 'deprecate' EventEmitter = require('events').EventEmitter bindings = process.atomBinding 'app' @@ -7,19 +8,6 @@ downloadItemBindings = process.atomBinding 'download_item' app = bindings.app app.__proto__ = EventEmitter.prototype -wrapSession = (session) -> - # session is an Event Emitter. - session.__proto__ = EventEmitter.prototype - -wrapDownloadItem = (downloadItem) -> - # downloadItem is an Event Emitter. - downloadItem.__proto__ = EventEmitter.prototype - # Be compatible with old APIs. - downloadItem.url = downloadItem.getUrl() - downloadItem.filename = downloadItem.getFilename() - downloadItem.mimeType = downloadItem.getMimeType() - downloadItem.hasUserGesture = downloadItem.hasUserGesture() - app.setApplicationMenu = (menu) -> require('menu').setApplicationMenu menu @@ -47,17 +35,37 @@ app.setAppPath = (path) -> app.getAppPath = -> appPath -# Be compatible with old API. -app.once 'ready', -> @emit 'finish-launching' -app.terminate = app.quit -app.getHomeDir = -> @getPath 'home' -app.getDataPath = -> @getPath 'userData' -app.setDataPath = (path) -> @setPath 'userData', path -app.resolveProxy = -> @defaultSession.resolveProxy.apply @defaultSession, arguments -app.on 'activate', (event, hasVisibleWindows) -> @emit 'activate-with-no-open-windows' if not hasVisibleWindows +# Helpers. +app.resolveProxy = (url, callback) -> @defaultSession.resolveProxy url, callback + +# Deprecated. +app.getHomeDir = deprecate 'app.getHomeDir', 'app.getPath', -> + @getPath 'home' +app.getDataPath = deprecate 'app.getDataPath', 'app.getPath', -> + @getPath 'userData' +app.setDataPath = deprecate 'app.setDataPath', 'app.setPath', (path) -> + @setPath 'userData', path +deprecate.rename app, 'terminate', 'quit' +deprecate.event app, 'finish-launching', 'ready', -> + setImmediate => # give default app a chance to setup default menu. + @emit 'finish-launching' +deprecate.event app, 'activate-with-no-open-windows', 'activate', (event, hasVisibleWindows) -> + @emit 'activate-with-no-open-windows' if not hasVisibleWindows # Wrappers for native classes. +wrapSession = (session) -> + # session is an EventEmitter. + session.__proto__ = EventEmitter.prototype sessionBindings._setWrapSession wrapSession + +wrapDownloadItem = (downloadItem) -> + # downloadItem is an EventEmitter. + downloadItem.__proto__ = EventEmitter.prototype + # Deprecated. + deprecate.property downloadItem, 'url', 'getUrl' + deprecate.property downloadItem, 'filename', 'getFilename' + deprecate.property downloadItem, 'mimeType', 'getMimeType' + deprecate.property downloadItem, 'hasUserGesture', 'hasUserGesture' downloadItemBindings._setWrapDownloadItem wrapDownloadItem # Only one App object pemitted. diff --git a/atom/browser/api/lib/atom-delegate.coffee b/atom/browser/api/lib/atom-delegate.coffee deleted file mode 100644 index 2e1e6334470b..000000000000 --- a/atom/browser/api/lib/atom-delegate.coffee +++ /dev/null @@ -1,6 +0,0 @@ -module.exports = - browserMainParts: - preMainMessageLoopRun: -> - -setImmediate -> - module.exports.browserMainParts.preMainMessageLoopRun() diff --git a/atom/browser/api/lib/browser-window.coffee b/atom/browser/api/lib/browser-window.coffee index 6ffba50d34cb..d8ac221c62e0 100644 --- a/atom/browser/api/lib/browser-window.coffee +++ b/atom/browser/api/lib/browser-window.coffee @@ -1,6 +1,7 @@ EventEmitter = require('events').EventEmitter app = require 'app' ipc = require 'ipc' +deprecate = require 'deprecate' BrowserWindow = process.atomBinding('window').BrowserWindow BrowserWindow::__proto__ = EventEmitter.prototype @@ -71,32 +72,32 @@ BrowserWindow.fromDevToolsWebContents = (webContents) -> # Helpers. BrowserWindow::loadUrl = -> @webContents.loadUrl.apply @webContents, arguments -BrowserWindow::send = -> @webContents.send.apply @webContents, arguments - -# Be compatible with old API. -BrowserWindow::undo = -> @webContents.undo() -BrowserWindow::redo = -> @webContents.redo() -BrowserWindow::cut = -> @webContents.cut() -BrowserWindow::copy = -> @webContents.copy() -BrowserWindow::paste = -> @webContents.paste() -BrowserWindow::selectAll = -> @webContents.selectAll() -BrowserWindow::restart = -> @webContents.reload() -BrowserWindow::getUrl = -> @webContents.getUrl() BrowserWindow::reload = -> @webContents.reload.apply @webContents, arguments -BrowserWindow::reloadIgnoringCache = -> @webContents.reloadIgnoringCache.apply @webContents, arguments -BrowserWindow::getPageTitle = -> @webContents.getTitle() -BrowserWindow::isLoading = -> @webContents.isLoading() -BrowserWindow::isWaitingForResponse = -> @webContents.isWaitingForResponse() -BrowserWindow::stop = -> @webContents.stop() -BrowserWindow::isCrashed = -> @webContents.isCrashed() -BrowserWindow::executeJavaScriptInDevTools = (code) -> @devToolsWebContents?.executeJavaScript code +BrowserWindow::send = -> @webContents.send.apply @webContents, arguments BrowserWindow::openDevTools = -> @webContents.openDevTools.apply @webContents, arguments BrowserWindow::closeDevTools = -> @webContents.closeDevTools() BrowserWindow::isDevToolsOpened = -> @webContents.isDevToolsOpened() BrowserWindow::toggleDevTools = -> @webContents.toggleDevTools() BrowserWindow::inspectElement = -> @webContents.inspectElement.apply @webContents, arguments BrowserWindow::inspectServiceWorker = -> @webContents.inspectServiceWorker() -BrowserWindow::print = -> @webContents.print.apply @webContents, arguments -BrowserWindow::printToPDF = -> @webContents.printToPDF.apply @webContents, arguments + +# Deprecated. +deprecate.rename BrowserWindow, 'restart', 'reload' +deprecate.member BrowserWindow, 'undo', 'webContents' +deprecate.member BrowserWindow, 'redo', 'webContents' +deprecate.member BrowserWindow, 'cut', 'webContents' +deprecate.member BrowserWindow, 'copy', 'webContents' +deprecate.member BrowserWindow, 'paste', 'webContents' +deprecate.member BrowserWindow, 'selectAll', 'webContents' +deprecate.member BrowserWindow, 'getUrl', 'webContents' +deprecate.member BrowserWindow, 'reloadIgnoringCache', 'webContents' +deprecate.member BrowserWindow, 'getPageTitle', 'webContents' +deprecate.member BrowserWindow, 'isLoading', 'webContents' +deprecate.member BrowserWindow, 'isWaitingForResponse', 'webContents' +deprecate.member BrowserWindow, 'stop', 'webContents' +deprecate.member BrowserWindow, 'isCrashed', 'webContents' +deprecate.member BrowserWindow, 'executeJavaScriptInDevTools', 'webContents' +deprecate.member BrowserWindow, 'print', 'webContents' +deprecate.member BrowserWindow, 'printToPDF', 'webContents' module.exports = BrowserWindow diff --git a/atom/browser/lib/chrome-extension.coffee b/atom/browser/lib/chrome-extension.coffee index 15f7bfd54c56..8d313ad0cb51 100644 --- a/atom/browser/lib/chrome-extension.coffee +++ b/atom/browser/lib/chrome-extension.coffee @@ -55,7 +55,7 @@ app.once 'ready', -> BrowserWindow = require 'browser-window' # Load persistented extensions. - loadedExtensionsPath = path.join app.getDataPath(), 'DevTools Extensions' + loadedExtensionsPath = path.join app.getPath('userData'), 'DevTools Extensions' try loadedExtensions = JSON.parse fs.readFileSync(loadedExtensionsPath) diff --git a/atom/renderer/api/lib/ipc.coffee b/atom/renderer/api/lib/ipc.coffee index 1c508a3a5493..01eeb4b6da14 100644 --- a/atom/renderer/api/lib/ipc.coffee +++ b/atom/renderer/api/lib/ipc.coffee @@ -1,3 +1,5 @@ +deprecate = require 'deprecate' + binding = process.atomBinding 'ipc' v8Util = process.atomBinding 'v8_util' @@ -14,7 +16,7 @@ ipc.sendToHost = (args...) -> binding.send 'ipc-message-host', [args...] # Deprecated. -ipc.sendChannel = ipc.send -ipc.sendChannelSync = ipc.sendSync +deprecate.rename ipc, 'sendChannel', 'send' +deprecate.rename ipc, 'sendChannelSync', 'sendSync' module.exports = ipc diff --git a/filenames.gypi b/filenames.gypi index b39362bd1cd4..fe05c34c3422 100644 --- a/filenames.gypi +++ b/filenames.gypi @@ -9,7 +9,6 @@ ], 'coffee_sources': [ 'atom/browser/api/lib/app.coffee', - 'atom/browser/api/lib/atom-delegate.coffee', 'atom/browser/api/lib/auto-updater.coffee', 'atom/browser/api/lib/auto-updater/auto-updater-mac.coffee', 'atom/browser/api/lib/auto-updater/auto-updater-win.coffee', From 5d1f7ed029d638319a6c3d31c7a916107dcfab3e Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Mon, 9 Nov 2015 22:56:12 +0800 Subject: [PATCH 089/249] Update brightray for atom/brightray#161 --- vendor/brightray | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vendor/brightray b/vendor/brightray index 80543fe2b0fc..7c9915847e84 160000 --- a/vendor/brightray +++ b/vendor/brightray @@ -1 +1 @@ -Subproject commit 80543fe2b0fc04b5096b1ba7ebb9553431d8dfc0 +Subproject commit 7c9915847e84076b5444ee945e6dc2904fb345d1 From 828d911ed195f31450d77b0b585baa1a1d4f708b Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Tue, 10 Nov 2015 15:12:07 +0800 Subject: [PATCH 090/249] Deprecate ipc module for ipcRenderer --- atom/renderer/api/lib/ipc-renderer.coffee | 16 +++++++++++++++ atom/renderer/api/lib/ipc.coffee | 24 ++++++++++------------ atom/renderer/atom_render_view_observer.cc | 5 ++++- filenames.gypi | 1 + 4 files changed, 32 insertions(+), 14 deletions(-) create mode 100644 atom/renderer/api/lib/ipc-renderer.coffee diff --git a/atom/renderer/api/lib/ipc-renderer.coffee b/atom/renderer/api/lib/ipc-renderer.coffee new file mode 100644 index 000000000000..29004d212b56 --- /dev/null +++ b/atom/renderer/api/lib/ipc-renderer.coffee @@ -0,0 +1,16 @@ +binding = process.atomBinding 'ipc' +v8Util = process.atomBinding 'v8_util' + +# Created by init.coffee. +ipcRenderer = v8Util.getHiddenValue global, 'ipc' + +ipcRenderer.send = (args...) -> + binding.send 'ipc-message', [args...] + +ipcRenderer.sendSync = (args...) -> + JSON.parse binding.sendSync('ipc-message-sync', [args...]) + +ipcRenderer.sendToHost = (args...) -> + binding.send 'ipc-message-host', [args...] + +module.exports = ipcRenderer diff --git a/atom/renderer/api/lib/ipc.coffee b/atom/renderer/api/lib/ipc.coffee index 01eeb4b6da14..e2fcdcd86e8a 100644 --- a/atom/renderer/api/lib/ipc.coffee +++ b/atom/renderer/api/lib/ipc.coffee @@ -1,21 +1,19 @@ deprecate = require 'deprecate' +ipcRenderer = require 'ipc-renderer' +{EventEmitter} = require 'events' -binding = process.atomBinding 'ipc' -v8Util = process.atomBinding 'v8_util' +# This module is deprecated, we mirror everything from ipcRenderer. +deprecate.warn 'ipc module', 'ipcRenderer module' -# Created by init.coffee. -ipc = v8Util.getHiddenValue global, 'ipc' - -ipc.send = (args...) -> - binding.send 'ipc-message', [args...] - -ipc.sendSync = (args...) -> - JSON.parse binding.sendSync('ipc-message-sync', [args...]) - -ipc.sendToHost = (args...) -> - binding.send 'ipc-message-host', [args...] +# Routes events of ipcRenderer. +ipc = new EventEmitter +ipcRenderer.emit = (channel, event, args...) -> + ipc.emit channel, args... + EventEmitter::emit.apply ipcRenderer, arguments # Deprecated. +for method of ipcRenderer when method.startsWith 'send' + ipc[method] = ipcRenderer[method] deprecate.rename ipc, 'sendChannel', 'send' deprecate.rename ipc, 'sendChannelSync', 'sendSync' diff --git a/atom/renderer/atom_render_view_observer.cc b/atom/renderer/atom_render_view_observer.cc index 456ca5ba4b24..ecd9401420f8 100644 --- a/atom/renderer/atom_render_view_observer.cc +++ b/atom/renderer/atom_render_view_observer.cc @@ -142,7 +142,10 @@ void AtomRenderViewObserver::OnBrowserMessage(const base::string16& channel, v8::Local ipc; if (GetIPCObject(isolate, context, &ipc)) { - mate::EmitEvent(isolate, ipc, channel, ListValueToVector(isolate, args)); + auto args_vector = ListValueToVector(isolate, args); + // Insert a dummy Event object. + args_vector.insert(args_vector.begin(), v8::Object::New(isolate)); + mate::EmitEvent(isolate, ipc, channel, args_vector); } } diff --git a/filenames.gypi b/filenames.gypi index fe05c34c3422..93cb4f3e07aa 100644 --- a/filenames.gypi +++ b/filenames.gypi @@ -50,6 +50,7 @@ 'atom/renderer/lib/web-view/web-view-attributes.coffee', 'atom/renderer/lib/web-view/web-view-constants.coffee', 'atom/renderer/api/lib/ipc.coffee', + 'atom/renderer/api/lib/ipc-renderer.coffee', 'atom/renderer/api/lib/remote.coffee', 'atom/renderer/api/lib/screen.coffee', 'atom/renderer/api/lib/web-frame.coffee', From 765cfb10941dd3b04566b01ce71eb78e730fd742 Mon Sep 17 00:00:00 2001 From: Felix Rieseberg Date: Tue, 10 Nov 2015 08:28:14 +0100 Subject: [PATCH 091/249] Document Notifications --- .../desktop-environment-integration.md | 39 +++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/docs/tutorial/desktop-environment-integration.md b/docs/tutorial/desktop-environment-integration.md index 78067f3d8a12..08758d67933f 100644 --- a/docs/tutorial/desktop-environment-integration.md +++ b/docs/tutorial/desktop-environment-integration.md @@ -8,6 +8,44 @@ applications can put a custom menu in the dock menu. This guide explains how to integrate your application into those desktop environments with Electron APIs. +## Notifications (Windows, Linux, OS X) +All three operating systems provide means for applications to send notifications to the user. Electron conveniently allows developers to send notifications using the [JavaScript Notification API](https://notifications.spec.whatwg.org/), using the currently running operating system's native notification APIs to display it. + +```javascript +var myNotificiation = new Notification('Title', { + body: 'Lorem Ipsum Dolor Sit Amet' +}); + +myNotification.onclick = function () { + console.log('Notification clicked') +} +``` +While code and user experience across operating systems are similar, but there are fine differences. + +#### Windows + * On Windows 10, notifications "just work". + * On Windows 8.1 and Windows 8, a shortcut to your app, with a [System.AppUserModel.ID](https://msdn.microsoft.com/en-us/library/windows/desktop/dd391569(v=vs.85).aspx), must be installed to the Start screen. Note, however, that it does not need to be pinned to the Start screen. + * On Windows 7 and below, notifications are not supported. You can however send "balloon notifications" using the [Tray API](trayballoon). + +To use an image in your notification, pass a local image file (preferably `png`) in the `icon` property of your notification's options. The notification will still display if you submit and incorrect or `http/https`-based URL, but the image will not be displayed. + +``` +new Notification('Title', { + body: 'Notification with icon', + icon: 'file:///C:/Users/feriese/Desktop/icon.png' +}); +``` + +Keep furthermore in mind that the maximum length for the body is 250 characters, with the Windows team recommending that notifications should be kept to 200 characters. + +#### Linux +Notifications are sent using Ubuntu's Unity (and will obviously not be displayed if Unity is not running). For more information about Unity's on screen notifications, [check out the project page](https://unity.ubuntu.com/projects/notifyosd/). + +#### OS X +Notifications are straight-forward on OS X, you should however be aware of [Apple's Human Interface guidelines regarding notifications](https://developer.apple.com/library/mac/documentation/UserExperience/Conceptual/OSXHIGuidelines/NotificationCenter.html). + +Note that notifications are limited to 256 bytes in size - and will be truncated if you exceed that limit. + ## Recent documents (Windows & OS X) Windows and OS X provide easy access to a list of recent documents opened by @@ -252,3 +290,4 @@ window.setDocumentEdited(true); [app-registration]: http://msdn.microsoft.com/en-us/library/windows/desktop/ee872121(v=vs.85).aspx [unity-launcher]: https://help.ubuntu.com/community/UnityLaunchersAndDesktopFiles#Adding_shortcuts_to_a_launcher [setthumbarbuttons]: ../api/browser-window.md#browserwindowsetthumbarbuttonsbuttons +[trayballoon]: ../api/tray.md#traydisplayballoonoptions-windows \ No newline at end of file From 6515a445a0175102ab4e34be66723b9cd9cf6fd8 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Tue, 10 Nov 2015 15:29:43 +0800 Subject: [PATCH 092/249] Use ipcRenderer in Electron's code --- atom/renderer/api/lib/remote.coffee | 6 +++--- atom/renderer/lib/override.coffee | 6 +++--- atom/renderer/lib/web-view/guest-view-internal.coffee | 10 +++++----- atom/renderer/lib/web-view/web-view.coffee | 2 +- spec/api-ipc-spec.coffee | 4 ++-- spec/api-session-spec.coffee | 8 +++----- spec/fixtures/api/localstorage.html | 2 +- spec/fixtures/api/preload.html | 2 +- spec/fixtures/api/send-sync-message.html | 2 +- spec/fixtures/module/preload-ipc.js | 4 ++-- spec/fixtures/module/send-later.js | 2 +- spec/fixtures/pages/basic-auth.html | 2 +- spec/fixtures/pages/beforeunload-false.html | 2 +- spec/fixtures/pages/document-hidden.html | 2 +- spec/fixtures/pages/history.html | 2 +- spec/fixtures/pages/ipc-message.html | 2 +- spec/fixtures/pages/onkeyup.html | 2 +- spec/fixtures/pages/onmouseup.html | 2 +- spec/fixtures/pages/window-opener.html | 2 +- spec/static/index.html | 2 +- 20 files changed, 32 insertions(+), 34 deletions(-) diff --git a/atom/renderer/api/lib/remote.coffee b/atom/renderer/api/lib/remote.coffee index 2de14d541527..5d5905ba24a6 100644 --- a/atom/renderer/api/lib/remote.coffee +++ b/atom/renderer/api/lib/remote.coffee @@ -1,4 +1,4 @@ -ipc = require 'ipc' +ipc = require 'ipc-renderer' v8Util = process.atomBinding 'v8_util' CallbacksRegistry = require 'callbacks-registry' @@ -119,11 +119,11 @@ metaToPlainObject = (meta) -> obj # Browser calls a callback in renderer. -ipc.on 'ATOM_RENDERER_CALLBACK', (id, args) -> +ipc.on 'ATOM_RENDERER_CALLBACK', (event, id, args) -> callbacksRegistry.apply id, metaToValue(args) # A callback in browser is released. -ipc.on 'ATOM_RENDERER_RELEASE_CALLBACK', (id) -> +ipc.on 'ATOM_RENDERER_RELEASE_CALLBACK', (event, id) -> callbacksRegistry.remove id # Get remote module. diff --git a/atom/renderer/lib/override.coffee b/atom/renderer/lib/override.coffee index 93cf8b8357e8..e54a0e9685c2 100644 --- a/atom/renderer/lib/override.coffee +++ b/atom/renderer/lib/override.coffee @@ -1,4 +1,4 @@ -ipc = require 'ipc' +ipc = require 'ipc-renderer' remote = require 'remote' # Helper function to resolve relative url. @@ -11,7 +11,7 @@ resolveUrl = (url) -> class BrowserWindowProxy constructor: (@guestId) -> @closed = false - ipc.on 'ATOM_SHELL_GUEST_WINDOW_MANAGER_WINDOW_CLOSED', (guestId) => + ipc.on 'ATOM_SHELL_GUEST_WINDOW_MANAGER_WINDOW_CLOSED', (event, guestId) => if guestId is @guestId @closed = true @@ -99,7 +99,7 @@ if guestId? postMessage: (message, targetOrigin='*') -> ipc.send 'ATOM_SHELL_GUEST_WINDOW_MANAGER_WINDOW_OPENER_POSTMESSAGE', guestId, message, targetOrigin, location.origin -ipc.on 'ATOM_SHELL_GUEST_WINDOW_POSTMESSAGE', (guestId, message, sourceOrigin) -> +ipc.on 'ATOM_SHELL_GUEST_WINDOW_POSTMESSAGE', (event, guestId, message, sourceOrigin) -> # Manually dispatch event instead of using postMessage because we also need to # set event.source. event = document.createEvent 'Event' diff --git a/atom/renderer/lib/web-view/guest-view-internal.coffee b/atom/renderer/lib/web-view/guest-view-internal.coffee index 2852d1122874..37dc25f9ee04 100644 --- a/atom/renderer/lib/web-view/guest-view-internal.coffee +++ b/atom/renderer/lib/web-view/guest-view-internal.coffee @@ -1,4 +1,4 @@ -ipc = require 'ipc' +ipc = require 'ipc-renderer' webFrame = require 'web-frame' requestId = 0 @@ -37,16 +37,16 @@ dispatchEvent = (webView, event, args...) -> module.exports = registerEvents: (webView, viewInstanceId) -> - ipc.on "ATOM_SHELL_GUEST_VIEW_INTERNAL_DISPATCH_EVENT-#{viewInstanceId}", (event, args...) -> - dispatchEvent webView, event, args... + ipc.on "ATOM_SHELL_GUEST_VIEW_INTERNAL_DISPATCH_EVENT-#{viewInstanceId}", (event, domEvent, args...) -> + dispatchEvent webView, domEvent, args... - ipc.on "ATOM_SHELL_GUEST_VIEW_INTERNAL_IPC_MESSAGE-#{viewInstanceId}", (channel, args...) -> + ipc.on "ATOM_SHELL_GUEST_VIEW_INTERNAL_IPC_MESSAGE-#{viewInstanceId}", (event, channel, args...) -> domEvent = new Event('ipc-message') domEvent.channel = channel domEvent.args = [args...] webView.dispatchEvent domEvent - ipc.on "ATOM_SHELL_GUEST_VIEW_INTERNAL_SIZE_CHANGED-#{viewInstanceId}", (args...) -> + ipc.on "ATOM_SHELL_GUEST_VIEW_INTERNAL_SIZE_CHANGED-#{viewInstanceId}", (event, args...) -> domEvent = new Event('size-changed') for f, i in ['oldWidth', 'oldHeight', 'newWidth', 'newHeight'] domEvent[f] = args[i] diff --git a/atom/renderer/lib/web-view/web-view.coffee b/atom/renderer/lib/web-view/web-view.coffee index 3a563101f003..3dc54b258d50 100644 --- a/atom/renderer/lib/web-view/web-view.coffee +++ b/atom/renderer/lib/web-view/web-view.coffee @@ -135,7 +135,7 @@ class WebViewImpl guestViewInternal.setSize @guestInstanceId, normal: newSize createGuest: -> - guestViewInternal.createGuest @buildParams(), (guestInstanceId) => + guestViewInternal.createGuest @buildParams(), (event, guestInstanceId) => @attachWindow guestInstanceId dispatchEvent: (webViewEvent) -> diff --git a/spec/api-ipc-spec.coffee b/spec/api-ipc-spec.coffee index 1155aa73e83d..e5028c602b1f 100644 --- a/spec/api-ipc-spec.coffee +++ b/spec/api-ipc-spec.coffee @@ -1,5 +1,5 @@ assert = require 'assert' -ipc = require 'ipc' +ipc = require 'ipc-renderer' path = require 'path' remote = require 'remote' @@ -70,7 +70,7 @@ describe 'ipc module', -> describe 'ipc.sender.send', -> it 'should work when sending an object containing id property', (done) -> obj = id: 1, name: 'ly' - ipc.once 'message', (message) -> + ipc.once 'message', (event, message) -> assert.deepEqual message, obj done() ipc.send 'message', obj diff --git a/spec/api-session-spec.coffee b/spec/api-session-spec.coffee index 9e083d27c0f7..8baca1557ccb 100644 --- a/spec/api-session-spec.coffee +++ b/spec/api-session-spec.coffee @@ -78,7 +78,7 @@ describe 'session module', -> # A 5 MB mock pdf. mockPDF = new Buffer 1024 * 1024 * 5 contentDisposition = 'inline; filename="mock.pdf"' - ipc = require 'ipc' + ipc = require 'ipc-renderer' downloadFilePath = path.join fixtures, 'mock.pdf' downloadServer = http.createServer (req, res) -> res.writeHead 200, { @@ -94,8 +94,7 @@ describe 'session module', -> {port} = downloadServer.address() ipc.sendSync 'set-download-option', false w.loadUrl "#{url}:#{port}" - ipc.once 'download-done', (state, url, mimeType, receivedBytes, - totalBytes, disposition, filename) -> + ipc.once 'download-done', (event, state, url, mimeType, receivedBytes, totalBytes, disposition, filename) -> assert.equal state, 'completed' assert.equal filename, 'mock.pdf' assert.equal url, "http://127.0.0.1:#{port}/" @@ -112,8 +111,7 @@ describe 'session module', -> {port} = downloadServer.address() ipc.sendSync 'set-download-option', true w.loadUrl "#{url}:#{port}/" - ipc.once 'download-done', (state, url, mimeType, receivedBytes, - totalBytes, disposition, filename) -> + ipc.once 'download-done', (event, state, url, mimeType, receivedBytes, totalBytes, disposition, filename) -> assert.equal state, 'cancelled' assert.equal filename, 'mock.pdf' assert.equal mimeType, 'application/pdf' diff --git a/spec/fixtures/api/localstorage.html b/spec/fixtures/api/localstorage.html index 8110a0b4be6a..d1450e93c98d 100644 --- a/spec/fixtures/api/localstorage.html +++ b/spec/fixtures/api/localstorage.html @@ -2,7 +2,7 @@ diff --git a/spec/fixtures/api/send-sync-message.html b/spec/fixtures/api/send-sync-message.html index d6fe83f907e1..40bae94b810f 100644 --- a/spec/fixtures/api/send-sync-message.html +++ b/spec/fixtures/api/send-sync-message.html @@ -1,7 +1,7 @@ diff --git a/spec/fixtures/module/preload-ipc.js b/spec/fixtures/module/preload-ipc.js index 9b6e0201248e..76bd481cab6f 100644 --- a/spec/fixtures/module/preload-ipc.js +++ b/spec/fixtures/module/preload-ipc.js @@ -1,4 +1,4 @@ -var ipc = require('ipc'); -ipc.on('ping', function(message) { +var ipc = require('ipc-renderer'); +ipc.on('ping', function(event, message) { ipc.sendToHost('pong', message); }); diff --git a/spec/fixtures/module/send-later.js b/spec/fixtures/module/send-later.js index fce96b84b787..9cd5bfd38853 100644 --- a/spec/fixtures/module/send-later.js +++ b/spec/fixtures/module/send-later.js @@ -1,4 +1,4 @@ -var ipc = require('ipc'); +var ipc = require('ipc-renderer'); window.onload = function() { ipc.send('answer', typeof window.process); } diff --git a/spec/fixtures/pages/basic-auth.html b/spec/fixtures/pages/basic-auth.html index aa95546a9c11..f2b9fab199fe 100644 --- a/spec/fixtures/pages/basic-auth.html +++ b/spec/fixtures/pages/basic-auth.html @@ -2,7 +2,7 @@ diff --git a/spec/fixtures/pages/history.html b/spec/fixtures/pages/history.html index b5029d638926..ef0083535973 100644 --- a/spec/fixtures/pages/history.html +++ b/spec/fixtures/pages/history.html @@ -2,7 +2,7 @@ diff --git a/spec/fixtures/pages/ipc-message.html b/spec/fixtures/pages/ipc-message.html index 15bfef49c4da..65e347275c21 100644 --- a/spec/fixtures/pages/ipc-message.html +++ b/spec/fixtures/pages/ipc-message.html @@ -1,7 +1,7 @@ diff --git a/spec/fixtures/pages/onkeyup.html b/spec/fixtures/pages/onkeyup.html index 99e6c3e98382..87e6dc596b5b 100644 --- a/spec/fixtures/pages/onkeyup.html +++ b/spec/fixtures/pages/onkeyup.html @@ -2,7 +2,7 @@ diff --git a/spec/fixtures/pages/onmouseup.html b/spec/fixtures/pages/onmouseup.html index 1fd38bc7211f..ea486fdf80ed 100644 --- a/spec/fixtures/pages/onmouseup.html +++ b/spec/fixtures/pages/onmouseup.html @@ -2,7 +2,7 @@ diff --git a/spec/fixtures/pages/window-opener.html b/spec/fixtures/pages/window-opener.html index 226b57dbd709..a7b59bd1a45b 100644 --- a/spec/fixtures/pages/window-opener.html +++ b/spec/fixtures/pages/window-opener.html @@ -4,7 +4,7 @@ if (window.opener !== null) window.opener.postMessage(typeof window.opener, '*'); else - require('ipc').send('opener', window.opener); + require('ipc-renderer').send('opener', window.opener); diff --git a/spec/static/index.html b/spec/static/index.html index 879d769860ed..e7c69f5ba7de 100644 --- a/spec/static/index.html +++ b/spec/static/index.html @@ -29,7 +29,7 @@ } require('coffee-script/register'); // Supports .coffee tests. - var ipc = require('ipc'); + var ipc = require('ipc-renderer'); // Rediret all output to browser. if (isCi) { From 844cea8f216539ad2233180ab28b934d060f12c7 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Tue, 10 Nov 2015 15:41:24 +0800 Subject: [PATCH 093/249] Deprecate ipc module for ipcMain --- atom/browser/api/lib/ipc-main.coffee | 3 +++ atom/browser/api/lib/ipc.coffee | 7 +++++-- filenames.gypi | 1 + 3 files changed, 9 insertions(+), 2 deletions(-) create mode 100644 atom/browser/api/lib/ipc-main.coffee diff --git a/atom/browser/api/lib/ipc-main.coffee b/atom/browser/api/lib/ipc-main.coffee new file mode 100644 index 000000000000..8021544479d2 --- /dev/null +++ b/atom/browser/api/lib/ipc-main.coffee @@ -0,0 +1,3 @@ +{EventEmitter} = require 'events' + +module.exports = new EventEmitter diff --git a/atom/browser/api/lib/ipc.coffee b/atom/browser/api/lib/ipc.coffee index 71cf1d17e491..f116b9a874a5 100644 --- a/atom/browser/api/lib/ipc.coffee +++ b/atom/browser/api/lib/ipc.coffee @@ -1,3 +1,6 @@ -EventEmitter = require('events').EventEmitter +deprecate = require 'deprecate' -module.exports = new EventEmitter +# This module is deprecated, we mirror everything from ipcRenderer. +deprecate.warn 'ipc module', 'ipcMain module' + +module.exports = require 'ipc-main' diff --git a/filenames.gypi b/filenames.gypi index 93cb4f3e07aa..4dc709c5ec57 100644 --- a/filenames.gypi +++ b/filenames.gypi @@ -18,6 +18,7 @@ 'atom/browser/api/lib/dialog.coffee', 'atom/browser/api/lib/global-shortcut.coffee', 'atom/browser/api/lib/ipc.coffee', + 'atom/browser/api/lib/ipc-main.coffee', 'atom/browser/api/lib/menu.coffee', 'atom/browser/api/lib/menu-item.coffee', 'atom/browser/api/lib/navigation-controller.coffee', From 751af25f374c0c144b3f56fb301170fc5b0829b8 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Tue, 10 Nov 2015 16:04:34 +0800 Subject: [PATCH 094/249] Use ipcMain in Electron's code --- atom/browser/api/lib/browser-window.coffee | 2 +- atom/browser/api/lib/navigation-controller.coffee | 2 +- atom/browser/api/lib/web-contents.coffee | 2 +- atom/browser/lib/guest-view-manager.coffee | 2 +- atom/browser/lib/guest-window-manager.coffee | 2 +- atom/browser/lib/rpc-server.coffee | 2 +- spec/api-browser-window-spec.coffee | 6 +++--- spec/api-ipc-spec.coffee | 2 +- spec/api-session-spec.coffee | 6 +++--- spec/asar-spec.coffee | 2 +- spec/static/main.js | 4 ++-- 11 files changed, 16 insertions(+), 16 deletions(-) diff --git a/atom/browser/api/lib/browser-window.coffee b/atom/browser/api/lib/browser-window.coffee index d8ac221c62e0..5bb633208840 100644 --- a/atom/browser/api/lib/browser-window.coffee +++ b/atom/browser/api/lib/browser-window.coffee @@ -1,6 +1,6 @@ EventEmitter = require('events').EventEmitter app = require 'app' -ipc = require 'ipc' +ipc = require 'ipc-main' deprecate = require 'deprecate' BrowserWindow = process.atomBinding('window').BrowserWindow diff --git a/atom/browser/api/lib/navigation-controller.coffee b/atom/browser/api/lib/navigation-controller.coffee index f78d92c341d6..34911dd759ec 100644 --- a/atom/browser/api/lib/navigation-controller.coffee +++ b/atom/browser/api/lib/navigation-controller.coffee @@ -1,4 +1,4 @@ -ipc = require 'ipc' +ipc = require 'ipc-main' # The history operation in renderer is redirected to browser. ipc.on 'ATOM_SHELL_NAVIGATION_CONTROLLER', (event, method, args...) -> diff --git a/atom/browser/api/lib/web-contents.coffee b/atom/browser/api/lib/web-contents.coffee index 331a561189d7..958c3f8270c6 100644 --- a/atom/browser/api/lib/web-contents.coffee +++ b/atom/browser/api/lib/web-contents.coffee @@ -2,7 +2,7 @@ EventEmitter = require('events').EventEmitter Menu = require './menu' NavigationController = require './navigation-controller' binding = process.atomBinding 'web_contents' -ipc = require 'ipc' +ipc = require 'ipc-main' nextId = 0 getNextId = -> ++nextId diff --git a/atom/browser/lib/guest-view-manager.coffee b/atom/browser/lib/guest-view-manager.coffee index 455e969812f7..c99b681498e4 100644 --- a/atom/browser/lib/guest-view-manager.coffee +++ b/atom/browser/lib/guest-view-manager.coffee @@ -1,4 +1,4 @@ -ipc = require 'ipc' +ipc = require 'ipc-main' webContents = require 'web-contents' webViewManager = null # Doesn't exist in early initialization. diff --git a/atom/browser/lib/guest-window-manager.coffee b/atom/browser/lib/guest-window-manager.coffee index 5de3ad3b042e..fe01c6fa771e 100644 --- a/atom/browser/lib/guest-window-manager.coffee +++ b/atom/browser/lib/guest-window-manager.coffee @@ -1,4 +1,4 @@ -ipc = require 'ipc' +ipc = require 'ipc-main' v8Util = process.atomBinding 'v8_util' BrowserWindow = require 'browser-window' diff --git a/atom/browser/lib/rpc-server.coffee b/atom/browser/lib/rpc-server.coffee index ae4b161674bd..c6a646edcd9b 100644 --- a/atom/browser/lib/rpc-server.coffee +++ b/atom/browser/lib/rpc-server.coffee @@ -1,4 +1,4 @@ -ipc = require 'ipc' +ipc = require 'ipc-main' path = require 'path' objectsRegistry = require './objects-registry.js' v8Util = process.atomBinding 'v8_util' diff --git a/spec/api-browser-window-spec.coffee b/spec/api-browser-window-spec.coffee index 1218d27b7fd7..460a1c1ec17c 100644 --- a/spec/api-browser-window-spec.coffee +++ b/spec/api-browser-window-spec.coffee @@ -201,12 +201,12 @@ describe 'browser-window module', -> describe '"web-preferences" option', -> afterEach -> - remote.require('ipc').removeAllListeners('answer') + remote.require('ipc-main').removeAllListeners('answer') describe '"preload" option', -> it 'loads the script before other scripts in window', (done) -> preload = path.join fixtures, 'module', 'set-global.js' - remote.require('ipc').once 'answer', (event, test) -> + remote.require('ipc-main').once 'answer', (event, test) -> assert.equal(test, 'preload') done() w.destroy() @@ -219,7 +219,7 @@ describe 'browser-window module', -> describe '"node-integration" option', -> it 'disables node integration when specified to false', (done) -> preload = path.join fixtures, 'module', 'send-later.js' - remote.require('ipc').once 'answer', (event, test) -> + remote.require('ipc-main').once 'answer', (event, test) -> assert.equal(test, 'undefined') done() w.destroy() diff --git a/spec/api-ipc-spec.coffee b/spec/api-ipc-spec.coffee index e5028c602b1f..d8918338c96c 100644 --- a/spec/api-ipc-spec.coffee +++ b/spec/api-ipc-spec.coffee @@ -83,7 +83,7 @@ describe 'ipc module', -> it 'does not crash when reply is not sent and browser is destroyed', (done) -> @timeout 10000 w = new BrowserWindow(show: false) - remote.require('ipc').once 'send-sync-message', (event) -> + remote.require('ipc-main').once 'send-sync-message', (event) -> event.returnValue = null w.destroy() done() diff --git a/spec/api-session-spec.coffee b/spec/api-session-spec.coffee index 8baca1557ccb..028768f61d38 100644 --- a/spec/api-session-spec.coffee +++ b/spec/api-session-spec.coffee @@ -60,9 +60,9 @@ describe 'session module', -> describe 'session.clearStorageData(options)', -> fixtures = path.resolve __dirname, 'fixtures' it 'clears localstorage data', (done) -> - ipc = remote.require('ipc') - ipc.on 'count', (event, count) -> - ipc.removeAllListeners 'count' + ipcMain = remote.require('ipc-main') + ipcMain.on 'count', (event, count) -> + ipcMain.removeAllListeners 'count' assert not count done() w.loadUrl 'file://' + path.join(fixtures, 'api', 'localstorage.html') diff --git a/spec/asar-spec.coffee b/spec/asar-spec.coffee index 75f0cec63adb..3e3890d529f1 100644 --- a/spec/asar-spec.coffee +++ b/spec/asar-spec.coffee @@ -407,7 +407,7 @@ describe 'asar package', -> describe 'asar protocol', -> url = require 'url' remote = require 'remote' - ipc = remote.require 'ipc' + ipc = remote.require 'ipc-main' BrowserWindow = remote.require 'browser-window' it 'can request a file in package', (done) -> diff --git a/spec/static/main.js b/spec/static/main.js index 5b10bb6d43d7..702c88ecdd94 100644 --- a/spec/static/main.js +++ b/spec/static/main.js @@ -1,5 +1,5 @@ var app = require('app'); -var ipc = require('ipc'); +var ipc = require('ipc-main'); var dialog = require('dialog'); var path = require('path'); var BrowserWindow = require('browser-window'); @@ -78,7 +78,7 @@ app.on('ready', function() { // For session's download test, listen 'will-download' event in browser, and // reply the result to renderer for verifying var downloadFilePath = path.join(__dirname, '..', 'fixtures', 'mock.pdf'); - require('ipc').on('set-download-option', function(event, need_cancel) { + ipc.on('set-download-option', function(event, need_cancel) { window.webContents.session.once('will-download', function(e, item, webContents) { item.setSavePath(downloadFilePath); From 05611f5e60166f350d4b6776435e62924b8d6e7d Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Tue, 10 Nov 2015 16:21:08 +0800 Subject: [PATCH 095/249] spec: Use multiparty instead of formidable The latter is buggy and affects our specs. --- spec/api-crash-reporter-spec.coffee | 7 ++----- spec/package.json | 2 +- spec/static/main.js | 1 + 3 files changed, 4 insertions(+), 6 deletions(-) diff --git a/spec/api-crash-reporter-spec.coffee b/spec/api-crash-reporter-spec.coffee index 618adaaf9dec..5e06cade8cec 100644 --- a/spec/api-crash-reporter-spec.coffee +++ b/spec/api-crash-reporter-spec.coffee @@ -3,7 +3,7 @@ path = require 'path' http = require 'http' url = require 'url' remote = require 'remote' -formidable = require 'formidable' +multiparty = require 'multiparty' crashReporter = remote.require 'crash-reporter' BrowserWindow = remote.require 'browser-window' @@ -26,10 +26,8 @@ describe 'crash-reporter module', -> @timeout 120000 server = http.createServer (req, res) -> server.close() - form = new formidable.IncomingForm() - process.throwDeprecation = false + form = new multiparty.Form() form.parse req, (error, fields, files) -> - process.throwDeprecation = true assert.equal fields['prod'], 'Electron' assert.equal fields['ver'], process.versions['electron'] assert.equal fields['process_type'], 'renderer' @@ -39,7 +37,6 @@ describe 'crash-reporter module', -> assert.equal fields['_productName'], 'Zombies' assert.equal fields['_companyName'], 'Umbrella Corporation' assert.equal fields['_version'], require('remote').require('app').getVersion() - assert files['upload_file_minidump']['name']? res.end('abc-123-def') done() diff --git a/spec/package.json b/spec/package.json index cf1d0abe89e3..38bd83796701 100644 --- a/spec/package.json +++ b/spec/package.json @@ -5,7 +5,7 @@ "version": "0.1.0", "devDependencies": { "basic-auth": "^1.0.0", - "formidable": "1.0.16", + "multiparty": "4.1.2", "graceful-fs": "3.0.5", "mocha": "2.1.0", "q": "0.9.7", diff --git a/spec/static/main.js b/spec/static/main.js index 702c88ecdd94..70c47cc37e1c 100644 --- a/spec/static/main.js +++ b/spec/static/main.js @@ -9,6 +9,7 @@ process.port = 0; // will be used by crash-reporter spec. app.commandLine.appendSwitch('js-flags', '--expose_gc'); app.commandLine.appendSwitch('ignore-certificate-errors'); +app.commandLine.appendSwitch('disable-renderer-backgrounding'); // Accessing stdout in the main process will result in the process.stdout // throwing UnknownSystemError in renderer process sometimes. This line makes From 90a7d4a906e902a4212a57d2dcc860204b389b13 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Tue, 10 Nov 2015 16:48:24 +0800 Subject: [PATCH 096/249] docs: Update with new IPC modules --- docs/README.md | 4 +- docs/api/ipc-main-process.md | 76 -------------------------- docs/api/ipc-main.md | 71 ++++++++++++++++++++++++ docs/api/ipc-renderer.md | 53 +++++++++--------- docs/api/web-contents.md | 18 ++---- docs/api/web-view-tag.md | 11 ++-- docs/tutorial/online-offline-events.md | 46 ++++++++-------- 7 files changed, 136 insertions(+), 143 deletions(-) delete mode 100644 docs/api/ipc-main-process.md create mode 100644 docs/api/ipc-main.md diff --git a/docs/README.md b/docs/README.md index 754048f5e3f3..fb5c64a8f17e 100644 --- a/docs/README.md +++ b/docs/README.md @@ -36,7 +36,7 @@ * [content-tracing](api/content-tracing.md) * [dialog](api/dialog.md) * [global-shortcut](api/global-shortcut.md) -* [ipc (main process)](api/ipc-main-process.md) +* [ipc-main](api/ipc-main.md) * [menu](api/menu.md) * [menu-item](api/menu-item.md) * [power-monitor](api/power-monitor.md) @@ -48,7 +48,7 @@ ### Modules for the Renderer Process (Web Page): -* [ipc (renderer)](api/ipc-renderer.md) +* [ipc-renderer](api/ipc-renderer.md) * [remote](api/remote.md) * [web-frame](api/web-frame.md) diff --git a/docs/api/ipc-main-process.md b/docs/api/ipc-main-process.md deleted file mode 100644 index 98d9c3c22d43..000000000000 --- a/docs/api/ipc-main-process.md +++ /dev/null @@ -1,76 +0,0 @@ -# ipc (main process) - -The `ipc` module, when used in the main process, handles asynchronous and -synchronous messages sent from a renderer process (web page). Messages sent from -a renderer will be emitted to this module. - -## Sending Messages - -It is also possible to send messages from the main process to the renderer -process, see [WebContents.send](web-contents.md#webcontentssendchannel-args) -for more information. - -- When sending a message, the event name is the `channel`. -- To reply a synchronous message, you need to set `event.returnValue`. -- To send an asynchronous back to the sender, you can use - `event.sender.send(...)`. - -An example of sending and handling messages between the render and main -processes: - -```javascript -// In main process. -var ipc = require('ipc'); -ipc.on('asynchronous-message', function(event, arg) { - console.log(arg); // prints "ping" - event.sender.send('asynchronous-reply', 'pong'); -}); - -ipc.on('synchronous-message', function(event, arg) { - console.log(arg); // prints "ping" - event.returnValue = 'pong'; -}); -``` - -```javascript -// In renderer process (web page). -var ipc = require('ipc'); -console.log(ipc.sendSync('synchronous-message', 'ping')); // prints "pong" - -ipc.on('asynchronous-reply', function(arg) { - console.log(arg); // prints "pong" -}); -ipc.send('asynchronous-message', 'ping'); -``` - -## Listening for Messages - -The `ipc` module has the following method to listen for events: - -### `ipc.on(channel, callback)` - -* `channel` String - The event name. -* `callback` Function - -When the event occurs the `callback` is called with an `event` object and a -message, `arg`. - -## IPC Events - -The `event` object passed to the `callback` has the following methods: - -### `Event.returnValue` - -Set this to the value to be returned in a synchronous message. - -### `Event.sender` - -Returns the `WebContents` that sent the message. - -### `Event.sender.send(channel[, arg1][, arg2][, ...])` - -* `channel` String - The event name. -* `arg` (optional) - -This sends an asynchronous message back to the render process. Optionally, there -can be one or a series of arguments, `arg`, which can have any type. diff --git a/docs/api/ipc-main.md b/docs/api/ipc-main.md new file mode 100644 index 000000000000..4f3d6ebc3bf7 --- /dev/null +++ b/docs/api/ipc-main.md @@ -0,0 +1,71 @@ +# ipcMain + +The `ipcMain` module, when used in the main process, handles asynchronous and +synchronous messages sent from a renderer process (web page). Messages sent from +a renderer will be emitted to this module. + +## Sending Messages + +It is also possible to send messages from the main process to the renderer +process, see [WebContents.send][webcontents-send] for more information. + +* When sending a message, the event name is the `channel`. +* To reply a synchronous message, you need to set `event.returnValue`. +* To send an asynchronous back to the sender, you can use + `event.sender.send(...)`. + +An example of sending and handling messages between the render and main +processes: + +```javascript +// In main process. +var ipcMain = require('ipc-main'); +ipcMain.on('asynchronous-message', function(event, arg) { + console.log(arg); // prints "ping" + event.sender.send('asynchronous-reply', 'pong'); +}); + +ipcMain.on('synchronous-message', function(event, arg) { + console.log(arg); // prints "ping" + event.returnValue = 'pong'; +}); +``` + +```javascript +// In renderer process (web page). +var ipcRenderer = require('ipc-renderer'); +console.log(ipcRenderer.sendSync('synchronous-message', 'ping')); // prints "pong" + +ipcRenderer.on('asynchronous-reply', function(event, arg) { + console.log(arg); // prints "pong" +}); +ipcRenderer.send('asynchronous-message', 'ping'); +``` + +## Listening for Messages + +The `ipcMain` module has the following method to listen for events: + +### `ipcMain.on(channel, callback)` + +* `channel` String - The event name. +* `callback` Function + +When the event occurs the `callback` is called with an `event` object and a +message, `arg`. + +## IPC Event + +The `event` object passed to the `callback` has the following methods: + +### `event.returnValue` + +Set this to the value to be returned in a synchronous message. + +### `event.sender` + +Returns the `webContents` that sent the message, you can call +`event.sender.send` to reply to the asynchronous message, see +[WebContents.send][webcontents-send] for more information. + +[webcontents-send]: web-contents.md#webcontentssendchannel-args diff --git a/docs/api/ipc-renderer.md b/docs/api/ipc-renderer.md index 752af2ebe293..e591f9e0bca2 100644 --- a/docs/api/ipc-renderer.md +++ b/docs/api/ipc-renderer.md @@ -1,52 +1,55 @@ -# ipc (renderer) +# ipcRenderer -The `ipc` module provides a few methods so you can send synchronous and +The `ipcRenderer` module provides a few methods so you can send synchronous and asynchronous messages from the render process (web page) to the main process. You can also receive replies from the main process. -**Note:** If you want to make use of modules in the main process from the renderer -process, you might consider using the [remote](remote.md) module. +See [ipcMain](ipc-main.md) for code examples. -See [ipc (main process)](ipc-main-process.md) for code examples. +## Listening for Messages -## Methods +The `ipcRenderer` module has the following method to listen for events: -The `ipc` module has the following methods for sending messages: +### `ipcRenderer.on(channel, callback)` -**Note:** When using these methods to send a `message` you must also listen -for it in the main process with [`ipc (main process)`](ipc-main-process.md). +* `channel` String - The event name. +* `callback` Function -### `ipc.send(channel[, arg1][, arg2][, ...])` +When the event occurs the `callback` is called with an `event` object and +arbitrary arguments. + +## Sending Messages + +The `ipcRenderer` module has the following methods for sending messages: + +### `ipcRenderer.send(channel[, arg1][, arg2][, ...])` * `channel` String - The event name. * `arg` (optional) -Send an event to the main process asynchronously via a `channel`. Optionally, -there can be a message: one or a series of arguments, `arg`, which can have any -type. The main process handles it by listening for the `channel` event with -`ipc`. +Send an event to the main process asynchronously via a `channel`, you can also +send arbitrary arguments. The main process handles it by listening for the +`channel` event with `ipcMain`. -### `ipc.sendSync(channel[, arg1][, arg2][, ...])` +### `ipcRenderer.sendSync(channel[, arg1][, arg2][, ...])` * `channel` String - The event name. * `arg` (optional) -Send an event to the main process synchronously via a `channel`. Optionally, -there can be a message: one or a series of arguments, `arg`, which can have any -type. The main process handles it by listening for the `channel` event with -`ipc`. +Send an event to the main process synchronously via a `channel`, you can also +send arbitrary arguments. The main process handles it by listening for the +`channel` event with `ipcMain`. The main process handles it by listening for the `channel` event with `ipc` and replies by setting the `event.returnValue`. -**Note:** Sending a synchronous message will block the whole renderer process so -using this method is not recommended. +__Note:__ Sending a synchronous message will block the whole renderer process, +unless you know what you are doing you should never use it. -### `ipc.sendToHost(channel[, arg1][, arg2][, ...])` +### `ipcRenderer.sendToHost(channel[, arg1][, arg2][, ...])` * `channel` String - The event name. * `arg` (optional) -Like `ipc.send` but the event will be sent to the host page in a `` -instead of the main process. Optionally, there can be a message: one or a series -of arguments, `arg`, which can have any type. +Like `ipcRenderer.send` but the event will be sent to the `` element in +the host page instead of the main process. diff --git a/docs/api/web-contents.md b/docs/api/web-contents.md index 52a06b87edb1..d62706b2ba9a 100644 --- a/docs/api/web-contents.md +++ b/docs/api/web-contents.md @@ -510,13 +510,14 @@ Starts inspecting element at position (`x`, `y`). Opens the developer tools for the service worker context. -### `webContents.send(channel[, args...])` +### `webContents.send(channel[, arg1][, arg2][, ...])` * `channel` String -* `args...` (optional) +* `arg` (optional) -Send `args...` to the web page via `channel` in an asynchronous message, the web -page can handle it by listening to the `channel` event of the `ipc` module. +Send an asynchronous message to renderer process via `channel`, you can also +send arbitrary arguments. The renderer process can handle the message by +listening to the `channel` event with the `ipcRenderer` module. An example of sending messages from the main process to the renderer process: @@ -537,7 +538,7 @@ app.on('ready', function() { @@ -545,13 +546,6 @@ app.on('ready', function() { ``` -**Note:** - -1. The IPC message handler in web pages does not have an `event` parameter, - which is different from the handlers in the main process. -2. There is no way to send synchronous messages from the main process to a - renderer process, because it would be very easy to cause dead locks. - ### `webContents.enableDeviceEmulation(parameters)` `parameters` Object, properties: diff --git a/docs/api/web-view-tag.md b/docs/api/web-view-tag.md index 3fda3a98edb5..9a0e0be33b36 100644 --- a/docs/api/web-view-tag.md +++ b/docs/api/web-view-tag.md @@ -355,15 +355,16 @@ Prints `webview`'s web page. Same with `webContents.print([options])`. Prints webview's web page as PDF, Same with `webContents.printToPDF(options, callback)` -### `.send(channel[, args...])` +### `.send(channel[, arg1][, arg2][, ...])` * `channel` String * `arg` (optional) -Send `args..` to guest page via `channel` in asynchronous message, the guest -page can handle it by listening to the `channel` event of `ipc` module. +Send an asynchronous message to renderer process via `channel`, you can also +send arbitrary arguments. The renderer process can handle the message by +listening to the `channel` event with the `ipcRenderer` module. -See [WebContents.send](web-contents.md#webcontentssendchannel-args) for +See [webContents.send](web-contents.md#webcontentssendchannel-args) for examples. ### `.sendInputEvent(event)` @@ -372,7 +373,7 @@ examples. Sends an input `event` to the page. -See [WebContents.sendInputEvent](web-contents.md##webcontentssendinputeventevent) +See [webContents.sendInputEvent](web-contents.md##webcontentssendinputeventevent) for detailed description of `event` object. ## DOM events diff --git a/docs/tutorial/online-offline-events.md b/docs/tutorial/online-offline-events.md index 88f9a32f2ec6..46d659e07d05 100644 --- a/docs/tutorial/online-offline-events.md +++ b/docs/tutorial/online-offline-events.md @@ -21,18 +21,18 @@ _online-status.html_ ```html - - - + alertOnlineStatus(); + + ``` @@ -46,7 +46,7 @@ _main.js_ ```javascript var app = require('app'); -var ipc = require('ipc'); +var ipcMain = require('ipc-main'); var BrowserWindow = require('browser-window'); var onlineStatusWindow; @@ -55,7 +55,7 @@ app.on('ready', function() { onlineStatusWindow.loadUrl('file://' + __dirname + '/online-status.html'); }); -ipc.on('online-status-changed', function(event, status) { +ipcMain.on('online-status-changed', function(event, status) { console.log(status); }); ``` @@ -65,18 +65,18 @@ _online-status.html_ ```html - - - + updateOnlineStatus(); + + ``` From d234f10177c71cdf6860e90e3317f3b5d17eb13e Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Tue, 10 Nov 2015 16:59:08 +0800 Subject: [PATCH 097/249] Implement event.sender for ipcRenderer --- atom/renderer/atom_render_view_observer.cc | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/atom/renderer/atom_render_view_observer.cc b/atom/renderer/atom_render_view_observer.cc index ecd9401420f8..931913dd75d0 100644 --- a/atom/renderer/atom_render_view_observer.cc +++ b/atom/renderer/atom_render_view_observer.cc @@ -31,6 +31,7 @@ #include "third_party/WebKit/public/web/WebScriptSource.h" #include "third_party/WebKit/public/web/WebView.h" #include "ui/base/resource/resource_bundle.h" +#include "native_mate/dictionary.h" namespace atom { @@ -143,8 +144,10 @@ void AtomRenderViewObserver::OnBrowserMessage(const base::string16& channel, v8::Local ipc; if (GetIPCObject(isolate, context, &ipc)) { auto args_vector = ListValueToVector(isolate, args); - // Insert a dummy Event object. - args_vector.insert(args_vector.begin(), v8::Object::New(isolate)); + // Insert the Event object, event.sender is ipc. + mate::Dictionary event = mate::Dictionary::CreateEmpty(isolate); + event.Set("sender", ipc); + args_vector.insert(args_vector.begin(), event.GetHandle()); mate::EmitEvent(isolate, ipc, channel, args_vector); } } From 682433028c8ebb5360f3ac0551f57f314aeb99ec Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Tue, 10 Nov 2015 17:43:29 +0800 Subject: [PATCH 098/249] docs: Clean up the desktop-environment-integration.md --- .../desktop-environment-integration.md | 68 +++++++++++++------ 1 file changed, 47 insertions(+), 21 deletions(-) diff --git a/docs/tutorial/desktop-environment-integration.md b/docs/tutorial/desktop-environment-integration.md index 08758d67933f..39f74ff10771 100644 --- a/docs/tutorial/desktop-environment-integration.md +++ b/docs/tutorial/desktop-environment-integration.md @@ -9,7 +9,11 @@ This guide explains how to integrate your application into those desktop environments with Electron APIs. ## Notifications (Windows, Linux, OS X) -All three operating systems provide means for applications to send notifications to the user. Electron conveniently allows developers to send notifications using the [JavaScript Notification API](https://notifications.spec.whatwg.org/), using the currently running operating system's native notification APIs to display it. + +All three operating systems provide means for applications to send notifications +to the user. Electron conveniently allows developers to send notifications with +the [HTML5 Notification API](https://notifications.spec.whatwg.org/), using +the currently running operating system's native notification APIs to display it. ```javascript var myNotificiation = new Notification('Title', { @@ -20,31 +24,50 @@ myNotification.onclick = function () { console.log('Notification clicked') } ``` -While code and user experience across operating systems are similar, but there are fine differences. -#### Windows - * On Windows 10, notifications "just work". - * On Windows 8.1 and Windows 8, a shortcut to your app, with a [System.AppUserModel.ID](https://msdn.microsoft.com/en-us/library/windows/desktop/dd391569(v=vs.85).aspx), must be installed to the Start screen. Note, however, that it does not need to be pinned to the Start screen. - * On Windows 7 and below, notifications are not supported. You can however send "balloon notifications" using the [Tray API](trayballoon). +While code and user experience across operating systems are similar, but there +are fine differences. -To use an image in your notification, pass a local image file (preferably `png`) in the `icon` property of your notification's options. The notification will still display if you submit and incorrect or `http/https`-based URL, but the image will not be displayed. +### Windows -``` +* On Windows 10, notifications "just work". +* On Windows 8.1 and Windows 8, a shortcut to your app, with a [Application User +Model ID][app-user-model-id], must be installed to the Start screen. Note, +however, that it does not need to be pinned to the Start screen. +* On Windows 7 and below, notifications are not supported. You can however send +"balloon notifications" using the [Tray API](tray-balloon). + +To use an image in your notification, pass a local image file (preferably `png`) +in the `icon` property of your notification's options. The notification will +still display if you submit and incorrect or `http/https`-based URL, but the +image will not be displayed. + +```javascript new Notification('Title', { body: 'Notification with icon', icon: 'file:///C:/Users/feriese/Desktop/icon.png' }); ``` -Keep furthermore in mind that the maximum length for the body is 250 characters, with the Windows team recommending that notifications should be kept to 200 characters. +Keep furthermore in mind that the maximum length for the body is 250 characters, +with the Windows team recommending that notifications should be kept to 200 +characters. -#### Linux -Notifications are sent using Ubuntu's Unity (and will obviously not be displayed if Unity is not running). For more information about Unity's on screen notifications, [check out the project page](https://unity.ubuntu.com/projects/notifyosd/). +### Linux -#### OS X -Notifications are straight-forward on OS X, you should however be aware of [Apple's Human Interface guidelines regarding notifications](https://developer.apple.com/library/mac/documentation/UserExperience/Conceptual/OSXHIGuidelines/NotificationCenter.html). +Notifications are sent using `libnotify`, it can show notifications on any +desktop environment that follows [Desktop Notifications +Specification][notification-spec], including Cinnamon, Enlightenment, Unity, +GNOME, KDE. -Note that notifications are limited to 256 bytes in size - and will be truncated if you exceed that limit. +### OS X + +Notifications are straight-forward on OS X, you should however be aware of +[Apple's Human Interface guidelines regarding +notifications](https://developer.apple.com/library/mac/documentation/UserExperience/Conceptual/OSXHIGuidelines/NotificationCenter.html). + +Note that notifications are limited to 256 bytes in size - and will be truncated +if you exceed that limit. ## Recent documents (Windows & OS X) @@ -81,7 +104,8 @@ registered as a handler of the file type of the document, otherwise the file won't appear in JumpList even after you have added it. You can find everything on registering your application in [Application Registration][app-registration]. -When a user clicks a file from the JumpList, a new instance of your application will be started with the path of the file added as a command line argument. +When a user clicks a file from the JumpList, a new instance of your application +will be started with the path of the file added as a command line argument. ### OS X Notes @@ -192,10 +216,10 @@ __Thumbnail toolbar of Windows Media Player:__ ![player](https://i-msdn.sec.s-msft.com/dynimg/IC420540.png) -You can use [BrowserWindow.setThumbarButtons][setthumbarbuttons] to set thumbnail -toolbar in your application: +You can use [BrowserWindow.setThumbarButtons][setthumbarbuttons] to set +thumbnail toolbar in your application: -``` +```javascript var BrowserWindow = require('browser-window'); var path = require('path'); var win = new BrowserWindow({ @@ -226,8 +250,8 @@ win.setThumbarButtons([]); ## Unity Launcher Shortcuts (Linux) -In Unity, you can add custom entries to its launcher via modifying the `.desktop` -file, see [Adding Shortcuts to a Launcher][unity-launcher]. +In Unity, you can add custom entries to its launcher via modifying the +`.desktop` file, see [Adding Shortcuts to a Launcher][unity-launcher]. __Launcher shortcuts of Audacious:__ @@ -290,4 +314,6 @@ window.setDocumentEdited(true); [app-registration]: http://msdn.microsoft.com/en-us/library/windows/desktop/ee872121(v=vs.85).aspx [unity-launcher]: https://help.ubuntu.com/community/UnityLaunchersAndDesktopFiles#Adding_shortcuts_to_a_launcher [setthumbarbuttons]: ../api/browser-window.md#browserwindowsetthumbarbuttonsbuttons -[trayballoon]: ../api/tray.md#traydisplayballoonoptions-windows \ No newline at end of file +[tray-balloon]: ../api/tray.md#traydisplayballoonoptions-windows +[app-user-model-id]: https://msdn.microsoft.com/en-us/library/windows/desktop/dd378459(v=vs.85).aspx +[notification-spec]: https://developer.gnome.org/notification-spec/ From d582ddf790969527155e3dd6ccda3eaebb8d1327 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Tue, 10 Nov 2015 17:44:14 +0800 Subject: [PATCH 099/249] Update brightray for win7 crash of using notification --- vendor/brightray | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vendor/brightray b/vendor/brightray index 7c9915847e84..29bd72a7537f 160000 --- a/vendor/brightray +++ b/vendor/brightray @@ -1 +1 @@ -Subproject commit 7c9915847e84076b5444ee945e6dc2904fb345d1 +Subproject commit 29bd72a7537ffb99775e3e56ad5662fd4a1bfed0 From 1f01a4535ae6073f6730b993a5b3089c14611cfb Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Tue, 10 Nov 2015 18:04:59 +0800 Subject: [PATCH 100/249] Fix compilation error of brightray --- vendor/brightray | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vendor/brightray b/vendor/brightray index 29bd72a7537f..871bc3ccf10a 160000 --- a/vendor/brightray +++ b/vendor/brightray @@ -1 +1 @@ -Subproject commit 29bd72a7537ffb99775e3e56ad5662fd4a1bfed0 +Subproject commit 871bc3ccf10a86c4d63116f6279dd6095faf3af4 From 08e245e3dc502baa1f84ec62c85add45738ce5ff Mon Sep 17 00:00:00 2001 From: Levin Rickert Date: Tue, 10 Nov 2015 12:42:05 +0100 Subject: [PATCH 101/249] Fix typo --- atom/browser/api/lib/ipc.coffee | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/atom/browser/api/lib/ipc.coffee b/atom/browser/api/lib/ipc.coffee index f116b9a874a5..b8ab05a886b9 100644 --- a/atom/browser/api/lib/ipc.coffee +++ b/atom/browser/api/lib/ipc.coffee @@ -1,6 +1,6 @@ deprecate = require 'deprecate' -# This module is deprecated, we mirror everything from ipcRenderer. +# This module is deprecated, we mirror everything from ipcMain. deprecate.warn 'ipc module', 'ipcMain module' module.exports = require 'ipc-main' From f6a0e5ad31d3fb187649b9a4658f5d6e8fae0eb2 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Tue, 10 Nov 2015 20:32:16 +0800 Subject: [PATCH 102/249] Update brightray for atom/brightray#167 --- vendor/brightray | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vendor/brightray b/vendor/brightray index 871bc3ccf10a..4e069f1806ef 160000 --- a/vendor/brightray +++ b/vendor/brightray @@ -1 +1 @@ -Subproject commit 871bc3ccf10a86c4d63116f6279dd6095faf3af4 +Subproject commit 4e069f1806efe5da9a965e61f329b19b7791104a From f98147ea014734e02b43dec6170783b1ac43f3d2 Mon Sep 17 00:00:00 2001 From: Nishanth Shanmugham Date: Tue, 10 Nov 2015 09:27:39 -0600 Subject: [PATCH 103/249] Tray: Rename events to drag-enter and drag-leave Previously, the names were drag-entered and drag-exited. The new names mirror the HTML Drag and Drop event names --- atom/browser/api/atom_api_tray.cc | 4 ++-- docs/api/tray.md | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/atom/browser/api/atom_api_tray.cc b/atom/browser/api/atom_api_tray.cc index 5381c77c3793..00b8eda7b54a 100644 --- a/atom/browser/api/atom_api_tray.cc +++ b/atom/browser/api/atom_api_tray.cc @@ -79,11 +79,11 @@ void Tray::OnDropFiles(const std::vector& files) { } void Tray::OnDragEntered() { - Emit("drag-entered"); + Emit("drag-enter"); } void Tray::OnDragExited() { - Emit("drag-exited"); + Emit("drag-leave"); } bool Tray::IsDestroyed() const { diff --git a/docs/api/tray.md b/docs/api/tray.md index 5d187fc5b88c..37e17d88ca25 100644 --- a/docs/api/tray.md +++ b/docs/api/tray.md @@ -119,11 +119,11 @@ closes it. Emitted when dragged files are dropped in the tray icon. -### Event: 'drag-entered' _OS X_ +### Event: 'drag-enter' _OS X_ Emitted when a drag operation enters the tray icon. -### Event: 'drag-exited' _OS X_ +### Event: 'drag-leave' _OS X_ Emitted when a drag operation exits the tray icon. From d1e8e71e3f786199db5ce843475775ddcc88634f Mon Sep 17 00:00:00 2001 From: Nishanth Shanmugham Date: Tue, 10 Nov 2015 10:02:50 -0600 Subject: [PATCH 104/249] Tray: Add drag-end and drop events --- atom/browser/api/atom_api_tray.cc | 8 ++++++++ atom/browser/api/atom_api_tray.h | 2 ++ atom/browser/ui/tray_icon.cc | 8 ++++++++ atom/browser/ui/tray_icon.h | 2 ++ atom/browser/ui/tray_icon_cocoa.mm | 9 +++++++++ atom/browser/ui/tray_icon_observer.h | 2 ++ 6 files changed, 31 insertions(+) diff --git a/atom/browser/api/atom_api_tray.cc b/atom/browser/api/atom_api_tray.cc index 00b8eda7b54a..0c24240f223c 100644 --- a/atom/browser/api/atom_api_tray.cc +++ b/atom/browser/api/atom_api_tray.cc @@ -74,6 +74,10 @@ void Tray::OnBalloonClosed() { Emit("balloon-closed"); } +void Tray::OnDrop() { + Emit("drop"); +} + void Tray::OnDropFiles(const std::vector& files) { Emit("drop-files", files); } @@ -86,6 +90,10 @@ void Tray::OnDragExited() { Emit("drag-leave"); } +void Tray::OnDragEnded() { + Emit("drag-end"); +} + bool Tray::IsDestroyed() const { return !tray_icon_; } diff --git a/atom/browser/api/atom_api_tray.h b/atom/browser/api/atom_api_tray.h index b26796bccedc..d8d6dcead16c 100644 --- a/atom/browser/api/atom_api_tray.h +++ b/atom/browser/api/atom_api_tray.h @@ -48,9 +48,11 @@ class Tray : public mate::TrackableObject, void OnBalloonShow() override; void OnBalloonClicked() override; void OnBalloonClosed() override; + void OnDrop() override; void OnDropFiles(const std::vector& files) override; void OnDragEntered() override; void OnDragExited() override; + void OnDragEnded() override; // mate::Wrappable: bool IsDestroyed() const override; diff --git a/atom/browser/ui/tray_icon.cc b/atom/browser/ui/tray_icon.cc index bc69b6e72759..1696aab276b1 100644 --- a/atom/browser/ui/tray_icon.cc +++ b/atom/browser/ui/tray_icon.cc @@ -55,6 +55,10 @@ void TrayIcon::NotifyRightClicked(const gfx::Rect& bounds, int modifiers) { OnRightClicked(bounds, modifiers)); } +void TrayIcon::NotifyDrop() { + FOR_EACH_OBSERVER(TrayIconObserver, observers_, OnDrop()); +} + void TrayIcon::NotifyDropFiles(const std::vector& files) { FOR_EACH_OBSERVER(TrayIconObserver, observers_, OnDropFiles(files)); } @@ -67,4 +71,8 @@ void TrayIcon::NotifyDragExited() { FOR_EACH_OBSERVER(TrayIconObserver, observers_, OnDragExited()); } +void TrayIcon::NotifyDragEnded() { + FOR_EACH_OBSERVER(TrayIconObserver, observers_, OnDragEnded()); +} + } // namespace atom diff --git a/atom/browser/ui/tray_icon.h b/atom/browser/ui/tray_icon.h index b63d3c48c262..bc29acd8a255 100644 --- a/atom/browser/ui/tray_icon.h +++ b/atom/browser/ui/tray_icon.h @@ -61,9 +61,11 @@ class TrayIcon { void NotifyBalloonClosed(); void NotifyRightClicked(const gfx::Rect& bounds = gfx::Rect(), int modifiers = 0); + void NotifyDrop(); void NotifyDropFiles(const std::vector& files); void NotifyDragEntered(); void NotifyDragExited(); + void NotifyDragEnded(); protected: TrayIcon(); diff --git a/atom/browser/ui/tray_icon_cocoa.mm b/atom/browser/ui/tray_icon_cocoa.mm index 40505a64d8cd..c373e94519bb 100644 --- a/atom/browser/ui/tray_icon_cocoa.mm +++ b/atom/browser/ui/tray_icon_cocoa.mm @@ -262,6 +262,15 @@ const CGFloat kVerticalTitleMargin = 2; trayIcon_->NotifyDragExited(); } +- (void)draggingEnded:(id )sender { + trayIcon_->NotifyDragEnded(); +} + +- (BOOL)prepareForDragOperation:(id )sender { + trayIcon_->NotifyDrop(); + return YES; +} + - (BOOL)performDragOperation:(id )sender { NSPasteboard* pboard = [sender draggingPasteboard]; diff --git a/atom/browser/ui/tray_icon_observer.h b/atom/browser/ui/tray_icon_observer.h index e9a8bd33f1d3..ed421ed85452 100644 --- a/atom/browser/ui/tray_icon_observer.h +++ b/atom/browser/ui/tray_icon_observer.h @@ -22,9 +22,11 @@ class TrayIconObserver { virtual void OnBalloonClicked() {} virtual void OnBalloonClosed() {} virtual void OnRightClicked(const gfx::Rect& bounds, int modifiers) {} + virtual void OnDrop() {} virtual void OnDropFiles(const std::vector& files) {} virtual void OnDragEntered() {} virtual void OnDragExited() {} + virtual void OnDragEnded() {} protected: virtual ~TrayIconObserver() {} From ed179ecf03fcfb40daeacd1b35621989dc65322b Mon Sep 17 00:00:00 2001 From: Nishanth Shanmugham Date: Tue, 10 Nov 2015 10:14:55 -0600 Subject: [PATCH 105/249] docs: Update tray docs with drop and drag-end events --- docs/api/tray.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/docs/api/tray.md b/docs/api/tray.md index 37e17d88ca25..47f02c5478fa 100644 --- a/docs/api/tray.md +++ b/docs/api/tray.md @@ -112,6 +112,10 @@ Emitted when the tray balloon is clicked. Emitted when the tray balloon is closed because of timeout or user manually closes it. +### Event: 'drop' _OS X_ + +Emitted when any dragged items are dropped on the tray icon. + ### Event: 'drop-files' _OS X_ * `event` @@ -127,6 +131,10 @@ Emitted when a drag operation enters the tray icon. Emitted when a drag operation exits the tray icon. +### Event: 'drag-end' _OS X_ + +Emitted when a drag operation ends on the tray or ends at another location. + ## Methods The `Tray` module has the following methods: From 916671d4d2af9b5a9dcfdc6f67ef3a646d638ded Mon Sep 17 00:00:00 2001 From: Ming Luo Date: Tue, 10 Nov 2015 14:55:00 -0500 Subject: [PATCH 106/249] Suggest adding arguments when running webdriver --- docs/tutorial/using-selenium-and-webdriver.md | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/docs/tutorial/using-selenium-and-webdriver.md b/docs/tutorial/using-selenium-and-webdriver.md index b87f8f11dac9..867e452442b3 100644 --- a/docs/tutorial/using-selenium-and-webdriver.md +++ b/docs/tutorial/using-selenium-and-webdriver.md @@ -46,9 +46,12 @@ var webdriver = require('selenium-webdriver'); var driver = new webdriver.Builder() // The "9515" is the port opened by chrome driver. .usingServer('http://localhost:9515') - .withCapabilities({chromeOptions: { - // Here is the path to your Electron binary. - binary: '/Path-to-Your-App.app/Contents/MacOS/Atom'}}) + .withCapabilities({ + chromeOptions: { + // Here is the path to your Electron binary. + binary: '/Path-to-Your-App.app/Contents/MacOS/Atom', + } + }) .forBrowser('electron') .build(); @@ -96,7 +99,10 @@ var options = { port: 9515, // "9515" is the port opened by chrome driver. desiredCapabilities: { browserName: 'chrome', - chromeOptions: {binary: '/Path-to-Your-App.app/Electron'} // Path to your Electron binary. + chromeOptions: { + binary: '/Path-to-Your-App/electron', // Path to your Electron binary. + args: [/* cli arguments */] // Optional, perhaps 'app=' + /path/to/your/app/ + } } }; @@ -119,4 +125,8 @@ To test your application without rebuilding Electron, simply [place](https://github.com/atom/electron/blob/master/docs/tutorial/application-distribution.md) your app source into Electron's resource directory. +Alternatively, pass an argument to run with your electron binary that points to +your app's folder. This eliminates the need to copy-paste your app into +Electron's resource directory. + [chrome-driver]: https://sites.google.com/a/chromium.org/chromedriver/ From b611154f4330d7dc67dd4de8dcdb59972390876c Mon Sep 17 00:00:00 2001 From: Plusb Preco Date: Wed, 11 Nov 2015 09:03:49 +0900 Subject: [PATCH 107/249] Standardize the webContents object name --- docs/api/ipc-main.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/api/ipc-main.md b/docs/api/ipc-main.md index 4f3d6ebc3bf7..f74c70426a5c 100644 --- a/docs/api/ipc-main.md +++ b/docs/api/ipc-main.md @@ -7,7 +7,7 @@ a renderer will be emitted to this module. ## Sending Messages It is also possible to send messages from the main process to the renderer -process, see [WebContents.send][webcontents-send] for more information. +process, see [webContents.send][webcontents-send] for more information. * When sending a message, the event name is the `channel`. * To reply a synchronous message, you need to set `event.returnValue`. @@ -66,6 +66,6 @@ Set this to the value to be returned in a synchronous message. Returns the `webContents` that sent the message, you can call `event.sender.send` to reply to the asynchronous message, see -[WebContents.send][webcontents-send] for more information. +[webContents.send][webcontents-send] for more information. [webcontents-send]: web-contents.md#webcontentssendchannel-args From 319acc1e8afbeec7cb2ab2bedce2ee86284d6a40 Mon Sep 17 00:00:00 2001 From: Plusb Preco Date: Wed, 11 Nov 2015 09:44:33 +0900 Subject: [PATCH 108/249] Update as upstream --- docs-translations/ko-KR/README.md | 4 +- .../ko-KR/api/ipc-main-process.md | 71 ------------------- docs-translations/ko-KR/api/ipc-main.md | 66 +++++++++++++++++ docs-translations/ko-KR/api/ipc-renderer.md | 43 +++++------ docs-translations/ko-KR/api/web-view-tag.md | 10 +-- .../desktop-environment-integration.md | 53 +++++++++++++- .../ko-KR/tutorial/online-offline-events.md | 46 ++++++------ 7 files changed, 171 insertions(+), 122 deletions(-) delete mode 100644 docs-translations/ko-KR/api/ipc-main-process.md create mode 100644 docs-translations/ko-KR/api/ipc-main.md diff --git a/docs-translations/ko-KR/README.md b/docs-translations/ko-KR/README.md index bfe08e5e1032..73df16241528 100644 --- a/docs-translations/ko-KR/README.md +++ b/docs-translations/ko-KR/README.md @@ -36,7 +36,7 @@ * [content-tracing](api/content-tracing.md) * [dialog](api/dialog.md) * [global-shortcut](api/global-shortcut.md) -* [ipc (main process)](api/ipc-main-process.md) +* [ipc-main](api/ipc-main.md) * [menu](api/menu.md) * [menu-item](api/menu-item.md) * [power-monitor](api/power-monitor.md) @@ -48,7 +48,7 @@ ### 랜더러 프로세스에서 사용할 수 있는 모듈 (웹 페이지): -* [ipc (renderer)](api/ipc-renderer.md) +* [ipc-renderer](api/ipc-renderer.md) * [remote](api/remote.md) * [web-frame](api/web-frame.md) diff --git a/docs-translations/ko-KR/api/ipc-main-process.md b/docs-translations/ko-KR/api/ipc-main-process.md deleted file mode 100644 index ad4e545ce474..000000000000 --- a/docs-translations/ko-KR/api/ipc-main-process.md +++ /dev/null @@ -1,71 +0,0 @@ -# ipc (main process) - -`ipc` (main process) 모듈은 메인 프로세스에서 사용할 때 랜더러 프로세스(웹 페이지)에서 전달된 동기 또는 비동기 메시지를 보내고 받는 방법을 제공합니다. -랜더러 프로세스에서 메시지를 전달하면 이 모듈을 통해 메시지를 받을 수 있습니다. - -## 메시지 전송 - -물론 메인 프로세스에서 랜더러 프로세스로 메시지를 보내는 것도 가능합니다. -자세한 내용은 [WebContents.send](web-contents.md#webcontentssendchannel-args)를 참고하세요. - -- 메시지를 전송할 때 이벤트 이름은 `channel`이 됩니다. -- 메시지에 동기로 응답할 땐 반드시 `event.returnValue`를 설정해야 합니다. -- 메시지를 비동기로 응답할 땐 `event.sender.send(...)` 메서드를 사용할 수 있습니다. - -랜더러 프로세스와 메인 프로세스간에 메시지를 전달하고 받는 예제입니다: - -```javascript -// 메인 프로세스 -var ipc = require('ipc'); -ipc.on('asynchronous-message', function(event, arg) { - console.log(arg); // prints "ping" - event.sender.send('asynchronous-reply', 'pong'); -}); - -ipc.on('synchronous-message', function(event, arg) { - console.log(arg); // prints "ping" - event.returnValue = 'pong'; -}); -``` - -```javascript -// 랜더러 프로세스 (web page) -var ipc = require('ipc'); -console.log(ipc.sendSync('synchronous-message', 'ping')); // prints "pong" - -ipc.on('asynchronous-reply', function(arg) { - console.log(arg); // prints "pong" -}); -ipc.send('asynchronous-message', 'ping'); -``` - -## 메시지 리스닝 - -`ipc` 모듈은 다음과 같은 이벤트 메서드를 가지고 있습니다: - -### `ipc.on(channel, callback)` - -* `channel` String - 이벤트 이름 -* `callback` Function - -이벤트가 발생하면 `callback`에 `event` 객체와 `arg` 메시지가 포함되어 호출됩니다. - -## IPC Events - -`callback`에서 전달된 `event` 객체는 다음과 같은 메서드와 속성을 가지고 있습니다: - -### `Event.returnValue` - -이 메시지를 지정하면 동기 메시지를 전달합니다. - -### `Event.sender` - -메시지를 보낸 `WebContents` 객체를 반환합니다. - -### `Event.sender.send(channel[, arg1][, arg2][, ...])` - -* `channel` String - The event name. -* `arg` (optional) - -랜더러 프로세스로 비동기 메시지를 전달합니다. -옵션으로 `arg`에 한 개 또는 여러 개의 메시지를 포함할 수 있습니다. 모든 타입을 사용할 수 있습니다. diff --git a/docs-translations/ko-KR/api/ipc-main.md b/docs-translations/ko-KR/api/ipc-main.md new file mode 100644 index 000000000000..cecbf980e720 --- /dev/null +++ b/docs-translations/ko-KR/api/ipc-main.md @@ -0,0 +1,66 @@ +# ipcMain + +`ipcMain` 모듈은 메인 프로세스에서 사용할 때 랜더러 프로세스(웹 페이지)에서 전달된 동기/비동기 메시지를 주고 받는 방법을 제공합니다. +랜더러 프로세스에서 메시지를 전달하면 이 모듈을 통해 메시지를 받을 수 있습니다. + +## 메시지 전송 + +물론 메시지를 받는 것 말고도 메인 프로세스에서 랜더러 프로세스로 보내는 것도 가능합니다. +자세한 내용은 [webContents.send](web-contents.md#webcontentssendchannel-args)를 참고하세요. + +* 메시지를 전송할 때 이벤트 이름은 `channel`이 됩니다. +* 메시지에 동기로 응답할 땐 반드시 `event.returnValue`를 설정해야 합니다. +* 메시지를 비동기로 응답할 땐 `event.sender.send(...)` 메서드를 사용할 수 있습니다. + +다음 예제는 랜더러 프로세스와 메인 프로세스간에 메시지를 전달하고 받는 예제입니다: + +```javascript +// 메인 프로세스 +var ipc = require('ipc'); +ipc.on('asynchronous-message', function(event, arg) { + console.log(arg); // prints "ping" + event.sender.send('asynchronous-reply', 'pong'); +}); + +ipc.on('synchronous-message', function(event, arg) { + console.log(arg); // prints "ping" + event.returnValue = 'pong'; +}); +``` + +```javascript +// 랜더러 프로세스 (웹 페이지) +var ipc = require('ipc'); +console.log(ipc.sendSync('synchronous-message', 'ping')); // prints "pong" + +ipc.on('asynchronous-reply', function(arg) { + console.log(arg); // prints "pong" +}); +ipc.send('asynchronous-message', 'ping'); +``` + +## 메시지 리스닝 + +`ipcMain`은 다음과 같은 이벤트 리스닝 메서드를 가지고 있습니다: + +### `ipc.on(channel, callback)` + +* `channel` String - 이벤트 이름 +* `callback` Function + +이벤트가 발생하면 `event` 객체와 `arg` 메시지와 함께 `callback`이 호출됩니다. + +## IPC 이벤트 + +`callback`에서 전달된 `event` 객체는 다음과 같은 메서드와 속성을 가지고 있습니다: + +### `Event.returnValue` + +이 메시지를 지정하면 동기 메시지를 전달합니다. + +### `Event.sender` + +메시지를 보낸 `webContents` 객체를 반환합니다. `event.sender.send` 메서드를 통해 비동기로 메시지를 전달할 수 있습니다. +자세한 내용은 [webContents.send][webcontents-send]를 참고하세요. + +[webcontents-send]: web-contents.md#webcontentssendchannel-args diff --git a/docs-translations/ko-KR/api/ipc-renderer.md b/docs-translations/ko-KR/api/ipc-renderer.md index 67864c4e1157..28442a29073a 100644 --- a/docs-translations/ko-KR/api/ipc-renderer.md +++ b/docs-translations/ko-KR/api/ipc-renderer.md @@ -1,45 +1,48 @@ -# ipc (renderer) +# ipcRenderer -`ipc` (renderer) 모듈은 메인 프로세스로 동기 또는 비동기 메시지를 보내고 받는 방법을 제공합니다. -물론 메인 프로세스로부터 받은 메시지에 응답할 수도 있습니다. +`ipcRenderer` 모듈은 랜더러 프로세스에서 메인 프로세스로 동기/비동기 메시지를 주고 받는 방법을 제공합니다. +또한 메인 프로세스로부터 받은 메시지에 응답할 수도 있습니다. -**참고:** 만약 랜더러 프로세스에서 메인 프로세스의 모듈을 직접적 사용하고 싶다면 [remote](remote.md) 모듈을 사용하는 것을 고려해보는 것이 좋습니다. +[ipcMain](ipc-main.md)에서 코드 예제를 확인할 수 있습니다. -[ipc (main process)](ipc-main-process.md)에서 예제를 확인 할 수 있습니다. +## 메시지 리스닝 -## Methods +`ipcRenderer`는 다음과 같은 이벤트 리스닝 메서드를 가지고 있습니다: -`ipc` 모듈은 다음과 같은 메서드를 가지고 있습니다: +### `ipcRenderer.on(channel, callback)` -**참고:** 이 메소드들을 사용하여 `message`를 보낼 땐 반드시 메인 프로세스의 -[`ipc (main process)`](ipc-main-process.md) 모듈에서도 이벤트 리스너를 등록해 두어야 합니다. +* `channel` String - 이벤트 이름 +* `callback` Function -### `ipc.send(channel[, arg1][, arg2][, ...])` +이벤트가 일어나면 `event` 객체와 임의의 인자와 함께 `callback` 함수가 호출됩니다. + +## 메시지 보내기 + +`ipcRenderer`는 다음과 같은 메시지 전송 메서드를 가지고 있습니다: + +### `ipcRenderer.send(channel[, arg1][, arg2][, ...])` * `channel` String - 이벤트 이름 * `arg` (optional) -`channel`을 통해 메인 프로세스에 비동기 메시지를 보냅니다. -옵션으로 `arg`에 한 개 또는 여러 개의 메시지를 포함할 수 있습니다. 모든 타입을 사용할 수 있습니다. -메인 프로세스는 `ipc`를 통해 `channel` 이벤트를 리스닝 할 수 있습니다. +`channel`을 통해 메인 프로세스에 비동기 메시지를 보냅니다. 그리고 필요에 따라 임의의 인자를 사용할 수도 있습니다. +메인 프로세스는 `ipcMain` 모듈의 `channel` 이벤트를 통해 이벤트를 리스닝 할 수 있습니다. -### `ipc.sendSync(channel[, arg1][, arg2][, ...])` +### `ipcRenderer.sendSync(channel[, arg1][, arg2][, ...])` * `channel` String - 이벤트 이름 * `arg` (optional) -`channel`을 통해 메인 프로세스에 동기 메시지를 보냅니다. -옵션으로 `arg`에 한 개 또는 여러 개의 메시지를 포함할 수 있습니다. 모든 타입을 사용할 수 있습니다. +`channel`을 통해 메인 프로세스에 동기 메시지를 보냅니다. 그리고 필요에 따라 임의의 인자를 사용할 수도 있습니다. 메인 프로세스는 `ipc`를 통해 `channel` 이벤트를 리스닝 할 수 있습니다. 메인 프로세스에선 `ipc` 모듈의 `channel` 이벤트를 통해 받은 `event.returnValue`로 회신 할 수 있습니다. -**참고:** 동기 메시징은 모든 랜더러 프로세스의 작업을 일시 중단시킵니다. 이 메서드를 사용하는 것을 권장하지 않습니다. +__참고:__ 동기 메서드는 모든 랜더러 프로세스의 작업을 일시 중단시킵니다. 사용 목적이 확실하지 않다면 사용하지 않는 것이 좋습니다. -### `ipc.sendToHost(channel[, arg1][, arg2][, ...])` +### `ipcRenderer.sendToHost(channel[, arg1][, arg2][, ...])` * `channel` String - 이벤트 이름 * `arg` (optional) -`ipc.send`와 비슷하지만 이벤트를 메인 프로세스 대신 호스트 페이지내의 ``로 보냅니다. -옵션으로 `arg`에 한 개 또는 여러 개의 메시지를 포함할 수 있습니다. 모든 타입을 사용할 수 있습니다. +`ipcRenderer.send`와 비슷하지만 이벤트를 메인 프로세스 대신 호스트 페이지내의 `` 요소로 보냅니다. diff --git a/docs-translations/ko-KR/api/web-view-tag.md b/docs-translations/ko-KR/api/web-view-tag.md index 69b94465aede..bb9a1305c8a9 100644 --- a/docs-translations/ko-KR/api/web-view-tag.md +++ b/docs-translations/ko-KR/api/web-view-tag.md @@ -333,15 +333,15 @@ Webview 페이지를 인쇄합니다. `webContents.print([options])` 메서드 Webview 페이지를 PDF 형식으로 인쇄합니다. `webContents.printToPDF(options, callback)` 메서드와 같습니다. -### `.send(channel[, args...])` +### `.send(channel[, arg1][, arg2][, ...])` * `channel` String * `args` (optional) -`channel`을 통해 페이지에 `args` 비동기 메시지를 보냅니다. -페이지에선 `ipc` 모듈의 `channel` 이벤트를 사용하면 이 메시지를 받을 수 있습니다. +`channel`을 통해 랜더러 프로세스로 비동기 메시지를 보냅니다. 또한 `args`를 지정하여 임의의 인자를 보낼 수도 있습니다. +랜더러 프로세스는 `ipcRenderer` 모듈의 `channel` 이벤트로 이 메시지를 받아 처리할 수 있습니다. -예제는 [WebContents.send](web-contents.md#webcontentssendchannel-args)를 참고하세요. +예제는 [webContents.send](web-contents.md#webcontentssendchannel-args)를 참고하세요. ### `.sendInputEvent(event)` @@ -349,7 +349,7 @@ Webview 페이지를 PDF 형식으로 인쇄합니다. `webContents.printToPDF(o 페이지에 input `event`를 보냅니다. -`event` 객체에 대해 자세한 내용을 알아보려면 [WebContents.sendInputEvent](web-contents.md##webcontentssendinputeventevent)를 참고하세요. +`event` 객체에 대해 자세히 알아보려면 [webContents.sendInputEvent](web-contents.md##webcontentssendinputeventevent)를 참고하세요. ## DOM 이벤트 diff --git a/docs-translations/ko-KR/tutorial/desktop-environment-integration.md b/docs-translations/ko-KR/tutorial/desktop-environment-integration.md index b721f5a4a358..1212cbb9c433 100644 --- a/docs-translations/ko-KR/tutorial/desktop-environment-integration.md +++ b/docs-translations/ko-KR/tutorial/desktop-environment-integration.md @@ -3,7 +3,57 @@ 어플리케이션 배포의 대상이 되는 서로 다른 운영체제 시스템의 환경에 맞춰 어플리케이션의 기능을 통합할 수 있습니다. 예를 들어 Windows에선 태스크바의 JumpList에 바로가기를 추가할 수 있고 Mac(OS X)에선 dock 메뉴에 커스텀 메뉴를 추가할 수 있습니다. -이 가이드는 Electron API를 이용하여 각 운영체제 시스템의 기능을 활용하는 방법을 설명합니다. +이 문서는 Electron API를 이용하여 각 운영체제 시스템의 기능을 활용하는 방법을 설명합니다. + +## 데스크톱 알림 (Windows, Linux, OS X) + +Windows, Linux, OS X 운영체제 모두 기본적으로 어플리케이션에서 유저에게 알림 보낼 수 있는 방법을 제공합니다. +Electron은 HTML5 Notification API](https://notifications.spec.whatwg.org/)를 통해 개발자가 +편리하게 데스크톱 알림을 사용할 수 있는 기능을 제공합니다. 데스크톱 알림은 운영체제의 네이티브 알림 API를 사용하여 표시합니다. + +```javascript +var myNotificiation = new Notification('Title', { + body: 'Lorem Ipsum Dolor Sit Amet' +}); + +myNotification.onclick = function () { + console.log('Notification clicked') +} +``` + +위 코드를 통해 생성한 데스크톱 알림은 각 운영체제 모두 비슷한 사용자 경험을 제공합니다. 하지만 몇 가지 다른 점들이 있습니다. + +### Windows + +* Windows 10에선 "아무 문제 없이 잘" 작동합니다. +* Windows 8.1과 8에선 [Application User Model ID][app-user-model-id]로 바로가기를 만들어 놔야 합니다. +이 바로가기는 반드시 시작 화면에 설치되어 있어야 합니다. 참고로 반드시 시작 화면에 고정 할 필요는 없습니다. +* Windows 7과 그 이하 버전은 데스크톱 알림을 지원하지 않습니다. 혹시 "풍선 알림" 기능을 찾는다면 [Tray API](tray-balloon)를 사용하세요. + +이미지를 데스크톱 알림에 사용하려면 알림 옵션의 `icon` 속성에 로컬 이미지 파일(`png` 권장)을 지정하면 됩니다. +데스크톱 알림은 잘못된 경로를 지정하거나 `http/https` 기반의 URL을 지정해도 이미지가 보이지 않을 뿐 정상 작동합니다. + +```javascript +new Notification('Title', { + body: 'Notification with icon', + icon: 'file:///C:/Users/feriese/Desktop/icon.png' +}); +``` + +또한 `body`의 최대 길이는 250자 입니다. Windows 개발팀에선 알림 문자열을 200자 이하로 유지하는 것을 권장합니다. + +### Linux + +데스크톱 알림의 구현으로 `libnotify`를 사용합니다. 따라서 [Desktop Notifications Specification][notification-spec]을 +따르는 모든 데스크탑 환경에서 데스크톱 알림 기능을 사용할 수 있습니다. Cinnamon, Enlightenment, Unity, GNOME, KDE등을 지원합니다. + +### OS X + +OS X에서의 데스크톱 알림은 아주 직관적입니다. 하지만 데스크톱 알림을 사용할 땐 +[Apple's Human Interface guidelines regarding notifications](https://developer.apple.com/library/mac/documentation/UserExperience/Conceptual/OSXHIGuidelines/NotificationCenter.html) +가이드를 고려해야 합니다. + +참고로 데스크롭 알림의 최대 길이는 256 바이트 입니다. 길이가 초과할 경우 초과한 글자가 잘립니다. ## 최근 사용한 문서 (Windows & OS X) @@ -220,3 +270,4 @@ window.setDocumentEdited(true); [app-registration]: http://msdn.microsoft.com/en-us/library/windows/desktop/ee872121(v=vs.85).aspx [unity-launcher]: https://help.ubuntu.com/community/UnityLaunchersAndDesktopFiles#Adding_shortcuts_to_a_launcher [setthumbarbuttons]: ../api/browser-window.md#browserwindowsetthumbarbuttonsbuttons +[trayballoon]: ../api/tray.md#traydisplayballoonoptions-windows diff --git a/docs-translations/ko-KR/tutorial/online-offline-events.md b/docs-translations/ko-KR/tutorial/online-offline-events.md index cc8ae4855d55..5950d40525e2 100644 --- a/docs-translations/ko-KR/tutorial/online-offline-events.md +++ b/docs-translations/ko-KR/tutorial/online-offline-events.md @@ -20,18 +20,18 @@ _online-status.html_ ```html - - - + alertOnlineStatus(); + + ``` @@ -44,7 +44,7 @@ _main.js_ ```javascript var app = require('app'); -var ipc = require('ipc'); +var ipcMain = require('ipc-main'); var BrowserWindow = require('browser-window'); var onlineStatusWindow; @@ -53,7 +53,7 @@ app.on('ready', function() { onlineStatusWindow.loadUrl('file://' + __dirname + '/online-status.html'); }); -ipc.on('online-status-changed', function(event, status) { +ipcMain.on('online-status-changed', function(event, status) { console.log(status); }); ``` @@ -63,18 +63,18 @@ _online-status.html_ ```html - - - + updateOnlineStatus(); + + ``` From d37aa8bed9b3131cd254a5cf396da9a28534d9db Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Tue, 10 Nov 2015 22:17:27 +0800 Subject: [PATCH 109/249] Reorder switches --- atom/browser/api/atom_api_window.cc | 3 ++ atom/common/options_switches.cc | 63 +++++++++++++++-------------- atom/common/options_switches.h | 25 ++++++------ 3 files changed, 48 insertions(+), 43 deletions(-) diff --git a/atom/browser/api/atom_api_window.cc b/atom/browser/api/atom_api_window.cc index 497b5a6930ff..bd24b444db3a 100644 --- a/atom/browser/api/atom_api_window.cc +++ b/atom/browser/api/atom_api_window.cc @@ -60,7 +60,10 @@ void OnCapturePageDone( callback.Run(gfx::Image::CreateFrom1xBitmap(bitmap)); } +// Convert min-width to minWidth recursively in the dictionary. + #if defined(OS_WIN) +// Convert binary data to Buffer. v8::Local ToBuffer(v8::Isolate* isolate, void* val, int size) { auto buffer = node::Buffer::New(isolate, static_cast(val), size); if (buffer.IsEmpty()) diff --git a/atom/common/options_switches.cc b/atom/common/options_switches.cc index 903c15ee6dd1..9fe38cdfd352 100644 --- a/atom/common/options_switches.cc +++ b/atom/common/options_switches.cc @@ -34,8 +34,6 @@ const char kKiosk[] = "kiosk"; // Make windows stays on the top of all other windows. const char kAlwaysOnTop[] = "always-on-top"; -const char kNodeIntegration[] = "node-integration"; - // Enable the NSView to accept first mouse event. const char kAcceptFirstMouse[] = "accept-first-mouse"; @@ -45,12 +43,6 @@ const char kUseContentSize[] = "use-content-size"; // The requested title bar style for the window const char kTitleBarStyle[] = "title-bar-style"; -// The WebPreferences. -const char kWebPreferences[] = "web-preferences"; - -// The factor of which page should be zoomed. -const char kZoomFactor[] = "zoom-factor"; - // The menu bar is hidden unless "Alt" is pressed. const char kAutoHideMenuBar[] = "auto-hide-menu-bar"; @@ -60,27 +52,6 @@ const char kEnableLargerThanScreen[] = "enable-larger-than-screen"; // Forces to use dark theme on Linux. const char kDarkTheme[] = "dark-theme"; -// Enable DirectWrite on Windows. -const char kDirectWrite[] = "direct-write"; - -// Enable plugins. -const char kEnablePlugins[] = "enable-plugins"; - -// Ppapi Flash path. -const char kPpapiFlashPath[] = "ppapi-flash-path"; - -// Ppapi Flash version. -const char kPpapiFlashVersion[] = "ppapi-flash-version"; - -// Instancd ID of guest WebContents. -const char kGuestInstanceID[] = "guest-instance-id"; - -// Script that will be loaded by guest WebContents before other scripts. -const char kPreloadScript[] = "preload"; - -// Like --preload, but the passed argument is an URL. -const char kPreloadUrl[] = "preload-url"; - // Whether the window should be transparent. const char kTransparent[] = "transparent"; @@ -96,8 +67,23 @@ const char kStandardWindow[] = "standard-window"; // Default browser window background color. const char kBackgroundColor[] = "background-color"; -// Path to client certificate. -const char kClientCertificate[] = "client-certificate"; +// The WebPreferences. +const char kWebPreferences[] = "web-preferences"; + +// The factor of which page should be zoomed. +const char kZoomFactor[] = "zoom-factor"; + +// Script that will be loaded by guest WebContents before other scripts. +const char kPreloadScript[] = "preload"; + +// Like --preload, but the passed argument is an URL. +const char kPreloadUrl[] = "preload-url"; + +// Enable the node integration. +const char kNodeIntegration[] = "node-integration"; + +// Instancd ID of guest WebContents. +const char kGuestInstanceID[] = "guest-instance-id"; // Web runtime features. const char kExperimentalFeatures[] = "experimental-features"; @@ -106,9 +92,24 @@ const char kOverlayScrollbars[] = "overlay-scrollbars"; const char kOverlayFullscreenVideo[] = "overlay-fullscreen-video"; const char kSharedWorker[] = "shared-worker"; +// Enable plugins. +const char kEnablePlugins[] = "enable-plugins"; + +// Ppapi Flash path. +const char kPpapiFlashPath[] = "ppapi-flash-path"; + +// Ppapi Flash version. +const char kPpapiFlashVersion[] = "ppapi-flash-version"; + // Set page visiblity to always visible. const char kPageVisibility[] = "page-visibility"; +// Enable DirectWrite on Windows. +const char kDirectWrite[] = "direct-write"; + +// Path to client certificate. +const char kClientCertificate[] = "client-certificate"; + // Disable HTTP cache. const char kDisableHttpCache[] = "disable-http-cache"; diff --git a/atom/common/options_switches.h b/atom/common/options_switches.h index 9887359a502b..9f171836f653 100644 --- a/atom/common/options_switches.h +++ b/atom/common/options_switches.h @@ -27,41 +27,42 @@ extern const char kFullscreen[]; extern const char kSkipTaskbar[]; extern const char kKiosk[]; extern const char kAlwaysOnTop[]; -extern const char kNodeIntegration[]; extern const char kAcceptFirstMouse[]; extern const char kUseContentSize[]; extern const char kTitleBarStyle[]; -extern const char kWebPreferences[]; -extern const char kZoomFactor[]; extern const char kAutoHideMenuBar[]; extern const char kEnableLargerThanScreen[]; extern const char kDarkTheme[]; -extern const char kDirectWrite[]; -extern const char kEnablePlugins[]; -extern const char kPpapiFlashPath[]; -extern const char kPpapiFlashVersion[]; -extern const char kGuestInstanceID[]; -extern const char kPreloadScript[]; -extern const char kPreloadUrl[]; extern const char kTransparent[]; extern const char kType[]; extern const char kDisableAutoHideCursor[]; extern const char kStandardWindow[]; extern const char kBackgroundColor[]; -extern const char kClientCertificate[]; +extern const char kWebPreferences[]; +// WebPreferences. +extern const char kZoomFactor[]; +extern const char kPreloadScript[]; +extern const char kPreloadUrl[]; +extern const char kNodeIntegration[]; +extern const char kGuestInstanceID[]; extern const char kExperimentalFeatures[]; extern const char kExperimentalCanvasFeatures[]; extern const char kOverlayScrollbars[]; extern const char kOverlayFullscreenVideo[]; extern const char kSharedWorker[]; extern const char kPageVisibility[]; +extern const char kDirectWrite[]; +// Following are actually command line switches, should be moved to other files. +extern const char kEnablePlugins[]; +extern const char kPpapiFlashPath[]; +extern const char kPpapiFlashVersion[]; +extern const char kClientCertificate[]; extern const char kDisableHttpCache[]; extern const char kRegisterStandardSchemes[]; extern const char kSSLVersionFallbackMin[]; extern const char kCipherSuiteBlacklist[]; - extern const char kAppUserModelId[]; } // namespace switches From 737e22b003a0a0f943e956b7d92b5216a77cdc5e Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Tue, 10 Nov 2015 22:23:21 +0800 Subject: [PATCH 110/249] Use minWidth style for options instead of min-width --- atom/browser/lib/guest-view-manager.coffee | 10 ++-- atom/browser/lib/guest-window-manager.coffee | 4 +- atom/browser/web_contents_preferences.cc | 8 ++-- atom/common/options_switches.cc | 50 ++++++++++---------- atom/renderer/lib/init.coffee | 4 +- spec/chromium-spec.coffee | 2 +- 6 files changed, 39 insertions(+), 39 deletions(-) diff --git a/atom/browser/lib/guest-view-manager.coffee b/atom/browser/lib/guest-view-manager.coffee index c99b681498e4..8b2658a180cf 100644 --- a/atom/browser/lib/guest-view-manager.coffee +++ b/atom/browser/lib/guest-view-manager.coffee @@ -118,11 +118,11 @@ attachGuest = (embedder, elementInstanceId, guestInstanceId, params) -> destroyGuest embedder, oldGuestInstanceId webPreferences = - 'guest-instance-id': guestInstanceId - 'node-integration': params.nodeintegration ? false - 'plugins': params.plugins - 'web-security': !params.disablewebsecurity - webPreferences['preload-url'] = params.preload if params.preload + guestInstanceId: guestInstanceId + nodeIntegration: params.nodeintegration ? false + plugins: params.plugins + webSecurity: !params.disablewebsecurity + webPreferences.preloadUrl = params.preload if params.preload webViewManager.addGuest guestInstanceId, elementInstanceId, embedder, guest, webPreferences guest.attachParams = params diff --git a/atom/browser/lib/guest-window-manager.coffee b/atom/browser/lib/guest-window-manager.coffee index fe01c6fa771e..f2c5fe3a43cd 100644 --- a/atom/browser/lib/guest-window-manager.coffee +++ b/atom/browser/lib/guest-window-manager.coffee @@ -11,8 +11,8 @@ mergeBrowserWindowOptions = (embedder, options) -> options.__proto__ = embedder.browserWindowOptions else # Or only inherit web-preferences if it is a webview. - options['web-preferences'] ?= {} - options['web-preferences'].__proto__ = embedder.getWebPreferences() + options.webPreferences ?= {} + options.webPreferences.__proto__ = embedder.getWebPreferences() options # Create a new guest created by |embedder| with |options|. diff --git a/atom/browser/web_contents_preferences.cc b/atom/browser/web_contents_preferences.cc index 14e32353af65..a0088221ba2c 100644 --- a/atom/browser/web_contents_preferences.cc +++ b/atom/browser/web_contents_preferences.cc @@ -135,21 +135,21 @@ void WebContentsPreferences::OverrideWebkitPrefs( prefs->images_enabled = b; if (self->web_preferences_.GetBoolean("java", &b)) prefs->java_enabled = b; - if (self->web_preferences_.GetBoolean("text-areas-are-resizable", &b)) + if (self->web_preferences_.GetBoolean("textAreasAreResizable", &b)) prefs->text_areas_are_resizable = b; if (self->web_preferences_.GetBoolean("webgl", &b)) prefs->experimental_webgl_enabled = b; if (self->web_preferences_.GetBoolean("webaudio", &b)) prefs->webaudio_enabled = b; - if (self->web_preferences_.GetBoolean("web-security", &b)) { + if (self->web_preferences_.GetBoolean("webSecurity", &b)) { prefs->web_security_enabled = b; prefs->allow_displaying_insecure_content = !b; prefs->allow_running_insecure_content = !b; } - if (self->web_preferences_.GetBoolean("allow-displaying-insecure-content", + if (self->web_preferences_.GetBoolean("allowDisplayingInsecureContent", &b)) prefs->allow_displaying_insecure_content = b; - if (self->web_preferences_.GetBoolean("allow-running-insecure-content", &b)) + if (self->web_preferences_.GetBoolean("allowRunningInsecureContent", &b)) prefs->allow_running_insecure_content = b; } diff --git a/atom/common/options_switches.cc b/atom/common/options_switches.cc index 9fe38cdfd352..9b3b50b4bf31 100644 --- a/atom/common/options_switches.cc +++ b/atom/common/options_switches.cc @@ -17,40 +17,40 @@ const char kX[] = "x"; const char kY[] = "y"; const char kWidth[] = "width"; const char kHeight[] = "height"; -const char kMinWidth[] = "min-width"; -const char kMinHeight[] = "min-height"; -const char kMaxWidth[] = "max-width"; -const char kMaxHeight[] = "max-height"; +const char kMinWidth[] = "minWidth"; +const char kMinHeight[] = "minHeight"; +const char kMaxWidth[] = "maxWidth"; +const char kMaxHeight[] = "maxHeight"; const char kResizable[] = "resizable"; const char kFullscreen[] = "fullscreen"; // Whether the window should show in taskbar. -const char kSkipTaskbar[] = "skip-taskbar"; +const char kSkipTaskbar[] = "skipTaskbar"; // Start with the kiosk mode, see Opera's page for description: // http://www.opera.com/support/mastering/kiosk/ const char kKiosk[] = "kiosk"; // Make windows stays on the top of all other windows. -const char kAlwaysOnTop[] = "always-on-top"; +const char kAlwaysOnTop[] = "alwaysOnTop"; // Enable the NSView to accept first mouse event. -const char kAcceptFirstMouse[] = "accept-first-mouse"; +const char kAcceptFirstMouse[] = "acceptFirstMouse"; // Whether window size should include window frame. -const char kUseContentSize[] = "use-content-size"; +const char kUseContentSize[] = "useContentSize"; // The requested title bar style for the window -const char kTitleBarStyle[] = "title-bar-style"; +const char kTitleBarStyle[] = "titleBarStyle"; // The menu bar is hidden unless "Alt" is pressed. -const char kAutoHideMenuBar[] = "auto-hide-menu-bar"; +const char kAutoHideMenuBar[] = "autoHideMenuBar"; // Enable window to be resized larger than screen. -const char kEnableLargerThanScreen[] = "enable-larger-than-screen"; +const char kEnableLargerThanScreen[] = "enableLargerThanScreen"; // Forces to use dark theme on Linux. -const char kDarkTheme[] = "dark-theme"; +const char kDarkTheme[] = "darkTheme"; // Whether the window should be transparent. const char kTransparent[] = "transparent"; @@ -59,38 +59,38 @@ const char kTransparent[] = "transparent"; const char kType[] = "type"; // Disable auto-hiding cursor. -const char kDisableAutoHideCursor[] = "disable-auto-hide-cursor"; +const char kDisableAutoHideCursor[] = "disableAutoHideCursor"; // Use the OS X's standard window instead of the textured window. -const char kStandardWindow[] = "standard-window"; +const char kStandardWindow[] = "standardWindow"; // Default browser window background color. -const char kBackgroundColor[] = "background-color"; +const char kBackgroundColor[] = "backgroundColor"; // The WebPreferences. -const char kWebPreferences[] = "web-preferences"; +const char kWebPreferences[] = "webPreferences"; // The factor of which page should be zoomed. -const char kZoomFactor[] = "zoom-factor"; +const char kZoomFactor[] = "zoomFactor"; // Script that will be loaded by guest WebContents before other scripts. const char kPreloadScript[] = "preload"; // Like --preload, but the passed argument is an URL. -const char kPreloadUrl[] = "preload-url"; +const char kPreloadUrl[] = "preloadUrl"; // Enable the node integration. -const char kNodeIntegration[] = "node-integration"; +const char kNodeIntegration[] = "nodeIntegration"; // Instancd ID of guest WebContents. -const char kGuestInstanceID[] = "guest-instance-id"; +const char kGuestInstanceID[] = "guestInstanceId"; // Web runtime features. -const char kExperimentalFeatures[] = "experimental-features"; -const char kExperimentalCanvasFeatures[] = "experimental-canvas-features"; -const char kOverlayScrollbars[] = "overlay-scrollbars"; -const char kOverlayFullscreenVideo[] = "overlay-fullscreen-video"; -const char kSharedWorker[] = "shared-worker"; +const char kExperimentalFeatures[] = "experimentalFeatures"; +const char kExperimentalCanvasFeatures[] = "experimentalCanvasFeatures"; +const char kOverlayScrollbars[] = "overlayScrollbars"; +const char kOverlayFullscreenVideo[] = "overlayFullscreenVideo"; +const char kSharedWorker[] = "sharedWorker"; // Enable plugins. const char kEnablePlugins[] = "enable-plugins"; diff --git a/atom/renderer/lib/init.coffee b/atom/renderer/lib/init.coffee index b7224b39aeed..ed3482fb972b 100644 --- a/atom/renderer/lib/init.coffee +++ b/atom/renderer/lib/init.coffee @@ -25,10 +25,10 @@ v8Util.setHiddenValue global, 'ipc', new events.EventEmitter # Process command line arguments. nodeIntegration = 'false' for arg in process.argv - if arg.indexOf('--guest-instance-id=') == 0 + if arg.indexOf('--guestInstanceId=') == 0 # This is a guest web view. process.guestInstanceId = parseInt arg.substr(arg.indexOf('=') + 1) - else if arg.indexOf('--node-integration=') == 0 + else if arg.indexOf('--nodeIntegration=') == 0 nodeIntegration = arg.substr arg.indexOf('=') + 1 else if arg.indexOf('--preload=') == 0 preloadScript = arg.substr arg.indexOf('=') + 1 diff --git a/spec/chromium-spec.coffee b/spec/chromium-spec.coffee index a034f9378235..09bae3d92e7e 100644 --- a/spec/chromium-spec.coffee +++ b/spec/chromium-spec.coffee @@ -70,7 +70,7 @@ describe 'chromium feature', -> b.close() done() window.addEventListener 'message', listener - b = window.open "file://#{fixtures}/pages/window-opener-node.html", '', 'node-integration=no,show=no' + b = window.open "file://#{fixtures}/pages/window-opener-node.html", '', 'nodeIntegration=no,show=no' it 'inherit options of parent window', (done) -> listener = (event) -> From 5cca947f4d94e1fdd6c8d50a6b362cf5a6937f66 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Wed, 11 Nov 2015 00:26:17 +0800 Subject: [PATCH 111/249] Remove unneeded override code --- atom/renderer/lib/override.coffee | 6 ------ 1 file changed, 6 deletions(-) diff --git a/atom/renderer/lib/override.coffee b/atom/renderer/lib/override.coffee index e54a0e9685c2..729de8ed64d2 100644 --- a/atom/renderer/lib/override.coffee +++ b/atom/renderer/lib/override.coffee @@ -60,12 +60,6 @@ window.open = (url, frameName='', features='') -> (options[name] = parseInt(options[name], 10) if options[name]?) for name in ints - # Inherit the node-integration option of current window. - unless options['node-integration']? - for arg in process.argv when arg.indexOf('--node-integration=') is 0 - options['node-integration'] = arg.substr(-4) is 'true' - break - guestId = ipc.sendSync 'ATOM_SHELL_GUEST_WINDOW_MANAGER_WINDOW_OPEN', url, frameName, options if guestId new BrowserWindowProxy(guestId) From 960d325a58f636a676d3e67251542a1624785536 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Wed, 11 Nov 2015 00:26:46 +0800 Subject: [PATCH 112/249] Be compatible with old BrowserWindow options --- atom/browser/api/atom_api_window.cc | 54 +++++++++++++++++++++++++++-- vendor/native_mate | 2 +- 2 files changed, 52 insertions(+), 4 deletions(-) diff --git a/atom/browser/api/atom_api_window.cc b/atom/browser/api/atom_api_window.cc index bd24b444db3a..048a8eff1df9 100644 --- a/atom/browser/api/atom_api_window.cc +++ b/atom/browser/api/atom_api_window.cc @@ -3,6 +3,7 @@ // found in the LICENSE file. #include "atom/browser/api/atom_api_window.h" +#include "atom/common/native_mate_converters/value_converter.h" #include "atom/browser/api/atom_api_menu.h" #include "atom/browser/api/atom_api_web_contents.h" @@ -60,10 +61,54 @@ void OnCapturePageDone( callback.Run(gfx::Image::CreateFrom1xBitmap(bitmap)); } -// Convert min-width to minWidth recursively in the dictionary. +// Converts min-width to minWidth, returns false if no conversion is needed. +bool TranslateOldKey(const std::string& key, std::string* new_key) { + if (key.find('-') == std::string::npos) + return false; + new_key->reserve(key.size()); + bool next_upper_case = false; + for (char c : key) { + if (c == '-') { + next_upper_case = true; + } else if (next_upper_case) { + new_key->push_back(base::ToUpperASCII(c)); + next_upper_case = false; + } else { + new_key->push_back(c); + } + } + return true; +} + +// Converts min-width to minWidth recursively in the dictionary. +void TranslateOldOptions(v8::Isolate* isolate, v8::Local options) { + auto context = isolate->GetCurrentContext(); + auto maybe_keys = options->GetOwnPropertyNames(context); + if (maybe_keys.IsEmpty()) + return; + std::vector keys; + if (!mate::ConvertFromV8(isolate, maybe_keys.ToLocalChecked(), &keys)) + return; + mate::Dictionary dict(isolate, options); + for (const auto& key : keys) { + v8::Local value; + if (!dict.Get(key, &value)) // Shouldn't happen, but guard it anyway. + continue; + // Go recursively. + v8::Local sub_options; + if (mate::ConvertFromV8(isolate, value, &sub_options)) + TranslateOldOptions(isolate, sub_options); + // Translate key. + std::string new_key; + if (TranslateOldKey(key, &new_key)) { + dict.Set(new_key, value); + dict.Delete(key); + } + } +} #if defined(OS_WIN) -// Convert binary data to Buffer. +// Converts binary data to Buffer. v8::Local ToBuffer(v8::Isolate* isolate, void* val, int size) { auto buffer = node::Buffer::New(isolate, static_cast(val), size); if (buffer.IsEmpty()) @@ -77,7 +122,10 @@ v8::Local ToBuffer(v8::Isolate* isolate, void* val, int size) { Window::Window(v8::Isolate* isolate, const mate::Dictionary& options) { - // Use options['web-preferences'] to create WebContents. + // Be compatible with old style field names like min-width. + TranslateOldOptions(isolate, options.GetHandle()); + + // Use options.webPreferences to create WebContents. mate::Dictionary web_preferences = mate::Dictionary::CreateEmpty(isolate); options.Get(switches::kWebPreferences, &web_preferences); diff --git a/vendor/native_mate b/vendor/native_mate index 21cda4e7fcff..93984941005b 160000 --- a/vendor/native_mate +++ b/vendor/native_mate @@ -1 +1 @@ -Subproject commit 21cda4e7fcff592f33f989c1fea575658281711d +Subproject commit 93984941005bab194a2d47aff655d525c064efcb From b807685453b06d3192a788c7fa24ca0fceff8f14 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Wed, 11 Nov 2015 00:27:08 +0800 Subject: [PATCH 113/249] Deep copy the options Otherwise a window's options is possible to be affected by others. --- atom/browser/lib/guest-window-manager.coffee | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/atom/browser/lib/guest-window-manager.coffee b/atom/browser/lib/guest-window-manager.coffee index f2c5fe3a43cd..3ed8932d444c 100644 --- a/atom/browser/lib/guest-window-manager.coffee +++ b/atom/browser/lib/guest-window-manager.coffee @@ -4,15 +4,24 @@ BrowserWindow = require 'browser-window' frameToGuest = {} +# Copy attribute of |parent| to |child| if it is not defined in |child|. +mergeOptions = (child, parent) -> + for own key, value of parent when key not in child + if typeof value is 'object' + child[key] = mergeOptions {}, value + else + child[key] = value + child + # Merge |options| with the |embedder|'s window's options. mergeBrowserWindowOptions = (embedder, options) -> if embedder.browserWindowOptions? # Inherit the original options if it is a BrowserWindow. - options.__proto__ = embedder.browserWindowOptions + mergeOptions options, embedder.browserWindowOptions else # Or only inherit web-preferences if it is a webview. options.webPreferences ?= {} - options.webPreferences.__proto__ = embedder.getWebPreferences() + mergeOptions options.webPreferences, embedder.getWebPreferences() options # Create a new guest created by |embedder| with |options|. From ba457681b200715068ab0db4e1672ef5e854ff9d Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Wed, 11 Nov 2015 10:32:25 +0800 Subject: [PATCH 114/249] Avoid storing unrelated things in WebContentsPreferences --- atom/browser/api/atom_api_web_contents.cc | 4 +--- atom/browser/web_contents_preferences.cc | 16 +++++++++++----- atom/browser/web_contents_preferences.h | 6 +++++- 3 files changed, 17 insertions(+), 9 deletions(-) diff --git a/atom/browser/api/atom_api_web_contents.cc b/atom/browser/api/atom_api_web_contents.cc index 5165877d1670..d67794a91aeb 100644 --- a/atom/browser/api/atom_api_web_contents.cc +++ b/atom/browser/api/atom_api_web_contents.cc @@ -269,9 +269,7 @@ WebContents::WebContents(v8::Isolate* isolate, managed_web_contents()->GetView()->SetDelegate(this); // Save the preferences in C++. - base::DictionaryValue web_preferences; - mate::ConvertFromV8(isolate, options.GetHandle(), &web_preferences); - new WebContentsPreferences(web_contents, &web_preferences); + new WebContentsPreferences(web_contents, options); web_contents->SetUserAgentOverride(GetBrowserContext()->GetUserAgent()); diff --git a/atom/browser/web_contents_preferences.cc b/atom/browser/web_contents_preferences.cc index a0088221ba2c..2adb77211b27 100644 --- a/atom/browser/web_contents_preferences.cc +++ b/atom/browser/web_contents_preferences.cc @@ -6,10 +6,12 @@ #include +#include "atom/common/native_mate_converters/value_converter.h" #include "atom/common/options_switches.h" #include "base/command_line.h" #include "base/strings/string_number_conversions.h" #include "content/public/common/web_preferences.h" +#include "native_mate/dictionary.h" #include "net/base/filename_util.h" #if defined(OS_WIN) @@ -36,12 +38,16 @@ const char* kWebRuntimeFeatures[] = { WebContentsPreferences::WebContentsPreferences( content::WebContents* web_contents, - base::DictionaryValue* web_preferences) { - web_preferences_.Swap(web_preferences); - web_contents->SetUserData(UserDataKey(), this); + const mate::Dictionary& web_preferences) { + v8::Isolate* isolate = web_preferences.isolate(); + mate::Dictionary copied(isolate, web_preferences.GetHandle()->Clone()); + // Following fields should not be stored. + copied.Delete("embedder"); + copied.Delete("isGuest"); + copied.Delete("session"); - // The "isGuest" is not a preferences field. - web_preferences_.Remove("isGuest", nullptr); + mate::ConvertFromV8(isolate, copied.GetHandle(), &web_preferences_); + web_contents->SetUserData(UserDataKey(), this); } WebContentsPreferences::~WebContentsPreferences() { diff --git a/atom/browser/web_contents_preferences.h b/atom/browser/web_contents_preferences.h index 3e36df021478..8b04f9ee24e6 100644 --- a/atom/browser/web_contents_preferences.h +++ b/atom/browser/web_contents_preferences.h @@ -16,6 +16,10 @@ namespace content { struct WebPreferences; } +namespace mate { +class Dictionary; +} + namespace atom { // Stores and applies the preferences of WebContents. @@ -31,7 +35,7 @@ class WebContentsPreferences content::WebContents* web_contents, content::WebPreferences* prefs); WebContentsPreferences(content::WebContents* web_contents, - base::DictionaryValue* web_preferences); + const mate::Dictionary& web_preferences); ~WebContentsPreferences() override; // $.extend(|web_preferences_|, |new_web_preferences|). From 60ec1ca3f71d9e3ee08eb9e4b868a492d6073d20 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Wed, 11 Nov 2015 10:33:59 +0800 Subject: [PATCH 115/249] Use new styles of browserWindow options --- atom/browser/default_app/default_app.js | 4 ++-- spec/api-browser-window-spec.coffee | 20 ++++++++++---------- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/atom/browser/default_app/default_app.js b/atom/browser/default_app/default_app.js index 2378902b44ec..de8b14d5f4d7 100644 --- a/atom/browser/default_app/default_app.js +++ b/atom/browser/default_app/default_app.js @@ -12,8 +12,8 @@ app.on('ready', function() { mainWindow = new BrowserWindow({ width: 800, height: 600, - 'auto-hide-menu-bar': true, - 'use-content-size': true, + autoHideMenuBar: true, + useContentSize: true, }); mainWindow.loadUrl('file://' + __dirname + '/index.html'); mainWindow.focus(); diff --git a/spec/api-browser-window-spec.coffee b/spec/api-browser-window-spec.coffee index 460a1c1ec17c..4528ab72b660 100644 --- a/spec/api-browser-window-spec.coffee +++ b/spec/api-browser-window-spec.coffee @@ -138,10 +138,10 @@ describe 'browser-window module', -> w.setResizable not w.isResizable() assert.deepEqual s, w.getSize() - describe '"use-content-size" option', -> + describe '"useContentSize" option', -> it 'make window created with content size when used', -> w.destroy() - w = new BrowserWindow(show: false, width: 400, height: 400, 'use-content-size': true) + w = new BrowserWindow(show: false, width: 400, height: 400, useContentSize: true) contentSize = w.getContentSize() assert.equal contentSize[0], 400 assert.equal contentSize[1], 400 @@ -153,7 +153,7 @@ describe 'browser-window module', -> it 'works for framless window', -> w.destroy() - w = new BrowserWindow(show: false, frame: false, width: 400, height: 400, 'use-content-size': true) + w = new BrowserWindow(show: false, frame: false, width: 400, height: 400, useContentSize: true) contentSize = w.getContentSize() assert.equal contentSize[0], 400 assert.equal contentSize[1], 400 @@ -167,22 +167,22 @@ describe 'browser-window module', -> it 'creates browser window with hidden title bar', -> w.destroy() - w = new BrowserWindow(show: false, width: 400, height: 400, 'title-bar-style': 'hidden') + w = new BrowserWindow(show: false, width: 400, height: 400, titleBarStyle: 'hidden') contentSize = w.getContentSize() assert.equal contentSize[1], 400 it 'creates browser window with hidden inset title bar', -> w.destroy() - w = new BrowserWindow(show: false, width: 400, height: 400, 'title-bar-style': 'hidden-inset') + w = new BrowserWindow(show: false, width: 400, height: 400, titleBarStyle: 'hidden-inset') contentSize = w.getContentSize() assert.equal contentSize[1], 400 - describe '"enable-larger-than-screen" option', -> + describe '"enableLargerThanScreen" option', -> return if process.platform is 'linux' beforeEach -> w.destroy() - w = new BrowserWindow(show: true, width: 400, height: 400, 'enable-larger-than-screen': true) + w = new BrowserWindow(show: true, width: 400, height: 400, enableLargerThanScreen: true) it 'can move the window out of screen', -> w.setPosition -10, -10 @@ -212,7 +212,7 @@ describe 'browser-window module', -> w.destroy() w = new BrowserWindow show: false - 'web-preferences': + webPreferences: preload: preload w.loadUrl 'file://' + path.join(fixtures, 'api', 'preload.html') @@ -225,9 +225,9 @@ describe 'browser-window module', -> w.destroy() w = new BrowserWindow show: false - 'web-preferences': + webPreferences: preload: preload - 'node-integration': false + nodeIntegration: false w.loadUrl 'file://' + path.join(fixtures, 'api', 'blank.html') describe 'beforeunload handler', -> From f63a4a05b79c063bc81ebd75fc66ae4904c3a758 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Wed, 11 Nov 2015 10:37:01 +0800 Subject: [PATCH 116/249] spec: Make the crash-reporter test more reliable --- spec/api-crash-reporter-spec.coffee | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/spec/api-crash-reporter-spec.coffee b/spec/api-crash-reporter-spec.coffee index 5e06cade8cec..6232edfd3b6c 100644 --- a/spec/api-crash-reporter-spec.coffee +++ b/spec/api-crash-reporter-spec.coffee @@ -24,10 +24,15 @@ describe 'crash-reporter module', -> it 'should send minidump when renderer crashes', (done) -> @timeout 120000 + called = false server = http.createServer (req, res) -> server.close() form = new multiparty.Form() form.parse req, (error, fields, files) -> + # This callback can be called for twice sometimes. + return if called + called = true + assert.equal fields['prod'], 'Electron' assert.equal fields['ver'], process.versions['electron'] assert.equal fields['process_type'], 'renderer' From 0e9415a256764a84595489843c12b5f7e80df64f Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Wed, 11 Nov 2015 22:55:32 +0800 Subject: [PATCH 117/249] docs: More notes on --proxy-server, close #3390 --- docs/api/chrome-command-line-switches.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/docs/api/chrome-command-line-switches.md b/docs/api/chrome-command-line-switches.md index 69e785f79e72..96dffb963135 100644 --- a/docs/api/chrome-command-line-switches.md +++ b/docs/api/chrome-command-line-switches.md @@ -33,8 +33,10 @@ Enables remote debugging over HTTP on the specified `port`. ## --proxy-server=`address:port` -Use a specified proxy server, which overrides the system setting. This switch only -affects HTTP and HTTPS requests. +Use a specified proxy server, which overrides the system setting. This switch +only affects requests with HTTP protocol, including HTTPS and WebSocket +requests. It is also noteworthy that not all proxy servers support HTTPS and +WebSocket requests. ## --proxy-pac-url=`url` From 28db51ad8340cb68313bb80893ddf3ae8c9b5a54 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Wed, 11 Nov 2015 23:55:43 +0800 Subject: [PATCH 118/249] docs: Update BrowserWindow's options --- docs/api/browser-window.md | 60 +++++++++++++++++++------------------- 1 file changed, 30 insertions(+), 30 deletions(-) diff --git a/docs/api/browser-window.md b/docs/api/browser-window.md index fbac6b10863b..0499b6355a00 100644 --- a/docs/api/browser-window.md +++ b/docs/api/browser-window.md @@ -33,20 +33,20 @@ It creates a new `BrowserWindow` with native properties as set by the `options`. * `height` Integer - Window's height. * `x` Integer - Window's left offset from screen. * `y` Integer - Window's top offset from screen. -* `use-content-size` Boolean - The `width` and `height` would be used as web +* `useContentSize` Boolean - The `width` and `height` would be used as web page's size, which means the actual window's size will include window frame's size and be slightly larger. * `center` Boolean - Show window in the center of the screen. -* `min-width` Integer - Window's minimum width. -* `min-height` Integer - Window's minimum height. -* `max-width` Integer - Window's maximum width. -* `max-height` Integer - Window's maximum height. +* `minWidth` Integer - Window's minimum width. +* `minHeight` Integer - Window's minimum height. +* `maxWidth` Integer - Window's maximum width. +* `maxHeight` Integer - Window's maximum height. * `resizable` Boolean - Whether window is resizable. -* `always-on-top` Boolean - Whether the window should always stay on top of +* `alwaysOnTop` Boolean - Whether the window should always stay on top of other windows. * `fullscreen` Boolean - Whether the window should show in fullscreen. When set to `false` the fullscreen button will be hidden or disabled on OS X. -* `skip-taskbar` Boolean - Whether to show the window in taskbar. +* `skipTaskbar` Boolean - Whether to show the window in taskbar. * `kiosk` Boolean - The kiosk mode. * `title` String - Default window title. * `icon` [NativeImage](native-image.md) - The window icon, when omitted on @@ -54,24 +54,24 @@ It creates a new `BrowserWindow` with native properties as set by the `options`. * `show` Boolean - Whether window should be shown when created. * `frame` Boolean - Specify `false` to create a [Frameless Window](frameless-window.md). -* `accept-first-mouse` Boolean - Whether the web view accepts a single +* `acceptFirstMouse` Boolean - Whether the web view accepts a single mouse-down event that simultaneously activates the window. -* `disable-auto-hide-cursor` Boolean - Whether to hide cursor when typing. -* `auto-hide-menu-bar` Boolean - Auto hide the menu bar unless the `Alt` +* `disableAutoHideCursor` Boolean - Whether to hide cursor when typing. +* `autoHideMenuBar` Boolean - Auto hide the menu bar unless the `Alt` key is pressed. -* `enable-larger-than-screen` Boolean - Enable the window to be resized larger +* `enableLargerThanScreen` Boolean - Enable the window to be resized larger than screen. -* `background-color` String - Window's background color as Hexadecimal value, +* `backgroundColor` String - Window's background color as Hexadecimal value, like `#66CD00` or `#FFF`. This is only implemented on Linux and Windows. -* `dark-theme` Boolean - Forces using dark theme for the window, only works on +* `darkTheme` Boolean - Forces using dark theme for the window, only works on some GTK+3 desktop environments. * `transparent` Boolean - Makes the window [transparent](frameless-window.md). * `type` String - Specifies the type of the window, possible types are `desktop`, `dock`, `toolbar`, `splash`, `notification`. This only works on Linux. -* `standard-window` Boolean - Uses the OS X's standard window instead of the +* `standardWindow` Boolean - Uses the OS X's standard window instead of the textured window. Defaults to `true`. -* `title-bar-style` String, OS X - specifies the style of window title bar. +* `titleBarStyle` String, OS X - specifies the style of window title bar. This option is supported on OS X 10.10 Yosemite and newer. There are three possible values: * `default` or not specified results in the standard gray opaque Mac title @@ -81,8 +81,8 @@ It creates a new `BrowserWindow` with native properties as set by the `options`. the top left. * `hidden-inset` results in a hidden title bar with an alternative look where the traffic light buttons are slightly more inset from the window edge. -* `web-preferences` Object - Settings of web page's features, properties: - * `node-integration` Boolean - Whether node integration is enabled. Default +* `webPreferences` Object - Settings of web page's features, properties: + * `nodeIntegration` Boolean - Whether node integration is enabled. Default is `true`. * `preload` String - Specifies a script that will be loaded before other scripts run in the page. This script will always have access to node APIs @@ -94,31 +94,31 @@ It creates a new `BrowserWindow` with native properties as set by the `options`. prefix, the page will use an in-memory session. By assigning the same `partition`, multiple pages can share the same session. If the `partition` is unset then default session of the app will be used. - * `zoom-factor` Number - The default zoom factor of the page, `3.0` represents + * `zoomFactor` Number - The default zoom factor of the page, `3.0` represents `300%`. * `javascript` Boolean - * `web-security` Boolean - When setting `false`, it will disable the + * `webSecurity` Boolean - When setting `false`, it will disable the same-origin policy (Usually using testing websites by people), and set - `allow_displaying_insecure_content` and `allow_running_insecure_content` to + `allowDisplayingInsecureContent` and `allowRunningInsecureContent` to `true` if these two options are not set by user. - * `allow-displaying-insecure-content` Boolean - Allow an https page to display + * `allowDisplayingInsecureContent` Boolean - Allow an https page to display content like images from http URLs. - * `allow-running-insecure-content` Boolean - Allow a https page to run + * `allowRunningInsecureContent` Boolean - Allow a https page to run JavaScript, CSS or plugins from http URLs. * `images` Boolean * `java` Boolean - * `text-areas-are-resizable` Boolean + * `textAreasAreResizable` Boolean * `webgl` Boolean * `webaudio` Boolean * `plugins` Boolean - Whether plugins should be enabled. - * `experimental-features` Boolean - * `experimental-canvas-features` Boolean - * `overlay-scrollbars` Boolean - * `overlay-fullscreen-video` Boolean - * `shared-worker` Boolean - * `direct-write` Boolean - Whether the DirectWrite font rendering system on + * `experimentalFeatures` Boolean + * `experimentalCanvasFeatures` Boolean + * `overlayScrollbars` Boolean + * `overlayFullscreenVideo` Boolean + * `sharedWorker` Boolean + * `directWrite` Boolean - Whether the DirectWrite font rendering system on Windows is enabled. - * `page-visibility` Boolean - Page would be forced to be always in visible + * `pageVisibility` Boolean - Page would be forced to be always in visible or hidden state once set, instead of reflecting current window's visibility. Users can set it to `true` to prevent throttling of DOM timers. From ca49ddc95dbc25e641e5258980dc4ee4673e1a23 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Thu, 12 Nov 2015 09:49:05 +0800 Subject: [PATCH 119/249] Update brightray --- vendor/brightray | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vendor/brightray b/vendor/brightray index 4e069f1806ef..10ea3c5207dc 160000 --- a/vendor/brightray +++ b/vendor/brightray @@ -1 +1 @@ -Subproject commit 4e069f1806efe5da9a965e61f329b19b7791104a +Subproject commit 10ea3c5207dc18b3103aaf6e457193f8454becf1 From 020214ff951ff837f83247621b762689f1b1fa21 Mon Sep 17 00:00:00 2001 From: Plusb Preco Date: Thu, 12 Nov 2015 12:24:28 +0900 Subject: [PATCH 120/249] Update as upstream --- .../ko-KR/api/chrome-command-line-switches.md | 4 ++++ docs-translations/ko-KR/api/tray.md | 16 ++++++++++++++++ .../tutorial/using-selenium-and-webdriver.md | 19 ++++++++++++++----- 3 files changed, 34 insertions(+), 5 deletions(-) diff --git a/docs-translations/ko-KR/api/chrome-command-line-switches.md b/docs-translations/ko-KR/api/chrome-command-line-switches.md index 5b055c49ec9d..aea9c49a1021 100644 --- a/docs-translations/ko-KR/api/chrome-command-line-switches.md +++ b/docs-translations/ko-KR/api/chrome-command-line-switches.md @@ -34,6 +34,10 @@ HTTP 요청 캐시를 비활성화 합니다. 시스템 설정의 프록시 서버를 무시하고 지정한 서버로 연결합니다. HTTP와 HTTPS 요청에만 적용됩니다. +시스템 프록시 서버 설정을 무시하고 지정한 서버로 연결합니다. +이 스위치는 HTTP와 HTTPS 그리고 WebSocket 요청에만 적용됩니다. +그리고 모든 프록시 서버가 HTTPS가 WebSocket 요청을 지원하지 않고 있을 수 있으므로 사용시 주의해야 합니다. + ## --proxy-pac-url=`url` 지정한 `url`의 PAC 스크립트를 사용합니다. diff --git a/docs-translations/ko-KR/api/tray.md b/docs-translations/ko-KR/api/tray.md index cd821f581b32..22fec3089e69 100644 --- a/docs-translations/ko-KR/api/tray.md +++ b/docs-translations/ko-KR/api/tray.md @@ -107,6 +107,10 @@ __주의:__ `bounds`는 OS X 와 Windows에서만 작동합니다. 알림풍선이 시간이 지나 사라지거나 유저가 클릭하여 닫을 때 발생하는 이벤트입니다. +### Event: 'drop' _OS X_ + +드래그 가능한 아이템이 트레이 아이콘에 드롭되면 발생하는 이벤트입니다. + ### Event: 'drop-files' _OS X_ * `event` @@ -114,6 +118,18 @@ __주의:__ `bounds`는 OS X 와 Windows에서만 작동합니다. 트레이 아이콘에 파일이 드롭되면 발생하는 이벤트입니다. +### Event: 'drag-enter' _OS X_ + +트레이 아이콘에 드래그 작업이 시작될 때 발생하는 이벤트입니다. + +### Event: 'drag-leave' _OS X_ + +트레이 아이콘에 드래그 작업이 종료될 때 발생하는 이벤트입니다. + +### Event: 'drag-end' _OS X_ + +트레이 아이콘에 드래그 작업이 종료되거나 다른 위치에서 종료될 때 발생하는 이벤트입니다. + ## Methods `Tray` 모듈은 다음과 같은 메서드를 가지고 있습니다: diff --git a/docs-translations/ko-KR/tutorial/using-selenium-and-webdriver.md b/docs-translations/ko-KR/tutorial/using-selenium-and-webdriver.md index a9fd84a68bc2..52e6d28307c9 100644 --- a/docs-translations/ko-KR/tutorial/using-selenium-and-webdriver.md +++ b/docs-translations/ko-KR/tutorial/using-selenium-and-webdriver.md @@ -44,9 +44,12 @@ var webdriver = require('selenium-webdriver'); var driver = new webdriver.Builder() // 작동하고 있는 크롬 드라이버의 포트 "9515"를 사용합니다. .usingServer('http://localhost:9515') - .withCapabilities({chromeOptions: { - // 여기에 사용중인 Electron 바이너리의 경로를 지정하세요. - binary: '/Path-to-Your-App.app/Contents/MacOS/Atom'}}) + .withCapabilities({ + chromeOptions: { + // 여기에 사용중인 Electron 바이너리의 경로를 지정하세요. + binary: '/Path-to-Your-App.app/Contents/MacOS/Atom', + } + }) .forBrowser('electron') .build(); @@ -92,7 +95,10 @@ var options = { port: 9515, // 연결할 크롬 드라이버 서버의 포트를 설정합니다. desiredCapabilities: { browserName: 'chrome', - chromeOptions: {binary: '/Path-to-Your-App.app/Electron'} // Electron 바이너리의 위치 + chromeOptions: { + binary: '/Path-to-Your-App/electron', // Electron 바이너리 경로 + args: [/* cli arguments */] // 선택 사항, 'app=' + /path/to/your/app/ + } } }; @@ -109,9 +115,12 @@ client .end(); ``` -## 작업환경 +## 작업 환경 따로 Electron을 다시 빌드하지 않는 경우 간단히 어플리케이션을 Electron의 리소스 디렉터리에 [배치](application-distribution.md)하여 바로 테스트 할 수 있습니다. +또한, Electron 바이너리의 명령줄 인수에 어플리케이션 폴더를 지정하는 방법으로 실행할 수도 있습니다. +이 방법을 사용하면 어플리케이션 폴더를 Electron의 `resource` 디렉터리로 복사하는 불필요한 과정을 생략할 수 있습니다. + [chrome-driver]: https://sites.google.com/a/chromium.org/chromedriver/ From ce0167756e2a587eea6a31c6fad7660a68fab8f5 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Thu, 12 Nov 2015 16:27:28 +0800 Subject: [PATCH 121/249] Update node for atom/node#13 --- vendor/node | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vendor/node b/vendor/node index edfbc29d0942..1445826ca73c 160000 --- a/vendor/node +++ b/vendor/node @@ -1 +1 @@ -Subproject commit edfbc29d09425f2f387c52d77f6351b6ce101659 +Subproject commit 1445826ca73cc79bc57d503dd11d4ffaf695625c From c2c09daa236bc57c7bb79cbae617fc6ca72842da Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Thu, 12 Nov 2015 16:28:22 +0800 Subject: [PATCH 122/249] Add "electron" module --- atom/browser/api/lib/exports/electron.coffee | 47 +++++++++++++++++++ atom/browser/lib/init.coffee | 1 + atom/common/api/lib/exports/electron.coffee | 15 ++++++ atom/renderer/api/lib/exports/electron.coffee | 17 +++++++ atom/renderer/lib/init.coffee | 1 + filenames.gypi | 3 ++ 6 files changed, 84 insertions(+) create mode 100644 atom/browser/api/lib/exports/electron.coffee create mode 100644 atom/common/api/lib/exports/electron.coffee create mode 100644 atom/renderer/api/lib/exports/electron.coffee diff --git a/atom/browser/api/lib/exports/electron.coffee b/atom/browser/api/lib/exports/electron.coffee new file mode 100644 index 000000000000..6c7929706cc6 --- /dev/null +++ b/atom/browser/api/lib/exports/electron.coffee @@ -0,0 +1,47 @@ +# Import common modules. +module.exports = require '../../../../common/api/lib/exports/electron' + +Object.defineProperties module.exports, + # Browser side modules, please sort with alphabet order. + app: + enumerable: true + get: -> require '../app' + autoUpdater: + enumerable: true + get: -> require '../auto-updater' + BrowserWindow: + enumerable: true + get: -> require '../browser-window' + contentTracing: + enumerable: true + get: -> require '../content-tracing' + dialog: + enumerable: true + get: -> require '../dialog' + ipcMain: + enumerable: true + get: -> require '../ipc-main' + globalShortcut: + enumerable: true + get: -> require '../global-shortcut' + Menu: + enumerable: true + get: -> require '../menu' + MenuItem: + enumerable: true + get: -> require '../menu-item' + powerMonitor: + enumerable: true + get: -> require '../power-monitor' + powerSaveBlocker: + enumerable: true + get: -> require '../power-save-blocker' + protocol: + enumerable: true + get: -> require '../protocol' + screen: + enumerable: true + get: -> require '../screen' + tray: + enumerable: true + get: -> require '../tray' diff --git a/atom/browser/lib/init.coffee b/atom/browser/lib/init.coffee index 80d2da31b705..fd6059bd739d 100644 --- a/atom/browser/lib/init.coffee +++ b/atom/browser/lib/init.coffee @@ -17,6 +17,7 @@ require path.resolve(__dirname, '..', '..', 'common', 'lib', 'init') # Electron's built-in libraries. globalPaths = Module.globalPaths globalPaths.push path.resolve(__dirname, '..', 'api', 'lib') +globalPaths.push path.resolve(__dirname, '..', 'api', 'lib', 'exports') if process.platform is 'win32' # Redirect node's console to use our own implementations, since node can not diff --git a/atom/common/api/lib/exports/electron.coffee b/atom/common/api/lib/exports/electron.coffee new file mode 100644 index 000000000000..a57d5be94c22 --- /dev/null +++ b/atom/common/api/lib/exports/electron.coffee @@ -0,0 +1,15 @@ +Object.defineProperties exports, + # Common modules, please sort with alphabet order. + clipboard: + # Must be enumerable, otherwise it woulde be invisible to remote module. + enumerable: true + get: -> require '../clipboard' + crashRepoter: + enumerable: true + get: -> require '../crash-reporter' + nativeImage: + enumerable: true + get: -> require '../native-image' + shell: + enumerable: true + get: -> require '../shell' diff --git a/atom/renderer/api/lib/exports/electron.coffee b/atom/renderer/api/lib/exports/electron.coffee new file mode 100644 index 000000000000..5d7f2a57edd0 --- /dev/null +++ b/atom/renderer/api/lib/exports/electron.coffee @@ -0,0 +1,17 @@ +# Import common modules. +module.exports = require '../../../../common/api/lib/exports/electron' + +Object.defineProperties module.exports, + # Renderer side modules, please sort with alphabet order. + ipcRenderer: + enumerable: true + get: -> require '../ipc-renderer' + remote: + enumerable: true + get: -> require '../remote' + screen: + enumerable: true + get: -> require '../screen' + webFrame: + enumerable: true + get: -> require '../web-frame' diff --git a/atom/renderer/lib/init.coffee b/atom/renderer/lib/init.coffee index ed3482fb972b..4779794278c2 100644 --- a/atom/renderer/lib/init.coffee +++ b/atom/renderer/lib/init.coffee @@ -17,6 +17,7 @@ require path.resolve(__dirname, '..', '..', 'common', 'lib', 'init') # of Atom's built-in libraries. globalPaths = Module.globalPaths globalPaths.push path.resolve(__dirname, '..', 'api', 'lib') +globalPaths.push path.resolve(__dirname, '..', 'api', 'lib', 'exports') # The global variable will be used by ipc for event dispatching v8Util = process.atomBinding 'v8_util' diff --git a/filenames.gypi b/filenames.gypi index 4dc709c5ec57..de7ee26c5e41 100644 --- a/filenames.gypi +++ b/filenames.gypi @@ -16,6 +16,7 @@ 'atom/browser/api/lib/browser-window.coffee', 'atom/browser/api/lib/content-tracing.coffee', 'atom/browser/api/lib/dialog.coffee', + 'atom/browser/api/lib/exports/electron.coffee', 'atom/browser/api/lib/global-shortcut.coffee', 'atom/browser/api/lib/ipc.coffee', 'atom/browser/api/lib/ipc-main.coffee', @@ -38,6 +39,7 @@ 'atom/common/api/lib/clipboard.coffee', 'atom/common/api/lib/crash-reporter.coffee', 'atom/common/api/lib/deprecate.coffee', + 'atom/common/api/lib/exports/electron.coffee', 'atom/common/api/lib/native-image.coffee', 'atom/common/api/lib/shell.coffee', 'atom/common/lib/init.coffee', @@ -50,6 +52,7 @@ 'atom/renderer/lib/web-view/web-view.coffee', 'atom/renderer/lib/web-view/web-view-attributes.coffee', 'atom/renderer/lib/web-view/web-view-constants.coffee', + 'atom/renderer/api/lib/exports/electron.coffee', 'atom/renderer/api/lib/ipc.coffee', 'atom/renderer/api/lib/ipc-renderer.coffee', 'atom/renderer/api/lib/remote.coffee', From f9d7e7ce559d28307058cf196e280e8e2d2eed0e Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Thu, 12 Nov 2015 17:02:04 +0800 Subject: [PATCH 123/249] Add ELECTRON_DISABLE_OLD_STYLE_MODULES env --- atom/browser/lib/init.coffee | 7 ++++--- atom/common/lib/init.coffee | 5 +++-- atom/renderer/lib/init.coffee | 7 ++++--- 3 files changed, 11 insertions(+), 8 deletions(-) diff --git a/atom/browser/lib/init.coffee b/atom/browser/lib/init.coffee index fd6059bd739d..a9092e3f9513 100644 --- a/atom/browser/lib/init.coffee +++ b/atom/browser/lib/init.coffee @@ -13,12 +13,13 @@ require path.resolve(__dirname, '..', '..', 'common', 'lib', 'reset-search-paths # Import common settings. require path.resolve(__dirname, '..', '..', 'common', 'lib', 'init') -# Add browser/api/lib to module search paths, which contains javascript part of -# Electron's built-in libraries. +# Expose public APIs. globalPaths = Module.globalPaths -globalPaths.push path.resolve(__dirname, '..', 'api', 'lib') globalPaths.push path.resolve(__dirname, '..', 'api', 'lib', 'exports') +unless process.env.ELECTRON_DISABLE_OLD_STYLE_MODULES + globalPaths.push path.resolve(__dirname, '..', 'api', 'lib') + if process.platform is 'win32' # Redirect node's console to use our own implementations, since node can not # handle console output when running as GUI program. diff --git a/atom/common/lib/init.coffee b/atom/common/lib/init.coffee index 1c80e6171a4d..a92871994da1 100644 --- a/atom/common/lib/init.coffee +++ b/atom/common/lib/init.coffee @@ -9,8 +9,9 @@ process.atomBinding = (name) -> catch e process.binding "atom_common_#{name}" if /No such module/.test e.message -# Add common/api/lib to module search paths. -Module.globalPaths.push path.resolve(__dirname, '..', 'api', 'lib') +unless process.env.ELECTRON_DISABLE_OLD_STYLE_MODULES + # Add common/api/lib to module search paths. + Module.globalPaths.push path.resolve(__dirname, '..', 'api', 'lib') # setImmediate and process.nextTick makes use of uv_check and uv_prepare to # run the callbacks, however since we only run uv loop on requests, the diff --git a/atom/renderer/lib/init.coffee b/atom/renderer/lib/init.coffee index 4779794278c2..4f0e6a328794 100644 --- a/atom/renderer/lib/init.coffee +++ b/atom/renderer/lib/init.coffee @@ -13,12 +13,13 @@ require path.resolve(__dirname, '..', '..', 'common', 'lib', 'reset-search-paths # Import common settings. require path.resolve(__dirname, '..', '..', 'common', 'lib', 'init') -# Add renderer/api/lib to require's search paths, which contains javascript part -# of Atom's built-in libraries. +# Expose public APIs. globalPaths = Module.globalPaths -globalPaths.push path.resolve(__dirname, '..', 'api', 'lib') globalPaths.push path.resolve(__dirname, '..', 'api', 'lib', 'exports') +unless process.env.ELECTRON_DISABLE_OLD_STYLE_MODULES + globalPaths.push path.resolve(__dirname, '..', 'api', 'lib') + # The global variable will be used by ipc for event dispatching v8Util = process.atomBinding 'v8_util' v8Util.setHiddenValue global, 'ipc', new events.EventEmitter From fb5beb9af541d3405329789ad61945c20b03ef39 Mon Sep 17 00:00:00 2001 From: Shawn K Date: Thu, 12 Nov 2015 01:00:41 -0800 Subject: [PATCH 124/249] Add --js-flags support for main thread. Allow use of flags that must be set before V8 is initialized, such as "--harmony_proxies", e.g. --js-flags="--harmony_proxies --harmony_collections" --- atom/browser/javascript_environment.cc | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/atom/browser/javascript_environment.cc b/atom/browser/javascript_environment.cc index cc06bb6ff9c2..ae4f8e55e76e 100644 --- a/atom/browser/javascript_environment.cc +++ b/atom/browser/javascript_environment.cc @@ -2,6 +2,8 @@ // Use of this source code is governed by the MIT license that can be // found in the LICENSE file. +#include + #include "atom/browser/javascript_environment.h" #include "base/command_line.h" @@ -27,8 +29,18 @@ bool JavascriptEnvironment::Initialize() { const char expose_debug_as[] = "--expose_debug_as=v8debug"; v8::V8::SetFlagsFromString(expose_debug_as, sizeof(expose_debug_as) - 1); } + + const std::string js_flags_switch = "js-flags"; + + if (cmd->HasSwitch(js_flags_switch)) { + const char *js_flags_value = + (cmd->GetSwitchValueASCII(js_flags_switch)).c_str(); + v8::V8::SetFlagsFromString(js_flags_value, strlen(js_flags_value)); + } + gin::IsolateHolder::Initialize(gin::IsolateHolder::kNonStrictMode, gin::ArrayBufferAllocator::SharedInstance()); + return true; } From 1d1f911b095ce29206f4b7f74221f3bac7b28e0d Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Thu, 12 Nov 2015 18:28:04 +0800 Subject: [PATCH 125/249] Use require('electron') in Electron's code --- atom/browser/api/lib/app.coffee | 9 ++--- atom/browser/api/lib/browser-window.coffee | 8 ++--- atom/browser/api/lib/dialog.coffee | 4 +-- atom/browser/api/lib/exports/electron.coffee | 5 +++ atom/browser/api/lib/global-shortcut.coffee | 4 +-- atom/browser/api/lib/ipc.coffee | 4 +-- atom/browser/api/lib/menu-item.coffee | 3 +- atom/browser/api/lib/menu.coffee | 7 ++-- .../api/lib/navigation-controller.coffee | 6 ++-- atom/browser/api/lib/power-monitor.coffee | 5 +-- .../browser/api/lib/power-save-blocker.coffee | 4 +-- atom/browser/api/lib/protocol.coffee | 5 +-- atom/browser/api/lib/screen.coffee | 4 +-- atom/browser/api/lib/tray.coffee | 5 ++- atom/browser/api/lib/web-contents.coffee | 11 +++---- atom/browser/default_app/default_app.js | 5 +-- atom/browser/default_app/index.html | 8 +++-- atom/browser/default_app/main.js | 20 ++++++----- atom/browser/lib/chrome-extension.coffee | 6 ++-- atom/browser/lib/guest-view-manager.coffee | 14 ++++---- atom/browser/lib/guest-window-manager.coffee | 17 +++++----- atom/browser/lib/init.coffee | 5 +-- atom/browser/lib/objects-registry.coffee | 2 +- atom/browser/lib/rpc-server.coffee | 31 +++++++++--------- atom/common/api/lib/clipboard.coffee | 3 +- atom/common/api/lib/crash-reporter.coffee | 7 ++-- atom/common/api/lib/exports/electron.coffee | 5 +++ atom/renderer/api/lib/ipc.coffee | 3 +- atom/renderer/api/lib/remote.coffee | 31 +++++++++--------- atom/renderer/api/lib/screen.coffee | 2 +- atom/renderer/lib/inspector.coffee | 8 ++--- atom/renderer/lib/override.coffee | 27 ++++++++------- .../lib/web-view/guest-view-internal.coffee | 27 ++++++++------- .../lib/web-view/web-view-attributes.coffee | 3 +- atom/renderer/lib/web-view/web-view.coffee | 4 +-- spec/api-app-spec.coffee | 5 ++- spec/api-browser-window-spec.coffee | 12 +++---- spec/api-clipboard-spec.coffee | 4 +-- spec/api-crash-reporter-spec.coffee | 7 ++-- spec/api-ipc-spec.coffee | 17 +++++----- spec/api-menu-spec.coffee | 5 ++- spec/api-protocol-spec.coffee | 5 +-- spec/api-screen-spec.coffee | 3 +- spec/api-session-spec.coffee | 16 ++++----- spec/asar-spec.coffee | 18 +++++----- spec/chromium-spec.coffee | 5 +-- spec/fixtures/api/beforeunload-false.html | 2 +- .../api/close-beforeunload-empty-string.html | 2 +- .../api/close-beforeunload-false.html | 2 +- .../api/close-beforeunload-string.html | 2 +- .../fixtures/api/close-beforeunload-true.html | 2 +- spec/fixtures/api/crash.html | 2 +- spec/fixtures/api/localstorage.html | 6 ++-- spec/fixtures/api/preload.html | 2 +- spec/fixtures/api/send-sync-message.html | 4 +-- spec/fixtures/asar/script.asar | Bin 204 -> 221 bytes spec/fixtures/asar/web.asar | Bin 201 -> 218 bytes spec/fixtures/module/preload-ipc.js | 6 ++-- spec/fixtures/module/send-later.js | 4 +-- spec/fixtures/pages/basic-auth.html | 6 ++-- spec/fixtures/pages/beforeunload-false.html | 4 +-- spec/fixtures/pages/document-hidden.html | 2 +- spec/fixtures/pages/history.html | 2 +- spec/fixtures/pages/ipc-message.html | 2 +- spec/fixtures/pages/onkeyup.html | 2 +- spec/fixtures/pages/onmouseup.html | 2 +- spec/fixtures/pages/window-open-size.html | 2 +- spec/fixtures/pages/window-opener.html | 2 +- spec/node-spec.coffee | 3 +- spec/static/index.html | 17 ++++++---- spec/static/main.js | 28 ++++++++-------- 71 files changed, 265 insertions(+), 250 deletions(-) diff --git a/atom/browser/api/lib/app.coffee b/atom/browser/api/lib/app.coffee index b5025a3a4fee..0113e90a1a1f 100644 --- a/atom/browser/api/lib/app.coffee +++ b/atom/browser/api/lib/app.coffee @@ -1,5 +1,5 @@ -deprecate = require 'deprecate' -EventEmitter = require('events').EventEmitter +electron = require 'electron' +{EventEmitter} = require 'events' bindings = process.atomBinding 'app' sessionBindings = process.atomBinding 'session' @@ -9,10 +9,10 @@ app = bindings.app app.__proto__ = EventEmitter.prototype app.setApplicationMenu = (menu) -> - require('menu').setApplicationMenu menu + electron.menu.setApplicationMenu menu app.getApplicationMenu = -> - require('menu').getApplicationMenu() + electron.menu.getApplicationMenu() app.commandLine = appendSwitch: bindings.appendSwitch, @@ -39,6 +39,7 @@ app.getAppPath = -> app.resolveProxy = (url, callback) -> @defaultSession.resolveProxy url, callback # Deprecated. +{deprecate} = electron app.getHomeDir = deprecate 'app.getHomeDir', 'app.getPath', -> @getPath 'home' app.getDataPath = deprecate 'app.getDataPath', 'app.getPath', -> diff --git a/atom/browser/api/lib/browser-window.coffee b/atom/browser/api/lib/browser-window.coffee index 5bb633208840..3cefa1bf60ce 100644 --- a/atom/browser/api/lib/browser-window.coffee +++ b/atom/browser/api/lib/browser-window.coffee @@ -1,7 +1,5 @@ -EventEmitter = require('events').EventEmitter -app = require 'app' -ipc = require 'ipc-main' -deprecate = require 'deprecate' +{app, ipcMain, deprecate} = require 'electron' +{EventEmitter} = require 'events' BrowserWindow = process.atomBinding('window').BrowserWindow BrowserWindow::__proto__ = EventEmitter.prototype @@ -15,7 +13,7 @@ BrowserWindow::_init = -> # Make new windows requested by links behave like "window.open" @webContents.on '-new-window', (event, url, frameName) -> options = show: true, width: 800, height: 600 - ipc.emit 'ATOM_SHELL_GUEST_WINDOW_MANAGER_WINDOW_OPEN', event, url, frameName, options + ipcMain.emit 'ATOM_SHELL_GUEST_WINDOW_MANAGER_WINDOW_OPEN', event, url, frameName, options # window.resizeTo(...) # window.moveTo(...) diff --git a/atom/browser/api/lib/dialog.coffee b/atom/browser/api/lib/dialog.coffee index 0843af04282e..f10ce58c17f5 100644 --- a/atom/browser/api/lib/dialog.coffee +++ b/atom/browser/api/lib/dialog.coffee @@ -1,7 +1,7 @@ +{app, BrowserWindow} = require 'electron' + binding = process.atomBinding 'dialog' v8Util = process.atomBinding 'v8_util' -app = require 'app' -BrowserWindow = require 'browser-window' fileDialogProperties = openFile: 1 << 0 diff --git a/atom/browser/api/lib/exports/electron.coffee b/atom/browser/api/lib/exports/electron.coffee index 6c7929706cc6..a09a6441c3f8 100644 --- a/atom/browser/api/lib/exports/electron.coffee +++ b/atom/browser/api/lib/exports/electron.coffee @@ -45,3 +45,8 @@ Object.defineProperties module.exports, tray: enumerable: true get: -> require '../tray' + # The internal modules, invisible unless you know their names. + NavigationController: + get: -> require '../navigation-controller' + webContents: + get: -> require '../web-contents' diff --git a/atom/browser/api/lib/global-shortcut.coffee b/atom/browser/api/lib/global-shortcut.coffee index 8b24d2725366..56c3e128767e 100644 --- a/atom/browser/api/lib/global-shortcut.coffee +++ b/atom/browser/api/lib/global-shortcut.coffee @@ -1,5 +1,3 @@ -bindings = process.atomBinding 'global_shortcut' - -globalShortcut = bindings.globalShortcut +{globalShortcut} = process.atomBinding 'global_shortcut' module.exports = globalShortcut diff --git a/atom/browser/api/lib/ipc.coffee b/atom/browser/api/lib/ipc.coffee index b8ab05a886b9..8019a385dd90 100644 --- a/atom/browser/api/lib/ipc.coffee +++ b/atom/browser/api/lib/ipc.coffee @@ -1,6 +1,6 @@ -deprecate = require 'deprecate' +{deprecate, ipcMain} = require 'electron' # This module is deprecated, we mirror everything from ipcMain. deprecate.warn 'ipc module', 'ipcMain module' -module.exports = require 'ipc-main' +module.exports = ipcMain diff --git a/atom/browser/api/lib/menu-item.coffee b/atom/browser/api/lib/menu-item.coffee index cfefeec4edbb..92e2283b417d 100644 --- a/atom/browser/api/lib/menu-item.coffee +++ b/atom/browser/api/lib/menu-item.coffee @@ -1,4 +1,3 @@ -BrowserWindow = require 'browser-window' v8Util = process.atomBinding 'v8_util' nextCommandId = 0 @@ -18,7 +17,7 @@ class MenuItem @types = ['normal', 'separator', 'submenu', 'checkbox', 'radio'] constructor: (options) -> - Menu = require 'menu' + {Menu} = require 'electron' {click, @selector, @type, @role, @label, @sublabel, @accelerator, @icon, @enabled, @visible, @checked, @submenu} = options diff --git a/atom/browser/api/lib/menu.coffee b/atom/browser/api/lib/menu.coffee index f66c1568c003..26e2dc233506 100644 --- a/atom/browser/api/lib/menu.coffee +++ b/atom/browser/api/lib/menu.coffee @@ -1,8 +1,7 @@ -BrowserWindow = require 'browser-window' -EventEmitter = require('events').EventEmitter -MenuItem = require 'menu-item' -v8Util = process.atomBinding 'v8_util' +{BrowserWindow, MenuItem} = require 'electron' +{EventEmitter} = require 'events' +v8Util = process.atomBinding 'v8_util' bindings = process.atomBinding 'menu' # Automatically generated radio menu item's group id. diff --git a/atom/browser/api/lib/navigation-controller.coffee b/atom/browser/api/lib/navigation-controller.coffee index 34911dd759ec..88b1ed30ddd3 100644 --- a/atom/browser/api/lib/navigation-controller.coffee +++ b/atom/browser/api/lib/navigation-controller.coffee @@ -1,10 +1,10 @@ -ipc = require 'ipc-main' +{ipcMain} = require 'electron' # The history operation in renderer is redirected to browser. -ipc.on 'ATOM_SHELL_NAVIGATION_CONTROLLER', (event, method, args...) -> +ipcMain.on 'ATOM_SHELL_NAVIGATION_CONTROLLER', (event, method, args...) -> event.sender[method] args... -ipc.on 'ATOM_SHELL_SYNC_NAVIGATION_CONTROLLER', (event, method, args...) -> +ipcMain.on 'ATOM_SHELL_SYNC_NAVIGATION_CONTROLLER', (event, method, args...) -> event.returnValue = event.sender[method] args... # JavaScript implementation of Chromium's NavigationController. diff --git a/atom/browser/api/lib/power-monitor.coffee b/atom/browser/api/lib/power-monitor.coffee index f13e60eb9da8..54bf9391827c 100644 --- a/atom/browser/api/lib/power-monitor.coffee +++ b/atom/browser/api/lib/power-monitor.coffee @@ -1,5 +1,6 @@ -powerMonitor = process.atomBinding('power_monitor').powerMonitor -EventEmitter = require('events').EventEmitter +{EventEmitter} = require 'events' + +{powerMonitor} = process.atomBinding 'power_monitor' powerMonitor.__proto__ = EventEmitter.prototype diff --git a/atom/browser/api/lib/power-save-blocker.coffee b/atom/browser/api/lib/power-save-blocker.coffee index 7f428bc40f19..58392bc9aa8b 100644 --- a/atom/browser/api/lib/power-save-blocker.coffee +++ b/atom/browser/api/lib/power-save-blocker.coffee @@ -1,3 +1,3 @@ -bindings = process.atomBinding 'power_save_blocker' +{powerSaveBlocker} = process.atomBinding 'power_save_blocker' -module.exports = bindings.powerSaveBlocker +module.exports = powerSaveBlocker diff --git a/atom/browser/api/lib/protocol.coffee b/atom/browser/api/lib/protocol.coffee index 13f2a6d10270..a1dbc7c17d75 100644 --- a/atom/browser/api/lib/protocol.coffee +++ b/atom/browser/api/lib/protocol.coffee @@ -1,7 +1,8 @@ -app = require 'app' +{app} = require 'electron' + throw new Error('Can not initialize protocol module before app is ready') unless app.isReady() -protocol = process.atomBinding('protocol').protocol +{protocol} = process.atomBinding 'protocol' # Warn about removed APIs. logAndThrow = (callback, message) -> diff --git a/atom/browser/api/lib/screen.coffee b/atom/browser/api/lib/screen.coffee index 6ef5a5f66338..87c42f091df2 100644 --- a/atom/browser/api/lib/screen.coffee +++ b/atom/browser/api/lib/screen.coffee @@ -1,6 +1,6 @@ -EventEmitter = require('events').EventEmitter +{EventEmitter} = require 'events' +{screen} = process.atomBinding 'screen' -screen = process.atomBinding('screen').screen screen.__proto__ = EventEmitter.prototype module.exports = screen diff --git a/atom/browser/api/lib/tray.coffee b/atom/browser/api/lib/tray.coffee index 1c225ddd403c..41cfc96d3f56 100644 --- a/atom/browser/api/lib/tray.coffee +++ b/atom/browser/api/lib/tray.coffee @@ -1,7 +1,6 @@ -EventEmitter = require('events').EventEmitter -bindings = process.atomBinding 'tray' +{EventEmitter} = require 'events' +{Tray} = process.atomBinding 'tray' -Tray = bindings.Tray Tray::__proto__ = EventEmitter.prototype Tray::setContextMenu = (menu) -> diff --git a/atom/browser/api/lib/web-contents.coffee b/atom/browser/api/lib/web-contents.coffee index 958c3f8270c6..b3b1e7ed9fa4 100644 --- a/atom/browser/api/lib/web-contents.coffee +++ b/atom/browser/api/lib/web-contents.coffee @@ -1,8 +1,7 @@ -EventEmitter = require('events').EventEmitter -Menu = require './menu' -NavigationController = require './navigation-controller' +{EventEmitter} = require 'events' +{ipcMain, NavigationController, Menu} = require 'electron' + binding = process.atomBinding 'web_contents' -ipc = require 'ipc-main' nextId = 0 getNextId = -> ++nextId @@ -60,11 +59,11 @@ wrapWebContents = (webContents) -> # Dispatch IPC messages to the ipc module. webContents.on 'ipc-message', (event, packed) -> [channel, args...] = packed - ipc.emit channel, event, args... + ipcMain.emit channel, event, args... webContents.on 'ipc-message-sync', (event, packed) -> [channel, args...] = packed Object.defineProperty event, 'returnValue', set: (value) -> event.sendReply JSON.stringify(value) - ipc.emit channel, event, args... + ipcMain.emit channel, event, args... # Handle context menu action request from pepper plugin. webContents.on 'pepper-context-menu', (event, params) -> diff --git a/atom/browser/default_app/default_app.js b/atom/browser/default_app/default_app.js index de8b14d5f4d7..6a94db4836f8 100644 --- a/atom/browser/default_app/default_app.js +++ b/atom/browser/default_app/default_app.js @@ -1,5 +1,6 @@ -var app = require('app'); -var BrowserWindow = require('browser-window'); +const electron = require('electron'); +const app = electron.app; +const BrowserWindow = electron.BrowserWindow; var mainWindow = null; diff --git a/atom/browser/default_app/index.html b/atom/browser/default_app/index.html index 96e45806d5dd..e55cdf77b7fd 100644 --- a/atom/browser/default_app/index.html +++ b/atom/browser/default_app/index.html @@ -57,13 +57,17 @@ diff --git a/spec/fixtures/api/preload.html b/spec/fixtures/api/preload.html index 5e73c92971c1..b0e42ebe2ea3 100644 --- a/spec/fixtures/api/preload.html +++ b/spec/fixtures/api/preload.html @@ -3,7 +3,7 @@ diff --git a/spec/fixtures/api/send-sync-message.html b/spec/fixtures/api/send-sync-message.html index 40bae94b810f..80950740570a 100644 --- a/spec/fixtures/api/send-sync-message.html +++ b/spec/fixtures/api/send-sync-message.html @@ -1,8 +1,8 @@ diff --git a/spec/fixtures/asar/script.asar b/spec/fixtures/asar/script.asar index 152045ad2a6bb6e1337bc70448fecde5100e3709..7239786ec90ea4317573ac9e080073a42b13e6d6 100755 GIT binary patch delta 58 zcmX@Zc$aZPFq5gt#L#Hn)ST4hlA`=Pbxpm@g5;poyp+_U)FQoNAVWjFATuvrT}MH^ LARkC;T5|yaT{;tO delta 41 vcmcc1c!qI8Fq5(Q#L#G&%z|WfO}*mOyc7-fg3P>hbsYuuf_xyYY0U)y91IMc diff --git a/spec/fixtures/asar/web.asar b/spec/fixtures/asar/web.asar index 0c7a788e759dc131689de6fb977bbbba4d795260..1e9db65b8128ec9ab0fa415ccf7dc6e6dc874b28 100644 GIT binary patch delta 38 tcmX@fc#Cm@0h6i0M5Ac2)ST4hlA`=Pbxpm@g5;poyp+_U)S`)#%mMz_4X6MB delta 21 ccmcb`c#?5~0h6)uM5Acd%z|Wf&54W60Zj!4=l}o! diff --git a/spec/fixtures/module/preload-ipc.js b/spec/fixtures/module/preload-ipc.js index 76bd481cab6f..ed95055c1249 100644 --- a/spec/fixtures/module/preload-ipc.js +++ b/spec/fixtures/module/preload-ipc.js @@ -1,4 +1,4 @@ -var ipc = require('ipc-renderer'); -ipc.on('ping', function(event, message) { - ipc.sendToHost('pong', message); +var ipcRenderer = require('electron').ipcRenderer; +ipcRenderer.on('ping', function(event, message) { + ipcRenderer.sendToHost('pong', message); }); diff --git a/spec/fixtures/module/send-later.js b/spec/fixtures/module/send-later.js index 9cd5bfd38853..13f02452db1c 100644 --- a/spec/fixtures/module/send-later.js +++ b/spec/fixtures/module/send-later.js @@ -1,4 +1,4 @@ -var ipc = require('ipc-renderer'); +var ipcRenderer = require('electron').ipcRenderer; window.onload = function() { - ipc.send('answer', typeof window.process); + ipcRenderer.send('answer', typeof window.process); } diff --git a/spec/fixtures/pages/basic-auth.html b/spec/fixtures/pages/basic-auth.html index f2b9fab199fe..ec9383ca4d08 100644 --- a/spec/fixtures/pages/basic-auth.html +++ b/spec/fixtures/pages/basic-auth.html @@ -2,7 +2,7 @@ diff --git a/spec/fixtures/pages/beforeunload-false.html b/spec/fixtures/pages/beforeunload-false.html index 4f14613bf371..0b71b07c834a 100644 --- a/spec/fixtures/pages/beforeunload-false.html +++ b/spec/fixtures/pages/beforeunload-false.html @@ -3,8 +3,8 @@ diff --git a/spec/fixtures/pages/history.html b/spec/fixtures/pages/history.html index ef0083535973..6100293fdac4 100644 --- a/spec/fixtures/pages/history.html +++ b/spec/fixtures/pages/history.html @@ -2,7 +2,7 @@ diff --git a/spec/fixtures/pages/ipc-message.html b/spec/fixtures/pages/ipc-message.html index 65e347275c21..f543c9abf082 100644 --- a/spec/fixtures/pages/ipc-message.html +++ b/spec/fixtures/pages/ipc-message.html @@ -1,7 +1,7 @@ diff --git a/spec/fixtures/pages/onkeyup.html b/spec/fixtures/pages/onkeyup.html index 87e6dc596b5b..4e75dbb1e4ac 100644 --- a/spec/fixtures/pages/onkeyup.html +++ b/spec/fixtures/pages/onkeyup.html @@ -2,7 +2,7 @@ diff --git a/spec/fixtures/pages/onmouseup.html b/spec/fixtures/pages/onmouseup.html index ea486fdf80ed..123825a28fbd 100644 --- a/spec/fixtures/pages/onmouseup.html +++ b/spec/fixtures/pages/onmouseup.html @@ -2,7 +2,7 @@ diff --git a/spec/fixtures/pages/window-open-size.html b/spec/fixtures/pages/window-open-size.html index 7b06cfddf551..b32e39889a4c 100644 --- a/spec/fixtures/pages/window-open-size.html +++ b/spec/fixtures/pages/window-open-size.html @@ -1,7 +1,7 @@ diff --git a/spec/fixtures/pages/window-opener.html b/spec/fixtures/pages/window-opener.html index a7b59bd1a45b..58a8b6ea1ae9 100644 --- a/spec/fixtures/pages/window-opener.html +++ b/spec/fixtures/pages/window-opener.html @@ -4,7 +4,7 @@ if (window.opener !== null) window.opener.postMessage(typeof window.opener, '*'); else - require('ipc-renderer').send('opener', window.opener); + require('electron').ipcRenderer.send('opener', window.opener); diff --git a/spec/node-spec.coffee b/spec/node-spec.coffee index 969fc76f41ff..e6b2aa15821c 100644 --- a/spec/node-spec.coffee +++ b/spec/node-spec.coffee @@ -3,7 +3,8 @@ child_process = require 'child_process' fs = require 'fs' path = require 'path' os = require 'os' -remote = require 'remote' + +{remote} = require 'electron' describe 'node feature', -> fixtures = path.join __dirname, 'fixtures' diff --git a/spec/static/index.html b/spec/static/index.html index e7c69f5ba7de..ea86f6ee302d 100644 --- a/spec/static/index.html +++ b/spec/static/index.html @@ -14,22 +14,25 @@ process.throwDeprecation = true; // Check if we are running in CI. - var argv = require('remote').process.argv; + var electron = require ('electron'); + var remote = electron.remote; + var ipcRenderer = electron.ipcRenderer; + + var argv = remote.process.argv; var isCi = argv[2] == '--ci'; if (!isCi) { - var win = require('remote').getCurrentWindow(); + var win = remote.getCurrentWindow(); win.show(); win.focus(); } // Show DevTools. document.oncontextmenu = function(e) { - require('remote').getCurrentWindow().inspectElement(e.clientX, e.clientY); + remote.getCurrentWindow().inspectElement(e.clientX, e.clientY); } require('coffee-script/register'); // Supports .coffee tests. - var ipc = require('ipc-renderer'); // Rediret all output to browser. if (isCi) { @@ -37,11 +40,11 @@ return { log: function() { args = Array.prototype.slice.call(arguments); - ipc.send('console.log', args); + ipcRenderer.send('console.log', args); }, error: function() { args = Array.prototype.slice.call(arguments); - ipc.send('console.error', args); + ipcRenderer.send('console.error', args); }, } }); @@ -70,7 +73,7 @@ var runner = mocha.run(function() { Mocha.utils.highlightTags('code'); if (isCi) - ipc.send('process.exit', runner.failures); + ipcRenderer.send('process.exit', runner.failures); }); }); })(); diff --git a/spec/static/main.js b/spec/static/main.js index 70c47cc37e1c..e071474f9a94 100644 --- a/spec/static/main.js +++ b/spec/static/main.js @@ -1,8 +1,10 @@ -var app = require('app'); -var ipc = require('ipc-main'); -var dialog = require('dialog'); -var path = require('path'); -var BrowserWindow = require('browser-window'); +const electron = require('electron'); +const app = electron.app; +const ipcMain = electron.ipcMain; +const dialog = electron.dialog; +const BrowserWindow = electron.BrowserWindow; + +const path = require('path'); var window = null; process.port = 0; // will be used by crash-reporter spec. @@ -16,27 +18,27 @@ app.commandLine.appendSwitch('disable-renderer-backgrounding'); // sure we can reproduce it in renderer process. process.stdout; -ipc.on('message', function(event, arg) { +ipcMain.on('message', function(event, arg) { event.sender.send('message', arg); }); -ipc.on('console.log', function(event, args) { +ipcMain.on('console.log', function(event, args) { console.error.apply(console, args); }); -ipc.on('console.error', function(event, args) { +ipcMain.on('console.error', function(event, args) { console.error.apply(console, args); }); -ipc.on('process.exit', function(event, code) { +ipcMain.on('process.exit', function(event, code) { process.exit(code); }); -ipc.on('eval', function(event, script) { +ipcMain.on('eval', function(event, script) { event.returnValue = eval(script); }); -ipc.on('echo', function(event, msg) { +ipcMain.on('echo', function(event, msg) { event.returnValue = msg; }); @@ -54,7 +56,7 @@ app.on('window-all-closed', function() { app.on('ready', function() { // Test if using protocol module would crash. - require('protocol').registerStringProtocol('test-if-crashes', function() {}); + electron.protocol.registerStringProtocol('test-if-crashes', function() {}); window = new BrowserWindow({ title: 'Electron Tests', @@ -79,7 +81,7 @@ app.on('ready', function() { // For session's download test, listen 'will-download' event in browser, and // reply the result to renderer for verifying var downloadFilePath = path.join(__dirname, '..', 'fixtures', 'mock.pdf'); - ipc.on('set-download-option', function(event, need_cancel) { + ipcMain.on('set-download-option', function(event, need_cancel) { window.webContents.session.once('will-download', function(e, item, webContents) { item.setSavePath(downloadFilePath); From 8b2942c2795d2371aea0dacfddd2b58a66752c58 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Thu, 12 Nov 2015 20:30:40 +0800 Subject: [PATCH 126/249] Optimize remote.require('electron') --- atom/browser/api/lib/exports/electron.coffee | 3 +++ atom/browser/lib/rpc-server.coffee | 18 ++++++++++++++++-- atom/common/api/lib/exports/electron.coffee | 2 +- atom/renderer/api/lib/remote.coffee | 19 ++++++++++++++++++- 4 files changed, 38 insertions(+), 4 deletions(-) diff --git a/atom/browser/api/lib/exports/electron.coffee b/atom/browser/api/lib/exports/electron.coffee index a09a6441c3f8..6f70e6b38b36 100644 --- a/atom/browser/api/lib/exports/electron.coffee +++ b/atom/browser/api/lib/exports/electron.coffee @@ -1,6 +1,9 @@ # Import common modules. module.exports = require '../../../../common/api/lib/exports/electron' +v8Util = process.atomBinding 'v8_util' +v8Util.setHiddenValue module.exports, 'electronModule', true + Object.defineProperties module.exports, # Browser side modules, please sort with alphabet order. app: diff --git a/atom/browser/lib/rpc-server.coffee b/atom/browser/lib/rpc-server.coffee index 3479f30f0b53..5c67026debf2 100644 --- a/atom/browser/lib/rpc-server.coffee +++ b/atom/browser/lib/rpc-server.coffee @@ -1,5 +1,7 @@ -{ipcMain} = require 'electron' path = require 'path' + +electron = require 'electron' +{ipcMain} = electron objectsRegistry = require './objects-registry' v8Util = process.atomBinding 'v8_util' @@ -14,7 +16,11 @@ valueToMeta = (sender, value, optimizeSimpleObject=false) -> meta.type = 'array' if Array.isArray value meta.type = 'error' if value instanceof Error meta.type = 'date' if value instanceof Date - meta.type = 'promise' if value? and value.constructor.name is 'Promise' + meta.type = 'promise' if value?.constructor.name is 'Promise' + + # require('electron'). + if meta.type is 'object' and v8Util.getHiddenValue value, 'electronModule' + meta.type = 'electronModule' # Treat simple objects as value. if optimizeSimpleObject and meta.type is 'object' and v8Util.getHiddenValue value, 'simple' @@ -43,6 +49,8 @@ valueToMeta = (sender, value, optimizeSimpleObject=false) -> meta.members = plainObjectToMeta value else if meta.type is 'date' meta.value = value.getTime() + else if meta.type is 'electronModule' + meta.members = (name for name of value) else meta.type = 'value' meta.value = value @@ -122,6 +130,12 @@ ipcMain.on 'ATOM_BROWSER_REQUIRE', (event, module) -> catch e event.returnValue = exceptionToMeta e +ipcMain.on 'ATOM_BROWSER_GET_BUILTIN', (event, module) -> + try + event.returnValue = valueToMeta event.sender, electron[module] + catch e + event.returnValue = exceptionToMeta e + ipcMain.on 'ATOM_BROWSER_GLOBAL', (event, name) -> try event.returnValue = valueToMeta event.sender, global[name] diff --git a/atom/common/api/lib/exports/electron.coffee b/atom/common/api/lib/exports/electron.coffee index 26e8ce2f1835..7bcb23a2ca4d 100644 --- a/atom/common/api/lib/exports/electron.coffee +++ b/atom/common/api/lib/exports/electron.coffee @@ -4,7 +4,7 @@ Object.defineProperties exports, # Must be enumerable, otherwise it woulde be invisible to remote module. enumerable: true get: -> require '../clipboard' - crashRepoter: + crashReporter: enumerable: true get: -> require '../crash-reporter' nativeImage: diff --git a/atom/renderer/api/lib/remote.coffee b/atom/renderer/api/lib/remote.coffee index 9faed14bf5cd..09e7dcdcb574 100644 --- a/atom/renderer/api/lib/remote.coffee +++ b/atom/renderer/api/lib/remote.coffee @@ -18,7 +18,7 @@ wrapArgs = (args, visited=[]) -> type: 'array', value: wrapArgs(value, visited) else if Buffer.isBuffer value type: 'buffer', value: Array::slice.call(value, 0) - else if value? and value.constructor.name is 'Promise' + else if value?.constructor.name is 'Promise' type: 'promise', then: valueToMeta(value.then.bind(value)) else if value? and typeof value is 'object' and v8Util.getHiddenValue value, 'atomId' type: 'remote-object', id: v8Util.getHiddenValue value, 'atomId' @@ -49,6 +49,15 @@ metaToValue = (meta) -> when 'date' then new Date(meta.value) when 'exception' throw new Error("#{meta.message}\n#{meta.stack}") + when 'electronModule' + # require('electron'). + ret = {} + for member in meta.members + do (member) -> + Object.defineProperty ret, member, + enumerable: true + get: -> exports.getBuiltin member + ret else if meta.type is 'function' # A shadow class to represent the remote function object. @@ -135,6 +144,14 @@ exports.require = (module) -> meta = ipcRenderer.sendSync 'ATOM_BROWSER_REQUIRE', module moduleCache[module] = metaToValue meta +# Alias to remote.require('electron').xxx. +builtinCache = {} +exports.getBuiltin = (module) -> + return builtinCache[module] if builtinCache[module]? + + meta = ipcRenderer.sendSync 'ATOM_BROWSER_GET_BUILTIN', module + builtinCache[module] = metaToValue meta + # Get current BrowserWindow object. windowCache = null exports.getCurrentWindow = -> From eac2e7cc614d4e98e2828921f63d55f7b5e2c85c Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Thu, 12 Nov 2015 21:20:09 +0800 Subject: [PATCH 127/249] docs: Update codes in docs to use require('electron') --- docs/README.md | 30 +++++++++---------- docs/api/app.md | 2 +- docs/api/browser-window.md | 13 +------- docs/api/chrome-command-line-switches.md | 2 +- docs/api/clipboard.md | 5 +--- docs/api/content-tracing.md | 2 +- docs/api/crash-reporter.md | 4 +-- docs/api/dialog.md | 6 ++-- docs/api/frameless-window.md | 5 ++-- docs/api/global-shortcut.md | 5 ++-- docs/api/ipc-main.md | 4 +-- docs/api/menu.md | 10 +++---- docs/api/native-image.md | 29 +++++++++--------- docs/api/power-monitor.md | 6 ++-- docs/api/power-save-blocker.md | 4 +-- docs/api/protocol.md | 7 +++-- docs/api/remote.md | 18 ++++++----- docs/api/screen.md | 21 ++++++------- docs/api/session.md | 4 +-- docs/api/shell.md | 2 +- docs/api/synopsis.md | 9 +++--- docs/api/tray.md | 7 +++-- docs/api/web-contents.md | 14 ++++----- docs/api/web-frame.md | 4 +-- docs/api/web-view-tag.md | 8 ++--- docs/tutorial/application-packaging.md | 6 ++-- .../desktop-environment-integration.md | 13 ++++---- docs/tutorial/devtools-extension.md | 5 ++-- docs/tutorial/online-offline-events.md | 18 ++++++----- docs/tutorial/quick-start.md | 7 +++-- docs/tutorial/using-pepper-flash-plugin.md | 17 ----------- docs/tutorial/using-selenium-and-webdriver.md | 4 +-- 32 files changed, 134 insertions(+), 157 deletions(-) diff --git a/docs/README.md b/docs/README.md index fb5c64a8f17e..208ff8bf47b6 100644 --- a/docs/README.md +++ b/docs/README.md @@ -31,32 +31,32 @@ ### Modules for the Main Process: * [app](api/app.md) -* [auto-updater](api/auto-updater.md) -* [browser-window](api/browser-window.md) -* [content-tracing](api/content-tracing.md) +* [autoUpdater](api/auto-updater.md) +* [BrowserWindow](api/browser-window.md) +* [contentTracing](api/content-tracing.md) * [dialog](api/dialog.md) -* [global-shortcut](api/global-shortcut.md) -* [ipc-main](api/ipc-main.md) -* [menu](api/menu.md) -* [menu-item](api/menu-item.md) -* [power-monitor](api/power-monitor.md) -* [power-save-blocker](api/power-save-blocker.md) +* [globalShortcut](api/global-shortcut.md) +* [ipcMain](api/ipc-main.md) +* [Menu](api/menu.md) +* [MenuItem](api/menu-item.md) +* [powerMonitor](api/power-monitor.md) +* [powerSaveBlocker](api/power-save-blocker.md) * [protocol](api/protocol.md) * [session](api/session.md) -* [web-contents](api/web-contents.md) -* [tray](api/tray.md) +* [webContents](api/web-contents.md) +* [Tray](api/tray.md) ### Modules for the Renderer Process (Web Page): -* [ipc-renderer](api/ipc-renderer.md) +* [ipcRenderer](api/ipc-renderer.md) * [remote](api/remote.md) -* [web-frame](api/web-frame.md) +* [webFrame](api/web-frame.md) ### Modules for Both Processes: * [clipboard](api/clipboard.md) -* [crash-reporter](api/crash-reporter.md) -* [native-image](api/native-image.md) +* [crashReporter](api/crash-reporter.md) +* [nativeImage](api/native-image.md) * [screen](api/screen.md) * [shell](api/shell.md) diff --git a/docs/api/app.md b/docs/api/app.md index fdb9f9980592..1edc40fb89ae 100644 --- a/docs/api/app.md +++ b/docs/api/app.md @@ -6,7 +6,7 @@ The following example shows how to quit the application when the last window is closed: ```javascript -var app = require('app'); +const app = require('electron').app; app.on('window-all-closed', function() { app.quit(); }); diff --git a/docs/api/browser-window.md b/docs/api/browser-window.md index 0499b6355a00..670c814c741d 100644 --- a/docs/api/browser-window.md +++ b/docs/api/browser-window.md @@ -4,7 +4,7 @@ The `BrowserWindow` class gives you the ability to create a browser window. For example: ```javascript -var BrowserWindow = require('browser-window'); +const BrowserWindow = require('electron').BrowserWindow; var win = new BrowserWindow({ width: 800, height: 600, show: false }); win.on('closed', function() { @@ -291,11 +291,8 @@ Remove the DevTools extension whose name is `name`. Objects created with `new BrowserWindow` have the following properties: ```javascript -var BrowserWindow = require('browser-window'); - // In this example `win` is our instance var win = new BrowserWindow({ width: 800, height: 600 }); - ``` ### `win.webContents` @@ -316,14 +313,6 @@ Objects created with `new BrowserWindow` have the following instance methods: **Note:** Some methods are only available on specific operating systems and are labeled as such. -```javascript -var BrowserWindow = require('browser-window'); - -// In this example `win` is our instance -var win = new BrowserWindow({ width: 800, height: 600 }); - -``` - ### `win.destroy()` Force closing the window, the `unload` and `beforeunload` event won't be emitted diff --git a/docs/api/chrome-command-line-switches.md b/docs/api/chrome-command-line-switches.md index 96dffb963135..d163a726d40e 100644 --- a/docs/api/chrome-command-line-switches.md +++ b/docs/api/chrome-command-line-switches.md @@ -6,7 +6,7 @@ them in your app's main script before the [ready][ready] event of [app][app] module is emitted: ```javascript -var app = require('app'); +const app = require('electron').app; app.commandLine.appendSwitch('remote-debugging-port', '8315'); app.commandLine.appendSwitch('host-rules', 'MAP * 127.0.0.1'); diff --git a/docs/api/clipboard.md b/docs/api/clipboard.md index a99605baea18..7cb5b840bc1c 100644 --- a/docs/api/clipboard.md +++ b/docs/api/clipboard.md @@ -4,7 +4,7 @@ The `clipboard` module provides methods to perform copy and paste operations. The following example shows how to write a string to the clipboard: ```javascript -var clipboard = require('clipboard'); +const clipboard = require('electron').clipboard; clipboard.writeText('Example String'); ``` @@ -12,7 +12,6 @@ On X Window systems, there is also a selection clipboard. To manipulate it you need to pass `selection` to each method: ```javascript -var clipboard = require('clipboard'); clipboard.writeText('Example String', 'selection'); console.log(clipboard.readText('selection')); ``` @@ -82,7 +81,6 @@ Returns an array of supported formats for the clipboard `type`. Returns whether the clipboard supports the format of specified `data`. ```javascript -var clipboard = require('clipboard'); console.log(clipboard.has('

selection

')); ``` @@ -102,7 +100,6 @@ Reads `data` from the clipboard. * `type` String (optional) ```javascript -var clipboard = require('clipboard'); clipboard.write({text: 'test', html: "test"}); ``` Writes `data` to the clipboard. diff --git a/docs/api/content-tracing.md b/docs/api/content-tracing.md index 2e05fc67668f..734e2c47cfb4 100644 --- a/docs/api/content-tracing.md +++ b/docs/api/content-tracing.md @@ -6,7 +6,7 @@ so you need to open `chrome://tracing/` in a Chrome browser and load the generated file to view the result. ```javascript -var contentTracing = require('content-tracing'); +const contentTracing = require('electron').contentTracing; contentTracing.startRecording('*', contentTracing.DEFAULT_OPTIONS, function() { console.log('Tracing started'); diff --git a/docs/api/crash-reporter.md b/docs/api/crash-reporter.md index 64a3b2cf748d..8127c9bc1c93 100644 --- a/docs/api/crash-reporter.md +++ b/docs/api/crash-reporter.md @@ -6,7 +6,7 @@ The following is an example of automatically submitting a crash report to a remote server: ```javascript -var crashReporter = require('crash-reporter'); +const crashReporter = require('electron').crashReporter; crashReporter.start({ productName: 'YourName', @@ -62,7 +62,7 @@ The crash reporter will send the following data to the `submitUrl` as `POST`: * `ver` String - The version of Electron. * `platform` String - e.g. 'win32'. * `process_type` String - e.g. 'renderer'. -* `guid` String - e.g. '5e1286fc-da97-479e-918b-6bfb0c3d1c72' +* `guid` String - e.g. '5e1286fc-da97-479e-918b-6bfb0c3d1c72' * `_version` String - The version in `package.json`. * `_productName` String - The product name in the `crashReporter` `options` object. diff --git a/docs/api/dialog.md b/docs/api/dialog.md index 6acfb79884e3..884fb7c07327 100644 --- a/docs/api/dialog.md +++ b/docs/api/dialog.md @@ -8,7 +8,7 @@ An example of showing a dialog to select multiple files and directories: ```javascript var win = ...; // BrowserWindow in which to show the dialog -var dialog = require('dialog'); +const dialog = require('electron').dialog; console.log(dialog.showOpenDialog({ properties: [ 'openFile', 'openDirectory', 'multiSelections' ]})); ``` @@ -114,6 +114,6 @@ will be passed via `callback(response)`. Displays a modal dialog that shows an error message. This API can be called safely before the `ready` event the `app` module emits, -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, +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. diff --git a/docs/api/frameless-window.md b/docs/api/frameless-window.md index 707a928f9db6..e70749f2894c 100644 --- a/docs/api/frameless-window.md +++ b/docs/api/frameless-window.md @@ -9,7 +9,7 @@ To create a frameless window, you need to set `frame` to `false` in ```javascript -var BrowserWindow = require('browser-window'); +const BrowserWindow = require('electron').BrowserWindow; var win = new BrowserWindow({ width: 800, height: 600, frame: false }); ``` @@ -23,8 +23,7 @@ the window controls ("traffic lights") for standard window actions. You can do so by specifying the new `title-bar-style` option: ```javascript -var BrowserWindow = require('browser-window'); -var win = new BrowserWindow({ width: 800, height: 600, 'title-bar-style': 'hidden' }); +var win = new BrowserWindow({ 'title-bar-style': 'hidden' }); ``` ## Transparent window diff --git a/docs/api/global-shortcut.md b/docs/api/global-shortcut.md index c9dfb194529a..a0f069d7f1c5 100644 --- a/docs/api/global-shortcut.md +++ b/docs/api/global-shortcut.md @@ -9,8 +9,9 @@ not have the keyboard focus. You should not use this module until the `ready` event of the app module is emitted. ```javascript -var app = require('app'); -var globalShortcut = require('global-shortcut'); +const electron = require('electron'); +const app = electron.app; +const globalShortcut = electron.globalShortcut; app.on('ready', function() { // Register a 'ctrl+x' shortcut listener. diff --git a/docs/api/ipc-main.md b/docs/api/ipc-main.md index f74c70426a5c..cdbc0ce34eec 100644 --- a/docs/api/ipc-main.md +++ b/docs/api/ipc-main.md @@ -19,7 +19,7 @@ processes: ```javascript // In main process. -var ipcMain = require('ipc-main'); +const ipcMain = require('electron').ipcMain; ipcMain.on('asynchronous-message', function(event, arg) { console.log(arg); // prints "ping" event.sender.send('asynchronous-reply', 'pong'); @@ -33,7 +33,7 @@ ipcMain.on('synchronous-message', function(event, arg) { ```javascript // In renderer process (web page). -var ipcRenderer = require('ipc-renderer'); +const ipcRenderer = require('electron').ipcRenderer; console.log(ipcRenderer.sendSync('synchronous-message', 'ping')); // prints "pong" ipcRenderer.on('asynchronous-reply', function(event, arg) { diff --git a/docs/api/menu.md b/docs/api/menu.md index cabd04ca8550..c947f36d4790 100644 --- a/docs/api/menu.md +++ b/docs/api/menu.md @@ -16,9 +16,9 @@ the user right clicks the page: ```html diff --git a/docs/api/tray.md b/docs/api/tray.md index 47f02c5478fa..ff4310308a86 100644 --- a/docs/api/tray.md +++ b/docs/api/tray.md @@ -4,9 +4,10 @@ A `Tray` represents an icon in an operating system's notification area, it is usually attached with a context menu. ```javascript -var app = require('app'); -var Menu = require('menu'); -var Tray = require('tray'); +const electron = require('electron'); +const app = electron.app; +const Menu = electron.Menu; +const Tray = electron.Tray; var appIcon = null; app.on('ready', function(){ diff --git a/docs/api/web-contents.md b/docs/api/web-contents.md index d62706b2ba9a..aff5752ab55f 100644 --- a/docs/api/web-contents.md +++ b/docs/api/web-contents.md @@ -8,7 +8,7 @@ the [`BrowserWindow`](browser-window.md) object. An example of accessing the `webContents` object: ```javascript -var BrowserWindow = require('browser-window'); +const BrowserWindow = require('electron').BrowserWindow; var win = new BrowserWindow({width: 800, height: 1500}); win.loadUrl("http://github.com"); @@ -211,17 +211,15 @@ e.g. the `http://` or `file://`. ### `webContents.getUrl()` -```javascript -var BrowserWindow = require('browser-window'); +Returns URL of the current web page. +```javascript var win = new BrowserWindow({width: 800, height: 600}); win.loadUrl("http://github.com"); var currentUrl = win.webContents.getUrl(); ``` -Returns URL of the current web page. - ### `webContents.getTitle()` Returns the title of the current web page. @@ -445,8 +443,8 @@ By default, an empty `options` will be regarded as: ``` ```javascript -var BrowserWindow = require('browser-window'); -var fs = require('fs'); +const BrowserWindow = require('electron').BrowserWindow; +const fs = require('fs'); var win = new BrowserWindow({width: 800, height: 600}); win.loadUrl("http://github.com"); @@ -538,7 +536,7 @@ app.on('ready', function() { diff --git a/docs/api/web-frame.md b/docs/api/web-frame.md index 33597543b773..c9cfb48f3437 100644 --- a/docs/api/web-frame.md +++ b/docs/api/web-frame.md @@ -6,7 +6,7 @@ web page. An example of zooming current page to 200%. ```javascript -var webFrame = require('web-frame'); +var webFrame = require('electron').webFrame; webFrame.setZoomFactor(2); ``` @@ -59,7 +59,7 @@ whether the word passed is correctly spelled. An example of using [node-spellchecker][spellchecker] as provider: ```javascript -require('web-frame').setSpellCheckProvider("en-US", true, { +webFrame.setSpellCheckProvider("en-US", true, { spellCheck: function(text) { return !(require('spellchecker').isMisspelled(text)); } diff --git a/docs/api/web-view-tag.md b/docs/api/web-view-tag.md index 9a0e0be33b36..a12ec447138f 100644 --- a/docs/api/web-view-tag.md +++ b/docs/api/web-view-tag.md @@ -515,7 +515,7 @@ The following example code opens the new url in system's default browser. ```javascript webview.addEventListener('new-window', function(e) { - require('shell').openExternal(e.url); + require('electron').shell.openExternal(e.url); }); ``` @@ -555,9 +555,9 @@ webview.send('ping'); ```javascript // In guest page. -var ipc = require('ipc'); -ipc.on('ping', function() { - ipc.sendToHost('pong'); +var ipcRenderer = require('electron').ipcRenderer; +ipcRenderer.on('ping', function() { + ipcRenderer.sendToHost('pong'); }); ``` diff --git a/docs/tutorial/application-packaging.md b/docs/tutorial/application-packaging.md index 0cf3a6b596f4..7c1ea773e2ff 100644 --- a/docs/tutorial/application-packaging.md +++ b/docs/tutorial/application-packaging.md @@ -51,14 +51,14 @@ $ asar list /path/to/example.asar Read a file in the `asar` archive: ```javascript -var fs = require('fs'); +const fs = require('fs'); fs.readFileSync('/path/to/example.asar/file.txt'); ``` List all files under the root of the archive: ```javascript -var fs = require('fs'); +const fs = require('fs'); fs.readdirSync('/path/to/example.asar'); ``` @@ -71,7 +71,7 @@ require('/path/to/example.asar/dir/module.js'); You can also display a web page in an `asar` archive with `BrowserWindow`: ```javascript -var BrowserWindow = require('browser-window'); +const BrowserWindow = require('electron').BrowserWindow; var win = new BrowserWindow({width: 800, height: 600}); win.loadUrl('file:///path/to/example.asar/static/index.html'); ``` diff --git a/docs/tutorial/desktop-environment-integration.md b/docs/tutorial/desktop-environment-integration.md index 39f74ff10771..7c4807d8f4d4 100644 --- a/docs/tutorial/desktop-environment-integration.md +++ b/docs/tutorial/desktop-environment-integration.md @@ -86,7 +86,6 @@ To add a file to recent documents, you can use the [app.addRecentDocument][addrecentdocument] API: ```javascript -var app = require('app'); app.addRecentDocument('/Users/USERNAME/Desktop/work.type'); ``` @@ -125,8 +124,10 @@ To set your custom dock menu, you can use the `app.dock.setMenu` API, which is only available on OS X: ```javascript -var app = require('app'); -var Menu = require('menu'); +const electron = require('electron'); +const app = electron.app; +const Menu = electron.Menu; + var dockMenu = Menu.buildFromTemplate([ { label: 'New Window', click: function() { console.log('New Window'); } }, { label: 'New Window with Settings', submenu: [ @@ -172,7 +173,6 @@ To set user tasks for your application, you can use [app.setUserTasks][setusertaskstasks] API: ```javascript -var app = require('app'); app.setUserTasks([ { program: process.execPath, @@ -220,8 +220,9 @@ You can use [BrowserWindow.setThumbarButtons][setthumbarbuttons] to set thumbnail toolbar in your application: ```javascript -var BrowserWindow = require('browser-window'); -var path = require('path'); +const BrowserWindow = require('electron').BrowserWindow; +const path = require('path'); + var win = new BrowserWindow({ width: 800, height: 600 diff --git a/docs/tutorial/devtools-extension.md b/docs/tutorial/devtools-extension.md index 8a2144be6966..258fb41947ff 100644 --- a/docs/tutorial/devtools-extension.md +++ b/docs/tutorial/devtools-extension.md @@ -24,14 +24,15 @@ Then you can load the extension in Electron by opening DevTools in any window, and running the following code in the DevTools console: ```javascript -require('remote').require('browser-window').addDevToolsExtension('/some-directory/react-devtools/shells/chrome'); +const BrowserWindow = require('electron').remote.require('electron').BrowserWindow; +BrowserWindow.addDevToolsExtension('/some-directory/react-devtools/shells/chrome'); ``` To unload the extension, you can call the `BrowserWindow.removeDevToolsExtension` API with its name and it will not load the next time you open the DevTools: ```javascript -require('remote').require('browser-window').removeDevToolsExtension('React Developer Tools'); +BrowserWindow.removeDevToolsExtension('React Developer Tools'); ``` ## Format of DevTools Extension diff --git a/docs/tutorial/online-offline-events.md b/docs/tutorial/online-offline-events.md index 46d659e07d05..6e031282b55a 100644 --- a/docs/tutorial/online-offline-events.md +++ b/docs/tutorial/online-offline-events.md @@ -6,10 +6,11 @@ using standard HTML5 APIs, as shown in the following example. _main.js_ ```javascript -var app = require('app'); -var BrowserWindow = require('browser-window'); -var onlineStatusWindow; +const electron = require('electron'); +const app = electron.app; +const BrowserWindow = electron.BrowserWindow; +var onlineStatusWindow; app.on('ready', function() { onlineStatusWindow = new BrowserWindow({ width: 0, height: 0, show: false }); onlineStatusWindow.loadUrl('file://' + __dirname + '/online-status.html'); @@ -45,11 +46,12 @@ to the main process and handled as needed, as shown in the following example. _main.js_ ```javascript -var app = require('app'); -var ipcMain = require('ipc-main'); -var BrowserWindow = require('browser-window'); -var onlineStatusWindow; +const electron = require('electron'); +const app = electron.app; +const ipcMain = electron.ipcMain; +const BrowserWindow = electron.BrowserWindow; +var onlineStatusWindow; app.on('ready', function() { onlineStatusWindow = new BrowserWindow({ width: 0, height: 0, show: false }); onlineStatusWindow.loadUrl('file://' + __dirname + '/online-status.html'); @@ -67,7 +69,7 @@ _online-status.html_ - + + + ``` To run your app, read [Run your app](../tutorial/quick-start.md#run-your-app). + +## Destructuring assignment + +If you are using CoffeeScript or Babel, you can also use +[destructuring assignment][desctructuring-assignment] to make it easier to use +built-in modules: + +```javascript +const {app, BrowserWindow} = require('electron') +``` + +However if you are using plain JavaScript, you have to wait until Chrome fully +supports ES6. + +## Disable old styles of using built-in modules + +Before v0.35.0, all built-in modules have to be used in the form of +`require('module-name')`, though it has [many disadvantages][issue-387], we are +still supporting it for compatibility with old apps. + +To disable the old styles completely, you can set the +`ELECTRON_HIDE_INTERNAL_MODULES` environment variable: + +```javascript +process.env.ELECTRON_HIDE_INTERNAL_MODULES = 'true' +``` + +Or call the `hideInternalModules` API: + +```javascript +require('electron').hideInternalModules() +``` + +[gui]: https://en.wikipedia.org/wiki/Graphical_user_interface +[main-process]: ../tutorial/quick-start.md#the-main-process +[desctructuring-assignment]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment +[issue-387]: https://github.com/atom/electron/issues/387 From edd807d2271634dbe1228f13863a034e5801ed29 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Thu, 12 Nov 2015 22:56:18 +0800 Subject: [PATCH 131/249] Fix a typo --- atom/browser/api/lib/app.coffee | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/atom/browser/api/lib/app.coffee b/atom/browser/api/lib/app.coffee index 0113e90a1a1f..3494a6e6e431 100644 --- a/atom/browser/api/lib/app.coffee +++ b/atom/browser/api/lib/app.coffee @@ -9,10 +9,10 @@ app = bindings.app app.__proto__ = EventEmitter.prototype app.setApplicationMenu = (menu) -> - electron.menu.setApplicationMenu menu + electron.Menu.setApplicationMenu menu app.getApplicationMenu = -> - electron.menu.getApplicationMenu() + electron.Menu.getApplicationMenu() app.commandLine = appendSwitch: bindings.appendSwitch, From ce6a7c7d088eb0dc387a99c6ed74fd9ee839a0eb Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Thu, 12 Nov 2015 23:02:39 +0800 Subject: [PATCH 132/249] spec: Disable old APIs in tests --- script/test.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/script/test.py b/script/test.py index 28aeac9dc1ff..7f75d3113d69 100755 --- a/script/test.py +++ b/script/test.py @@ -16,6 +16,9 @@ PRODUCT_NAME = atom_gyp()['product_name%'] def main(): os.chdir(SOURCE_ROOT) + # Disable old APIs + os.environ['ELECTRON_HIDE_INTERNAL_MODULES'] = 'true' + config = 'D' if len(sys.argv) == 2 and sys.argv[1] == '-R': config = 'R' From d072e612823bdf342b519c866e09c55269b0cadf Mon Sep 17 00:00:00 2001 From: Robo Date: Thu, 5 Nov 2015 19:36:36 +0530 Subject: [PATCH 133/249] session: api to allow handling certificate verification --- atom/browser/api/atom_api_app.cc | 15 ---- atom/browser/api/atom_api_session.cc | 7 ++ atom/browser/atom_browser_context.cc | 5 ++ atom/browser/atom_browser_context.h | 1 + atom/browser/atom_cert_verifier.cc | 84 +++++++++++++++++++ atom/browser/atom_cert_verifier.h | 47 +++++++++++ atom/browser/browser.cc | 10 +++ atom/browser/browser.h | 4 + atom/browser/browser_observer.h | 11 +++ .../native_mate_converters/net_converter.cc | 19 +++++ .../native_mate_converters/net_converter.h | 8 ++ docs/api/app.md | 4 +- docs/api/session.md | 31 +++++++ filenames.gypi | 2 + 14 files changed, 231 insertions(+), 17 deletions(-) create mode 100644 atom/browser/atom_cert_verifier.cc create mode 100644 atom/browser/atom_cert_verifier.h diff --git a/atom/browser/api/atom_api_app.cc b/atom/browser/api/atom_api_app.cc index 1c5c2c04f145..e4d9c9ab6460 100644 --- a/atom/browser/api/atom_api_app.cc +++ b/atom/browser/api/atom_api_app.cc @@ -61,21 +61,6 @@ struct Converter { }; #endif -template<> -struct Converter> { - static v8::Local ToV8( - v8::Isolate* isolate, - const scoped_refptr& val) { - mate::Dictionary dict(isolate, v8::Object::New(isolate)); - std::string encoded_data; - net::X509Certificate::GetPEMEncoded( - val->os_cert_handle(), &encoded_data); - dict.Set("data", encoded_data); - dict.Set("issuerName", val->issuer().GetDisplayName()); - return dict.GetHandle(); - } -}; - } // namespace mate diff --git a/atom/browser/api/atom_api_session.cc b/atom/browser/api/atom_api_session.cc index 0ec9c05ed84e..f94d879fcc15 100644 --- a/atom/browser/api/atom_api_session.cc +++ b/atom/browser/api/atom_api_session.cc @@ -13,9 +13,11 @@ #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/browser.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" +#include "atom/common/native_mate_converters/net_converter.h" #include "atom/common/node_includes.h" #include "base/files/file_path.h" #include "base/prefs/pref_service.h" @@ -365,6 +367,7 @@ v8::Local Session::Cookies(v8::Isolate* isolate) { mate::ObjectTemplateBuilder Session::GetObjectTemplateBuilder( v8::Isolate* isolate) { + auto browser = base::Unretained(Browser::Get()); return mate::ObjectTemplateBuilder(isolate) .SetMethod("resolveProxy", &Session::ResolveProxy) .SetMethod("clearCache", &Session::ClearCache) @@ -373,6 +376,10 @@ mate::ObjectTemplateBuilder Session::GetObjectTemplateBuilder( .SetMethod("setDownloadPath", &Session::SetDownloadPath) .SetMethod("enableNetworkEmulation", &Session::EnableNetworkEmulation) .SetMethod("disableNetworkEmulation", &Session::DisableNetworkEmulation) + .SetMethod("setCertificateVerifier", + base::Bind(&Browser::SetCertificateVerifier, browser)) + .SetMethod("removeCertificateVerifier", + base::Bind(&Browser::RemoveCertificateVerifier, browser)) .SetProperty("cookies", &Session::Cookies); } diff --git a/atom/browser/atom_browser_context.cc b/atom/browser/atom_browser_context.cc index 6cfb160489fc..bfb506e8e246 100644 --- a/atom/browser/atom_browser_context.cc +++ b/atom/browser/atom_browser_context.cc @@ -5,6 +5,7 @@ #include "atom/browser/atom_browser_context.h" #include "atom/browser/atom_browser_main_parts.h" +#include "atom/browser/atom_cert_verifier.h" #include "atom/browser/atom_download_manager_delegate.h" #include "atom/browser/atom_ssl_config_service.h" #include "atom/browser/browser.h" @@ -158,6 +159,10 @@ content::BrowserPluginGuestManager* AtomBrowserContext::GetGuestManager() { return guest_manager_.get(); } +net::CertVerifier* AtomBrowserContext::CreateCertVerifier() { + return new AtomCertVerifier; +} + net::SSLConfigService* AtomBrowserContext::CreateSSLConfigService() { return new AtomSSLConfigService; } diff --git a/atom/browser/atom_browser_context.h b/atom/browser/atom_browser_context.h index aafa092442bc..81f9533c9c5e 100644 --- a/atom/browser/atom_browser_context.h +++ b/atom/browser/atom_browser_context.h @@ -27,6 +27,7 @@ class AtomBrowserContext : public brightray::BrowserContext { content::URLRequestInterceptorScopedVector* interceptors) override; net::HttpCache::BackendFactory* CreateHttpCacheBackendFactory( const base::FilePath& base_path) override; + net::CertVerifier* CreateCertVerifier() override; net::SSLConfigService* CreateSSLConfigService() override; bool AllowNTLMCredentialsForDomain(const GURL& auth_origin) override; diff --git a/atom/browser/atom_cert_verifier.cc b/atom/browser/atom_cert_verifier.cc new file mode 100644 index 000000000000..d8d1cb112dc2 --- /dev/null +++ b/atom/browser/atom_cert_verifier.cc @@ -0,0 +1,84 @@ +// Copyright (c) 2015 GitHub, Inc. +// Use of this source code is governed by the MIT license that can be +// found in the LICENSE file. + +#include "atom/browser/atom_cert_verifier.h" + +#include "atom/browser/browser.h" +#include "atom/common/native_mate_converters/net_converter.h" +#include "content/public/browser/browser_thread.h" +#include "net/base/net_errors.h" +#include "net/cert/x509_certificate.h" + +using content::BrowserThread; + +namespace atom { + +namespace { + +void RunResult(const net::CompletionCallback& callback, bool success) { + DCHECK_CURRENTLY_ON(BrowserThread::UI); + + int result = net::OK; + if (!success) + result = net::ERR_FAILED; + + BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, + base::Bind(callback, result)); +} + +} // namespace + +AtomCertVerifier::AtomCertVerifier() { + Browser::Get()->AddObserver(this); + default_cert_verifier_.reset(net::CertVerifier::CreateDefault()); +} + +AtomCertVerifier::~AtomCertVerifier() { + Browser::Get()->RemoveObserver(this); +} + +int AtomCertVerifier::Verify( + net::X509Certificate* cert, + const std::string& hostname, + const std::string& ocsp_response, + int flags, + net::CRLSet* crl_set, + net::CertVerifyResult* verify_result, + const net::CompletionCallback& callback, + scoped_ptr* out_req, + const net::BoundNetLog& net_log) { + DCHECK_CURRENTLY_ON(BrowserThread::IO); + + if (callback.is_null() || !verify_result || hostname.empty()) + return net::ERR_INVALID_ARGUMENT; + + if (!handler_.is_null()) { + BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, + base::Bind(handler_, hostname, + make_scoped_refptr(cert), + base::Bind(&RunResult, callback))); + return net::ERR_IO_PENDING; + } + + return default_cert_verifier_->Verify(cert, hostname, ocsp_response, + flags, crl_set, verify_result, + callback, out_req, net_log); +} + +bool AtomCertVerifier::SupportsOCSPStapling() { + if (handler_.is_null()) + return default_cert_verifier_->SupportsOCSPStapling(); + return false; +} + +void AtomCertVerifier::OnSetCertificateVerifier( + const CertificateVerifier& handler) { + handler_ = handler; +} + +void AtomCertVerifier::OnRemoveCertificateVerifier() { + handler_.Reset(); +} + +} // namespace atom diff --git a/atom/browser/atom_cert_verifier.h b/atom/browser/atom_cert_verifier.h new file mode 100644 index 000000000000..a9e16e268837 --- /dev/null +++ b/atom/browser/atom_cert_verifier.h @@ -0,0 +1,47 @@ +// Copyright (c) 2015 GitHub, Inc. +// Use of this source code is governed by the MIT license that can be +// found in the LICENSE file. + +#ifndef ATOM_BROWSER_ATOM_CERT_VERIFIER_H_ +#define ATOM_BROWSER_ATOM_CERT_VERIFIER_H_ + +#include + +#include "atom/browser/browser_observer.h" +#include "net/cert/cert_verifier.h" + +namespace atom { + +class AtomCertVerifier : public net::CertVerifier, + public BrowserObserver { + public: + AtomCertVerifier(); + ~AtomCertVerifier() override; + + // net::CertVerifier: + int Verify(net::X509Certificate* cert, + const std::string& hostname, + const std::string& ocsp_response, + int flags, + net::CRLSet* crl_set, + net::CertVerifyResult* verify_result, + const net::CompletionCallback& callback, + scoped_ptr* out_req, + const net::BoundNetLog& net_log) override; + bool SupportsOCSPStapling() override; + + protected: + void OnSetCertificateVerifier(const CertificateVerifier& handler) override; + void OnRemoveCertificateVerifier() override; + + private: + scoped_ptr default_cert_verifier_; + + CertificateVerifier handler_; + + DISALLOW_COPY_AND_ASSIGN(AtomCertVerifier); +}; + +} // namespace atom + +#endif // ATOM_BROWSER_ATOM_CERT_VERIFIER_H_ diff --git a/atom/browser/browser.cc b/atom/browser/browser.cc index 57741786520d..2e743ec7535a 100644 --- a/atom/browser/browser.cc +++ b/atom/browser/browser.cc @@ -156,6 +156,16 @@ void Browser::RequestLogin(LoginHandler* login_handler) { FOR_EACH_OBSERVER(BrowserObserver, observers_, OnLogin(login_handler)); } +void Browser::SetCertificateVerifier(const CertificateVerifier& handler) { + FOR_EACH_OBSERVER(BrowserObserver, + observers_, + OnSetCertificateVerifier(handler)); +} + +void Browser::RemoveCertificateVerifier() { + FOR_EACH_OBSERVER(BrowserObserver, observers_, OnRemoveCertificateVerifier()); +} + void Browser::NotifyAndShutdown() { if (is_shutdown_) return; diff --git a/atom/browser/browser.h b/atom/browser/browser.h index e20db080b67a..04278f1b2711 100644 --- a/atom/browser/browser.h +++ b/atom/browser/browser.h @@ -135,6 +135,10 @@ class Browser : public WindowListObserver { // Request basic auth login. void RequestLogin(LoginHandler* login_handler); + // Set.remove the ceritificate verifier provided by the user. + void SetCertificateVerifier(const CertificateVerifier& handler); + void RemoveCertificateVerifier(); + void AddObserver(BrowserObserver* obs) { observers_.AddObserver(obs); } diff --git a/atom/browser/browser_observer.h b/atom/browser/browser_observer.h index 7dccbfbac3c5..679a29746324 100644 --- a/atom/browser/browser_observer.h +++ b/atom/browser/browser_observer.h @@ -7,6 +7,7 @@ #include +#include "base/callback.h" #include "base/memory/scoped_ptr.h" #include "content/public/browser/client_certificate_delegate.h" @@ -16,12 +17,19 @@ class WebContents; namespace net { class SSLCertRequestInfo; +class X509Certificate; } namespace atom { class LoginHandler; +// A callback specialisation used by AtomCertVerifier during verification. +using CertificateVerifier = + base::Callback, + const base::Callback&)>; + class BrowserObserver { public: // The browser is about to close all windows. @@ -62,6 +70,9 @@ class BrowserObserver { // The browser requests HTTP login. virtual void OnLogin(LoginHandler* login_handler) {} + virtual void OnSetCertificateVerifier(const CertificateVerifier& handler) {} + virtual void OnRemoveCertificateVerifier() {} + protected: virtual ~BrowserObserver() {} }; diff --git a/atom/common/native_mate_converters/net_converter.cc b/atom/common/native_mate_converters/net_converter.cc index 4796d962660a..4749a4fedfc2 100644 --- a/atom/common/native_mate_converters/net_converter.cc +++ b/atom/common/native_mate_converters/net_converter.cc @@ -4,7 +4,11 @@ #include "atom/common/native_mate_converters/net_converter.h" +#include + +#include "atom/common/node_includes.h" #include "native_mate/dictionary.h" +#include "net/cert/x509_certificate.h" #include "net/url_request/url_request.h" namespace mate { @@ -31,4 +35,19 @@ v8::Local Converter::ToV8( return mate::ConvertToV8(isolate, dict); } +// static +v8::Local Converter>::ToV8( + v8::Isolate* isolate, const scoped_refptr& val) { + mate::Dictionary dict(isolate, v8::Object::New(isolate)); + std::string encoded_data; + net::X509Certificate::GetPEMEncoded( + val->os_cert_handle(), &encoded_data); + auto buffer = node::Buffer::Copy(isolate, + encoded_data.data(), + encoded_data.size()).ToLocalChecked(); + dict.Set("data", buffer); + dict.Set("issuerName", val->issuer().GetDisplayName()); + return dict.GetHandle(); +} + } // namespace mate diff --git a/atom/common/native_mate_converters/net_converter.h b/atom/common/native_mate_converters/net_converter.h index 352c613eaabb..b11c55929b98 100644 --- a/atom/common/native_mate_converters/net_converter.h +++ b/atom/common/native_mate_converters/net_converter.h @@ -5,11 +5,13 @@ #ifndef ATOM_COMMON_NATIVE_MATE_CONVERTERS_NET_CONVERTER_H_ #define ATOM_COMMON_NATIVE_MATE_CONVERTERS_NET_CONVERTER_H_ +#include "base/memory/ref_counted.h" #include "native_mate/converter.h" namespace net { class AuthChallengeInfo; class URLRequest; +class X509Certificate; } namespace mate { @@ -26,6 +28,12 @@ struct Converter { const net::AuthChallengeInfo* val); }; +template<> +struct Converter> { + static v8::Local ToV8(v8::Isolate* isolate, + const scoped_refptr& val); +}; + } // namespace mate #endif // ATOM_COMMON_NATIVE_MATE_CONVERTERS_NET_CONVERTER_H_ diff --git a/docs/api/app.md b/docs/api/app.md index fdb9f9980592..ce377d915dac 100644 --- a/docs/api/app.md +++ b/docs/api/app.md @@ -139,8 +139,8 @@ Returns: * `webContents` [WebContents](web-contents.md) * `url` URL * `certificateList` [Objects] - * `data` PEM encoded data - * `issuerName` Issuer's Common Name + * `data` Buffer - PEM encoded data + * `issuerName` String - Issuer's Common Name * `callback` Function Emitted when a client certificate is requested. diff --git a/docs/api/session.md b/docs/api/session.md index 25db92b73b25..c0f1e8fa7955 100644 --- a/docs/api/session.md +++ b/docs/api/session.md @@ -220,3 +220,34 @@ window.webContents.session.enableNetworkEmulation({offline: true}); Disables any network emulation already active for the `session`. Resets to the original network configuration. + +### `session.setCertificateVerifier(handler)` + +* `handler` Function + * `hostname` String + * `certificate` Object + * `data` Buffer - PEM encoded data + * `issuerName` String + * `callback` Function + +Sets the certificate verifier for the `session`, will be called +whenever a server certificate verification is requested by the +network layer with `hostname`, `certificate` and `callback`. +`callback` should be called with a boolean response to +indicate continuation or cancellation of the request. + +```js +var handler = function(hostname, certificate, callback) { + if (hostname == "github.com") { + // verification logic + callback(true) + } + callback(false) +} + +window.webContents.session.setCertificateVerifier(handler) +``` + +### `session.removeCertificateVerifier()` + +Removes the certificate verifier provided for the `session`. diff --git a/filenames.gypi b/filenames.gypi index 4dc709c5ec57..9618a962cd97 100644 --- a/filenames.gypi +++ b/filenames.gypi @@ -128,6 +128,8 @@ 'atom/browser/atom_download_manager_delegate.h', 'atom/browser/atom_browser_main_parts.cc', 'atom/browser/atom_browser_main_parts.h', + 'atom/browser/atom_cert_verifier.cc', + 'atom/browser/atom_cert_verifier.h', 'atom/browser/atom_browser_main_parts_mac.mm', 'atom/browser/atom_browser_main_parts_posix.cc', 'atom/browser/atom_javascript_dialog_manager.cc', From 3d5437e0a45b884d850ff125d38c0c49edc4d86f Mon Sep 17 00:00:00 2001 From: Robo Date: Fri, 13 Nov 2015 02:36:38 +0530 Subject: [PATCH 134/249] tracing: fix docs and allow null values in file path conversion fromv8 --- atom/common/native_mate_converters/file_path_converter.h | 3 +++ docs/api/content-tracing.md | 9 +++++++-- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/atom/common/native_mate_converters/file_path_converter.h b/atom/common/native_mate_converters/file_path_converter.h index 468f506de8a3..7df1289e243b 100644 --- a/atom/common/native_mate_converters/file_path_converter.h +++ b/atom/common/native_mate_converters/file_path_converter.h @@ -21,6 +21,9 @@ struct Converter { static bool FromV8(v8::Isolate* isolate, v8::Local val, base::FilePath* out) { + if (val->IsNull()) + return true; + base::FilePath::StringType path; if (Converter::FromV8(isolate, val, &path)) { *out = base::FilePath(path); diff --git a/docs/api/content-tracing.md b/docs/api/content-tracing.md index 2e05fc67668f..9fc335b3bc18 100644 --- a/docs/api/content-tracing.md +++ b/docs/api/content-tracing.md @@ -6,9 +6,14 @@ so you need to open `chrome://tracing/` in a Chrome browser and load the generated file to view the result. ```javascript -var contentTracing = require('content-tracing'); +const contentTracing = require('content-tracing'); -contentTracing.startRecording('*', contentTracing.DEFAULT_OPTIONS, function() { +const options = { + categoryFilter: '*', + traceOptions: 'record-until-full,enable-sampling' +} + +contentTracing.startRecording(options, function() { console.log('Tracing started'); setTimeout(function() { From bb439c5f1c1a6a4af88f80067bc7eac262c11dff Mon Sep 17 00:00:00 2001 From: Robo Date: Fri, 13 Nov 2015 02:43:21 +0530 Subject: [PATCH 135/249] browser: check window liveness before setting title --- atom/browser/native_window.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/atom/browser/native_window.cc b/atom/browser/native_window.cc index 8027fdfa4c1c..ba5dad74f523 100644 --- a/atom/browser/native_window.cc +++ b/atom/browser/native_window.cc @@ -512,7 +512,7 @@ void NativeWindow::TitleWasSet(content::NavigationEntry* entry, FOR_EACH_OBSERVER(NativeWindowObserver, observers_, OnPageTitleUpdated(&prevent_default, text)); - if (!prevent_default) + if (!prevent_default && !is_closed_) SetTitle(text); } From 37e6e6fab78ed0fdb1885301359350cfcb8ffe07 Mon Sep 17 00:00:00 2001 From: Robo Date: Fri, 13 Nov 2015 01:25:23 +0530 Subject: [PATCH 136/249] emit verify-certificate event for handling verification --- atom/browser/api/atom_api_session.cc | 30 ++++- atom/browser/api/atom_api_session.h | 7 ++ atom/browser/atom_cert_verifier.cc | 159 +++++++++++++++++++++------ atom/browser/atom_cert_verifier.h | 125 +++++++++++++++++++-- atom/browser/browser.cc | 10 +- atom/browser/browser.h | 7 +- atom/browser/browser_observer.h | 13 +-- docs/api/session.md | 55 ++++----- 8 files changed, 313 insertions(+), 93 deletions(-) diff --git a/atom/browser/api/atom_api_session.cc b/atom/browser/api/atom_api_session.cc index f94d879fcc15..ecb8bba3a3c2 100644 --- a/atom/browser/api/atom_api_session.cc +++ b/atom/browser/api/atom_api_session.cc @@ -239,12 +239,24 @@ void SetProxyInIO(net::URLRequestContextGetter* getter, RunCallbackInUI(callback); } +void PassVerificationResult( + scoped_refptr request, + bool success) { + int result = net::OK; + if (!success) + result = net::ERR_FAILED; + request->ContinueWithResult(result); +} + } // namespace Session::Session(AtomBrowserContext* browser_context) : browser_context_(browser_context) { AttachAsUserData(browser_context); + // Observe Browser to get certificate verification notification. + Browser::Get()->AddObserver(this); + // Observe DownloadManger to get download notifications. content::BrowserContext::GetDownloadManager(browser_context)-> AddObserver(this); @@ -253,9 +265,22 @@ Session::Session(AtomBrowserContext* browser_context) Session::~Session() { content::BrowserContext::GetDownloadManager(browser_context())-> RemoveObserver(this); + Browser::Get()->RemoveObserver(this); Destroy(); } +void Session::OnCertVerification( + const scoped_refptr& request) { + bool prevent_default = Emit( + "verify-certificate", + request->hostname(), + request->certificate(), + base::Bind(&PassVerificationResult, request)); + + if (!prevent_default) + request->ContinueWithResult(net::ERR_IO_PENDING); +} + void Session::OnDownloadCreated(content::DownloadManager* manager, content::DownloadItem* item) { auto web_contents = item->GetWebContents(); @@ -367,7 +392,6 @@ v8::Local Session::Cookies(v8::Isolate* isolate) { mate::ObjectTemplateBuilder Session::GetObjectTemplateBuilder( v8::Isolate* isolate) { - auto browser = base::Unretained(Browser::Get()); return mate::ObjectTemplateBuilder(isolate) .SetMethod("resolveProxy", &Session::ResolveProxy) .SetMethod("clearCache", &Session::ClearCache) @@ -376,10 +400,6 @@ mate::ObjectTemplateBuilder Session::GetObjectTemplateBuilder( .SetMethod("setDownloadPath", &Session::SetDownloadPath) .SetMethod("enableNetworkEmulation", &Session::EnableNetworkEmulation) .SetMethod("disableNetworkEmulation", &Session::DisableNetworkEmulation) - .SetMethod("setCertificateVerifier", - base::Bind(&Browser::SetCertificateVerifier, browser)) - .SetMethod("removeCertificateVerifier", - base::Bind(&Browser::RemoveCertificateVerifier, browser)) .SetProperty("cookies", &Session::Cookies); } diff --git a/atom/browser/api/atom_api_session.h b/atom/browser/api/atom_api_session.h index 39712f6c8486..e6ce5a5842db 100644 --- a/atom/browser/api/atom_api_session.h +++ b/atom/browser/api/atom_api_session.h @@ -8,6 +8,8 @@ #include #include "atom/browser/api/trackable_object.h" +#include "atom/browser/atom_cert_verifier.h" +#include "atom/browser/browser_observer.h" #include "content/public/browser/download_manager.h" #include "native_mate/handle.h" #include "net/base/completion_callback.h" @@ -34,6 +36,7 @@ class AtomBrowserContext; namespace api { class Session: public mate::TrackableObject, + public BrowserObserver, public content::DownloadManager::Observer { public: using ResolveProxyCallback = base::Callback; @@ -52,6 +55,10 @@ class Session: public mate::TrackableObject, explicit Session(AtomBrowserContext* browser_context); ~Session(); + // BrowserObserver: + void OnCertVerification( + const scoped_refptr&) override; + // content::DownloadManager::Observer: void OnDownloadCreated(content::DownloadManager* manager, content::DownloadItem* item) override; diff --git a/atom/browser/atom_cert_verifier.cc b/atom/browser/atom_cert_verifier.cc index d8d1cb112dc2..f5afdd35719b 100644 --- a/atom/browser/atom_cert_verifier.cc +++ b/atom/browser/atom_cert_verifier.cc @@ -6,36 +6,108 @@ #include "atom/browser/browser.h" #include "atom/common/native_mate_converters/net_converter.h" +#include "base/callback_helpers.h" +#include "base/sha1.h" +#include "base/stl_util.h" #include "content/public/browser/browser_thread.h" #include "net/base/net_errors.h" -#include "net/cert/x509_certificate.h" using content::BrowserThread; namespace atom { -namespace { - -void RunResult(const net::CompletionCallback& callback, bool success) { - DCHECK_CURRENTLY_ON(BrowserThread::UI); - - int result = net::OK; - if (!success) - result = net::ERR_FAILED; - - BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, - base::Bind(callback, result)); +AtomCertVerifier::RequestParams::RequestParams( + const net::SHA1HashValue cert_fingerprint, + const net::SHA1HashValue ca_fingerprint, + const std::string& hostname_arg, + const std::string& ocsp_response_arg, + int flags_arg) + : hostname(hostname_arg), + ocsp_response(ocsp_response_arg), + flags(flags_arg) { + hash_values.reserve(3); + net::SHA1HashValue ocsp_hash; + base::SHA1HashBytes( + reinterpret_cast(ocsp_response.data()), + ocsp_response.size(), ocsp_hash.data); + hash_values.push_back(ocsp_hash); + hash_values.push_back(cert_fingerprint); + hash_values.push_back(ca_fingerprint); } -} // namespace +bool AtomCertVerifier::RequestParams::operator<( + const RequestParams& other) const { + if (flags != other.flags) + return flags < other.flags; + if (hostname != other.hostname) + return hostname < other.hostname; + return std::lexicographical_compare( + hash_values.begin(), + hash_values.end(), + other.hash_values.begin(), + other.hash_values.end(), + net::SHA1HashValueLessThan()); +} + +void AtomCertVerifier::CertVerifyRequest::RunResult(int result) { + DCHECK_CURRENTLY_ON(BrowserThread::IO); + + for (auto& callback : callbacks_) + callback.Run(result); + cert_verifier_->RemoveRequest(this); + Release(); +} + +void AtomCertVerifier::CertVerifyRequest::DelegateToDefaultVerifier() { + DCHECK_CURRENTLY_ON(BrowserThread::IO); + + int rv = cert_verifier_->default_cert_verifier()->Verify( + certificate_.get(), + key_.hostname, + key_.ocsp_response, + key_.flags, + crl_set_.get(), + verify_result_, + base::Bind(&CertVerifyRequest::RunResult, + weak_ptr_factory_.GetWeakPtr()), + &new_out_req_, + net_log_); + + if (rv != net::ERR_IO_PENDING && !callbacks_.empty()) { + for (auto& callback : callbacks_) + callback.Run(rv); + cert_verifier_->RemoveRequest(this); + Release(); + } +} + +void AtomCertVerifier::CertVerifyRequest::ContinueWithResult(int result) { + DCHECK_CURRENTLY_ON(BrowserThread::UI); + + if (handled_) + return; + + handled_ = true; + + if (result != net::ERR_IO_PENDING) { + BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, + base::Bind(&CertVerifyRequest::RunResult, + weak_ptr_factory_.GetWeakPtr(), + result)); + return; + } + + BrowserThread::PostTask( + BrowserThread::IO, FROM_HERE, + base::Bind(&CertVerifyRequest::DelegateToDefaultVerifier, + weak_ptr_factory_.GetWeakPtr())); +} AtomCertVerifier::AtomCertVerifier() { - Browser::Get()->AddObserver(this); default_cert_verifier_.reset(net::CertVerifier::CreateDefault()); } AtomCertVerifier::~AtomCertVerifier() { - Browser::Get()->RemoveObserver(this); } int AtomCertVerifier::Verify( @@ -53,32 +125,57 @@ int AtomCertVerifier::Verify( if (callback.is_null() || !verify_result || hostname.empty()) return net::ERR_INVALID_ARGUMENT; - if (!handler_.is_null()) { + const RequestParams key(cert->fingerprint(), + cert->ca_fingerprint(), + hostname, + ocsp_response, + flags); + + CertVerifyRequest* request = FindRequest(key); + + if (!request) { + request = new CertVerifyRequest(this, + key, + cert, + crl_set, + verify_result, + out_req, + net_log); + requests_.insert(make_scoped_refptr(request)); + BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, - base::Bind(handler_, hostname, - make_scoped_refptr(cert), - base::Bind(&RunResult, callback))); - return net::ERR_IO_PENDING; + base::Bind(&Browser::RequestCertVerification, + base::Unretained(Browser::Get()), + make_scoped_refptr(request))); } - return default_cert_verifier_->Verify(cert, hostname, ocsp_response, - flags, crl_set, verify_result, - callback, out_req, net_log); + request->AddCompletionCallback(callback); + + return net::ERR_IO_PENDING; } bool AtomCertVerifier::SupportsOCSPStapling() { - if (handler_.is_null()) - return default_cert_verifier_->SupportsOCSPStapling(); - return false; + return true; } -void AtomCertVerifier::OnSetCertificateVerifier( - const CertificateVerifier& handler) { - handler_ = handler; +AtomCertVerifier::CertVerifyRequest* AtomCertVerifier::FindRequest( + const RequestParams& key) { + DCHECK_CURRENTLY_ON(BrowserThread::IO); + + auto it = std::lower_bound(requests_.begin(), + requests_.end(), + key, + CertVerifyRequestToRequestParamsComparator()); + if (it != requests_.end() && !(key < (*it)->key())) + return (*it).get(); + return nullptr; } -void AtomCertVerifier::OnRemoveCertificateVerifier() { - handler_.Reset(); +void AtomCertVerifier::RemoveRequest(CertVerifyRequest* request) { + DCHECK_CURRENTLY_ON(BrowserThread::IO); + + bool erased = requests_.erase(request) == 1; + DCHECK(erased); } } // namespace atom diff --git a/atom/browser/atom_cert_verifier.h b/atom/browser/atom_cert_verifier.h index a9e16e268837..27e530074d02 100644 --- a/atom/browser/atom_cert_verifier.h +++ b/atom/browser/atom_cert_verifier.h @@ -5,19 +5,108 @@ #ifndef ATOM_BROWSER_ATOM_CERT_VERIFIER_H_ #define ATOM_BROWSER_ATOM_CERT_VERIFIER_H_ +#include #include +#include -#include "atom/browser/browser_observer.h" +#include "base/memory/ref_counted.h" +#include "net/base/hash_value.h" #include "net/cert/cert_verifier.h" +#include "net/cert/crl_set.h" +#include "net/cert/x509_certificate.h" +#include "net/log/net_log.h" namespace atom { -class AtomCertVerifier : public net::CertVerifier, - public BrowserObserver { +class AtomCertVerifier : public net::CertVerifier { public: + struct RequestParams { + RequestParams( + const net::SHA1HashValue cert_fingerprint, + const net::SHA1HashValue ca_fingerprint, + const std::string& hostname_arg, + const std::string& ocsp_response, + int flags); + ~RequestParams() {} + + bool operator<(const RequestParams& other) const; + + std::string hostname; + std::string ocsp_response; + int flags; + std::vector hash_values; + }; + + class CertVerifyRequest + : public net::CertVerifier::Request, + public base::RefCountedThreadSafe { + public: + CertVerifyRequest( + AtomCertVerifier* cert_verifier, + const RequestParams& key, + scoped_refptr cert, + scoped_refptr crl_set, + net::CertVerifyResult* verify_result, + scoped_ptr* out_req, + const net::BoundNetLog& net_log) + : cert_verifier_(cert_verifier), + key_(key), + certificate_(cert), + crl_set_(crl_set), + verify_result_(verify_result), + out_req_(out_req), + net_log_(net_log), + handled_(false), + weak_ptr_factory_(this) { + out_req_->reset(this); + new_out_req_.reset(new net::CertVerifier::Request()); + } + + ~CertVerifyRequest() { + out_req_->reset(); + } + + void RunResult(int result); + void DelegateToDefaultVerifier(); + void ContinueWithResult(int result); + + void AddCompletionCallback(net::CompletionCallback callback) { + callbacks_.push_back(callback); + } + + const RequestParams key() const { return key_; } + + std::string hostname() const { return key_.hostname; } + + scoped_refptr certificate() const { + return certificate_; + } + + private: + friend class base::RefCountedThreadSafe; + + AtomCertVerifier* cert_verifier_; + const RequestParams key_; + + scoped_refptr certificate_; + scoped_refptr crl_set_; + net::CertVerifyResult* verify_result_; + scoped_ptr* out_req_; + scoped_ptr new_out_req_; + const net::BoundNetLog net_log_; + + std::vector callbacks_; + bool handled_; + + base::WeakPtrFactory weak_ptr_factory_; + + DISALLOW_COPY_AND_ASSIGN(CertVerifyRequest); + }; + AtomCertVerifier(); ~AtomCertVerifier() override; + protected: // net::CertVerifier: int Verify(net::X509Certificate* cert, const std::string& hostname, @@ -30,14 +119,34 @@ class AtomCertVerifier : public net::CertVerifier, const net::BoundNetLog& net_log) override; bool SupportsOCSPStapling() override; - protected: - void OnSetCertificateVerifier(const CertificateVerifier& handler) override; - void OnRemoveCertificateVerifier() override; + net::CertVerifier* default_cert_verifier() const { + return default_cert_verifier_.get(); + } private: - scoped_ptr default_cert_verifier_; + CertVerifyRequest* FindRequest(const RequestParams& key); + void RemoveRequest(CertVerifyRequest* request); - CertificateVerifier handler_; + struct CertVerifyRequestToRequestParamsComparator { + bool operator()(const scoped_refptr request, + const RequestParams& key) const { + return request->key() < key; + } + }; + + struct CertVerifyRequestComparator { + bool operator()(const scoped_refptr req1, + const scoped_refptr req2) const { + return req1->key() < req2->key(); + } + }; + + using ActiveRequestSet = + std::set, + CertVerifyRequestComparator>; + ActiveRequestSet requests_; + + scoped_ptr default_cert_verifier_; DISALLOW_COPY_AND_ASSIGN(AtomCertVerifier); }; diff --git a/atom/browser/browser.cc b/atom/browser/browser.cc index 2e743ec7535a..a3e1f0247cff 100644 --- a/atom/browser/browser.cc +++ b/atom/browser/browser.cc @@ -7,6 +7,7 @@ #include #include "atom/browser/atom_browser_main_parts.h" +#include "atom/browser/atom_cert_verifier.h" #include "atom/browser/native_window.h" #include "atom/browser/window_list.h" #include "base/message_loop/message_loop.h" @@ -156,14 +157,11 @@ void Browser::RequestLogin(LoginHandler* login_handler) { FOR_EACH_OBSERVER(BrowserObserver, observers_, OnLogin(login_handler)); } -void Browser::SetCertificateVerifier(const CertificateVerifier& handler) { +void Browser::RequestCertVerification( + const scoped_refptr& request) { FOR_EACH_OBSERVER(BrowserObserver, observers_, - OnSetCertificateVerifier(handler)); -} - -void Browser::RemoveCertificateVerifier() { - FOR_EACH_OBSERVER(BrowserObserver, observers_, OnRemoveCertificateVerifier()); + OnCertVerification(request)); } void Browser::NotifyAndShutdown() { diff --git a/atom/browser/browser.h b/atom/browser/browser.h index 04278f1b2711..b0ac7d272130 100644 --- a/atom/browser/browser.h +++ b/atom/browser/browser.h @@ -29,6 +29,7 @@ class MenuModel; namespace atom { +class AtomCertVerifier; class LoginHandler; // This class is used for control application-wide operations. @@ -135,9 +136,9 @@ class Browser : public WindowListObserver { // Request basic auth login. void RequestLogin(LoginHandler* login_handler); - // Set.remove the ceritificate verifier provided by the user. - void SetCertificateVerifier(const CertificateVerifier& handler); - void RemoveCertificateVerifier(); + // Request Server Certificate Verification. + void RequestCertVerification( + const scoped_refptr& request); void AddObserver(BrowserObserver* obs) { observers_.AddObserver(obs); diff --git a/atom/browser/browser_observer.h b/atom/browser/browser_observer.h index 679a29746324..75f63d85e2b0 100644 --- a/atom/browser/browser_observer.h +++ b/atom/browser/browser_observer.h @@ -7,7 +7,7 @@ #include -#include "base/callback.h" +#include "atom/browser/atom_cert_verifier.h" #include "base/memory/scoped_ptr.h" #include "content/public/browser/client_certificate_delegate.h" @@ -24,12 +24,6 @@ namespace atom { class LoginHandler; -// A callback specialisation used by AtomCertVerifier during verification. -using CertificateVerifier = - base::Callback, - const base::Callback&)>; - class BrowserObserver { public: // The browser is about to close all windows. @@ -70,8 +64,9 @@ class BrowserObserver { // The browser requests HTTP login. virtual void OnLogin(LoginHandler* login_handler) {} - virtual void OnSetCertificateVerifier(const CertificateVerifier& handler) {} - virtual void OnRemoveCertificateVerifier() {} + // The browser requests Server Certificate Verification. + virtual void OnCertVerification( + const scoped_refptr& request) {} protected: virtual ~BrowserObserver() {} diff --git a/docs/api/session.md b/docs/api/session.md index c0f1e8fa7955..928128cca32c 100644 --- a/docs/api/session.md +++ b/docs/api/session.md @@ -34,6 +34,30 @@ session.on('will-download', function(event, item, webContents) { }); ``` +### Event: 'verify-certificate' + +* `event` Event +* `hostname` String +* `certificate` Object + * `data` Buffer - PEM encoded data + * `issuerName` String +* `callback` Function + +Fired whenever a server certificate verification is requested by the +network layer with `hostname`, `certificate` and `callback`. +`callback` should be called with a boolean response to +indicate continuation or cancellation of the request. + +```js +session.on('verify-certificate', function(event, hostname, certificate, callback) { + if (hostname == "github.com") { + // verification logic + callback(true); + } + callback(false); +}); +``` + ## Methods The `session` object has the following methods: @@ -220,34 +244,3 @@ window.webContents.session.enableNetworkEmulation({offline: true}); Disables any network emulation already active for the `session`. Resets to the original network configuration. - -### `session.setCertificateVerifier(handler)` - -* `handler` Function - * `hostname` String - * `certificate` Object - * `data` Buffer - PEM encoded data - * `issuerName` String - * `callback` Function - -Sets the certificate verifier for the `session`, will be called -whenever a server certificate verification is requested by the -network layer with `hostname`, `certificate` and `callback`. -`callback` should be called with a boolean response to -indicate continuation or cancellation of the request. - -```js -var handler = function(hostname, certificate, callback) { - if (hostname == "github.com") { - // verification logic - callback(true) - } - callback(false) -} - -window.webContents.session.setCertificateVerifier(handler) -``` - -### `session.removeCertificateVerifier()` - -Removes the certificate verifier provided for the `session`. From 852500e5faade74d7cf41f257150af7f6c752a63 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Fri, 13 Nov 2015 09:38:22 +0800 Subject: [PATCH 137/249] Fix a few places using old style require --- atom/browser/api/lib/auto-updater/auto-updater-win.coffee | 4 ++-- atom/common/api/lib/clipboard.coffee | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/atom/browser/api/lib/auto-updater/auto-updater-win.coffee b/atom/browser/api/lib/auto-updater/auto-updater-win.coffee index a9a61d8efe3f..12ebedaaf71c 100644 --- a/atom/browser/api/lib/auto-updater/auto-updater-win.coffee +++ b/atom/browser/api/lib/auto-updater/auto-updater-win.coffee @@ -1,6 +1,6 @@ -app = require 'app' -url = require 'url' +{app} = require 'electron' {EventEmitter} = require 'events' +url = require 'url' squirrelUpdate = require './squirrel-update-win' diff --git a/atom/common/api/lib/clipboard.coffee b/atom/common/api/lib/clipboard.coffee index b337f7195079..0ea97d86ba81 100644 --- a/atom/common/api/lib/clipboard.coffee +++ b/atom/common/api/lib/clipboard.coffee @@ -1,6 +1,6 @@ if process.platform is 'linux' and process.type is 'renderer' {remote} = require 'electron' # On Linux we could not access clipboard in renderer process. - module.exports = remote.require 'clipboard' + module.exports = remote.getBuiltin 'clipboard' else module.exports = process.atomBinding 'clipboard' From bfaa50a79ea2c28c7a0c71fde17efd048ed6eaff Mon Sep 17 00:00:00 2001 From: Robo Date: Fri, 13 Nov 2015 07:44:05 +0530 Subject: [PATCH 138/249] retrieve download directory using on linux --- atom/browser/api/atom_api_app.cc | 17 ++++++++++++++++- docs/api/app.md | 1 + 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/atom/browser/api/atom_api_app.cc b/atom/browser/api/atom_api_app.cc index 1c5c2c04f145..d6d961a08dc4 100644 --- a/atom/browser/api/atom_api_app.cc +++ b/atom/browser/api/atom_api_app.cc @@ -22,6 +22,7 @@ #include "base/command_line.h" #include "base/environment.h" #include "base/files/file_path.h" +#include "base/nix/xdg_util.h" #include "base/path_service.h" #include "brightray/browser/brightray_paths.h" #include "content/public/browser/client_certificate_delegate.h" @@ -155,6 +156,17 @@ void PassLoginInformation(scoped_refptr login_handler, login_handler->CancelAuth(); } +bool GetUserDownloadsDirectory(base::FilePath* path) { +#if defined(OS_LINUX) + *path = base::nix::GetXDGUserDirectory("DOWNLOAD", "Downloads"); + return true; +#elif defined(OS_MACOSX) + return false; +#elif defined(OS_WIN) + return false; +#endif +} + } // namespace App::App() { @@ -272,8 +284,11 @@ base::FilePath App::GetPath(mate::Arguments* args, const std::string& name) { int key = GetPathConstant(name); if (key >= 0) succeed = PathService::Get(key, &path); - if (!succeed) + if (!succeed) { + if (name == "downloads" && GetUserDownloadsDirectory(&path)) + return path; args->ThrowError("Failed to get path"); + } return path; } diff --git a/docs/api/app.md b/docs/api/app.md index fdb9f9980592..4282b2d133ac 100644 --- a/docs/api/app.md +++ b/docs/api/app.md @@ -241,6 +241,7 @@ You can request the following paths by the name: * `userDesktop` The current user's Desktop directory. * `exe` The current executable file. * `module` The `libchromiumcontent` library. +* `downloads` User's download directory. ### `app.setPath(name, path)` From f2439cefd0dba89df02993011ac46dd32a1f79a6 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Fri, 13 Nov 2015 10:58:10 +0800 Subject: [PATCH 139/249] linux: Don't throw error when using autoUpdater Fix #3194. --- atom/browser/api/lib/auto-updater.coffee | 10 ++++------ ...o-updater-mac.coffee => auto-updater-native.coffee} | 0 filenames.gypi | 2 +- 3 files changed, 5 insertions(+), 7 deletions(-) rename atom/browser/api/lib/auto-updater/{auto-updater-mac.coffee => auto-updater-native.coffee} (100%) diff --git a/atom/browser/api/lib/auto-updater.coffee b/atom/browser/api/lib/auto-updater.coffee index 41b78a00d7e0..d5e69e2a5c2e 100644 --- a/atom/browser/api/lib/auto-updater.coffee +++ b/atom/browser/api/lib/auto-updater.coffee @@ -1,7 +1,5 @@ -switch process.platform - when 'win32' - module.exports = require './auto-updater/auto-updater-win' - when 'darwin' - module.exports = require './auto-updater/auto-updater-mac' +module.exports = + if process.platform is 'win32' + require './auto-updater/auto-updater-win' else - throw new Error('auto-updater is not implemented on this platform') + require './auto-updater/auto-updater-native' diff --git a/atom/browser/api/lib/auto-updater/auto-updater-mac.coffee b/atom/browser/api/lib/auto-updater/auto-updater-native.coffee similarity index 100% rename from atom/browser/api/lib/auto-updater/auto-updater-mac.coffee rename to atom/browser/api/lib/auto-updater/auto-updater-native.coffee diff --git a/filenames.gypi b/filenames.gypi index de7ee26c5e41..658c8e76b6b0 100644 --- a/filenames.gypi +++ b/filenames.gypi @@ -10,7 +10,7 @@ 'coffee_sources': [ 'atom/browser/api/lib/app.coffee', 'atom/browser/api/lib/auto-updater.coffee', - 'atom/browser/api/lib/auto-updater/auto-updater-mac.coffee', + 'atom/browser/api/lib/auto-updater/auto-updater-native.coffee', 'atom/browser/api/lib/auto-updater/auto-updater-win.coffee', 'atom/browser/api/lib/auto-updater/squirrel-update-win.coffee', 'atom/browser/api/lib/browser-window.coffee', From 78934dceb9dee799b07aedd8c3bdc1ddf42cae6c Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Fri, 13 Nov 2015 12:22:08 +0800 Subject: [PATCH 140/249] Cleanup and docs for the --js-flags --- atom/browser/javascript_environment.cc | 17 +++++++---------- docs/api/chrome-command-line-switches.md | 9 +++++++++ 2 files changed, 16 insertions(+), 10 deletions(-) diff --git a/atom/browser/javascript_environment.cc b/atom/browser/javascript_environment.cc index ae4f8e55e76e..dc27cedee56f 100644 --- a/atom/browser/javascript_environment.cc +++ b/atom/browser/javascript_environment.cc @@ -2,11 +2,12 @@ // Use of this source code is governed by the MIT license that can be // found in the LICENSE file. -#include - #include "atom/browser/javascript_environment.h" +#include + #include "base/command_line.h" +#include "content/public/common/content_switches.h" #include "gin/array_buffer.h" #include "gin/v8_initializer.h" @@ -30,17 +31,13 @@ bool JavascriptEnvironment::Initialize() { v8::V8::SetFlagsFromString(expose_debug_as, sizeof(expose_debug_as) - 1); } - const std::string js_flags_switch = "js-flags"; - - if (cmd->HasSwitch(js_flags_switch)) { - const char *js_flags_value = - (cmd->GetSwitchValueASCII(js_flags_switch)).c_str(); - v8::V8::SetFlagsFromString(js_flags_value, strlen(js_flags_value)); - } + // --js-flags. + std::string js_flags = cmd->GetSwitchValueASCII(switches::kJavaScriptFlags); + if (!js_flags.empty()) + v8::V8::SetFlagsFromString(js_flags.c_str(), js_flags.size()); gin::IsolateHolder::Initialize(gin::IsolateHolder::kNonStrictMode, gin::ArrayBufferAllocator::SharedInstance()); - return true; } diff --git a/docs/api/chrome-command-line-switches.md b/docs/api/chrome-command-line-switches.md index d163a726d40e..c1adf3c425f8 100644 --- a/docs/api/chrome-command-line-switches.md +++ b/docs/api/chrome-command-line-switches.md @@ -31,6 +31,15 @@ Disables the disk cache for HTTP requests. Enables remote debugging over HTTP on the specified `port`. +## --js-flags=`flags` + +Specifies the flags passed to JS engine. It has to be passed when starting +Electron if you want to enable the `flags` in the main process. + +```bash +$ electron --js-flags="--harmony_proxies --harmony_collections" your-app +``` + ## --proxy-server=`address:port` Use a specified proxy server, which overrides the system setting. This switch From 83ae9f8d71007944b9f9e5b631740ea7a416e1b9 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Fri, 13 Nov 2015 12:37:12 +0800 Subject: [PATCH 141/249] Import the chrome_paths code --- .../chrome/common/chrome_constants.cc | 68 ++ chromium_src/chrome/common/chrome_constants.h | 50 ++ chromium_src/chrome/common/chrome_paths.cc | 610 ++++++++++++++++++ chromium_src/chrome/common/chrome_paths.h | 152 +++++ .../chrome/common/chrome_paths_internal.h | 112 ++++ .../chrome/common/chrome_paths_linux.cc | 145 +++++ .../chrome/common/chrome_paths_mac.mm | 252 ++++++++ .../chrome/common/chrome_paths_win.cc | 122 ++++ filenames.gypi | 8 + 9 files changed, 1519 insertions(+) create mode 100644 chromium_src/chrome/common/chrome_constants.cc create mode 100644 chromium_src/chrome/common/chrome_constants.h create mode 100644 chromium_src/chrome/common/chrome_paths.cc create mode 100644 chromium_src/chrome/common/chrome_paths.h create mode 100644 chromium_src/chrome/common/chrome_paths_internal.h create mode 100644 chromium_src/chrome/common/chrome_paths_linux.cc create mode 100644 chromium_src/chrome/common/chrome_paths_mac.mm create mode 100644 chromium_src/chrome/common/chrome_paths_win.cc diff --git a/chromium_src/chrome/common/chrome_constants.cc b/chromium_src/chrome/common/chrome_constants.cc new file mode 100644 index 000000000000..1e7bd33a9658 --- /dev/null +++ b/chromium_src/chrome/common/chrome_constants.cc @@ -0,0 +1,68 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/common/chrome_constants.h" +#include "chrome/common/chrome_version.h" + +namespace chrome { + +// filenames +const base::FilePath::CharType kCacheDirname[] = FPL("Cache"); +const base::FilePath::CharType kChannelIDFilename[] = FPL("Origin Bound Certs"); +const base::FilePath::CharType kCookieFilename[] = FPL("Cookies"); +const base::FilePath::CharType kCRLSetFilename[] = + FPL("Certificate Revocation Lists"); +const base::FilePath::CharType kCustomDictionaryFileName[] = + FPL("Custom Dictionary.txt"); +const base::FilePath::CharType kExtensionActivityLogFilename[] = + FPL("Extension Activity"); +const base::FilePath::CharType kExtensionsCookieFilename[] = + FPL("Extension Cookies"); +const base::FilePath::CharType kFirstRunSentinel[] = FPL("First Run"); +const base::FilePath::CharType kGCMStoreDirname[] = FPL("GCM Store"); +const base::FilePath::CharType kLocalStateFilename[] = FPL("Local State"); +const base::FilePath::CharType kLocalStorePoolName[] = FPL("LocalStorePool"); +const base::FilePath::CharType kMediaCacheDirname[] = FPL("Media Cache"); +const base::FilePath::CharType kNetworkPersistentStateFilename[] = + FPL("Network Persistent State"); +const base::FilePath::CharType kOfflinePageArchviesDirname[] = + FPL("Offline Pages/archives"); +const base::FilePath::CharType kOfflinePageMetadataDirname[] = + FPL("Offline Pages/metadata"); +const base::FilePath::CharType kPreferencesFilename[] = FPL("Preferences"); +const base::FilePath::CharType kProtectedPreferencesFilenameDeprecated[] = + FPL("Protected Preferences"); +const base::FilePath::CharType kReadmeFilename[] = FPL("README"); +const base::FilePath::CharType kResetPromptMementoFilename[] = + FPL("Reset Prompt Memento"); +const base::FilePath::CharType kSafeBrowsingBaseFilename[] = + FPL("Safe Browsing"); +const base::FilePath::CharType kSecurePreferencesFilename[] = + FPL("Secure Preferences"); +const base::FilePath::CharType kServiceStateFileName[] = FPL("Service State"); +const base::FilePath::CharType kSingletonCookieFilename[] = + FPL("SingletonCookie"); +const base::FilePath::CharType kSingletonLockFilename[] = FPL("SingletonLock"); +const base::FilePath::CharType kSingletonSocketFilename[] = + FPL("SingletonSocket"); +const base::FilePath::CharType kSupervisedUserSettingsFilename[] = + FPL("Managed Mode Settings"); +const base::FilePath::CharType kThemePackFilename[] = FPL("Cached Theme.pak"); +const base::FilePath::CharType kThemePackMaterialDesignFilename[] = + FPL("Cached Theme Material Design.pak"); +const base::FilePath::CharType kWebAppDirname[] = FPL("Web Applications"); + +// File name of the Pepper Flash plugin on different platforms. +const base::FilePath::CharType kPepperFlashPluginFilename[] = +#if defined(OS_MACOSX) + FPL("PepperFlashPlayer.plugin"); +#elif defined(OS_WIN) + FPL("pepflashplayer.dll"); +#else // OS_LINUX, etc. + FPL("libpepflashplayer.so"); +#endif + +} // namespace chrome + +#undef FPL diff --git a/chromium_src/chrome/common/chrome_constants.h b/chromium_src/chrome/common/chrome_constants.h new file mode 100644 index 000000000000..e36eeeeff413 --- /dev/null +++ b/chromium_src/chrome/common/chrome_constants.h @@ -0,0 +1,50 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// A handful of resource-like constants related to the Chrome application. + +#ifndef CHROME_COMMON_CHROME_CONSTANTS_H_ +#define CHROME_COMMON_CHROME_CONSTANTS_H_ + +#include "base/files/file_path.h" + +namespace chrome { + +// filenames +extern const base::FilePath::CharType kCacheDirname[]; +extern const base::FilePath::CharType kChannelIDFilename[]; +extern const base::FilePath::CharType kCookieFilename[]; +extern const base::FilePath::CharType kCRLSetFilename[]; +extern const base::FilePath::CharType kCustomDictionaryFileName[]; +extern const base::FilePath::CharType kExtensionActivityLogFilename[]; +extern const base::FilePath::CharType kExtensionsCookieFilename[]; +extern const base::FilePath::CharType kFirstRunSentinel[]; +extern const base::FilePath::CharType kGCMStoreDirname[]; +extern const base::FilePath::CharType kLocalStateFilename[]; +extern const base::FilePath::CharType kLocalStorePoolName[]; +extern const base::FilePath::CharType kMediaCacheDirname[]; +extern const base::FilePath::CharType kNetworkPersistentStateFilename[]; +extern const base::FilePath::CharType kOfflinePageArchviesDirname[]; +extern const base::FilePath::CharType kOfflinePageMetadataDirname[]; +extern const base::FilePath::CharType kPreferencesFilename[]; +extern const base::FilePath::CharType kProtectedPreferencesFilenameDeprecated[]; +extern const base::FilePath::CharType kReadmeFilename[]; +extern const base::FilePath::CharType kResetPromptMementoFilename[]; +extern const base::FilePath::CharType kSafeBrowsingBaseFilename[]; +extern const base::FilePath::CharType kSecurePreferencesFilename[]; +extern const base::FilePath::CharType kServiceStateFileName[]; +extern const base::FilePath::CharType kSingletonCookieFilename[]; +extern const base::FilePath::CharType kSingletonLockFilename[]; +extern const base::FilePath::CharType kSingletonSocketFilename[]; +extern const base::FilePath::CharType kSupervisedUserSettingsFilename[]; +extern const base::FilePath::CharType kThemePackFilename[]; +extern const base::FilePath::CharType kThemePackMaterialDesignFilename[]; +extern const base::FilePath::CharType kWebAppDirname[]; + +// File name of the Pepper Flash plugin on different platforms. +extern const base::FilePath::CharType kPepperFlashPluginFilename[]; + +} // namespace chrome + +#endif // CHROME_COMMON_CHROME_CONSTANTS_H_ diff --git a/chromium_src/chrome/common/chrome_paths.cc b/chromium_src/chrome/common/chrome_paths.cc new file mode 100644 index 000000000000..d8a32446fe9e --- /dev/null +++ b/chromium_src/chrome/common/chrome_paths.cc @@ -0,0 +1,610 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/common/chrome_paths.h" + +#include "base/files/file_util.h" +#include "base/lazy_instance.h" +#include "base/logging.h" +#include "base/mac/bundle_locations.h" +#include "base/path_service.h" +#include "base/strings/string_util.h" +#include "base/sys_info.h" +#include "base/threading/thread_restrictions.h" +#include "base/version.h" +#include "chrome/common/chrome_constants.h" +#include "chrome/common/chrome_paths_internal.h" + +#if defined(OS_ANDROID) +#include "base/android/path_utils.h" +#include "base/base_paths_android.h" +// ui/base must only be used on Android. See BUILD.gn for dependency info. +#include "ui/base/ui_base_paths.h" // nogncheck +#endif + +#if defined(OS_MACOSX) +#include "base/mac/foundation_util.h" +#endif + +#if defined(OS_WIN) +#include "base/win/registry.h" +#endif + +namespace { + +// The Pepper Flash plugins are in a directory with this name. +const base::FilePath::CharType kPepperFlashBaseDirectory[] = + FILE_PATH_LITERAL("PepperFlash"); + +#if defined(OS_MACOSX) && !defined(OS_IOS) +const base::FilePath::CharType kPepperFlashSystemBaseDirectory[] = + FILE_PATH_LITERAL("Internet Plug-Ins/PepperFlashPlayer"); +const base::FilePath::CharType kFlashSystemBaseDirectory[] = + FILE_PATH_LITERAL("Internet Plug-Ins"); +const base::FilePath::CharType kFlashSystemPluginName[] = + FILE_PATH_LITERAL("Flash Player.plugin"); +#endif + +const base::FilePath::CharType kInternalNaClPluginFileName[] = + FILE_PATH_LITERAL("internal-nacl-plugin"); + +#if defined(OS_LINUX) +// The path to the external extension .json files. +// /usr/share seems like a good choice, see: http://www.pathname.com/fhs/ +const base::FilePath::CharType kFilepathSinglePrefExtensions[] = +#if defined(GOOGLE_CHROME_BUILD) + FILE_PATH_LITERAL("/usr/share/google-chrome/extensions"); +#else + FILE_PATH_LITERAL("/usr/share/chromium/extensions"); +#endif // defined(GOOGLE_CHROME_BUILD) + +// The path to the hint file that tells the pepper plugin loader +// where it can find the latest component updated flash. +const base::FilePath::CharType kComponentUpdatedFlashHint[] = + FILE_PATH_LITERAL("latest-component-updated-flash"); +#endif // defined(OS_LINUX) + +static base::LazyInstance + g_invalid_specified_user_data_dir = LAZY_INSTANCE_INITIALIZER; + +// Gets the path for internal plugins. +bool GetInternalPluginsDirectory(base::FilePath* result) { +#if defined(OS_MACOSX) && !defined(OS_IOS) + // If called from Chrome, get internal plugins from a subdirectory of the + // framework. + if (base::mac::AmIBundled()) { + *result = chrome::GetFrameworkBundlePath(); + DCHECK(!result->empty()); + *result = result->Append("Internet Plug-Ins"); + return true; + } + // In tests, just look in the module directory (below). +#endif + + // The rest of the world expects plugins in the module directory. + return PathService::Get(base::DIR_MODULE, result); +} + +#if defined(OS_WIN) +// Gets the Flash path if installed on the system. |is_npapi| determines whether +// to return the NPAPI of the PPAPI version of the system plugin. +bool GetSystemFlashFilename(base::FilePath* out_path, bool is_npapi) { + const wchar_t kNpapiFlashRegistryRoot[] = + L"SOFTWARE\\Macromedia\\FlashPlayerPlugin"; + const wchar_t kPepperFlashRegistryRoot[] = + L"SOFTWARE\\Macromedia\\FlashPlayerPepper"; + const wchar_t kFlashPlayerPathValueName[] = L"PlayerPath"; + + base::win::RegKey path_key( + HKEY_LOCAL_MACHINE, + is_npapi ? kNpapiFlashRegistryRoot : kPepperFlashRegistryRoot, KEY_READ); + base::string16 path_str; + if (FAILED(path_key.ReadValue(kFlashPlayerPathValueName, &path_str))) + return false; + + *out_path = base::FilePath(path_str); + return true; +} +#endif + +} // namespace + +namespace chrome { + +bool PathProvider(int key, base::FilePath* result) { + // Some keys are just aliases... + switch (key) { + case chrome::DIR_APP: + return PathService::Get(base::DIR_MODULE, result); + case chrome::DIR_LOGS: +#ifdef NDEBUG + // Release builds write to the data dir + return PathService::Get(chrome::DIR_USER_DATA, result); +#else + // Debug builds write next to the binary (in the build tree) +#if defined(OS_MACOSX) + if (!PathService::Get(base::DIR_EXE, result)) + return false; + if (base::mac::AmIBundled()) { + // If we're called from chrome, dump it beside the app (outside the + // app bundle), if we're called from a unittest, we'll already + // outside the bundle so use the exe dir. + // exe_dir gave us .../Chromium.app/Contents/MacOS/Chromium. + *result = result->DirName(); + *result = result->DirName(); + *result = result->DirName(); + } + return true; +#else + return PathService::Get(base::DIR_EXE, result); +#endif // defined(OS_MACOSX) +#endif // NDEBUG + case chrome::FILE_RESOURCE_MODULE: + return PathService::Get(base::FILE_MODULE, result); + } + + // Assume that we will not need to create the directory if it does not exist. + // This flag can be set to true for the cases where we want to create it. + bool create_dir = false; + + base::FilePath cur; + switch (key) { + case chrome::DIR_USER_DATA: + if (!GetDefaultUserDataDirectory(&cur)) { + NOTREACHED(); + return false; + } + create_dir = true; + break; + case chrome::DIR_USER_DOCUMENTS: + if (!GetUserDocumentsDirectory(&cur)) + return false; + create_dir = true; + break; + case chrome::DIR_USER_MUSIC: + if (!GetUserMusicDirectory(&cur)) + return false; + break; + case chrome::DIR_USER_PICTURES: + if (!GetUserPicturesDirectory(&cur)) + return false; + break; + case chrome::DIR_USER_VIDEOS: + if (!GetUserVideosDirectory(&cur)) + return false; + break; + case chrome::DIR_DEFAULT_DOWNLOADS_SAFE: +#if defined(OS_WIN) || defined(OS_LINUX) + if (!GetUserDownloadsDirectorySafe(&cur)) + return false; + break; +#else + // Fall through for all other platforms. +#endif + case chrome::DIR_DEFAULT_DOWNLOADS: +#if defined(OS_ANDROID) + if (!base::android::GetDownloadsDirectory(&cur)) + return false; +#else + if (!GetUserDownloadsDirectory(&cur)) + return false; + // Do not create the download directory here, we have done it twice now + // and annoyed a lot of users. +#endif + break; + case chrome::DIR_CRASH_DUMPS: +#if defined(OS_CHROMEOS) + // ChromeOS uses a separate directory. See http://crosbug.com/25089 + cur = base::FilePath("/var/log/chrome"); +#elif defined(OS_ANDROID) + if (!base::android::GetCacheDirectory(&cur)) + return false; +#else + // The crash reports are always stored relative to the default user data + // directory. This avoids the problem of having to re-initialize the + // exception handler after parsing command line options, which may + // override the location of the app's profile directory. + if (!GetDefaultUserDataDirectory(&cur)) + return false; +#endif +#if defined(OS_MACOSX) + cur = cur.Append(FILE_PATH_LITERAL("Crashpad")); +#else + cur = cur.Append(FILE_PATH_LITERAL("Crash Reports")); +#endif + create_dir = true; + break; +#if defined(OS_WIN) + case chrome::DIR_WATCHER_DATA: + // The watcher data is always stored relative to the default user data + // directory. This allows the watcher to be initialized before + // command-line options have been parsed. + if (!GetDefaultUserDataDirectory(&cur)) + return false; + cur = cur.Append(FILE_PATH_LITERAL("Diagnostics")); + break; +#endif + case chrome::DIR_RESOURCES: +#if defined(OS_MACOSX) + cur = base::mac::FrameworkBundlePath(); + cur = cur.Append(FILE_PATH_LITERAL("Resources")); +#else + if (!PathService::Get(chrome::DIR_APP, &cur)) + return false; + cur = cur.Append(FILE_PATH_LITERAL("resources")); +#endif + break; + case chrome::DIR_INSPECTOR: + if (!PathService::Get(chrome::DIR_RESOURCES, &cur)) + return false; + cur = cur.Append(FILE_PATH_LITERAL("inspector")); + break; + case chrome::DIR_APP_DICTIONARIES: +#if defined(OS_POSIX) + // We can't write into the EXE dir on Linux, so keep dictionaries + // alongside the safe browsing database in the user data dir. + // And we don't want to write into the bundle on the Mac, so push + // it to the user data dir there also. + if (!PathService::Get(chrome::DIR_USER_DATA, &cur)) + return false; +#else + if (!PathService::Get(base::DIR_EXE, &cur)) + return false; +#endif + cur = cur.Append(FILE_PATH_LITERAL("Dictionaries")); + create_dir = true; + break; + case chrome::DIR_INTERNAL_PLUGINS: + if (!GetInternalPluginsDirectory(&cur)) + return false; + break; + case chrome::DIR_PEPPER_FLASH_PLUGIN: + if (!GetInternalPluginsDirectory(&cur)) + return false; + cur = cur.Append(kPepperFlashBaseDirectory); + break; + case chrome::DIR_COMPONENT_UPDATED_PEPPER_FLASH_PLUGIN: + if (!PathService::Get(chrome::DIR_USER_DATA, &cur)) + return false; + cur = cur.Append(kPepperFlashBaseDirectory); + break; + case chrome::FILE_PEPPER_FLASH_SYSTEM_PLUGIN: +#if defined(OS_WIN) + if (!GetSystemFlashFilename(&cur, false)) + return false; +#elif defined(OS_MACOSX) && !defined(OS_IOS) + if (!GetLocalLibraryDirectory(&cur)) + return false; + cur = cur.Append(kPepperFlashSystemBaseDirectory); + cur = cur.Append(chrome::kPepperFlashPluginFilename); +#else + // Chrome on iOS does not supports PPAPI binaries, return false. + // TODO(wfh): If Adobe release PPAPI binaries for Linux, add support here. + return false; +#endif + break; + case chrome::FILE_FLASH_SYSTEM_PLUGIN: +#if defined(OS_WIN) + if (!GetSystemFlashFilename(&cur, true)) + return false; +#elif defined(OS_MACOSX) && !defined(OS_IOS) + if (!GetLocalLibraryDirectory(&cur)) + return false; + cur = cur.Append(kFlashSystemBaseDirectory); + cur = cur.Append(kFlashSystemPluginName); +#else + // Chrome on other platforms does not supports system NPAPI binaries. + return false; +#endif + break; + case chrome::FILE_LOCAL_STATE: + if (!PathService::Get(chrome::DIR_USER_DATA, &cur)) + return false; + cur = cur.Append(chrome::kLocalStateFilename); + break; + case chrome::FILE_RECORDED_SCRIPT: + if (!PathService::Get(chrome::DIR_USER_DATA, &cur)) + return false; + cur = cur.Append(FILE_PATH_LITERAL("script.log")); + break; + case chrome::FILE_PEPPER_FLASH_PLUGIN: + if (!PathService::Get(chrome::DIR_PEPPER_FLASH_PLUGIN, &cur)) + return false; + cur = cur.Append(chrome::kPepperFlashPluginFilename); + break; + // TODO(teravest): Remove this case once the internal NaCl plugin is gone. + // We currently need a path here to look up whether the plugin is disabled + // and what its permissions are. + case chrome::FILE_NACL_PLUGIN: + if (!GetInternalPluginsDirectory(&cur)) + return false; + cur = cur.Append(kInternalNaClPluginFileName); + break; + // PNaCl is currenly installable via the component updater or by being + // simply built-in. DIR_PNACL_BASE is used as the base directory for + // installation via component updater. DIR_PNACL_COMPONENT will be + // the final location of pnacl, which is a subdir of DIR_PNACL_BASE. + case chrome::DIR_PNACL_BASE: + if (!PathService::Get(chrome::DIR_USER_DATA, &cur)) + return false; + cur = cur.Append(FILE_PATH_LITERAL("pnacl")); + break; + // Where PNaCl files are ultimately located. The default finds the files + // inside the InternalPluginsDirectory / build directory, as if it + // was shipped along with chrome. The value can be overridden + // if it is installed via component updater. + case chrome::DIR_PNACL_COMPONENT: +#if defined(OS_MACOSX) + // PNaCl really belongs in the InternalPluginsDirectory but actually + // copying it there would result in the files also being shipped, which + // we don't want yet. So for now, just find them in the directory where + // they get built. + if (!PathService::Get(base::DIR_EXE, &cur)) + return false; + if (base::mac::AmIBundled()) { + // If we're called from chrome, it's beside the app (outside the + // app bundle), if we're called from a unittest, we'll already be + // outside the bundle so use the exe dir. + // exe_dir gave us .../Chromium.app/Contents/MacOS/Chromium. + cur = cur.DirName(); + cur = cur.DirName(); + cur = cur.DirName(); + } +#else + if (!GetInternalPluginsDirectory(&cur)) + return false; +#endif + cur = cur.Append(FILE_PATH_LITERAL("pnacl")); + break; +#if defined(WIDEVINE_CDM_AVAILABLE) && defined(ENABLE_PEPPER_CDMS) +#if defined(WIDEVINE_CDM_IS_COMPONENT) + case chrome::DIR_COMPONENT_WIDEVINE_CDM: + if (!PathService::Get(chrome::DIR_USER_DATA, &cur)) + return false; + cur = cur.Append(FILE_PATH_LITERAL("WidevineCDM")); + break; +#endif // defined(WIDEVINE_CDM_IS_COMPONENT) + // TODO(xhwang): FILE_WIDEVINE_CDM_ADAPTER has different meanings. + // In the component case, this is the source adapter. Otherwise, it is the + // actual Pepper module that gets loaded. + case chrome::FILE_WIDEVINE_CDM_ADAPTER: + if (!GetInternalPluginsDirectory(&cur)) + return false; + cur = cur.AppendASCII(kWidevineCdmAdapterFileName); + break; +#endif // defined(WIDEVINE_CDM_AVAILABLE) && defined(ENABLE_PEPPER_CDMS) + case chrome::FILE_RESOURCES_PACK: +#if defined(OS_MACOSX) && !defined(OS_IOS) + if (base::mac::AmIBundled()) { + cur = base::mac::FrameworkBundlePath(); + cur = cur.Append(FILE_PATH_LITERAL("Resources")) + .Append(FILE_PATH_LITERAL("resources.pak")); + break; + } +#elif defined(OS_ANDROID) + if (!PathService::Get(ui::DIR_RESOURCE_PAKS_ANDROID, &cur)) + return false; +#else + // If we're not bundled on mac or Android, resources.pak should be next + // to the binary (e.g., for unit tests). + if (!PathService::Get(base::DIR_MODULE, &cur)) + return false; +#endif + cur = cur.Append(FILE_PATH_LITERAL("resources.pak")); + break; + case chrome::DIR_RESOURCES_EXTENSION: + if (!PathService::Get(base::DIR_MODULE, &cur)) + return false; + cur = cur.Append(FILE_PATH_LITERAL("resources")) + .Append(FILE_PATH_LITERAL("extension")); + break; +#if defined(OS_CHROMEOS) + case chrome::DIR_CHROMEOS_WALLPAPERS: + if (!PathService::Get(chrome::DIR_USER_DATA, &cur)) + return false; + cur = cur.Append(FILE_PATH_LITERAL("wallpapers")); + break; + case chrome::DIR_CHROMEOS_WALLPAPER_THUMBNAILS: + if (!PathService::Get(chrome::DIR_USER_DATA, &cur)) + return false; + cur = cur.Append(FILE_PATH_LITERAL("wallpaper_thumbnails")); + break; + case chrome::DIR_CHROMEOS_CUSTOM_WALLPAPERS: + if (!PathService::Get(chrome::DIR_USER_DATA, &cur)) + return false; + cur = cur.Append(FILE_PATH_LITERAL("custom_wallpapers")); + break; +#endif +#if defined(ENABLE_SUPERVISED_USERS) +#if defined(OS_LINUX) + case chrome::DIR_SUPERVISED_USERS_DEFAULT_APPS: + if (!PathService::Get(chrome::DIR_STANDALONE_EXTERNAL_EXTENSIONS, &cur)) + return false; + cur = cur.Append(FILE_PATH_LITERAL("managed_users")); + break; +#endif + case chrome::DIR_SUPERVISED_USER_INSTALLED_WHITELISTS: + if (!PathService::Get(chrome::DIR_USER_DATA, &cur)) + return false; + cur = cur.Append(FILE_PATH_LITERAL("SupervisedUserInstalledWhitelists")); + break; +#endif + // The following are only valid in the development environment, and + // will fail if executed from an installed executable (because the + // generated path won't exist). + case chrome::DIR_GEN_TEST_DATA: +#if defined(OS_ANDROID) + // On Android, our tests don't have permission to write to DIR_MODULE. + // gtest/test_runner.py pushes data to external storage. + if (!PathService::Get(base::DIR_ANDROID_EXTERNAL_STORAGE, &cur)) + return false; +#else + if (!PathService::Get(base::DIR_MODULE, &cur)) + return false; +#endif + cur = cur.Append(FILE_PATH_LITERAL("test_data")); + if (!base::PathExists(cur)) // We don't want to create this. + return false; + break; + case chrome::DIR_TEST_DATA: + if (!PathService::Get(base::DIR_SOURCE_ROOT, &cur)) + return false; + cur = cur.Append(FILE_PATH_LITERAL("chrome")); + cur = cur.Append(FILE_PATH_LITERAL("test")); + cur = cur.Append(FILE_PATH_LITERAL("data")); + if (!base::PathExists(cur)) // We don't want to create this. + return false; + break; + case chrome::DIR_TEST_TOOLS: + if (!PathService::Get(base::DIR_SOURCE_ROOT, &cur)) + return false; + cur = cur.Append(FILE_PATH_LITERAL("chrome")); + cur = cur.Append(FILE_PATH_LITERAL("tools")); + cur = cur.Append(FILE_PATH_LITERAL("test")); + if (!base::PathExists(cur)) // We don't want to create this + return false; + break; +#if defined(OS_POSIX) && !defined(OS_MACOSX) && !defined(OS_OPENBSD) + case chrome::DIR_POLICY_FILES: { +#if defined(GOOGLE_CHROME_BUILD) + cur = base::FilePath(FILE_PATH_LITERAL("/etc/opt/chrome/policies")); +#else + cur = base::FilePath(FILE_PATH_LITERAL("/etc/chromium/policies")); +#endif + break; + } +#endif +#if defined(OS_MACOSX) && !defined(OS_IOS) + case chrome::DIR_USER_LIBRARY: { + if (!GetUserLibraryDirectory(&cur)) + return false; + if (!base::PathExists(cur)) // We don't want to create this. + return false; + break; + } + case chrome::DIR_USER_APPLICATIONS: { + if (!GetUserApplicationsDirectory(&cur)) + return false; + if (!base::PathExists(cur)) // We don't want to create this. + return false; + break; + } +#endif +#if defined(OS_CHROMEOS) || (defined(OS_LINUX) && defined(CHROMIUM_BUILD)) || \ + (defined(OS_MACOSX) && !defined(OS_IOS)) + case chrome::DIR_USER_EXTERNAL_EXTENSIONS: { + if (!PathService::Get(chrome::DIR_USER_DATA, &cur)) + return false; + cur = cur.Append(FILE_PATH_LITERAL("External Extensions")); + break; + } +#endif +#if defined(OS_LINUX) + case chrome::DIR_STANDALONE_EXTERNAL_EXTENSIONS: { + cur = base::FilePath(kFilepathSinglePrefExtensions); + break; + } +#endif + case chrome::DIR_EXTERNAL_EXTENSIONS: +#if defined(OS_MACOSX) && !defined(OS_IOS) + if (!chrome::GetGlobalApplicationSupportDirectory(&cur)) + return false; + + cur = cur.Append(FILE_PATH_LITERAL("Google")) + .Append(FILE_PATH_LITERAL("Chrome")) + .Append(FILE_PATH_LITERAL("External Extensions")); + create_dir = false; +#else + if (!PathService::Get(base::DIR_MODULE, &cur)) + return false; + + cur = cur.Append(FILE_PATH_LITERAL("extensions")); + create_dir = true; +#endif + break; + + case chrome::DIR_DEFAULT_APPS: +#if defined(OS_MACOSX) + cur = base::mac::FrameworkBundlePath(); + cur = cur.Append(FILE_PATH_LITERAL("Default Apps")); +#else + if (!PathService::Get(chrome::DIR_APP, &cur)) + return false; + cur = cur.Append(FILE_PATH_LITERAL("default_apps")); +#endif + break; + +#if defined(OS_LINUX) || (defined(OS_MACOSX) && !defined(OS_IOS)) + case chrome::DIR_NATIVE_MESSAGING: +#if defined(OS_MACOSX) +#if defined(GOOGLE_CHROME_BUILD) + cur = base::FilePath(FILE_PATH_LITERAL( + "/Library/Google/Chrome/NativeMessagingHosts")); +#else + cur = base::FilePath(FILE_PATH_LITERAL( + "/Library/Application Support/Chromium/NativeMessagingHosts")); +#endif +#else // defined(OS_MACOSX) +#if defined(GOOGLE_CHROME_BUILD) + cur = base::FilePath(FILE_PATH_LITERAL( + "/etc/opt/chrome/native-messaging-hosts")); +#else + cur = base::FilePath(FILE_PATH_LITERAL( + "/etc/chromium/native-messaging-hosts")); +#endif +#endif // !defined(OS_MACOSX) + break; + + case chrome::DIR_USER_NATIVE_MESSAGING: + if (!PathService::Get(chrome::DIR_USER_DATA, &cur)) + return false; + cur = cur.Append(FILE_PATH_LITERAL("NativeMessagingHosts")); + break; +#endif // defined(OS_LINUX) || (defined(OS_MACOSX) && !defined(OS_IOS)) +#if !defined(OS_ANDROID) + case chrome::DIR_GLOBAL_GCM_STORE: + if (!PathService::Get(chrome::DIR_USER_DATA, &cur)) + return false; + cur = cur.Append(kGCMStoreDirname); + break; +#endif // !defined(OS_ANDROID) +#if defined(OS_LINUX) + case chrome::FILE_COMPONENT_FLASH_HINT: + if (!PathService::Get(chrome::DIR_COMPONENT_UPDATED_PEPPER_FLASH_PLUGIN, + &cur)) { + return false; + } + cur = cur.Append(kComponentUpdatedFlashHint); + break; +#endif // defined(OS_LINUX) + + default: + return false; + } + + // TODO(bauerb): http://crbug.com/259796 + base::ThreadRestrictions::ScopedAllowIO allow_io; + if (create_dir && !base::PathExists(cur) && + !base::CreateDirectory(cur)) + return false; + + *result = cur; + return true; +} + +// This cannot be done as a static initializer sadly since Visual Studio will +// eliminate this object file if there is no direct entry point into it. +void RegisterPathProvider() { + PathService::RegisterProvider(PathProvider, PATH_START, PATH_END); +} + +void SetInvalidSpecifiedUserDataDir(const base::FilePath& user_data_dir) { + g_invalid_specified_user_data_dir.Get() = user_data_dir; +} + +const base::FilePath& GetInvalidSpecifiedUserDataDir() { + return g_invalid_specified_user_data_dir.Get(); +} + +} // namespace chrome diff --git a/chromium_src/chrome/common/chrome_paths.h b/chromium_src/chrome/common/chrome_paths.h new file mode 100644 index 000000000000..581fdc06f7c1 --- /dev/null +++ b/chromium_src/chrome/common/chrome_paths.h @@ -0,0 +1,152 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_COMMON_CHROME_PATHS_H__ +#define CHROME_COMMON_CHROME_PATHS_H__ + +#include "build/build_config.h" + +namespace base { +class FilePath; +} + +// This file declares path keys for the chrome module. These can be used with +// the PathService to access various special directories and files. + +namespace chrome { + +enum { + PATH_START = 1000, + + DIR_APP = PATH_START, // Directory where dlls and data reside. + DIR_LOGS, // Directory where logs should be written. + DIR_USER_DATA, // Directory where user data can be written. + DIR_CRASH_DUMPS, // Directory where crash dumps are written. +#if defined(OS_WIN) + DIR_WATCHER_DATA, // Directory where the Chrome watcher stores + // data. +#endif + DIR_RESOURCES, // Directory containing separate file resources + // used by Chrome at runtime. + DIR_INSPECTOR, // Directory where web inspector is located. + DIR_APP_DICTIONARIES, // Directory where the global dictionaries are. + DIR_USER_DOCUMENTS, // Directory for a user's "My Documents". + DIR_USER_MUSIC, // Directory for a user's music. + DIR_USER_PICTURES, // Directory for a user's pictures. + DIR_USER_VIDEOS, // Directory for a user's videos. + DIR_DEFAULT_DOWNLOADS_SAFE, // Directory for a user's + // "My Documents/Downloads", (Windows) or + // "Downloads". (Linux) + DIR_DEFAULT_DOWNLOADS, // Directory for a user's downloads. + DIR_INTERNAL_PLUGINS, // Directory where internal plugins reside. +#if defined(OS_POSIX) && !defined(OS_MACOSX) + DIR_POLICY_FILES, // Directory for system-wide read-only + // policy files that allow sys-admins + // to set policies for chrome. This directory + // contains subdirectories. +#endif +#if defined(OS_MACOSX) && !defined(OS_IOS) + DIR_USER_APPLICATIONS, // ~/Applications + DIR_USER_LIBRARY, // ~/Library +#endif +#if defined(OS_CHROMEOS) || (defined(OS_LINUX) && defined(CHROMIUM_BUILD)) || \ + (defined(OS_MACOSX) && !defined(OS_IOS)) + DIR_USER_EXTERNAL_EXTENSIONS, // Directory for per-user external extensions + // on Chrome Mac and Chromium Linux. + // On Chrome OS, this path is used for OEM + // customization. Getting this path does not + // create it. +#endif + +#if defined(OS_LINUX) + DIR_STANDALONE_EXTERNAL_EXTENSIONS, // Directory for 'per-extension' + // definition manifest files that + // describe extensions which are to be + // installed when chrome is run. +#endif + DIR_EXTERNAL_EXTENSIONS, // Directory where installer places .crx files. + + DIR_DEFAULT_APPS, // Directory where installer places .crx files + // to be installed when chrome is first run. + DIR_PEPPER_FLASH_PLUGIN, // Directory to the bundled Pepper Flash plugin, + // containing the plugin and the manifest. + DIR_COMPONENT_UPDATED_PEPPER_FLASH_PLUGIN, // Base directory of the Pepper + // Flash plugins downloaded by the + // component updater. + FILE_RESOURCE_MODULE, // Full path and filename of the module that + // contains embedded resources (version, + // strings, images, etc.). + FILE_LOCAL_STATE, // Path and filename to the file in which + // machine/installation-specific state is saved. + FILE_RECORDED_SCRIPT, // Full path to the script.log file that + // contains recorded browser events for + // playback. + FILE_PEPPER_FLASH_PLUGIN, // Full path to the bundled Pepper Flash plugin + // file. + FILE_PEPPER_FLASH_SYSTEM_PLUGIN, // Full path to the system version of the + // Pepper Flash plugin, downloadable from + // Adobe website. Querying this path might + // succeed no matter the file exists or not. + FILE_FLASH_SYSTEM_PLUGIN, // Full path to the system version of NPAPI + // Flash plugin, downloadable from Adobe + // website. Querying this path might succeed no + // matter the file exists or not. + FILE_NACL_PLUGIN, // Full path to the internal NaCl plugin file. + DIR_PNACL_BASE, // Full path to the base dir for PNaCl. + DIR_PNACL_COMPONENT, // Full path to the latest PNaCl version + // (subdir of DIR_PNACL_BASE). + DIR_COMPONENT_WIDEVINE_CDM, // Directory that contains component-updated + // Widevine CDM files. + FILE_WIDEVINE_CDM_ADAPTER, // Full path to the Widevine CDM adapter file. + FILE_RESOURCES_PACK, // Full path to the .pak file containing + // binary data (e.g., html files and images + // used by internal pages). + DIR_RESOURCES_EXTENSION, // Full path to extension resources. +#if defined(OS_CHROMEOS) + DIR_CHROMEOS_WALLPAPERS, // Directory where downloaded chromeos + // wallpapers reside. + DIR_CHROMEOS_WALLPAPER_THUMBNAILS, // Directory where downloaded chromeos + // wallpaper thumbnails reside. + DIR_CHROMEOS_CUSTOM_WALLPAPERS, // Directory where custom wallpapers + // reside. +#endif + DIR_SUPERVISED_USERS_DEFAULT_APPS, // Directory where installer places .crx + // files to be installed when managed user + // session starts. + DIR_SUPERVISED_USER_INSTALLED_WHITELISTS, // Directory where sanitized + // supervised user whitelists are + // installed. +#if defined(OS_LINUX) || (defined(OS_MACOSX) && !defined(OS_IOS)) + DIR_NATIVE_MESSAGING, // System directory where native messaging host + // manifest files are stored. + DIR_USER_NATIVE_MESSAGING, // Directory with Native Messaging Hosts + // installed per-user. +#endif +#if !defined(OS_ANDROID) + DIR_GLOBAL_GCM_STORE, // Directory where the global GCM instance + // stores its data. +#endif + + // Valid only in development environment; TODO(darin): move these + DIR_GEN_TEST_DATA, // Directory where generated test data resides. + DIR_TEST_DATA, // Directory where unit test data resides. + DIR_TEST_TOOLS, // Directory where unit test tools reside. +#if defined(OS_LINUX) + FILE_COMPONENT_FLASH_HINT, // A file in a known location that points to + // the component updated flash plugin. +#endif // defined(OS_LINUX) + + PATH_END +}; + +// Call once to register the provider for the path keys defined above. +void RegisterPathProvider(); + +// Get or set the invalid user data dir that was originally specified. +void SetInvalidSpecifiedUserDataDir(const base::FilePath& user_data_dir); +const base::FilePath& GetInvalidSpecifiedUserDataDir(); + +} // namespace chrome + +#endif // CHROME_COMMON_CHROME_PATHS_H__ diff --git a/chromium_src/chrome/common/chrome_paths_internal.h b/chromium_src/chrome/common/chrome_paths_internal.h new file mode 100644 index 000000000000..ae1cd623d773 --- /dev/null +++ b/chromium_src/chrome/common/chrome_paths_internal.h @@ -0,0 +1,112 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_COMMON_CHROME_PATHS_INTERNAL_H_ +#define CHROME_COMMON_CHROME_PATHS_INTERNAL_H_ + +#include + +#include "build/build_config.h" + +#if defined(OS_MACOSX) +#if defined(__OBJC__) +@class NSBundle; +#else +class NSBundle; +#endif +#endif + +namespace base { +class FilePath; +} + +namespace chrome { + +// Get the path to the user's data directory, regardless of whether +// DIR_USER_DATA has been overridden by a command-line option. +bool GetDefaultUserDataDirectory(base::FilePath* result); + +// Get the path to the user's cache directory. This is normally the +// same as the profile directory, but on Linux it can also be +// $XDG_CACHE_HOME and on Mac it can be under ~/Library/Caches. +// Note that the Chrome cache directories are actually subdirectories +// of this directory, with names like "Cache" and "Media Cache". +// This will always fill in |result| with a directory, sometimes +// just |profile_dir|. +void GetUserCacheDirectory(const base::FilePath& profile_dir, base::FilePath* result); + +// Get the path to the user's documents directory. +bool GetUserDocumentsDirectory(base::FilePath* result); + +#if defined(OS_WIN) || defined(OS_LINUX) +// Gets the path to a safe default download directory for a user. +bool GetUserDownloadsDirectorySafe(base::FilePath* result); +#endif + +// Get the path to the user's downloads directory. +bool GetUserDownloadsDirectory(base::FilePath* result); + +// Gets the path to the user's music directory. +bool GetUserMusicDirectory(base::FilePath* result); + +// Gets the path to the user's pictures directory. +bool GetUserPicturesDirectory(base::FilePath* result); + +// Gets the path to the user's videos directory. +bool GetUserVideosDirectory(base::FilePath* result); + +#if defined(OS_MACOSX) && !defined(OS_IOS) +// The "versioned directory" is a directory in the browser .app bundle. It +// contains the bulk of the application, except for the things that the system +// requires be located at spepcific locations. The versioned directory is +// in the .app at Contents/Versions/w.x.y.z. +base::FilePath GetVersionedDirectory(); + +// This overrides the directory returned by |GetVersionedDirectory()|, to be +// used when |GetVersionedDirectory()| can't automatically determine the proper +// location. This is the case when the browser didn't load itself but by, e.g., +// the app mode loader. This should be called before |ChromeMain()|. This takes +// ownership of the object |path| and the caller must not delete it. +void SetOverrideVersionedDirectory(const base::FilePath* path); + +// Most of the application is further contained within the framework. The +// framework bundle is located within the versioned directory at a specific +// path. The only components in the versioned directory not included in the +// framework are things that also depend on the framework, such as the helper +// app bundle. +base::FilePath GetFrameworkBundlePath(); + +// Get the local library directory. +bool GetLocalLibraryDirectory(base::FilePath* result); + +// Get the user library directory. +bool GetUserLibraryDirectory(base::FilePath* result); + +// Get the user applications directory. +bool GetUserApplicationsDirectory(base::FilePath* result); + +// Get the global Application Support directory (under /Library/). +bool GetGlobalApplicationSupportDirectory(base::FilePath* result); + +// Returns the NSBundle for the outer browser application, even when running +// inside the helper. In unbundled applications, such as tests, returns nil. +NSBundle* OuterAppBundle(); + +// Get the user data directory for the Chrome browser bundle at |bundle|. +// |bundle| should be the same value that would be returned from +[NSBundle +// mainBundle] if Chrome were launched normaly. This is used by app shims, +// which run from a bundle which isn't Chrome itself, but which need access to +// the user data directory to connect to a UNIX-domain socket therein. +// Returns false if there was a problem fetching the app data directory. +bool GetUserDataDirectoryForBrowserBundle(NSBundle* bundle, + base::FilePath* result); + +#endif // OS_MACOSX && !OS_IOS + +// Checks if the |process_type| has the rights to access the profile. +bool ProcessNeedsProfileDir(const std::string& process_type); + +} // namespace chrome + +#endif // CHROME_COMMON_CHROME_PATHS_INTERNAL_H_ diff --git a/chromium_src/chrome/common/chrome_paths_linux.cc b/chromium_src/chrome/common/chrome_paths_linux.cc new file mode 100644 index 000000000000..91348fec4808 --- /dev/null +++ b/chromium_src/chrome/common/chrome_paths_linux.cc @@ -0,0 +1,145 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/common/chrome_paths_internal.h" + +#include "base/base_paths.h" +#include "base/environment.h" +#include "base/files/file_util.h" +#include "base/memory/scoped_ptr.h" +#include "base/nix/xdg_util.h" +#include "base/path_service.h" +#include "chrome/common/chrome_paths.h" + +namespace chrome { + +using base::nix::GetXDGDirectory; +using base::nix::GetXDGUserDirectory; +using base::nix::kDotConfigDir; +using base::nix::kXdgConfigHomeEnvVar; + +namespace { + +const char kDownloadsDir[] = "Downloads"; +const char kMusicDir[] = "Music"; +const char kPicturesDir[] = "Pictures"; +const char kVideosDir[] = "Videos"; + +// Generic function for GetUser{Music,Pictures,Video}Directory. +bool GetUserMediaDirectory(const std::string& xdg_name, + const std::string& fallback_name, + base::FilePath* result) { +#if defined(OS_CHROMEOS) + // No local media directories on CrOS. + return false; +#else + *result = GetXDGUserDirectory(xdg_name.c_str(), fallback_name.c_str()); + + base::FilePath home; + PathService::Get(base::DIR_HOME, &home); + if (*result != home) { + base::FilePath desktop; + if (!PathService::Get(base::DIR_USER_DESKTOP, &desktop)) + return false; + if (*result != desktop) { + return true; + } + } + + *result = home.Append(fallback_name); + return true; +#endif +} + +} // namespace + +// See http://standards.freedesktop.org/basedir-spec/basedir-spec-latest.html +// for a spec on where config files go. The net effect for most +// systems is we use ~/.config/chromium/ for Chromium and +// ~/.config/google-chrome/ for official builds. +// (This also helps us sidestep issues with other apps grabbing ~/.chromium .) +bool GetDefaultUserDataDirectory(base::FilePath* result) { + scoped_ptr env(base::Environment::Create()); + base::FilePath config_dir(GetXDGDirectory(env.get(), + kXdgConfigHomeEnvVar, + kDotConfigDir)); +#if defined(GOOGLE_CHROME_BUILD) + *result = config_dir.Append("google-chrome"); +#else + *result = config_dir.Append("chromium"); +#endif + return true; +} + +void GetUserCacheDirectory(const base::FilePath& profile_dir, + base::FilePath* result) { + // See http://standards.freedesktop.org/basedir-spec/basedir-spec-latest.html + // for a spec on where cache files go. Our rule is: + // - if the user-data-dir in the standard place, + // use same subdirectory of the cache directory. + // (this maps ~/.config/google-chrome to ~/.cache/google-chrome as well + // as the same thing for ~/.config/chromium) + // - otherwise, use the profile dir directly. + + // Default value in cases where any of the following fails. + *result = profile_dir; + + scoped_ptr env(base::Environment::Create()); + + base::FilePath cache_dir; + if (!PathService::Get(base::DIR_CACHE, &cache_dir)) + return; + base::FilePath config_dir(GetXDGDirectory(env.get(), + kXdgConfigHomeEnvVar, + kDotConfigDir)); + + if (!config_dir.AppendRelativePath(profile_dir, &cache_dir)) + return; + + *result = cache_dir; +} + +bool GetUserDocumentsDirectory(base::FilePath* result) { + *result = GetXDGUserDirectory("DOCUMENTS", "Documents"); + return true; +} + +bool GetUserDownloadsDirectorySafe(base::FilePath* result) { + base::FilePath home; + PathService::Get(base::DIR_HOME, &home); + *result = home.Append(kDownloadsDir); + return true; +} + +bool GetUserDownloadsDirectory(base::FilePath* result) { + *result = GetXDGUserDirectory("DOWNLOAD", kDownloadsDir); + return true; +} + +// We respect the user's preferred pictures location, unless it is +// ~ or their desktop directory, in which case we default to ~/Music. +bool GetUserMusicDirectory(base::FilePath* result) { + return GetUserMediaDirectory("MUSIC", kMusicDir, result); +} + +// We respect the user's preferred pictures location, unless it is +// ~ or their desktop directory, in which case we default to ~/Pictures. +bool GetUserPicturesDirectory(base::FilePath* result) { + return GetUserMediaDirectory("PICTURES", kPicturesDir, result); +} + +// We respect the user's preferred pictures location, unless it is +// ~ or their desktop directory, in which case we default to ~/Videos. +bool GetUserVideosDirectory(base::FilePath* result) { + return GetUserMediaDirectory("VIDEOS", kVideosDir, result); +} + +bool ProcessNeedsProfileDir(const std::string& process_type) { + // For now we have no reason to forbid this on Linux as we don't + // have the roaming profile troubles there. Moreover the Linux breakpad needs + // profile dir access in all process if enabled on Linux. + return true; +} + +} // namespace chrome diff --git a/chromium_src/chrome/common/chrome_paths_mac.mm b/chromium_src/chrome/common/chrome_paths_mac.mm new file mode 100644 index 000000000000..09cf13bfe122 --- /dev/null +++ b/chromium_src/chrome/common/chrome_paths_mac.mm @@ -0,0 +1,252 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/common/chrome_paths_internal.h" + +#import +#include + +#include + +#include "base/base_paths.h" +#include "base/logging.h" +#import "base/mac/foundation_util.h" +#import "base/mac/scoped_nsautorelease_pool.h" +#include "base/memory/scoped_ptr.h" +#include "base/path_service.h" +#include "chrome/common/chrome_constants.h" + +namespace { + +#if !defined(OS_IOS) +const base::FilePath* g_override_versioned_directory = NULL; + +// Return a retained (NOT autoreleased) NSBundle* as the internal +// implementation of chrome::OuterAppBundle(), which should be the only +// caller. +NSBundle* OuterAppBundleInternal() { + base::mac::ScopedNSAutoreleasePool pool; + + if (!base::mac::AmIBundled()) { + // If unbundled (as in a test), there's no app bundle. + return nil; + } + + if (!base::mac::IsBackgroundOnlyProcess()) { + // Shortcut: in the browser process, just return the main app bundle. + return [[NSBundle mainBundle] retain]; + } + + // From C.app/Contents/Versions/1.2.3.4, go up three steps to get to C.app. + base::FilePath versioned_dir = chrome::GetVersionedDirectory(); + base::FilePath outer_app_dir = versioned_dir.DirName().DirName().DirName(); + const char* outer_app_dir_c = outer_app_dir.value().c_str(); + NSString* outer_app_dir_ns = [NSString stringWithUTF8String:outer_app_dir_c]; + + return [[NSBundle bundleWithPath:outer_app_dir_ns] retain]; +} +#endif // !defined(OS_IOS) + +char* ProductDirNameForBundle(NSBundle* chrome_bundle) { + const char* product_dir_name = NULL; +#if !defined(OS_IOS) + base::mac::ScopedNSAutoreleasePool pool; + + NSString* product_dir_name_ns = + [chrome_bundle objectForInfoDictionaryKey:@"CrProductDirName"]; + product_dir_name = [product_dir_name_ns fileSystemRepresentation]; +#else + DCHECK(!chrome_bundle); +#endif + + if (!product_dir_name) { +#if defined(GOOGLE_CHROME_BUILD) + product_dir_name = "Google/Chrome"; +#else + product_dir_name = "Chromium"; +#endif + } + + // Leaked, but the only caller initializes a static with this result, so it + // only happens once, and that's OK. + return strdup(product_dir_name); +} + +// ProductDirName returns the name of the directory inside +// ~/Library/Application Support that should hold the product application +// data. This can be overridden by setting the CrProductDirName key in the +// outer browser .app's Info.plist. The default is "Google/Chrome" for +// officially-branded builds, and "Chromium" for unbranded builds. For the +// official canary channel, the Info.plist will have CrProductDirName set +// to "Google/Chrome Canary". +std::string ProductDirName() { +#if defined(OS_IOS) + static const char* product_dir_name = ProductDirNameForBundle(nil); +#else + // Use OuterAppBundle() to get the main app's bundle. This key needs to live + // in the main app's bundle because it will be set differently on the canary + // channel, and the autoupdate system dictates that there can be no + // differences between channels within the versioned directory. This would + // normally use base::mac::FrameworkBundle(), but that references the + // framework bundle within the versioned directory. Ordinarily, the profile + // should not be accessed from non-browser processes, but those processes do + // attempt to get the profile directory, so direct them to look in the outer + // browser .app's Info.plist for the CrProductDirName key. + static const char* product_dir_name = + ProductDirNameForBundle(chrome::OuterAppBundle()); +#endif + return std::string(product_dir_name); +} + +bool GetDefaultUserDataDirectoryForProduct(const std::string& product_dir, + base::FilePath* result) { + bool success = false; + if (result && PathService::Get(base::DIR_APP_DATA, result)) { + *result = result->Append(product_dir); + success = true; + } + return success; +} + +} // namespace + +namespace chrome { + +bool GetDefaultUserDataDirectory(base::FilePath* result) { + return GetDefaultUserDataDirectoryForProduct(ProductDirName(), result); +} + +bool GetUserDocumentsDirectory(base::FilePath* result) { + return base::mac::GetUserDirectory(NSDocumentDirectory, result); +} + +void GetUserCacheDirectory(const base::FilePath& profile_dir, + base::FilePath* result) { + // If the profile directory is under ~/Library/Application Support, + // use a suitable cache directory under ~/Library/Caches. For + // example, a profile directory of ~/Library/Application + // Support/Google/Chrome/MyProfileName would use the cache directory + // ~/Library/Caches/Google/Chrome/MyProfileName. + + // Default value in cases where any of the following fails. + *result = profile_dir; + + base::FilePath app_data_dir; + if (!PathService::Get(base::DIR_APP_DATA, &app_data_dir)) + return; + base::FilePath cache_dir; + if (!PathService::Get(base::DIR_CACHE, &cache_dir)) + return; + if (!app_data_dir.AppendRelativePath(profile_dir, &cache_dir)) + return; + + *result = cache_dir; +} + +bool GetUserDownloadsDirectory(base::FilePath* result) { + return base::mac::GetUserDirectory(NSDownloadsDirectory, result); +} + +bool GetUserMusicDirectory(base::FilePath* result) { + return base::mac::GetUserDirectory(NSMusicDirectory, result); +} + +bool GetUserPicturesDirectory(base::FilePath* result) { + return base::mac::GetUserDirectory(NSPicturesDirectory, result); +} + +bool GetUserVideosDirectory(base::FilePath* result) { + return base::mac::GetUserDirectory(NSMoviesDirectory, result); +} + +#if !defined(OS_IOS) + +base::FilePath GetVersionedDirectory() { + if (g_override_versioned_directory) + return *g_override_versioned_directory; + + // Start out with the path to the running executable. + base::FilePath path; + PathService::Get(base::FILE_EXE, &path); + + // One step up to MacOS, another to Contents. + path = path.DirName().DirName(); + DCHECK_EQ(path.BaseName().value(), "Contents"); + + if (base::mac::IsBackgroundOnlyProcess()) { + // path identifies the helper .app's Contents directory in the browser + // .app's versioned directory. Go up two steps to get to the browser + // .app's versioned directory. + path = path.DirName().DirName(); + DCHECK_EQ(path.BaseName().value(), kChromeVersion); + } else { + // Go into the versioned directory. + path = path.Append("Versions").Append(kChromeVersion); + } + + return path; +} + +void SetOverrideVersionedDirectory(const base::FilePath* path) { + if (path != g_override_versioned_directory) { + delete g_override_versioned_directory; + g_override_versioned_directory = path; + } +} + +base::FilePath GetFrameworkBundlePath() { + // It's tempting to use +[NSBundle bundleWithIdentifier:], but it's really + // slow (about 30ms on 10.5 and 10.6), despite Apple's documentation stating + // that it may be more efficient than +bundleForClass:. +bundleForClass: + // itself takes 1-2ms. Getting an NSBundle from a path, on the other hand, + // essentially takes no time at all, at least when the bundle has already + // been loaded as it will have been in this case. The FilePath operations + // needed to compute the framework's path are also effectively free, so that + // is the approach that is used here. NSBundle is also documented as being + // not thread-safe, and thread safety may be a concern here. + + // The framework bundle is at a known path and name from the browser .app's + // versioned directory. + return GetVersionedDirectory().Append(kFrameworkName); +} + +bool GetLocalLibraryDirectory(base::FilePath* result) { + return base::mac::GetLocalDirectory(NSLibraryDirectory, result); +} + +bool GetUserLibraryDirectory(base::FilePath* result) { + return base::mac::GetUserDirectory(NSLibraryDirectory, result); +} + +bool GetUserApplicationsDirectory(base::FilePath* result) { + return base::mac::GetUserDirectory(NSApplicationDirectory, result); +} + +bool GetGlobalApplicationSupportDirectory(base::FilePath* result) { + return base::mac::GetLocalDirectory(NSApplicationSupportDirectory, result); +} + +NSBundle* OuterAppBundle() { + // Cache this. Foundation leaks it anyway, and this should be the only call + // to OuterAppBundleInternal(). + static NSBundle* bundle = OuterAppBundleInternal(); + return bundle; +} + +bool GetUserDataDirectoryForBrowserBundle(NSBundle* bundle, + base::FilePath* result) { + scoped_ptr + product_dir_name(ProductDirNameForBundle(bundle)); + return GetDefaultUserDataDirectoryForProduct(product_dir_name.get(), result); +} + +#endif // !defined(OS_IOS) + +bool ProcessNeedsProfileDir(const std::string& process_type) { + // For now we have no reason to forbid this on other MacOS as we don't + // have the roaming profile troubles there. + return true; +} + +} // namespace chrome diff --git a/chromium_src/chrome/common/chrome_paths_win.cc b/chromium_src/chrome/common/chrome_paths_win.cc new file mode 100644 index 000000000000..18073ca04759 --- /dev/null +++ b/chromium_src/chrome/common/chrome_paths_win.cc @@ -0,0 +1,122 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/common/chrome_paths_internal.h" + +#include +#include +#include +#include +#include + +#include "base/files/file_path.h" +#include "base/path_service.h" +#include "base/win/metro.h" +#include "base/win/scoped_co_mem.h" +#include "chrome/common/chrome_constants.h" +#include "chrome/common/chrome_switches.h" +#include "chrome/installer/util/browser_distribution.h" +#include "components/nacl/common/nacl_switches.h" + +namespace chrome { + +namespace { + +// Generic function to call SHGetFolderPath(). +bool GetUserDirectory(int csidl_folder, base::FilePath* result) { + // We need to go compute the value. It would be nice to support paths + // with names longer than MAX_PATH, but the system functions don't seem + // to be designed for it either, with the exception of GetTempPath + // (but other things will surely break if the temp path is too long, + // so we don't bother handling it. + wchar_t path_buf[MAX_PATH]; + path_buf[0] = 0; + if (FAILED(SHGetFolderPath(NULL, csidl_folder, NULL, + SHGFP_TYPE_CURRENT, path_buf))) { + return false; + } + *result = base::FilePath(path_buf); + return true; +} + +} // namespace + +bool GetDefaultUserDataDirectory(base::FilePath* result) { + if (!PathService::Get(base::DIR_LOCAL_APP_DATA, result)) + return false; + BrowserDistribution* dist = BrowserDistribution::GetDistribution(); + *result = result->Append(dist->GetInstallSubDir()); + *result = result->Append(chrome::kUserDataDirname); + return true; +} + +void GetUserCacheDirectory(const base::FilePath& profile_dir, + base::FilePath* result) { + // This function does more complicated things on Mac/Linux. + *result = profile_dir; +} + +bool GetUserDocumentsDirectory(base::FilePath* result) { + return GetUserDirectory(CSIDL_MYDOCUMENTS, result); +} + +// Return a default path for downloads that is safe. +// We just use 'Downloads' under DIR_USER_DOCUMENTS. Localizing +// 'downloads' is not a good idea because Chrome's UI language +// can be changed. +bool GetUserDownloadsDirectorySafe(base::FilePath* result) { + if (!GetUserDocumentsDirectory(result)) + return false; + + *result = result->Append(L"Downloads"); + return true; +} + +// On Vista and higher, use the downloads known folder. Since it can be +// relocated to point to a "dangerous" folder, callers should validate that the +// returned path is not dangerous before using it. +bool GetUserDownloadsDirectory(base::FilePath* result) { + typedef HRESULT (WINAPI *GetKnownFolderPath)( + REFKNOWNFOLDERID, DWORD, HANDLE, PWSTR*); + GetKnownFolderPath f = reinterpret_cast( + GetProcAddress(GetModuleHandle(L"shell32.dll"), "SHGetKnownFolderPath")); + base::win::ScopedCoMem path_buf; + if (f && SUCCEEDED(f(FOLDERID_Downloads, 0, NULL, &path_buf))) { + *result = base::FilePath(std::wstring(path_buf)); + return true; + } + return GetUserDownloadsDirectorySafe(result); +} + +bool GetUserMusicDirectory(base::FilePath* result) { + return GetUserDirectory(CSIDL_MYMUSIC, result); +} + +bool GetUserPicturesDirectory(base::FilePath* result) { + return GetUserDirectory(CSIDL_MYPICTURES, result); +} + +bool GetUserVideosDirectory(base::FilePath* result) { + return GetUserDirectory(CSIDL_MYVIDEO, result); +} + +bool ProcessNeedsProfileDir(const std::string& process_type) { + // On windows we don't want subprocesses other than the browser process and + // service processes to be able to use the profile directory because if it + // lies on a network share the sandbox will prevent us from accessing it. + + if (process_type.empty() || process_type == switches::kServiceProcess) + return true; + +#if !defined(DISABLE_NACL) + if (process_type == switches::kNaClBrokerProcess || + process_type == switches::kNaClLoaderProcess) { + return true; + } +#endif + + return false; +} + +} // namespace chrome diff --git a/filenames.gypi b/filenames.gypi index 658c8e76b6b0..0e91dd21e16d 100644 --- a/filenames.gypi +++ b/filenames.gypi @@ -419,6 +419,14 @@ 'chromium_src/chrome/browser/ui/views/color_chooser_aura.h', 'chromium_src/chrome/browser/ui/views/frame/global_menu_bar_registrar_x11.cc', 'chromium_src/chrome/browser/ui/views/frame/global_menu_bar_registrar_x11.h', + 'chromium_src/chrome/common/chrome_constants.cc', + 'chromium_src/chrome/common/chrome_constants.h', + 'chromium_src/chrome/common/chrome_paths.cc', + 'chromium_src/chrome/common/chrome_paths.h', + 'chromium_src/chrome/common/chrome_paths_internal.h', + 'chromium_src/chrome/common/chrome_paths_linux.cc', + 'chromium_src/chrome/common/chrome_paths_mac.mm', + 'chromium_src/chrome/common/chrome_paths_win.cc', 'chromium_src/chrome/common/chrome_utility_messages.h', 'chromium_src/chrome/common/pref_names.cc', 'chromium_src/chrome/common/pref_names.h', From 05d2e431debde75edd84d83b357fb7b3a6eea9c7 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Fri, 13 Nov 2015 13:03:00 +0800 Subject: [PATCH 142/249] Fix building on OS X --- chromium_src/chrome/common/chrome_constants.cc | 8 +++++++- chromium_src/chrome/common/chrome_constants.h | 8 ++++++++ chromium_src/chrome/common/chrome_paths_mac.mm | 3 +-- 3 files changed, 16 insertions(+), 3 deletions(-) diff --git a/chromium_src/chrome/common/chrome_constants.cc b/chromium_src/chrome/common/chrome_constants.cc index 1e7bd33a9658..43a6ccdc7cb4 100644 --- a/chromium_src/chrome/common/chrome_constants.cc +++ b/chromium_src/chrome/common/chrome_constants.cc @@ -3,10 +3,16 @@ // found in the LICENSE file. #include "chrome/common/chrome_constants.h" -#include "chrome/common/chrome_version.h" + +#define FPL FILE_PATH_LITERAL namespace chrome { +#if defined(OS_MACOSX) +const base::FilePath::CharType kFrameworkName[] = + FPL(ATOM_PRODUCT_NAME " Framework.framework"); +#endif // OS_MACOSX + // filenames const base::FilePath::CharType kCacheDirname[] = FPL("Cache"); const base::FilePath::CharType kChannelIDFilename[] = FPL("Origin Bound Certs"); diff --git a/chromium_src/chrome/common/chrome_constants.h b/chromium_src/chrome/common/chrome_constants.h index e36eeeeff413..2df506ac5d59 100644 --- a/chromium_src/chrome/common/chrome_constants.h +++ b/chromium_src/chrome/common/chrome_constants.h @@ -11,6 +11,14 @@ namespace chrome { +#if defined(OS_MACOSX) +// NOTE: if you change the value of kFrameworkName, please don't forget to +// update components/test/run_all_unittests.cc as well. +// TODO(tfarina): Remove the comment above, when you fix components to use plist +// on Mac. +extern const base::FilePath::CharType kFrameworkName[]; +#endif // OS_MACOSX + // filenames extern const base::FilePath::CharType kCacheDirname[]; extern const base::FilePath::CharType kChannelIDFilename[]; diff --git a/chromium_src/chrome/common/chrome_paths_mac.mm b/chromium_src/chrome/common/chrome_paths_mac.mm index 09cf13bfe122..4a4eb87dc254 100644 --- a/chromium_src/chrome/common/chrome_paths_mac.mm +++ b/chromium_src/chrome/common/chrome_paths_mac.mm @@ -179,10 +179,9 @@ base::FilePath GetVersionedDirectory() { // .app's versioned directory. Go up two steps to get to the browser // .app's versioned directory. path = path.DirName().DirName(); - DCHECK_EQ(path.BaseName().value(), kChromeVersion); } else { // Go into the versioned directory. - path = path.Append("Versions").Append(kChromeVersion); + path = path.Append("Frameworks"); } return path; From d3caea91b073b1c38117135c7e720b2a7deef047 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Fri, 13 Nov 2015 13:05:16 +0800 Subject: [PATCH 143/249] Add paths from chrome_paths --- atom/app/atom_main_delegate.cc | 3 +++ atom/browser/api/atom_api_app.cc | 30 +++++++++++++----------------- docs/api/app.md | 8 ++++++-- 3 files changed, 22 insertions(+), 19 deletions(-) diff --git a/atom/app/atom_main_delegate.cc b/atom/app/atom_main_delegate.cc index 3bc1ac497082..80283131069d 100644 --- a/atom/app/atom_main_delegate.cc +++ b/atom/app/atom_main_delegate.cc @@ -16,6 +16,7 @@ #include "base/debug/stack_trace.h" #include "base/environment.h" #include "base/logging.h" +#include "chrome/common/chrome_paths.h" #include "content/public/common/content_switches.h" #include "ui/base/resource/resource_bundle.h" @@ -79,6 +80,8 @@ bool AtomMainDelegate::BasicStartupComplete(int* exit_code) { if (enable_stack_dumping) base::debug::EnableInProcessStackDumping(); + chrome::RegisterPathProvider(); + return brightray::MainDelegate::BasicStartupComplete(exit_code); } diff --git a/atom/browser/api/atom_api_app.cc b/atom/browser/api/atom_api_app.cc index d6d961a08dc4..e1fa03af5fbd 100644 --- a/atom/browser/api/atom_api_app.cc +++ b/atom/browser/api/atom_api_app.cc @@ -22,9 +22,9 @@ #include "base/command_line.h" #include "base/environment.h" #include "base/files/file_path.h" -#include "base/nix/xdg_util.h" #include "base/path_service.h" #include "brightray/browser/brightray_paths.h" +#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/common/content_switches.h" @@ -100,12 +100,22 @@ int GetPathConstant(const std::string& name) { return base::DIR_HOME; else if (name == "temp") return base::DIR_TEMP; - else if (name == "userDesktop") + else if (name == "userDesktop" || name == "desktop") return base::DIR_USER_DESKTOP; else if (name == "exe") return base::FILE_EXE; else if (name == "module") return base::FILE_MODULE; + else if (name == "documents") + return chrome::DIR_USER_DOCUMENTS; + else if (name == "downloads") + return chrome::DIR_DEFAULT_DOWNLOADS; + else if (name == "music") + return chrome::DIR_USER_MUSIC; + else if (name == "pictures") + return chrome::DIR_USER_PICTURES; + else if (name == "videos") + return chrome::DIR_USER_VIDEOS; else return -1; } @@ -156,17 +166,6 @@ void PassLoginInformation(scoped_refptr login_handler, login_handler->CancelAuth(); } -bool GetUserDownloadsDirectory(base::FilePath* path) { -#if defined(OS_LINUX) - *path = base::nix::GetXDGUserDirectory("DOWNLOAD", "Downloads"); - return true; -#elif defined(OS_MACOSX) - return false; -#elif defined(OS_WIN) - return false; -#endif -} - } // namespace App::App() { @@ -284,11 +283,8 @@ base::FilePath App::GetPath(mate::Arguments* args, const std::string& name) { int key = GetPathConstant(name); if (key >= 0) succeed = PathService::Get(key, &path); - if (!succeed) { - if (name == "downloads" && GetUserDownloadsDirectory(&path)) - return path; + if (!succeed) args->ThrowError("Failed to get path"); - } return path; } diff --git a/docs/api/app.md b/docs/api/app.md index b145ce7f01d4..9d10bbb835c5 100644 --- a/docs/api/app.md +++ b/docs/api/app.md @@ -238,10 +238,14 @@ You can request the following paths by the name: * `userData` The directory for storing your app's configuration files, which by default it is the `appData` directory appended with your app's name. * `temp` Temporary directory. -* `userDesktop` The current user's Desktop directory. * `exe` The current executable file. * `module` The `libchromiumcontent` library. -* `downloads` User's download directory. +* `desktop` The current user's Desktop directory. +* `documents` Directory for a user's "My Documents". +* `downloads` Directory for a user's downloads. +* `music` Directory for a user's music. +* `pictures` Directory for a user's pictures. +* `videos` Directory for a user's videos. ### `app.setPath(name, path)` From fdc19f2d3a16e703fbcc6985a4a98673a0292936 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Fri, 13 Nov 2015 13:23:13 +0800 Subject: [PATCH 144/249] Fix building on Windows --- .../chrome/common/chrome_paths_win.cc | 19 ++----------------- 1 file changed, 2 insertions(+), 17 deletions(-) diff --git a/chromium_src/chrome/common/chrome_paths_win.cc b/chromium_src/chrome/common/chrome_paths_win.cc index 18073ca04759..37f4ec2b05bd 100644 --- a/chromium_src/chrome/common/chrome_paths_win.cc +++ b/chromium_src/chrome/common/chrome_paths_win.cc @@ -15,9 +15,6 @@ #include "base/win/metro.h" #include "base/win/scoped_co_mem.h" #include "chrome/common/chrome_constants.h" -#include "chrome/common/chrome_switches.h" -#include "chrome/installer/util/browser_distribution.h" -#include "components/nacl/common/nacl_switches.h" namespace chrome { @@ -43,12 +40,7 @@ bool GetUserDirectory(int csidl_folder, base::FilePath* result) { } // namespace bool GetDefaultUserDataDirectory(base::FilePath* result) { - if (!PathService::Get(base::DIR_LOCAL_APP_DATA, result)) - return false; - BrowserDistribution* dist = BrowserDistribution::GetDistribution(); - *result = result->Append(dist->GetInstallSubDir()); - *result = result->Append(chrome::kUserDataDirname); - return true; + return PathService::Get(base::DIR_LOCAL_APP_DATA, result); } void GetUserCacheDirectory(const base::FilePath& profile_dir, @@ -106,16 +98,9 @@ bool ProcessNeedsProfileDir(const std::string& process_type) { // service processes to be able to use the profile directory because if it // lies on a network share the sandbox will prevent us from accessing it. - if (process_type.empty() || process_type == switches::kServiceProcess) + if (process_type.empty()) return true; -#if !defined(DISABLE_NACL) - if (process_type == switches::kNaClBrokerProcess || - process_type == switches::kNaClLoaderProcess) { - return true; - } -#endif - return false; } From 860c46b3c1fb05aae557971a17adbed9601e151c Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Fri, 13 Nov 2015 13:58:31 +0800 Subject: [PATCH 145/249] Separate options from switches On Windows the case sensitivity of command line switches are ignored, so --nodeIntegraion will become --nodeintegration. We should separate options from switches so we use "nodeIntegraion" in options, while passing "--node-integration" in command line. --- atom/browser/api/atom_api_window.cc | 14 +++---- atom/browser/native_window.cc | 38 +++++++++---------- atom/browser/native_window_mac.mm | 18 ++++----- atom/browser/native_window_views.cc | 20 +++++----- atom/browser/web_contents_preferences.cc | 48 ++++++++++++++---------- atom/common/options_switches.cc | 31 +++++++++++---- atom/common/options_switches.h | 22 ++++++++++- atom/renderer/lib/init.coffee | 4 +- 8 files changed, 119 insertions(+), 76 deletions(-) diff --git a/atom/browser/api/atom_api_window.cc b/atom/browser/api/atom_api_window.cc index 048a8eff1df9..61f43f9aac38 100644 --- a/atom/browser/api/atom_api_window.cc +++ b/atom/browser/api/atom_api_window.cc @@ -127,16 +127,16 @@ Window::Window(v8::Isolate* isolate, const mate::Dictionary& options) { // Use options.webPreferences to create WebContents. mate::Dictionary web_preferences = mate::Dictionary::CreateEmpty(isolate); - options.Get(switches::kWebPreferences, &web_preferences); + options.Get(options::kWebPreferences, &web_preferences); // Be compatible with old options which are now in web_preferences. v8::Local value; - if (options.Get(switches::kNodeIntegration, &value)) - web_preferences.Set(switches::kNodeIntegration, value); - if (options.Get(switches::kPreloadScript, &value)) - web_preferences.Set(switches::kPreloadScript, value); - if (options.Get(switches::kZoomFactor, &value)) - web_preferences.Set(switches::kZoomFactor, value); + if (options.Get(options::kNodeIntegration, &value)) + web_preferences.Set(options::kNodeIntegration, value); + if (options.Get(options::kPreloadScript, &value)) + web_preferences.Set(options::kPreloadScript, value); + if (options.Get(options::kZoomFactor, &value)) + web_preferences.Set(options::kZoomFactor, value); // Creates the WebContents used by BrowserWindow. auto web_contents = WebContents::Create(isolate, web_preferences); diff --git a/atom/browser/native_window.cc b/atom/browser/native_window.cc index ba5dad74f523..ad7a6c4b0654 100644 --- a/atom/browser/native_window.cc +++ b/atom/browser/native_window.cc @@ -56,16 +56,16 @@ NativeWindow::NativeWindow( aspect_ratio_(0.0), inspectable_web_contents_(inspectable_web_contents), weak_factory_(this) { - options.Get(switches::kFrame, &has_frame_); - options.Get(switches::kTransparent, &transparent_); - options.Get(switches::kEnableLargerThanScreen, &enable_larger_than_screen_); + options.Get(options::kFrame, &has_frame_); + options.Get(options::kTransparent, &transparent_); + options.Get(options::kEnableLargerThanScreen, &enable_larger_than_screen_); // Tell the content module to initialize renderer widget with transparent // mode. ui::GpuSwitchingManager::SetTransparent(transparent_); // Read icon before window is created. - options.Get(switches::kIcon, &icon_); + options.Get(options::kIcon, &icon_); WindowList::AddWindow(this); } @@ -91,25 +91,25 @@ void NativeWindow::InitFromOptions(const mate::Dictionary& options) { // Setup window from options. int x = -1, y = -1; bool center; - if (options.Get(switches::kX, &x) && options.Get(switches::kY, &y)) { + if (options.Get(options::kX, &x) && options.Get(options::kY, &y)) { SetPosition(gfx::Point(x, y)); - } else if (options.Get(switches::kCenter, ¢er) && center) { + } else if (options.Get(options::kCenter, ¢er) && center) { Center(); } // On Linux and Window we may already have maximum size defined. extensions::SizeConstraints size_constraints(GetContentSizeConstraints()); int min_height = 0, min_width = 0; - if (options.Get(switches::kMinHeight, &min_height) | - options.Get(switches::kMinWidth, &min_width)) { + if (options.Get(options::kMinHeight, &min_height) | + options.Get(options::kMinWidth, &min_width)) { size_constraints.set_minimum_size(gfx::Size(min_width, min_height)); } int max_height = INT_MAX, max_width = INT_MAX; - if (options.Get(switches::kMaxHeight, &max_height) | - options.Get(switches::kMaxWidth, &max_width)) { + if (options.Get(options::kMaxHeight, &max_height) | + options.Get(options::kMaxWidth, &max_width)) { size_constraints.set_maximum_size(gfx::Size(max_width, max_height)); } bool use_content_size = false; - options.Get(switches::kUseContentSize, &use_content_size); + options.Get(options::kUseContentSize, &use_content_size); if (use_content_size) { SetContentSizeConstraints(size_constraints); } else { @@ -117,39 +117,39 @@ void NativeWindow::InitFromOptions(const mate::Dictionary& options) { } #if defined(OS_WIN) || defined(USE_X11) bool resizable; - if (options.Get(switches::kResizable, &resizable)) { + if (options.Get(options::kResizable, &resizable)) { SetResizable(resizable); } #endif bool top; - if (options.Get(switches::kAlwaysOnTop, &top) && top) { + if (options.Get(options::kAlwaysOnTop, &top) && top) { SetAlwaysOnTop(true); } #if defined(OS_MACOSX) || defined(OS_WIN) bool fullscreen; - if (options.Get(switches::kFullscreen, &fullscreen) && fullscreen) { + if (options.Get(options::kFullscreen, &fullscreen) && fullscreen) { SetFullScreen(true); } #endif bool skip; - if (options.Get(switches::kSkipTaskbar, &skip) && skip) { + if (options.Get(options::kSkipTaskbar, &skip) && skip) { SetSkipTaskbar(skip); } bool kiosk; - if (options.Get(switches::kKiosk, &kiosk) && kiosk) { + if (options.Get(options::kKiosk, &kiosk) && kiosk) { SetKiosk(kiosk); } std::string color; - if (options.Get(switches::kBackgroundColor, &color)) { + if (options.Get(options::kBackgroundColor, &color)) { SetBackgroundColor(color); } std::string title("Electron"); - options.Get(switches::kTitle, &title); + options.Get(options::kTitle, &title); SetTitle(title); // Then show it. bool show = true; - options.Get(switches::kShow, &show); + options.Get(options::kShow, &show); if (show) Show(); } diff --git a/atom/browser/native_window_mac.mm b/atom/browser/native_window_mac.mm index 28c8a5ae59a0..b129ded6f85e 100644 --- a/atom/browser/native_window_mac.mm +++ b/atom/browser/native_window_mac.mm @@ -320,8 +320,8 @@ NativeWindowMac::NativeWindowMac( is_kiosk_(false), attention_request_id_(0) { int width = 800, height = 600; - options.Get(switches::kWidth, &width); - options.Get(switches::kHeight, &height); + options.Get(options::kWidth, &width); + options.Get(options::kHeight, &height); NSRect main_screen_rect = [[[NSScreen screens] objectAtIndex:0] frame]; NSRect cocoa_bounds = NSMakeRect( @@ -331,14 +331,14 @@ NativeWindowMac::NativeWindowMac( height); bool useStandardWindow = true; - options.Get(switches::kStandardWindow, &useStandardWindow); + options.Get(options::kStandardWindow, &useStandardWindow); bool resizable = true; - options.Get(switches::kResizable, &resizable); + options.Get(options::kResizable, &resizable); // New title bar styles are available in Yosemite or newer std::string titleBarStyle; if (base::mac::IsOSYosemiteOrLater()) - options.Get(switches::kTitleBarStyle, &titleBarStyle); + options.Get(options::kTitleBarStyle, &titleBarStyle); NSUInteger styleMask = NSTitledWindowMask | NSClosableWindowMask | NSMiniaturizableWindowMask; @@ -394,23 +394,23 @@ NativeWindowMac::NativeWindowMac( // On OS X the initial window size doesn't include window frame. bool use_content_size = false; - options.Get(switches::kUseContentSize, &use_content_size); + options.Get(options::kUseContentSize, &use_content_size); if (!has_frame() || !use_content_size) SetSize(gfx::Size(width, height)); // Enable the NSView to accept first mouse event. bool acceptsFirstMouse = false; - options.Get(switches::kAcceptFirstMouse, &acceptsFirstMouse); + options.Get(options::kAcceptFirstMouse, &acceptsFirstMouse); [window_ setAcceptsFirstMouse:acceptsFirstMouse]; // Disable auto-hiding cursor. bool disableAutoHideCursor = false; - options.Get(switches::kDisableAutoHideCursor, &disableAutoHideCursor); + options.Get(options::kDisableAutoHideCursor, &disableAutoHideCursor); [window_ setDisableAutoHideCursor:disableAutoHideCursor]; // Disable fullscreen button when 'fullscreen' is specified to false. bool fullscreen; - if (!(options.Get(switches::kFullscreen, &fullscreen) && + if (!(options.Get(options::kFullscreen, &fullscreen) && !fullscreen)) { NSUInteger collectionBehavior = [window_ collectionBehavior]; collectionBehavior |= NSWindowCollectionBehaviorFullScreenPrimary; diff --git a/atom/browser/native_window_views.cc b/atom/browser/native_window_views.cc index 876058789d0f..c12ae1986c64 100644 --- a/atom/browser/native_window_views.cc +++ b/atom/browser/native_window_views.cc @@ -132,13 +132,13 @@ NativeWindowViews::NativeWindowViews( keyboard_event_handler_(new views::UnhandledKeyboardEventHandler), use_content_size_(false), resizable_(true) { - options.Get(switches::kTitle, &title_); - options.Get(switches::kAutoHideMenuBar, &menu_bar_autohide_); + options.Get(options::kTitle, &title_); + options.Get(options::kAutoHideMenuBar, &menu_bar_autohide_); #if defined(OS_WIN) // On Windows we rely on the CanResize() to indicate whether window can be // resized, and it should be set before window is created. - options.Get(switches::kResizable, &resizable_); + options.Get(options::kResizable, &resizable_); #endif if (enable_larger_than_screen()) @@ -150,8 +150,8 @@ NativeWindowViews::NativeWindowViews( gfx::Size(), gfx::Size(INT_MAX / 10, INT_MAX / 10))); int width = 800, height = 600; - options.Get(switches::kWidth, &width); - options.Get(switches::kHeight, &height); + options.Get(options::kWidth, &width); + options.Get(options::kHeight, &height); gfx::Rect bounds(0, 0, width, height); widget_size_ = bounds.size(); @@ -187,7 +187,7 @@ NativeWindowViews::NativeWindowViews( window_->Init(params); bool fullscreen = false; - options.Get(switches::kFullscreen, &fullscreen); + options.Get(options::kFullscreen, &fullscreen); #if defined(USE_X11) // Start monitoring window states. @@ -195,7 +195,7 @@ NativeWindowViews::NativeWindowViews( // Set _GTK_THEME_VARIANT to dark if we have "dark-theme" option set. bool use_dark_theme = false; - if (options.Get(switches::kDarkTheme, &use_dark_theme) && use_dark_theme) { + if (options.Get(options::kDarkTheme, &use_dark_theme) && use_dark_theme) { XDisplay* xdisplay = gfx::GetXDisplay(); XChangeProperty(xdisplay, GetAcceleratedWidget(), XInternAtom(xdisplay, "_GTK_THEME_VARIANT", False), @@ -209,7 +209,7 @@ NativeWindowViews::NativeWindowViews( // to manually set the _NET_WM_STATE. std::vector<::Atom> state_atom_list; bool skip_taskbar = false; - if (options.Get(switches::kSkipTaskbar, &skip_taskbar) && skip_taskbar) { + if (options.Get(options::kSkipTaskbar, &skip_taskbar) && skip_taskbar) { state_atom_list.push_back(GetAtom("_NET_WM_STATE_SKIP_TASKBAR")); } @@ -223,7 +223,7 @@ NativeWindowViews::NativeWindowViews( // Set the _NET_WM_WINDOW_TYPE. std::string window_type; - if (options.Get(switches::kType, &window_type)) + if (options.Get(options::kType, &window_type)) SetWindowType(GetAcceleratedWidget(), window_type); #endif @@ -274,7 +274,7 @@ NativeWindowViews::NativeWindowViews( gfx::Size size = bounds.size(); if (has_frame() && - options.Get(switches::kUseContentSize, &use_content_size_) && + options.Get(options::kUseContentSize, &use_content_size_) && use_content_size_) size = ContentSizeToWindowSize(size); diff --git a/atom/browser/web_contents_preferences.cc b/atom/browser/web_contents_preferences.cc index 2adb77211b27..188de4d1bfe7 100644 --- a/atom/browser/web_contents_preferences.cc +++ b/atom/browser/web_contents_preferences.cc @@ -25,13 +25,23 @@ namespace atom { namespace { // Array of available web runtime features. -const char* kWebRuntimeFeatures[] = { - switches::kExperimentalFeatures, - switches::kExperimentalCanvasFeatures, - switches::kOverlayScrollbars, - switches::kOverlayFullscreenVideo, - switches::kSharedWorker, - switches::kPageVisibility, +struct FeaturePair { + const char* name; + const char* cmd; +}; +FeaturePair kWebRuntimeFeatures[] = { + { options::kExperimentalFeatures, + switches::kExperimentalFeatures }, + { options::kExperimentalCanvasFeatures, + switches::kExperimentalCanvasFeatures }, + { options::kOverlayScrollbars, + switches::kOverlayScrollbars }, + { options::kOverlayFullscreenVideo, + switches::kOverlayFullscreenVideo }, + { options::kSharedWorker, + switches::kSharedWorker }, + { options::kPageVisibility, + switches::kPageVisibility }, }; } // namespace @@ -69,7 +79,7 @@ void WebContentsPreferences::AppendExtraCommandLineSwitches( bool b; #if defined(OS_WIN) // Check if DirectWrite is disabled. - if (web_preferences.GetBoolean(switches::kDirectWrite, &b) && !b) + if (web_preferences.GetBoolean(options::kDirectWrite, &b) && !b) command_line->AppendSwitch(::switches::kDisableDirectWrite); #endif @@ -80,17 +90,17 @@ void WebContentsPreferences::AppendExtraCommandLineSwitches( // This set of options are not availabe in WebPreferences, so we have to pass // them via command line and enable them in renderer procss. for (size_t i = 0; i < arraysize(kWebRuntimeFeatures); ++i) { - const char* feature = kWebRuntimeFeatures[i]; - if (web_preferences.GetBoolean(feature, &b)) - command_line->AppendSwitchASCII(feature, b ? "true" : "false"); + const auto& feature = kWebRuntimeFeatures[i]; + if (web_preferences.GetBoolean(feature.name, &b)) + command_line->AppendSwitchASCII(feature.cmd, b ? "true" : "false"); } // Check if we have node integration specified. bool node_integration = true; - web_preferences.GetBoolean(switches::kNodeIntegration, &node_integration); + web_preferences.GetBoolean(options::kNodeIntegration, &node_integration); // Be compatible with old API of "node-integration" option. std::string old_token; - if (web_preferences.GetString(switches::kNodeIntegration, &old_token) && + if (web_preferences.GetString(options::kNodeIntegration, &old_token) && old_token != "disable") node_integration = true; command_line->AppendSwitchASCII(switches::kNodeIntegration, @@ -98,12 +108,12 @@ void WebContentsPreferences::AppendExtraCommandLineSwitches( // The preload script. base::FilePath::StringType preload; - if (web_preferences.GetString(switches::kPreloadScript, &preload)) { + if (web_preferences.GetString(options::kPreloadScript, &preload)) { if (base::FilePath(preload).IsAbsolute()) command_line->AppendSwitchNative(switches::kPreloadScript, preload); else LOG(ERROR) << "preload script must have absolute path."; - } else if (web_preferences.GetString(switches::kPreloadUrl, &preload)) { + } else if (web_preferences.GetString(options::kPreloadUrl, &preload)) { // Translate to file path if there is "preload-url" option. base::FilePath preload_path; if (net::FileURLToFilePath(GURL(preload), &preload_path)) @@ -114,15 +124,14 @@ void WebContentsPreferences::AppendExtraCommandLineSwitches( // The zoom factor. double zoom_factor = 1.0; - if (web_preferences.GetDouble(switches::kZoomFactor, &zoom_factor) && + if (web_preferences.GetDouble(options::kZoomFactor, &zoom_factor) && zoom_factor != 1.0) command_line->AppendSwitchASCII(switches::kZoomFactor, base::DoubleToString(zoom_factor)); // --guest-instance-id, which is used to identify guest WebContents. int guest_instance_id; - if (web_preferences.GetInteger(switches::kGuestInstanceID, - &guest_instance_id)) + if (web_preferences.GetInteger(options::kGuestInstanceID, &guest_instance_id)) command_line->AppendSwitchASCII(switches::kGuestInstanceID, base::IntToString(guest_instance_id)); } @@ -152,8 +161,7 @@ void WebContentsPreferences::OverrideWebkitPrefs( prefs->allow_displaying_insecure_content = !b; prefs->allow_running_insecure_content = !b; } - if (self->web_preferences_.GetBoolean("allowDisplayingInsecureContent", - &b)) + if (self->web_preferences_.GetBoolean("allowDisplayingInsecureContent", &b)) prefs->allow_displaying_insecure_content = b; if (self->web_preferences_.GetBoolean("allowRunningInsecureContent", &b)) prefs->allow_running_insecure_content = b; diff --git a/atom/common/options_switches.cc b/atom/common/options_switches.cc index 9b3b50b4bf31..1d375ba0fc4e 100644 --- a/atom/common/options_switches.cc +++ b/atom/common/options_switches.cc @@ -6,7 +6,7 @@ namespace atom { -namespace switches { +namespace options { const char kTitle[] = "title"; const char kIcon[] = "icon"; @@ -85,6 +85,12 @@ const char kNodeIntegration[] = "nodeIntegration"; // Instancd ID of guest WebContents. const char kGuestInstanceID[] = "guestInstanceId"; +// Set page visiblity to always visible. +const char kPageVisibility[] = "pageVisibility"; + +// Enable DirectWrite on Windows. +const char kDirectWrite[] = "directWrite"; + // Web runtime features. const char kExperimentalFeatures[] = "experimentalFeatures"; const char kExperimentalCanvasFeatures[] = "experimentalCanvasFeatures"; @@ -92,6 +98,10 @@ const char kOverlayScrollbars[] = "overlayScrollbars"; const char kOverlayFullscreenVideo[] = "overlayFullscreenVideo"; const char kSharedWorker[] = "sharedWorker"; +} // namespace options + +namespace switches { + // Enable plugins. const char kEnablePlugins[] = "enable-plugins"; @@ -101,12 +111,6 @@ const char kPpapiFlashPath[] = "ppapi-flash-path"; // Ppapi Flash version. const char kPpapiFlashVersion[] = "ppapi-flash-version"; -// Set page visiblity to always visible. -const char kPageVisibility[] = "page-visibility"; - -// Enable DirectWrite on Windows. -const char kDirectWrite[] = "direct-write"; - // Path to client certificate. const char kClientCertificate[] = "client-certificate"; @@ -126,6 +130,19 @@ const char kCipherSuiteBlacklist[] = "cipher-suite-blacklist"; // The browser process app model ID const char kAppUserModelId[] = "app-user-model-id"; +// The command line switch versions of the options. +const char kZoomFactor[] = "zoom-factor"; +const char kPreloadScript[] = "preload"; +const char kPreloadUrl[] = "preload-url"; +const char kNodeIntegration[] = "node-integration"; +const char kGuestInstanceID[] = "guest-instance-id"; +const char kExperimentalFeatures[] = "experimental-features"; +const char kExperimentalCanvasFeatures[] = "experimental-canvas-features"; +const char kOverlayScrollbars[] = "overlay-scrollbars"; +const char kOverlayFullscreenVideo[] = "overlay-fullscreen-video"; +const char kSharedWorker[] = "shared-worker"; +const char kPageVisibility[] = "page-visiblity"; + } // namespace switches } // namespace atom diff --git a/atom/common/options_switches.h b/atom/common/options_switches.h index 9f171836f653..7f262fb0f721 100644 --- a/atom/common/options_switches.h +++ b/atom/common/options_switches.h @@ -7,7 +7,7 @@ namespace atom { -namespace switches { +namespace options { extern const char kTitle[]; extern const char kIcon[]; @@ -41,6 +41,7 @@ extern const char kBackgroundColor[]; extern const char kWebPreferences[]; // WebPreferences. +extern const char kDirectWrite[]; extern const char kZoomFactor[]; extern const char kPreloadScript[]; extern const char kPreloadUrl[]; @@ -52,9 +53,14 @@ extern const char kOverlayScrollbars[]; extern const char kOverlayFullscreenVideo[]; extern const char kSharedWorker[]; extern const char kPageVisibility[]; -extern const char kDirectWrite[]; + +} // namespace options + // Following are actually command line switches, should be moved to other files. + +namespace switches { + extern const char kEnablePlugins[]; extern const char kPpapiFlashPath[]; extern const char kPpapiFlashVersion[]; @@ -65,6 +71,18 @@ extern const char kSSLVersionFallbackMin[]; extern const char kCipherSuiteBlacklist[]; extern const char kAppUserModelId[]; +extern const char kZoomFactor[]; +extern const char kPreloadScript[]; +extern const char kPreloadUrl[]; +extern const char kNodeIntegration[]; +extern const char kGuestInstanceID[]; +extern const char kExperimentalFeatures[]; +extern const char kExperimentalCanvasFeatures[]; +extern const char kOverlayScrollbars[]; +extern const char kOverlayFullscreenVideo[]; +extern const char kSharedWorker[]; +extern const char kPageVisibility[]; + } // namespace switches } // namespace atom diff --git a/atom/renderer/lib/init.coffee b/atom/renderer/lib/init.coffee index b7155c1cc55a..d9f104f8d4fc 100644 --- a/atom/renderer/lib/init.coffee +++ b/atom/renderer/lib/init.coffee @@ -27,10 +27,10 @@ v8Util.setHiddenValue global, 'ipc', new events.EventEmitter # Process command line arguments. nodeIntegration = 'false' for arg in process.argv - if arg.indexOf('--guestInstanceId=') == 0 + if arg.indexOf('--guest-instance-id=') == 0 # This is a guest web view. process.guestInstanceId = parseInt arg.substr(arg.indexOf('=') + 1) - else if arg.indexOf('--nodeIntegration=') == 0 + else if arg.indexOf('--node-integration=') == 0 nodeIntegration = arg.substr arg.indexOf('=') + 1 else if arg.indexOf('--preload=') == 0 preloadScript = arg.substr arg.indexOf('=') + 1 From 9ac87e844a08e5131c1e327e616eb19ddfb79948 Mon Sep 17 00:00:00 2001 From: Sunny Date: Fri, 13 Nov 2015 15:41:20 +0800 Subject: [PATCH 146/249] Fix node_bindings link in Simplified Chinese document translation --- docs/development/atom-shell-vs-node-webkit.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/development/atom-shell-vs-node-webkit.md b/docs/development/atom-shell-vs-node-webkit.md index c1fffa304ab5..4431a54eacee 100644 --- a/docs/development/atom-shell-vs-node-webkit.md +++ b/docs/development/atom-shell-vs-node-webkit.md @@ -35,7 +35,7 @@ __3. Node Integration__ In NW.js, the Node integration in web pages requires patching Chromium to work, while in Electron we chose a different way to integrate the libuv loop with each platform's message loop to avoid hacking Chromium. See the -[`node_bindings`](../../atom/common/) code for how that was done. +[`node_bindings`](../../../atom/common/) code for how that was done. __4. Multi-context__ From fbb8e61958c8950455883e2a4ae12088ba030a12 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Fri, 13 Nov 2015 16:03:40 +0800 Subject: [PATCH 147/249] Replace "Url" in API names with "URL" --- atom/browser/api/atom_api_auto_updater.cc | 2 +- atom/browser/api/atom_api_cookies.cc | 6 +- atom/browser/api/atom_api_download_item.cc | 6 +- atom/browser/api/atom_api_download_item.h | 2 +- atom/browser/api/atom_api_protocol.cc | 4 +- atom/browser/api/atom_api_web_contents.cc | 4 +- atom/browser/api/lib/app.coffee | 3 +- atom/browser/api/lib/auto-updater.coffee | 9 +- .../lib/auto-updater/auto-updater-win.coffee | 12 +-- .../auto-updater/squirrel-update-win.coffee | 8 +- atom/browser/api/lib/browser-window.coffee | 8 +- .../api/lib/navigation-controller.coffee | 20 ++-- atom/browser/api/lib/web-contents.coffee | 8 +- atom/browser/atom_access_token_store.cc | 6 +- atom/browser/default_app/default_app.js | 2 +- atom/browser/lib/guest-view-manager.coffee | 4 +- atom/browser/lib/guest-window-manager.coffee | 8 +- .../browser/net/url_request_async_asar_job.cc | 4 +- atom/browser/net/url_request_async_asar_job.h | 6 +- atom/browser/web_contents_preferences.cc | 2 +- atom/common/api/atom_api_native_image.cc | 5 +- atom/common/api/lib/crash-reporter.coffee | 19 ++-- atom/common/api/lib/native-image.coffee | 8 +- atom/common/options_switches.cc | 4 +- atom/common/options_switches.h | 4 +- atom/common/platform_util_win.cc | 4 +- atom/renderer/api/atom_api_web_frame.cc | 10 +- atom/renderer/api/atom_api_web_frame.h | 2 +- atom/renderer/api/lib/web-frame.coffee | 10 +- atom/renderer/lib/override.coffee | 4 +- .../lib/web-view/guest-view-internal.coffee | 6 +- .../lib/web-view/web-view-attributes.coffee | 8 +- atom/renderer/lib/web-view/web-view.coffee | 91 ++++++++++--------- docs/api/auto-updater.md | 6 +- docs/api/browser-window.md | 6 +- docs/api/crash-reporter.md | 6 +- docs/api/download-item.md | 2 +- docs/api/native-image.md | 8 +- docs/api/remote.md | 2 +- docs/api/session.md | 6 +- docs/api/synopsis.md | 2 +- docs/api/web-contents.md | 30 +++--- docs/api/web-frame.md | 6 +- docs/api/web-view-tag.md | 14 +-- docs/tutorial/application-packaging.md | 2 +- docs/tutorial/online-offline-events.md | 4 +- docs/tutorial/quick-start.md | 2 +- docs/tutorial/using-pepper-flash-plugin.md | 2 +- spec/api-browser-window-spec.coffee | 34 +++---- spec/api-clipboard-spec.coffee | 4 +- spec/api-crash-reporter-spec.coffee | 4 +- spec/api-ipc-spec.coffee | 2 +- spec/api-session-spec.coffee | 8 +- spec/asar-spec.coffee | 4 +- spec/chromium-spec.coffee | 4 +- spec/fixtures/api/crash.html | 2 +- spec/static/main.js | 4 +- 57 files changed, 251 insertions(+), 212 deletions(-) diff --git a/atom/browser/api/atom_api_auto_updater.cc b/atom/browser/api/atom_api_auto_updater.cc index 1c80f73f7a7d..1a02a54d4533 100644 --- a/atom/browser/api/atom_api_auto_updater.cc +++ b/atom/browser/api/atom_api_auto_updater.cc @@ -81,7 +81,7 @@ void AutoUpdater::OnWindowAllClosed() { mate::ObjectTemplateBuilder AutoUpdater::GetObjectTemplateBuilder( v8::Isolate* isolate) { return mate::ObjectTemplateBuilder(isolate) - .SetMethod("setFeedUrl", &auto_updater::AutoUpdater::SetFeedURL) + .SetMethod("setFeedURL", &auto_updater::AutoUpdater::SetFeedURL) .SetMethod("checkForUpdates", &auto_updater::AutoUpdater::CheckForUpdates) .SetMethod("quitAndInstall", &AutoUpdater::QuitAndInstall); } diff --git a/atom/browser/api/atom_api_cookies.cc b/atom/browser/api/atom_api_cookies.cc index 4f989eff7275..a3b2c37c9acd 100644 --- a/atom/browser/api/atom_api_cookies.cc +++ b/atom/browser/api/atom_api_cookies.cc @@ -204,7 +204,7 @@ void Cookies::GetCookiesOnIOThread(scoped_ptr filter, Passed(&filter), callback))) { BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, base::Bind(&RunGetCookiesCallbackOnUIThread, isolate(), - "Url is not valid", net::CookieList(), callback)); + "URL is not valid", net::CookieList(), callback)); } } @@ -229,7 +229,7 @@ void Cookies::Remove(const mate::Dictionary& details, error_message = "Details(url, name) of removing cookie are required."; } if (error_message.empty() && !url.is_valid()) { - error_message = "Url is not valid."; + error_message = "URL is not valid."; } if (!error_message.empty()) { RunRemoveCookiesCallbackOnUIThread(isolate(), error_message, callback); @@ -261,7 +261,7 @@ void Cookies::Set(const base::DictionaryValue& options, GURL gurl(url); if (error_message.empty() && !gurl.is_valid()) { - error_message = "Url is not valid."; + error_message = "URL is not valid."; } if (!error_message.empty()) { diff --git a/atom/browser/api/atom_api_download_item.cc b/atom/browser/api/atom_api_download_item.cc index 691cfbfef594..7dd271304a43 100644 --- a/atom/browser/api/atom_api_download_item.cc +++ b/atom/browser/api/atom_api_download_item.cc @@ -103,7 +103,7 @@ int64 DownloadItem::GetTotalBytes() { return download_item_->GetTotalBytes(); } -const GURL& DownloadItem::GetUrl() { +const GURL& DownloadItem::GetURL() { return download_item_->GetURL(); } @@ -116,7 +116,7 @@ bool DownloadItem::HasUserGesture() { } std::string DownloadItem::GetFilename() { - return base::UTF16ToUTF8(net::GenerateFileName(GetUrl(), + return base::UTF16ToUTF8(net::GenerateFileName(GetURL(), GetContentDisposition(), std::string(), download_item_->GetSuggestedFilename(), @@ -152,7 +152,7 @@ mate::ObjectTemplateBuilder DownloadItem::GetObjectTemplateBuilder( .SetMethod("cancel", &DownloadItem::Cancel) .SetMethod("getReceivedBytes", &DownloadItem::GetReceivedBytes) .SetMethod("getTotalBytes", &DownloadItem::GetTotalBytes) - .SetMethod("getUrl", &DownloadItem::GetUrl) + .SetMethod("getURL", &DownloadItem::GetURL) .SetMethod("getMimeType", &DownloadItem::GetMimeType) .SetMethod("hasUserGesture", &DownloadItem::HasUserGesture) .SetMethod("getFilename", &DownloadItem::GetFilename) diff --git a/atom/browser/api/atom_api_download_item.h b/atom/browser/api/atom_api_download_item.h index 14074a4bed0d..955801cd9940 100644 --- a/atom/browser/api/atom_api_download_item.h +++ b/atom/browser/api/atom_api_download_item.h @@ -49,7 +49,7 @@ class DownloadItem : public mate::EventEmitter, bool HasUserGesture(); std::string GetFilename(); std::string GetContentDisposition(); - const GURL& GetUrl(); + const GURL& GetURL(); void SetSavePath(const base::FilePath& path); private: diff --git a/atom/browser/api/atom_api_protocol.cc b/atom/browser/api/atom_api_protocol.cc index e76f26f0d4f5..b1ad7981377a 100644 --- a/atom/browser/api/atom_api_protocol.cc +++ b/atom/browser/api/atom_api_protocol.cc @@ -37,7 +37,7 @@ mate::ObjectTemplateBuilder Protocol::GetObjectTemplateBuilder( .SetMethod("registerBufferProtocol", &Protocol::RegisterProtocol) .SetMethod("registerFileProtocol", - &Protocol::RegisterProtocol) + &Protocol::RegisterProtocol) .SetMethod("registerHttpProtocol", &Protocol::RegisterProtocol) .SetMethod("unregisterProtocol", &Protocol::UnregisterProtocol) @@ -47,7 +47,7 @@ mate::ObjectTemplateBuilder Protocol::GetObjectTemplateBuilder( .SetMethod("interceptBufferProtocol", &Protocol::InterceptProtocol) .SetMethod("interceptFileProtocol", - &Protocol::InterceptProtocol) + &Protocol::InterceptProtocol) .SetMethod("interceptHttpProtocol", &Protocol::InterceptProtocol) .SetMethod("uninterceptProtocol", &Protocol::UninterceptProtocol); diff --git a/atom/browser/api/atom_api_web_contents.cc b/atom/browser/api/atom_api_web_contents.cc index d67794a91aeb..601a4ba63f13 100644 --- a/atom/browser/api/atom_api_web_contents.cc +++ b/atom/browser/api/atom_api_web_contents.cc @@ -1003,8 +1003,8 @@ mate::ObjectTemplateBuilder WebContents::GetObjectTemplateBuilder( .SetMethod("isAlive", &WebContents::IsAlive, true) .SetMethod("getId", &WebContents::GetID) .SetMethod("equal", &WebContents::Equal) - .SetMethod("_loadUrl", &WebContents::LoadURL) - .SetMethod("_getUrl", &WebContents::GetURL) + .SetMethod("_loadURL", &WebContents::LoadURL) + .SetMethod("_getURL", &WebContents::GetURL) .SetMethod("getTitle", &WebContents::GetTitle) .SetMethod("isLoading", &WebContents::IsLoading) .SetMethod("isWaitingForResponse", &WebContents::IsWaitingForResponse) diff --git a/atom/browser/api/lib/app.coffee b/atom/browser/api/lib/app.coffee index 3494a6e6e431..f8d3cedd38f9 100644 --- a/atom/browser/api/lib/app.coffee +++ b/atom/browser/api/lib/app.coffee @@ -63,10 +63,11 @@ wrapDownloadItem = (downloadItem) -> # downloadItem is an EventEmitter. downloadItem.__proto__ = EventEmitter.prototype # Deprecated. - deprecate.property downloadItem, 'url', 'getUrl' + deprecate.property downloadItem, 'url', 'getURL' deprecate.property downloadItem, 'filename', 'getFilename' deprecate.property downloadItem, 'mimeType', 'getMimeType' deprecate.property downloadItem, 'hasUserGesture', 'hasUserGesture' + deprecate.rename downloadItem, 'getUrl', 'getURL' downloadItemBindings._setWrapDownloadItem wrapDownloadItem # Only one App object pemitted. diff --git a/atom/browser/api/lib/auto-updater.coffee b/atom/browser/api/lib/auto-updater.coffee index d5e69e2a5c2e..28df59fbc3db 100644 --- a/atom/browser/api/lib/auto-updater.coffee +++ b/atom/browser/api/lib/auto-updater.coffee @@ -1,5 +1,12 @@ -module.exports = +{deprecate} = require 'electron' + +autoUpdater = if process.platform is 'win32' require './auto-updater/auto-updater-win' else require './auto-updater/auto-updater-native' + +# Deprecated. +deprecate.rename autoUpdater, 'setFeedUrl', 'setFeedURL' + +module.exports = autoUpdater diff --git a/atom/browser/api/lib/auto-updater/auto-updater-win.coffee b/atom/browser/api/lib/auto-updater/auto-updater-win.coffee index 12ebedaaf71c..e7cb194ffcf4 100644 --- a/atom/browser/api/lib/auto-updater/auto-updater-win.coffee +++ b/atom/browser/api/lib/auto-updater/auto-updater-win.coffee @@ -9,28 +9,28 @@ class AutoUpdater extends EventEmitter squirrelUpdate.processStart() app.quit() - setFeedUrl: (updateUrl) -> - @updateUrl = updateUrl + setFeedURL: (updateURL) -> + @updateURL = updateURL checkForUpdates: -> - return @emitError 'Update URL is not set' unless @updateUrl + return @emitError 'Update URL is not set' unless @updateURL return @emitError 'Can not find Squirrel' unless squirrelUpdate.supported() @emit 'checking-for-update' - squirrelUpdate.download @updateUrl, (error, update) => + squirrelUpdate.download @updateURL, (error, update) => return @emitError error if error? return @emit 'update-not-available' unless update? @emit 'update-available' - squirrelUpdate.update @updateUrl, (error) => + squirrelUpdate.update @updateURL, (error) => return @emitError error if error? {releaseNotes, version} = update # Following information is not available on Windows, so fake them. date = new Date - url = @updateUrl + url = @updateURL @emit 'update-downloaded', {}, releaseNotes, version, date, url, => @quitAndInstall() diff --git a/atom/browser/api/lib/auto-updater/squirrel-update-win.coffee b/atom/browser/api/lib/auto-updater/squirrel-update-win.coffee index ed302124e52e..ee914c4fa827 100644 --- a/atom/browser/api/lib/auto-updater/squirrel-update-win.coffee +++ b/atom/browser/api/lib/auto-updater/squirrel-update-win.coffee @@ -41,8 +41,8 @@ exports.processStart = (callback) -> spawnUpdate ['--processStart', exeName], true, -> # Download the releases specified by the URL and write new results to stdout. -exports.download = (updateUrl, callback) -> - spawnUpdate ['--download', updateUrl], false, (error, stdout) -> +exports.download = (updateURL, callback) -> + spawnUpdate ['--download', updateURL], false, (error, stdout) -> return callback(error) if error? try @@ -55,8 +55,8 @@ exports.download = (updateUrl, callback) -> callback null, update # Update the application to the latest remote version specified by URL. -exports.update = (updateUrl, callback) -> - spawnUpdate ['--update', updateUrl], false, callback +exports.update = (updateURL, callback) -> + spawnUpdate ['--update', updateURL], false, callback # Is the Update.exe installed with the current application? exports.supported = -> diff --git a/atom/browser/api/lib/browser-window.coffee b/atom/browser/api/lib/browser-window.coffee index 3cefa1bf60ce..9947bc1a50ba 100644 --- a/atom/browser/api/lib/browser-window.coffee +++ b/atom/browser/api/lib/browser-window.coffee @@ -69,7 +69,8 @@ BrowserWindow.fromDevToolsWebContents = (webContents) -> return window for window in windows when window.devToolsWebContents?.equal webContents # Helpers. -BrowserWindow::loadUrl = -> @webContents.loadUrl.apply @webContents, arguments +BrowserWindow::loadURL = -> @webContents.loadURL.apply @webContents, arguments +BrowserWindow::getURL = -> @webContents.getURL() BrowserWindow::reload = -> @webContents.reload.apply @webContents, arguments BrowserWindow::send = -> @webContents.send.apply @webContents, arguments BrowserWindow::openDevTools = -> @webContents.openDevTools.apply @webContents, arguments @@ -80,14 +81,12 @@ BrowserWindow::inspectElement = -> @webContents.inspectElement.apply @webContent BrowserWindow::inspectServiceWorker = -> @webContents.inspectServiceWorker() # Deprecated. -deprecate.rename BrowserWindow, 'restart', 'reload' deprecate.member BrowserWindow, 'undo', 'webContents' deprecate.member BrowserWindow, 'redo', 'webContents' deprecate.member BrowserWindow, 'cut', 'webContents' deprecate.member BrowserWindow, 'copy', 'webContents' deprecate.member BrowserWindow, 'paste', 'webContents' deprecate.member BrowserWindow, 'selectAll', 'webContents' -deprecate.member BrowserWindow, 'getUrl', 'webContents' deprecate.member BrowserWindow, 'reloadIgnoringCache', 'webContents' deprecate.member BrowserWindow, 'getPageTitle', 'webContents' deprecate.member BrowserWindow, 'isLoading', 'webContents' @@ -97,5 +96,8 @@ deprecate.member BrowserWindow, 'isCrashed', 'webContents' deprecate.member BrowserWindow, 'executeJavaScriptInDevTools', 'webContents' deprecate.member BrowserWindow, 'print', 'webContents' deprecate.member BrowserWindow, 'printToPDF', 'webContents' +deprecate.rename BrowserWindow, 'restart', 'reload' +deprecate.rename BrowserWindow, 'loadUrl', 'loadURL' +deprecate.rename BrowserWindow, 'getUrl', 'getURL' module.exports = BrowserWindow diff --git a/atom/browser/api/lib/navigation-controller.coffee b/atom/browser/api/lib/navigation-controller.coffee index 88b1ed30ddd3..7d276e57e31a 100644 --- a/atom/browser/api/lib/navigation-controller.coffee +++ b/atom/browser/api/lib/navigation-controller.coffee @@ -9,7 +9,7 @@ ipcMain.on 'ATOM_SHELL_SYNC_NAVIGATION_CONTROLLER', (event, method, args...) -> # JavaScript implementation of Chromium's NavigationController. # Instead of relying on Chromium for history control, we compeletely do history -# control on user land, and only rely on WebContents.loadUrl for navigation. +# control on user land, and only rely on WebContents.loadURL for navigation. # This helps us avoid Chromium's various optimizations so we can ensure renderer # process is restarted everytime. class NavigationController @@ -17,9 +17,9 @@ class NavigationController @clearHistory() # webContents may have already navigated to a page. - if @webContents._getUrl() + if @webContents._getURL() @currentIndex++ - @history.push @webContents._getUrl() + @history.push @webContents._getURL() @webContents.on 'navigation-entry-commited', (event, url, inPage, replaceEntry) => if @inPageIndex > -1 and not inPage @@ -42,12 +42,12 @@ class NavigationController @currentIndex++ @history.push url - loadUrl: (url, options={}) -> + loadURL: (url, options={}) -> @pendingIndex = -1 - @webContents._loadUrl url, options + @webContents._loadURL url, options @webContents.emit 'load-url', url, options - getUrl: -> + getURL: -> if @currentIndex is -1 '' else @@ -59,7 +59,7 @@ class NavigationController reload: -> @pendingIndex = @currentIndex - @webContents._loadUrl @getUrl(), {} + @webContents._loadURL @getURL(), {} reloadIgnoringCache: -> @webContents._reloadIgnoringCache() # Rely on WebContents to clear cache. @@ -89,7 +89,7 @@ class NavigationController if @inPageIndex > -1 and @pendingIndex >= @inPageIndex @webContents._goBack() else - @webContents._loadUrl @history[@pendingIndex], {} + @webContents._loadURL @history[@pendingIndex], {} goForward: -> return unless @canGoForward() @@ -97,12 +97,12 @@ class NavigationController if @inPageIndex > -1 and @pendingIndex >= @inPageIndex @webContents._goForward() else - @webContents._loadUrl @history[@pendingIndex], {} + @webContents._loadURL @history[@pendingIndex], {} goToIndex: (index) -> return unless @canGoToIndex index @pendingIndex = index - @webContents._loadUrl @history[@pendingIndex], {} + @webContents._loadURL @history[@pendingIndex], {} goToOffset: (offset) -> return unless @canGoToOffset offset diff --git a/atom/browser/api/lib/web-contents.coffee b/atom/browser/api/lib/web-contents.coffee index b3b1e7ed9fa4..1a224c7416f5 100644 --- a/atom/browser/api/lib/web-contents.coffee +++ b/atom/browser/api/lib/web-contents.coffee @@ -1,5 +1,5 @@ {EventEmitter} = require 'events' -{ipcMain, NavigationController, Menu} = require 'electron' +{deprecate, ipcMain, NavigationController, Menu} = require 'electron' binding = process.atomBinding 'web_contents' @@ -45,7 +45,7 @@ wrapWebContents = (webContents) -> # Make sure webContents.executeJavaScript would run the code only when the # web contents has been loaded. webContents.executeJavaScript = (code, hasUserGesture=false) -> - if @getUrl() and not @isLoading() + if @getURL() and not @isLoading() @_executeJavaScript code, hasUserGesture else webContents.once 'did-finish-load', @_executeJavaScript.bind(this, code, hasUserGesture) @@ -70,6 +70,10 @@ wrapWebContents = (webContents) -> menu = Menu.buildFromTemplate params.menu menu.popup params.x, params.y + # Deprecated. + deprecate.rename webContents, 'loadUrl', 'loadURL' + deprecate.rename webContents, 'getUrl', 'getURL' + webContents.printToPDF = (options, callback) -> printingSetting = pageRage: [] diff --git a/atom/browser/atom_access_token_store.cc b/atom/browser/atom_access_token_store.cc index 3d254f060188..adf2f5061cb0 100644 --- a/atom/browser/atom_access_token_store.cc +++ b/atom/browser/atom_access_token_store.cc @@ -18,7 +18,7 @@ namespace { // Notice that we just combined the api key with the url together here, because // if we use the standard {url: key} format Chromium would override our key with // the predefined one in common.gypi of libchromiumcontent, which is empty. -const char* kGeolocationProviderUrl = +const char* kGeolocationProviderURL = "https://www.googleapis.com/geolocation/v1/geolocate?key=" GOOGLEAPIS_API_KEY; @@ -35,11 +35,11 @@ void AtomAccessTokenStore::LoadAccessTokens( const LoadAccessTokensCallbackType& callback) { AccessTokenSet access_token_set; - // Equivelent to access_token_set[kGeolocationProviderUrl]. + // Equivelent to access_token_set[kGeolocationProviderURL]. // Somehow base::string16 is causing compilation errors when used in a pair // of std::map on Linux, this can work around it. std::pair token_pair; - token_pair.first = GURL(kGeolocationProviderUrl); + token_pair.first = GURL(kGeolocationProviderURL); access_token_set.insert(token_pair); auto browser_context = AtomBrowserMainParts::Get()->browser_context(); diff --git a/atom/browser/default_app/default_app.js b/atom/browser/default_app/default_app.js index 6a94db4836f8..2ec765d0d691 100644 --- a/atom/browser/default_app/default_app.js +++ b/atom/browser/default_app/default_app.js @@ -16,6 +16,6 @@ app.on('ready', function() { autoHideMenuBar: true, useContentSize: true, }); - mainWindow.loadUrl('file://' + __dirname + '/index.html'); + mainWindow.loadURL('file://' + __dirname + '/index.html'); mainWindow.focus(); }); diff --git a/atom/browser/lib/guest-view-manager.coffee b/atom/browser/lib/guest-view-manager.coffee index 4a33b281c9dc..e6be05a907bf 100644 --- a/atom/browser/lib/guest-view-manager.coffee +++ b/atom/browser/lib/guest-view-manager.coffee @@ -79,7 +79,7 @@ createGuest = (embedder, params) -> opts = {} opts.httpReferrer = params.httpreferrer if params.httpreferrer opts.userAgent = params.useragent if params.useragent - @loadUrl params.src, opts + @loadURL params.src, opts if params.allowtransparency? @setAllowTransparency params.allowtransparency @@ -122,7 +122,7 @@ attachGuest = (embedder, elementInstanceId, guestInstanceId, params) -> nodeIntegration: params.nodeintegration ? false plugins: params.plugins webSecurity: !params.disablewebsecurity - webPreferences.preloadUrl = params.preload if params.preload + webPreferences.preloadURL = params.preload if params.preload webViewManager.addGuest guestInstanceId, elementInstanceId, embedder, guest, webPreferences guest.attachParams = params diff --git a/atom/browser/lib/guest-window-manager.coffee b/atom/browser/lib/guest-window-manager.coffee index c602d370bac0..c311e01cf487 100644 --- a/atom/browser/lib/guest-window-manager.coffee +++ b/atom/browser/lib/guest-window-manager.coffee @@ -27,11 +27,11 @@ mergeBrowserWindowOptions = (embedder, options) -> createGuest = (embedder, url, frameName, options) -> guest = frameToGuest[frameName] if frameName and guest? - guest.loadUrl url + guest.loadURL url return guest.id guest = new BrowserWindow(options) - guest.loadUrl url + guest.loadURL url # Remember the embedder, will be used by window.opener methods. v8Util.setHiddenValue guest.webContents, 'embedder', embedder @@ -74,12 +74,12 @@ ipcMain.on 'ATOM_SHELL_GUEST_WINDOW_MANAGER_WINDOW_METHOD', (event, guestId, met ipcMain.on 'ATOM_SHELL_GUEST_WINDOW_MANAGER_WINDOW_POSTMESSAGE', (event, guestId, message, targetOrigin) -> guestContents = BrowserWindow.fromId(guestId)?.webContents - if guestContents?.getUrl().indexOf(targetOrigin) is 0 or targetOrigin is '*' + if guestContents?.getURL().indexOf(targetOrigin) is 0 or targetOrigin is '*' guestContents.send 'ATOM_SHELL_GUEST_WINDOW_POSTMESSAGE', guestId, message, targetOrigin ipcMain.on 'ATOM_SHELL_GUEST_WINDOW_MANAGER_WINDOW_OPENER_POSTMESSAGE', (event, guestId, message, targetOrigin, sourceOrigin) -> embedder = v8Util.getHiddenValue event.sender, 'embedder' - if embedder?.getUrl().indexOf(targetOrigin) is 0 or targetOrigin is '*' + if embedder?.getURL().indexOf(targetOrigin) is 0 or targetOrigin is '*' embedder.send 'ATOM_SHELL_GUEST_WINDOW_POSTMESSAGE', guestId, message, sourceOrigin ipcMain.on 'ATOM_SHELL_GUEST_WINDOW_MANAGER_WEB_CONTENTS_METHOD', (event, guestId, method, args...) -> diff --git a/atom/browser/net/url_request_async_asar_job.cc b/atom/browser/net/url_request_async_asar_job.cc index ba0189e5f6e0..303bfc0170d9 100644 --- a/atom/browser/net/url_request_async_asar_job.cc +++ b/atom/browser/net/url_request_async_asar_job.cc @@ -6,13 +6,13 @@ namespace atom { -UrlRequestAsyncAsarJob::UrlRequestAsyncAsarJob( +URLRequestAsyncAsarJob::URLRequestAsyncAsarJob( net::URLRequest* request, net::NetworkDelegate* network_delegate) : JsAsker(request, network_delegate) { } -void UrlRequestAsyncAsarJob::StartAsync(scoped_ptr options) { +void URLRequestAsyncAsarJob::StartAsync(scoped_ptr options) { base::FilePath::StringType file_path; if (options->IsType(base::Value::TYPE_DICTIONARY)) { static_cast(options.get())->GetString( diff --git a/atom/browser/net/url_request_async_asar_job.h b/atom/browser/net/url_request_async_asar_job.h index 748b96d84d28..df1aed350b8b 100644 --- a/atom/browser/net/url_request_async_asar_job.h +++ b/atom/browser/net/url_request_async_asar_job.h @@ -11,15 +11,15 @@ namespace atom { // Like URLRequestAsarJob, but asks the JavaScript handler for file path. -class UrlRequestAsyncAsarJob : public JsAsker { +class URLRequestAsyncAsarJob : public JsAsker { public: - UrlRequestAsyncAsarJob(net::URLRequest*, net::NetworkDelegate*); + URLRequestAsyncAsarJob(net::URLRequest*, net::NetworkDelegate*); // JsAsker: void StartAsync(scoped_ptr options) override; private: - DISALLOW_COPY_AND_ASSIGN(UrlRequestAsyncAsarJob); + DISALLOW_COPY_AND_ASSIGN(URLRequestAsyncAsarJob); }; } // namespace atom diff --git a/atom/browser/web_contents_preferences.cc b/atom/browser/web_contents_preferences.cc index 188de4d1bfe7..83145368c5fe 100644 --- a/atom/browser/web_contents_preferences.cc +++ b/atom/browser/web_contents_preferences.cc @@ -113,7 +113,7 @@ void WebContentsPreferences::AppendExtraCommandLineSwitches( command_line->AppendSwitchNative(switches::kPreloadScript, preload); else LOG(ERROR) << "preload script must have absolute path."; - } else if (web_preferences.GetString(options::kPreloadUrl, &preload)) { + } else if (web_preferences.GetString(options::kPreloadURL, &preload)) { // Translate to file path if there is "preload-url" option. base::FilePath preload_path; if (net::FileURLToFilePath(GURL(preload), &preload_path)) diff --git a/atom/common/api/atom_api_native_image.cc b/atom/common/api/atom_api_native_image.cc index df6c14dab350..e0f0940a7420 100644 --- a/atom/common/api/atom_api_native_image.cc +++ b/atom/common/api/atom_api_native_image.cc @@ -168,7 +168,8 @@ mate::ObjectTemplateBuilder NativeImage::GetObjectTemplateBuilder( template_.Reset(isolate, mate::ObjectTemplateBuilder(isolate) .SetMethod("toPng", &NativeImage::ToPNG) .SetMethod("toJpeg", &NativeImage::ToJPEG) - .SetMethod("toDataUrl", &NativeImage::ToDataURL) + .SetMethod("toDataURL", &NativeImage::ToDataURL) + .SetMethod("toDataUrl", &NativeImage::ToDataURL) // deprecated. .SetMethod("isEmpty", &NativeImage::IsEmpty) .SetMethod("getSize", &NativeImage::GetSize) .SetMethod("setTemplateImage", &NativeImage::SetTemplateImage) @@ -309,7 +310,7 @@ void Initialize(v8::Local exports, v8::Local unused, dict.SetMethod("createEmpty", &atom::api::NativeImage::CreateEmpty); dict.SetMethod("createFromPath", &atom::api::NativeImage::CreateFromPath); dict.SetMethod("createFromBuffer", &atom::api::NativeImage::CreateFromBuffer); - dict.SetMethod("createFromDataUrl", + dict.SetMethod("createFromDataURL", &atom::api::NativeImage::CreateFromDataURL); } diff --git a/atom/common/api/lib/crash-reporter.coffee b/atom/common/api/lib/crash-reporter.coffee index 873fc1848c59..0713da99daef 100644 --- a/atom/common/api/lib/crash-reporter.coffee +++ b/atom/common/api/lib/crash-reporter.coffee @@ -1,14 +1,21 @@ -binding = process.atomBinding 'crash_reporter' fs = require 'fs' os = require 'os' path = require 'path' {spawn} = require 'child_process' +electron = require 'electron' +binding = process.atomBinding 'crash_reporter' + class CrashReporter start: (options={}) -> - {@productName, companyName, submitUrl, autoSubmit, ignoreSystemCrashHandler, extra} = options + {@productName, companyName, submitURL, autoSubmit, ignoreSystemCrashHandler, extra} = options + + # Deprecated. + {deprecate} = electron + if options.submitUrl + submitURL ?= options.submitUrl + deprecate.warn 'submitUrl', 'submitURL' - electron = require 'electron' {app} = if process.type is 'browser' electron @@ -17,7 +24,7 @@ class CrashReporter @productName ?= app.getName() companyName ?= 'GitHub, Inc' - submitUrl ?= 'http://54.249.141.255:1127/post' + submitURL ?= 'http://54.249.141.255:1127/post' autoSubmit ?= true ignoreSystemCrashHandler ?= false extra ?= {} @@ -26,11 +33,11 @@ class CrashReporter extra._companyName ?= companyName extra._version ?= app.getVersion() - start = => binding.start @productName, companyName, submitUrl, autoSubmit, ignoreSystemCrashHandler, extra + start = => binding.start @productName, companyName, submitURL, autoSubmit, ignoreSystemCrashHandler, extra if process.platform is 'win32' args = [ - "--reporter-url=#{submitUrl}" + "--reporter-url=#{submitURL}" "--application-name=#{@productName}" "--v=1" ] diff --git a/atom/common/api/lib/native-image.coffee b/atom/common/api/lib/native-image.coffee index c3cbb60ef030..2bdfd494f44b 100644 --- a/atom/common/api/lib/native-image.coffee +++ b/atom/common/api/lib/native-image.coffee @@ -1 +1,7 @@ -module.exports = process.atomBinding 'native_image' +{deprecate} = require 'electron' +nativeImage = process.atomBinding 'native_image' + +# Deprecated. +deprecate.rename nativeImage, 'createFromDataUrl', 'createFromDataURL' + +module.exports = nativeImage diff --git a/atom/common/options_switches.cc b/atom/common/options_switches.cc index 1d375ba0fc4e..1124cfba4bac 100644 --- a/atom/common/options_switches.cc +++ b/atom/common/options_switches.cc @@ -77,7 +77,7 @@ const char kZoomFactor[] = "zoomFactor"; const char kPreloadScript[] = "preload"; // Like --preload, but the passed argument is an URL. -const char kPreloadUrl[] = "preloadUrl"; +const char kPreloadURL[] = "preloadURL"; // Enable the node integration. const char kNodeIntegration[] = "nodeIntegration"; @@ -133,7 +133,7 @@ const char kAppUserModelId[] = "app-user-model-id"; // The command line switch versions of the options. const char kZoomFactor[] = "zoom-factor"; const char kPreloadScript[] = "preload"; -const char kPreloadUrl[] = "preload-url"; +const char kPreloadURL[] = "preload-url"; const char kNodeIntegration[] = "node-integration"; const char kGuestInstanceID[] = "guest-instance-id"; const char kExperimentalFeatures[] = "experimental-features"; diff --git a/atom/common/options_switches.h b/atom/common/options_switches.h index 7f262fb0f721..cd52c97597c9 100644 --- a/atom/common/options_switches.h +++ b/atom/common/options_switches.h @@ -44,7 +44,7 @@ extern const char kWebPreferences[]; extern const char kDirectWrite[]; extern const char kZoomFactor[]; extern const char kPreloadScript[]; -extern const char kPreloadUrl[]; +extern const char kPreloadURL[]; extern const char kNodeIntegration[]; extern const char kGuestInstanceID[]; extern const char kExperimentalFeatures[]; @@ -73,7 +73,7 @@ extern const char kAppUserModelId[]; extern const char kZoomFactor[]; extern const char kPreloadScript[]; -extern const char kPreloadUrl[]; +extern const char kPreloadURL[]; extern const char kNodeIntegration[]; extern const char kGuestInstanceID[]; extern const char kExperimentalFeatures[]; diff --git a/atom/common/platform_util_win.cc b/atom/common/platform_util_win.cc index 87f45e5cb2d4..cca392952e65 100644 --- a/atom/common/platform_util_win.cc +++ b/atom/common/platform_util_win.cc @@ -307,8 +307,8 @@ bool OpenExternal(const GURL& url) { // "Some versions of windows (Win2k before SP3, Win XP before SP1) crash in // ShellExecute on long URLs (bug 161357 on bugzilla.mozilla.org). IE 5 and 6 // support URLS of 2083 chars in length, 2K is safe." - const size_t kMaxUrlLength = 2048; - if (escaped_url.length() > kMaxUrlLength) { + const size_t kMaxURLLength = 2048; + if (escaped_url.length() > kMaxURLLength) { NOTREACHED(); return false; } diff --git a/atom/renderer/api/atom_api_web_frame.cc b/atom/renderer/api/atom_api_web_frame.cc index 69613043043d..e9b2b03055e6 100644 --- a/atom/renderer/api/atom_api_web_frame.cc +++ b/atom/renderer/api/atom_api_web_frame.cc @@ -98,7 +98,7 @@ void WebFrame::RegisterURLSchemeAsSecure(const std::string& scheme) { blink::WebString::fromUTF8(scheme)); } -void WebFrame::RegisterURLSchemeAsBypassingCsp(const std::string& scheme) { +void WebFrame::RegisterURLSchemeAsBypassingCSP(const std::string& scheme) { // Register scheme to bypass pages's Content Security Policy. blink::WebSecurityPolicy::registerURLSchemeAsBypassingContentSecurityPolicy( blink::WebString::fromUTF8(scheme)); @@ -129,11 +129,11 @@ mate::ObjectTemplateBuilder WebFrame::GetObjectTemplateBuilder( &WebFrame::RegisterElementResizeCallback) .SetMethod("attachGuest", &WebFrame::AttachGuest) .SetMethod("setSpellCheckProvider", &WebFrame::SetSpellCheckProvider) - .SetMethod("registerUrlSchemeAsSecure", + .SetMethod("registerURLSchemeAsSecure", &WebFrame::RegisterURLSchemeAsSecure) - .SetMethod("registerUrlSchemeAsBypassingCsp", - &WebFrame::RegisterURLSchemeAsBypassingCsp) - .SetMethod("registerUrlSchemeAsPrivileged", + .SetMethod("registerURLSchemeAsBypassingCSP", + &WebFrame::RegisterURLSchemeAsBypassingCSP) + .SetMethod("registerURLSchemeAsPrivileged", &WebFrame::RegisterURLSchemeAsPrivileged); } diff --git a/atom/renderer/api/atom_api_web_frame.h b/atom/renderer/api/atom_api_web_frame.h index a3dec6cb7689..95a5a82a313d 100644 --- a/atom/renderer/api/atom_api_web_frame.h +++ b/atom/renderer/api/atom_api_web_frame.h @@ -57,7 +57,7 @@ class WebFrame : public mate::Wrappable { v8::Local provider); void RegisterURLSchemeAsSecure(const std::string& scheme); - void RegisterURLSchemeAsBypassingCsp(const std::string& scheme); + void RegisterURLSchemeAsBypassingCSP(const std::string& scheme); void RegisterURLSchemeAsPrivileged(const std::string& scheme); // mate::Wrappable: diff --git a/atom/renderer/api/lib/web-frame.coffee b/atom/renderer/api/lib/web-frame.coffee index 6525730e86f1..53564c615ca4 100644 --- a/atom/renderer/api/lib/web-frame.coffee +++ b/atom/renderer/api/lib/web-frame.coffee @@ -1 +1,9 @@ -module.exports = process.atomBinding('web_frame').webFrame +{deprecate} = require 'electron' +{webFrame} = process.atomBinding 'web_frame' + +# Deprecated. +deprecate.rename webFrame, 'registerUrlSchemeAsSecure', 'registerURLSchemeAsSecure' +deprecate.rename webFrame, 'registerUrlSchemeAsBypassingCSP', 'registerURLSchemeAsBypassingCSP' +deprecate.rename webFrame, 'registerUrlSchemeAsPrivileged', 'registerURLSchemeAsPrivileged' + +module.exports = webFrame diff --git a/atom/renderer/lib/override.coffee b/atom/renderer/lib/override.coffee index d12952a1b831..a3a2f9ac62da 100644 --- a/atom/renderer/lib/override.coffee +++ b/atom/renderer/lib/override.coffee @@ -2,7 +2,7 @@ # Helper function to resolve relative url. a = window.top.document.createElement 'a' -resolveUrl = (url) -> +resolveURL = (url) -> a.href = url a.href @@ -55,7 +55,7 @@ window.open = (url, frameName='', features='') -> options.height ?= 600 # Resolve relative urls. - url = resolveUrl url + url = resolveURL url (options[name] = parseInt(options[name], 10) if options[name]?) for name in ints diff --git a/atom/renderer/lib/web-view/guest-view-internal.coffee b/atom/renderer/lib/web-view/guest-view-internal.coffee index a01a994b5bf9..61a93d8cb6e3 100644 --- a/atom/renderer/lib/web-view/guest-view-internal.coffee +++ b/atom/renderer/lib/web-view/guest-view-internal.coffee @@ -5,14 +5,14 @@ requestId = 0 WEB_VIEW_EVENTS = 'load-commit': ['url', 'isMainFrame'] 'did-finish-load': [] - 'did-fail-load': ['errorCode', 'errorDescription', 'validatedUrl'] + 'did-fail-load': ['errorCode', 'errorDescription', 'validatedURL'] 'did-frame-finish-load': ['isMainFrame'] 'did-start-loading': [] 'did-stop-loading': [] - 'did-get-response-details': ['status', 'newUrl', 'originalUrl', + 'did-get-response-details': ['status', 'newURL', 'originalURL', 'httpResponseCode', 'requestMethod', 'referrer', 'headers'] - 'did-get-redirect-request': ['oldUrl', 'newUrl', 'isMainFrame'] + 'did-get-redirect-request': ['oldURL', 'newURL', 'isMainFrame'] 'dom-ready': [] 'console-message': ['level', 'message', 'line', 'sourceId'] 'new-window': ['url', 'frameName', 'disposition', 'options'] diff --git a/atom/renderer/lib/web-view/web-view-attributes.coffee b/atom/renderer/lib/web-view/web-view-attributes.coffee index 48e57ea95aaf..7760b400ce17 100644 --- a/atom/renderer/lib/web-view/web-view-attributes.coffee +++ b/atom/renderer/lib/web-view/web-view-attributes.coffee @@ -6,7 +6,7 @@ webViewConstants = require './web-view-constants' # Helper function to resolve url set in attribute. a = document.createElement 'a' -resolveUrl = (url) -> +resolveURL = (url) -> a.href = url a.href @@ -116,7 +116,7 @@ class SrcAttribute extends WebViewAttribute getValue: -> if @webViewImpl.webviewNode.hasAttribute @name - resolveUrl @webViewImpl.webviewNode.getAttribute(@name) + resolveURL @webViewImpl.webviewNode.getAttribute(@name) else '' @@ -178,7 +178,7 @@ class SrcAttribute extends WebViewAttribute if useragent then opts.userAgent = useragent guestContents = remote.getGuestWebContents(@webViewImpl.guestInstanceId) - guestContents.loadUrl @getValue(), opts + guestContents.loadURL @getValue(), opts # Attribute specifies HTTP referrer. class HttpReferrerAttribute extends WebViewAttribute @@ -197,7 +197,7 @@ class PreloadAttribute extends WebViewAttribute getValue: -> return '' unless @webViewImpl.webviewNode.hasAttribute @name - preload = resolveUrl @webViewImpl.webviewNode.getAttribute(@name) + preload = resolveURL @webViewImpl.webviewNode.getAttribute(@name) protocol = preload.substr 0, 5 unless protocol is 'file:' console.error webViewConstants.ERROR_MSG_INVALID_PRELOAD_ATTRIBUTE diff --git a/atom/renderer/lib/web-view/web-view.coffee b/atom/renderer/lib/web-view/web-view.coffee index 204889de79e9..5e3f7d6bae56 100644 --- a/atom/renderer/lib/web-view/web-view.coffee +++ b/atom/renderer/lib/web-view/web-view.coffee @@ -1,4 +1,4 @@ -{webFrame, remote} = require 'electron' +{deprecate, webFrame, remote} = require 'electron' v8Util = process.atomBinding 'v8_util' guestViewInternal = require './guest-view-internal' @@ -252,49 +252,49 @@ registerWebViewElement = -> # Public-facing API methods. methods = [ - "getUrl" - "getTitle" - "isLoading" - "isWaitingForResponse" - "stop" - "reload" - "reloadIgnoringCache" - "canGoBack" - "canGoForward" - "canGoToOffset" - "clearHistory" - "goBack" - "goForward" - "goToIndex" - "goToOffset" - "isCrashed" - "setUserAgent" - "getUserAgent" - "executeJavaScript" - "insertCSS" - "openDevTools" - "closeDevTools" - "isDevToolsOpened" - "inspectElement" - "setAudioMuted" - "isAudioMuted" - "undo" - "redo" - "cut" - "copy" - "paste" - "pasteAndMatchStyle" - "delete" - "selectAll" - "unselect" - "replace" - "replaceMisspelling" - "send" - "getId" - "inspectServiceWorker" - "print" - "printToPDF" - "sendInputEvent" + 'getURL' + 'getTitle' + 'isLoading' + 'isWaitingForResponse' + 'stop' + 'reload' + 'reloadIgnoringCache' + 'canGoBack' + 'canGoForward' + 'canGoToOffset' + 'clearHistory' + 'goBack' + 'goForward' + 'goToIndex' + 'goToOffset' + 'isCrashed' + 'setUserAgent' + 'getUserAgent' + 'executeJavaScript' + 'insertCSS' + 'openDevTools' + 'closeDevTools' + 'isDevToolsOpened' + 'inspectElement' + 'setAudioMuted' + 'isAudioMuted' + 'undo' + 'redo' + 'cut' + 'copy' + 'paste' + 'pasteAndMatchStyle' + 'delete' + 'selectAll' + 'unselect' + 'replace' + 'replaceMisspelling' + 'send' + 'getId' + 'inspectServiceWorker' + 'print' + 'printToPDF' + 'sendInputEvent' ] # Forward proto.foo* method calls to WebViewImpl.foo*. @@ -304,6 +304,9 @@ registerWebViewElement = -> internal.webContents[m] args... proto[m] = createHandler m for m in methods + # Deprecated. + deprecate.rename proto, 'getUrl', 'getURL' + window.WebView = webFrame.registerEmbedderCustomElement 'webview', prototype: proto diff --git a/docs/api/auto-updater.md b/docs/api/auto-updater.md index eb0ea3752995..fa4f92cb936d 100644 --- a/docs/api/auto-updater.md +++ b/docs/api/auto-updater.md @@ -67,7 +67,7 @@ Returns: * `releaseNotes` String * `releaseName` String * `releaseDate` Date -* `updateUrl` String +* `updateURL` String Emitted when an update has been downloaded. @@ -77,7 +77,7 @@ On Windows only `releaseName` is available. The `autoUpdater` object has the following methods: -### `autoUpdater.setFeedUrl(url)` +### `autoUpdater.setFeedURL(url)` * `url` String @@ -86,7 +86,7 @@ once it is set. ### `autoUpdater.checkForUpdates()` -Asks the server whether there is an update. You must call `setFeedUrl` before +Asks the server whether there is an update. You must call `setFeedURL` before using this API. ### `autoUpdater.quitAndInstall()` diff --git a/docs/api/browser-window.md b/docs/api/browser-window.md index 670c814c741d..3b293e99621c 100644 --- a/docs/api/browser-window.md +++ b/docs/api/browser-window.md @@ -11,7 +11,7 @@ win.on('closed', function() { win = null; }); -win.loadUrl('https://github.com'); +win.loadURL('https://github.com'); win.show(); ``` @@ -613,9 +613,9 @@ Same as `webContents.print([options])` Same as `webContents.printToPDF(options, callback)` -### `win.loadUrl(url[, options])` +### `win.loadURL(url[, options])` -Same as `webContents.loadUrl(url[, options])`. +Same as `webContents.loadURL(url[, options])`. ### `win.reload()` diff --git a/docs/api/crash-reporter.md b/docs/api/crash-reporter.md index 8127c9bc1c93..6c66a855f753 100644 --- a/docs/api/crash-reporter.md +++ b/docs/api/crash-reporter.md @@ -11,7 +11,7 @@ const crashReporter = require('electron').crashReporter; crashReporter.start({ productName: 'YourName', companyName: 'YourCompany', - submitUrl: 'https://your-domain.com/url-to-submit', + submitURL: 'https://your-domain.com/url-to-submit', autoSubmit: true }); ``` @@ -26,7 +26,7 @@ The `crash-reporter` module has the following methods: * `productName` String, default: Electron. * `companyName` String, default: GitHub, Inc. -* `submitUrl` String, default: http://54.249.141.255:1127/post. +* `submitURL` String, default: http://54.249.141.255:1127/post. * URL that crash reports will be sent to as POST. * `autoSubmit` Boolean, default: `true`. * Send the crash report without user interaction. @@ -57,7 +57,7 @@ ID. ## crash-reporter Payload -The crash reporter will send the following data to the `submitUrl` as `POST`: +The crash reporter will send the following data to the `submitURL` as `POST`: * `ver` String - The version of Electron. * `platform` String - e.g. 'win32'. diff --git a/docs/api/download-item.md b/docs/api/download-item.md index 53cd56cca9e5..756353b8ba3d 100644 --- a/docs/api/download-item.md +++ b/docs/api/download-item.md @@ -66,7 +66,7 @@ Resumes the download that has been paused. Cancels the download operation. -### `downloadItem.getUrl()` +### `downloadItem.getURL()` Returns a `String` represents the origin url where the item is downloaded from. diff --git a/docs/api/native-image.md b/docs/api/native-image.md index 74dc7a68fad9..c08788965a74 100644 --- a/docs/api/native-image.md +++ b/docs/api/native-image.md @@ -103,11 +103,11 @@ Creates a new `nativeImage` instance from a file located at `path`. Creates a new `nativeImage` instance from `buffer`. The default `scaleFactor` is 1.0. -### `nativeImage.createFromDataUrl(dataUrl)` +### `nativeImage.createFromDataURL(dataURL)` -* `dataUrl` String +* `dataURL` String -Creates a new `nativeImage` instance from `dataUrl`. +Creates a new `nativeImage` instance from `dataURL`. ## Instance Methods @@ -129,7 +129,7 @@ Returns a [Buffer][buffer] that contains the image's `PNG` encoded data. Returns a [Buffer][buffer] that contains the image's `JPEG` encoded data. -### `image.toDataUrl()` +### `image.toDataURL()` Returns the data URL of the image. diff --git a/docs/api/remote.md b/docs/api/remote.md index 6eaa206465aa..d6aca3ec2617 100644 --- a/docs/api/remote.md +++ b/docs/api/remote.md @@ -16,7 +16,7 @@ const remote = require('electron').remote; const BrowserWindow = remote.require('electron').BrowserWindow; var win = new BrowserWindow({ width: 800, height: 600 }); -win.loadUrl('https://github.com'); +win.loadURL('https://github.com'); ``` **Note:** for the reverse (access the renderer process from the main process), diff --git a/docs/api/session.md b/docs/api/session.md index 0fa72585b94e..c3a3c91eea93 100644 --- a/docs/api/session.md +++ b/docs/api/session.md @@ -8,7 +8,7 @@ instance of `BrowserWindow`. For example: const BrowserWindow = require('electron').BrowserWindow; var win = new BrowserWindow({ width: 800, height: 600 }); -win.loadUrl("http://github.com"); +win.loadURL("http://github.com"); var session = win.webContents.session ``` @@ -28,7 +28,7 @@ Calling `event.preventDefault()` will cancel the download. ```javascript session.on('will-download', function(event, item, webContents) { event.preventDefault(); - require('request')(item.getUrl(), function(data) { + require('request')(item.getURL(), function(data) { require('fs').writeFileSync('/somewhere', data); }); }); @@ -47,7 +47,7 @@ const BrowserWindow = require('electron').BrowserWindow; var win = new BrowserWindow({ width: 800, height: 600 }); -win.loadUrl('https://github.com'); +win.loadURL('https://github.com'); win.webContents.on('did-finish-load', function() { // Query all cookies. diff --git a/docs/api/synopsis.md b/docs/api/synopsis.md index f6c161b6963a..4cacf52cabd7 100644 --- a/docs/api/synopsis.md +++ b/docs/api/synopsis.md @@ -25,7 +25,7 @@ var window = null; app.on('ready', function() { window = new BrowserWindow({width: 800, height: 600}); - window.loadUrl('https://github.com'); + window.loadURL('https://github.com'); }); ``` diff --git a/docs/api/web-contents.md b/docs/api/web-contents.md index aff5752ab55f..917e0670590c 100644 --- a/docs/api/web-contents.md +++ b/docs/api/web-contents.md @@ -11,7 +11,7 @@ the [`BrowserWindow`](browser-window.md) object. An example of accessing the const BrowserWindow = require('electron').BrowserWindow; var win = new BrowserWindow({width: 800, height: 1500}); -win.loadUrl("http://github.com"); +win.loadURL("http://github.com"); var webContents = win.webContents; ``` @@ -32,7 +32,7 @@ Returns: * `event` Event * `errorCode` Integer * `errorDescription` String -* `validatedUrl` String +* `validatedURL` String This event is like `did-finish-load` but emitted when the load failed or was cancelled, e.g. `window.stop()` is invoked. @@ -61,8 +61,8 @@ Returns: * `event` Event * `status` Boolean -* `newUrl` String -* `originalUrl` String +* `newURL` String +* `originalURL` String * `httpResponseCode` Integer * `requestMethod` String * `referrer` String @@ -76,8 +76,8 @@ Emitted when details regarding a requested resource are available. Returns: * `event` Event -* `oldUrl` String -* `newUrl` String +* `oldURL` String +* `newURL` String * `isMainFrame` Boolean * `httpResponseCode` Integer * `requestMethod` String @@ -99,7 +99,7 @@ Emitted when the document in the given frame is loaded. Returns: * `event` Event -* `favicons` Array - Array of Urls +* `favicons` Array - Array of URLs Emitted when page receives favicon urls. @@ -133,7 +133,7 @@ Emitted when a user or the page wants to start navigation. It can happen when th `window.location` object is changed or a user clicks a link in the page. This event will not emit when the navigation is started programmatically with -APIs like `webContents.loadUrl` and `webContents.back`. +APIs like `webContents.loadURL` and `webContents.back`. Calling `event.preventDefault()` will prevent the navigation. @@ -198,7 +198,7 @@ Returns the `session` object used by this webContents. See [session documentation](session.md) for this object's methods. -### `webContents.loadUrl(url[, options])` +### `webContents.loadURL(url[, options])` * `url` URL * `options` Object (optional), properties: @@ -209,15 +209,15 @@ See [session documentation](session.md) for this object's methods. Loads the `url` in the window, the `url` must contain the protocol prefix, e.g. the `http://` or `file://`. -### `webContents.getUrl()` +### `webContents.getURL()` Returns URL of the current web page. ```javascript var win = new BrowserWindow({width: 800, height: 600}); -win.loadUrl("http://github.com"); +win.loadURL("http://github.com"); -var currentUrl = win.webContents.getUrl(); +var currentURL = win.webContents.getURL(); ``` ### `webContents.getTitle()` @@ -447,7 +447,7 @@ const BrowserWindow = require('electron').BrowserWindow; const fs = require('fs'); var win = new BrowserWindow({width: 800, height: 600}); -win.loadUrl("http://github.com"); +win.loadURL("http://github.com"); win.webContents.on("did-finish-load", function() { // Use default printing options @@ -524,7 +524,7 @@ An example of sending messages from the main process to the renderer process: var window = null; app.on('ready', function() { window = new BrowserWindow({width: 800, height: 600}); - window.loadUrl('file://' + __dirname + '/index.html'); + window.loadURL('file://' + __dirname + '/index.html'); window.webContents.on('did-finish-load', function() { window.webContents.send('ping', 'whoooooooh!'); }); @@ -660,7 +660,7 @@ when the DevTools has been closed. Returns true if the process of saving page has been initiated successfully. ```javascript -win.loadUrl('https://github.com'); +win.loadURL('https://github.com'); win.webContents.on('did-finish-load', function() { win.webContents.savePage('/tmp/test.html', 'HTMLComplete', function(error) { diff --git a/docs/api/web-frame.md b/docs/api/web-frame.md index c9cfb48f3437..38c5e30db43f 100644 --- a/docs/api/web-frame.md +++ b/docs/api/web-frame.md @@ -66,7 +66,7 @@ webFrame.setSpellCheckProvider("en-US", true, { }); ``` -### `webFrame.registerUrlSchemeAsSecure(scheme)` +### `webFrame.registerURLSchemeAsSecure(scheme)` * `scheme` String @@ -76,14 +76,14 @@ Secure schemes do not trigger mixed content warnings. For example, `https` and `data` are secure schemes because they cannot be corrupted by active network attackers. -### `webFrame.registerUrlSchemeAsBypassingCsp(scheme)` +### `webFrame.registerURLSchemeAsBypassingCSP(scheme)` * `scheme` String Resources will be loaded from this `scheme` regardless of the current page's Content Security Policy. -### `webFrame.registerUrlSchemeAsPrivileged(scheme)` +### `webFrame.registerURLSchemeAsPrivileged(scheme)` * `scheme` String diff --git a/docs/api/web-view-tag.md b/docs/api/web-view-tag.md index a12ec447138f..25b0e399465d 100644 --- a/docs/api/web-view-tag.md +++ b/docs/api/web-view-tag.md @@ -170,7 +170,7 @@ webview.addEventListener("dom-ready", function() { }); ``` -### `.getUrl()` +### `.getURL()` Returns URL of guest page. @@ -402,7 +402,7 @@ Returns: * `errorCode` Integer * `errorDescription` String -* `validatedUrl` String +* `validatedURL` String This event is like `did-finish-load`, but fired when the load failed or was cancelled, e.g. `window.stop()` is invoked. @@ -428,8 +428,8 @@ Corresponds to the points in time when the spinner of the tab stops spinning. Returns: * `status` Boolean -* `newUrl` String -* `originalUrl` String +* `newURL` String +* `originalURL` String * `httpResponseCode` Integer * `requestMethod` String * `referrer` String @@ -442,8 +442,8 @@ Fired when details regarding a requested resource is available. Returns: -* `oldUrl` String -* `newUrl` String +* `oldURL` String +* `newURL` String * `isMainFrame` Boolean Fired when a redirect was received while requesting a resource. @@ -466,7 +466,7 @@ url. Returns: -* `favicons` Array - Array of Urls. +* `favicons` Array - Array of URLs. Fired when page receives favicon urls. diff --git a/docs/tutorial/application-packaging.md b/docs/tutorial/application-packaging.md index 7c1ea773e2ff..45973e49eaa9 100644 --- a/docs/tutorial/application-packaging.md +++ b/docs/tutorial/application-packaging.md @@ -73,7 +73,7 @@ You can also display a web page in an `asar` archive with `BrowserWindow`: ```javascript const BrowserWindow = require('electron').BrowserWindow; var win = new BrowserWindow({width: 800, height: 600}); -win.loadUrl('file:///path/to/example.asar/static/index.html'); +win.loadURL('file:///path/to/example.asar/static/index.html'); ``` ### Web API diff --git a/docs/tutorial/online-offline-events.md b/docs/tutorial/online-offline-events.md index 6e031282b55a..d143118e0158 100644 --- a/docs/tutorial/online-offline-events.md +++ b/docs/tutorial/online-offline-events.md @@ -13,7 +13,7 @@ const BrowserWindow = electron.BrowserWindow; var onlineStatusWindow; app.on('ready', function() { onlineStatusWindow = new BrowserWindow({ width: 0, height: 0, show: false }); - onlineStatusWindow.loadUrl('file://' + __dirname + '/online-status.html'); + onlineStatusWindow.loadURL('file://' + __dirname + '/online-status.html'); }); ``` @@ -54,7 +54,7 @@ const BrowserWindow = electron.BrowserWindow; var onlineStatusWindow; app.on('ready', function() { onlineStatusWindow = new BrowserWindow({ width: 0, height: 0, show: false }); - onlineStatusWindow.loadUrl('file://' + __dirname + '/online-status.html'); + onlineStatusWindow.loadURL('file://' + __dirname + '/online-status.html'); }); ipcMain.on('online-status-changed', function(event, status) { diff --git a/docs/tutorial/quick-start.md b/docs/tutorial/quick-start.md index 7c55340f75e2..4c61413436dd 100644 --- a/docs/tutorial/quick-start.md +++ b/docs/tutorial/quick-start.md @@ -105,7 +105,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.webContents.openDevTools(); diff --git a/docs/tutorial/using-pepper-flash-plugin.md b/docs/tutorial/using-pepper-flash-plugin.md index 4cbbb519f4c2..a9918b220ac0 100644 --- a/docs/tutorial/using-pepper-flash-plugin.md +++ b/docs/tutorial/using-pepper-flash-plugin.md @@ -36,7 +36,7 @@ app.on('ready', function() { 'plugins': true } }); - mainWindow.loadUrl('file://' + __dirname + '/index.html'); + mainWindow.loadURL('file://' + __dirname + '/index.html'); // Something else }); ``` diff --git a/spec/api-browser-window-spec.coffee b/spec/api-browser-window-spec.coffee index 055cd8ed3468..00437ae412ba 100644 --- a/spec/api-browser-window-spec.coffee +++ b/spec/api-browser-window-spec.coffee @@ -31,14 +31,14 @@ describe 'browser-window module', -> fs.unlinkSync(test) assert.equal String(content), 'unload' done() - w.loadUrl 'file://' + path.join(fixtures, 'api', 'unload.html') + w.loadURL 'file://' + path.join(fixtures, 'api', 'unload.html') it 'should emit beforeunload handler', (done) -> w.on 'onbeforeunload', -> done() w.webContents.on 'did-finish-load', -> w.close() - w.loadUrl 'file://' + path.join(fixtures, 'api', 'beforeunload-false.html') + w.loadURL 'file://' + path.join(fixtures, 'api', 'beforeunload-false.html') describe 'window.close()', -> it 'should emit unload handler', (done) -> @@ -48,23 +48,23 @@ describe 'browser-window module', -> fs.unlinkSync(test) assert.equal String(content), 'close' done() - w.loadUrl 'file://' + path.join(fixtures, 'api', 'close.html') + w.loadURL 'file://' + path.join(fixtures, 'api', 'close.html') it 'should emit beforeunload handler', (done) -> w.on 'onbeforeunload', -> done() - w.loadUrl 'file://' + path.join(fixtures, 'api', 'close-beforeunload-false.html') + w.loadURL 'file://' + path.join(fixtures, 'api', 'close-beforeunload-false.html') - describe 'BrowserWindow.loadUrl(url)', -> + describe 'BrowserWindow.loadURL(url)', -> it 'should emit did-start-loading event', (done) -> w.webContents.on 'did-start-loading', -> done() - w.loadUrl 'about:blank' + w.loadURL 'about:blank' it 'should emit did-fail-load event', (done) -> w.webContents.on 'did-fail-load', -> done() - w.loadUrl 'file://a.txt' + w.loadURL 'file://a.txt' describe 'BrowserWindow.show()', -> it 'should focus on window', -> @@ -214,7 +214,7 @@ describe 'browser-window module', -> show: false webPreferences: preload: preload - w.loadUrl 'file://' + path.join(fixtures, 'api', 'preload.html') + w.loadURL 'file://' + path.join(fixtures, 'api', 'preload.html') describe '"node-integration" option', -> it 'disables node integration when specified to false', (done) -> @@ -228,28 +228,28 @@ describe 'browser-window module', -> webPreferences: preload: preload nodeIntegration: false - w.loadUrl 'file://' + path.join(fixtures, 'api', 'blank.html') + w.loadURL 'file://' + path.join(fixtures, 'api', 'blank.html') describe 'beforeunload handler', -> it 'returning true would not prevent close', (done) -> w.on 'closed', -> done() - w.loadUrl 'file://' + path.join(fixtures, 'api', 'close-beforeunload-true.html') + w.loadURL 'file://' + path.join(fixtures, 'api', 'close-beforeunload-true.html') it 'returning non-empty string would not prevent close', (done) -> w.on 'closed', -> done() - w.loadUrl 'file://' + path.join(fixtures, 'api', 'close-beforeunload-string.html') + w.loadURL 'file://' + path.join(fixtures, 'api', 'close-beforeunload-string.html') it 'returning false would prevent close', (done) -> w.on 'onbeforeunload', -> done() - w.loadUrl 'file://' + path.join(fixtures, 'api', 'close-beforeunload-false.html') + w.loadURL 'file://' + path.join(fixtures, 'api', 'close-beforeunload-false.html') it 'returning empty string would prevent close', (done) -> w.on 'onbeforeunload', -> done() - w.loadUrl 'file://' + path.join(fixtures, 'api', 'close-beforeunload-empty-string.html') + w.loadURL 'file://' + path.join(fixtures, 'api', 'close-beforeunload-empty-string.html') describe 'new-window event', -> return if isCI and process.platform is 'darwin' @@ -259,7 +259,7 @@ describe 'browser-window module', -> assert.equal url, 'http://host/' assert.equal frameName, 'host' done() - w.loadUrl "file://#{fixtures}/pages/window-open.html" + w.loadURL "file://#{fixtures}/pages/window-open.html" it 'emits when link with target is called', (done) -> w.webContents.once 'new-window', (e, url, frameName) -> @@ -267,7 +267,7 @@ describe 'browser-window module', -> assert.equal url, 'http://host/' assert.equal frameName, 'target' done() - w.loadUrl "file://#{fixtures}/pages/target-name.html" + w.loadURL "file://#{fixtures}/pages/target-name.html" describe 'maximize event', -> return if isCI @@ -296,7 +296,7 @@ describe 'browser-window module', -> xdescribe 'beginFrameSubscription method', -> it 'subscribes frame updates', (done) -> - w.loadUrl "file://#{fixtures}/api/blank.html" + w.loadURL "file://#{fixtures}/api/blank.html" w.webContents.beginFrameSubscription (data) -> assert.notEqual data.length, 0 w.webContents.endFrameSubscription() @@ -321,4 +321,4 @@ describe 'browser-window module', -> fs.rmdirSync savePageDir done() - w.loadUrl "file://#{fixtures}/pages/save_page/index.html" + w.loadURL "file://#{fixtures}/pages/save_page/index.html" diff --git a/spec/api-clipboard-spec.coffee b/spec/api-clipboard-spec.coffee index b02eb855be09..19da3fc75f1b 100644 --- a/spec/api-clipboard-spec.coffee +++ b/spec/api-clipboard-spec.coffee @@ -11,7 +11,7 @@ describe 'clipboard module', -> p = path.join fixtures, 'assets', 'logo.png' i = nativeImage.createFromPath p clipboard.writeImage p - assert.equal clipboard.readImage().toDataUrl(), i.toDataUrl() + assert.equal clipboard.readImage().toDataURL(), i.toDataURL() describe 'clipboard.readText()', -> it 'returns unicode string correctly', -> @@ -49,4 +49,4 @@ describe 'clipboard module', -> clipboard.write {text: "test", html: 'Hi', image: p} assert.equal clipboard.readText(), text assert.equal clipboard.readHtml(), markup - assert.equal clipboard.readImage().toDataUrl(), i.toDataUrl() + assert.equal clipboard.readImage().toDataURL(), i.toDataURL() diff --git a/spec/api-crash-reporter-spec.coffee b/spec/api-crash-reporter-spec.coffee index 281a1a77ae48..676dbf9d6929 100644 --- a/spec/api-crash-reporter-spec.coffee +++ b/spec/api-crash-reporter-spec.coffee @@ -55,5 +55,5 @@ describe 'crash-reporter module', -> pathname: path.join fixtures, 'api', 'crash.html' search: "?port=#{port}" if process.platform is 'darwin' - crashReporter.start {'submitUrl': 'http://127.0.0.1:' + port} - w.loadUrl url + crashReporter.start {'submitURL': 'http://127.0.0.1:' + port} + w.loadURL url diff --git a/spec/api-ipc-spec.coffee b/spec/api-ipc-spec.coffee index 1e6ee8f8447f..a8d2a65cdef7 100644 --- a/spec/api-ipc-spec.coffee +++ b/spec/api-ipc-spec.coffee @@ -86,7 +86,7 @@ describe 'ipc module', -> event.returnValue = null w.destroy() done() - w.loadUrl 'file://' + path.join(fixtures, 'api', 'send-sync-message.html') + w.loadURL 'file://' + path.join(fixtures, 'api', 'send-sync-message.html') describe 'remote listeners', -> it 'can be added and removed correctly', -> diff --git a/spec/api-session-spec.coffee b/spec/api-session-spec.coffee index f544dff4c34e..bf91bdd6fc77 100644 --- a/spec/api-session-spec.coffee +++ b/spec/api-session-spec.coffee @@ -23,7 +23,7 @@ describe 'session module', -> server.listen 0, '127.0.0.1', -> {port} = server.address() - w.loadUrl "#{url}:#{port}" + w.loadURL "#{url}:#{port}" w.webContents.on 'did-finish-load', -> w.webContents.session.cookies.get {url: url}, (error, list) -> return done(error) if error @@ -64,7 +64,7 @@ describe 'session module', -> ipcMain.removeAllListeners 'count' assert not count done() - w.loadUrl 'file://' + path.join(fixtures, 'api', 'localstorage.html') + w.loadURL 'file://' + path.join(fixtures, 'api', 'localstorage.html') w.webContents.on 'did-finish-load', -> options = origin: "file://", @@ -91,7 +91,7 @@ describe 'session module', -> downloadServer.listen 0, '127.0.0.1', -> {port} = downloadServer.address() ipcRenderer.sendSync 'set-download-option', false - w.loadUrl "#{url}:#{port}" + w.loadURL "#{url}:#{port}" ipcRenderer.once 'download-done', (event, state, url, mimeType, receivedBytes, totalBytes, disposition, filename) -> assert.equal state, 'completed' assert.equal filename, 'mock.pdf' @@ -108,7 +108,7 @@ describe 'session module', -> downloadServer.listen 0, '127.0.0.1', -> {port} = downloadServer.address() ipcRenderer.sendSync 'set-download-option', true - w.loadUrl "#{url}:#{port}/" + w.loadURL "#{url}:#{port}/" ipcRenderer.once 'download-done', (event, state, url, mimeType, receivedBytes, totalBytes, disposition, filename) -> assert.equal state, 'cancelled' assert.equal filename, 'mock.pdf' diff --git a/spec/asar-spec.coffee b/spec/asar-spec.coffee index f84fb0599156..ad480a582525 100644 --- a/spec/asar-spec.coffee +++ b/spec/asar-spec.coffee @@ -453,7 +453,7 @@ describe 'asar package', -> ipcMain.once 'dirname', (event, dirname) -> assert.equal dirname, path.dirname(p) done() - w.loadUrl u + w.loadURL u it 'loads script tag in html', (done) -> after -> @@ -463,7 +463,7 @@ describe 'asar package', -> w = new BrowserWindow(show: false, width: 400, height: 400) p = path.resolve fixtures, 'asar', 'script.asar', 'index.html' u = url.format protocol: 'file', slashed: true, pathname: p - w.loadUrl u + w.loadURL u ipcMain.once 'ping', (event, message) -> assert.equal message, 'pong' done() diff --git a/spec/chromium-spec.coffee b/spec/chromium-spec.coffee index ebd7b36dc1a3..435f7bbbe3e5 100644 --- a/spec/chromium-spec.coffee +++ b/spec/chromium-spec.coffee @@ -43,7 +43,7 @@ describe 'chromium feature', -> w.webContents.on 'ipc-message', (event, args) -> assert.deepEqual args, ['hidden', true] done() - w.loadUrl url + w.loadURL url describe 'navigator.webkitGetUserMedia', -> it 'calls its callbacks', (done) -> @@ -96,7 +96,7 @@ describe 'chromium feature', -> w.webContents.on 'ipc-message', (event, args) -> assert.deepEqual args, ['opener', null] done() - w.loadUrl url + w.loadURL url it 'is not null for window opened by window.open', (done) -> listener = (event) -> diff --git a/spec/fixtures/api/crash.html b/spec/fixtures/api/crash.html index 30494849373d..c1fb621426af 100644 --- a/spec/fixtures/api/crash.html +++ b/spec/fixtures/api/crash.html @@ -6,7 +6,7 @@ var crashReporter = require('electron').crashReporter; crashReporter.start({ productName: 'Zombies', companyName: 'Umbrella Corporation', - submitUrl: 'http://127.0.0.1:' + port, + submitURL: 'http://127.0.0.1:' + port, autoSubmit: true, ignoreSystemCrashHandler: true, extra: { diff --git a/spec/static/main.js b/spec/static/main.js index e071474f9a94..be3690cd9e7d 100644 --- a/spec/static/main.js +++ b/spec/static/main.js @@ -67,7 +67,7 @@ app.on('ready', function() { javascript: true // Test whether web-preferences crashes. }, }); - window.loadUrl('file://' + __dirname + '/index.html'); + window.loadURL('file://' + __dirname + '/index.html'); window.on('unresponsive', function() { var chosen = dialog.showMessageBox(window, { type: 'warning', @@ -88,7 +88,7 @@ app.on('ready', function() { item.on('done', function(e, state) { window.webContents.send('download-done', state, - item.getUrl(), + item.getURL(), item.getMimeType(), item.getReceivedBytes(), item.getTotalBytes(), From e8ffd24e4e12d33c739dc4c0953efe288699fd60 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Fri, 13 Nov 2015 16:41:33 +0800 Subject: [PATCH 148/249] Rename the "clicked" event to "click" in Tray --- atom/browser/api/atom_api_tray.cc | 8 ++++---- atom/browser/api/lib/browser-window.coffee | 2 +- atom/browser/api/lib/tray.coffee | 14 ++++++++++---- atom/common/api/lib/deprecate.coffee | 7 +++++-- docs/api/tray.md | 12 ++++++------ 5 files changed, 26 insertions(+), 17 deletions(-) diff --git a/atom/browser/api/atom_api_tray.cc b/atom/browser/api/atom_api_tray.cc index 0c24240f223c..d3c5931ad6da 100644 --- a/atom/browser/api/atom_api_tray.cc +++ b/atom/browser/api/atom_api_tray.cc @@ -44,21 +44,21 @@ mate::Wrappable* Tray::New(v8::Isolate* isolate, const gfx::Image& image) { void Tray::OnClicked(const gfx::Rect& bounds, int modifiers) { v8::Locker locker(isolate()); v8::HandleScope handle_scope(isolate()); - EmitCustomEvent("clicked", + EmitCustomEvent("click", ModifiersToObject(isolate(), modifiers), bounds); } void Tray::OnDoubleClicked(const gfx::Rect& bounds, int modifiers) { v8::Locker locker(isolate()); v8::HandleScope handle_scope(isolate()); - EmitCustomEvent("double-clicked", + EmitCustomEvent("double-click", ModifiersToObject(isolate(), modifiers), bounds); } void Tray::OnRightClicked(const gfx::Rect& bounds, int modifiers) { v8::Locker locker(isolate()); v8::HandleScope handle_scope(isolate()); - EmitCustomEvent("right-clicked", + EmitCustomEvent("right-click", ModifiersToObject(isolate(), modifiers), bounds); } @@ -67,7 +67,7 @@ void Tray::OnBalloonShow() { } void Tray::OnBalloonClicked() { - Emit("balloon-clicked"); + Emit("balloon-click"); } void Tray::OnBalloonClosed() { diff --git a/atom/browser/api/lib/browser-window.coffee b/atom/browser/api/lib/browser-window.coffee index 9947bc1a50ba..99921372f14c 100644 --- a/atom/browser/api/lib/browser-window.coffee +++ b/atom/browser/api/lib/browser-window.coffee @@ -1,7 +1,7 @@ {app, ipcMain, deprecate} = require 'electron' {EventEmitter} = require 'events' -BrowserWindow = process.atomBinding('window').BrowserWindow +{BrowserWindow} = process.atomBinding 'window' BrowserWindow::__proto__ = EventEmitter.prototype BrowserWindow::_init = -> diff --git a/atom/browser/api/lib/tray.coffee b/atom/browser/api/lib/tray.coffee index 41cfc96d3f56..db26ab5b7ed1 100644 --- a/atom/browser/api/lib/tray.coffee +++ b/atom/browser/api/lib/tray.coffee @@ -1,13 +1,19 @@ +{deprecate} = require 'electron' {EventEmitter} = require 'events' -{Tray} = process.atomBinding 'tray' +{Tray} = process.atomBinding 'tray' Tray::__proto__ = EventEmitter.prototype +Tray::_init = -> + # Deprecated. + deprecate.rename this, 'popContextMenu', 'popUpContextMenu' + deprecate.event this, 'clicked', 'click' + deprecate.event this, 'double-clicked', 'double-click' + deprecate.event this, 'right-clicked', 'right-click' + deprecate.event this, 'balloon-clicked', 'balloon-click' + Tray::setContextMenu = (menu) -> @_setContextMenu menu @menu = menu # Keep a strong reference of menu. -# Keep compatibility with old APIs. -Tray::popContextMenu = Tray::popUpContextMenu - module.exports = Tray diff --git a/atom/common/api/lib/deprecate.coffee b/atom/common/api/lib/deprecate.coffee index 070a9feb6aab..1daf5e4714fd 100644 --- a/atom/common/api/lib/deprecate.coffee +++ b/atom/common/api/lib/deprecate.coffee @@ -42,12 +42,15 @@ deprecate.property = (object, property, method) -> # Deprecate an event. deprecate.event = (emitter, oldName, newName, fn) -> warned = false - emitter.on newName, -> + emitter.on newName, (args...) -> if @listenerCount(oldName) > 0 # there is listeners for old API. unless warned or process.noDeprecation warned = true deprecate.warn "'#{oldName}' event", "'#{newName}' event" - fn.apply this, arguments + if fn? + fn.apply this, arguments + else + @emit oldName, args... # Print deprecate warning. deprecate.warn = (oldName, newName) -> diff --git a/docs/api/tray.md b/docs/api/tray.md index ff4310308a86..47936ab15e60 100644 --- a/docs/api/tray.md +++ b/docs/api/tray.md @@ -31,10 +31,10 @@ __Platform limitations:__ * On Linux distributions that only have app indicator support, you have to install `libappindicator1` to make the tray icon work. * App indicator will only be shown when it has a context menu. -* When app indicator is used on Linux, the `clicked` event is ignored. +* When app indicator is used on Linux, the `click` event is ignored. If you want to keep exact same behaviors on all platforms, you should not -rely on the `clicked` event and always attach a context menu to the tray icon. +rely on the `click` event and always attach a context menu to the tray icon. ## Class: Tray @@ -53,7 +53,7 @@ The `Tray` module emits the following events: **Note:** Some events are only available on specific operating systems and are labeled as such. -### Event: 'clicked' +### Event: 'click' * `event` Event * `altKey` Boolean @@ -70,7 +70,7 @@ Emitted when the tray icon is clicked. __Note:__ The `bounds` payload is only implemented on OS X and Windows. -### Event: 'right-clicked' _OS X_ _Windows_ +### Event: 'right-click' _OS X_ _Windows_ * `event` Event * `altKey` Boolean @@ -85,7 +85,7 @@ __Note:__ The `bounds` payload is only implemented on OS X and Windows. Emitted when the tray icon is right clicked. -### Event: 'double-clicked' _OS X_ _Windows_ +### Event: 'double-click' _OS X_ _Windows_ * `event` Event * `altKey` Boolean @@ -104,7 +104,7 @@ Emitted when the tray icon is double clicked. Emitted when the tray balloon shows. -### Event: 'balloon-clicked' _Windows_ +### Event: 'balloon-click' _Windows_ Emitted when the tray balloon is clicked. From e76a7f7b7d662ebcd7d6a441e1dfc39118638775 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Fri, 13 Nov 2015 21:52:05 +0800 Subject: [PATCH 149/249] Fix typo, tray => Tray --- atom/browser/api/lib/exports/electron.coffee | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/atom/browser/api/lib/exports/electron.coffee b/atom/browser/api/lib/exports/electron.coffee index 6f70e6b38b36..768224d95796 100644 --- a/atom/browser/api/lib/exports/electron.coffee +++ b/atom/browser/api/lib/exports/electron.coffee @@ -45,7 +45,7 @@ Object.defineProperties module.exports, screen: enumerable: true get: -> require '../screen' - tray: + Tray: enumerable: true get: -> require '../tray' # The internal modules, invisible unless you know their names. From 9bf0a8647e86c10df4b21bfdca4168ca1c89235a Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Fri, 13 Nov 2015 21:52:27 +0800 Subject: [PATCH 150/249] Make it easier to use remote --- atom/renderer/api/lib/remote.coffee | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/atom/renderer/api/lib/remote.coffee b/atom/renderer/api/lib/remote.coffee index 09e7dcdcb574..a38d6ec0bf42 100644 --- a/atom/renderer/api/lib/remote.coffee +++ b/atom/renderer/api/lib/remote.coffee @@ -134,6 +134,19 @@ ipcRenderer.on 'ATOM_RENDERER_CALLBACK', (event, id, args) -> ipcRenderer.on 'ATOM_RENDERER_RELEASE_CALLBACK', (event, id) -> callbacksRegistry.remove id +# List all built-in modules in browser process. +# NB(zcbenz): We should probably send an sync message to browser process to get +# them, but that would slow down the startup speed. +browserModules = + ['app', 'autoUpdater', 'BrowserWindow', 'contentTracing', 'dialog', + 'globalShortcut', 'ipcMain', 'Menu', 'MenuItem', 'powerMonitor', + 'powerSaveBlocker', 'protocol', 'Tray', 'clipboard', 'crashReporter', + 'nativeImage', 'screen', 'shell'] +# And add a helper receiver for each one. +for name in browserModules + do (name) -> + Object.defineProperty exports, name, get: -> exports.getBuiltin name + # Get remote module. # (Just like node's require, the modules are cached permanently, note that this # is safe leak since the object is not expected to get freed in browser) From 099278855c3067521a4c5f5988379f38ca4a6405 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Fri, 13 Nov 2015 21:54:56 +0800 Subject: [PATCH 151/249] Simplify how remote.require('electron') is optimized --- atom/browser/api/lib/exports/electron.coffee | 3 --- atom/browser/lib/rpc-server.coffee | 6 ------ atom/renderer/api/lib/remote.coffee | 12 +++--------- 3 files changed, 3 insertions(+), 18 deletions(-) diff --git a/atom/browser/api/lib/exports/electron.coffee b/atom/browser/api/lib/exports/electron.coffee index 768224d95796..f0c3b87c987b 100644 --- a/atom/browser/api/lib/exports/electron.coffee +++ b/atom/browser/api/lib/exports/electron.coffee @@ -1,9 +1,6 @@ # Import common modules. module.exports = require '../../../../common/api/lib/exports/electron' -v8Util = process.atomBinding 'v8_util' -v8Util.setHiddenValue module.exports, 'electronModule', true - Object.defineProperties module.exports, # Browser side modules, please sort with alphabet order. app: diff --git a/atom/browser/lib/rpc-server.coffee b/atom/browser/lib/rpc-server.coffee index 5c67026debf2..df6d4f1f94ec 100644 --- a/atom/browser/lib/rpc-server.coffee +++ b/atom/browser/lib/rpc-server.coffee @@ -18,10 +18,6 @@ valueToMeta = (sender, value, optimizeSimpleObject=false) -> meta.type = 'date' if value instanceof Date meta.type = 'promise' if value?.constructor.name is 'Promise' - # require('electron'). - if meta.type is 'object' and v8Util.getHiddenValue value, 'electronModule' - meta.type = 'electronModule' - # Treat simple objects as value. if optimizeSimpleObject and meta.type is 'object' and v8Util.getHiddenValue value, 'simple' meta.type = 'value' @@ -49,8 +45,6 @@ valueToMeta = (sender, value, optimizeSimpleObject=false) -> meta.members = plainObjectToMeta value else if meta.type is 'date' meta.value = value.getTime() - else if meta.type is 'electronModule' - meta.members = (name for name of value) else meta.type = 'value' meta.value = value diff --git a/atom/renderer/api/lib/remote.coffee b/atom/renderer/api/lib/remote.coffee index a38d6ec0bf42..e177ea4bb6b4 100644 --- a/atom/renderer/api/lib/remote.coffee +++ b/atom/renderer/api/lib/remote.coffee @@ -49,15 +49,6 @@ metaToValue = (meta) -> when 'date' then new Date(meta.value) when 'exception' throw new Error("#{meta.message}\n#{meta.stack}") - when 'electronModule' - # require('electron'). - ret = {} - for member in meta.members - do (member) -> - Object.defineProperty ret, member, - enumerable: true - get: -> exports.getBuiltin member - ret else if meta.type is 'function' # A shadow class to represent the remote function object. @@ -157,6 +148,9 @@ exports.require = (module) -> meta = ipcRenderer.sendSync 'ATOM_BROWSER_REQUIRE', module moduleCache[module] = metaToValue meta +# Optimize require('electron'). +moduleCache.electron = exports + # Alias to remote.require('electron').xxx. builtinCache = {} exports.getBuiltin = (module) -> From b925ac00566b29b2410bf9f05a556a667db944f0 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Fri, 13 Nov 2015 22:15:16 +0800 Subject: [PATCH 152/249] Send sync message to get list of modules --- atom/browser/lib/rpc-server.coffee | 3 +++ atom/renderer/api/lib/remote.coffee | 8 +------- 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/atom/browser/lib/rpc-server.coffee b/atom/browser/lib/rpc-server.coffee index df6d4f1f94ec..6cbc5ffc1fd5 100644 --- a/atom/browser/lib/rpc-server.coffee +++ b/atom/browser/lib/rpc-server.coffee @@ -206,3 +206,6 @@ ipcMain.on 'ATOM_BROWSER_GUEST_WEB_CONTENTS', (event, guestInstanceId) -> event.returnValue = valueToMeta event.sender, guestViewManager.getGuest(guestInstanceId) catch e event.returnValue = exceptionToMeta e + +ipcMain.on 'ATOM_BROWSER_LIST_MODULES', (event) -> + event.returnValue = (name for name of electron) diff --git a/atom/renderer/api/lib/remote.coffee b/atom/renderer/api/lib/remote.coffee index e177ea4bb6b4..48cdd937fb07 100644 --- a/atom/renderer/api/lib/remote.coffee +++ b/atom/renderer/api/lib/remote.coffee @@ -126,13 +126,7 @@ ipcRenderer.on 'ATOM_RENDERER_RELEASE_CALLBACK', (event, id) -> callbacksRegistry.remove id # List all built-in modules in browser process. -# NB(zcbenz): We should probably send an sync message to browser process to get -# them, but that would slow down the startup speed. -browserModules = - ['app', 'autoUpdater', 'BrowserWindow', 'contentTracing', 'dialog', - 'globalShortcut', 'ipcMain', 'Menu', 'MenuItem', 'powerMonitor', - 'powerSaveBlocker', 'protocol', 'Tray', 'clipboard', 'crashReporter', - 'nativeImage', 'screen', 'shell'] +browserModules = ipcRenderer.sendSync 'ATOM_BROWSER_LIST_MODULES' # And add a helper receiver for each one. for name in browserModules do (name) -> From 94e24abb998d73545b4a2eedf3872b5e13763d0f Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Fri, 13 Nov 2015 22:22:25 +0800 Subject: [PATCH 153/249] Use the new style remote module in Electron --- atom/common/api/lib/clipboard.coffee | 3 +-- atom/common/api/lib/crash-reporter.coffee | 6 +----- atom/renderer/api/lib/screen.coffee | 2 +- atom/renderer/lib/inspector.coffee | 4 ++-- atom/renderer/lib/override.coffee | 6 ++---- 5 files changed, 7 insertions(+), 14 deletions(-) diff --git a/atom/common/api/lib/clipboard.coffee b/atom/common/api/lib/clipboard.coffee index 0ea97d86ba81..a3a6d555fe5c 100644 --- a/atom/common/api/lib/clipboard.coffee +++ b/atom/common/api/lib/clipboard.coffee @@ -1,6 +1,5 @@ if process.platform is 'linux' and process.type is 'renderer' - {remote} = require 'electron' # On Linux we could not access clipboard in renderer process. - module.exports = remote.getBuiltin 'clipboard' + module.exports = require('electron').remote.clipboard else module.exports = process.atomBinding 'clipboard' diff --git a/atom/common/api/lib/crash-reporter.coffee b/atom/common/api/lib/crash-reporter.coffee index 0713da99daef..bd98ae2a4277 100644 --- a/atom/common/api/lib/crash-reporter.coffee +++ b/atom/common/api/lib/crash-reporter.coffee @@ -16,11 +16,7 @@ class CrashReporter submitURL ?= options.submitUrl deprecate.warn 'submitUrl', 'submitURL' - {app} = - if process.type is 'browser' - electron - else - electron.remote.require 'electron' + {app} = if process.type is 'browser' then electron else electron.remote @productName ?= app.getName() companyName ?= 'GitHub, Inc' diff --git a/atom/renderer/api/lib/screen.coffee b/atom/renderer/api/lib/screen.coffee index b70aa55b5708..9eecd49dc5bf 100644 --- a/atom/renderer/api/lib/screen.coffee +++ b/atom/renderer/api/lib/screen.coffee @@ -1 +1 @@ -module.exports = require('electron').remote.require('electron').screen +module.exports = require('electron').remote.screen diff --git a/atom/renderer/lib/inspector.coffee b/atom/renderer/lib/inspector.coffee index 34c6876fc274..d5ddfd72e486 100644 --- a/atom/renderer/lib/inspector.coffee +++ b/atom/renderer/lib/inspector.coffee @@ -33,7 +33,7 @@ convertToMenuTemplate = (items) -> createMenu = (x, y, items, document) -> {remote} = require 'electron' - {Menu} = remote.require 'electron' + {Menu} = remote menu = Menu.buildFromTemplate convertToMenuTemplate(items) # The menu is expected to show asynchronously. @@ -43,7 +43,7 @@ createMenu = (x, y, items, document) -> showFileChooserDialog = (callback) -> {remote} = require 'electron' - {dialog} = remote.require 'electron' + {dialog} = remote files = dialog.showOpenDialog {} callback pathToHtml5FileObject files[0] if files? diff --git a/atom/renderer/lib/override.coffee b/atom/renderer/lib/override.coffee index a3a2f9ac62da..0b60ce0d6686 100644 --- a/atom/renderer/lib/override.coffee +++ b/atom/renderer/lib/override.coffee @@ -67,19 +67,17 @@ window.open = (url, frameName='', features='') -> # Use the dialog API to implement alert(). window.alert = (message, title='') -> - dialog = remote.require 'dialog' buttons = ['OK'] message = message.toString() - dialog.showMessageBox remote.getCurrentWindow(), {message, title, buttons} + remote.dialog.showMessageBox remote.getCurrentWindow(), {message, title, buttons} # Alert should always return undefined. return # And the confirm(). window.confirm = (message, title='') -> - dialog = remote.require 'dialog' buttons = ['OK', 'Cancel'] cancelId = 1 - not dialog.showMessageBox remote.getCurrentWindow(), {message, title, buttons, cancelId} + not remote.dialog.showMessageBox remote.getCurrentWindow(), {message, title, buttons, cancelId} # But we do not support prompt(). window.prompt = -> From 5cacf79bc5ceb82a793b2cc3916f0a8ee4fc14ae Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Fri, 13 Nov 2015 22:34:00 +0800 Subject: [PATCH 154/249] docs: Document the new style of remote module --- docs/api/menu.md | 4 ++-- docs/api/remote.md | 11 ++++++++++- docs/api/synopsis.md | 2 +- docs/tutorial/devtools-extension.md | 2 +- 4 files changed, 14 insertions(+), 5 deletions(-) diff --git a/docs/api/menu.md b/docs/api/menu.md index c947f36d4790..1d819682160b 100644 --- a/docs/api/menu.md +++ b/docs/api/menu.md @@ -17,8 +17,8 @@ the user right clicks the page: diff --git a/docs/tutorial/devtools-extension.md b/docs/tutorial/devtools-extension.md index 258fb41947ff..7c7ea7d64a24 100644 --- a/docs/tutorial/devtools-extension.md +++ b/docs/tutorial/devtools-extension.md @@ -24,7 +24,7 @@ Then you can load the extension in Electron by opening DevTools in any window, and running the following code in the DevTools console: ```javascript -const BrowserWindow = require('electron').remote.require('electron').BrowserWindow; +const BrowserWindow = require('electron').remote.BrowserWindow; BrowserWindow.addDevToolsExtension('/some-directory/react-devtools/shells/chrome'); ``` From 2a7f874373c44d1606cbabe2c921763732fca87c Mon Sep 17 00:00:00 2001 From: Robo Date: Sat, 14 Nov 2015 02:25:23 +0530 Subject: [PATCH 155/249] browser: fix reloadignoringcache api --- atom/browser/api/atom_api_web_contents.cc | 5 ----- atom/browser/api/lib/navigation-controller.coffee | 4 ++-- 2 files changed, 2 insertions(+), 7 deletions(-) diff --git a/atom/browser/api/atom_api_web_contents.cc b/atom/browser/api/atom_api_web_contents.cc index 601a4ba63f13..1c3334e93669 100644 --- a/atom/browser/api/atom_api_web_contents.cc +++ b/atom/browser/api/atom_api_web_contents.cc @@ -658,10 +658,6 @@ void WebContents::Stop() { web_contents()->Stop(); } -void WebContents::ReloadIgnoringCache() { - web_contents()->GetController().ReloadIgnoringCache(false); -} - void WebContents::GoBack() { atom::AtomBrowserClient::SuppressRendererProcessRestartForOnce(); web_contents()->GetController().GoBack(); @@ -1009,7 +1005,6 @@ mate::ObjectTemplateBuilder WebContents::GetObjectTemplateBuilder( .SetMethod("isLoading", &WebContents::IsLoading) .SetMethod("isWaitingForResponse", &WebContents::IsWaitingForResponse) .SetMethod("_stop", &WebContents::Stop) - .SetMethod("_reloadIgnoringCache", &WebContents::ReloadIgnoringCache) .SetMethod("_goBack", &WebContents::GoBack) .SetMethod("_goForward", &WebContents::GoForward) .SetMethod("_goToOffset", &WebContents::GoToOffset) diff --git a/atom/browser/api/lib/navigation-controller.coffee b/atom/browser/api/lib/navigation-controller.coffee index 7d276e57e31a..d0c539a99db5 100644 --- a/atom/browser/api/lib/navigation-controller.coffee +++ b/atom/browser/api/lib/navigation-controller.coffee @@ -62,8 +62,8 @@ class NavigationController @webContents._loadURL @getURL(), {} reloadIgnoringCache: -> - @webContents._reloadIgnoringCache() # Rely on WebContents to clear cache. - @reload() + @pendingIndex = @currentIndex + @webContents._loadURL @getURL(), {extraHeaders: "pragma: no-cache\n"} canGoBack: -> @getActiveIndex() > 0 From e2959ed3fc4199ec9815bb8cf605d4ae23246029 Mon Sep 17 00:00:00 2001 From: Robo Date: Sat, 14 Nov 2015 12:09:18 +0530 Subject: [PATCH 156/249] add docs --- docs/api/web-contents.md | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/docs/api/web-contents.md b/docs/api/web-contents.md index 917e0670590c..1c73c5713fa1 100644 --- a/docs/api/web-contents.md +++ b/docs/api/web-contents.md @@ -207,7 +207,13 @@ See [session documentation](session.md) for this object's methods. * `extraHeaders` String - Extra headers separated by "\n" Loads the `url` in the window, the `url` must contain the protocol prefix, -e.g. the `http://` or `file://`. +e.g. the `http://` or `file://`. If the load should bypass http cache then +use the `pragma` header to achieve it. + +```javascript +const options = {"extraHeaders" : "pragma: no-cache\n"} +webContents.loadURL(url, options) +``` ### `webContents.getURL()` From 9f9436d6dc46dd5f583bd66fc6a30d6f4ca928eb Mon Sep 17 00:00:00 2001 From: Heilig Benedek Date: Sat, 14 Nov 2015 23:59:38 +0100 Subject: [PATCH 157/249] Moved scope creation before the allocation of the buffer in `FrameSubscriber` --- atom/browser/api/frame_subscriber.cc | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/atom/browser/api/frame_subscriber.cc b/atom/browser/api/frame_subscriber.cc index 526769f9cd6c..cf0eae14a9a8 100644 --- a/atom/browser/api/frame_subscriber.cc +++ b/atom/browser/api/frame_subscriber.cc @@ -38,6 +38,9 @@ void FrameSubscriber::OnFrameDelivered( if (!result) return; + v8::Locker locker(isolate_); + v8::HandleScope handle_scope(isolate_); + gfx::Rect rect = frame->visible_rect(); size_t rgb_arr_size = rect.width() * rect.height() * 4; v8::MaybeLocal buffer = node::Buffer::New(isolate_, rgb_arr_size); @@ -56,8 +59,6 @@ void FrameSubscriber::OnFrameDelivered( rect.width() * 4, media::YV12); - v8::Locker locker(isolate_); - v8::HandleScope handle_scope(isolate_); callback_.Run(buffer.ToLocalChecked()); } From c1373d7480c48036fed38297770751f5944482ed Mon Sep 17 00:00:00 2001 From: Eddie Zaneski Date: Sun, 15 Nov 2015 10:48:09 -0500 Subject: [PATCH 158/249] Fix typo in notifications example docs --- docs/tutorial/desktop-environment-integration.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/tutorial/desktop-environment-integration.md b/docs/tutorial/desktop-environment-integration.md index 7c4807d8f4d4..6e570ee71f92 100644 --- a/docs/tutorial/desktop-environment-integration.md +++ b/docs/tutorial/desktop-environment-integration.md @@ -16,7 +16,7 @@ the [HTML5 Notification API](https://notifications.spec.whatwg.org/), using the currently running operating system's native notification APIs to display it. ```javascript -var myNotificiation = new Notification('Title', { +var myNotification = new Notification('Title', { body: 'Lorem Ipsum Dolor Sit Amet' }); From 42a3771f98a8ba657d15e62dbbb972e68b063735 Mon Sep 17 00:00:00 2001 From: Plusb Preco Date: Mon, 16 Nov 2015 08:30:08 +0900 Subject: [PATCH 159/249] Small change --- docs-translations/ko-KR/tutorial/quick-start.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs-translations/ko-KR/tutorial/quick-start.md b/docs-translations/ko-KR/tutorial/quick-start.md index 5c2cc80f4060..942b133f2a35 100644 --- a/docs-translations/ko-KR/tutorial/quick-start.md +++ b/docs-translations/ko-KR/tutorial/quick-start.md @@ -181,7 +181,7 @@ $ ./Electron.app/Contents/MacOS/Electron your-app/ ### 미리 작성된 앱 실행하기 -[`atom/electron-quick-start`](https://github.com/atom/electron-quick-start) 저장소를 클론하면 이 가이드에서 작성한 예제 앱을 바로 실행해 볼 수 있습니다. +[`atom/electron-quick-start`](https://github.com/atom/electron-quick-start) 저장소를 클론하면 이 문서에서 작성한 예제 앱을 바로 실행해 볼 수 있습니다. **참고**: 이 예제를 실행시키려면 [Git](https://git-scm.com)과 [Node.js](https://nodejs.org/en/download/)가 필요합니다. (CLI에서 실행 가능한 [npm](https://npmjs.org)이 있어야 합니다) From ad776887da5e8fe6115cb6e2f4e48d76564f02b9 Mon Sep 17 00:00:00 2001 From: Plusb Preco Date: Mon, 16 Nov 2015 08:34:41 +0900 Subject: [PATCH 160/249] Update README.md --- README-ko.md | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/README-ko.md b/README-ko.md index c8a3e6c59fb7..a0d1a9d3438f 100644 --- a/README-ko.md +++ b/README-ko.md @@ -8,16 +8,17 @@ :zap: *프레임워크 이름이 Atom Shell에서 Electron으로 변경되었습니다* :zap: -Electron 프레임워크는 JavaScript, HTML 그리고 CSS를 사용하여 Cross-Platform 데스크톱 어플리케이션을 개발할 수 있도록 해주는 프레임워크입니다. 이 프레임워크는 [Node.js](https://nodejs.org) 와 -[Chromium](http://www.chromium.org)을 기반으로 만들어 졌으며 [Atom Editor](https://github.com/atom/atom)에 사용되고 있습니다. +Electron 프레임워크는 JavaScript, HTML 그리고 CSS를 사용하여 Cross-Platform 데스크톱 어플리케이션을 개발할 수 있도록 해주는 프레임워크입니다. +이 프레임워크는 [Node.js](https://nodejs.org/) 와 [Chromium](http://www.chromium.org)을 기반으로 만들어 졌으며 +[Atom Editor](https://github.com/atom/atom)에 사용되고 있습니다. Electron에 대한 중요한 알림을 받고 싶다면 Twitter에서 [@ElectronJS](https://twitter.com/electronjs)를 팔로우 하세요. -이 프로젝트는 기여자 규약 1.2를 준수합니다. 이 프로젝트에 참여할 때 코드를 유지해야 합니다. 받아들일 수 없는 행동은 atom@github.com로 보고 하십시오. +이 프로젝트는 [기여자 규약 1.2](http://contributor-covenant.org/version/1/2/0/)를 준수합니다. 이 프로젝트에 참여할 때 코드를 유지해야 합니다. 받아들일 수 없는 행위를 발견했을 경우 atom@github.com로 보고 하십시오. ## 다운로드 -Linux, Windows, Mac용으로 미리 빌드된 Electron 바이너리와 디버그 심볼이 준비되어 있습니다. [releases](https://github.com/atom/electron/releases) 페이지에서 받아 볼 수 있습니다. +Linux, Windows, OS X 용으로 미리 빌드된 Electron 바이너리와 디버그 심볼이 준비되어 있습니다. [releases](https://github.com/atom/electron/releases) 페이지에서 받아 볼 수 있습니다. 또한 [`npm`](https://docs.npmjs.com/)을 통해 미리 빌드된 Electron 바이너리를 받을 수도 있습니다: @@ -55,7 +56,7 @@ Electron을 빌드 하는 방법과 프로젝트에 기여하는 방법도 문 다음 링크를 통해 커뮤니티에 질문을 올리거나 토론을 나눌 수 있습니다: -- Atom 포럼의 [`electron`](http://discuss.atom.io/category/electron) 카테고리 +- Atom 포럼의 [`electron`](http://discuss.atom.io/c/electron) 카테고리 - Freenode 채팅의 `#atom-shell` 채널 - Slack의 [`Atom`](http://atom-slack.herokuapp.com/) 채널 From e12e119381ab1170c8394f62bb26cccce6703bf1 Mon Sep 17 00:00:00 2001 From: Plusb Preco Date: Mon, 16 Nov 2015 12:15:21 +0900 Subject: [PATCH 161/249] Update as upstream * Update as upstream * Fix typos * Improve grammar --- docs-translations/ko-KR/README.md | 30 +++--- docs-translations/ko-KR/api/app.md | 8 +- docs-translations/ko-KR/api/auto-updater.md | 6 +- .../ko-KR/api/chrome-command-line-switches.md | 13 ++- docs-translations/ko-KR/api/clipboard.md | 5 +- .../ko-KR/api/content-tracing.md | 9 +- docs-translations/ko-KR/api/crash-reporter.md | 8 +- docs-translations/ko-KR/api/dialog.md | 2 +- docs-translations/ko-KR/api/download-item.md | 101 ++++++++++++++++++ .../ko-KR/api/frameless-window.md | 6 +- .../ko-KR/api/global-shortcut.md | 5 +- docs-translations/ko-KR/api/ipc-main.md | 12 +-- docs-translations/ko-KR/api/menu.md | 10 +- docs-translations/ko-KR/api/native-image.md | 33 +++--- docs-translations/ko-KR/api/power-monitor.md | 4 +- .../ko-KR/api/power-save-blocker.md | 4 +- docs-translations/ko-KR/api/protocol.md | 7 +- docs-translations/ko-KR/api/remote.md | 21 +++- docs-translations/ko-KR/api/screen.md | 7 +- docs-translations/ko-KR/api/session.md | 6 +- docs-translations/ko-KR/api/shell.md | 2 +- docs-translations/ko-KR/api/synopsis.md | 59 +++++++--- docs-translations/ko-KR/api/tray.md | 25 ++--- docs-translations/ko-KR/api/web-frame.md | 16 ++- docs-translations/ko-KR/api/web-view-tag.md | 20 ++-- .../ko-KR/tutorial/application-packaging.md | 24 ++--- .../desktop-environment-integration.md | 15 +-- .../ko-KR/tutorial/devtools-extension.md | 5 +- .../ko-KR/tutorial/online-offline-events.md | 22 ++-- .../ko-KR/tutorial/quick-start.md | 9 +- .../tutorial/using-pepper-flash-plugin.md | 19 +--- .../tutorial/using-selenium-and-webdriver.md | 4 +- 32 files changed, 340 insertions(+), 177 deletions(-) create mode 100644 docs-translations/ko-KR/api/download-item.md diff --git a/docs-translations/ko-KR/README.md b/docs-translations/ko-KR/README.md index 73df16241528..c4c771194954 100644 --- a/docs-translations/ko-KR/README.md +++ b/docs-translations/ko-KR/README.md @@ -31,32 +31,32 @@ ### 메인 프로세스에서 사용할 수 있는 모듈: * [app](api/app.md) -* [auto-updater](api/auto-updater.md) -* [browser-window (0% 번역됨)](api/browser-window.md) -* [content-tracing](api/content-tracing.md) +* [autoUpdater](api/auto-updater.md) +* [BrowserWindow (0% 번역됨)](api/browser-window.md) +* [contentTracing](api/content-tracing.md) * [dialog](api/dialog.md) -* [global-shortcut](api/global-shortcut.md) -* [ipc-main](api/ipc-main.md) -* [menu](api/menu.md) -* [menu-item](api/menu-item.md) -* [power-monitor](api/power-monitor.md) -* [power-save-blocker](api/power-save-blocker.md) +* [globalShortcut](api/global-shortcut.md) +* [ipcMain](api/ipc-main.md) +* [Menu](api/menu.md) +* [MenuItem](api/menu-item.md) +* [powerMonitor](api/power-monitor.md) +* [powerSaveBlocker](api/power-save-blocker.md) * [protocol](api/protocol.md) * [session](api/session.md) -* [web-contents (0% 번역됨)](api/web-contents.md) -* [tray](api/tray.md) +* [webContents (0% 번역됨)](api/web-contents.md) +* [Tray](api/tray.md) ### 랜더러 프로세스에서 사용할 수 있는 모듈 (웹 페이지): -* [ipc-renderer](api/ipc-renderer.md) +* [ipcRenderer](api/ipc-renderer.md) * [remote](api/remote.md) -* [web-frame](api/web-frame.md) +* [webFrame](api/web-frame.md) ### 두 프로세스 모두 사용할 수 있는 모듈: * [clipboard](api/clipboard.md) -* [crash-reporter](api/crash-reporter.md) -* [native-image](api/native-image.md) +* [crashReporter](api/crash-reporter.md) +* [nativeImage](api/native-image.md) * [screen](api/screen.md) * [shell](api/shell.md) diff --git a/docs-translations/ko-KR/api/app.md b/docs-translations/ko-KR/api/app.md index f5e8e8d96b96..e37642743099 100644 --- a/docs-translations/ko-KR/api/app.md +++ b/docs-translations/ko-KR/api/app.md @@ -5,7 +5,7 @@ 밑의 예제는 마지막 윈도우창가 종료되었을 때, 어플리케이션을 종료시키는 예제입니다: ```javascript -var app = require('app'); +const app = require('electron').app; app.on('window-all-closed', function() { app.quit(); }); @@ -240,6 +240,12 @@ GPU가 작동하던 중 크래시가 일어났을 때 발생하는 이벤트입 * `userDesktop` - 현재 사용자의 데스트탑 디렉터리. * `exe` - 현재 실행중인 Electron 바이너리 파일. * `module` - `libchromiumcontent` 라이브러리. +* `desktop` - 사용자의 데스크탑 디렉터리. +* `documents` - 사용자의 "내 문서" 디렉터리. +* `downloads` - 사용자의 다운로드 디렉터리. +* `music` - 사용자의 음악 디렉터리. +* `pictures` - 사용자의 사진 디렉터리. +* `videos` - 사용자의 동영상 디렉터리. ### `app.setPath(name, path)` diff --git a/docs-translations/ko-KR/api/auto-updater.md b/docs-translations/ko-KR/api/auto-updater.md index f12d04042ef2..1b0d9c032ccc 100644 --- a/docs-translations/ko-KR/api/auto-updater.md +++ b/docs-translations/ko-KR/api/auto-updater.md @@ -62,7 +62,7 @@ Returns: * `releaseNotes` String * `releaseName` String * `releaseDate` Date -* `updateUrl` String +* `updateURL` String 업데이트의 다운로드가 완료되었을 때 발생하는 이벤트입니다. @@ -70,7 +70,7 @@ Returns: `autoUpdater` 객체에서 사용할 수 있는 메서드입니다: -### `autoUpdater.setFeedUrl(url)` +### `autoUpdater.setFeedURL(url)` * `url` String @@ -78,7 +78,7 @@ Returns: ### `autoUpdater.checkForUpdates()` -서버에 새로운 업데이트가 있는지 요청을 보내 확인합니다. API를 사용하기 전에 `setFeedUrl`를 호출해야 합니다. +서버에 새로운 업데이트가 있는지 요청을 보내 확인합니다. API를 사용하기 전에 `setFeedURL`를 호출해야 합니다. ### `autoUpdater.quitAndInstall()` diff --git a/docs-translations/ko-KR/api/chrome-command-line-switches.md b/docs-translations/ko-KR/api/chrome-command-line-switches.md index aea9c49a1021..216d402c41e9 100644 --- a/docs-translations/ko-KR/api/chrome-command-line-switches.md +++ b/docs-translations/ko-KR/api/chrome-command-line-switches.md @@ -5,7 +5,7 @@ 어플리케이션 내부에서 스위치들을 추가할 수 있습니다: ```javascript -var app = require('app'); +const app = require('electron').app; app.commandLine.appendSwitch('remote-debugging-port', '8315'); app.commandLine.appendSwitch('host-rules', 'MAP * 127.0.0.1'); @@ -28,7 +28,16 @@ HTTP 요청 캐시를 비활성화 합니다. ## --remote-debugging-port=`port` -지정한 `port`에 HTTP기반의 리모트 디버거를 활성화 시킵니다. (개발자 콘솔) +지정한 `port`에 HTTP 기반의 리모트 디버거를 활성화 시킵니다. (개발자 콘솔) + +## --js-flags=`flags` + +JS 엔진에 지정한 플래그를 전달합니다. +`flags`를 메인 프로세스에서 활성화하고자 한다면, Electron이 시작되기 전에 스위치를 전달해야 합니다. + +```bash +$ electron --js-flags="--harmony_proxies --harmony_collections" your-app +``` ## --proxy-server=`address:port` diff --git a/docs-translations/ko-KR/api/clipboard.md b/docs-translations/ko-KR/api/clipboard.md index 080078274e01..01f1945856f3 100644 --- a/docs-translations/ko-KR/api/clipboard.md +++ b/docs-translations/ko-KR/api/clipboard.md @@ -3,14 +3,13 @@ `clipboard` 모듈은 복사/붙여넣기 작업을 수행하는 방법을 제공합니다. 다음 예제는 클립보드에 문자열을 씁니다: ```javascript -var clipboard = require('clipboard'); +const clipboard = require('electron').clipboard; clipboard.writeText('Example String'); ``` X Window 시스템에선 selection 클립보드도 존재합니다. 이를 사용하려면 인자 뒤에 `selection` 문자열을 같이 지정해주어야 합니다: ```javascript -var clipboard = require('clipboard'); clipboard.writeText('Example String', 'selection'); console.log(clipboard.readText('selection')); ``` @@ -78,7 +77,6 @@ console.log(clipboard.readText('selection')); 클립보드가 지정한 `data`의 형식을 지원하는지 확인합니다. ```javascript -var clipboard = require('clipboard'); console.log(clipboard.has('

selection

')); ``` @@ -98,7 +96,6 @@ console.log(clipboard.has('

selection

')); * `type` String (optional) ```javascript -var clipboard = require('clipboard'); clipboard.write({text: 'test', html: "test"}); ``` diff --git a/docs-translations/ko-KR/api/content-tracing.md b/docs-translations/ko-KR/api/content-tracing.md index 08221fbc7076..f5f8b03d294a 100644 --- a/docs-translations/ko-KR/api/content-tracing.md +++ b/docs-translations/ko-KR/api/content-tracing.md @@ -4,9 +4,14 @@ 이 모듈은 웹 인터페이스를 포함하고 있지 않으며 크롬 브라우저에서 `chrome://tracing/` 페이지를 열어 생성된 파일을 로드하면 결과를 볼 수 있습니다. ```javascript -var contentTracing = require('content-tracing'); +const contentTracing = require('electron').contentTracing; -contentTracing.startRecording('*', contentTracing.DEFAULT_OPTIONS, function() { +const options = { + categoryFilter: '*', + traceOptions: 'record-until-full,enable-sampling' +}; + +contentTracing.startRecording(options, function() { console.log('Tracing started'); setTimeout(function() { diff --git a/docs-translations/ko-KR/api/crash-reporter.md b/docs-translations/ko-KR/api/crash-reporter.md index 88cd3b82f301..a5d29551571e 100644 --- a/docs-translations/ko-KR/api/crash-reporter.md +++ b/docs-translations/ko-KR/api/crash-reporter.md @@ -5,12 +5,12 @@ 다음 예제는 윈격 서버에 어플리케이션 크래시 정보를 자동으로 보고하는 예제입니다: ```javascript -var crashReporter = require('crash-reporter'); +const crashReporter = require('electron').crashReporter; crashReporter.start({ productName: 'YourName', companyName: 'YourCompany', - submitUrl: 'https://your-domain.com/url-to-submit', + submitURL: 'https://your-domain.com/url-to-submit', autoSubmit: true }); ``` @@ -25,7 +25,7 @@ crashReporter.start({ * `productName` String, 기본값: Electron * `companyName` String, 기본값: GitHub, Inc -* `submitUrl` String, 기본값: http://54.249.141.255:1127/post +* `submitURL` String, 기본값: http://54.249.141.255:1127/post * 크래시 리포트는 POST 방식으로 이 URL로 전송됩니다. * `autoSubmit` Boolean, 기본값: true * true로 지정할 경우 유저의 승인 없이 자동으로 오류를 보고합니다. @@ -52,7 +52,7 @@ crashReporter.start({ ## crash-reporter 업로드 형식 -Crash Reporter는 다음과 같은 데이터를 `submitUrl`에 `POST` 방식으로 전송합니다: +Crash Reporter는 다음과 같은 데이터를 `submitURL`에 `POST` 방식으로 전송합니다: * `ver` String - Electron의 버전 * `platform` String - 예시 'win32' diff --git a/docs-translations/ko-KR/api/dialog.md b/docs-translations/ko-KR/api/dialog.md index 08530c054797..e7e81240da0f 100644 --- a/docs-translations/ko-KR/api/dialog.md +++ b/docs-translations/ko-KR/api/dialog.md @@ -7,7 +7,7 @@ ```javascript var win = ...; // 대화 상자를 사용할 BrowserWindow 객체 -var dialog = require('dialog'); +const dialog = require('electron').dialog; console.log(dialog.showOpenDialog({ properties: [ 'openFile', 'openDirectory', 'multiSelections' ]})); ``` diff --git a/docs-translations/ko-KR/api/download-item.md b/docs-translations/ko-KR/api/download-item.md new file mode 100644 index 000000000000..756353b8ba3d --- /dev/null +++ b/docs-translations/ko-KR/api/download-item.md @@ -0,0 +1,101 @@ +# DownloadItem + +`DownloadItem` is an EventEmitter represents a download item in Electron. It +is used in `will-download` event of `Session` module, and allows users to +control the download item. + +```javascript +// In the main process. +win.webContents.session.on('will-download', function(event, item, webContents) { + // Set the save path, making Electron not to prompt a save dialog. + item.setSavePath('/tmp/save.pdf'); + console.log(item.getMimeType()); + console.log(item.getFilename()); + console.log(item.getTotalBytes()); + item.on('updated', function() { + console.log('Received bytes: ' + item.getReceivedBytes()); + }); + item.on('done', function(e, state) { + if (state == "completed") { + console.log("Download successfully"); + } else { + console.log("Download is cancelled or interrupted that can't be resumed"); + } + }); +``` + +## Events + +### Event: 'updated' + +Emits when the `downloadItem` gets updated. + +### Event: 'done' + +* `event` Event +* `state` String + * `completed` - The download completed successfully. + * `cancelled` - The download has been cancelled. + * `interrupted` - An error broke the connection with the file server. + +Emits when the download is in a terminal state. This includes a completed +download, a cancelled download(via `downloadItem.cancel()`), and interrupted +download that can't be resumed. + +## Methods + +The `downloadItem` object has the following methods: + +### `downloadItem.setSavePath(path)` + +* `path` String - Set the save file path of the download item. + +The API is only available in session's `will-download` callback function. +If user doesn't set the save path via the API, Electron will use the original +routine to determine the save path(Usually prompts a save dialog). + +### `downloadItem.pause()` + +Pauses the download. + +### `downloadItem.resume()` + +Resumes the download that has been paused. + +### `downloadItem.cancel()` + +Cancels the download operation. + +### `downloadItem.getURL()` + +Returns a `String` represents the origin url where the item is downloaded from. + +### `downloadItem.getMimeType()` + +Returns a `String` represents the mime type. + +### `downloadItem.hasUserGesture()` + +Returns a `Boolean` indicates whether the download has user gesture. + +### `downloadItem.getFilename()` + +Returns a `String` represents the file name of the download item. + +**Note:** The file name is not always the same as the actual one saved in local +disk. If user changes the file name in a prompted download saving dialog, the +actual name of saved file will be different. + +### `downloadItem.getTotalBytes()` + +Returns a `Integer` represents the total size in bytes of the download item. +If the size is unknown, it returns 0. + +### `downloadItem.getReceivedBytes()` + +Returns a `Integer` represents the received bytes of the download item. + +### `downloadItem.getContentDisposition()` + +Returns a `String` represents the Content-Disposition field from the response +header. diff --git a/docs-translations/ko-KR/api/frameless-window.md b/docs-translations/ko-KR/api/frameless-window.md index 28662c311ba2..decc0217ed1e 100644 --- a/docs-translations/ko-KR/api/frameless-window.md +++ b/docs-translations/ko-KR/api/frameless-window.md @@ -9,7 +9,7 @@ Frameless Window는 [테두리](https://developer.mozilla.org/en-US/docs/Glossar Frameless Window를 만드려면 [BrowserWindow](browser-window.md) 객체의 `options`에서 `frame` 옵션을 `false`로 지정하면 됩니다: ```javascript -var BrowserWindow = require('browser-window'); +const BrowserWindow = require('electron').BrowserWindow; var win = new BrowserWindow({ width: 800, height: 600, frame: false }); ``` @@ -20,8 +20,8 @@ OS X 10.10 Yosemite 이후의 최신 버전부터는 테두리가 없는 창을 옵션을 통해 제목만 숨기고 창 구성 요소("흔히 신호등으로 알고 있는")의 기능과 창 크기를 그대로 유지할 수 있습니다: ```javascript -var BrowserWindow = require('browser-window'); -var win = new BrowserWindow({ width: 800, height: 600, 'title-bar-style': 'hidden' }); +var win = new BrowserWindow({ 'title-bar-style': 'hidden' }); +``` ## 투명한 창 만들기 diff --git a/docs-translations/ko-KR/api/global-shortcut.md b/docs-translations/ko-KR/api/global-shortcut.md index f000a3bdb6a4..2120f73cc5cb 100644 --- a/docs-translations/ko-KR/api/global-shortcut.md +++ b/docs-translations/ko-KR/api/global-shortcut.md @@ -7,8 +7,9 @@ 이 모듈은 `app` 모듈의 `ready` 이벤트 이전에 사용할 수 없습니다. ```javascript -var app = require('app'); -var globalShortcut = require('global-shortcut'); +const electron = require('electron'); +const app = electron.app; +const globalShortcut = electron.globalShortcut; app.on('ready', function() { // 'ctrl+x' 단축키를 리스너에 등록합니다. diff --git a/docs-translations/ko-KR/api/ipc-main.md b/docs-translations/ko-KR/api/ipc-main.md index cecbf980e720..fae8aa4d5cf6 100644 --- a/docs-translations/ko-KR/api/ipc-main.md +++ b/docs-translations/ko-KR/api/ipc-main.md @@ -16,25 +16,25 @@ ```javascript // 메인 프로세스 -var ipc = require('ipc'); +const ipcMain = require('electron').ipcMain; ipc.on('asynchronous-message', function(event, arg) { - console.log(arg); // prints "ping" + console.log(arg); // "ping" 출력 event.sender.send('asynchronous-reply', 'pong'); }); ipc.on('synchronous-message', function(event, arg) { - console.log(arg); // prints "ping" + console.log(arg); // "ping" 출력 event.returnValue = 'pong'; }); ``` ```javascript // 랜더러 프로세스 (웹 페이지) -var ipc = require('ipc'); -console.log(ipc.sendSync('synchronous-message', 'ping')); // prints "pong" +const ipcRenderer = require('electron').ipcRenderer; +console.log(ipc.sendSync('synchronous-message', 'ping')); // "pong" 출력 ipc.on('asynchronous-reply', function(arg) { - console.log(arg); // prints "pong" + console.log(arg); // "pong" 출력 }); ipc.send('asynchronous-message', 'ping'); ``` diff --git a/docs-translations/ko-KR/api/menu.md b/docs-translations/ko-KR/api/menu.md index 56b7f4a198e5..d55fa807a362 100644 --- a/docs-translations/ko-KR/api/menu.md +++ b/docs-translations/ko-KR/api/menu.md @@ -11,9 +11,9 @@ ```html - + + + ``` 어플리케이션을 실행하려면 [앱 실행하기](../tutorial/quick-start.md#앱 실행하기) 문서를 참고하기 바랍니다. + +## 분리 할당 + +만약 CoffeeScript나 Babel을 사용하고 있다면, 빌트인 모듈을 사용할 때 +[분리 할당][desctructuring-assignment]을 통해 직관적으로 사용할 수 있습니다: + +```javascript +const {app, BrowserWindow} = require('electron') +``` + +아직 플레인 자바스크립트를 쓰고 있다면, Chrome이 ES6를 완전히 지원하기 전까지 기다려야 합니다. + +## 이전 스타일의 빌트인 모듈 비활성화 + +v0.35.0 이전 버전에선 빌트인 모듈이 모두 `require('module-name')`같은 형식으로 사용되었습니다. +하지만 [많은 단점][issue-387]이 있기 때문에 현재 변경되었습니다. +하지만 오래된 앱의 호환성 유지를 위해 아직 구 버전 API를 지원하고 있습니다. + +완벽하게 모든 구 버전 API를 비활성화하려면 `ELECTRON_HIDE_INTERNAL_MODULES` 환경 변수를 설정하면 됩니다: + +```javascript +process.env.ELECTRON_HIDE_INTERNAL_MODULES = 'true' +``` + +또는 `hideInternalModules` API를 사용해도 됩니다: + +```javascript +require('electron').hideInternalModules() +``` + +[gui]: https://en.wikipedia.org/wiki/Graphical_user_interface +[main-process]: ../tutorial/quick-start.md#메인-프로세스 +[desctructuring-assignment]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment +[issue-387]: https://github.com/atom/electron/issues/387 \ No newline at end of file diff --git a/docs-translations/ko-KR/api/tray.md b/docs-translations/ko-KR/api/tray.md index 22fec3089e69..96722bb2409e 100644 --- a/docs-translations/ko-KR/api/tray.md +++ b/docs-translations/ko-KR/api/tray.md @@ -3,9 +3,10 @@ `Tray`는 OS의 알림 영역에 아이콘을 표시합니다. 보통 컨텍스트 메뉴(context menu)를 같이 사용합니다. ```javascript -var app = require('app'); -var Menu = require('menu'); -var Tray = require('tray'); +const electron = require('electron'); +const app = electron.app; +const Menu = electron.Menu; +const Tray = electron.Tray; var appIcon = null; app.on('ready', function(){ @@ -29,7 +30,7 @@ __플랫폼별 한계:__ * 앱 알림 표시기는 컨텍스트 메뉴를 가지고 있을 때만 보입니다. * Linux에서 앱 알림 표시기가 사용될 경우, `clicked` 이벤트는 무시됩니다. -이러한 이유로 Tray API가 모든 플랫폼에서 똑같이 작동하게 하고 싶다면 `clicked` 이벤트에 의존해선 안됩니다. +이러한 이유로 Tray API가 모든 플랫폼에서 똑같이 작동하게 하고 싶다면 `click` 이벤트에 의존해선 안됩니다. 그리고 언제나 컨텍스트 메뉴를 포함해야 합니다. ## Class: Tray @@ -48,7 +49,7 @@ __플랫폼별 한계:__ **참고:** 몇가지 이벤트는 특정한 플랫폼에서만 작동합니다. -### Event: 'clicked' +### Event: 'click' * `event` Event * `altKey` Boolean @@ -65,7 +66,7 @@ __플랫폼별 한계:__ __주의:__ `bounds`는 OS X 와 Windows에서만 작동합니다. -### Event: 'right-clicked' _OS X_ _Windows_ +### Event: 'right-click' _OS X_ _Windows_ * `event` Event * `altKey` Boolean @@ -80,7 +81,7 @@ __주의:__ `bounds`는 OS X 와 Windows에서만 작동합니다. 트레이 아이콘을 오른쪽 클릭될 때 호출 됩니다. -### Event: 'double-clicked' _OS X_ _Windows_ +### Event: 'double-click' _OS X_ _Windows_ * `event` Event * `altKey` Boolean @@ -97,15 +98,15 @@ __주의:__ `bounds`는 OS X 와 Windows에서만 작동합니다. ### Event: 'balloon-show' _Windows_ -알림풍선이 보여질 때 발생하는 이벤트입니다. +풍선 팝업이 보여질 때 발생하는 이벤트입니다. -### Event: 'balloon-clicked' _Windows_ +### Event: 'balloon-click' _Windows_ -알림풍선이 클릭될 때 발생하는 이벤트입니다. +풍선 팝업이 클릭될 때 발생하는 이벤트입니다. ### Event: 'balloon-closed' _Windows_ -알림풍선이 시간이 지나 사라지거나 유저가 클릭하여 닫을 때 발생하는 이벤트입니다. +풍선 팝업이 시간이 지나 사라지거나 유저가 클릭하여 닫을 때 발생하는 이벤트입니다. ### Event: 'drop' _OS X_ @@ -177,7 +178,7 @@ __주의:__ `bounds`는 OS X 와 Windows에서만 작동합니다. * `title` String * `content` String -트레이에 알림풍선을 생성합니다. +트레이에 풍선 팝업을 생성합니다. ### `Tray.popContextMenu([position])` _OS X_ _Windows_ diff --git a/docs-translations/ko-KR/api/web-frame.md b/docs-translations/ko-KR/api/web-frame.md index d09114e559c8..5b94a9a6ad71 100644 --- a/docs-translations/ko-KR/api/web-frame.md +++ b/docs-translations/ko-KR/api/web-frame.md @@ -5,7 +5,7 @@ 다음 예제는 현재 페이지를 200% 줌 합니다: ```javascript -var webFrame = require('web-frame'); +var webFrame = require('electron').webFrame; webFrame.setZoomFactor(2); ``` @@ -55,14 +55,14 @@ Input field나 text area에 철자 검사(spell checking) 제공자를 설정합 [node-spellchecker][spellchecker]를 철자 검사 제공자로 사용하는 예제입니다: ```javascript -require('web-frame').setSpellCheckProvider("en-US", true, { +webFrame.setSpellCheckProvider("en-US", true, { spellCheck: function(text) { return !(require('spellchecker').isMisspelled(text)); } }); ``` -### `webFrame.registerUrlSchemeAsSecure(scheme)` +### `webFrame.registerURLSchemeAsSecure(scheme)` * `scheme` String @@ -70,10 +70,16 @@ require('web-frame').setSpellCheckProvider("en-US", true, { 보안 스킴은 혼합된 컨텐츠 경고를 발생시키지 않습니다. 예를 들어 `https` 와 `data`는 네트워크 공격자로부터 손상될 가능성이 없기 때문에 보안 스킴이라고 할 수 있습니다. -### `webFrame.registerUrlSchemeAsBypassingCsp(scheme)` +### `webFrame.registerURLSchemeAsBypassingCSP(scheme)` * `scheme` String -현재 페이지 컨텐츠의 보안 정책에 상관없이 이 `scheme`로부터 리소스가 로드됩니다. +현재 페이지 컨텐츠의 보안 정책에 상관없이 `scheme`로부터 리소스가 로드됩니다. + +### `webFrame.registerURLSchemeAsPrivileged(scheme)` + + * `scheme` String + +보안 `scheme`를 지정합니다. 리소스와 ServiceWorker 설정에 대해 보안 정책을 우회합니다. [spellchecker]: https://github.com/atom/node-spellchecker diff --git a/docs-translations/ko-KR/api/web-view-tag.md b/docs-translations/ko-KR/api/web-view-tag.md index bb9a1305c8a9..eb40151a234d 100644 --- a/docs-translations/ko-KR/api/web-view-tag.md +++ b/docs-translations/ko-KR/api/web-view-tag.md @@ -156,7 +156,7 @@ webview.addEventListener("dom-ready", function() { }); ``` -### `.getUrl()` +### `.getURL()` 페이지의 URL을 반환합니다. @@ -376,7 +376,7 @@ Returns: * `errorCode` Integer * `errorDescription` String -* `validatedUrl` String +* `validatedURL` String `did-finish-load`와 비슷합니다. 하지만 이 이벤트는 `window.stop()`과 같은 무언가로 인해 로드에 실패했을 때 발생하는 이벤트입니다. @@ -401,8 +401,8 @@ Returns: Returns: * `status` Boolean -* `newUrl` String -* `originalUrl` String +* `newURL` String +* `originalURL` String * `httpResponseCode` Integer * `requestMethod` String * `referrer` String @@ -415,8 +415,8 @@ Returns: Returns: -* `oldUrl` String -* `newUrl` String +* `oldURL` String +* `newURL` String * `isMainFrame` Boolean 리소스를 요청하고 받는 도중에 리다이렉트가 생기면 발생하는 이벤트입니다. @@ -484,7 +484,7 @@ Returns: ```javascript webview.addEventListener('new-window', function(e) { - require('shell').openExternal(e.url); + require('electron').shell.openExternal(e.url); }); ``` @@ -522,9 +522,9 @@ webview.send('ping'); ```javascript // In guest page. -var ipc = require('ipc'); -ipc.on('ping', function() { - ipc.sendToHost('pong'); +var ipcRenderer = require('electron').ipcRenderer; +ipcRenderer.on('ping', function() { + ipcRenderer.sendToHost('pong'); }); ``` diff --git a/docs-translations/ko-KR/tutorial/application-packaging.md b/docs-translations/ko-KR/tutorial/application-packaging.md index d7a96dbb4b43..9a5e3dfb20e2 100644 --- a/docs-translations/ko-KR/tutorial/application-packaging.md +++ b/docs-translations/ko-KR/tutorial/application-packaging.md @@ -47,14 +47,14 @@ $ asar list /path/to/example.asar `asar` 아카이브에선 다음과 같이 파일을 읽을 수 있습니다: ```javascript -var fs = require('fs'); +const fs = require('fs'); fs.readFileSync('/path/to/example.asar/file.txt'); ``` 아카이브 내의 루트 디렉터리를 리스팅합니다: ```javascript -var fs = require('fs'); +const fs = require('fs'); fs.readdirSync('/path/to/example.asar'); ``` @@ -67,9 +67,9 @@ require('/path/to/example.asar/dir/module.js'); `BrowserWindow` 클래스를 이용해 원하는 웹 페이지도 표시할 수 있습니다: ```javascript -var BrowserWindow = require('browser-window'); +const BrowserWindow = require('electron').BrowserWindow; var win = new BrowserWindow({width: 800, height: 600}); -win.loadUrl('file:///path/to/example.asar/static/index.html'); +win.loadURL('file:///path/to/example.asar/static/index.html'); ``` ### Web API @@ -90,8 +90,8 @@ $.get('file:///path/to/example.asar/file.txt', function(data) { ### `asar` 아카이브를 일반 파일로 취급하기 -`asar` 아카이브의 체크섬(checksum)등을 검사하기 위해선 `asar` 아카이브를 파일 그대로 읽어들여야 할 필요가 있습니다. -이 작업을 하기 위해 `original-fs`라고 하는 빌트인 모듈을 `fs` 모듈 대신에 사용할 수 있습니다. +`asar` 아카이브의 체크섬(checksum)을 검사하는 작업등을 하기 위해선 `asar` 아카이브를 파일 그대로 읽어야 합니다. +이러한 작업을 하기 위해 `original-fs` 빌트인 모듈을 `fs` 모듈 대신에 사용할 수 있습니다. 이 모듈은 `asar` 지원이 빠져있습니다. 즉 파일 그대로를 읽어들입니다: ```javascript @@ -112,13 +112,13 @@ originalFs.readFileSync('/path/to/example.asar'); `asar` 아카이브는 디렉터리처럼 사용할 수 있도록 구현되었지만 그것은 실제 파일시스템의 디렉터리가 아닌 가상의 디렉터리입니다. 그런 이유로 몇몇 API에서 지원하는 `cwd` 옵션을 `asar` 아카이브 안의 디렉터리 경로로 지정하면 나중에 문제가 발생할 수 있습니다. -### 특정 API로 인한 예외적인 압축 해제 +### 특정 API로 인한 예외적인 아카이브 압축 해제 많은 `fs` API가 `asar` 아카이브의 압축을 해제하지 않고 바로 아카이브를 읽거나 정보를 가져올 수 있으나 -몇몇 API는 시스템의 실제 파일의 경로를 기반으로 작동하므로 이 API들을 사용할 땐 Electron은 -이 API가 원할하게 작동할 수 있도록 하기 위해 임시경로에 해당 파일들의 압축을 해제합니다. 이 작업은 약간의 오버헤드를 불러 일으킬 수 있습니다. +몇몇 API는 시스템의 실제 파일의 경로를 기반으로 작동하므로 Electron은 API가 원할하게 작동할 수 있도록 +임시 경로에 해당되는 파일의 압축을 해제합니다. 이 작업은 약간의 오버헤드를 불러 일으킬 수 있습니다. -해당하는 API 메서드는 다음과 같습니다: +위 예외에 해당하는 API 메서드는 다음과 같습니다: * `child_process.execFile` * `fs.open` @@ -127,7 +127,7 @@ originalFs.readFileSync('/path/to/example.asar'); ### `fs.stat`의 잘못된 스테이터스 정보 -`fs.stat` 로 부터 반환되는 `Stats` 객체와 비슷한 API들은 `asar` 아카이브를 타겟으로 할 경우 예측된 디렉터리 피일 정보를 가집니다. +`fs.stat` 로 부터 반환되는 `Stats` 객체와 비슷한 API들은 `asar` 아카이브를 타겟으로 할 경우 예측된 디렉터리 파일 정보를 가집니다. 왜냐하면 아카이브의 디렉터리 경로는 실제 파일시스템에 존재하지 않기 때문입니다. 그러한 이유로 파일 크기와 파일 타입 등을 확인할 때 `Stats` 객체를 신뢰해선 안됩니다. @@ -145,6 +145,6 @@ $ asar pack app app.asar --unpack *.node 커맨드를 실행한 후 같은 디렉터리에 `app.asar` 파일 외에 `app.asar.unpacked` 폴더가 같이 생성됩니다. 이 폴더안에 unpack 옵션에서 설정한 파일들이 압축이 풀린 상태로 포함되어 있습니다. -유저에게 어플리케이션을 배포할 때 반드시 해당 폴더도 같이 배포하여야합니다. +사용자에게 어플리케이션을 배포할 때 반드시 해당 폴더도 같이 배포해야 합니다. [asar]: https://github.com/atom/asar diff --git a/docs-translations/ko-KR/tutorial/desktop-environment-integration.md b/docs-translations/ko-KR/tutorial/desktop-environment-integration.md index 1212cbb9c433..fe0a6450bc11 100644 --- a/docs-translations/ko-KR/tutorial/desktop-environment-integration.md +++ b/docs-translations/ko-KR/tutorial/desktop-environment-integration.md @@ -28,7 +28,7 @@ myNotification.onclick = function () { * Windows 10에선 "아무 문제 없이 잘" 작동합니다. * Windows 8.1과 8에선 [Application User Model ID][app-user-model-id]로 바로가기를 만들어 놔야 합니다. 이 바로가기는 반드시 시작 화면에 설치되어 있어야 합니다. 참고로 반드시 시작 화면에 고정 할 필요는 없습니다. -* Windows 7과 그 이하 버전은 데스크톱 알림을 지원하지 않습니다. 혹시 "풍선 알림" 기능을 찾는다면 [Tray API](tray-balloon)를 사용하세요. +* Windows 7과 그 이하 버전은 데스크톱 알림을 지원하지 않습니다. 혹시 "풍선 팝업 알림" 기능을 찾는다면 [Tray API](tray-balloon)를 사용하세요. 이미지를 데스크톱 알림에 사용하려면 알림 옵션의 `icon` 속성에 로컬 이미지 파일(`png` 권장)을 지정하면 됩니다. 데스크톱 알림은 잘못된 경로를 지정하거나 `http/https` 기반의 URL을 지정해도 이미지가 보이지 않을 뿐 정상 작동합니다. @@ -70,7 +70,6 @@ __어플리케이션 dock menu:__ 파일을 최근 문서에 추가하려면 [app.addRecentDocument][addrecentdocument] API를 사용할 수 있습니다: ```javascript -var app = require('app'); app.addRecentDocument('/Users/USERNAME/Desktop/work.type'); ``` @@ -104,8 +103,10 @@ __Terminal.app의 dock menu:__ 커스텀 dock menu를 설정하려면 `app.dock.setMenu` API를 사용하면 됩니다. OS X에서만 사용 가능합니다: ```javascript -var app = require('app'); -var Menu = require('menu'); +const electron = require('electron'); +const app = electron.app; +const Menu = electron.Menu; + var dockMenu = Menu.buildFromTemplate([ { label: 'New Window', click: function() { console.log('New Window'); } }, { label: 'New Window with Settings', submenu: [ @@ -144,7 +145,6 @@ OS X의 dock menu(진짜 메뉴)와는 달리 Windows의 사용자 작업은 어 사용자 작업을 설정하려면 [app.setUserTasks][setusertaskstasks] 메서드를 통해 구현할 수 있습니다: ```javascript -var app = require('app'); app.setUserTasks([ { program: process.execPath, @@ -187,8 +187,9 @@ __Windows Media Player의 섬네일 툴바:__ [BrowserWindow.setThumbarButtons][setthumbarbuttons] API를 통해 어플리케이션에 섬네일 툴바를 설정할 수 있습니다: ```javascript -var BrowserWindow = require('browser-window'); -var path = require('path'); +const BrowserWindow = require('electron').BrowserWindow; +const path = require('path'); + var win = new BrowserWindow({ width: 800, height: 600 diff --git a/docs-translations/ko-KR/tutorial/devtools-extension.md b/docs-translations/ko-KR/tutorial/devtools-extension.md index 659c769dde34..04b592955cdc 100644 --- a/docs-translations/ko-KR/tutorial/devtools-extension.md +++ b/docs-translations/ko-KR/tutorial/devtools-extension.md @@ -22,13 +22,14 @@ $ git clone --recursive https://github.com/facebook/react-devtools.git 그리고 개발자 콘솔에서 다음 코드를 입력하면 확장 기능을 로드할 수 있습니다: ```javascript -require('remote').require('browser-window').addDevToolsExtension('/some-directory/react-devtools/shells/chrome'); +const BrowserWindow = require('electron').remote.BrowserWindow; +BrowserWindow.addDevToolsExtension('/some-directory/react-devtools/shells/chrome'); ``` 확장 기능을 언로드 하고 콘솔을 다시 열 때 해당 확장 기능이 로드되지 않도록 하려면 `BrowserWindow.removeDevToolsExtension` API를 사용하면 됩니다: ```javascript -require('remote').require('browser-window').removeDevToolsExtension('React Developer Tools'); +BrowserWindow.removeDevToolsExtension('React Developer Tools'); ``` ## 개발자 콘솔 확장 기능의 구성 형식 diff --git a/docs-translations/ko-KR/tutorial/online-offline-events.md b/docs-translations/ko-KR/tutorial/online-offline-events.md index 5950d40525e2..0b989516a6ab 100644 --- a/docs-translations/ko-KR/tutorial/online-offline-events.md +++ b/docs-translations/ko-KR/tutorial/online-offline-events.md @@ -5,13 +5,14 @@ _main.js_ ```javascript -var app = require('app'); -var BrowserWindow = require('browser-window'); -var onlineStatusWindow; +const electron = require('electron'); +const app = electron.app; +const BrowserWindow = electron.BrowserWindow; +var onlineStatusWindow; app.on('ready', function() { onlineStatusWindow = new BrowserWindow({ width: 0, height: 0, show: false }); - onlineStatusWindow.loadUrl('file://' + __dirname + '/online-status.html'); + onlineStatusWindow.loadURL('file://' + __dirname + '/online-status.html'); }); ``` @@ -43,14 +44,15 @@ _online-status.html_ _main.js_ ```javascript -var app = require('app'); -var ipcMain = require('ipc-main'); -var BrowserWindow = require('browser-window'); -var onlineStatusWindow; +const electron = require('electron'); +const app = electron.app; +const ipcMain = electron.ipcMain; +const BrowserWindow = electron.BrowserWindow; +var onlineStatusWindow; app.on('ready', function() { onlineStatusWindow = new BrowserWindow({ width: 0, height: 0, show: false }); - onlineStatusWindow.loadUrl('file://' + __dirname + '/online-status.html'); + onlineStatusWindow.loadURL('file://' + __dirname + '/online-status.html'); }); ipcMain.on('online-status-changed', function(event, status) { @@ -65,7 +67,7 @@ _online-status.html_ + + +``` + +### `webContents.enableDeviceEmulation(parameters)` + +`parameters` Object, properties: + +* `screenPosition` String - 에뮬레이트 할 화면 종료를 지정합니다 + (default: `desktop`) + * `desktop` + * `mobile` +* `screenSize` Object - 에뮬레이트 화면의 크기를 지정합니다 (screenPosition == mobile) + * `width` Integer - 에뮬레이트 화면의 너비를 지정합니다 + * `height` Integer - 에뮬레이트 화면의 높이를 지정합니다 +* `viewPosition` Object - 화면에서 뷰의 위치 + (screenPosition == mobile) (default: `{x: 0, y: 0}`) + * `x` Integer - 좌상단 모서리로부터의 x 축의 오프셋 + * `y` Integer - 좌상단 모서리로부터의 y 축의 오프셋 +* `deviceScaleFactor` Integer - 디바이스의 스케일 팩터(scale factor)를 지정합니다. + (0일 경우 기본 디바이스 스케일 팩터를 기본으로 사용합니다) (default: `0`) +* `viewSize` Object - 에뮬레이트 된 뷰의 크기를 지정합니다 (빈 값은 오버라이드 하지 않는 다는 + 것을 의미합니다) + * `width` Integer - 에뮬레이트 된 뷰의 너비를 지정합니다 + * `height` Integer - 에뮬레이트 된 뷰의 높이를 지정합니다 +* `fitToView` Boolean - 에뮬레이트의 뷰가 사용 가능한 공간에 맞추어 스케일 다운 될지 여부를 + 지정합니다 (기본값: `false`) +* `offset` Object - 사용 가능한 공간에서 에뮬레이트 된 뷰의 오프셋을 지정합니다 + (fit to view 모드 외에서) (기본값: `{x: 0, y: 0}`) + * `x` Float - 좌상단 모서리에서 x 축의 오프셋을 지정합니다 + * `y` Float - 좌상단 모서리에서 y 축의 오프셋을 지정합니다 +* `scale` Float - 사용 가능한 공간에서 에뮬레이드 된 뷰의 스케일 (fit to view 모드 외에서) + (기본값: `1`) + +주어진 파라미터로 디바이스 에뮬레이션을 사용합니다. + +### `webContents.disableDeviceEmulation()` + +`webContents.enableDeviceEmulation`로 사용가능해진 디바이스 에뮬레이선을 비활성화 합니다. + +### `webContents.sendInputEvent(event)` + +* `event` Object + * `type` String (**required**) - 이벤트의 타입. 다음 값들이 가능합니다. `mouseDown`, + `mouseUp`, `mouseEnter`, `mouseLeave`, `contextMenu`, `mouseWheel`, + `keyDown`, `keyUp`, `char`. + * `modifiers` Array - 이벤트의 수정자(modifier)들에 대한 배열. 다음 값들을 포함 할 수 + 있습니다. `shift`, `control`, `alt`, `meta`, `isKeypad`, `isAutoRepeat`, + `leftButtonDown`, `middleButtonDown`, `rightButtonDown`, `capsLock`, + `numLock`, `left`, `right`. + +input `event`를 페이지로 보냅니다. + +키보드 이벤트들에 대해서는 `event` 객체는 다음 속성들을 추가적으로 가지고 있습니다: + +* `keyCode` String (**required**) - 키보드 이벤트로 보낼 수 있는 단일 캐릭터. 모든 UTF-8가 + 사용 가능합니다. + +마우스 이벤트들에 대해서는 `event` 객체는 다음 속성들을 추가적으로 가지고 있습니다: + +* `x` Integer (**required**) +* `y` Integer (**required**) +* `button` String - 눌린 버튼. 다음 값들이 가능합니다. `left`, `middle`, `right` +* `globalX` Integer +* `globalY` Integer +* `movementX` Integer +* `movementY` Integer +* `clickCount` Integer + +`mouseWheel` 이벤트에 대해서는 `event` 객체는 다음 속성들을 추가적으로 가지고 있습니다: + +* `deltaX` Integer +* `deltaY` Integer +* `wheelTicksX` Integer +* `wheelTicksY` Integer +* `accelerationRatioX` Integer +* `accelerationRatioY` Integer +* `hasPreciseScrollingDeltas` Boolean +* `canScroll` Boolean + +### `webContents.beginFrameSubscription(callback)` + +* `callback` Function + +프레젠테이션 이벤트들과 캡쳐된 프레임들에 대한 구독을 시작하면 `callback`이 프레젠테이션 이벤트가 +발생할 때 `callback(frameBuffer)`과 같은 형식으로 호출됩니다. + +`frameBuffer`는 raw 픽셀 데이터를 포함한 `Buffer`입니다. 대부분의 기계에서 픽셀 데이터는 32bit +BGRA 포맷으로 효율적으로 저장됩니다. 하지만 실제 재프리젠테이션은 프로세서의 endianness에 의존성을 +가지고 있습니다(대부분의 현재 프로세스들은 little-endian입니다. big-endian 프로세서들를 가진 +기계들에서 data는 32bit ARGB format입니다). + +### `webContents.endFrameSubscription()` + +프레임 프레젠테이션 이벤트들에 대한 구독을 중지합니다. + +## Instance Properties + +`WebContents`객체들은 다음 속성들을 가지고 있습니다: + +### `webContents.devToolsWebContents` + +이 `WebContents`에 대한 DevTools의 `WebContents`를 가져옵니다. + +**Note:** 사용자가 절대로 이 객체를 저장해서는 안됩니다. 그럴경우 DevTools가 닫혔을 때, `null`이 +될 수도 있습니다. + +### `webContents.savePage(fullPath, saveType, callback)` + +* `fullPath` String - 전체 파일 경로. +* `saveType` String - 저장 타입을 지정합니다. + * `HTMLOnly` - 페이지의 HTML만 저장합니다. + * `HTMLComplete` - 페이지의 완성된 HTML을 저장합니다. + * `MHTML` - 페이지의 완성된 HTML을 MHTML로 저장합니다. +* `callback` Function - `function(error) {}`. + * `error` Error + +만약 페이지를 저장하는 프로세스가 성공적으로 끝났을 경우 true를 반환합니다. + +```javascript +win.loadURL('https://github.com'); + +win.webContents.on('did-finish-load', function() { + win.webContents.savePage('/tmp/test.html', 'HTMLComplete', function(error) { + if (!error) + console.log("Save page successfully"); + }); +}); +``` From 5995451366af07debb53d30765e042cd34c2e7ae Mon Sep 17 00:00:00 2001 From: Dongjoon Hyun Date: Tue, 17 Nov 2015 16:49:08 +0900 Subject: [PATCH 184/249] Add missing translations --- docs-translations/ko-KR/api/menu-item.md | 29 ++++++++++++------------ 1 file changed, 14 insertions(+), 15 deletions(-) diff --git a/docs-translations/ko-KR/api/menu-item.md b/docs-translations/ko-KR/api/menu-item.md index e4c5c677676d..fc5539c8cdf1 100644 --- a/docs-translations/ko-KR/api/menu-item.md +++ b/docs-translations/ko-KR/api/menu-item.md @@ -25,11 +25,10 @@ * `id` String - 현재 메뉴 아이템에 대해 유일키를 지정합니다. 이 키는 이후 `position` 옵션에서 사용할 수 있습니다. * `position` String - 미리 지정한 `id`를 이용하여 메뉴 아이템의 위치를 세밀하게 조정합니다. -When creating menu items, it is recommended to specify `role` instead of -manually implementing the behavior if there is matching action, so menu can have -best native experience. +메뉴 아이템을 생성할 때, 매칭되는 액션이 있다면 수동으로 직접 구현하는 대신 `role`을 설정하여, +고유 OS 경험을 최대한 살릴 것을 권장합니다. -The `role` property can have following values: +`role` 속성은 다음 값을 가질 수 있습니다.: * `undo` * `redo` @@ -37,16 +36,16 @@ The `role` property can have following values: * `copy` * `paste` * `selectall` -* `minimize` - Minimize current window -* `close` - Close current window +* `minimize` - 현재 윈도우를 최소화 합니다. +* `close` - 현재 윈도우를 닫습니다. -On OS X `role` can also have following additional values: +OS X에서 `role`은 다음 값을 추가로 가질 수 있습니다. -* `about` - Map to the `orderFrontStandardAboutPanel` action -* `hide` - Map to the `hide` action -* `hideothers` - Map to the `hideOtherApplications` action -* `unhide` - Map to the `unhideAllApplications` action -* `front` - Map to the `arrangeInFront` action -* `window` - The submenu is a "Window" menu -* `help` - The submenu is a "Help" menu -* `services` - The submenu is a "Services" menu +* `about` - `orderFrontStandardAboutPanel` 액션에 매핑합니다. +* `hide` - `hide` 액션에 매핑합니다. +* `hideothers` - `hideOtherApplications` 액션에 매핑합니다. +* `unhide` - `unhideAllApplications` 액션에 매핑합니다. +* `front` - `arrangeInFront` 액션에 매핑합니다. +* `window` - 부메뉴가 "Window" 메뉴입니다. +* `help` - 부메뉴가 "Help" 메뉴입니다. +* `services` - 부메뉴가 "Services" 메뉴입니다. From 855c1ead008377dab4ecca20d5589099c807ab45 Mon Sep 17 00:00:00 2001 From: Moises lopes ferreira Date: Fri, 13 Nov 2015 11:35:13 -0200 Subject: [PATCH 185/249] Portuguese translation of coding-style.md --- .../pt-BR/development/coding-style.md | 29 +++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 docs-translations/pt-BR/development/coding-style.md diff --git a/docs-translations/pt-BR/development/coding-style.md b/docs-translations/pt-BR/development/coding-style.md new file mode 100644 index 000000000000..f3b4d6d58f37 --- /dev/null +++ b/docs-translations/pt-BR/development/coding-style.md @@ -0,0 +1,29 @@ +# Estilo de Codificação + +Estas são as diretrizes de estilo para codificar no Electron. + +## C++ and Python + +Para C ++ e Python, seguimos os padrões do projeto Chromium [Estilo de Codificação](http://www.chromium.org/developers/coding-style). Há também um +script `script/cpplint.py` para verificar se todos os arquivos estão em conformidade. + +A versão Python que estamos usando agora é a Python 2.7. + +O código C ++ usa do Chromium's um monte de tipos e abstrações, por isso é recomendada para se familiarizar com eles. Um bom lugar para começar com a documentação do Chromium's [Important Abstractions and Data Structures](https://www.chromium.org/developers/coding-style/important-abstractions-and-data-structures). O documento menciona alguns tipos especiais, com escopo tipos (que automaticamente libera sua memória quando sai do escopo), registrando mecanismos etc. + +## CoffeeScript + +For CoffeeScript, we follow GitHub's [Style +Guide](https://github.com/styleguide/javascript) and the following rules: + +Para CoffeeScript, seguimos o estilo do GitHub [Guia de Estilo] (https://github.com/styleguide/javascript) com as seguintes regras: + +* Os arquivos devem **NÃO DEVEM** com nova linha no final, porque queremos corresponder aos padrões de estilo Google. + +* Os nomes dos arquivos devem ser concatenados com o `-` em vez de`_`, por exemplo, `file-name.coffee` em vez de`file_name.coffee`, porque no [github/atom](https://github.com/github/atom) os nomes dos módulos são geralmente em o formulário `module-name`. Esta regra só se aplica aos arquivos com extensão `.coffee`. +* +## API Names + +Ao criar uma nova API, devemos preferencialmente utilizar métodos getters e setters em vez de +estilo de uma função do jQuery. Por exemplo, `.getText()` e `.setText(text)` utilize `.text([text])`. Existe uma +[discussão](https://github.com/atom/electron/issues/46) sobre este assunto. From 217311ef213ba1347506cd165b30447fd789f130 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Tue, 17 Nov 2015 19:00:33 +0800 Subject: [PATCH 186/249] No need to use weak reference Ref-counting manages everything. --- atom/browser/api/atom_api_session.cc | 5 +---- atom/browser/atom_cert_verifier.cc | 8 +++----- atom/browser/atom_cert_verifier.h | 5 +---- 3 files changed, 5 insertions(+), 13 deletions(-) diff --git a/atom/browser/api/atom_api_session.cc b/atom/browser/api/atom_api_session.cc index 07b9b68a94d7..579b64bf4a7d 100644 --- a/atom/browser/api/atom_api_session.cc +++ b/atom/browser/api/atom_api_session.cc @@ -241,10 +241,7 @@ void SetProxyInIO(net::URLRequestContextGetter* getter, void PassVerificationResult( scoped_refptr request, bool success) { - int result = net::OK; - if (!success) - result = net::ERR_FAILED; - request->ContinueWithResult(result); + request->ContinueWithResult(success ? net::OK : net::ERR_FAILED); } } // namespace diff --git a/atom/browser/atom_cert_verifier.cc b/atom/browser/atom_cert_verifier.cc index e56e611faa81..0ff0d1e4a547 100644 --- a/atom/browser/atom_cert_verifier.cc +++ b/atom/browser/atom_cert_verifier.cc @@ -66,8 +66,7 @@ void AtomCertVerifier::CertVerifyRequest::DelegateToDefaultVerifier() { key_.flags, crl_set_.get(), verify_result_, - base::Bind(&CertVerifyRequest::RunResult, - weak_ptr_factory_.GetWeakPtr()), + base::Bind(&CertVerifyRequest::RunResult, this), out_req_, net_log_); @@ -86,15 +85,14 @@ void AtomCertVerifier::CertVerifyRequest::ContinueWithResult(int result) { if (result != net::ERR_IO_PENDING) { BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, base::Bind(&CertVerifyRequest::RunResult, - weak_ptr_factory_.GetWeakPtr(), + this, result)); return; } BrowserThread::PostTask( BrowserThread::IO, FROM_HERE, - base::Bind(&CertVerifyRequest::DelegateToDefaultVerifier, - weak_ptr_factory_.GetWeakPtr())); + base::Bind(&CertVerifyRequest::DelegateToDefaultVerifier, this)); } AtomCertVerifier::AtomCertVerifier() diff --git a/atom/browser/atom_cert_verifier.h b/atom/browser/atom_cert_verifier.h index e5560ff82fe4..50446dd38bd2 100644 --- a/atom/browser/atom_cert_verifier.h +++ b/atom/browser/atom_cert_verifier.h @@ -55,8 +55,7 @@ class AtomCertVerifier : public net::CertVerifier { verify_result_(verify_result), out_req_(out_req), net_log_(net_log), - handled_(false), - weak_ptr_factory_(this) { + handled_(false) { } void RunResult(int result); @@ -91,8 +90,6 @@ class AtomCertVerifier : public net::CertVerifier { std::vector callbacks_; bool handled_; - base::WeakPtrFactory weak_ptr_factory_; - DISALLOW_COPY_AND_ASSIGN(CertVerifyRequest); }; From 37f355724a4557e8af4e3d9e62ff5633b16dedfb Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Tue, 17 Nov 2015 19:03:09 +0800 Subject: [PATCH 187/249] Move AtomCertVerifier to atom/browser/net --- atom/browser/api/atom_api_session.h | 2 +- atom/browser/atom_browser_context.cc | 2 +- atom/browser/{ => net}/atom_cert_verifier.cc | 2 +- atom/browser/{ => net}/atom_cert_verifier.h | 6 +++--- filenames.gypi | 4 ++-- 5 files changed, 8 insertions(+), 8 deletions(-) rename atom/browser/{ => net}/atom_cert_verifier.cc (99%) rename atom/browser/{ => net}/atom_cert_verifier.h (96%) diff --git a/atom/browser/api/atom_api_session.h b/atom/browser/api/atom_api_session.h index 05d67b8842ef..db72558db473 100644 --- a/atom/browser/api/atom_api_session.h +++ b/atom/browser/api/atom_api_session.h @@ -8,7 +8,7 @@ #include #include "atom/browser/api/trackable_object.h" -#include "atom/browser/atom_cert_verifier.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" diff --git a/atom/browser/atom_browser_context.cc b/atom/browser/atom_browser_context.cc index b1092757ae48..ab3ab1bd139e 100644 --- a/atom/browser/atom_browser_context.cc +++ b/atom/browser/atom_browser_context.cc @@ -5,10 +5,10 @@ #include "atom/browser/atom_browser_context.h" #include "atom/browser/atom_browser_main_parts.h" -#include "atom/browser/atom_cert_verifier.h" #include "atom/browser/atom_download_manager_delegate.h" #include "atom/browser/atom_ssl_config_service.h" #include "atom/browser/browser.h" +#include "atom/browser/net/atom_cert_verifier.h" #include "atom/browser/net/atom_url_request_job_factory.h" #include "atom/browser/net/asar/asar_protocol_handler.h" #include "atom/browser/net/http_protocol_handler.h" diff --git a/atom/browser/atom_cert_verifier.cc b/atom/browser/net/atom_cert_verifier.cc similarity index 99% rename from atom/browser/atom_cert_verifier.cc rename to atom/browser/net/atom_cert_verifier.cc index 0ff0d1e4a547..65e558280822 100644 --- a/atom/browser/atom_cert_verifier.cc +++ b/atom/browser/net/atom_cert_verifier.cc @@ -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/atom_cert_verifier.h" +#include "atom/browser/net/atom_cert_verifier.h" #include "atom/browser/browser.h" #include "atom/common/native_mate_converters/net_converter.h" diff --git a/atom/browser/atom_cert_verifier.h b/atom/browser/net/atom_cert_verifier.h similarity index 96% rename from atom/browser/atom_cert_verifier.h rename to atom/browser/net/atom_cert_verifier.h index 50446dd38bd2..52b6fb5303e6 100644 --- a/atom/browser/atom_cert_verifier.h +++ b/atom/browser/net/atom_cert_verifier.h @@ -2,8 +2,8 @@ // Use of this source code is governed by the MIT license that can be // found in the LICENSE file. -#ifndef ATOM_BROWSER_ATOM_CERT_VERIFIER_H_ -#define ATOM_BROWSER_ATOM_CERT_VERIFIER_H_ +#ifndef ATOM_BROWSER_NET_ATOM_CERT_VERIFIER_H_ +#define ATOM_BROWSER_NET_ATOM_CERT_VERIFIER_H_ #include #include @@ -159,4 +159,4 @@ class AtomCertVerifier : public net::CertVerifier { } // namespace atom -#endif // ATOM_BROWSER_ATOM_CERT_VERIFIER_H_ +#endif // ATOM_BROWSER_NET_ATOM_CERT_VERIFIER_H_ diff --git a/filenames.gypi b/filenames.gypi index fd8856abd4d0..92e0a2c204fb 100644 --- a/filenames.gypi +++ b/filenames.gypi @@ -131,8 +131,6 @@ 'atom/browser/atom_download_manager_delegate.h', 'atom/browser/atom_browser_main_parts.cc', 'atom/browser/atom_browser_main_parts.h', - 'atom/browser/atom_cert_verifier.cc', - 'atom/browser/atom_cert_verifier.h', 'atom/browser/atom_browser_main_parts_mac.mm', 'atom/browser/atom_browser_main_parts_posix.cc', 'atom/browser/atom_javascript_dialog_manager.cc', @@ -175,6 +173,8 @@ 'atom/browser/net/asar/asar_protocol_handler.h', 'atom/browser/net/asar/url_request_asar_job.cc', 'atom/browser/net/asar/url_request_asar_job.h', + 'atom/browser/net/atom_cert_verifier.cc', + 'atom/browser/net/atom_cert_verifier.h', 'atom/browser/net/atom_url_request_job_factory.cc', 'atom/browser/net/atom_url_request_job_factory.h', 'atom/browser/net/http_protocol_handler.cc', From ea1e4160eace08e8fb216af6a6413baaa7577520 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Tue, 17 Nov 2015 19:05:38 +0800 Subject: [PATCH 188/249] Move AtomSSLConfigService to atom/browser/net --- atom/browser/atom_browser_context.cc | 2 +- atom/browser/{ => net}/atom_ssl_config_service.cc | 2 +- atom/browser/{ => net}/atom_ssl_config_service.h | 6 +++--- filenames.gypi | 4 ++-- 4 files changed, 7 insertions(+), 7 deletions(-) rename atom/browser/{ => net}/atom_ssl_config_service.cc (97%) rename atom/browser/{ => net}/atom_ssl_config_service.h (76%) diff --git a/atom/browser/atom_browser_context.cc b/atom/browser/atom_browser_context.cc index ab3ab1bd139e..08c799962728 100644 --- a/atom/browser/atom_browser_context.cc +++ b/atom/browser/atom_browser_context.cc @@ -6,9 +6,9 @@ #include "atom/browser/atom_browser_main_parts.h" #include "atom/browser/atom_download_manager_delegate.h" -#include "atom/browser/atom_ssl_config_service.h" #include "atom/browser/browser.h" #include "atom/browser/net/atom_cert_verifier.h" +#include "atom/browser/net/atom_ssl_config_service.h" #include "atom/browser/net/atom_url_request_job_factory.h" #include "atom/browser/net/asar/asar_protocol_handler.h" #include "atom/browser/net/http_protocol_handler.h" diff --git a/atom/browser/atom_ssl_config_service.cc b/atom/browser/net/atom_ssl_config_service.cc similarity index 97% rename from atom/browser/atom_ssl_config_service.cc rename to atom/browser/net/atom_ssl_config_service.cc index 0a47067b0a68..2b3143e93cb4 100644 --- a/atom/browser/atom_ssl_config_service.cc +++ b/atom/browser/net/atom_ssl_config_service.cc @@ -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/atom_ssl_config_service.h" +#include "atom/browser/net/atom_ssl_config_service.h" #include #include diff --git a/atom/browser/atom_ssl_config_service.h b/atom/browser/net/atom_ssl_config_service.h similarity index 76% rename from atom/browser/atom_ssl_config_service.h rename to atom/browser/net/atom_ssl_config_service.h index 3fa91c62c438..2e3ac4f6c597 100644 --- a/atom/browser/atom_ssl_config_service.h +++ b/atom/browser/net/atom_ssl_config_service.h @@ -2,8 +2,8 @@ // Use of this source code is governed by the MIT license that can be // found in the LICENSE file. -#ifndef ATOM_BROWSER_ATOM_SSL_CONFIG_SERVICE_H_ -#define ATOM_BROWSER_ATOM_SSL_CONFIG_SERVICE_H_ +#ifndef ATOM_BROWSER_NET_ATOM_SSL_CONFIG_SERVICE_H_ +#define ATOM_BROWSER_NET_ATOM_SSL_CONFIG_SERVICE_H_ #include "net/ssl/ssl_config_service.h" @@ -25,4 +25,4 @@ class AtomSSLConfigService : public net::SSLConfigService { } // namespace atom -#endif // ATOM_BROWSER_ATOM_SSL_CONFIG_SERVICE_H_ +#endif // ATOM_BROWSER_NET_ATOM_SSL_CONFIG_SERVICE_H_ diff --git a/filenames.gypi b/filenames.gypi index 92e0a2c204fb..7e1f3e1827e0 100644 --- a/filenames.gypi +++ b/filenames.gypi @@ -141,8 +141,6 @@ 'atom/browser/atom_resource_dispatcher_host_delegate.h', 'atom/browser/atom_speech_recognition_manager_delegate.cc', 'atom/browser/atom_speech_recognition_manager_delegate.h', - 'atom/browser/atom_ssl_config_service.cc', - 'atom/browser/atom_ssl_config_service.h', 'atom/browser/bridge_task_runner.cc', 'atom/browser/bridge_task_runner.h', 'atom/browser/browser.cc', @@ -175,6 +173,8 @@ 'atom/browser/net/asar/url_request_asar_job.h', 'atom/browser/net/atom_cert_verifier.cc', 'atom/browser/net/atom_cert_verifier.h', + 'atom/browser/net/atom_ssl_config_service.cc', + 'atom/browser/net/atom_ssl_config_service.h', 'atom/browser/net/atom_url_request_job_factory.cc', 'atom/browser/net/atom_url_request_job_factory.h', 'atom/browser/net/http_protocol_handler.cc', From e3517b701e0f1d18a965cb8f67888baddb8645ce Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Tue, 17 Nov 2015 19:44:55 +0800 Subject: [PATCH 189/249] Create a new CertVerifierRequest for each request It greatly simplifies the code. --- atom/browser/api/atom_api_session.cc | 3 +- atom/browser/net/atom_cert_verifier.cc | 129 ++++--------------------- atom/browser/net/atom_cert_verifier.h | 105 ++++++-------------- 3 files changed, 48 insertions(+), 189 deletions(-) diff --git a/atom/browser/api/atom_api_session.cc b/atom/browser/api/atom_api_session.cc index 579b64bf4a7d..3ac36abf5318 100644 --- a/atom/browser/api/atom_api_session.cc +++ b/atom/browser/api/atom_api_session.cc @@ -267,7 +267,7 @@ void Session::RequestCertVerification( bool prevent_default = Emit( "verify-certificate", request->hostname(), - request->certificate(), + make_scoped_refptr(request->cert()), base::Bind(&PassVerificationResult, request)); if (!prevent_default) @@ -294,6 +294,7 @@ bool Session::IsDestroyed() const { } void Session::Destroy() { + browser_context_->cert_verifier()->SetDelegate(nullptr); browser_context_ = nullptr; } diff --git a/atom/browser/net/atom_cert_verifier.cc b/atom/browser/net/atom_cert_verifier.cc index 65e558280822..dcfe29afddad 100644 --- a/atom/browser/net/atom_cert_verifier.cc +++ b/atom/browser/net/atom_cert_verifier.cc @@ -6,74 +6,15 @@ #include "atom/browser/browser.h" #include "atom/common/native_mate_converters/net_converter.h" -#include "base/sha1.h" -#include "base/stl_util.h" #include "content/public/browser/browser_thread.h" #include "net/base/net_errors.h" +#include "net/cert/crl_set.h" +#include "net/cert/x509_certificate.h" using content::BrowserThread; namespace atom { -AtomCertVerifier::RequestParams::RequestParams( - const net::SHA1HashValue cert_fingerprint, - const net::SHA1HashValue ca_fingerprint, - const std::string& hostname_arg, - const std::string& ocsp_response_arg, - int flags_arg) - : hostname(hostname_arg), - ocsp_response(ocsp_response_arg), - flags(flags_arg) { - hash_values.reserve(3); - net::SHA1HashValue ocsp_hash; - base::SHA1HashBytes( - reinterpret_cast(ocsp_response.data()), - ocsp_response.size(), ocsp_hash.data); - hash_values.push_back(ocsp_hash); - hash_values.push_back(cert_fingerprint); - hash_values.push_back(ca_fingerprint); -} - -bool AtomCertVerifier::RequestParams::operator<( - const RequestParams& other) const { - if (flags != other.flags) - return flags < other.flags; - if (hostname != other.hostname) - return hostname < other.hostname; - return std::lexicographical_compare( - hash_values.begin(), - hash_values.end(), - other.hash_values.begin(), - other.hash_values.end(), - net::SHA1HashValueLessThan()); -} - -void AtomCertVerifier::CertVerifyRequest::RunResult(int result) { - DCHECK_CURRENTLY_ON(BrowserThread::IO); - - for (auto& callback : callbacks_) - callback.Run(result); - cert_verifier_->RemoveRequest(this); -} - -void AtomCertVerifier::CertVerifyRequest::DelegateToDefaultVerifier() { - DCHECK_CURRENTLY_ON(BrowserThread::IO); - - int rv = cert_verifier_->default_cert_verifier()->Verify( - certificate_.get(), - key_.hostname, - key_.ocsp_response, - key_.flags, - crl_set_.get(), - verify_result_, - base::Bind(&CertVerifyRequest::RunResult, this), - out_req_, - net_log_); - - if (rv != net::ERR_IO_PENDING) - RunResult(rv); -} - void AtomCertVerifier::CertVerifyRequest::ContinueWithResult(int result) { DCHECK_CURRENTLY_ON(BrowserThread::UI); @@ -84,9 +25,7 @@ void AtomCertVerifier::CertVerifyRequest::ContinueWithResult(int result) { if (result != net::ERR_IO_PENDING) { BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, - base::Bind(&CertVerifyRequest::RunResult, - this, - result)); + base::Bind(callback_, result)); return; } @@ -95,6 +34,15 @@ void AtomCertVerifier::CertVerifyRequest::ContinueWithResult(int result) { base::Bind(&CertVerifyRequest::DelegateToDefaultVerifier, this)); } +void AtomCertVerifier::CertVerifyRequest::DelegateToDefaultVerifier() { + DCHECK_CURRENTLY_ON(BrowserThread::IO); + int result = cert_verifier_->default_cert_verifier_->Verify( + cert_.get(), hostname_, ocsp_response_, flags_, crl_set_.get(), + verify_result_, callback_, out_req_, net_log_); + if (result != net::ERR_IO_PENDING) + callback_.Run(result); +} + AtomCertVerifier::AtomCertVerifier() : delegate_(nullptr) { default_cert_verifier_.reset(net::CertVerifier::CreateDefault()); @@ -118,32 +66,13 @@ int AtomCertVerifier::Verify( if (callback.is_null() || !verify_result || hostname.empty() || !delegate_) return net::ERR_INVALID_ARGUMENT; - const RequestParams key(cert->fingerprint(), - cert->ca_fingerprint(), - hostname, - ocsp_response, - flags); - - CertVerifyRequest* request = FindRequest(key); - - if (!request) { - request = new CertVerifyRequest(this, - key, - cert, - crl_set, - verify_result, - out_req, - net_log); - requests_.insert(make_scoped_refptr(request)); - - BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, - base::Bind(&Delegate::RequestCertVerification, - base::Unretained(delegate_), - make_scoped_refptr(request))); - } - - request->AddCompletionCallback(callback); - + CertVerifyRequest* request = new CertVerifyRequest( + this, cert, hostname, ocsp_response, flags, crl_set, verify_result, + callback, out_req, net_log); + BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, + base::Bind(&Delegate::RequestCertVerification, + base::Unretained(delegate_), + make_scoped_refptr(request))); return net::ERR_IO_PENDING; } @@ -151,24 +80,4 @@ bool AtomCertVerifier::SupportsOCSPStapling() { return true; } -AtomCertVerifier::CertVerifyRequest* AtomCertVerifier::FindRequest( - const RequestParams& key) { - DCHECK_CURRENTLY_ON(BrowserThread::IO); - - auto it = std::lower_bound(requests_.begin(), - requests_.end(), - key, - CertVerifyRequestToRequestParamsComparator()); - if (it != requests_.end() && !(key < (*it)->key())) - return (*it).get(); - return nullptr; -} - -void AtomCertVerifier::RemoveRequest(CertVerifyRequest* request) { - DCHECK_CURRENTLY_ON(BrowserThread::IO); - - bool erased = requests_.erase(request) == 1; - DCHECK(erased); -} - } // namespace atom diff --git a/atom/browser/net/atom_cert_verifier.h b/atom/browser/net/atom_cert_verifier.h index 52b6fb5303e6..02c2444cd7a4 100644 --- a/atom/browser/net/atom_cert_verifier.h +++ b/atom/browser/net/atom_cert_verifier.h @@ -5,89 +5,64 @@ #ifndef ATOM_BROWSER_NET_ATOM_CERT_VERIFIER_H_ #define ATOM_BROWSER_NET_ATOM_CERT_VERIFIER_H_ -#include #include -#include #include "base/memory/ref_counted.h" -#include "net/base/hash_value.h" #include "net/cert/cert_verifier.h" -#include "net/cert/crl_set.h" -#include "net/cert/x509_certificate.h" -#include "net/log/net_log.h" namespace atom { class AtomCertVerifier : public net::CertVerifier { public: - struct RequestParams { - RequestParams( - const net::SHA1HashValue cert_fingerprint, - const net::SHA1HashValue ca_fingerprint, - const std::string& hostname_arg, - const std::string& ocsp_response, - int flags); - ~RequestParams() {} - - bool operator<(const RequestParams& other) const; - - std::string hostname; - std::string ocsp_response; - int flags; - std::vector hash_values; - }; - class CertVerifyRequest : public base::RefCountedThreadSafe { public: - CertVerifyRequest( - AtomCertVerifier* cert_verifier, - const RequestParams& key, - scoped_refptr cert, - scoped_refptr crl_set, - net::CertVerifyResult* verify_result, - scoped_ptr* out_req, - const net::BoundNetLog& net_log) + CertVerifyRequest(AtomCertVerifier* cert_verifier, + net::X509Certificate* cert, + const std::string& hostname, + const std::string& ocsp_response, + int flags, + net::CRLSet* crl_set, + net::CertVerifyResult* verify_result, + const net::CompletionCallback& callback, + scoped_ptr* out_req, + const net::BoundNetLog& net_log) : cert_verifier_(cert_verifier), - key_(key), - certificate_(cert), + cert_(cert), + hostname_(hostname), + ocsp_response_(ocsp_response), + flags_(flags), crl_set_(crl_set), verify_result_(verify_result), + callback_(callback), out_req_(out_req), net_log_(net_log), handled_(false) { } - void RunResult(int result); - void DelegateToDefaultVerifier(); void ContinueWithResult(int result); - void AddCompletionCallback(net::CompletionCallback callback) { - callbacks_.push_back(callback); - } - - const RequestParams key() const { return key_; } - - std::string hostname() const { return key_.hostname; } - - scoped_refptr certificate() const { - return certificate_; - } + const std::string& hostname() const { return hostname_; } + net::X509Certificate* cert() const { return cert_.get(); } private: friend class base::RefCountedThreadSafe; ~CertVerifyRequest() {} - AtomCertVerifier* cert_verifier_; - const RequestParams key_; + void DelegateToDefaultVerifier(); - scoped_refptr certificate_; + AtomCertVerifier* cert_verifier_; + + scoped_refptr cert_; + std::string hostname_; + std::string ocsp_response_; + int flags_; scoped_refptr crl_set_; net::CertVerifyResult* verify_result_; + net::CompletionCallback callback_; scoped_ptr* out_req_; - const net::BoundNetLog net_log_; + const net::BoundNetLog& net_log_; - std::vector callbacks_; bool handled_; DISALLOW_COPY_AND_ASSIGN(CertVerifyRequest); @@ -95,7 +70,6 @@ class AtomCertVerifier : public net::CertVerifier { class Delegate { public: - Delegate() {} virtual ~Delegate() {} // Called on UI thread. @@ -123,35 +97,10 @@ class AtomCertVerifier : public net::CertVerifier { const net::BoundNetLog& net_log) override; bool SupportsOCSPStapling() override; - net::CertVerifier* default_cert_verifier() const { - return default_cert_verifier_.get(); - } - private: - CertVerifyRequest* FindRequest(const RequestParams& key); - void RemoveRequest(CertVerifyRequest* request); - - struct CertVerifyRequestToRequestParamsComparator { - bool operator()(const scoped_refptr request, - const RequestParams& key) const { - return request->key() < key; - } - }; - - struct CertVerifyRequestComparator { - bool operator()(const scoped_refptr req1, - const scoped_refptr req2) const { - return req1->key() < req2->key(); - } - }; - - using ActiveRequestSet = - std::set, - CertVerifyRequestComparator>; - ActiveRequestSet requests_; + friend class CertVerifyRequest; Delegate* delegate_; - scoped_ptr default_cert_verifier_; DISALLOW_COPY_AND_ASSIGN(AtomCertVerifier); From ebe66daa56c0926d004aa1769ad77e18fd044394 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Tue, 17 Nov 2015 21:36:36 +0800 Subject: [PATCH 190/249] Emit verify-certificate only when default verifier fails --- atom/browser/api/atom_api_session.cc | 5 ++- atom/browser/net/atom_cert_verifier.cc | 62 +++++++++++++++----------- atom/browser/net/atom_cert_verifier.h | 51 +++++++-------------- docs/api/session.md | 15 ++++--- 4 files changed, 65 insertions(+), 68 deletions(-) diff --git a/atom/browser/api/atom_api_session.cc b/atom/browser/api/atom_api_session.cc index 3ac36abf5318..c75bf9dd0bcc 100644 --- a/atom/browser/api/atom_api_session.cc +++ b/atom/browser/api/atom_api_session.cc @@ -266,11 +266,12 @@ void Session::RequestCertVerification( const scoped_refptr& request) { bool prevent_default = Emit( "verify-certificate", - request->hostname(), - make_scoped_refptr(request->cert()), + 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); } diff --git a/atom/browser/net/atom_cert_verifier.cc b/atom/browser/net/atom_cert_verifier.cc index dcfe29afddad..0f94e4fe2ad2 100644 --- a/atom/browser/net/atom_cert_verifier.cc +++ b/atom/browser/net/atom_cert_verifier.cc @@ -15,6 +15,9 @@ using content::BrowserThread; namespace atom { +AtomCertVerifier::CertVerifyRequest::~CertVerifyRequest() { +} + void AtomCertVerifier::CertVerifyRequest::ContinueWithResult(int result) { DCHECK_CURRENTLY_ON(BrowserThread::UI); @@ -22,25 +25,10 @@ void AtomCertVerifier::CertVerifyRequest::ContinueWithResult(int result) { return; handled_ = true; - - if (result != net::ERR_IO_PENDING) { - BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, - base::Bind(callback_, result)); - return; - } - BrowserThread::PostTask( BrowserThread::IO, FROM_HERE, - base::Bind(&CertVerifyRequest::DelegateToDefaultVerifier, this)); -} - -void AtomCertVerifier::CertVerifyRequest::DelegateToDefaultVerifier() { - DCHECK_CURRENTLY_ON(BrowserThread::IO); - int result = cert_verifier_->default_cert_verifier_->Verify( - cert_.get(), hostname_, ocsp_response_, flags_, crl_set_.get(), - verify_result_, callback_, out_req_, net_log_); - if (result != net::ERR_IO_PENDING) - callback_.Run(result); + base::Bind(args_.callback, + result == net::ERR_IO_PENDING ? result_ : result)); } AtomCertVerifier::AtomCertVerifier() @@ -66,18 +54,42 @@ int AtomCertVerifier::Verify( if (callback.is_null() || !verify_result || hostname.empty() || !delegate_) return net::ERR_INVALID_ARGUMENT; - CertVerifyRequest* request = new CertVerifyRequest( - this, cert, hostname, ocsp_response, flags, crl_set, verify_result, - callback, out_req, net_log); - BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, - base::Bind(&Delegate::RequestCertVerification, - base::Unretained(delegate_), - make_scoped_refptr(request))); - return net::ERR_IO_PENDING; + 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; + } + + return result; } 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 diff --git a/atom/browser/net/atom_cert_verifier.h b/atom/browser/net/atom_cert_verifier.h index 02c2444cd7a4..8736db0f8723 100644 --- a/atom/browser/net/atom_cert_verifier.h +++ b/atom/browser/net/atom_cert_verifier.h @@ -14,55 +14,35 @@ namespace atom { class AtomCertVerifier : public net::CertVerifier { public: + struct VerifyArgs { + scoped_refptr cert; + const std::string& hostname; + net::CompletionCallback callback; + }; + class CertVerifyRequest : public base::RefCountedThreadSafe { public: CertVerifyRequest(AtomCertVerifier* cert_verifier, - net::X509Certificate* cert, - const std::string& hostname, - const std::string& ocsp_response, - int flags, - net::CRLSet* crl_set, - net::CertVerifyResult* verify_result, - const net::CompletionCallback& callback, - scoped_ptr* out_req, - const net::BoundNetLog& net_log) + int result, + const VerifyArgs& args) : cert_verifier_(cert_verifier), - cert_(cert), - hostname_(hostname), - ocsp_response_(ocsp_response), - flags_(flags), - crl_set_(crl_set), - verify_result_(verify_result), - callback_(callback), - out_req_(out_req), - net_log_(net_log), + result_(result), + args_(args), handled_(false) { } void ContinueWithResult(int result); - const std::string& hostname() const { return hostname_; } - net::X509Certificate* cert() const { return cert_.get(); } + const VerifyArgs& args() const { return args_; } private: friend class base::RefCountedThreadSafe; - ~CertVerifyRequest() {} - - void DelegateToDefaultVerifier(); + ~CertVerifyRequest(); AtomCertVerifier* cert_verifier_; - - scoped_refptr cert_; - std::string hostname_; - std::string ocsp_response_; - int flags_; - scoped_refptr crl_set_; - net::CertVerifyResult* verify_result_; - net::CompletionCallback callback_; - scoped_ptr* out_req_; - const net::BoundNetLog& net_log_; - + int result_; + VerifyArgs args_; bool handled_; DISALLOW_COPY_AND_ASSIGN(CertVerifyRequest); @@ -100,6 +80,9 @@ class AtomCertVerifier : public net::CertVerifier { private: friend class CertVerifyRequest; + void VerifyCertificateFromDelegate(const VerifyArgs& args, int result); + void OnDefaultVerificationResult(const VerifyArgs& args, int result); + Delegate* delegate_; scoped_ptr default_cert_verifier_; diff --git a/docs/api/session.md b/docs/api/session.md index 210d58753519..cd802f34b20a 100644 --- a/docs/api/session.md +++ b/docs/api/session.md @@ -21,7 +21,7 @@ var session = win.webContents.session * `item` [DownloadItem](download-item.md) * `webContents` [WebContents](web-contents.md) -Fired when Electron is about to download `item` in `webContents`. +Emitted when Electron is about to download `item` in `webContents`. Calling `event.preventDefault()` will cancel the download. @@ -43,18 +43,19 @@ session.on('will-download', function(event, item, webContents) { * `issuerName` String * `callback` Function -Fired whenever a server certificate verification is requested by the -network layer with `hostname`, `certificate` and `callback`. -`callback` should be called with a boolean response to -indicate continuation or cancellation of the request. +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 + // Verification logic. + event.preventDefault(); callback(true); + } else { + callback(false); } - callback(false); }); ``` From 961ee5a4d914e9195ef731c86d6f3b28295c7590 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Tue, 17 Nov 2015 21:41:36 +0800 Subject: [PATCH 191/249] Rename verify-certificate to untrusted-certificate --- atom/browser/api/atom_api_session.cc | 2 +- docs/api/session.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/atom/browser/api/atom_api_session.cc b/atom/browser/api/atom_api_session.cc index c75bf9dd0bcc..6527f67ab3f1 100644 --- a/atom/browser/api/atom_api_session.cc +++ b/atom/browser/api/atom_api_session.cc @@ -265,7 +265,7 @@ Session::~Session() { void Session::RequestCertVerification( const scoped_refptr& request) { bool prevent_default = Emit( - "verify-certificate", + "untrusted-certificate", request->args().hostname, request->args().cert, base::Bind(&PassVerificationResult, request)); diff --git a/docs/api/session.md b/docs/api/session.md index cd802f34b20a..e385e222d529 100644 --- a/docs/api/session.md +++ b/docs/api/session.md @@ -34,7 +34,7 @@ session.on('will-download', function(event, item, webContents) { }); ``` -### Event: 'verify-certificate' +### Event: 'untrusted-certificate' * `event` Event * `hostname` String From 247a0a8ae2c5ce6a7c257112d87ad869dd9a2078 Mon Sep 17 00:00:00 2001 From: Plusb Preco Date: Wed, 18 Nov 2015 02:12:40 +0900 Subject: [PATCH 192/249] Add BrowserWindow translation --- docs-translations/ko-KR/README.md | 4 +- docs-translations/ko-KR/api/browser-window.md | 704 ++++++++++++++++++ 2 files changed, 706 insertions(+), 2 deletions(-) create mode 100644 docs-translations/ko-KR/api/browser-window.md diff --git a/docs-translations/ko-KR/README.md b/docs-translations/ko-KR/README.md index b2082b0d2e7a..34826f9d3403 100644 --- a/docs-translations/ko-KR/README.md +++ b/docs-translations/ko-KR/README.md @@ -32,7 +32,7 @@ * [app](api/app.md) * [autoUpdater](api/auto-updater.md) -* [BrowserWindow (0% 번역됨)](api/browser-window.md) +* [BrowserWindow (20% 번역됨 - 작업중)](api/browser-window.md) * [contentTracing](api/content-tracing.md) * [dialog](api/dialog.md) * [globalShortcut](api/global-shortcut.md) @@ -43,7 +43,7 @@ * [powerSaveBlocker](api/power-save-blocker.md) * [protocol](api/protocol.md) * [session](api/session.md) -* [webContents (0% 번역됨)](api/web-contents.md) +* [webContents](api/web-contents.md) * [Tray](api/tray.md) ### 랜더러 프로세스에서 사용할 수 있는 모듈 (웹 페이지): diff --git a/docs-translations/ko-KR/api/browser-window.md b/docs-translations/ko-KR/api/browser-window.md new file mode 100644 index 000000000000..30165e858519 --- /dev/null +++ b/docs-translations/ko-KR/api/browser-window.md @@ -0,0 +1,704 @@ +# BrowserWindow + +`BrowserWindow` 클래스는 브라우저 창(윈도우 창)을 만드는 역할을 담당합니다. + +다음 예제는 윈도우 창을 생성합니다: + +```javascript +const BrowserWindow = require('electron').BrowserWindow; + +var win = new BrowserWindow({ width: 800, height: 600, show: false }); +win.on('closed', function() { + win = null; +}); + +win.loadURL('https://github.com'); +win.show(); +``` + +또한 [Frameless Window](frameless-window.md) API를 사용하여 창 테두리가 없는 윈도우 창을 생성할 수 있습니다. + +## Class: BrowserWindow + +`BrowserWindow`는 [EventEmitter](http://nodejs.org/api/events.html#events_class_events_eventemitter)를 상속받은 클래스 입니다. + +`BrowserWindow`는 `options`를 통해 네이티브 속성을 포함한 새로운 윈도우 창을 생성합니다. + +### `new BrowserWindow(options)` + +`options` 객체에서 사용할 수 있는 속성들: + +* `width` Integer - 윈도우 창의 가로 너비. +* `height` Integer - 윈도우 창의 세로 높이. +* `x` Integer - 화면을 기준으로 창 좌측을 오프셋 한 위치. +* `y` Integer - 화면을 기준으로 창 상단을 오프셋 한 위치. +* `useContentSize` Boolean - `width`와 `height`를 웹 페이지의 크기로 사용합니다. + 이 속성을 사용하면 웹 페이지의 크기에 윈도우 프레임 크기가 추가되므로 실제 창은 조금 더 커질 수 있습니다. +* `center` Boolean - 윈도우 창을 화면 정 중앙에 위치시킵니다. +* `minWidth` Integer - 윈도우 창의 최소 가로 너비. +* `minHeight` Integer - 윈도우 창의 최소 세로 높이. +* `maxWidth` Integer - 윈도우 창의 최대 가로 너비. +* `maxHeight` Integer - 윈도우 창의 최대 세로 높이. +* `resizable` Boolean - 윈도우 창의 크기를 재조정 할 수 있는지 여부. +* `alwaysOnTop` Boolean - 윈도우 창이 언제나 다른 창들 위에 유지되는지 여부. +* `fullscreen` Boolean - 윈도우 창의 전체화면 활성화 여부. + `false`로 지정했을 경우 OS X에선 전체화면 버튼이 숨겨지거나 비활성화됩니다. +* `skipTaskbar` Boolean - 작업 표시줄 어플리케이션 아이콘 표시 여부. +* `kiosk` Boolean - Kiosk(키오스크) 모드. +* `title` String - 기본 윈도우 창 제목. +* `icon` [NativeImage](native-image.md) - 윈도우 아이콘, 생략하면 실행 파일의 아이콘이 대신 사용됩니다. +* `show` Boolean - 윈도우가 생성되면 보여줄지 여부. +* `frame` Boolean - `false`로 지정하면 창을 [Frameless Window](frameless-window.md) 형태로 생성합니다. +* `acceptFirstMouse` Boolean - 윈도우가 비활성화 상태일 때 내부 컨텐츠 클릭 시 활성화 되는 동시에 단일 mouse-down 이벤트를 발생시킬지 여부. +* `disableAutoHideCursor` Boolean - 파이핑중 자동으로 커서를 숨길지 여부. +* `autoHideMenuBar` Boolean - `Alt`를 누르지 않는 한 어플리케이션 메뉴바를 숨길지 여부. +* `enableLargerThanScreen` Boolean - 윈도우 창 크기가 화면 크기보다 크게 재조정 될 수 있는지 여부. +* `backgroundColor` String - 16진수로 표현된 윈도우의 배경 색. `#66CD00` 또는 `#FFF`가 사용될 수 있습니다. + 이 속성은 Linux와 Windows에만 구현되어 있습니다. +* `darkTheme` Boolean - 설정에 상관 없이 무조건 어두운 윈도우 테마를 사용합니다. 몇몇 GTK+3 데스크톱 환경에서만 작동합니다. +* `transparent` Boolean - 윈도우 창을 [투명화](frameless-window.md)합니다. +* `type` String - 윈도우 창 종류를 지정합니다. + 사용할 수 있는 창 종류는 `desktop`, `dock`, `toolbar`, `splash`, `notification`와 같습니다. + 이 속성은 Linux에서만 작동합니다. +* `standardWindow` Boolean - OS X의 표준 윈도우를 텍스쳐 윈도우 대신 사용합니다. 기본 값은 `true`입니다. +* `titleBarStyle` String, OS X - 윈도우 타이틀 바 스타일을 지정합니다. 이 속성은 OS X 10.10 Yosemite 이후 버전만 지원합니다. + 다음 3가지 종류의 값을 사용할 수 있습니다: + * `default` 또는 미지정: 표준 Mac 회색 불투명 스타일을 사용합니다. + * `hidden`: 타이틀 바를 숨기고 컨텐츠 전체를 윈도우 크기에 맞춥니다. + 타이틀 바는 없어지지만 표준 창 컨트롤 ("신호등 버튼")은 왼쪽 상단에 유지됩니다. + * `hidden-inset`: `hidden` 타이틀 바 속성과 함께 신호등 버튼이 윈도우 모서리로부터 약간 더 안쪽으로 들어가도록합니다. +* `webPreferences` Object - 웹 페이지 기능을 설정합니다. 사용할 수 있는 속성은 다음과 같습니다: + * `nodeIntegration` Boolean - node(node.js) 통합 여부. 기본값은 `true`입니다. + * `preload` String - 스크립트를 지정하면 페이지 내의 다른 스크립트가 작동하기 전에 로드됩니다. + 여기서 지정한 스크립트는 페이지의 node 통합 활성화 여부에 상관없이 언제나 모든 node API에 접근할 수 있습니다. + 그리고 `preload` 스크립트의 경로는 절대 경로로 지정해야 합니다. + * `partition` String - 페이지에서 사용할 세션을 지정합니다. 만약 `partition`이 + `persist:`로 시작하면 페이지는 지속성 세션을 사용하며 다른 모든 앱 내의 페이지에서 같은 `partition`을 사용할 수 있습니다. + 만약 `persist:` 접두어로 시작하지 않으면 페이지는 인-메모리 세션을 사용합니다. 여러 페이지에서 같은 `partition`을 지정하면 + 같은 세션을 공유할 수 있습니다. `partition`을 지정하지 않으면 어플리케이션의 기본 세션이 사용됩니다. + * `zoomFactor` Number - 페이지의 기본 줌 값을 지정합니다. 예를 들어 `300%`를 표현하려면 `3.0`으로 지정합니다. + * `javascript` Boolean + * `webSecurity` Boolean - `false`로 지정하면 same-origin 정책을 비활성화합니다. (이 속성은 보통 사람에 의해 웹 사이트를 테스트할 때 사용합니다) + 그리고 `allowDisplayingInsecureContent`와 `allowRunningInsecureContent`이 사용자로부터 `true`로 지정되지 않은 경우 `true`로 지정합니다. + * `allowDisplayingInsecureContent` Boolean - https 페이지에서 http URL에서 로드한 이미지 같은 리소스를 표시할 수 있도록 허용합니다. + * `allowRunningInsecureContent` Boolean - https 페이지에서 http URL에서 로드한 JavaScript와 CSS 또는 플러그인을 실행시킬 수 있도록 허용합니다. + * `images` Boolean + * `java` Boolean + * `textAreasAreResizable` Boolean + * `webgl` Boolean + * `webaudio` Boolean + * `plugins` Boolean - 어떤 플러그인이 활성화되어야 하는지 지정합니다. + * `experimentalFeatures` Boolean + * `experimentalCanvasFeatures` Boolean + * `overlayScrollbars` Boolean + * `overlayFullscreenVideo` Boolean + * `sharedWorker` Boolean + * `directWrite` Boolean - Windows에서 폰트 랜더링을 위해 DirectWrite를 사용하는지를 지정합니다. + * `pageVisibility` Boolean - 현재 윈도우의 가시성을 반영하는 대신 페이지가 visible 또는 hidden 중 지정된 상태를 계속 유지하도록 합니다. + 이 속성을 `true`로 지정하면 DOM 타이머의 스로틀링을 방지할 수 있습니다. + +## Events + +`BrowserWindow` 객체는 다음과 같은 이벤트를 발생시킵니다: + +**참고:** 몇몇 이벤트는 라벨에 특정한 OS에서만 작동합니다. + +### Event: 'page-title-updated' + +Returns: + +* `event` Event + +문서의 제목이 변경될 때 발생하는 이벤트 입니다. +`event.preventDefault()`를 호출하여 네이티브 윈도우의 제목이 변경되는 것을 방지할 수 있습니다. + +### Event: 'close' + +Returns: + +* `event` Event + +Emitted when the window is going to be closed. It's emitted before the +`beforeunload` and `unload` event of the DOM. Calling `event.preventDefault()` +will cancel the close. + +Usually you would want to use the `beforeunload` handler to decide whether the +window should be closed, which will also be called when the window is +reloaded. In Electron, returning an empty string or `false` would cancel the +close. For example: + +```javascript +window.onbeforeunload = function(e) { + console.log('I do not want to be closed'); + + // Unlike usual browsers, in which a string should be returned and the user is + // prompted to confirm the page unload, Electron gives developers more options. + // Returning empty string or false would prevent the unloading now. + // You can also use the dialog API to let the user confirm closing the application. + e.returnValue = false; +}; +``` + +### Event: 'closed' + +Emitted when the window is closed. After you have received this event you should +remove the reference to the window and avoid using it anymore. + +### Event: 'unresponsive' + +Emitted when the web page becomes unresponsive. + +### Event: 'responsive' + +Emitted when the unresponsive web page becomes responsive again. + +### Event: 'blur' + +Emitted when the window loses focus. + +### Event: 'focus' + +Emitted when the window gains focus. + +### Event: 'maximize' + +Emitted when window is maximized. + +### Event: 'unmaximize' + +Emitted when the window exits from maximized state. + +### Event: 'minimize' + +Emitted when the window is minimized. + +### Event: 'restore' + +Emitted when the window is restored from minimized state. + +### Event: 'resize' + +Emitted when the window is getting resized. + +### Event: 'move' + +Emitted when the window is getting moved to a new position. + +__Note__: On OS X this event is just an alias of `moved`. + +### Event: 'moved' _OS X_ + +Emitted once when the window is moved to a new position. + +### Event: 'enter-full-screen' + +Emitted when the window enters full screen state. + +### Event: 'leave-full-screen' + +Emitted when the window leaves full screen state. + +### Event: 'enter-html-full-screen' + +Emitted when the window enters full screen state triggered by html api. + +### Event: 'leave-html-full-screen' + +Emitted when the window leaves full screen state triggered by html api. + +### Event: 'app-command': + +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 +commands, as well as the "Back" button built into some mice on Windows. + +```js +someWindow.on('app-command', function(e, cmd) { + // Navigate the window back when the user hits their mouse back button + if (cmd === 'browser-backward' && someWindow.webContents.canGoBack()) { + someWindow.webContents.goBack(); + } +}); +``` + +## Methods + +`BrowserWindow` 객체는 다음과 같은 메서드를 가지고 있습니다: + +### `BrowserWindow.getAllWindows()` + +Returns an array of all opened browser windows. + +### `BrowserWindow.getFocusedWindow()` + +Returns the window that is focused in this application. + +### `BrowserWindow.fromWebContents(webContents)` + +* `webContents` [WebContents](web-contents.md) + +Find a window according to the `webContents` it owns. + +### `BrowserWindow.fromId(id)` + +* `id` Integer + +Find a window according to its ID. + +### `BrowserWindow.addDevToolsExtension(path)` + +* `path` String + +Adds DevTools extension located at `path`, and returns extension's name. + +The extension will be remembered so you only need to call this API once, this +API is not for programming use. + +### `BrowserWindow.removeDevToolsExtension(name)` + +* `name` String + +Remove the DevTools extension whose name is `name`. + +## Instance Properties + +Objects created with `new BrowserWindow` have the following properties: + +```javascript +// In this example `win` is our instance +var win = new BrowserWindow({ width: 800, height: 600 }); +``` + +### `win.webContents` + +The `WebContents` object this window owns, all web page related events and +operations will be done via it. + +See the [`webContents` documentation](web-contents.md) for its methods and +events. + +### `win.id` + +The unique ID of this window. + +## Instance Methods + +Objects created with `new BrowserWindow` have the following instance methods: + +**Note:** Some methods are only available on specific operating systems and are labeled as such. + +### `win.destroy()` + +Force closing the window, the `unload` and `beforeunload` event won't be emitted +for the web page, and `close` event will also not be emitted +for this window, but it guarantees the `closed` event will be emitted. + +You should only use this method when the renderer process (web page) has +crashed. + +### `win.close()` + +Try to close the window, this has the same effect with user manually clicking +the close button of the window. The web page may cancel the close though, see +the [close event](#event-close). + +### `win.focus()` + +Focus on the window. + +### `win.isFocused()` + +Returns a boolean, whether the window is focused. + +### `win.show()` + +Shows and gives focus to the window. + +### `win.showInactive()` + +Shows the window but doesn't focus on it. + +### `win.hide()` + +Hides the window. + +### `win.isVisible()` + +Returns a boolean, whether the window is visible to the user. + +### `win.maximize()` + +Maximizes the window. + +### `win.unmaximize()` + +Unmaximizes the window. + +### `win.isMaximized()` + +Returns a boolean, whether the window is maximized. + +### `win.minimize()` + +Minimizes the window. On some platforms the minimized window will be shown in +the Dock. + +### `win.restore()` + +Restores the window from minimized state to its previous state. + +### `win.isMinimized()` + +Returns a boolean, whether the window is minimized. + +### `win.setFullScreen(flag)` + +* `flag` Boolean + +Sets whether the window should be in fullscreen mode. + +### `win.isFullScreen()` + +Returns a boolean, whether the window is in fullscreen mode. + +### `win.setAspectRatio(aspectRatio[, extraSize])` _OS X_ + +* `aspectRatio` The aspect ratio we want to maintain for some portion of the +content view. +* `extraSize` Object (optional) - The extra size not to be included while +maintaining the aspect ratio. Properties: + * `width` Integer + * `height` Integer + +This will have a window maintain an aspect ratio. The extra size allows a +developer to have space, specified in pixels, not included within the aspect +ratio calculations. This API already takes into account the difference between a +window's size and its content size. + +Consider a normal window with an HD video player and associated controls. +Perhaps there are 15 pixels of controls on the left edge, 25 pixels of controls +on the right edge and 50 pixels of controls below the player. In order to +maintain a 16:9 aspect ratio (standard aspect ratio for HD @1920x1080) within +the player itself we would call this function with arguments of 16/9 and +[ 40, 50 ]. The second argument doesn't care where the extra width and height +are within the content view--only that they exist. Just sum any extra width and +height areas you have within the overall content view. + +### `win.setBounds(options)` + +`options` Object, properties: + +* `x` Integer +* `y` Integer +* `width` Integer +* `height` Integer + +Resizes and moves the window to `width`, `height`, `x`, `y`. + +### `win.getBounds()` + +Returns an object that contains window's width, height, x and y values. + +### `win.setSize(width, height)` + +* `width` Integer +* `height` Integer + +Resizes the window to `width` and `height`. + +### `win.getSize()` + +Returns an array that contains window's width and height. + +### `win.setContentSize(width, height)` + +* `width` Integer +* `height` Integer + +Resizes the window's client area (e.g. the web page) to `width` and `height`. + +### `win.getContentSize()` + +Returns an array that contains window's client area's width and height. + +### `win.setMinimumSize(width, height)` + +* `width` Integer +* `height` Integer + +Sets the minimum size of window to `width` and `height`. + +### `win.getMinimumSize()` + +Returns an array that contains window's minimum width and height. + +### `win.setMaximumSize(width, height)` + +* `width` Integer +* `height` Integer + +Sets the maximum size of window to `width` and `height`. + +### `win.getMaximumSize()` + +Returns an array that contains window's maximum width and height. + +### `win.setResizable(resizable)` + +* `resizable` Boolean + +Sets whether the window can be manually resized by user. + +### `win.isResizable()` + +Returns whether the window can be manually resized by user. + +### `win.setAlwaysOnTop(flag)` + +* `flag` Boolean + +Sets whether the window should show always on top of other windows. After +setting this, the window is still a normal window, not a toolbox window which +can not be focused on. + +### `win.isAlwaysOnTop()` + +Returns whether the window is always on top of other windows. + +### `win.center()` + +Moves window to the center of the screen. + +### `win.setPosition(x, y)` + +* `x` Integer +* `y` Integer + +Moves window to `x` and `y`. + +### `win.getPosition()` + +Returns an array that contains window's current position. + +### `win.setTitle(title)` + +* `title` String + +Changes the title of native window to `title`. + +### `win.getTitle()` + +Returns the title of the native window. + +**Note:** The title of web page can be different from the title of the native +window. + +### `win.flashFrame(flag)` + +* `flag` Boolean + +Starts or stops flashing the window to attract user's attention. + +### `win.setSkipTaskbar(skip)` + +* `skip` Boolean + +Makes the window not show in the taskbar. + +### `win.setKiosk(flag)` + +* `flag` Boolean + +Enters or leaves the kiosk mode. + +### `win.isKiosk()` + +Returns whether the window is in kiosk mode. + +### `win.hookWindowMessage(message, callback)` _WINDOWS_ + +* `message` Integer +* `callback` Function + +Hooks a windows message. The `callback` is called when +the message is received in the WndProc. + +### `win.isWindowMessageHooked(message)` _WINDOWS_ + +* `message` Integer + +Returns `true` or `false` depending on whether the message is hooked. + +### `win.unhookWindowMessage(message)` _WINDOWS_ + +* `message` Integer + +Unhook the window message. + +### `win.unhookAllWindowMessages()` _WINDOWS_ + +Unhooks all of the window messages. + +### `win.setRepresentedFilename(filename)` _OS X_ + +* `filename` String + +Sets the pathname of the file the window represents, and the icon of the file +will show in window's title bar. + +### `win.getRepresentedFilename()` _OS X_ + +Returns the pathname of the file the window represents. + +### `win.setDocumentEdited(edited)` _OS X_ + +* `edited` Boolean + +Specifies whether the window’s document has been edited, and the icon in title +bar will become grey when set to `true`. + +### `win.isDocumentEdited()` _OS X_ + +Whether the window's document has been edited. + +### `win.focusOnWebView()` + +### `win.blurWebView()` + +### `win.capturePage([rect, ]callback)` + +* `rect` Object (optional)- The area of page to be captured, properties: + * `x` Integer + * `y` Integer + * `width` Integer + * `height` Integer +* `callback` Function + +Captures a snapshot of the page within `rect`. Upon completion `callback` will +be called with `callback(image)`. The `image` is an instance of +[NativeImage](native-image.md) that stores data of the snapshot. Omitting +`rect` will capture the whole visible page. + +### `win.print([options])` + +Same as `webContents.print([options])` + +### `win.printToPDF(options, callback)` + +Same as `webContents.printToPDF(options, callback)` + +### `win.loadURL(url[, options])` + +Same as `webContents.loadURL(url[, options])`. + +### `win.reload()` + +Same as `webContents.reload`. + +### `win.setMenu(menu)` _Linux_ _Windows_ + +* `menu` Menu + +Sets the `menu` as the window's menu bar, setting it to `null` will remove the +menu bar. + +### `win.setProgressBar(progress)` + +* `progress` Double + +Sets progress value in progress bar. Valid range is [0, 1.0]. + +Remove progress bar when progress < 0; +Change to indeterminate mode when progress > 1. + +On Linux platform, only supports Unity desktop environment, you need to specify +the `*.desktop` file name to `desktopName` field in `package.json`. By default, +it will assume `app.getName().desktop`. + +### `win.setOverlayIcon(overlay, description)` _Windows 7+_ + +* `overlay` [NativeImage](native-image.md) - the icon to display on the bottom +right corner of the taskbar icon. If this parameter is `null`, the overlay is +cleared +* `description` String - a description that will be provided to Accessibility +screen readers + +Sets a 16px overlay onto the current taskbar icon, usually used to convey some +sort of application status or to passively notify the user. + + +### `win.setThumbarButtons(buttons)` _Windows 7+_ + +`buttons` Array of `button` Objects: + +`button` Object, properties: + +* `icon` [NativeImage](native-image.md) - The icon showing in thumbnail + toolbar. +* `tooltip` String (optional) - The text of the button's tooltip. +* `flags` Array (optional) - Control specific states and behaviors + of the button. By default, it uses `enabled`. It can include following + Strings: + * `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 taskbar button's + flyout 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. +* `click` - Function + +Add a thumbnail toolbar with a specified set of buttons to the thumbnail image +of a window in a taskbar button layout. Returns a `Boolean` object indicates +whether the thumbnail has been added successfully. + +The number of buttons in thumbnail toolbar should be no greater than 7 due to +the limited room. Once you setup the thumbnail toolbar, the toolbar cannot be +removed due to the platform's limitation. But you can call the API with an empty +array to clean the buttons. + +### `win.showDefinitionForSelection()` _OS X_ + +Shows pop-up dictionary that searches the selected word on the page. + +### `win.setAutoHideMenuBar(hide)` + +* `hide` Boolean + +Sets whether the window menu bar should hide itself automatically. Once set the +menu bar will only show when users press the single `Alt` key. + +If the menu bar is already visible, calling `setAutoHideMenuBar(true)` won't +hide it immediately. + +### `win.isMenuBarAutoHide()` + +Returns whether menu bar automatically hides itself. + +### `win.setMenuBarVisibility(visible)` + +* `visible` Boolean + +Sets whether the menu bar should be visible. If the menu bar is auto-hide, users +can still bring up the menu bar by pressing the single `Alt` key. + +### `win.isMenuBarVisible()` + +Returns whether the menu bar is visible. + +### `win.setVisibleOnAllWorkspaces(visible)` + +* `visible` Boolean + +Sets whether the window should be visible on all workspaces. + +**Note:** This API does nothing on Windows. + +### `win.isVisibleOnAllWorkspaces()` + +Returns whether the window is visible on all workspaces. + +**Note:** This API always returns false on Windows. From b4eca40d07fbbe7165c8623b268144349e159814 Mon Sep 17 00:00:00 2001 From: Plusb Preco Date: Wed, 18 Nov 2015 03:09:51 +0900 Subject: [PATCH 193/249] Improve grammar * Improve grammar * Standardize docs * Fix typos --- docs-translations/ko-KR/README.md | 2 +- .../ko-KR/api/chrome-command-line-switches.md | 2 +- docs-translations/ko-KR/api/menu-item.md | 29 ++-- docs-translations/ko-KR/api/web-contents.md | 136 +++++++++--------- docs-translations/ko-KR/api/web-view-tag.md | 8 +- .../ko-KR/tutorial/debugging-main-process.md | 2 +- .../ko-KR/tutorial/devtools-extension.md | 10 +- .../ko-KR/tutorial/quick-start.md | 2 +- 8 files changed, 95 insertions(+), 96 deletions(-) diff --git a/docs-translations/ko-KR/README.md b/docs-translations/ko-KR/README.md index 34826f9d3403..39b9367d0ecf 100644 --- a/docs-translations/ko-KR/README.md +++ b/docs-translations/ko-KR/README.md @@ -7,7 +7,7 @@ * [네이티브 Node 모듈 사용하기](tutorial/using-native-node-modules.md) * [메인 프로세스 디버깅하기](tutorial/debugging-main-process.md) * [Selenium 과 WebDriver 사용하기](tutorial/using-selenium-and-webdriver.md) -* [개발자 콘솔 확장기능](tutorial/devtools-extension.md) +* [개발자 도구 확장 기능](tutorial/devtools-extension.md) * [Pepper 플래시 플러그인 사용하기](tutorial/using-pepper-flash-plugin.md) ## 튜토리얼 diff --git a/docs-translations/ko-KR/api/chrome-command-line-switches.md b/docs-translations/ko-KR/api/chrome-command-line-switches.md index 216d402c41e9..d3aa5dd6411b 100644 --- a/docs-translations/ko-KR/api/chrome-command-line-switches.md +++ b/docs-translations/ko-KR/api/chrome-command-line-switches.md @@ -28,7 +28,7 @@ HTTP 요청 캐시를 비활성화 합니다. ## --remote-debugging-port=`port` -지정한 `port`에 HTTP 기반의 리모트 디버거를 활성화 시킵니다. (개발자 콘솔) +지정한 `port`에 HTTP 기반의 리모트 디버거를 활성화 시킵니다. (개발자 도구) ## --js-flags=`flags` diff --git a/docs-translations/ko-KR/api/menu-item.md b/docs-translations/ko-KR/api/menu-item.md index fc5539c8cdf1..b17d3b9ec391 100644 --- a/docs-translations/ko-KR/api/menu-item.md +++ b/docs-translations/ko-KR/api/menu-item.md @@ -1,6 +1,6 @@ # MenuItem -`menu-item` 모듈은 어플리케이션 또는 컨텍스트 [`menu`](menu.md)에 아이템을 추가할 수 있도록 관련 클래스를 제공합니다. +`menu-item` 모듈은 어플리케이션 또는 컨텍스트 [`menu`](menu.md)에 항목 아이템을 추가할 수 있도록 관련 클래스를 제공합니다. [`menu`](menu.md)에서 예제를 확인할 수 있습니다. @@ -25,10 +25,9 @@ * `id` String - 현재 메뉴 아이템에 대해 유일키를 지정합니다. 이 키는 이후 `position` 옵션에서 사용할 수 있습니다. * `position` String - 미리 지정한 `id`를 이용하여 메뉴 아이템의 위치를 세밀하게 조정합니다. -메뉴 아이템을 생성할 때, 매칭되는 액션이 있다면 수동으로 직접 구현하는 대신 `role`을 설정하여, -고유 OS 경험을 최대한 살릴 것을 권장합니다. +메뉴 아이템을 생성할 때, 다음 목록과 일치하는 표준 동작은 수동으로 직접 구현하는 대신 `role` 속성을 지정하여 고유 OS 경험을 최대한 살릴 수 있습니다. -`role` 속성은 다음 값을 가질 수 있습니다.: +`role` 속성은 다음 값을 가질 수 있습니다: * `undo` * `redo` @@ -36,16 +35,16 @@ * `copy` * `paste` * `selectall` -* `minimize` - 현재 윈도우를 최소화 합니다. -* `close` - 현재 윈도우를 닫습니다. +* `minimize` - 현재 윈도우를 최소화합니다 +* `close` - 현재 윈도우를 닫습니다 -OS X에서 `role`은 다음 값을 추가로 가질 수 있습니다. +OS X에서의 `role`은 다음 값을 추가로 가질 수 있습니다: -* `about` - `orderFrontStandardAboutPanel` 액션에 매핑합니다. -* `hide` - `hide` 액션에 매핑합니다. -* `hideothers` - `hideOtherApplications` 액션에 매핑합니다. -* `unhide` - `unhideAllApplications` 액션에 매핑합니다. -* `front` - `arrangeInFront` 액션에 매핑합니다. -* `window` - 부메뉴가 "Window" 메뉴입니다. -* `help` - 부메뉴가 "Help" 메뉴입니다. -* `services` - 부메뉴가 "Services" 메뉴입니다. +* `about` - 매핑된 `orderFrontStandardAboutPanel` 액션 +* `hide` - 매핑된 `hide` 액션 +* `hideothers` - 매핑된 `hideOtherApplications` 액션 +* `unhide` - 매핑된 `unhideAllApplications` 액션 +* `front` - 매핑된 `arrangeInFront` 액션 +* `window` - 부 메뉴를 가지는 "Window" 메뉴 +* `help` - 부 메뉴를 가지는 "Help" 메뉴 +* `services` - 부 메뉴를 가지는 "Services" 메뉴 diff --git a/docs-translations/ko-KR/api/web-contents.md b/docs-translations/ko-KR/api/web-contents.md index 355e019e9c9b..89c5a4a767f0 100644 --- a/docs-translations/ko-KR/api/web-contents.md +++ b/docs-translations/ko-KR/api/web-contents.md @@ -1,9 +1,8 @@ # webContents -`webContents`는 -[EventEmitter](http://nodejs.org/api/events.html#events_class_events_eventemitter)입니다. +`webContents`는 [EventEmitter](http://nodejs.org/api/events.html#events_class_events_eventemitter)를 상속받았습니다. -웹페이지의 렌더링과 관리를 책임지며 [`BrowserWindow`](browser-window.md)의 속성입니다. 다음은 `webContents` 객체를 접근하는 예입니다: +웹 페이지의 렌더링과 관리를 책임지며 [`BrowserWindow`](browser-window.md)의 속성입니다. 다음은 `webContents` 객체에 접근하는 예제입니다: ```javascript const BrowserWindow = require('electron').BrowserWindow; @@ -20,7 +19,7 @@ var webContents = win.webContents; ### Event: 'did-finish-load' -네비게이션이 끝났을 때 발생하는 이벤트입니다. 즉, 탭의 스피너가 멈추고 `onload` 이벤트가 발생했을 때를 얘기합니다. +탐색 작업이 끝났을 때 발생하는 이벤트입니다. 브라우저의 탭의 스피너가 멈추고 `onload` 이벤트가 발생했을 때를 말합니다. ### Event: 'did-fail-load' @@ -31,8 +30,8 @@ Returns: * `errorDescription` String * `validatedURL` String -이 이벤트는 `did-finish-load`와 비슷하나, 로드가 실패했거나 취소되었을 때도 발생합니다. 예를들면 `window.stop()`이 실행되었을 때 발생합니다. -모든 에러 코드들의 목록과 설명은 [여기](https://code.google.com/p/chromium/codesearch#chromium/src/net/base/net_error_list.h)서 확인 가능합니다. +이 이벤트는 `did-finish-load`와 비슷하나, 로드가 실패했거나 취소되었을 때 발생합니다. 예를 들면 `window.stop()`이 실행되었을 때 발생합니다. +발생할 수 있는 전체 에러 코드의 목록과 설명은 [여기](https://code.google.com/p/chromium/codesearch#chromium/src/net/base/net_error_list.h)서 확인할 수 있습니다. ### Event: 'did-frame-finish-load' @@ -41,15 +40,15 @@ Returns: * `event` Event * `isMainFrame` Boolean -프레임(Frame)이 네비게이션을 끝냈을 때 발생하는 이벤트입니다. +프레임(Frame)이 탐색을 끝냈을 때 발생하는 이벤트입니다. ### Event: 'did-start-loading' -탭의 스피너가 회전을 시작한 시점과 같습니다. +브라우저 탭의 스피너가 회전을 시작한 때와 같은 시점에 대응하는 이벤트입니다. ### Event: 'did-stop-loading' -탭의 스피너가 회전을 멈추었을 떄의 시점과 같습니다. +브라우저 탭의 스피너가 회전을 멈추었을 때와 같은 시점에 대응하는 이벤트입니다. ### Event: 'did-get-response-details' @@ -64,7 +63,7 @@ Returns: * `referrer` String * `headers` Object -요청한 리소스의 정보가 존재할 때 발생하는 이벤트입니다. +요청한 리소스에 관련된 자세한 정보를 사용할 수 있을 때 발생하는 이벤트입니다. `status`는 리소스를 다운로드하기 위한 소켓 연결을 나타냅니다. ### Event: 'did-get-redirect-request' @@ -80,7 +79,7 @@ Returns: * `referrer` String * `headers` Object -리소스를 요청할 때 리다이렉트 응답을 받았을 때 발생하는 이벤트입니다. +리소스를 요청하는 동안에 리다이렉트 응답을 받았을 때 발생하는 이벤트입니다. ### Event: 'dom-ready' @@ -95,9 +94,9 @@ Returns: Returns: * `event` Event -* `favicons` Array - Array of URLs +* `favicons` Array - URL 배열 -페이지가 favicon을 받았을 때 발생하는 이벤트입니다. +페이지가 favicon(파비콘) URL을 받았을 때 발생하는 이벤트입니다. ### Event: 'new-window' @@ -108,14 +107,14 @@ Returns: * `frameName` String * `disposition` String - `default`, `foreground-tab`, `background-tab`, `new-window`, `other`중 하나일 수 있습니다. -* `options` Object - 새로운 `BrowserWindow`를 만들 때 사용되는 옵션들입니다. +* `options` Object - 새로운 `BrowserWindow` 객체를 만들 때 사용되는 옵션 객체입니다. 페이지가 `url`에 대하여 새로운 윈도우를 열기위해 요청한 경우 발생하는 이벤트입니다. -`window.open`이나 ``과 같은 외부 링크 등에 의해 요청될 수 있습니다. +`window.open`이나 ``과 같은 외부 링크에 의해 요청될 수 있습니다. -기본값으로 `BrowserWindow`는 `url`로 생성됩니다. +기본값으로 `BrowserWindow`는 `url`을 기반으로 생성됩니다. -`event.preventDefault()`를 호출하면 새로운 창을 만드는 것을 방지할 수 있습니다. +`event.preventDefault()`를 호출하면 새로운 창이 생성되는 것을 방지할 수 있습니다. ### Event: 'will-navigate' @@ -124,13 +123,13 @@ Returns: * `event` Event * `url` String -사용자 또는 페이지가 새로운 네비게이션을 원할 때 발생하는 이벤트입니다. +사용자 또는 페이지가 새로운 페이지로 이동할 때 발생하는 이벤트입니다. `window.location` 객체가 변경되거나 사용자가 페이지의 링크를 클릭했을 때 발생합니다. 이 이벤트는 `webContents.loadURL`과 `webContents.back` 같은 API를 이용하여 프로그램적으로 -시작된 네비게이션에 대해서는 발생하지 않습니다. +시작된 탐색에 대해서는 발생하지 않습니다. -`event.preventDefault()`를 호출하면 네비게이션을 방지할 수 있습니다. +`event.preventDefault()`를 호출하면 탐색을 방지할 수 있습니다. ### Event: 'crashed' @@ -152,15 +151,15 @@ Returns: ### Event: 'devtools-opened' -DevTools가 열렸을 때 발생되는 이벤트입니다. +개발자 도구가 열렸을 때 발생되는 이벤트입니다. ### Event: 'devtools-closed' -DevTools가 닫혔을 때 발생되는 이벤트입니다. +개발자 도구가 닫혔을 때 발생되는 이벤트입니다. ### Event: 'devtools-focused' -DevTools에 포커스가 가거나 DevTools가 열렸을 때 발생되는 이벤트입니다. +개발자 도구에 포커스가 가거나 개발자 도구가 열렸을 때 발생되는 이벤트입니다. ### Event: 'login' @@ -185,13 +184,13 @@ Returns: ## Instance Methods -`webContents`객체는 다음과 같은 인스턴스 메소드들을 가지고 있습니다. +`webContents`객체는 다음과 같은 인스턴스 메서드들을 가지고 있습니다. ### `webContents.session` webContents에서 사용되는 `session`객체를 반환합니다. -[session 문서](session.md)에서 이 객체의 메소드들을 확인할 수 있습니다. +[session](session.md) 문서에서 이 객체의 메서드들을 확인할 수 있습니다. ### `webContents.loadURL(url[, options])` @@ -229,7 +228,7 @@ var currentURL = win.webContents.getURL(); ### `webContents.stop()` -대기중인 네비게이션들을 모두 멈춥니다. +대기중인 탐색 작업을 모두 멈춥니다. ### `webContents.reload()` @@ -237,11 +236,11 @@ var currentURL = win.webContents.getURL(); ### `webContents.reloadIgnoringCache()` -현재 페이지를 캐시를 무시한채로 새로고침합니다. +현재 웹 페이지의 캐시를 무시한 채로 새로고침합니다. ### `webContents.canGoBack()` -브라우저가 이전의 웹 페이지로 돌아갈 수 있는지 여부를 반환합니다. +브라우저가 이전 웹 페이지로 돌아갈 수 있는지 여부를 반환합니다. ### `webContents.canGoForward()` @@ -255,7 +254,7 @@ var currentURL = win.webContents.getURL(); ### `webContents.clearHistory()` -네비게이션 기록을 삭제합니다. +탐색 기록을 삭제합니다. ### `webContents.goBack()` @@ -269,13 +268,13 @@ var currentURL = win.webContents.getURL(); * `index` Integer -브라우저가 지정된 절대 웹 페이지 인덱스로 네비게이트하게 합니다. +브라우저가 지정된 절대 웹 페이지 인덱스로 탐색하게 합니다. ### `webContents.goToOffset(offset)` * `offset` Integer -"current entry"에서 지정된 offset으로 네비게이트 합니다. +"current entry"에서 지정된 offset으로 탐색합니다. ### `webContents.isCrashed()` @@ -285,27 +284,27 @@ var currentURL = win.webContents.getURL(); * `userAgent` String -현재의 웹 페이지의 유저 에이전트를 오버라이드 합니다. +현재 웹 페이지의 유저 에이전트를 덮어씌웁니다. ### `webContents.getUserAgent()` -현재 웹 페이지의 유저 에이전트 `String`을 반환합니다. +현재 웹 페이지의 유저 에이전트 문자열을 반환합니다. ### `webContents.insertCSS(css)` * `css` String -Injects CSS into the current web page. +CSS 코드를 현재 웹 페이지에 삽입합니다. ### `webContents.executeJavaScript(code[, userGesture])` * `code` String * `userGesture` Boolean (optional) -페이지에서 코드를 실행합니다. +페이지에서 자바스크립트 코드를 실행합니다. -브라우저 윈도우에서 `requestFullScreen`와 같은 몇몇 HTML API들은 사용자의 행동으로만 호출될 수 -있습니다. `userGesture`를 `true`로 설정하면 이런 제약을 무시할 수 있습니다. +기본적으로 `requestFullScreen`와 같은 몇몇 HTML API들은 사용자의 조작에 의해서만 호출될 수 있습니다. +`userGesture`를 `true`로 설정하면 이러한 제약을 무시할 수 있습니다. ### `webContents.setAudioMuted(muted)` @@ -319,64 +318,64 @@ Injects CSS into the current web page. ### `webContents.undo()` -웹 페이지에서 `undo` 에디팅 커맨드를 실행합니다. +웹 페이지에서 `undo` 편집 커맨드를 실행합니다. ### `webContents.redo()` -웹 페이지에서 `redo` 에디팅 커맨드를 실행합니다. +웹 페이지에서 `redo` 편집 커맨드를 실행합니다. ### `webContents.cut()` -웹 페이지에서 `cut` 에디팅 커맨드를 실행합니다. +웹 페이지에서 `cut` 편집 커맨드를 실행합니다. ### `webContents.copy()` -웹 페이지에서 `copy` 에디팅 커맨드를 실행합니다. +웹 페이지에서 `copy` 편집 커맨드를 실행합니다. ### `webContents.paste()` -웹 페이지에서 `paste` 에디팅 커맨드를 실행합니다. +웹 페이지에서 `paste` 편집 커맨드를 실행합니다. ### `webContents.pasteAndMatchStyle()` -웹 페이지에서 `pasteAndMatchStyle` 에디팅 커맨드를 실행합니다. +웹 페이지에서 `pasteAndMatchStyle` 편집 커맨드를 실행합니다. ### `webContents.delete()` -웹 페이지에서 `delete` 에디팅 커맨드를 실행합니다. +웹 페이지에서 `delete` 편집 커맨드를 실행합니다. ### `webContents.selectAll()` -웹 페이지에서 `selectAll` 에디팅 커맨드를 실행합니다. +웹 페이지에서 `selectAll` 편집 커맨드를 실행합니다. ### `webContents.unselect()` -웹 페이지에서 `unselect` 에디팅 커맨드를 실행합니다. +웹 페이지에서 `unselect` 편집 커맨드를 실행합니다. ### `webContents.replace(text)` * `text` String -웹 페이지에서 `replace` 에디팅 커맨드를 실행합니다. +웹 페이지에서 `replace` 편집 커맨드를 실행합니다. ### `webContents.replaceMisspelling(text)` * `text` String -웹 페이지에서 `replaceMisspelling` 에디팅 커맨드를 실행합니다. +웹 페이지에서 `replaceMisspelling` 편집 커맨드를 실행합니다. ### `webContents.hasServiceWorker(callback)` * `callback` Function -ServiceWorker가 등록되어있는지 확인하고 `callback`에 대한 응답으로 boolean을 반환합니다. +ServiceWorker가 등록되어있는지 확인하고 `callback`에 대한 응답으로 boolean 값을 반환합니다. ### `webContents.unregisterServiceWorker(callback)` * `callback` Function -ServiceWorker가 존재하면 모두 등록을 해제하고 JS promise가 만족될 때 `callback`에 대한 -응답으로 boolean을 반환하거나 JS promise가 만족되지 않을 때 false를 반환합니다. +ServiceWorker가 존재하면 모두 등록을 해제하고 JS Promise가 만족될 때 `callback`에 대한 +응답으로 boolean을 반환하거나 JS Promise가 만족되지 않을 때 `false`를 반환합니다. ### `webContents.print([options])` @@ -392,8 +391,8 @@ ServiceWorker가 존재하면 모두 등록을 해제하고 JS promise가 만족 웹 페이지에서 `window.print()`를 호출하는 것은 `webContents.print({silent: false, printBackground: false})`를 호출하는 것과 같습니다. -**Note:** 윈도우즈에서 print API는 `pdf.dll`에 의존합니다. 당신의 어플리케이션이 print 기능을 -필요로 하지 않는다면 바이너리 크기를 줄이기 위해 `pdf.dll`을 삭제하셔도 안전합니다. +**Note:** Windows에서의 프린터 API는 `pdf.dll`에 의존합니다. +어플리케이션이 print 기능을 사용하지 않는 경우 전체 바이너리 크기를 줄이기 위해 `pdf.dll`을 삭제해도 됩니다. ### `webContents.printToPDF(options, callback)` @@ -456,18 +455,18 @@ win.webContents.on("did-finish-load", function() { * `path` String -특정 경로를 DevTools의 워크스페이스에 추가합니다. +특정 경로를 개발자 도구의 워크스페이스에 추가합니다. ### `webContents.removeWorkSpace(path)` * `path` String -특정 경로를 DevTools의 워크스페이스에서 제거합니다. +특정 경로를 개발자 도구의 워크스페이스에서 제거합니다. ### `webContents.openDevTools([options])` * `options` Object (optional). Properties: - * `detach` Boolean - 새 창에서 DevTools를 엽니다. + * `detach` Boolean - 새 창에서 개발자 도구를 엽니다. 개발자 도구를 엽니다. @@ -538,18 +537,18 @@ app.on('ready', function() { `parameters` Object, properties: * `screenPosition` String - 에뮬레이트 할 화면 종료를 지정합니다 - (default: `desktop`) + (기본값: `desktop`) * `desktop` * `mobile` * `screenSize` Object - 에뮬레이트 화면의 크기를 지정합니다 (screenPosition == mobile) * `width` Integer - 에뮬레이트 화면의 너비를 지정합니다 * `height` Integer - 에뮬레이트 화면의 높이를 지정합니다 * `viewPosition` Object - 화면에서 뷰의 위치 - (screenPosition == mobile) (default: `{x: 0, y: 0}`) + (screenPosition == mobile) (기본값: `{x: 0, y: 0}`) * `x` Integer - 좌상단 모서리로부터의 x 축의 오프셋 * `y` Integer - 좌상단 모서리로부터의 y 축의 오프셋 * `deviceScaleFactor` Integer - 디바이스의 스케일 팩터(scale factor)를 지정합니다. - (0일 경우 기본 디바이스 스케일 팩터를 기본으로 사용합니다) (default: `0`) + (0일 경우 기본 디바이스 스케일 팩터를 기본으로 사용합니다) (기본값: `0`) * `viewSize` Object - 에뮬레이트 된 뷰의 크기를 지정합니다 (빈 값은 오버라이드 하지 않는 다는 것을 의미합니다) * `width` Integer - 에뮬레이트 된 뷰의 너비를 지정합니다 @@ -572,20 +571,22 @@ app.on('ready', function() { ### `webContents.sendInputEvent(event)` * `event` Object - * `type` String (**required**) - 이벤트의 타입. 다음 값들이 가능합니다. `mouseDown`, + * `type` String (**required**) - 이벤트의 타입. 다음 값들을 사용할 수 있습니다: `mouseDown`, `mouseUp`, `mouseEnter`, `mouseLeave`, `contextMenu`, `mouseWheel`, `keyDown`, `keyUp`, `char`. * `modifiers` Array - 이벤트의 수정자(modifier)들에 대한 배열. 다음 값들을 포함 할 수 - 있습니다. `shift`, `control`, `alt`, `meta`, `isKeypad`, `isAutoRepeat`, + 있습니다: `shift`, `control`, `alt`, `meta`, `isKeypad`, `isAutoRepeat`, `leftButtonDown`, `middleButtonDown`, `rightButtonDown`, `capsLock`, `numLock`, `left`, `right`. -input `event`를 페이지로 보냅니다. +Input `event`를 웹 페이지로 전송합니다. -키보드 이벤트들에 대해서는 `event` 객체는 다음 속성들을 추가적으로 가지고 있습니다: +키보드 이벤트들에 대해서는 `event` 객체는 다음 속성들을 추가로 가지고 있습니다: -* `keyCode` String (**required**) - 키보드 이벤트로 보낼 수 있는 단일 캐릭터. 모든 UTF-8가 - 사용 가능합니다. +* `keyCode` String (**required**) - 키보드 이벤트로 보내지는 문자. + 단일 UTF-8 문자를 사용할 수 있고 이벤트를 발생시키는 다음 키 중 하나를 포함할 수 있습니다: + `enter`, `backspace`, `delete`, `tab`, `escape`, `control`, `alt`, `shift`, `end`, + `home`, `insert`, `left`, `up`, `right`, `down`, `pageUp`, `pageDown`, `printScreen` 마우스 이벤트들에 대해서는 `event` 객체는 다음 속성들을 추가적으로 가지고 있습니다: @@ -631,10 +632,9 @@ BGRA 포맷으로 효율적으로 저장됩니다. 하지만 실제 재프리젠 ### `webContents.devToolsWebContents` -이 `WebContents`에 대한 DevTools의 `WebContents`를 가져옵니다. +이 `WebContents`에 대한 개발자 도구의 `WebContents`를 가져옵니다. -**Note:** 사용자가 절대로 이 객체를 저장해서는 안됩니다. 그럴경우 DevTools가 닫혔을 때, `null`이 -될 수도 있습니다. +**Note:** 사용자가 절대로 이 객체를 저장해서는 안 됩니다. 개발자 도구가 닫혔을 때, `null`이 반환될 수 있습니다. ### `webContents.savePage(fullPath, saveType, callback)` diff --git a/docs-translations/ko-KR/api/web-view-tag.md b/docs-translations/ko-KR/api/web-view-tag.md index eb40151a234d..7b3d259fdfc7 100644 --- a/docs-translations/ko-KR/api/web-view-tag.md +++ b/docs-translations/ko-KR/api/web-view-tag.md @@ -256,15 +256,15 @@ webview.addEventListener("dom-ready", function() { ### `.openDevTools()` -페이지에 대한 개발자 콘솔을 엽니다. +페이지에 대한 개발자 도구를 엽니다. ### `.closeDevTools()` -페이지에 대한 개발자 콘솔을 닫습니다. +페이지에 대한 개발자 도구를 닫습니다. ### `.isDevToolsOpened()` -페이지에 대한 개발자 콘솔이 열려있는지 확인합니다. 불린 값을 반환합니다. +페이지에 대한 개발자 도구가 열려있는지 확인합니다. 불린 값을 반환합니다. ### `.inspectElement(x, y)` @@ -275,7 +275,7 @@ webview.addEventListener("dom-ready", function() { ### `.inspectServiceWorker()` -Service worker에 대한 개발자 콘솔을 엽니다. +Service worker에 대한 개발자 도구를 엽니다. ### `.undo()` diff --git a/docs-translations/ko-KR/tutorial/debugging-main-process.md b/docs-translations/ko-KR/tutorial/debugging-main-process.md index c11f3db04f3a..b03e2542dcd3 100644 --- a/docs-translations/ko-KR/tutorial/debugging-main-process.md +++ b/docs-translations/ko-KR/tutorial/debugging-main-process.md @@ -1,6 +1,6 @@ # 메인 프로세스 디버깅하기 -브라우저 창의 개발자 콘솔은 웹 페이지 같은 랜더러 프로세스의 스크립트만 디버깅이 가능합니다. +브라우저 창의 개발자 도구는 웹 페이지 같은 랜더러 프로세스의 스크립트만 디버깅이 가능합니다. 대신 Electron은 메인 프로세스의 디버깅을 위해 `--debug` 과 `--debug-brk` 스위치들을 제공합니다. ## 커맨드 라인 스위치(command line switches) diff --git a/docs-translations/ko-KR/tutorial/devtools-extension.md b/docs-translations/ko-KR/tutorial/devtools-extension.md index 04b592955cdc..05ec3893ead0 100644 --- a/docs-translations/ko-KR/tutorial/devtools-extension.md +++ b/docs-translations/ko-KR/tutorial/devtools-extension.md @@ -1,8 +1,8 @@ -# 개발자 콘솔 확장 +# 개발자 도구 확장 기능 어플리케이션의 디버깅을 쉽게 하기 위해 Electron은 기본적으로 [Chrome DevTools Extension][devtools-extension]을 지원합니다. -개발자 콘솔 확장 기능은 간단하게 사용할 확장 기능 플러그인의 소스 코드를 다운로드한 후 `BrowserWindow.addDevToolsExtension` API를 이용하여 +개발자 도구 확장 기능은 간단하게 사용할 확장 기능 플러그인의 소스 코드를 다운로드한 후 `BrowserWindow.addDevToolsExtension` API를 이용하여 어플리케이션 내에 로드할 수 있습니다. 한가지 주의할 점은 확장 기능 사용시 창이 생성될 때 마다 일일이 해당 API를 호출할 필요는 없습니다. ** 주의: 현재 React DevTools은 작동하지 않습니다. https://github.com/atom/electron/issues/915 이슈를 참고하세요! ** @@ -19,7 +19,7 @@ $ git clone --recursive https://github.com/facebook/react-devtools.git [`react-devtools/shells/chrome/Readme.md`](https://github.com/facebook/react-devtools/blob/master/shells/chrome/Readme.md) 를 통해 확장 기능을 개발하는 방법을 알아볼 수 있습니다. -그리고 개발자 콘솔에서 다음 코드를 입력하면 확장 기능을 로드할 수 있습니다: +그리고 개발자 도구에서 다음 코드를 입력하면 확장 기능을 로드할 수 있습니다: ```javascript const BrowserWindow = require('electron').remote.BrowserWindow; @@ -32,9 +32,9 @@ BrowserWindow.addDevToolsExtension('/some-directory/react-devtools/shells/chrome BrowserWindow.removeDevToolsExtension('React Developer Tools'); ``` -## 개발자 콘솔 확장 기능의 구성 형식 +## 개발자 도구 확장 기능의 구성 형식 -모든 개발자 콘솔 확장은 완벽히 Chrome 브라우저를 위해 작성되었기 때문에 Electron에서도 로드할 수 있습니다. +모든 개발자 도구 확장은 완벽히 Chrome 브라우저를 위해 작성되었기 때문에 Electron에서도 로드할 수 있습니다. 하지만 반드시 확장 기능은 소스 코드 디렉터리(폴더) 형태여야 합니다. 그래서 `crx` 등의 포맷으로 패키징된 확장 기능의 경우 사용자가 직접 해당 패키지의 압축을 풀어서 로드하지 않는 이상 Electron에서 해당 확장 기능의 압축을 풀 방법이 없습니다. diff --git a/docs-translations/ko-KR/tutorial/quick-start.md b/docs-translations/ko-KR/tutorial/quick-start.md index 2c1aa5f9837e..dea6a343e6bf 100644 --- a/docs-translations/ko-KR/tutorial/quick-start.md +++ b/docs-translations/ko-KR/tutorial/quick-start.md @@ -93,7 +93,7 @@ app.on('ready', function() { // 그리고 현재 디렉터리의 index.html을 로드합니다. mainWindow.loadURL('file://' + __dirname + '/index.html'); - // 개발자 콘솔을 엽니다. + // 개발자 도구를 엽니다. mainWindow.webContents.openDevTools(); // 창이 닫히면 호출됩니다. From c21d7b537a9621b93dc2e42e1102a258d02613ff Mon Sep 17 00:00:00 2001 From: Plusb Preco Date: Wed, 18 Nov 2015 03:40:58 +0900 Subject: [PATCH 194/249] Update as upstream --- docs-translations/ko-KR/api/app.md | 4 ++-- docs-translations/ko-KR/api/session.md | 24 +++++++++++++++++++++ docs-translations/ko-KR/api/web-contents.md | 19 ++++++++++------ 3 files changed, 38 insertions(+), 9 deletions(-) diff --git a/docs-translations/ko-KR/api/app.md b/docs-translations/ko-KR/api/app.md index d5fa007618a8..51e88c534ff4 100644 --- a/docs-translations/ko-KR/api/app.md +++ b/docs-translations/ko-KR/api/app.md @@ -140,8 +140,8 @@ Returns: * `webContents` [WebContents](web-contents.md) * `url` URL * `certificateList` [Objects] - * `data` PEM으로 인코딩된 데이터 - * `issuerName` 발급자의 공통 이름 + * `data` Buffer - PEM으로 인코딩된 데이터 + * `issuerName` String - 발급자의 공통 이름 * `callback` Function 사용자 인증이 요청되었을 때 발생하는 이벤트 입니다. diff --git a/docs-translations/ko-KR/api/session.md b/docs-translations/ko-KR/api/session.md index ad7ceaced4fc..749ca6efbb0f 100644 --- a/docs-translations/ko-KR/api/session.md +++ b/docs-translations/ko-KR/api/session.md @@ -33,6 +33,30 @@ 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 + +`hostname`에 대한 `certificate`의 유효성 검증이 실패했을 때 발생하는 이벤트 입니다. +인증서를 신뢰한다면 `event.preventDefault()` 와 `callback(true)`를 호출하여 기본 동작을 방지해야 합니다. + +```javascript +session.on('verify-certificate', function(event, hostname, certificate, callback) { + if (hostname == "github.com") { + // verification logic. + event.preventDefault(); + callback(true); + } else { + callback(false); + } +}); +``` + ## Methods `session` 객체는 다음과 같은 메서드와 속성을 가지고 있습니다: diff --git a/docs-translations/ko-KR/api/web-contents.md b/docs-translations/ko-KR/api/web-contents.md index 89c5a4a767f0..3193527f9c79 100644 --- a/docs-translations/ko-KR/api/web-contents.md +++ b/docs-translations/ko-KR/api/web-contents.md @@ -200,8 +200,13 @@ webContents에서 사용되는 `session`객체를 반환합니다. * `userAgent` String - 요청을 시작한 유저 에이전트. * `extraHeaders` String - "\n"로 구분된 Extra 헤더들. -윈도우에 `url`을 로드합니다. `url`은 `http://` or `file://`과 같은 프로토콜 접두사를 -가지고 있어야 합니다. +윈도우에 웹 페이지 `url`을 로드합니다. `url`은 `http://` or `file://`과 같은 프로토콜 접두사를 가지고 있어야 합니다. +만약 반드시 http 캐시를 사용하지 않고 로드해야 하는 경우 `pragma` 헤더를 사용할 수 있습니다. + +```javascript +const options = {"extraHeaders" : "pragma: no-cache\n"} +webContents.loadURL(url, options) +``` ### `webContents.getURL()` @@ -573,7 +578,7 @@ app.on('ready', function() { * `event` Object * `type` String (**required**) - 이벤트의 타입. 다음 값들을 사용할 수 있습니다: `mouseDown`, `mouseUp`, `mouseEnter`, `mouseLeave`, `contextMenu`, `mouseWheel`, - `keyDown`, `keyUp`, `char`. + `mouseMove`, `keyDown`, `keyUp`, `char`. * `modifiers` Array - 이벤트의 수정자(modifier)들에 대한 배열. 다음 값들을 포함 할 수 있습니다: `shift`, `control`, `alt`, `meta`, `isKeypad`, `isAutoRepeat`, `leftButtonDown`, `middleButtonDown`, `rightButtonDown`, `capsLock`, @@ -581,14 +586,14 @@ app.on('ready', function() { Input `event`를 웹 페이지로 전송합니다. -키보드 이벤트들에 대해서는 `event` 객체는 다음 속성들을 추가로 가지고 있습니다: +키보드 이벤트들에 대해서는 `event` 객체는 다음 속성들을 사용할 수 있습니다: -* `keyCode` String (**required**) - 키보드 이벤트로 보내지는 문자. +* `keyCode` Char or String (**required**) - 키보드 이벤트로 보내지는 문자. 단일 UTF-8 문자를 사용할 수 있고 이벤트를 발생시키는 다음 키 중 하나를 포함할 수 있습니다: `enter`, `backspace`, `delete`, `tab`, `escape`, `control`, `alt`, `shift`, `end`, `home`, `insert`, `left`, `up`, `right`, `down`, `pageUp`, `pageDown`, `printScreen` -마우스 이벤트들에 대해서는 `event` 객체는 다음 속성들을 추가적으로 가지고 있습니다: +마우스 이벤트들에 대해서는 `event` 객체는 다음 속성들을 사용할 수 있습니다: * `x` Integer (**required**) * `y` Integer (**required**) @@ -599,7 +604,7 @@ Input `event`를 웹 페이지로 전송합니다. * `movementY` Integer * `clickCount` Integer -`mouseWheel` 이벤트에 대해서는 `event` 객체는 다음 속성들을 추가적으로 가지고 있습니다: +`mouseWheel` 이벤트에 대해서는 `event` 객체는 다음 속성들을 사용할 수 있습니다: * `deltaX` Integer * `deltaY` Integer From 9c69416e322ca62930956030540a3cedf582a006 Mon Sep 17 00:00:00 2001 From: Ben Gotow Date: Tue, 17 Nov 2015 13:43:55 -0800 Subject: [PATCH 195/249] Fix sizing of Mac OS X tray icon after image change - Consolidate logic that applies view dimensions into a function - Use `NSVariableStatusItemLength` instead of trying to sync status item width - Use modern Obj-C syntax `@[], @{}` in a few places - Recompute view bounds after updating image in `setImage:` --- atom/browser/ui/tray_icon_cocoa.mm | 50 ++++++++++++++++-------------- docs/api/tray.md | 3 +- 2 files changed, 28 insertions(+), 25 deletions(-) diff --git a/atom/browser/ui/tray_icon_cocoa.mm b/atom/browser/ui/tray_icon_cocoa.mm index 34ca4e9a9112..0527681cd3ec 100644 --- a/atom/browser/ui/tray_icon_cocoa.mm +++ b/atom/browser/ui/tray_icon_cocoa.mm @@ -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 { diff --git a/docs/api/tray.md b/docs/api/tray.md index 528705acb325..7e84ad202bb4 100644 --- a/docs/api/tray.md +++ b/docs/api/tray.md @@ -158,7 +158,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_ From 57aecbc415bb19c07f31802e0913c809e5c7e1a3 Mon Sep 17 00:00:00 2001 From: Plusb Preco Date: Wed, 18 Nov 2015 07:09:10 +0900 Subject: [PATCH 196/249] Small changes --- docs-translations/ko-KR/api/menu-item.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/docs-translations/ko-KR/api/menu-item.md b/docs-translations/ko-KR/api/menu-item.md index b17d3b9ec391..dfcc4fcb2413 100644 --- a/docs-translations/ko-KR/api/menu-item.md +++ b/docs-translations/ko-KR/api/menu-item.md @@ -40,11 +40,11 @@ OS X에서의 `role`은 다음 값을 추가로 가질 수 있습니다: -* `about` - 매핑된 `orderFrontStandardAboutPanel` 액션 -* `hide` - 매핑된 `hide` 액션 -* `hideothers` - 매핑된 `hideOtherApplications` 액션 -* `unhide` - 매핑된 `unhideAllApplications` 액션 -* `front` - 매핑된 `arrangeInFront` 액션 +* `about` - `orderFrontStandardAboutPanel` 액션에 대응 +* `hide` - `hide` 액션에 대응 +* `hideothers` - `hideOtherApplications` 액션에 대응 +* `unhide` - `unhideAllApplications` 액션에 대응 +* `front` - `arrangeInFront` 액션에 대응 * `window` - 부 메뉴를 가지는 "Window" 메뉴 * `help` - 부 메뉴를 가지는 "Help" 메뉴 * `services` - 부 메뉴를 가지는 "Services" 메뉴 From 7cc965b178c44b6e0e7117032f04549bb25ec718 Mon Sep 17 00:00:00 2001 From: Plusb Preco Date: Wed, 18 Nov 2015 09:21:38 +0900 Subject: [PATCH 197/249] Translate docs --- docs-translations/ko-KR/README.md | 2 +- docs-translations/ko-KR/api/browser-window.md | 69 ++++++++++--------- 2 files changed, 36 insertions(+), 35 deletions(-) diff --git a/docs-translations/ko-KR/README.md b/docs-translations/ko-KR/README.md index 39b9367d0ecf..a6328586b5de 100644 --- a/docs-translations/ko-KR/README.md +++ b/docs-translations/ko-KR/README.md @@ -32,7 +32,7 @@ * [app](api/app.md) * [autoUpdater](api/auto-updater.md) -* [BrowserWindow (20% 번역됨 - 작업중)](api/browser-window.md) +* [BrowserWindow (30% 번역됨 - 작업중)](api/browser-window.md) * [contentTracing](api/content-tracing.md) * [dialog](api/dialog.md) * [globalShortcut](api/global-shortcut.md) diff --git a/docs-translations/ko-KR/api/browser-window.md b/docs-translations/ko-KR/api/browser-window.md index 30165e858519..10dc0a8ff101 100644 --- a/docs-translations/ko-KR/api/browser-window.md +++ b/docs-translations/ko-KR/api/browser-window.md @@ -118,103 +118,104 @@ Returns: * `event` Event -Emitted when the window is going to be closed. It's emitted before the -`beforeunload` and `unload` event of the DOM. Calling `event.preventDefault()` -will cancel the close. +윈도우가 닫히기 시작할 때 발생하는 이벤트입니다. +이 이벤트는 DOM의 `beforeunload` 와 `unload` 이벤트가 호출되기 전에 발생합니다. +`event.preventDefault()`를 호출하여 윈도우 종료를 취소할 수 있습니다. -Usually you would want to use the `beforeunload` handler to decide whether the -window should be closed, which will also be called when the window is -reloaded. In Electron, returning an empty string or `false` would cancel the -close. For example: +보통 창을 닫아야 할지 결정하기 위해 `beforeunload` 이벤트를 사용하려고 할 것입니다. +이 이벤트는 윈도우 컨텐츠를 새로고칠 때도 발생합니다. +Electron에선 빈 문자열 또는 `false`를 전달할 경우 윈도우 종료를 취소합니다. + +예시는 다음과 같습니다: ```javascript window.onbeforeunload = function(e) { console.log('I do not want to be closed'); - // Unlike usual browsers, in which a string should be returned and the user is - // prompted to confirm the page unload, Electron gives developers more options. - // Returning empty string or false would prevent the unloading now. - // You can also use the dialog API to let the user confirm closing the application. + // 반드시 문자열을 반환해야 하고 사용자에게 페이지 언로드에 대한 확인 창을 보여주는 보통의 브라우저와는 달리 + // Electron은 개발자에게 더 많은 옵션을 제공합니다. + // 빈 문자열을 반환하거나 false를 반환하면 페이지 언로드를 방지합니다. + // 또한 dialog API를 통해 사용자에게 어플리케이션을 종료할지에 대한 확인 창을 보여줄 수도 있습니다. e.returnValue = false; }; ``` ### Event: 'closed' -Emitted when the window is closed. After you have received this event you should -remove the reference to the window and avoid using it anymore. +윈도우 종료가 완료된 경우 발생하는 이벤트입니다. +이 이벤트가 발생했을 경우 반드시 윈도우 창의 레퍼런스가 더 이상 사용되지 않도록 제거해야 합니다. ### Event: 'unresponsive' -Emitted when the web page becomes unresponsive. +웹 페이지가 응답하지 않을 때 발생하는 이벤트입니다. ### Event: 'responsive' -Emitted when the unresponsive web page becomes responsive again. +응답하지 않는 웹 페이지가 다시 응답하기 시작했을 때 발생하는 이벤트입니다. ### Event: 'blur' -Emitted when the window loses focus. +윈도우가 포커스를 잃었을 떄 발생하는 이벤트입니다. ### Event: 'focus' -Emitted when the window gains focus. +윈도우가 포커스를 가졌을 때 발생하는 이벤트입니다. ### Event: 'maximize' -Emitted when window is maximized. +윈도우가 최대화됐을 때 발생하는 이벤트입니다. ### Event: 'unmaximize' -Emitted when the window exits from maximized state. +윈도우의 최대화 상태가 해제되었을 때 발생하는 이벤트입니다. ### Event: 'minimize' -Emitted when the window is minimized. +윈도우가 최소화됐을 때 발생하는 이벤트입니다. ### Event: 'restore' -Emitted when the window is restored from minimized state. +윈도우가 최소화 상태에서 복구되었을 때 발생하는 이벤트입니다. ### Event: 'resize' -Emitted when the window is getting resized. +윈도우의 크기가 재조정될 때 발생하는 이벤트입니다. ### Event: 'move' -Emitted when the window is getting moved to a new position. +윈도우가 새로운 위치로 이동될 때 발생하는 이벤트입니다. -__Note__: On OS X this event is just an alias of `moved`. +__참고__: OS X에선 이 이벤트가 그저 `moved` 이벤트의 별칭(alias)으로 사용됩니다. ### Event: 'moved' _OS X_ -Emitted once when the window is moved to a new position. +윈도우가 새로운 위치로 이동되었을 때 발생하는 이벤트입니다. (한 번만) ### Event: 'enter-full-screen' -Emitted when the window enters full screen state. +윈도우가 풀 스크린 모드로 진입할 때 발생하는 이벤트입니다. ### Event: 'leave-full-screen' -Emitted when the window leaves full screen state. +윈도우가 풀 스크린 모드에서 해제될 때 발생하는 이벤트입니다. ### Event: 'enter-html-full-screen' -Emitted when the window enters full screen state triggered by html api. +윈도우가 HTML API에 의해 풀 스크린 모드로 진입할 때 발생하는 이벤트입니다. ### Event: 'leave-html-full-screen' -Emitted when the window leaves full screen state triggered by html api. +윈도우가 HTML API에 의해 풀 스크린 모드에서 해제될 때 발생하는 이벤트입니다. ### Event: 'app-command': -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 -commands, as well as the "Back" button built into some mice on Windows. +[App Command](https://msdn.microsoft.com/en-us/library/windows/desktop/ms646275(v=vs.85).aspx)가 호출됐을 때 발생하는 이벤트입니다. +이 이벤트는 일반적으로 키보드 미디어 키 또는 브라우저 커맨드(기본 동작 키)에 관련되어 있습니다. +예를 들어 Windows에서 작동하는 몇몇 마우스는 "뒤로가기" 같은 동작을 포함하고 있습니다. -```js +```javascript someWindow.on('app-command', function(e, cmd) { - // Navigate the window back when the user hits their mouse back button + // 마우스의 뒤로가기 버튼을 눌렀을 때 뒤로가기 탐색을 실행합니다 if (cmd === 'browser-backward' && someWindow.webContents.canGoBack()) { someWindow.webContents.goBack(); } From 0dd14ad204d9951f63a0c4b24e5c511a5a82b807 Mon Sep 17 00:00:00 2001 From: Plusb Preco Date: Wed, 18 Nov 2015 09:36:14 +0900 Subject: [PATCH 198/249] 'app-command' event is only available in Windows --- docs/api/browser-window.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/api/browser-window.md b/docs/api/browser-window.md index 3b293e99621c..80b7a5f35271 100644 --- a/docs/api/browser-window.md +++ b/docs/api/browser-window.md @@ -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 From 0e8ab0688d00e476c0baa9b74ce5c5cfc3d37de2 Mon Sep 17 00:00:00 2001 From: Plusb Preco Date: Wed, 18 Nov 2015 09:43:28 +0900 Subject: [PATCH 199/249] Fix wrong markdown --- docs/api/browser-window.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/api/browser-window.md b/docs/api/browser-window.md index 80b7a5f35271..e5fcfb9003ae 100644 --- a/docs/api/browser-window.md +++ b/docs/api/browser-window.md @@ -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' __Windows__ +### 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 From d129aa9085ce71e8de21abd489f0e218c18891fe Mon Sep 17 00:00:00 2001 From: Plusb Preco Date: Wed, 18 Nov 2015 09:50:14 +0900 Subject: [PATCH 200/249] Update as upstream --- docs-translations/ko-KR/api/browser-window.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs-translations/ko-KR/api/browser-window.md b/docs-translations/ko-KR/api/browser-window.md index 10dc0a8ff101..1046f8bd5ca7 100644 --- a/docs-translations/ko-KR/api/browser-window.md +++ b/docs-translations/ko-KR/api/browser-window.md @@ -207,7 +207,7 @@ __참고__: OS X에선 이 이벤트가 그저 `moved` 이벤트의 별칭(alias 윈도우가 HTML API에 의해 풀 스크린 모드에서 해제될 때 발생하는 이벤트입니다. -### Event: 'app-command': +### Event: 'app-command' _Windows_ [App Command](https://msdn.microsoft.com/en-us/library/windows/desktop/ms646275(v=vs.85).aspx)가 호출됐을 때 발생하는 이벤트입니다. 이 이벤트는 일반적으로 키보드 미디어 키 또는 브라우저 커맨드(기본 동작 키)에 관련되어 있습니다. From 1022179a1ff78c9622538ec150517ffcedffb78c Mon Sep 17 00:00:00 2001 From: Ben Gotow Date: Tue, 17 Nov 2015 17:36:37 -0800 Subject: [PATCH 201/249] Improve exception messages from remote calls Spent a while tracking down `Error processing argument -1`, caused by a missing param (`app.exit()` now takes an exit code.) Improve the rpc-server so that it prints the function name when possible, so it's much easier to identify which remote call is causing the error. --- atom/browser/lib/rpc-server.coffee | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/atom/browser/lib/rpc-server.coffee b/atom/browser/lib/rpc-server.coffee index ae4b161674bd..830b966f04a2 100644 --- a/atom/browser/lib/rpc-server.coffee +++ b/atom/browser/lib/rpc-server.coffee @@ -103,13 +103,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) -> From c2eddb20f7c75473e30f45d6f495131df3a24831 Mon Sep 17 00:00:00 2001 From: "Howard.Zuo" Date: Wed, 18 Nov 2015 09:37:45 +0800 Subject: [PATCH 202/249] use loadURL since loadUrl is deprecated --- docs-translations/es/tutorial/quick-start.md | 4 ++-- docs-translations/jp/quick-start.md | 2 +- docs-translations/pt-BR/tutorial/quick-start.md | 14 +++++++------- docs-translations/zh-CN/tutorial/quick-start.md | 2 +- docs-translations/zh-TW/tutorial/quick-start.md | 4 ++-- 5 files changed, 13 insertions(+), 13 deletions(-) diff --git a/docs-translations/es/tutorial/quick-start.md b/docs-translations/es/tutorial/quick-start.md index 3db92177ca24..ee1127eb0269 100644 --- a/docs-translations/es/tutorial/quick-start.md +++ b/docs-translations/es/tutorial/quick-start.md @@ -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(); diff --git a/docs-translations/jp/quick-start.md b/docs-translations/jp/quick-start.md index aa26a8a55ab0..9a929ff84dc4 100644 --- a/docs-translations/jp/quick-start.md +++ b/docs-translations/jp/quick-start.md @@ -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(); diff --git a/docs-translations/pt-BR/tutorial/quick-start.md b/docs-translations/pt-BR/tutorial/quick-start.md index 3ec71961a92b..f9883144c825 100644 --- a/docs-translations/pt-BR/tutorial/quick-start.md +++ b/docs-translations/pt-BR/tutorial/quick-start.md @@ -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. diff --git a/docs-translations/zh-CN/tutorial/quick-start.md b/docs-translations/zh-CN/tutorial/quick-start.md index 165c30142e72..906db8f4458b 100644 --- a/docs-translations/zh-CN/tutorial/quick-start.md +++ b/docs-translations/zh-CN/tutorial/quick-start.md @@ -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(); diff --git a/docs-translations/zh-TW/tutorial/quick-start.md b/docs-translations/zh-TW/tutorial/quick-start.md index 068138587f1d..18c62c5e75ce 100644 --- a/docs-translations/zh-TW/tutorial/quick-start.md +++ b/docs-translations/zh-TW/tutorial/quick-start.md @@ -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 -``` \ No newline at end of file +``` From 9a0dc3bfd76604b983d4cfdff227da91895b0be1 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Wed, 18 Nov 2015 10:07:03 +0800 Subject: [PATCH 203/249] Add Delegate for AtomBrowserClient --- atom/browser/api/atom_api_app.cc | 45 +++++++++++++++-------------- atom/browser/api/atom_api_app.h | 10 +++++-- atom/browser/atom_browser_client.cc | 11 ++++--- atom/browser/atom_browser_client.h | 5 ++++ atom/browser/browser.cc | 13 --------- atom/browser/browser.h | 6 ---- atom/browser/browser_observer.h | 17 ----------- 7 files changed, 41 insertions(+), 66 deletions(-) diff --git a/atom/browser/api/atom_api_app.cc b/atom/browser/api/atom_api_app.cc index df28829c46a4..b1efea5c45d3 100644 --- a/atom/browser/api/atom_api_app.cc +++ b/atom/browser/api/atom_api_app.cc @@ -154,11 +154,14 @@ void PassLoginInformation(scoped_refptr login_handler, } // namespace App::App() { + static_cast(AtomBrowserClient::Get())->set_delegate(this); Browser::Get()->AddObserver(this); content::GpuDataManager::GetInstance()->AddObserver(this); } App::~App() { + static_cast(AtomBrowserClient::Get())->set_delegate( + nullptr); Browser::Get()->RemoveObserver(this); content::GpuDataManager::GetInstance()->RemoveObserver(this); } @@ -212,27 +215,6 @@ void App::OnFinishLaunching() { Emit("ready"); } -void App::OnSelectCertificate( - content::WebContents* web_contents, - net::SSLCertRequestInfo* cert_request_info, - scoped_ptr delegate) { - std::shared_ptr - shared_delegate(delegate.release()); - bool prevent_default = - Emit("select-certificate", - api::WebContents::CreateFrom(isolate(), web_contents), - cert_request_info->host_and_port.ToString(), - cert_request_info->client_certs, - base::Bind(&OnClientCertificateSelected, - isolate(), - shared_delegate)); - - // Default to first certificate from the platform store. - if (!prevent_default) - shared_delegate->ContinueWithCertificate( - 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()); @@ -258,6 +240,27 @@ void App::OnLogin(LoginHandler* login_handler) { login_handler->CancelAuth(); } +void App::SelectClientCertificate( + content::WebContents* web_contents, + net::SSLCertRequestInfo* cert_request_info, + scoped_ptr delegate) { + std::shared_ptr + shared_delegate(delegate.release()); + bool prevent_default = + Emit("select-certificate", + api::WebContents::CreateFrom(isolate(), web_contents), + cert_request_info->host_and_port.ToString(), + cert_request_info->client_certs, + base::Bind(&OnClientCertificateSelected, + isolate(), + shared_delegate)); + + // Default to first certificate from the platform store. + if (!prevent_default) + shared_delegate->ContinueWithCertificate( + cert_request_info->client_certs[0].get()); +} + void App::OnGpuProcessCrashed(base::TerminationStatus exit_code) { Emit("gpu-process-crashed"); } diff --git a/atom/browser/api/atom_api_app.h b/atom/browser/api/atom_api_app.h index 683093d886c9..c3793cd54267 100644 --- a/atom/browser/api/atom_api_app.h +++ b/atom/browser/api/atom_api_app.h @@ -8,6 +8,7 @@ #include #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,13 @@ 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 SelectClientCertificate( content::WebContents* web_contents, net::SSLCertRequestInfo* cert_request_info, scoped_ptr delegate) override; - void OnLogin(LoginHandler* login_handler) override; // content::GpuDataManagerObserver: void OnGpuProcessCrashed(base::TerminationStatus exit_code) override; diff --git a/atom/browser/atom_browser_client.cc b/atom/browser/atom_browser_client.cc index 4969ce47a679..7049f4896c12 100644 --- a/atom/browser/atom_browser_client.cc +++ b/atom/browser/atom_browser_client.cc @@ -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() { @@ -222,10 +221,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() { diff --git a/atom/browser/atom_browser_client.h b/atom/browser/atom_browser_client.h index ee4700456cc6..25849e92d4f7 100644 --- a/atom/browser/atom_browser_client.h +++ b/atom/browser/atom_browser_client.h @@ -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. @@ -74,6 +77,8 @@ class AtomBrowserClient : public brightray::BrowserClient, scoped_ptr resource_dispatcher_host_delegate_; + Delegate* delegate_; + DISALLOW_COPY_AND_ASSIGN(AtomBrowserClient); }; diff --git a/atom/browser/browser.cc b/atom/browser/browser.cc index 57741786520d..c77f359760c9 100644 --- a/atom/browser/browser.cc +++ b/atom/browser/browser.cc @@ -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 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)); } diff --git a/atom/browser/browser.h b/atom/browser/browser.h index e20db080b67a..e46624b158df 100644 --- a/atom/browser/browser.h +++ b/atom/browser/browser.h @@ -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 delegate); - // Request basic auth login. void RequestLogin(LoginHandler* login_handler); diff --git a/atom/browser/browser_observer.h b/atom/browser/browser_observer.h index 7dccbfbac3c5..f6d76bc13fb3 100644 --- a/atom/browser/browser_observer.h +++ b/atom/browser/browser_observer.h @@ -7,17 +7,6 @@ #include -#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 delegate) {} - // The browser requests HTTP login. virtual void OnLogin(LoginHandler* login_handler) {} From 341341bf28178481cfc17262395d94f7af7f5c98 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Wed, 18 Nov 2015 10:10:21 +0800 Subject: [PATCH 204/249] Rename select-certificate to select-client-certificate --- atom/browser/api/atom_api_app.cc | 2 +- atom/browser/api/lib/app.coffee | 1 + docs/api/app.md | 4 ++-- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/atom/browser/api/atom_api_app.cc b/atom/browser/api/atom_api_app.cc index b1efea5c45d3..95db0c61ed7f 100644 --- a/atom/browser/api/atom_api_app.cc +++ b/atom/browser/api/atom_api_app.cc @@ -247,7 +247,7 @@ void App::SelectClientCertificate( std::shared_ptr shared_delegate(delegate.release()); bool prevent_default = - Emit("select-certificate", + Emit("select-client-certificate", api::WebContents::CreateFrom(isolate(), web_contents), cert_request_info->host_and_port.ToString(), cert_request_info->client_certs, diff --git a/atom/browser/api/lib/app.coffee b/atom/browser/api/lib/app.coffee index f8d3cedd38f9..44efaa240652 100644 --- a/atom/browser/api/lib/app.coffee +++ b/atom/browser/api/lib/app.coffee @@ -52,6 +52,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) -> diff --git a/docs/api/app.md b/docs/api/app.md index e1a4cbf964e3..4ff90f3e5785 100644 --- a/docs/api/app.md +++ b/docs/api/app.md @@ -131,7 +131,7 @@ Returns: Emitted when a new [browserWindow](browser-window.md) is created. -### Event: 'select-certificate' +### Event: 'select-client-certificate' Returns: @@ -151,7 +151,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]); }) From 74e8c8d6a59503c9cf9319bf8aa8249e85fd1d68 Mon Sep 17 00:00:00 2001 From: Plusb Preco Date: Wed, 18 Nov 2015 11:28:03 +0900 Subject: [PATCH 205/249] Translate docs, small changes --- docs-translations/ko-KR/README.md | 2 +- docs-translations/ko-KR/api/browser-window.md | 74 +++++++++---------- docs-translations/ko-KR/api/web-contents.md | 4 +- 3 files changed, 37 insertions(+), 43 deletions(-) diff --git a/docs-translations/ko-KR/README.md b/docs-translations/ko-KR/README.md index a6328586b5de..6899c91c32fa 100644 --- a/docs-translations/ko-KR/README.md +++ b/docs-translations/ko-KR/README.md @@ -32,7 +32,7 @@ * [app](api/app.md) * [autoUpdater](api/auto-updater.md) -* [BrowserWindow (30% 번역됨 - 작업중)](api/browser-window.md) +* [BrowserWindow (50% 번역됨 - 작업중)](api/browser-window.md) * [contentTracing](api/content-tracing.md) * [dialog](api/dialog.md) * [globalShortcut](api/global-shortcut.md) diff --git a/docs-translations/ko-KR/api/browser-window.md b/docs-translations/ko-KR/api/browser-window.md index 1046f8bd5ca7..df2d8b4572e1 100644 --- a/docs-translations/ko-KR/api/browser-window.md +++ b/docs-translations/ko-KR/api/browser-window.md @@ -228,139 +228,133 @@ someWindow.on('app-command', function(e, cmd) { ### `BrowserWindow.getAllWindows()` -Returns an array of all opened browser windows. +열려있는 모든 브라우저 윈도우의 배열을 반환합니다. ### `BrowserWindow.getFocusedWindow()` -Returns the window that is focused in this application. +어플리케이션에서 포커스된 윈도우를 반환합니다. ### `BrowserWindow.fromWebContents(webContents)` * `webContents` [WebContents](web-contents.md) -Find a window according to the `webContents` it owns. +`webContents`를 소유하고 있는 윈도우를 찾습니다. ### `BrowserWindow.fromId(id)` * `id` Integer -Find a window according to its ID. +ID에 해당하는 윈도우를 찾습니다. ### `BrowserWindow.addDevToolsExtension(path)` * `path` String -Adds DevTools extension located at `path`, and returns extension's name. +`path`에 있는 개발자 도구 확장 기능을 추가합니다. 그리고 확장 기능의 이름을 반환합니다. -The extension will be remembered so you only need to call this API once, this -API is not for programming use. +확장 기능은 기억됩니다. 따라서 API는 단 한 번만 호출되어야 합니다. +이 API는 실제 프로그램 작성에 사용할 수 없습니다. ### `BrowserWindow.removeDevToolsExtension(name)` * `name` String -Remove the DevTools extension whose name is `name`. +`name`에 해당하는 개발자 도구 확장 기능을 제거합니다. ## Instance Properties -Objects created with `new BrowserWindow` have the following properties: +`new BrowserWindow`로 생성한 객체는 다음과 같은 속성을 가지고 있습니다: ```javascript -// In this example `win` is our instance +// `win`은 BrowserWindow의 인스턴스입니다 var win = new BrowserWindow({ width: 800, height: 600 }); ``` ### `win.webContents` -The `WebContents` object this window owns, all web page related events and -operations will be done via it. +윈도우의 `WebContents` 객체입니다. 모든 웹 페이지와 관련된 이벤트와 작업이 이 객체를 통해 수행됩니다. -See the [`webContents` documentation](web-contents.md) for its methods and -events. +메서드나 이벤트에 대한 자세한 내용은 [`webContents` 문서](web-contents.md)를 참고하세요. ### `win.id` -The unique ID of this window. +윈도우의 유일 ID입니다. ## Instance Methods -Objects created with `new BrowserWindow` have the following instance methods: +`new BrowserWindow`로 생성한 객체는 다음과 같은 메서드들을 가지고 있습니다: -**Note:** Some methods are only available on specific operating systems and are labeled as such. +**참고:** 몇몇 메서드들은 라벨에서 특정한 운영체제 시스템에서만 작동합니다. ### `win.destroy()` -Force closing the window, the `unload` and `beforeunload` event won't be emitted -for the web page, and `close` event will also not be emitted -for this window, but it guarantees the `closed` event will be emitted. +윈도우를 강제로 닫습니다. 웹 페이지의 `unload` 와 `beforeunload` 이벤트는 일어나지 않습니다. +또한 이 윈도우의 `close`도 일어나지 않습니다. 하지만 `closed` 이벤트는 반드시 발생함을 보장합니다. -You should only use this method when the renderer process (web page) has -crashed. +이 메서드는 렌더러 프로세스가 예기치 않게 크래시가 일어났을 경우에만 사용해야 합니다. ### `win.close()` -Try to close the window, this has the same effect with user manually clicking -the close button of the window. The web page may cancel the close though, see -the [close event](#event-close). +윈도우의 종료를 시도합니다. 이 메서드는 사용자가 윈도우의 닫기 버튼을 클릭했을 때와 같은 효과를 냅니다. +웹 페이지는 로드가 취소되고 종료됩니다. 자세한 내용은 [close 이벤트](#event-close)를 참고하세요. ### `win.focus()` -Focus on the window. +윈도우에 포커스를 맞춥니다. ### `win.isFocused()` -Returns a boolean, whether the window is focused. +윈도우가 포커스 되었는지 여부를 반환합니다. ### `win.show()` -Shows and gives focus to the window. +윈도우를 표시하고 포커스합니다. ### `win.showInactive()` -Shows the window but doesn't focus on it. +윈도우를 표시만 하고 포커스하지 않습니다. ### `win.hide()` -Hides the window. +윈도우를 숨깁니다. ### `win.isVisible()` -Returns a boolean, whether the window is visible to the user. +윈도우가 사용자에게 표시되고 있는지 여부를 반환합니다. ### `win.maximize()` -Maximizes the window. +윈도우를 최대화 시킵니다. ### `win.unmaximize()` -Unmaximizes the window. +윈도우 최대화를 취소합니다. ### `win.isMaximized()` -Returns a boolean, whether the window is maximized. +윈도우가 최대화 되어있는지 여부를 반환합니다. ### `win.minimize()` -Minimizes the window. On some platforms the minimized window will be shown in -the Dock. +윈도우를 최소화 시킵니다. 어떤 플랫폼은 최소화된 윈도우가 Dock에 표시됩니다. ### `win.restore()` -Restores the window from minimized state to its previous state. +최소화된 윈도우를 이전 상태로 되돌립니다. ### `win.isMinimized()` -Returns a boolean, whether the window is minimized. +윈도우가 최소화 되었는지 여부를 반환합니다. ### `win.setFullScreen(flag)` * `flag` Boolean -Sets whether the window should be in fullscreen mode. +윈도우의 전체화면 상태를 지정합니다. ### `win.isFullScreen()` -Returns a boolean, whether the window is in fullscreen mode. +윈도우가 전체화면 모드 상태인지 여부를 반환합니다. ### `win.setAspectRatio(aspectRatio[, extraSize])` _OS X_ diff --git a/docs-translations/ko-KR/api/web-contents.md b/docs-translations/ko-KR/api/web-contents.md index 3193527f9c79..c1452f063791 100644 --- a/docs-translations/ko-KR/api/web-contents.md +++ b/docs-translations/ko-KR/api/web-contents.md @@ -190,7 +190,7 @@ Returns: webContents에서 사용되는 `session`객체를 반환합니다. -[session](session.md) 문서에서 이 객체의 메서드들을 확인할 수 있습니다. +[session 문서](session.md)에서 이 객체의 메서드들을 확인할 수 있습니다. ### `webContents.loadURL(url[, options])` @@ -283,7 +283,7 @@ var currentURL = win.webContents.getURL(); ### `webContents.isCrashed()` -렌더러 프로세스가 예기치 않게 종료되었는지 여부를 반환합니다. +렌더러 프로세스가 예기치 않게 종료 되었는지 여부를 반환합니다. ### `webContents.setUserAgent(userAgent)` From e432abfb4272c9822bad5ac1ac157f9a99aa755b Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Wed, 18 Nov 2015 10:39:25 +0800 Subject: [PATCH 206/249] Add certificate-error event --- atom/browser/api/atom_api_app.cc | 53 +++++++++++++++++++--------- atom/browser/api/atom_api_app.h | 12 +++++++ atom/browser/api/atom_api_session.cc | 19 ---------- atom/browser/api/atom_api_session.h | 4 --- atom/browser/api/lib/app.coffee | 6 ++++ atom/browser/atom_browser_client.cc | 20 +++++++++++ atom/browser/atom_browser_client.h | 12 +++++++ 7 files changed, 87 insertions(+), 39 deletions(-) diff --git a/atom/browser/api/atom_api_app.cc b/atom/browser/api/atom_api_app.cc index 95db0c61ed7f..73f4b3927728 100644 --- a/atom/browser/api/atom_api_app.cc +++ b/atom/browser/api/atom_api_app.cc @@ -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" @@ -216,30 +218,49 @@ void App::OnFinishLaunching() { } 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(), + 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))); - 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::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& 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, + 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, @@ -248,7 +269,7 @@ void App::SelectClientCertificate( shared_delegate(delegate.release()); bool prevent_default = Emit("select-client-certificate", - api::WebContents::CreateFrom(isolate(), web_contents), + WebContents::CreateFrom(isolate(), web_contents), cert_request_info->host_and_port.ToString(), cert_request_info->client_certs, base::Bind(&OnClientCertificateSelected, diff --git a/atom/browser/api/atom_api_app.h b/atom/browser/api/atom_api_app.h index c3793cd54267..ee7e02079125 100644 --- a/atom/browser/api/atom_api_app.h +++ b/atom/browser/api/atom_api_app.h @@ -51,6 +51,18 @@ class App : public AtomBrowserClient::Delegate, 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& callback, + content::CertificateRequestResultType* request) override; void SelectClientCertificate( content::WebContents* web_contents, net::SSLCertRequestInfo* cert_request_info, diff --git a/atom/browser/api/atom_api_session.cc b/atom/browser/api/atom_api_session.cc index 6527f67ab3f1..3510a21668e9 100644 --- a/atom/browser/api/atom_api_session.cc +++ b/atom/browser/api/atom_api_session.cc @@ -238,12 +238,6 @@ void SetProxyInIO(net::URLRequestContextGetter* getter, RunCallbackInUI(callback); } -void PassVerificationResult( - scoped_refptr request, - bool success) { - request->ContinueWithResult(success ? net::OK : net::ERR_FAILED); -} - } // namespace Session::Session(AtomBrowserContext* browser_context) @@ -262,19 +256,6 @@ Session::~Session() { Destroy(); } -void Session::RequestCertVerification( - const scoped_refptr& 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(); diff --git a/atom/browser/api/atom_api_session.h b/atom/browser/api/atom_api_session.h index db72558db473..ebcfc45223db 100644 --- a/atom/browser/api/atom_api_session.h +++ b/atom/browser/api/atom_api_session.h @@ -54,10 +54,6 @@ class Session: public mate::TrackableObject, explicit Session(AtomBrowserContext* browser_context); ~Session(); - // AtomCertVerifier::Delegate: - void RequestCertVerification( - const scoped_refptr&) override; - // content::DownloadManager::Observer: void OnDownloadCreated(content::DownloadManager* manager, content::DownloadItem* item) override; diff --git a/atom/browser/api/lib/app.coffee b/atom/browser/api/lib/app.coffee index 44efaa240652..3db4582abc7c 100644 --- a/atom/browser/api/lib/app.coffee +++ b/atom/browser/api/lib/app.coffee @@ -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', -> diff --git a/atom/browser/atom_browser_client.cc b/atom/browser/atom_browser_client.cc index 7049f4896c12..38fdc0e19f9e 100644 --- a/atom/browser/atom_browser_client.cc +++ b/atom/browser/atom_browser_client.cc @@ -207,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& 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, diff --git a/atom/browser/atom_browser_client.h b/atom/browser/atom_browser_client.h index 25849e92d4f7..75e17494593b 100644 --- a/atom/browser/atom_browser_client.h +++ b/atom/browser/atom_browser_client.h @@ -57,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& callback, + content::CertificateRequestResultType* request) override; void SelectClientCertificate( content::WebContents* web_contents, net::SSLCertRequestInfo* cert_request_info, From 3af4a40860a2c048a07712a5b692bd9655efaac9 Mon Sep 17 00:00:00 2001 From: Plusb Preco Date: Wed, 18 Nov 2015 11:43:16 +0900 Subject: [PATCH 207/249] Translation docs --- docs-translations/ko-KR/api/browser-window.md | 37 +++++++++---------- 1 file changed, 18 insertions(+), 19 deletions(-) diff --git a/docs-translations/ko-KR/api/browser-window.md b/docs-translations/ko-KR/api/browser-window.md index df2d8b4572e1..95780bc74ed2 100644 --- a/docs-translations/ko-KR/api/browser-window.md +++ b/docs-translations/ko-KR/api/browser-window.md @@ -388,92 +388,91 @@ height areas you have within the overall content view. * `width` Integer * `height` Integer -Resizes and moves the window to `width`, `height`, `x`, `y`. +윈도우를 지정한 `width`, `height`, `x`, `y`로 크기 재조정 및 이동합니다. ### `win.getBounds()` -Returns an object that contains window's width, height, x and y values. +윈도우의 width, height, x, y 값을 가지는 객체를 반환합니다. ### `win.setSize(width, height)` * `width` Integer * `height` Integer -Resizes the window to `width` and `height`. +`width`와 `height` 값으로 윈도우 크기를 재조정합니다. (너비, 높이) ### `win.getSize()` -Returns an array that contains window's width and height. +윈도우의 너비, 높이값을 가지는 배열을 반환합니다. ### `win.setContentSize(width, height)` * `width` Integer * `height` Integer -Resizes the window's client area (e.g. the web page) to `width` and `height`. +윈도우 클라이언트 영역(웹 페이지)의 크기를 `width`, `height`로 재조정합니다. ### `win.getContentSize()` -Returns an array that contains window's client area's width and height. +윈도우 클라이언트 영역의 너비, 높이 크기를 배열로 반환합니다. ### `win.setMinimumSize(width, height)` * `width` Integer * `height` Integer -Sets the minimum size of window to `width` and `height`. +윈도우의 최소 `width`, `height` 크기를 지정합니다. ### `win.getMinimumSize()` -Returns an array that contains window's minimum width and height. +윈도우의 최소 너비, 높이 크기를 배열로 반환합니다. ### `win.setMaximumSize(width, height)` * `width` Integer * `height` Integer -Sets the maximum size of window to `width` and `height`. +윈도우의 최대 `width`, `height` 크기를 지정합니다. ### `win.getMaximumSize()` -Returns an array that contains window's maximum width and height. +윈도우의 최대 너비, 높이 크기를 배열로 반환합니다. ### `win.setResizable(resizable)` * `resizable` Boolean -Sets whether the window can be manually resized by user. +윈도우의 크기가 사용자에 의해 재조정될 수 있는지를 지정합니다. ### `win.isResizable()` -Returns whether the window can be manually resized by user. +윈도우의 크기가 사용자에 의해 재조정될 수 있는지 여부를 반환합니다. ### `win.setAlwaysOnTop(flag)` * `flag` Boolean -Sets whether the window should show always on top of other windows. After -setting this, the window is still a normal window, not a toolbox window which -can not be focused on. +윈도우가 언제나 다른 윈도우들 위에 표시되는지 여부를 지정합니다. +이 설정을 활성화 하면 윈도우는 포커스 될 수 없는 툴박스 윈도우가 아닌 일반 윈도우로 유지됩니다. ### `win.isAlwaysOnTop()` -Returns whether the window is always on top of other windows. +윈도우가 언제나 다른 윈도우들 위에 표시되는지 여부를 반환합니다. ### `win.center()` -Moves window to the center of the screen. +윈도우를 화면 정 중앙으로 이동합니다. ### `win.setPosition(x, y)` * `x` Integer * `y` Integer -Moves window to `x` and `y`. +윈도우의 위치를 `x`, `y`로 이동합니다. ### `win.getPosition()` -Returns an array that contains window's current position. +윈도우의 현재 위치를 배열로 반환합니다. ### `win.setTitle(title)` From c5bfac196914218ff98d2a45bc6287641594deea Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Wed, 18 Nov 2015 11:17:08 +0800 Subject: [PATCH 208/249] Add session.setCertificateVerifyProc --- atom/browser/api/atom_api_session.cc | 15 +++++- atom/browser/api/atom_api_session.h | 3 +- atom/browser/net/atom_cert_verifier.cc | 74 ++++++++++---------------- atom/browser/net/atom_cert_verifier.h | 61 ++++----------------- 4 files changed, 51 insertions(+), 102 deletions(-) diff --git a/atom/browser/api/atom_api_session.cc b/atom/browser/api/atom_api_session.cc index 3510a21668e9..2a2c7b2fff35 100644 --- a/atom/browser/api/atom_api_session.cc +++ b/atom/browser/api/atom_api_session.cc @@ -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" @@ -243,7 +244,6 @@ void SetProxyInIO(net::URLRequestContextGetter* getter, 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)-> @@ -276,7 +276,6 @@ bool Session::IsDestroyed() const { } void Session::Destroy() { - browser_context_->cert_verifier()->SetDelegate(nullptr); browser_context_ = nullptr; } @@ -358,6 +357,17 @@ void Session::DisableNetworkEmulation() { base::Passed(&conditions))); } +void Session::SetCertVerifyProc(v8::Local val, mate::Arguments* args) { + AtomCertVerifier::VerifyProc proc; + if (val.IsEmpty() || + !(val->IsNull() || mate::ConvertFromV8(args->isolate(), val, &proc))) { + args->ThrowError("Must pass null or function"); + return; + } + + browser_context_->cert_verifier()->SetVerifyProc(proc); +} + v8::Local Session::Cookies(v8::Isolate* isolate) { if (cookies_.IsEmpty()) { auto handle = atom::api::Cookies::Create(isolate, browser_context()); @@ -376,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); } diff --git a/atom/browser/api/atom_api_session.h b/atom/browser/api/atom_api_session.h index ebcfc45223db..01dc0a408a8c 100644 --- a/atom/browser/api/atom_api_session.h +++ b/atom/browser/api/atom_api_session.h @@ -8,7 +8,6 @@ #include #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, - public AtomCertVerifier::Delegate, public content::DownloadManager::Observer { public: using ResolveProxyCallback = base::Callback; @@ -74,6 +72,7 @@ class Session: public mate::TrackableObject, void SetDownloadPath(const base::FilePath& path); void EnableNetworkEmulation(const mate::Dictionary& options); void DisableNetworkEmulation(); + void SetCertVerifyProc(v8::Local proc, mate::Arguments* args); v8::Local Cookies(v8::Isolate* isolate); // Cached object for cookies API. diff --git a/atom/browser/net/atom_cert_verifier.cc b/atom/browser/net/atom_cert_verifier.cc index 0f94e4fe2ad2..3633d805fb5b 100644 --- a/atom/browser/net/atom_cert_verifier.cc +++ b/atom/browser/net/atom_cert_verifier.cc @@ -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 diff --git a/atom/browser/net/atom_cert_verifier.h b/atom/browser/net/atom_cert_verifier.h index 8736db0f8723..796ae2849bda 100644 --- a/atom/browser/net/atom_cert_verifier.h +++ b/atom/browser/net/atom_cert_verifier.h @@ -8,61 +8,22 @@ #include #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 cert; - const std::string& hostname; - net::CompletionCallback callback; - }; - - class CertVerifyRequest - : public base::RefCountedThreadSafe { - 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(); - - 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& request) {} - }; - AtomCertVerifier(); virtual ~AtomCertVerifier(); - void SetDelegate(Delegate* delegate) { - delegate_ = delegate; - } + using VerifyProc = + base::Callback, + const base::Callback&)>; + + 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 default_cert_verifier_; DISALLOW_COPY_AND_ASSIGN(AtomCertVerifier); From 9ca022c98a30788d2074a585128b7df8106c6c7b Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Wed, 18 Nov 2015 11:35:26 +0800 Subject: [PATCH 209/249] docs: Update the certificate APIs --- atom/browser/api/atom_api_app.cc | 2 +- docs/api/app.md | 29 ++++++++++++++++++++ docs/api/session.md | 46 +++++++++++++++----------------- docs/api/web-contents.md | 33 +++++++++++++++++++++++ 4 files changed, 84 insertions(+), 26 deletions(-) diff --git a/atom/browser/api/atom_api_app.cc b/atom/browser/api/atom_api_app.cc index 73f4b3927728..28c3b4c15983 100644 --- a/atom/browser/api/atom_api_app.cc +++ b/atom/browser/api/atom_api_app.cc @@ -252,7 +252,7 @@ void App::AllowCertificateError( bool prevent_default = Emit("certificate-error", WebContents::CreateFrom(isolate(), web_contents), request_url, - cert_error, + net::ErrorToString(cert_error), ssl_info.cert, callback); diff --git a/docs/api/app.md b/docs/api/app.md index 4ff90f3e5785..d7850c4cb92c 100644 --- a/docs/api/app.md +++ b/docs/api/app.md @@ -131,6 +131,35 @@ Returns: Emitted when a new [browserWindow](browser-window.md) is created. +### 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: diff --git a/docs/api/session.md b/docs/api/session.md index e385e222d529..450be7b08e11 100644 --- a/docs/api/session.md +++ b/docs/api/session.md @@ -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); +}); +``` diff --git a/docs/api/web-contents.md b/docs/api/web-contents.md index 0988d25276f4..be22d947c752 100644 --- a/docs/api/web-contents.md +++ b/docs/api/web-contents.md @@ -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: From 47d7f2c0503231054a80a5c2a3769cf01ddcfbbb Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Wed, 18 Nov 2015 11:45:15 +0800 Subject: [PATCH 210/249] Fix cpplint warning --- atom/browser/api/atom_api_session.cc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/atom/browser/api/atom_api_session.cc b/atom/browser/api/atom_api_session.cc index 2a2c7b2fff35..27e1521f3d3f 100644 --- a/atom/browser/api/atom_api_session.cc +++ b/atom/browser/api/atom_api_session.cc @@ -357,10 +357,10 @@ void Session::DisableNetworkEmulation() { base::Passed(&conditions))); } -void Session::SetCertVerifyProc(v8::Local val, mate::Arguments* args) { +void Session::SetCertVerifyProc(v8::Local val, + mate::Arguments* args) { AtomCertVerifier::VerifyProc proc; - if (val.IsEmpty() || - !(val->IsNull() || mate::ConvertFromV8(args->isolate(), val, &proc))) { + if (!(val->IsNull() || mate::ConvertFromV8(args->isolate(), val, &proc))) { args->ThrowError("Must pass null or function"); return; } From 25e5c385561e7ebf625f7534c024b78239f41b26 Mon Sep 17 00:00:00 2001 From: Plusb Preco Date: Wed, 18 Nov 2015 12:45:33 +0900 Subject: [PATCH 211/249] Small changes --- docs-translations/ko-KR/api/browser-window.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/docs-translations/ko-KR/api/browser-window.md b/docs-translations/ko-KR/api/browser-window.md index 95780bc74ed2..f34830bede3a 100644 --- a/docs-translations/ko-KR/api/browser-window.md +++ b/docs-translations/ko-KR/api/browser-window.md @@ -472,19 +472,19 @@ height areas you have within the overall content view. ### `win.getPosition()` -윈도우의 현재 위치를 배열로 반환합니다. +윈도우의 위치를 배열로 반환합니다. ### `win.setTitle(title)` * `title` String -Changes the title of native window to `title`. +`title`을 네이티브 윈도우의 제목으로 지정합니다. ### `win.getTitle()` -Returns the title of the native window. +윈도우의 제목을 반환합니다. -**Note:** The title of web page can be different from the title of the native +**참고:** The title of web page can be different from the title of the native window. ### `win.flashFrame(flag)` @@ -689,10 +689,10 @@ Returns whether the menu bar is visible. Sets whether the window should be visible on all workspaces. -**Note:** This API does nothing on Windows. +**참고:** 이 API는 Windows에서 아무 일도 하지 않습니다. ### `win.isVisibleOnAllWorkspaces()` Returns whether the window is visible on all workspaces. -**Note:** This API always returns false on Windows. +**참고:** 이 API는 Windows에서 언제나 false를 반환합니다. From bcdd0952f8decce11bf30723422142cf624e3440 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Wed, 18 Nov 2015 17:56:50 +0800 Subject: [PATCH 212/249] docs: Fix typo --- docs/api/protocol.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/api/protocol.md b/docs/api/protocol.md index 0f854a2bb2f2..5f34165fa84a 100644 --- a/docs/api/protocol.md +++ b/docs/api/protocol.md @@ -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`. From 6892f0d2d4b8a04b1debe7c81b49bf78b32bd3c8 Mon Sep 17 00:00:00 2001 From: Plusb Preco Date: Wed, 18 Nov 2015 22:14:24 +0900 Subject: [PATCH 213/249] Add missed translation --- docs-translations/ko-KR/api/session.md | 33 +++++++++++--------------- 1 file changed, 14 insertions(+), 19 deletions(-) diff --git a/docs-translations/ko-KR/api/session.md b/docs-translations/ko-KR/api/session.md index 749ca6efbb0f..5df45f4ac216 100644 --- a/docs-translations/ko-KR/api/session.md +++ b/docs-translations/ko-KR/api/session.md @@ -181,25 +181,20 @@ proxy-uri-list = [","] proxy-uri = ["://"][":"] 예시: - "http=foopy:80;ftp=foopy2" -- use HTTP proxy "foopy:80" for http:// - URLs, and HTTP proxy "foopy2:80" for - ftp:// URLs. - "foopy:80" -- use HTTP proxy "foopy:80" for all URLs. - "foopy:80,bar,direct://" -- use HTTP proxy "foopy:80" for all URLs, - failing over to "bar" if "foopy:80" is - unavailable, and after that using no - proxy. - "socks4://foopy" -- use SOCKS v4 proxy "foopy:1080" for all - URLs. - "http=foopy,socks5://bar.com -- use HTTP proxy "foopy" for http URLs, - and fail over to the SOCKS5 proxy - "bar.com" if "foopy" is unavailable. - "http=foopy,direct:// -- use HTTP proxy "foopy" for http URLs, - and use no proxy if "foopy" is - unavailable. - "http=foopy;socks=foopy2 -- use HTTP proxy "foopy" for http URLs, - and use socks4://foopy2 for all other - URLs. + "http=foopy:80;ftp=foopy2" -- http:// URL에 "foopy:80" HTTP 프록시를 사용합니다. + "foopy2:80" 는 ftp:// URL에 사용됩니다. + "foopy:80" -- 모든 URL에 "foopy:80" 프록시를 사용합니다. + "foopy:80,bar,direct://" -- 모든 URL에 "foopy:80" HTTP 프록시를 사용합니다. + 문제가 발생하여 "foopy:80"를 사용할 수 없는 경우 "bar"를 대신 사용하여 + 장애를 복구하며 그 다음 문제가 생긴 경우 프록시를 사용하지 않습니다. + "socks4://foopy" -- 모든 URL에 "foopy:1000" SOCKS v4 프록시를 사용합니다. + "http=foopy,socks5://bar.com -- http:// URL에 "foopy" HTTP 프록시를 사용합니다. + 문제가 발생하여 "foopy"를 사용할 수 없는 경우 SOCKS5 "bar.com" + 프록시를 대신 사용합니다. + "http=foopy,direct:// -- http:// URL에 "foopy" HTTP 프록시를 사용합니다. + 그리고 문제가 발생하여 "foopy"를 사용할 수 없는 경우 프록시를 사용하지 않습니다. + "http=foopy;socks=foopy2 -- http:// URL에 "foopy" HTTP 프록시를 사용합니다. + 그리고 "socks4://foopy2" 프록시를 다른 모든 URL에 사용합니다. ``` ### `session.setDownloadPath(path)` From 250575719d82a2a851a837dcfb7aaca68acd659f Mon Sep 17 00:00:00 2001 From: Plusb Preco Date: Wed, 18 Nov 2015 23:32:47 +0900 Subject: [PATCH 214/249] Translate docs --- docs-translations/ko-KR/api/browser-window.md | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/docs-translations/ko-KR/api/browser-window.md b/docs-translations/ko-KR/api/browser-window.md index f34830bede3a..06b6543fe6e0 100644 --- a/docs-translations/ko-KR/api/browser-window.md +++ b/docs-translations/ko-KR/api/browser-window.md @@ -484,38 +484,36 @@ height areas you have within the overall content view. 윈도우의 제목을 반환합니다. -**참고:** The title of web page can be different from the title of the native -window. +**참고:** 웹 페이지의 제목과 네이티브 윈도우의 제목은 서로 다를 수 있습니다. ### `win.flashFrame(flag)` * `flag` Boolean -Starts or stops flashing the window to attract user's attention. +사용자가 윈도우에 관심을 가질 수 있도록 창을 깜빡이거나 이를 중지합니다. ### `win.setSkipTaskbar(skip)` * `skip` Boolean -Makes the window not show in the taskbar. +어플리케이션 아이콘을 작업 표시줄에 보이지 않도록 설정합니다. ### `win.setKiosk(flag)` * `flag` Boolean -Enters or leaves the kiosk mode. +Kiosk(키오스크) 모드를 설정합니다. ### `win.isKiosk()` -Returns whether the window is in kiosk mode. +현재 윈도우가 kiosk 모드인지 여부를 반환합니다. ### `win.hookWindowMessage(message, callback)` _WINDOWS_ * `message` Integer * `callback` Function -Hooks a windows message. The `callback` is called when -the message is received in the WndProc. +Windows 메시지를 후킹합니다. `callback`은 WndProc에서 메시지를 받았을 때 호출됩니다. ### `win.isWindowMessageHooked(message)` _WINDOWS_ From 0c2d769b8a96364552a9e48311adf23cdc06e4ae Mon Sep 17 00:00:00 2001 From: Plusb Preco Date: Wed, 18 Nov 2015 23:35:36 +0900 Subject: [PATCH 215/249] Fix platform label to uppercase --- docs/api/browser-window.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/api/browser-window.md b/docs/api/browser-window.md index e5fcfb9003ae..ca9b621cd835 100644 --- a/docs/api/browser-window.md +++ b/docs/api/browser-window.md @@ -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' _Windows_ +### 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 From 9db4af4cf32c1867d2461f9f084149df944f36d1 Mon Sep 17 00:00:00 2001 From: Plusb Preco Date: Wed, 18 Nov 2015 23:36:20 +0900 Subject: [PATCH 216/249] Fix platform label to uppercase (ko) --- docs-translations/ko-KR/api/browser-window.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs-translations/ko-KR/api/browser-window.md b/docs-translations/ko-KR/api/browser-window.md index 06b6543fe6e0..3db59f38e637 100644 --- a/docs-translations/ko-KR/api/browser-window.md +++ b/docs-translations/ko-KR/api/browser-window.md @@ -207,7 +207,7 @@ __참고__: OS X에선 이 이벤트가 그저 `moved` 이벤트의 별칭(alias 윈도우가 HTML API에 의해 풀 스크린 모드에서 해제될 때 발생하는 이벤트입니다. -### Event: 'app-command' _Windows_ +### Event: 'app-command' _WINDOWS_ [App Command](https://msdn.microsoft.com/en-us/library/windows/desktop/ms646275(v=vs.85).aspx)가 호출됐을 때 발생하는 이벤트입니다. 이 이벤트는 일반적으로 키보드 미디어 키 또는 브라우저 커맨드(기본 동작 키)에 관련되어 있습니다. From cc5a4f1dfeb6a5c2faba6951d2b803db348a214c Mon Sep 17 00:00:00 2001 From: Plusb Preco Date: Wed, 18 Nov 2015 23:42:03 +0900 Subject: [PATCH 217/249] Update as upstream --- docs-translations/ko-KR/api/tray.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs-translations/ko-KR/api/tray.md b/docs-translations/ko-KR/api/tray.md index 96722bb2409e..7a883b026797 100644 --- a/docs-translations/ko-KR/api/tray.md +++ b/docs-translations/ko-KR/api/tray.md @@ -169,7 +169,8 @@ __주의:__ `bounds`는 OS X 와 Windows에서만 작동합니다. * `highlight` Boolean -트레이 아이콘을 클릭했을 때 하이라이트 될지 설정합니다. +트레이 아이콘이 클릭됐을 때 아이콘의 배경이 파란색으로 하이라이트 될지 여부를 지정합니다. +기본값은 true입니다. ### `Tray.displayBalloon(options)` _Windows_ From f0d2bc87e81f90a775d54a82f5faeab50afa0c32 Mon Sep 17 00:00:00 2001 From: Plusb Preco Date: Thu, 19 Nov 2015 02:50:04 +0900 Subject: [PATCH 218/249] Add translation, improve grammar --- docs-translations/ko-KR/api/browser-window.md | 94 +++++++++---------- docs-translations/ko-KR/api/web-contents.md | 2 +- 2 files changed, 46 insertions(+), 50 deletions(-) diff --git a/docs-translations/ko-KR/api/browser-window.md b/docs-translations/ko-KR/api/browser-window.md index 3db59f38e637..eb68c8c8e716 100644 --- a/docs-translations/ko-KR/api/browser-window.md +++ b/docs-translations/ko-KR/api/browser-window.md @@ -304,7 +304,7 @@ var win = new BrowserWindow({ width: 800, height: 600 }); ### `win.isFocused()` -윈도우가 포커스 되었는지 여부를 반환합니다. +윈도우가 포커스되었는지 여부를 반환합니다. ### `win.show()` @@ -344,7 +344,7 @@ var win = new BrowserWindow({ width: 800, height: 600 }); ### `win.isMinimized()` -윈도우가 최소화 되었는지 여부를 반환합니다. +윈도우가 최소화되었는지 여부를 반환합니다. ### `win.setFullScreen(flag)` @@ -513,45 +513,43 @@ Kiosk(키오스크) 모드를 설정합니다. * `message` Integer * `callback` Function -Windows 메시지를 후킹합니다. `callback`은 WndProc에서 메시지를 받았을 때 호출됩니다. +Windows 메시지 훅을 등록합니다. `callback`은 WndProc에서 메시지를 받았을 때 호출됩니다. ### `win.isWindowMessageHooked(message)` _WINDOWS_ * `message` Integer -Returns `true` or `false` depending on whether the message is hooked. +지정한 메시지가 후킹됬는지 여부를 반환합니다. ### `win.unhookWindowMessage(message)` _WINDOWS_ * `message` Integer -Unhook the window message. +지정한 메시지 훅을 등록 해제합니다. ### `win.unhookAllWindowMessages()` _WINDOWS_ -Unhooks all of the window messages. +모든 메시지 훅을 등록 해제합니다. ### `win.setRepresentedFilename(filename)` _OS X_ * `filename` String -Sets the pathname of the file the window represents, and the icon of the file -will show in window's title bar. +윈도우 대표 파일의 경로명을 설정합니다. 파일의 아이콘이 윈도우 타이틀 바에 표시됩니다. ### `win.getRepresentedFilename()` _OS X_ -Returns the pathname of the file the window represents. +윈도우 대표 파일의 경로명을 반환합니다. ### `win.setDocumentEdited(edited)` _OS X_ * `edited` Boolean -Specifies whether the window’s document has been edited, and the icon in title -bar will become grey when set to `true`. +윈도우의 문서가 변경되었는지 여부를 설정합니다. 그리고 `true`로 설정했을 때 타이틀 바의 아이콘이 회색으로 표시됩니다. ### `win.isDocumentEdited()` _OS X_ -Whether the window's document has been edited. +윈도우의 문서가 변경되었는지 여부를 반환합니다. ### `win.focusOnWebView()` @@ -559,69 +557,65 @@ Whether the window's document has been edited. ### `win.capturePage([rect, ]callback)` -* `rect` Object (optional)- The area of page to be captured, properties: +* `rect` Object (optional)- 캡쳐할 페이지의 영역. 사용할 수 있는 속성은 다음과 같습니다: * `x` Integer * `y` Integer * `width` Integer * `height` Integer * `callback` Function -Captures a snapshot of the page within `rect`. Upon completion `callback` will -be called with `callback(image)`. The `image` is an instance of -[NativeImage](native-image.md) that stores data of the snapshot. Omitting -`rect` will capture the whole visible page. +페이지의 스크린샷을 `rect`에 설정한 만큼 캡처합니다. +캡처가 완료되면 `callback`이 `callback(image)` 형식으로 호출됩니다. +`image`는 [NativeImage](native-image.md)의 인스턴스이며 스크린샷 데이터를 담고있습니다. +`rect`를 생략하면 페이지 전체를 캡처합니다. ### `win.print([options])` -Same as `webContents.print([options])` +`webContents.print([options])` API와 같습니다. ### `win.printToPDF(options, callback)` -Same as `webContents.printToPDF(options, callback)` +`webContents.printToPDF(options, callback)` API와 같습니다. ### `win.loadURL(url[, options])` -Same as `webContents.loadURL(url[, options])`. +`webContents.loadURL(url[, options])` API와 같습니다. ### `win.reload()` -Same as `webContents.reload`. +`webContents.reload` API와 같습니다. ### `win.setMenu(menu)` _Linux_ _Windows_ * `menu` Menu -Sets the `menu` as the window's menu bar, setting it to `null` will remove the -menu bar. +지정한 `menu`를 윈도우의 메뉴로 설정합니다 `null`을 설정하면 메뉴를 제거합니다. ### `win.setProgressBar(progress)` * `progress` Double -Sets progress value in progress bar. Valid range is [0, 1.0]. +작업 표시줄에 표시되고 있는 어플리케이션 아이콘에 진행 상태를 표시합니다. [0, 1.0] 사이의 값을 지정할 수 있습니다. -Remove progress bar when progress < 0; -Change to indeterminate mode when progress > 1. +진행 상태가 < 0 이 되면 진행 상태 표시를 제거합니다. +진행 상태가 > 1 이 되면 불확정 상태 표시로 전환합니다. -On Linux platform, only supports Unity desktop environment, you need to specify -the `*.desktop` file name to `desktopName` field in `package.json`. By default, -it will assume `app.getName().desktop`. +Linux 플랫폼에선 Unity 데스크톱 환경만 지원합니다. +그리고 이 기능을 사용하려면 `*.desktop` 파일을 생성한 후 `package.json`의 `desktopName` 필드에 파일 이름을 지정해야 합니다. +기본적으로 `app.getName().desktop`을 통해 접근합니다. ### `win.setOverlayIcon(overlay, description)` _Windows 7+_ -* `overlay` [NativeImage](native-image.md) - the icon to display on the bottom -right corner of the taskbar icon. If this parameter is `null`, the overlay is -cleared -* `description` String - a description that will be provided to Accessibility -screen readers - -Sets a 16px overlay onto the current taskbar icon, usually used to convey some -sort of application status or to passively notify the user. +* `overlay` [NativeImage](native-image.md) - 작업 표시줄 아이콘의 우측 하단에 표시될 아이콘입니다. +`null`로 지정하면 빈 오버레이가 사용됩니다 +* `description` String - 접근성 설정에 의한 스크린 리더에 제공될 설명입니다 +현재 작업 표시줄 아이콘에 16px 크기의 오버레이를 지정합니다. +보통 이 기능은 어플리케이션의 여러 상태를 사용자에게 소극적으로 알리기 위한 방법으로 사용됩니다. ### `win.setThumbarButtons(buttons)` _Windows 7+_ -`buttons` Array of `button` Objects: +`buttons` `button` 객체의 배열: `button` Object, properties: @@ -654,43 +648,45 @@ array to clean the buttons. ### `win.showDefinitionForSelection()` _OS X_ -Shows pop-up dictionary that searches the selected word on the page. +페이지의 선택된 단어에 대한 사전 검색 결과 팝업을 표시합니다. ### `win.setAutoHideMenuBar(hide)` * `hide` Boolean -Sets whether the window menu bar should hide itself automatically. Once set the -menu bar will only show when users press the single `Alt` key. +메뉴 막대 자동 숨김 기능을 활성화 합니다. +숨겨진 메뉴는 사용자가 `Alt` 키를 단일 입력했을 때만 표시됩니다. -If the menu bar is already visible, calling `setAutoHideMenuBar(true)` won't -hide it immediately. +메뉴 막대가 이미 표시되고 있을 때 `setAutoHideMenuBar(true)`를 호출한다고 해서 메뉴가 즉시 숨겨지지는 않습니다. ### `win.isMenuBarAutoHide()` -Returns whether menu bar automatically hides itself. +메뉴 막대 자동 숨김 상태인지 여부를 반환합니다. ### `win.setMenuBarVisibility(visible)` * `visible` Boolean -Sets whether the menu bar should be visible. If the menu bar is auto-hide, users -can still bring up the menu bar by pressing the single `Alt` key. +메뉴 막대의 표시 여부를 설정합니다. +만약 메뉴 막대 자동 숨김 상태라면 여전히 사용자가 `Alt` 키를 입력하여 메뉴 막대를 표시되도록 할 수 있습니다. + +**역주:** 기본 메뉴 막대를 완전히 없애려면 `win.setMenu(null)`을 호출해야 합니다. +단순히 이 API를 사용하면 여전히 메뉴에 등록된 핫 키가 작동합니다. ### `win.isMenuBarVisible()` -Returns whether the menu bar is visible. +메뉴 막대가 표시되고 있는지 여부를 반환합니다. ### `win.setVisibleOnAllWorkspaces(visible)` * `visible` Boolean -Sets whether the window should be visible on all workspaces. +윈도우가 모든 워크스페이스에서 보여질지 여부를 설정합니다. **참고:** 이 API는 Windows에서 아무 일도 하지 않습니다. ### `win.isVisibleOnAllWorkspaces()` -Returns whether the window is visible on all workspaces. +윈도우가 모든 워크스페이스에서 보여질지 여부를 반환합니다. **참고:** 이 API는 Windows에서 언제나 false를 반환합니다. diff --git a/docs-translations/ko-KR/api/web-contents.md b/docs-translations/ko-KR/api/web-contents.md index c1452f063791..1bad5b47e863 100644 --- a/docs-translations/ko-KR/api/web-contents.md +++ b/docs-translations/ko-KR/api/web-contents.md @@ -283,7 +283,7 @@ var currentURL = win.webContents.getURL(); ### `webContents.isCrashed()` -렌더러 프로세스가 예기치 않게 종료 되었는지 여부를 반환합니다. +렌더러 프로세스가 예기치 않게 종료되었는지 여부를 반환합니다. ### `webContents.setUserAgent(userAgent)` From 70c7abbbfeb0b1f2aba88e58e069152d801a4203 Mon Sep 17 00:00:00 2001 From: Plusb Preco Date: Thu, 19 Nov 2015 02:51:27 +0900 Subject: [PATCH 219/249] Small changes --- docs-translations/ko-KR/api/browser-window.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs-translations/ko-KR/api/browser-window.md b/docs-translations/ko-KR/api/browser-window.md index eb68c8c8e716..6d5cdf1659af 100644 --- a/docs-translations/ko-KR/api/browser-window.md +++ b/docs-translations/ko-KR/api/browser-window.md @@ -670,7 +670,7 @@ array to clean the buttons. 메뉴 막대의 표시 여부를 설정합니다. 만약 메뉴 막대 자동 숨김 상태라면 여전히 사용자가 `Alt` 키를 입력하여 메뉴 막대를 표시되도록 할 수 있습니다. -**역주:** 기본 메뉴 막대를 완전히 없애려면 `win.setMenu(null)`을 호출해야 합니다. +**역주:** 기본 메뉴 막대를 완전히 없애려면 `win.setMenu(null)`를 호출해야 합니다. 단순히 이 API를 사용하면 여전히 메뉴에 등록된 핫 키가 작동합니다. ### `win.isMenuBarVisible()` From e2cd0578f3c32a935c9477f3fa2b4d4aae64fcb1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADtor=20Galv=C3=A3o?= Date: Wed, 18 Nov 2015 18:13:48 +0000 Subject: [PATCH 220/249] web-view-tag.md: small typo correction ('the' position swap) --- docs/api/web-view-tag.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/api/web-view-tag.md b/docs/api/web-view-tag.md index 25b0e399465d..47a3050a0429 100644 --- a/docs/api/web-view-tag.md +++ b/docs/api/web-view-tag.md @@ -262,7 +262,7 @@ Injects CSS into the guest page. * `code` String * `userGesture` Boolean - Default `false`. -Evaluates `code` in page. If `userGesture` is set, it will the create user +Evaluates `code` in page. If `userGesture` is set, it will create the user gesture context in the page. HTML APIs like `requestFullScreen`, which require user action, can take advantage of this option for automation. From 82e2da1d9a289fe5003fc9c85de7a880c2601093 Mon Sep 17 00:00:00 2001 From: Plusb Preco Date: Thu, 19 Nov 2015 03:53:10 +0900 Subject: [PATCH 221/249] Translate docs --- docs-translations/ko-KR/api/browser-window.md | 59 ++++++++----------- 1 file changed, 26 insertions(+), 33 deletions(-) diff --git a/docs-translations/ko-KR/api/browser-window.md b/docs-translations/ko-KR/api/browser-window.md index 6d5cdf1659af..554119a0a1e8 100644 --- a/docs-translations/ko-KR/api/browser-window.md +++ b/docs-translations/ko-KR/api/browser-window.md @@ -43,7 +43,7 @@ win.show(); * `alwaysOnTop` Boolean - 윈도우 창이 언제나 다른 창들 위에 유지되는지 여부. * `fullscreen` Boolean - 윈도우 창의 전체화면 활성화 여부. `false`로 지정했을 경우 OS X에선 전체화면 버튼이 숨겨지거나 비활성화됩니다. -* `skipTaskbar` Boolean - 작업 표시줄 어플리케이션 아이콘 표시 여부. +* `skipTaskbar` Boolean - 작업표시줄 어플리케이션 아이콘 표시 여부. * `kiosk` Boolean - Kiosk(키오스크) 모드. * `title` String - 기본 윈도우 창 제목. * `icon` [NativeImage](native-image.md) - 윈도우 아이콘, 생략하면 실행 파일의 아이콘이 대신 사용됩니다. @@ -496,7 +496,7 @@ height areas you have within the overall content view. * `skip` Boolean -어플리케이션 아이콘을 작업 표시줄에 보이지 않도록 설정합니다. +어플리케이션 아이콘을 작업표시줄에 보이지 않도록 설정합니다. ### `win.setKiosk(flag)` @@ -557,7 +557,7 @@ Windows 메시지 훅을 등록합니다. `callback`은 WndProc에서 메시지 ### `win.capturePage([rect, ]callback)` -* `rect` Object (optional)- 캡쳐할 페이지의 영역. 사용할 수 있는 속성은 다음과 같습니다: +* `rect` Object (optional) - 캡쳐할 페이지의 영역. 사용할 수 있는 속성은 다음과 같습니다: * `x` Integer * `y` Integer * `width` Integer @@ -595,7 +595,7 @@ Windows 메시지 훅을 등록합니다. `callback`은 WndProc에서 메시지 * `progress` Double -작업 표시줄에 표시되고 있는 어플리케이션 아이콘에 진행 상태를 표시합니다. [0, 1.0] 사이의 값을 지정할 수 있습니다. +작업표시줄에 표시되고 있는 어플리케이션 아이콘에 진행 상태를 표시합니다. [0, 1.0] 사이의 값을 지정할 수 있습니다. 진행 상태가 < 0 이 되면 진행 상태 표시를 제거합니다. 진행 상태가 > 1 이 되면 불확정 상태 표시로 전환합니다. @@ -606,45 +606,38 @@ Linux 플랫폼에선 Unity 데스크톱 환경만 지원합니다. ### `win.setOverlayIcon(overlay, description)` _Windows 7+_ -* `overlay` [NativeImage](native-image.md) - 작업 표시줄 아이콘의 우측 하단에 표시될 아이콘입니다. +* `overlay` [NativeImage](native-image.md) - 작업표시줄 아이콘의 우측 하단에 표시될 아이콘입니다. `null`로 지정하면 빈 오버레이가 사용됩니다 * `description` String - 접근성 설정에 의한 스크린 리더에 제공될 설명입니다 -현재 작업 표시줄 아이콘에 16px 크기의 오버레이를 지정합니다. +현재 작업표시줄 아이콘에 16px 크기의 오버레이를 지정합니다. 보통 이 기능은 어플리케이션의 여러 상태를 사용자에게 소극적으로 알리기 위한 방법으로 사용됩니다. ### `win.setThumbarButtons(buttons)` _Windows 7+_ -`buttons` `button` 객체의 배열: +`buttons` - `button` 객체의 배열: -`button` Object, properties: +`button` 객체는 다음과 같은 속성을 가지고 있습니다: -* `icon` [NativeImage](native-image.md) - The icon showing in thumbnail - toolbar. -* `tooltip` String (optional) - The text of the button's tooltip. -* `flags` Array (optional) - Control specific states and behaviors - of the button. By default, it uses `enabled`. It can include following - Strings: - * `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 taskbar button's - flyout 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. +* `icon` [NativeImage](native-image.md) - 미리보기 툴바에 보여질 아이콘. +* `tooltip` String (optional) - 버튼의 툴팁 텍스트. +* `flags` Array (optional) - 버튼의 특정 동작 및 상태 제어. 기본적으로 `enabled`이 사용됩니다. + 이 속성은 다음 문자열들을 포함할 수 있습니다: + * `enabled` - 사용자가 사용할 수 있도록 버튼이 활성화 됩니다. + * `disabled` - 버튼이 비활성화 됩니다. 버튼은 표시되지만 시각적인 상태는 사용자의 동작에 응답하지 않는 + 비활성화 상태로 표시됩니다. + * `dismissonclick` - 버튼이 클릭되면 작업표시줄 버튼의 미리보기(flyout)가 즉시 종료됩니다. + * `nobackground` - 버튼의 테두리를 표시하지 않습니다. 이미지에만 사용할 수 있습니다. + * `hidden` - 버튼을 사용자에게 표시되지 않도록 숨깁니다. + * `noninteractive` - 버튼은 활성화되어 있지만 반응이 제거되며 버튼을 눌러도 눌려지지 않은 상태를 유지합니다. + 이 값은 버튼을 알림의 용도로 사용하기 위해 만들어졌습니다. * `click` - Function -Add a thumbnail toolbar with a specified set of buttons to the thumbnail image -of a window in a taskbar button layout. Returns a `Boolean` object indicates -whether the thumbnail has been added successfully. +윈도우 작업표시줄 버튼 레이아웃의 미리보기 이미지 영역에 미리보기 툴바와 버튼 세트를 지정합니다. +반환되는 `Boolean` 값은 미리보기 툴바가 성공적으로 추가됬는지를 알려줍니다. -The number of buttons in thumbnail toolbar should be no greater than 7 due to -the limited room. Once you setup the thumbnail toolbar, the toolbar cannot be -removed due to the platform's limitation. But you can call the API with an empty -array to clean the buttons. +미리보기 이미지 영역의 제한된 크기로 인해 미리보기 툴바에 추가될 수 있는 최대 버튼의 개수는 7개이며 이 이상 추가될 수 없습니다. +플랫폼의 제약으로 인해 미리보기 툴바는 한 번 설정되면 삭제할 수 없습니다. 하지만 이 API에 빈 배열을 전달하여 버튼들을 제거할 수 있습니다. ### `win.showDefinitionForSelection()` _OS X_ @@ -681,12 +674,12 @@ array to clean the buttons. * `visible` Boolean -윈도우가 모든 워크스페이스에서 보여질지 여부를 설정합니다. +윈도우가 모든 워크스페이스에서 표시될지 여부를 설정합니다. **참고:** 이 API는 Windows에서 아무 일도 하지 않습니다. ### `win.isVisibleOnAllWorkspaces()` -윈도우가 모든 워크스페이스에서 보여질지 여부를 반환합니다. +윈도우가 모든 워크스페이스에서 표시될지 여부를 반환합니다. **참고:** 이 API는 Windows에서 언제나 false를 반환합니다. From ef64a211a2b3aeef6cdebbd01fd65ebdde63435d Mon Sep 17 00:00:00 2001 From: Plusb Preco Date: Thu, 19 Nov 2015 04:01:50 +0900 Subject: [PATCH 222/249] Standardize platform labels --- docs-translations/ko-KR/api/browser-window.md | 10 +++++----- docs/api/browser-window.md | 10 +++++----- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/docs-translations/ko-KR/api/browser-window.md b/docs-translations/ko-KR/api/browser-window.md index 554119a0a1e8..62b01d1f6c4d 100644 --- a/docs-translations/ko-KR/api/browser-window.md +++ b/docs-translations/ko-KR/api/browser-window.md @@ -207,7 +207,7 @@ __참고__: OS X에선 이 이벤트가 그저 `moved` 이벤트의 별칭(alias 윈도우가 HTML API에 의해 풀 스크린 모드에서 해제될 때 발생하는 이벤트입니다. -### Event: 'app-command' _WINDOWS_ +### Event: 'app-command' _Windows_ [App Command](https://msdn.microsoft.com/en-us/library/windows/desktop/ms646275(v=vs.85).aspx)가 호출됐을 때 발생하는 이벤트입니다. 이 이벤트는 일반적으로 키보드 미디어 키 또는 브라우저 커맨드(기본 동작 키)에 관련되어 있습니다. @@ -508,26 +508,26 @@ Kiosk(키오스크) 모드를 설정합니다. 현재 윈도우가 kiosk 모드인지 여부를 반환합니다. -### `win.hookWindowMessage(message, callback)` _WINDOWS_ +### `win.hookWindowMessage(message, callback)` _Windows_ * `message` Integer * `callback` Function Windows 메시지 훅을 등록합니다. `callback`은 WndProc에서 메시지를 받았을 때 호출됩니다. -### `win.isWindowMessageHooked(message)` _WINDOWS_ +### `win.isWindowMessageHooked(message)` _Windows_ * `message` Integer 지정한 메시지가 후킹됬는지 여부를 반환합니다. -### `win.unhookWindowMessage(message)` _WINDOWS_ +### `win.unhookWindowMessage(message)` _Windows_ * `message` Integer 지정한 메시지 훅을 등록 해제합니다. -### `win.unhookAllWindowMessages()` _WINDOWS_ +### `win.unhookAllWindowMessages()` _Windows_ 모든 메시지 훅을 등록 해제합니다. diff --git a/docs/api/browser-window.md b/docs/api/browser-window.md index ca9b621cd835..17f57a5a703c 100644 --- a/docs/api/browser-window.md +++ b/docs/api/browser-window.md @@ -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' _WINDOWS_ +### 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 @@ -541,7 +541,7 @@ Enters or leaves the kiosk mode. Returns whether the window is in kiosk mode. -### `win.hookWindowMessage(message, callback)` _WINDOWS_ +### `win.hookWindowMessage(message, callback)` _Windows_ * `message` Integer * `callback` Function @@ -549,19 +549,19 @@ Returns whether the window is in kiosk mode. Hooks a windows message. The `callback` is called when the message is received in the WndProc. -### `win.isWindowMessageHooked(message)` _WINDOWS_ +### `win.isWindowMessageHooked(message)` _Windows_ * `message` Integer Returns `true` or `false` depending on whether the message is hooked. -### `win.unhookWindowMessage(message)` _WINDOWS_ +### `win.unhookWindowMessage(message)` _Windows_ * `message` Integer Unhook the window message. -### `win.unhookAllWindowMessages()` _WINDOWS_ +### `win.unhookAllWindowMessages()` _Windows_ Unhooks all of the window messages. From f581730516b4810e6a3e06516b413146a309f2d1 Mon Sep 17 00:00:00 2001 From: Eran Tiktin Date: Wed, 18 Nov 2015 21:06:06 +0200 Subject: [PATCH 223/249] Update browser-window.md Changed the description of the preload key to make it clear you need to provide an absolute file path and not a file url. Also mentioned that it's possible to reintroduce Node globals when node integration is off and referenced the example from process.md (related to https://github.com/atom/electron/issues/254#issuecomment-157769756). --- docs/api/browser-window.md | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/docs/api/browser-window.md b/docs/api/browser-window.md index e5fcfb9003ae..48373b313e94 100644 --- a/docs/api/browser-window.md +++ b/docs/api/browser-window.md @@ -86,8 +86,12 @@ It creates a new `BrowserWindow` with native properties as set by the `options`. is `true`. * `preload` String - Specifies a script that will be loaded before other scripts run in the page. This script will always have access to node APIs - no matter whether node integration is turned on for the page, and the path - of `preload` script has to be absolute path. + no matter whether node integration is turned on or off. The value should + be the absolute file path to the script. + + When node integration is turned off, the preload script can reintroduce + Node global symbols back to the global scope. See example + [here](process.md#event-loaded). * `partition` String - Sets the session used by the page. If `partition` starts with `persist:`, the page will use a persistent session available to all pages in the app with the same `partition`. if there is no `persist:` From e4803e6f972fb3a648ff5c1657af23d9f372d365 Mon Sep 17 00:00:00 2001 From: Plusb Preco Date: Thu, 19 Nov 2015 05:12:38 +0900 Subject: [PATCH 224/249] Translate docs --- docs-translations/ko-KR/README.md | 2 +- docs-translations/ko-KR/api/browser-window.md | 26 +++++++------------ 2 files changed, 11 insertions(+), 17 deletions(-) diff --git a/docs-translations/ko-KR/README.md b/docs-translations/ko-KR/README.md index 6899c91c32fa..d70894f8a96a 100644 --- a/docs-translations/ko-KR/README.md +++ b/docs-translations/ko-KR/README.md @@ -32,7 +32,7 @@ * [app](api/app.md) * [autoUpdater](api/auto-updater.md) -* [BrowserWindow (50% 번역됨 - 작업중)](api/browser-window.md) +* [BrowserWindow](api/browser-window.md) * [contentTracing](api/content-tracing.md) * [dialog](api/dialog.md) * [globalShortcut](api/global-shortcut.md) diff --git a/docs-translations/ko-KR/api/browser-window.md b/docs-translations/ko-KR/api/browser-window.md index 62b01d1f6c4d..02ae9eb66049 100644 --- a/docs-translations/ko-KR/api/browser-window.md +++ b/docs-translations/ko-KR/api/browser-window.md @@ -358,26 +358,20 @@ var win = new BrowserWindow({ width: 800, height: 600 }); ### `win.setAspectRatio(aspectRatio[, extraSize])` _OS X_ -* `aspectRatio` The aspect ratio we want to maintain for some portion of the -content view. -* `extraSize` Object (optional) - The extra size not to be included while -maintaining the aspect ratio. Properties: +* `aspectRatio` 유지하려 하는 컨텐츠 뷰 일부의 종횡비 +* `extraSize` Object (optional) - 종횡비를 유지하는 동안 포함되지 않을 엑스트라 크기. 사용 가능한 속성: * `width` Integer * `height` Integer -This will have a window maintain an aspect ratio. The extra size allows a -developer to have space, specified in pixels, not included within the aspect -ratio calculations. This API already takes into account the difference between a -window's size and its content size. +이 메서드는 윈도우의 종횡비를 유지하는 기능을 수행합니다. +엑스트라 크기는 개발자가 픽셀로 특정한 공간이 있을 때 종횡비 계산에서 제외됩니다. +이 API는 윈도우의 크기와 컨텐츠 사이즈의 차이를 이미 고려하고 있습니다. -Consider a normal window with an HD video player and associated controls. -Perhaps there are 15 pixels of controls on the left edge, 25 pixels of controls -on the right edge and 50 pixels of controls below the player. In order to -maintain a 16:9 aspect ratio (standard aspect ratio for HD @1920x1080) within -the player itself we would call this function with arguments of 16/9 and -[ 40, 50 ]. The second argument doesn't care where the extra width and height -are within the content view--only that they exist. Just sum any extra width and -height areas you have within the overall content view. +일반 윈도우에서 작동하는 HD 비디오 플레이어와 관련된 컨트롤을 고려합니다. +만약 15 픽셀의 컨트롤이 왼쪽 가장자리에 있고 25 픽셀의 컨트롤이 오른쪽 가장자리에 있으며 50 픽셀의 컨트롤이 플레이어 밑에 있을 때 +플레이어 자체가 16:9 종횡비(HD의 표준 종횡비는 @1920x1080)를 유지하기 위해선 이 함수를 16/9, [ 40, 50 ] 인수와 함께 호출해야 합니다. +두번째 인수 엑스트라 크기는 존재하는 크기만 관여하고 컨텐츠 뷰 내의 크기는 관여하지 않습니다. +그저 전체 컨텐츠 뷰 내에 있는 모든 엑스트라 너비, 높이 영역이 합해집니다. ### `win.setBounds(options)` From b7ae9d33376e980e365b17dac6562442b0fc5386 Mon Sep 17 00:00:00 2001 From: Eran Tiktin Date: Thu, 19 Nov 2015 02:11:32 +0200 Subject: [PATCH 225/249] Update ipc-renderer.md Removed duplication. --- docs/api/ipc-renderer.md | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/docs/api/ipc-renderer.md b/docs/api/ipc-renderer.md index e591f9e0bca2..01f0bb3a83dd 100644 --- a/docs/api/ipc-renderer.md +++ b/docs/api/ipc-renderer.md @@ -37,11 +37,10 @@ send arbitrary arguments. The main process handles it by listening for the * `arg` (optional) Send an event to the main process synchronously via a `channel`, you can also -send arbitrary arguments. The main process handles it by listening for the -`channel` event with `ipcMain`. +send arbitrary arguments. -The main process handles it by listening for the `channel` event with `ipc` and -replies by setting the `event.returnValue`. +The main process handles it by listening for the `channel` event with +`ipcMain` and replies by setting `event.returnValue`. __Note:__ Sending a synchronous message will block the whole renderer process, unless you know what you are doing you should never use it. From 0232b77ce3243a0f00b601f73b1a7073fcde0236 Mon Sep 17 00:00:00 2001 From: Plusb Preco Date: Thu, 19 Nov 2015 09:32:44 +0900 Subject: [PATCH 226/249] Cleanup docs, Improve grammar --- README-ko.md | 35 ++++++++----- .../development/atom-shell-vs-node-webkit.md | 35 ++++++++----- .../development/build-instructions-linux.md | 43 +++++++++------- .../development/build-instructions-osx.md | 8 +-- .../development/build-instructions-windows.md | 38 +++++++++----- .../development/build-system-overview.md | 51 ++++++++++++------- docs-translations/ko-KR/styleguide.md | 49 +++++++++++------- 7 files changed, 163 insertions(+), 96 deletions(-) diff --git a/README-ko.md b/README-ko.md index a0d1a9d3438f..d35ba87f62b7 100644 --- a/README-ko.md +++ b/README-ko.md @@ -8,19 +8,26 @@ :zap: *프레임워크 이름이 Atom Shell에서 Electron으로 변경되었습니다* :zap: -Electron 프레임워크는 JavaScript, HTML 그리고 CSS를 사용하여 Cross-Platform 데스크톱 어플리케이션을 개발할 수 있도록 해주는 프레임워크입니다. -이 프레임워크는 [Node.js](https://nodejs.org/) 와 [Chromium](http://www.chromium.org)을 기반으로 만들어 졌으며 -[Atom Editor](https://github.com/atom/atom)에 사용되고 있습니다. +Electron 프레임워크는 JavaScript, HTML 그리고 CSS를 사용하여 Cross-Platform 데스크톱 +어플리케이션을 개발할 수 있도록 해주는 프레임워크입니다. 이 프레임워크는 +[Node.js](https://nodejs.org/)와 [Chromium](http://www.chromium.org)을 기반으로 +만들어졌으며 [Atom Editor](https://github.com/atom/atom)에 사용되고 있습니다. -Electron에 대한 중요한 알림을 받고 싶다면 Twitter에서 [@ElectronJS](https://twitter.com/electronjs)를 팔로우 하세요. +Electron에 대한 중요한 알림을 받고 싶다면 Twitter에서 +[@ElectronJS](https://twitter.com/electronjs)를 팔로우 하세요. -이 프로젝트는 [기여자 규약 1.2](http://contributor-covenant.org/version/1/2/0/)를 준수합니다. 이 프로젝트에 참여할 때 코드를 유지해야 합니다. 받아들일 수 없는 행위를 발견했을 경우 atom@github.com로 보고 하십시오. +이 프로젝트는 [기여자 규약 1.2](http://contributor-covenant.org/version/1/2/0/)을 +준수합니다. 따라서 이 프로젝트의 개발에 참여하려면 이 계약을 지켜야 합니다. +받아들일 수 없는 행위를 발견했을 경우 atom@github.com로 보고 하십시오. ## 다운로드 -Linux, Windows, OS X 용으로 미리 빌드된 Electron 바이너리와 디버그 심볼이 준비되어 있습니다. [releases](https://github.com/atom/electron/releases) 페이지에서 받아 볼 수 있습니다. +Linux, Windows, OS X 용으로 미리 빌드된 Electron 바이너리와 디버그 심볼이 준비되어 +있습니다. [releases](https://github.com/atom/electron/releases) 페이지에서 +받아 볼 수 있습니다. -또한 [`npm`](https://docs.npmjs.com/)을 통해 미리 빌드된 Electron 바이너리를 받을 수도 있습니다: +또한 [`npm`](https://docs.npmjs.com/)을 통해 미리 빌드된 Electron 바이너리를 +설치할 수도 있습니다: ```sh # $PATH에 `electron` 커맨드를 등록하고 전역에 설치합니다. @@ -36,8 +43,9 @@ npm install electron-prebuilt --save-dev ## 참조 문서 -[Docs](https://github.com/atom/electron/tree/master/docs/README.md)에 개발 가이드와 API 레퍼런스가 있습니다. -Electron을 빌드 하는 방법과 프로젝트에 기여하는 방법도 문서에 포함되어 있으니 참고하시기 바랍니다. +[Docs](https://github.com/atom/electron/tree/master/docs/README.md)에 개발 지침과 +API 레퍼런스가 있습니다. Electron을 빌드 하는 방법과 프로젝트에 기여하는법 또한 문서에 +포함되어 있으니 참고하시기 바랍니다. ## 참조 문서 (번역) @@ -50,14 +58,17 @@ Electron을 빌드 하는 방법과 프로젝트에 기여하는 방법도 문 ## 시작하기 -[`atom/electron-quick-start`](https://github.com/atom/electron-quick-start) 저장소를 클론하여 Electron을 간단히 접해볼 수 있습니다. +[`atom/electron-quick-start`](https://github.com/atom/electron-quick-start) +저장소를 클론하여 Electron을 간단히 접해볼 수 있습니다. ## 커뮤니티 다음 링크를 통해 커뮤니티에 질문을 올리거나 토론을 나눌 수 있습니다: - Atom 포럼의 [`electron`](http://discuss.atom.io/c/electron) 카테고리 -- Freenode 채팅의 `#atom-shell` 채널 +- Freenode 채팅의 `#atom-shell` 채널 - Slack의 [`Atom`](http://atom-slack.herokuapp.com/) 채널 -[awesome-electron](https://github.com/sindresorhus/awesome-electron) 프로젝트엔 커뮤니티가 운영중인 유용한 예제 어플리케이션과 도구, 리소스가 있으니 한번 참고해 보시기 바랍니다. +[awesome-electron](https://github.com/sindresorhus/awesome-electron) 프로젝트에 +커뮤니티가 운영중인 유용한 예제 어플리케이션과 도구, 리소스가 있으니 +한번 참고해 보시기 바랍니다. diff --git a/docs-translations/ko-KR/development/atom-shell-vs-node-webkit.md b/docs-translations/ko-KR/development/atom-shell-vs-node-webkit.md index 23aa31bfe4ed..e7dd017fd720 100644 --- a/docs-translations/ko-KR/development/atom-shell-vs-node-webkit.md +++ b/docs-translations/ko-KR/development/atom-shell-vs-node-webkit.md @@ -3,35 +3,46 @@ __참고: Electron은 Atom Shell의 새로운 이름입니다.__ NW.js 처럼 Electron은 JavaScript와 HTML 그리고 Node 통합 환경을 제공함으로써 -웹 페이지에서 저 수준 시스템에 접근할 수 있도록 하여 웹 기반 데스크탑 어플리케이션을 작성할 수 있도록 하는 프레임워크 입니다. +웹 페이지에서 저 수준 시스템에 접근할 수 있도록 하여 웹 기반 데스크탑 어플리케이션을 +작성할 수 있도록 하는 프레임워크 입니다. 하지만 Electron과 NW.js는 근본적인 개발흐름의 차이도 있습니다: __1. 어플리케이션의 엔트리 포인트__ NW.js에선 어플리케이션의 엔트리 포인트로 웹 페이지를 사용합니다. -`package.json`내의 main 필드에 메인 웹 페이지(index.html) URL을 지정하면 어플리케이션의 메인 윈도우로 열리게 됩니다. +`package.json`내의 main 필드에 메인 웹 페이지(index.html) URL을 지정하면 +어플리케이션의 메인 윈도우로 열리게 됩니다. -Electron에선 JavaScript를 엔트리 포인트로 사용합니다. URL을 직접 제공하는 대신 API를 사용하여 직접 브라우저 창과 HTML 파일을 로드할 수 있습니다. -또한 윈도우의 종료시기를 결정하는 이벤트를 리스닝해야합니다. +Electron에선 JavaScript를 엔트리 포인트로 사용합니다. URL을 직접 제공하는 대신 API를 +사용하여 직접 브라우저 창과 HTML 파일을 로드할 수 있습니다. 또한 윈도우의 종료시기를 +결정하는 이벤트를 리스닝해야합니다. -Electron은 Node.js 런타임과 비슷하게 작동합니다. Electron의 API는 저수준이기에 브라우저 테스팅을 위해 [PhantomJS](http://phantomjs.org/)를 사용할 수도 있습니다. +Electron은 Node.js 런타임과 비슷하게 작동합니다. Electron의 API는 저수준이기에 +브라우저 테스팅을 위해 [PhantomJS](http://phantomjs.org/)를 사용할 수도 있습니다. __2. 빌드 시스템__ -Electron은 Chromium의 모든것을 빌드하는 복잡성을 피하기 위해 [libchromiumcontent](https://github.com/brightray/libchromiumcontent)를 사용하여 -Chromium의 Content API에 접근합니다. libchromiumcontent은 단일 공유 라이브러리이고 Chromium Content 모듈과 종속성 라이브러리들을 포함합니다. -유저는 Electron을 빌드 하기 위해 높은 사양의 빌드용 컴퓨터를 구비할 필요가 없습니다. +Electron은 Chromium의 모든것을 빌드하는 복잡성을 피하기 위해 +[libchromiumcontent](https://github.com/brightray/libchromiumcontent)를 사용하여 +Chromium의 Content API에 접근합니다. libchromiumcontent은 단일 공유 라이브러리이고 +Chromium Content 모듈과 종속성 라이브러리들을 포함합니다. 유저는 Electron을 빌드 하기 +위해 높은 사양의 빌드용 컴퓨터를 구비할 필요가 없습니다. __3. Node 통합__ -NW.js는 웹 페이지에서 require를 사용할 수 있도록 Chromium을 패치했습니다. 한편 Electron은 Chromium의 해킹을 방지하기 위해 libuv loop와 각 플랫폼의 메시지 루프에 통합하는 등의 다른 방법을 채택하였습니다. -[`node_bindings`][node-bindings] 코드를 보면 이 부분이 어떻게 구현됬는지를 알 수 있습니다. +NW.js는 웹 페이지에서 require를 사용할 수 있도록 Chromium을 패치했습니다. +한편 Electron은 Chromium의 해킹을 방지하기 위해 libuv loop와 각 플랫폼의 +메시지 루프에 통합하는 다른 방법을 채택하였습니다. +[`node_bindings`][node-bindings]의 코드를 보면 이 부분이 어떻게 구현됬는지를 +알 수 있습니다. __4. 다중 컨텍스트__ -만약 NW.js를 사용해본적이 있다면 Node context와 Web context의 개념을 잘 알고 있을겁니다. 이 개념은 NW.js가 구현된 방식에 따라 만들어졌습니다. +만약 NW.js를 사용해본 적이 있다면 Node context와 Web context의 개념을 잘 알고 있을 +겁니다. 이러한 개념은 NW.js가 구현되기 위해 만들어졌습니다. -Node의 [다중 컨텍스트](http://strongloop.com/strongblog/whats-new-node-js-v0-12-multiple-context-execution/)를 사용할 경우 Electron은 웹 페이지에서 새로운 JavaScript 컨텍스트를 생성하지 않습니다. +Node의 [다중 컨텍스트](http://strongloop.com/strongblog/whats-new-node-js-v0-12-multiple-context-execution/)를 +사용하기 때문에 Electron은 웹 페이지의 새로운 JavaScript 컨텍스트를 생성하지 않습니다. [node-bindings]: https://github.com/atom/electron/tree/master/atom/common diff --git a/docs-translations/ko-KR/development/build-instructions-linux.md b/docs-translations/ko-KR/development/build-instructions-linux.md index cb254a80596d..7a6a476400a0 100644 --- a/docs-translations/ko-KR/development/build-instructions-linux.md +++ b/docs-translations/ko-KR/development/build-instructions-linux.md @@ -4,10 +4,14 @@ ## 빌드전 요구사양 -* Python 2.7.x. 몇몇 CentOS와 같은 배포판들은 아직도 Python 2.6.x 버전을 사용합니다. 그래서 `python -V`를 통해 버전을 확인해 줄 필요가 있습니다. -* Node.js v0.12.x. Node를 설치하는 방법은 여러가지가 있습니다. 그중 하나는 [Node.js](http://nodejs.org) 사이트에서 소스코드를 받아 빌드하는 방법입니다. - 이렇게 하면 Node를 일반 유저로 홈 디렉터리에 설치할 수 있습니다. 또는 [NodeSource](https://nodesource.com/blog/nodejs-v012-iojs-and-the-nodesource-linux-repositories)에서 소스 파일을 받아올 수 있습니다. - 자세한 내용은 [Node.js 설치 방법](https://github.com/joyent/node/wiki/Installation) 을 참고하세요. +* Python 2.7.x. 몇몇 CentOS와 같은 배포판들은 아직도 Python 2.6.x 버전을 사용합니다. + 그래서 먼저 `python -V`를 통해 버전을 확인할 필요가 있습니다. +* Node.js v0.12.x. Node를 설치하는 방법은 여러 가지가 있습니다. 먼저, + [Node.js](http://nodejs.org) 사이트에서 소스코드를 받아 빌드하는 방법입니다. + 이렇게 하면 Node를 일반 유저로 홈 디렉터리에 설치할 수 있습니다. 다른 방법으로는 + [NodeSource](https://nodesource.com/blog/nodejs-v012-iojs-and-the-nodesource-linux-repositories)에서 + 소스 파일을 받아와 설치할 수 있습니다. 자세한 내용은 [Node.js 설치 방법](https://github.com/joyent/node/wiki/Installation)을 + 참고하세요. * Clang 3.4 또는 최신 버전 * GTK+ 와 libnotify의 개발용 헤더 @@ -28,13 +32,14 @@ $ sudo yum install clang dbus-devel gtk2-devel libnotify-devel libgnome-keyring- alsa-lib-devel libXrandr-devel GConf2-devel nss-devel ``` -다른 배포판의 경우 pacman 같은 패키지 매니저를 통해 패키지를 설치 할 수 있습니다. 패키지의 이름은 대부분 위 예시와 비슷할 것입니다. -또는 소스코드를 내려받아 직접 빌드하는 방법도 있습니다. +다른 배포판의 경우 pacman 같은 패키지 매니저를 통해 패키지를 설치 할 수 있습니다. +패키지의 이름은 대부분 위 예시와 비슷할 것입니다. 또는 소스코드를 내려받아 +직접 빌드하는 방법도 있습니다. ## 가상머신을 사용하여 빌드 하는 경우 -만약 Electron을 가상머신으로 빌드 할 계획이라면 해당 가상머신의 스토리지를 최소 25GB 이상을 확보해 놓아야 합니다. - +만약 Electron을 가상머신으로 빌드 할 계획이라면 해당 가상머신의 스토리지를 +최소 25GB 이상을 확보해 놓아야 합니다. ## 코드 가져오기 @@ -44,10 +49,11 @@ $ git clone https://github.com/atom/electron.git ## 부트 스트랩 -부트스트랩 스크립트는 필수적인 빌드 종속성 라이브러리들을 모두 다운로드하고 프로젝트 파일을 생성합니다. -스크립트가 정상적으로 작동하기 위해선 Python 2.7.x 버전이 필요합니다. -아마 다운로드 작업이 상당히 많은 시간을 소요할 것입니다. -참고로 Electron은 빌드 툴체인으로 `ninja`를 사용하므로 `Makefile`은 생성되지 않습니다. +부트스트랩 스크립트는 필수적인 빌드 종속성 라이브러리들을 모두 다운로드하고 +프로젝트 파일을 생성합니다. 스크립트가 정상적으로 작동하기 위해선 +Python 2.7.x 버전이 필요합니다. 아마 다운로드 작업이 상당히 많은 시간을 +소요할 것입니다. 참고로 Electron은 빌드 툴체인으로 `ninja`를 사용하므로 +`Makefile`은 생성되지 않습니다. ```bash $ cd electron @@ -63,7 +69,8 @@ $ sudo apt-get install libc6-dev-armhf-cross linux-libc-dev-armhf-cross \ g++-arm-linux-gnueabihf ``` -그리고 `bootstrap.py` 스크립트의 `--target_arch` 파라미터에 `arm` 또는 `ia32` 아키텍쳐를 지정하여 크로스 컴파일 할 수 있습니다: +그리고 `bootstrap.py` 스크립트의 `--target_arch` 파라미터에 `arm` 또는 `ia32` +아키텍쳐를 지정하여 크로스 컴파일 할 수 있습니다: ```bash $ ./script/bootstrap.py -v --target_arch=arm @@ -77,16 +84,18 @@ $ ./script/bootstrap.py -v --target_arch=arm $ ./script/build.py ``` -이 스크립트는 `out/R` 디렉터리에 크기가 매우 큰 Electron 실행 파일을 배치합니다. 파일 크기는 1.3GB를 초과합니다. -이러한 문제가 발생하는 이유는 Release 타겟 바이너리가 디버그 심볼을 포함하기 때문입니다. -파일 크기를 줄이려면 `create-dist.py` 스크립트를 실행하세요: +이 스크립트는 `out/R` 디렉터리에 크기가 매우 큰 Electron 실행 파일을 배치합니다. +파일 크기는 1.3GB를 초과합니다. 이러한 문제가 발생하는 이유는 Release 타겟 바이너리가 +디버그 심볼을 포함하기 때문입니다. 파일 크기를 줄이려면 +`create-dist.py` 스크립트를 실행하세요: ```bash $ ./script/create-dist.py ``` 이 스크립트는 매우 작은 배포판을 `dist` 디렉터리에 생성합니다. -create-dist.py 스크립트를 실행한 이후부턴 1.3GB를 초과하는 공간을 차지하는 `out/R` 폴더의 바이너리는 삭제해도 됩니다. +create-dist.py 스크립트를 실행한 이후부턴 1.3GB를 초과하는 공간을 차지하는 +`out/R` 폴더의 바이너리는 삭제해도 됩니다. 또는 `Debug` 타겟만 빌드 할 수 있습니다: diff --git a/docs-translations/ko-KR/development/build-instructions-osx.md b/docs-translations/ko-KR/development/build-instructions-osx.md index 4951b975ae33..222d4fc31c4e 100644 --- a/docs-translations/ko-KR/development/build-instructions-osx.md +++ b/docs-translations/ko-KR/development/build-instructions-osx.md @@ -20,8 +20,9 @@ $ git clone https://github.com/atom/electron.git ## 부트 스트랩 -부트스트랩 스크립트는 필수적인 빌드 종속성 라이브러리들을 모두 다운로드하고 프로젝트 파일을 생성합니다. -참고로 Electron은 빌드 툴체인으로 `ninja`를 사용하므로 Xcode 프로젝트는 생성되지 않습니다. +부트스트랩 스크립트는 필수적인 빌드 종속성 라이브러리들을 모두 다운로드하고 +프로젝트 파일을 생성합니다. 참고로 Electron은 빌드 툴체인으로 `ninja`를 사용하므로 +Xcode 프로젝트는 생성되지 않습니다. ```bash $ cd electron @@ -46,7 +47,8 @@ $ ./script/build.py -c D ## 32비트 지원 -Electron은 현재 OS X 64비트만 지원하고 있습니다. 그리고 앞으로도 OS X 32비트는 지원할 계획이 없습니다. +Electron은 현재 OS X 64비트만 지원하고 있습니다. 그리고 앞으로도 OS X 32비트는 +지원할 계획이 없습니다. ## 테스트 diff --git a/docs-translations/ko-KR/development/build-instructions-windows.md b/docs-translations/ko-KR/development/build-instructions-windows.md index fa165ca153ac..69811ac388f7 100644 --- a/docs-translations/ko-KR/development/build-instructions-windows.md +++ b/docs-translations/ko-KR/development/build-instructions-windows.md @@ -11,14 +11,18 @@ * [Git](http://git-scm.com) 현재 사용하고 있는 PC에 Windows를 설치하지 않았다면 [modern.ie](https://www.modern.ie/en-us/virtualization-tools#downloads)에서 -사용 기한이 정해져있는 무료 가상머신 버전의 Windows를 받아 Electron을 빌드하는 방법도 있습니다. +사용 기한이 정해져있는 무료 가상머신 버전의 Windows를 받아 Electron을 +빌드하는 방법도 있습니다. -Electron은 모든 빌드를 command-line 스크립트를 통해 빌드합니다. 따라서 빌드에 Visual Studio를 사용할 수 없습니다. -하지만 여전히 Electron을 개발할 땐 아무 에디터나 사용할 수 있습니다. 빠른 시일내에 Visual Studio를 이용한 빌드도 지원할 계획입니다. +Electron은 모든 빌드를 command-line 스크립트를 통해 빌드합니다. 따라서 빌드에 +Visual Studio를 사용할 수 없습니다. 하지만 여전히 Electron을 개발할 땐 아무 에디터나 +사용할 수 있습니다. 빠른 시일내에 Visual Studio를 이용한 빌드도 지원할 계획입니다. -**참고:** Visual Studio가 직접 빌드에 사용되지 않더라도 IDE와 같이 제공된 빌드 툴체인이 빌드에 **필수적으로** 사용되므로 여전히 필요합니다. +**참고:** Visual Studio가 직접 빌드에 사용되지 않더라도 IDE와 같이 제공된 +빌드 툴체인이 빌드에 **반드시** 사용되므로 여전히 필요합니다. -**참고:** Visual Studio 2015는 사용할 수 없습니다. MSVS **2013**을 사용하고 있는지 확인해주세요. +**참고:** Visual Studio 2015는 사용할 수 없습니다. +MSVS **2013** 을 사용하고 있는지 확인해주세요. ## 코드 가져오기 @@ -28,8 +32,9 @@ $ git clone https://github.com/atom/electron.git ## 부트 스트랩 -부트스트랩 스크립트는 필수적인 빌드 종속성 라이브러리들을 모두 다운로드하고 프로젝트 파일을 생성합니다. -참고로 Electron은 빌드 툴체인으로 `ninja`를 사용하므로 Visual Studio 프로젝트는 생성되지 않습니다. +부트스트랩 스크립트는 필수적인 빌드 종속성 라이브러리들을 모두 다운로드하고 +프로젝트 파일을 생성합니다. 참고로 Electron은 빌드 툴체인으로 `ninja`를 사용하므로 +Visual Studio 프로젝트는 생성되지 않습니다. ```powershell $ cd electron @@ -50,11 +55,13 @@ $ python script\build.py $ python script\build.py -c D ``` -빌드가 모두 끝나면 `out/D` (디버그 타겟) 또는 `out/R` (릴리즈 타겟) 디렉터리에서 `electron.exe` 실행 파일을 찾을 수 있습니다. +빌드가 모두 끝나면 `out/D` (디버그 타겟) 또는 `out/R` (릴리즈 타겟) 디렉터리에서 +`electron.exe` 실행 파일을 찾을 수 있습니다. ## 64비트 빌드 -64비트를 타겟으로 빌드 하려면 부트스트랩 스크립트를 실행할 때 `--target_arch=x64` 인자를 같이 넘겨주면 됩니다: +64비트를 타겟으로 빌드 하려면 부트스트랩 스크립트를 실행할 때 +`--target_arch=x64` 인자를 같이 넘겨주면 됩니다: ```powershell $ python script\bootstrap.py -v --target_arch=x64 @@ -76,8 +83,8 @@ $ python script\cpplint.py $ python script\test.py ``` -테스트 실행시 `runas`와 같은 네이티브 모듈을 포함하는데 이 모듈은 디버그 빌드에서 같이 사용할 수 없습니다. -하지만 여전히 릴리즈 빌드에선 사용할 수 있습니다. +테스트 실행시 `runas`와 같은 네이티브 모듈을 포함하는데 이 모듈은 디버그 빌드에서 +같이 사용할 수 없습니다. 하지만 여전히 릴리즈 빌드에선 사용할 수 있습니다. 릴리즈 빌드로 테스트를 실행하려면 다음 커맨드를 사용하면 됩니다: @@ -89,7 +96,8 @@ $ python script\test.py -R ### Command xxxx not found -만약 `Command xxxx not found`와 같은 형식의 에러가 발생했다면 `VS2012 Command Prompt` 콘솔로 빌드 스크립트를 실행해볼 필요가 있습니다. +만약 `Command xxxx not found`와 같은 형식의 에러가 발생했다면 +`VS2012 Command Prompt` 콘솔로 빌드 스크립트를 실행해볼 필요가 있습니다. ### Fatal internal compiler error: C1001 @@ -97,7 +105,8 @@ Visual Studio가 업데이트까지 완벽하게 설치된 최신버전인지 ### Assertion failed: ((handle))->activecnt >= 0 -Cygwin에서 빌드 할 경우 `bootstrap.py` 스크립트가 다음의 에러와 함께 빌드에 실패할 수 있습니다: +Cygwin에서 빌드 할 경우 `bootstrap.py` 스크립트가 다음의 에러와 함께 빌드에 +실패할 수 있습니다: ``` Assertion failed: ((handle))->activecnt >= 0, file src\win\pipe.c, line 1430 @@ -136,4 +145,5 @@ $ mkdir ~\AppData\Roaming\npm ### node-gyp is not recognized as an internal or external command -Git Bash로 빌드 했을 때 이러한 에러가 발생할 수 있습니다. 반드시 PowerShell이나 VS2012 Command Prompt에서 빌드를 진행해야 합니다. +Git Bash로 빌드 했을 때 이러한 에러가 발생할 수 있습니다. 반드시 PowerShell이나 +VS2012 Command Prompt에서 빌드를 진행해야 합니다. diff --git a/docs-translations/ko-KR/development/build-system-overview.md b/docs-translations/ko-KR/development/build-system-overview.md index 34f93a8881bd..0c35d04d7bd7 100644 --- a/docs-translations/ko-KR/development/build-system-overview.md +++ b/docs-translations/ko-KR/development/build-system-overview.md @@ -9,31 +9,39 @@ Electron을 빌드 할 때 `gyp` 파일들은 다음과 같은 규칙을 따릅 * `atom.gyp`는 Electron의 빌드 과정 자체를 정의합니다. * `common.gypi`는 Node가 Chromium과 함께 빌드될 수 있도록 조정한 빌드 설정입니다. -* `vendor/brightray/brightray.gyp`는 `brightray`의 빌드 과정을 정의하고 Chromium과의 링킹에 대한 기본적인 설정을 포함합니다. +* `vendor/brightray/brightray.gyp`는 `brightray`의 빌드 과정을 정의하고 + Chromium 링킹에 대한 기본적인 설정을 포함합니다. * `vendor/brightray/brightray.gypi`는 빌드에 대한 일반적인 설정이 포함되어 있습니다. ## 구성요소 빌드 -Chromium은 꽤나 큰 프로젝트입니다. 이 때문에 최종 링킹 작업은 상당한 시간이 소요될 수 있습니다. -이 문제는 보통 개발을 어렵게 만듭니다. 우리는 이 문제를 해결하기 위해 Chromium의 "component build" 방식을 도입했습니다. -이는 각각의 컴포넌트를 각각 따로 분리하여 공유 라이브러리로 빌드 합니다. 하지만 이 방식을 사용하면 링킹 작업은 매우 빨라지지만 파일 크기와 성능이 느려집니다. +Chromium은 꽤나 큰 프로젝트입니다. 이러한 이유로 인해 최종 링킹 작업은 상당한 시간이 +소요될 수 있습니다. 보통 이런 문제는 개발을 어렵게 만듭니다. 우리는 이 문제를 해결하기 +위해 Chromium의 "component build" 방식을 도입했습니다. 이는 각각의 컴포넌트를 +각각 따로 분리하여 공유 라이브러리로 빌드 합니다. 하지만 이 빌드 방식을 사용하면 +링킹 작업은 매우 빨라지지만 실행 파일 크기가 커지고 성능이 저하됩니다. -Electron도 상당히 비슷한 접근을 했습니다: -`Debug`빌드 시 바이너리는 공유 라이브러리 버전의 Chromium 컴포넌트를 사용해서 링크 속도를 높이고 -`Release`빌드 시엔 정적 라이브러리 버전의 컴포넌트를 사용합니다. -이렇게 각 빌드의 단점을 상호 보완하여 디버그 시 빌드 속도는 향상되고 배포판 빌드 시 공유 라이브러리의 단점은 제거했습니다. +Electron도 이러한 방식에 상당히 비슷한 접근을 했습니다: +`Debug` 빌드 시 바이너리는 공유 라이브러리 버전의 Chromium 컴포넌트를 사용함으로써 +링크 속도를 높이고, `Release` 빌드 시 정적 라이브러리 버전의 컴포넌트를 사용합니다. +이렇게 각 빌드의 단점을 상호 보완하여 디버그 시 빌드 속도는 향상되고 배포판 빌드의 +공유 라이브러리의 단점은 개선했습니다. ## 부트스트랩 최소화 Prebuilt된 모든 Chromium 바이너리들은 부트스트랩 스크립트가 실행될 때 다운로드됩니다. -기본적으로 공유 라이브러리와 정적 라이브러리 모두 다운로드되며 최종 전체 파일 크기는 플랫폼에 따라 800MB에서 2GB까지 차지합니다. +기본적으로 공유 라이브러리와 정적 라이브러리 모두 다운로드되며 최종 전체 파일 크기는 +플랫폼에 따라 800MB에서 2GB까지 차지합니다. 기본적으로 (`libchromiumcontent`)는 Amazon Web Service를 통해 다운로드 됩니다. -만약 `LIBCHROMIUMCONTENT_MIRROR` 환경 변수가 설정되어 있으면 부트스트랩은 해당 링크를 사용하여 바이너리를 다운로드 합니다. -[libchromiumcontent-qiniu-mirror](https://github.com/hokein/libchromiumcontent-qiniu-mirror)는 libchromiumcontent의 미러입니다. -만약 AWS에 접근할 수 없다면 `export LIBCHROMIUMCONTENT_MIRROR=http://7xk3d2.dl1.z0.glb.clouddn.com/`를 통해 다운로드 할 수 있습니다. +만약 `LIBCHROMIUMCONTENT_MIRROR` 환경 변수가 설정되어 있으면 부트스트랩은 해당 링크를 +사용하여 바이너리를 다운로드 합니다. [libchromiumcontent-qiniu-mirror](https://github.com/hokein/libchromiumcontent-qiniu-mirror)는 +libchromiumcontent의 미러입니다. 만약 AWS에 접근할 수 없다면 +`export LIBCHROMIUMCONTENT_MIRROR=http://7xk3d2.dl1.z0.glb.clouddn.com/` 미러를 +통해 다운로드 할 수 있습니다. -만약 빠르게 Electron의 개발 또는 테스트만 하고 싶다면 `--dev` 플래그를 추가하여 공유 라이브러리만 다운로드할 수 있습니다: +만약 빠르게 Electron의 개발 또는 테스트만 하고 싶다면 `--dev` 플래그를 추가하여 +공유 라이브러리만 다운로드할 수 있습니다: ```bash $ ./script/bootstrap.py --dev @@ -43,14 +51,19 @@ $ ./script/build.py -c D ## 프로젝트 생성 (two-phrase) Electron은 `Release`와 `Debug` 빌드가 서로 다른 라이브러리 링크 방식을 사용합니다. -하지만 `gyp`는 따로 빌드 설정을 분리하여 라이브러리 링크 방식을 정의하는 것을 지원하지 않습니다. +하지만 `gyp`는 따로 빌드 설정을 분리하여 라이브러리 링크 방식을 정의하는 방법을 +지원하지 않습니다. -이 문제를 해결하기 위해 Electron은 링크 설정을 제어하는 `gyp` 변수 `libchromiumcontent_component`를 사용하고 `gyp`를 실행할 때 단 하나의 타겟만 생성합니다. +이 문제를 해결하기 위해 Electron은 링크 설정을 제어하는 `gyp` 변수 +`libchromiumcontent_component`를 사용하고 `gyp`를 실행할 때 +단 하나의 타겟만을 생성합니다. ## 타겟 이름 -많은 프로젝트에서 타겟 이름을 `Release` 와 `Debug`를 사용하는데 반해 Electron은 `R`과 `D`를 대신 사용합니다. -이유는 가끔 알 수 없는 이유(randomly)로 `Release` 와 `Debug` 중 하나만 빌드 설정에 정의되어 있을때 `gyp`가 크래시를 일으키는데 -전술한 바와 같이 Electron은 한번에 한개의 타겟만을 생성할 수 있기 때문입니다. +많은 프로젝트에서 타겟 이름을 `Release` 와 `Debug`를 사용하는데 반해 Electron은 +`R`과 `D`를 대신 사용합니다. 이유는 가끔 알 수 없는 이유(randomly)로 +`Release` 와 `Debug` 중 하나만 빌드 설정에 정의되어 있을때 `gyp`가 크래시를 일으키는데 +이유는 앞서 말한 바와 같이 Electron은 한번에 한개의 타겟만을 생성할 수 있기 때문입니다. -이 문제는 개발자에게만 영향을 미칩니다. 만약 단순히 Electron을 rebranding 하기 위해 빌드 한다면 이 문제에 신경 쓸 필요가 없습니다. +이 문제는 개발자에게만 영향을 미칩니다. 만약 단순히 Electron을 rebranding 하기 위해 +빌드 하는 것이라면 이 문제에 신경 쓸 필요가 없습니다. diff --git a/docs-translations/ko-KR/styleguide.md b/docs-translations/ko-KR/styleguide.md index 92b68e345505..7318c7e3b403 100644 --- a/docs-translations/ko-KR/styleguide.md +++ b/docs-translations/ko-KR/styleguide.md @@ -1,22 +1,28 @@ # Electron 문서 스타일 가이드 -[Electron 문서 읽기](#electron-문서-읽기) 와 [Electron 문서 작성하기](#electron-문서-작성하기) 중 이해가 필요한 부분을 찾아 참고하세요: +[Electron 문서 읽기](#electron-문서-읽기) 와 +[Electron 문서 작성하기](#electron-문서-작성하기) 중 이해가 필요한 부분을 찾아 +참고하세요: ## Electron 문서 작성하기 Electron 문서를 작성하는 규칙은 다음과 같습니다. - `h1` 제목은 페이지당 한 개만 사용할 수 있습니다. -- 코드 블럭에서 터미널 언어 선택시 `cmd` 대신 `bash`를 사용합니다. (syntax highlighter를 사용하기 위해서) -- 문서의 `h1` 제목은 반드시 현재 객체 이름과 같게 해야 합니다. (예시: `browser-window` → `BrowserWindow`) - - 하이픈(-)으로 구분되었던 어떻게 되었던 간에 예시와 같이 작성합니다. -- 헤더 밑에 헤더를 바로 사용하지 않습니다. 한 줄이라도 좋으니 헤더와 헤더 사이에 설명 추가합니다. -- 메서드 헤더는 `code` 틱으로 표시합니다. +- 코드 블럭에서 터미널 언어 선택시 `cmd` 대신 `bash`를 사용합니다. + (syntax highlighter를 사용하기 위해서) +- 문서의 `h1` 제목은 반드시 현재 객체 이름과 같게 해야 합니다. + (예시: `browser-window` → `BrowserWindow`) + - 하이픈(-)으로 구분되었건 다르게 구분되었건 예시와 같이 작성합니다. +- 헤더 밑에 헤더를 바로 사용하지 않습니다. 한 줄이라도 좋으니 헤더와 헤더 사이에 + 설명을 추가합니다. +- 메서드 헤더는 `code backtick` 으로 표시합니다. - 이벤트 헤더는 한 '따옴표'로 표시합니다. -- 리스트를 2 단계 이상 중첩하지 않습니다. (안타깝게도 markdown 랜더러가 지원하지 않습니다) -- 섹션에 대한 제목을 추가합니다: Events, Class 메서드 그리고 인스턴스 메서드등. +- 리스트를 2 단계 이상 중첩하지 않습니다. (안타깝게도 markdown 랜더러가 이를 + 지원하지 않습니다) +- 섹션에 대한 제목을 추가합니다. Events, Class 메서드 그리고 인스턴스 메서드 등 - 어떤 '것'의 사용 결과를 설명할 때 '될 것입니다' 형식을 사용하여 설명합니다. -- 이벤트와 메서드에는 `h3` 헤더를 사용합니다. +- 이벤트와 메서드를 표기할 땐 `h3` 헤더를 사용합니다. - 선택적 인수는 `function (required[, optional])` 형식으로 작성합니다. - 선택적 인수는 목록에서 호출되면 표시합니다. - 문장의 길이는 한 줄당 80 칸을 유지합니다. @@ -30,11 +36,13 @@ Electron 문서를 작성하는 규칙은 다음과 같습니다. 아직 번역되지 않은 언어를 추가하려면 (일부분 포함): -- 언어의 약어(예: en, ja, ko등)로 서브 디렉터리를 만듭니다. -- 서브 디렉터리에 `docs` 디렉터리를 복사합니다. 파일 이름과 디렉터리 구조는 모두 유지합니다. +- 언어의 약어(예: en-US, ja-JP, ko-KR)로 서브 디렉터리를 만듭니다. +- 서브 디렉터리에 `docs` 디렉터리를 복사합니다. 파일 이름과 디렉터리 구조는 + 모두 유지합니다. - 문서를 번역합니다. -- `README.md`에 번역한 문서의 링크를 추가하고 업데이트 합니다. -- 메인 Electron의 [README](https://github.com/atom/electron#documentation-translations)에 번역된 디렉터리의 링크를 추가합니다. +- 언어 디렉터리 내의 `README.md`에 번역한 문서의 링크를 추가합니다. +- 메인(upstream) Electron의 [README](https://github.com/atom/electron#documentation-translations)에 + 번역된 언어 디렉터리의 링크를 추가합니다. ## Electron 문서 읽기 @@ -42,7 +50,8 @@ Electron 문서 구조를 이해하는 데 참고할 수 있는 유용한 도움 ### Methods -[Method](https://developer.mozilla.org/en-US/docs/Glossary/Method) 문서의 예제입니다: +[Method](https://developer.mozilla.org/en-US/docs/Glossary/Method) 문서의 +예제입니다: --- @@ -53,8 +62,8 @@ Electron 문서 구조를 이해하는 데 참고할 수 있는 유용한 도움 --- -메서드 이름은 인수가 무엇을 받는지에 따라 결정됩니다. 선택적 인수는 브라켓([, ])으로 묶어 -이 인수가 다른 인수뒤에서 선택적으로 사용될 수 있다는 것을 표시합니다. +메서드 이름은 인수가 무엇을 받는지에 따라 결정됩니다. 선택적 인수는 브라켓([, ])으로 +묶어 이 인수가 다른 인수뒤에서 선택적으로 사용될 수 있다는 것을 표시합니다. 메서드 이름 하단에선 각 인수에 대해 자세한 설명을 합니다. 인수의 타입은 일반적인 타입 중 하나를 받거나: @@ -62,7 +71,8 @@ Electron 문서 구조를 이해하는 데 참고할 수 있는 유용한 도움 [`Number`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number), [`Object`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object), [`Array`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array) -와 같은 일반적으로 쓰이는 타입 중 하나를 받거나 Electron의 [`webContent`](api/web-content.md)같은 커스텀 타입을 받습니다. +와 같은 일반적으로 쓰이는 타입 중 하나를 받거나 Electron의 +[`webContent`](api/web-content.md)같은 커스텀 타입을 받습니다. ### Events @@ -78,8 +88,9 @@ Returns: --- -이벤트는 `.on` 리스너 메서드로 사용할 수 있습니다. 만약 이벤트에서 값을 반환한다면 문서에서 표시된 대로 -일정한 타입의 값을 반환합니다. 이벤트를 처리하거나 응답하려 한다면 다음과 같이 사용할 수 있습니다: +이벤트는 `.on` 리스너 메서드로 사용할 수 있습니다. 만약 이벤트에서 값을 반환한다면 +문서에서 표시된 대로 일정한 타입의 값을 반환합니다. 이벤트를 처리하거나 응답하려 한다면 +다음과 같이 사용할 수 있습니다: ```javascript Alarm.on('wake-up', function(time) { From ba5f8aa09683e34b265a4503436b58b120be78e7 Mon Sep 17 00:00:00 2001 From: Kevin Ramsunder Date: Wed, 18 Nov 2015 20:04:16 -0500 Subject: [PATCH 227/249] mac-app-store-submission-guide.md: typo correction --- docs/tutorial/mac-app-store-submission-guide.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/tutorial/mac-app-store-submission-guide.md b/docs/tutorial/mac-app-store-submission-guide.md index 4dc6f900a167..43b2d9a0a49b 100644 --- a/docs/tutorial/mac-app-store-submission-guide.md +++ b/docs/tutorial/mac-app-store-submission-guide.md @@ -7,7 +7,7 @@ limitations of the MAS build. ## How to Submit Your App The following steps introduce a simple way to submit your app to Mac App Store. -However, these steps do not ensure sure your app will be approved by Apple; you +However, these steps do not ensure your app will be approved by Apple; you still need to read Apple's [Submitting Your App][submitting-your-app] guide on how to meet the Mac App Store requirements. From c63121c2f65f86f0b070690ab47396d1356f413f Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Thu, 19 Nov 2015 13:49:50 +0800 Subject: [PATCH 228/249] Update libchromiumcontent Backport https://codereview.chromium.org/1324513002. --- 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 047ecf4faa76..2fb841acf35c 100644 --- a/script/lib/config.py +++ b/script/lib/config.py @@ -8,7 +8,7 @@ import sys BASE_URL = os.getenv('LIBCHROMIUMCONTENT_MIRROR') or \ 'http://gh-contractor-zcbenz.s3.amazonaws.com/libchromiumcontent' -LIBCHROMIUMCONTENT_COMMIT = '464aff2398f619b1d4d91b9187de69803919dca2' +LIBCHROMIUMCONTENT_COMMIT = '17a4337f7948a45b5ea4b8f391df152ba8db5979' PLATFORM = { 'cygwin': 'win32', From 2c06afad6ad3765ff7e55373196038498b38ae89 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Thu, 19 Nov 2015 15:10:33 +0800 Subject: [PATCH 229/249] Upload the dSYM symbols --- script/create-dist.py | 21 ++++++++++++++++++--- script/upload.py | 6 ++++++ 2 files changed, 24 insertions(+), 3 deletions(-) diff --git a/script/create-dist.py b/script/create-dist.py index d79d963c12ab..29f81ebd8579 100755 --- a/script/create-dist.py +++ b/script/create-dist.py @@ -1,5 +1,6 @@ #!/usr/bin/env python +import glob import os import re import shutil @@ -168,6 +169,11 @@ def create_symbols(): dump_symbols = os.path.join(SOURCE_ROOT, 'script', 'dump-symbols.py') execute([sys.executable, dump_symbols, destination]) + if PLATFORM == 'darwin': + dsyms = glob.glob(os.path.join(OUT_DIR, '*.dSYM')) + for dsym in dsyms: + shutil.copytree(dsym, os.path.join(DIST_DIR, os.path.basename(dsym))) + def create_dist_zip(): dist_name = '{0}-{1}-{2}-{3}.zip'.format(PROJECT_NAME, ATOM_SHELL_VERSION, @@ -203,12 +209,21 @@ def create_symbols_zip(): ATOM_SHELL_VERSION, get_platform_key(), get_target_arch()) - zip_file = os.path.join(SOURCE_ROOT, 'dist', dist_name) + zip_file = os.path.join(DIST_DIR, dist_name) + licenses = ['LICENSE', 'LICENSES.chromium.html', 'version'] with scoped_cwd(DIST_DIR): - files = ['LICENSE', 'LICENSES.chromium.html', 'version'] dirs = ['{0}.breakpad.syms'.format(PROJECT_NAME)] - make_zip(zip_file, files, dirs) + make_zip(zip_file, licenses, dirs) + + if PLATFORM == 'darwin': + dsym_name = '{0}-{1}-{2}-{3}-dsym.zip'.format(PROJECT_NAME, + ATOM_SHELL_VERSION, + get_platform_key(), + get_target_arch()) + with scoped_cwd(DIST_DIR): + dsyms = glob.glob('*.dSYM') + make_zip(os.path.join(DIST_DIR, dsym_name), licenses, dsyms) if __name__ == '__main__': diff --git a/script/upload.py b/script/upload.py index 318bbb594a11..c021d743a82e 100755 --- a/script/upload.py +++ b/script/upload.py @@ -31,6 +31,10 @@ SYMBOLS_NAME = '{0}-{1}-{2}-{3}-symbols.zip'.format(PROJECT_NAME, ATOM_SHELL_VERSION, get_platform_key(), get_target_arch()) +DSYM_NAME = '{0}-{1}-{2}-{3}-dsym.zip'.format(PROJECT_NAME, + ATOM_SHELL_VERSION, + get_platform_key(), + get_target_arch()) MKSNAPSHOT_NAME = 'mksnapshot-{0}-{1}-{2}.zip'.format(ATOM_SHELL_VERSION, get_platform_key(), get_target_arch()) @@ -82,6 +86,8 @@ def main(): # Upload atom-shell with GitHub Releases API. upload_atom_shell(github, release, os.path.join(DIST_DIR, DIST_NAME)) upload_atom_shell(github, release, os.path.join(DIST_DIR, SYMBOLS_NAME)) + if PLATFORM == 'darwin': + upload_atom_shell(github, release, os.path.join(DIST_DIR, DSYM_NAME)) # Upload chromedriver and mksnapshot for minor version update. if parse_version(args.version)[2] == '0': From d427ae10301be73844deea427f144e94bf457e94 Mon Sep 17 00:00:00 2001 From: Ben Gotow Date: Thu, 19 Nov 2015 00:39:45 -0800 Subject: [PATCH 230/249] Support the "desktop" window type on Mac OS X Adds the desktop window type referenced in https://github.com/atom/electron/issues/2899 for compatiblity with the linux version. Note that on Mac OS X, the desktop window cannot receive input events (seems to be a limitation of being behind the desktop). In this diff I also removed the `standardWindow` option from the docs, in favor of an additional `textured` value for window `type` on Mac OS X. The old `standardWindow` option continues to work, but seemed more confusing. If this seems like a bad idea, I can revert that change. --- atom/browser/native_window_mac.mm | 34 +++++++++++++++++++++++++++++-- docs/api/browser-window.md | 19 +++++++++-------- 2 files changed, 43 insertions(+), 10 deletions(-) diff --git a/atom/browser/native_window_mac.mm b/atom/browser/native_window_mac.mm index b129ded6f85e..5564f9116e4b 100644 --- a/atom/browser/native_window_mac.mm +++ b/atom/browser/native_window_mac.mm @@ -211,6 +211,8 @@ bool ScopedDisableResize::disable_resize_ = false; } @property BOOL acceptsFirstMouse; @property BOOL disableAutoHideCursor; +@property BOOL disableKeyOrMainWindow; + - (void)setShell:(atom::NativeWindowMac*)shell; - (void)setEnableLargerThanScreen:(bool)enable; @end @@ -257,6 +259,16 @@ bool ScopedDisableResize::disable_resize_ = false; return [children filteredArrayUsingPredicate:predicate]; } +- (BOOL)canBecomeMainWindow +{ + return !self.disableKeyOrMainWindow; +} + +- (BOOL)canBecomeKeyWindow +{ + return !self.disableKeyOrMainWindow; +} + @end @interface ControlRegionView : NSView @@ -330,8 +342,6 @@ NativeWindowMac::NativeWindowMac( width, height); - bool useStandardWindow = true; - options.Get(options::kStandardWindow, &useStandardWindow); bool resizable = true; options.Get(options::kResizable, &resizable); @@ -340,6 +350,17 @@ NativeWindowMac::NativeWindowMac( if (base::mac::IsOSYosemiteOrLater()) options.Get(options::kTitleBarStyle, &titleBarStyle); + std::string windowType; + options.Get(options::kType, &windowType); + + bool useStandardWindow = true; + // eventually deprecate separate "standardWindow" option in favor of + // standard / textured window types + options.Get(options::kStandardWindow, &useStandardWindow); + if (windowType == "textured") { + useStandardWindow = false; + } + NSUInteger styleMask = NSTitledWindowMask | NSClosableWindowMask | NSMiniaturizableWindowMask; if (!useStandardWindow || transparent() || !has_frame()) { @@ -371,6 +392,15 @@ NativeWindowMac::NativeWindowMac( [window_ setBackgroundColor:[NSColor clearColor]]; } + if (windowType == "desktop") { + [window_ setLevel:kCGDesktopWindowLevel - 1]; + [window_ setDisableKeyOrMainWindow: YES]; + [window_ setCollectionBehavior: + (NSWindowCollectionBehaviorCanJoinAllSpaces | + NSWindowCollectionBehaviorStationary | + NSWindowCollectionBehaviorIgnoresCycle)]; + } + // Remove non-transparent corners, see http://git.io/vfonD. if (!has_frame()) [window_ setOpaque:NO]; diff --git a/docs/api/browser-window.md b/docs/api/browser-window.md index f9b2a53ff595..a78531277e9e 100644 --- a/docs/api/browser-window.md +++ b/docs/api/browser-window.md @@ -66,11 +66,14 @@ It creates a new `BrowserWindow` with native properties as set by the `options`. * `darkTheme` Boolean - Forces using dark theme for the window, only works on some GTK+3 desktop environments. * `transparent` Boolean - Makes the window [transparent](frameless-window.md). -* `type` String - Specifies the type of the window, possible types are - `desktop`, `dock`, `toolbar`, `splash`, `notification`. This only works on - Linux. -* `standardWindow` Boolean - Uses the OS X's standard window instead of the - textured window. Defaults to `true`. +* `type` String - Specifies the type of the window, which applies + additional platform-specific properties. + - On Linux, possible types are `desktop`, `dock`, `toolbar`, `splash`, `notification`. + - On Mac OS X: + - `textured`: Adds metal gradient appearance (NSTexturedBackgroundWindowMask) + - `desktop`: Places the window at the desktop background window level (kCGDesktopWindowLevel - 1). + Note that the window will not receive focus, keyboard or mouse events, but + you can use `globalShortcut` to receive input sparingly. * `titleBarStyle` String, OS X - specifies the style of window title bar. This option is supported on OS X 10.10 Yosemite and newer. There are three possible values: @@ -86,11 +89,11 @@ It creates a new `BrowserWindow` with native properties as set by the `options`. is `true`. * `preload` String - Specifies a script that will be loaded before other scripts run in the page. This script will always have access to node APIs - no matter whether node integration is turned on or off. The value should + no matter whether node integration is turned on or off. The value should be the absolute file path to the script. - When node integration is turned off, the preload script can reintroduce - Node global symbols back to the global scope. See example + When node integration is turned off, the preload script can reintroduce + Node global symbols back to the global scope. See example [here](process.md#event-loaded). * `partition` String - Sets the session used by the page. If `partition` starts with `persist:`, the page will use a persistent session available to From 9a20b33d97c6131506170621ee132646424ceeab Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Thu, 19 Nov 2015 17:08:16 +0800 Subject: [PATCH 231/249] Add isDestroyed method for classes with destroy method --- atom/browser/api/atom_api_tray.cc | 1 + atom/browser/api/atom_api_web_contents.cc | 8 ++------ atom/browser/api/atom_api_web_contents.h | 1 - atom/browser/api/atom_api_window.cc | 6 +----- atom/browser/api/atom_api_window.h | 1 - 5 files changed, 4 insertions(+), 13 deletions(-) diff --git a/atom/browser/api/atom_api_tray.cc b/atom/browser/api/atom_api_tray.cc index d3c5931ad6da..5e32657f008a 100644 --- a/atom/browser/api/atom_api_tray.cc +++ b/atom/browser/api/atom_api_tray.cc @@ -161,6 +161,7 @@ void Tray::BuildPrototype(v8::Isolate* isolate, v8::Local prototype) { mate::ObjectTemplateBuilder(isolate, prototype) .SetMethod("destroy", &Tray::Destroy, true) + .SetMethod("isDestroyed", &Tray::IsDestroyed, true) .SetMethod("setImage", &Tray::SetImage) .SetMethod("setPressedImage", &Tray::SetPressedImage) .SetMethod("setToolTip", &Tray::SetToolTip) diff --git a/atom/browser/api/atom_api_web_contents.cc b/atom/browser/api/atom_api_web_contents.cc index 1c3334e93669..066ca9cc7b65 100644 --- a/atom/browser/api/atom_api_web_contents.cc +++ b/atom/browser/api/atom_api_web_contents.cc @@ -604,10 +604,6 @@ void WebContents::Destroy() { } } -bool WebContents::IsAlive() const { - return web_contents() != NULL; -} - int WebContents::GetID() const { return web_contents()->GetRenderProcessHost()->GetID(); } @@ -996,7 +992,7 @@ mate::ObjectTemplateBuilder WebContents::GetObjectTemplateBuilder( if (template_.IsEmpty()) template_.Reset(isolate, mate::ObjectTemplateBuilder(isolate) .SetMethod("destroy", &WebContents::Destroy, true) - .SetMethod("isAlive", &WebContents::IsAlive, true) + .SetMethod("isDestroyed", &WebContents::IsDestroyed, true) .SetMethod("getId", &WebContents::GetID) .SetMethod("equal", &WebContents::Equal) .SetMethod("_loadURL", &WebContents::LoadURL) @@ -1066,7 +1062,7 @@ mate::ObjectTemplateBuilder WebContents::GetObjectTemplateBuilder( } bool WebContents::IsDestroyed() const { - return !IsAlive(); + return !web_contents(); } AtomBrowserContext* WebContents::GetBrowserContext() const { diff --git a/atom/browser/api/atom_api_web_contents.h b/atom/browser/api/atom_api_web_contents.h index ae231cd3c61d..568a563e2c84 100644 --- a/atom/browser/api/atom_api_web_contents.h +++ b/atom/browser/api/atom_api_web_contents.h @@ -57,7 +57,6 @@ class WebContents : public mate::TrackableObject, // mate::TrackableObject: void Destroy() override; - bool IsAlive() const; int GetID() const; bool Equal(const WebContents* web_contents) const; void LoadURL(const GURL& url, const mate::Dictionary& options); diff --git a/atom/browser/api/atom_api_window.cc b/atom/browser/api/atom_api_window.cc index 61f43f9aac38..7f5b78a79780 100644 --- a/atom/browser/api/atom_api_window.cc +++ b/atom/browser/api/atom_api_window.cc @@ -284,10 +284,6 @@ void Window::Close() { window_->Close(); } -bool Window::IsClosed() { - return window_->IsClosed(); -} - void Window::Focus() { window_->Focus(true); } @@ -622,8 +618,8 @@ void Window::BuildPrototype(v8::Isolate* isolate, v8::Local prototype) { mate::ObjectTemplateBuilder(isolate, prototype) .SetMethod("destroy", &Window::Destroy, true) + .SetMethod("isDestroyed", &Window::IsDestroyed, true) .SetMethod("close", &Window::Close) - .SetMethod("isClosed", &Window::IsClosed) .SetMethod("focus", &Window::Focus) .SetMethod("isFocused", &Window::IsFocused) .SetMethod("show", &Window::Show) diff --git a/atom/browser/api/atom_api_window.h b/atom/browser/api/atom_api_window.h index 1c582551cc93..4161584206a7 100644 --- a/atom/browser/api/atom_api_window.h +++ b/atom/browser/api/atom_api_window.h @@ -89,7 +89,6 @@ class Window : public mate::TrackableObject, // APIs for NativeWindow. void Close(); - bool IsClosed(); void Focus(); bool IsFocused(); void Show(); From 47d7d49d192e79770c2dd4b73e2279a199d450cd Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Thu, 19 Nov 2015 20:47:11 +0800 Subject: [PATCH 232/249] Add session module --- atom/browser/api/lib/app.coffee | 6 ------ atom/browser/api/lib/exports/electron.coffee | 3 +++ atom/browser/api/lib/session.coffee | 17 +++++++++++++++++ atom/browser/api/lib/web-contents.coffee | 2 +- filenames.gypi | 1 + 5 files changed, 22 insertions(+), 7 deletions(-) create mode 100644 atom/browser/api/lib/session.coffee diff --git a/atom/browser/api/lib/app.coffee b/atom/browser/api/lib/app.coffee index 3db4582abc7c..9f9f5811d76a 100644 --- a/atom/browser/api/lib/app.coffee +++ b/atom/browser/api/lib/app.coffee @@ -2,7 +2,6 @@ electron = require 'electron' {EventEmitter} = require 'events' bindings = process.atomBinding 'app' -sessionBindings = process.atomBinding 'session' downloadItemBindings = process.atomBinding 'download_item' app = bindings.app @@ -61,11 +60,6 @@ deprecate.event app, 'activate-with-no-open-windows', 'activate', (event, hasVis deprecate.event app, 'select-certificate', 'select-client-certificate' # Wrappers for native classes. -wrapSession = (session) -> - # session is an EventEmitter. - session.__proto__ = EventEmitter.prototype -sessionBindings._setWrapSession wrapSession - wrapDownloadItem = (downloadItem) -> # downloadItem is an EventEmitter. downloadItem.__proto__ = EventEmitter.prototype diff --git a/atom/browser/api/lib/exports/electron.coffee b/atom/browser/api/lib/exports/electron.coffee index f0c3b87c987b..3f7d9b1a13fe 100644 --- a/atom/browser/api/lib/exports/electron.coffee +++ b/atom/browser/api/lib/exports/electron.coffee @@ -42,6 +42,9 @@ Object.defineProperties module.exports, screen: enumerable: true get: -> require '../screen' + session: + enumerable: true + get: -> require '../session' Tray: enumerable: true get: -> require '../tray' diff --git a/atom/browser/api/lib/session.coffee b/atom/browser/api/lib/session.coffee new file mode 100644 index 000000000000..e0fc7b6e0bca --- /dev/null +++ b/atom/browser/api/lib/session.coffee @@ -0,0 +1,17 @@ +{EventEmitter} = require 'events' + +bindings = process.atomBinding 'session' + +PERSIST_PERFIX = 'persist:' + +exports.fromPartition = (partition='') -> + if partition.startsWith PERSIST_PERFIX + bindings.fromPartition partition.substr(PERSIST_PERFIX.length), false + else + bindings.fromPartition partition, true + +wrapSession = (session) -> + # session is an EventEmitter. + session.__proto__ = EventEmitter.prototype + +bindings._setWrapSession wrapSession diff --git a/atom/browser/api/lib/web-contents.coffee b/atom/browser/api/lib/web-contents.coffee index 1a224c7416f5..335928dcea81 100644 --- a/atom/browser/api/lib/web-contents.coffee +++ b/atom/browser/api/lib/web-contents.coffee @@ -1,5 +1,5 @@ {EventEmitter} = require 'events' -{deprecate, ipcMain, NavigationController, Menu} = require 'electron' +{deprecate, ipcMain, session, NavigationController, Menu} = require 'electron' binding = process.atomBinding 'web_contents' diff --git a/filenames.gypi b/filenames.gypi index 7e1f3e1827e0..7157079178ee 100644 --- a/filenames.gypi +++ b/filenames.gypi @@ -26,6 +26,7 @@ 'atom/browser/api/lib/power-monitor.coffee', 'atom/browser/api/lib/power-save-blocker.coffee', 'atom/browser/api/lib/protocol.coffee', + 'atom/browser/api/lib/session.coffee', 'atom/browser/api/lib/screen.coffee', 'atom/browser/api/lib/tray.coffee', 'atom/browser/api/lib/web-contents.coffee', From 1392873cbc2c522877448cec2990c73517f29912 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Thu, 19 Nov 2015 21:03:42 +0800 Subject: [PATCH 233/249] Add session.defaultSession and remove app.defaultSession The latter has never been a public API, no need to keep it. --- atom/browser/api/atom_api_app.cc | 18 +----------------- atom/browser/api/atom_api_app.h | 3 --- atom/browser/api/lib/app.coffee | 10 +++++----- atom/browser/api/lib/browser-window.coffee | 4 +++- atom/browser/api/lib/session.coffee | 6 ++++++ 5 files changed, 15 insertions(+), 26 deletions(-) diff --git a/atom/browser/api/atom_api_app.cc b/atom/browser/api/atom_api_app.cc index 28c3b4c15983..697d6eca6aab 100644 --- a/atom/browser/api/atom_api_app.cc +++ b/atom/browser/api/atom_api_app.cc @@ -206,14 +206,6 @@ void App::OnWillFinishLaunching() { } void App::OnFinishLaunching() { - // Create the defaultSession. - v8::Locker locker(isolate()); - v8::HandleScope handle_scope(isolate()); - auto browser_context = static_cast( - AtomBrowserMainParts::Get()->browser_context()); - auto handle = Session::CreateFrom(isolate(), browser_context); - default_session_.Reset(isolate(), handle.ToV8()); - Emit("ready"); } @@ -325,13 +317,6 @@ std::string App::GetLocale() { return l10n_util::GetApplicationLocale(""); } -v8::Local App::DefaultSession(v8::Isolate* isolate) { - if (default_session_.IsEmpty()) - return v8::Null(isolate); - else - return v8::Local::New(isolate, default_session_); -} - bool App::MakeSingleInstance( const ProcessSingleton::NotificationCallback& callback) { if (process_singleton_.get()) @@ -382,8 +367,7 @@ mate::ObjectTemplateBuilder App::GetObjectTemplateBuilder( .SetMethod("allowNTLMCredentialsForAllDomains", &App::AllowNTLMCredentialsForAllDomains) .SetMethod("getLocale", &App::GetLocale) - .SetMethod("makeSingleInstance", &App::MakeSingleInstance) - .SetProperty("defaultSession", &App::DefaultSession); + .SetMethod("makeSingleInstance", &App::MakeSingleInstance); } // static diff --git a/atom/browser/api/atom_api_app.h b/atom/browser/api/atom_api_app.h index ee7e02079125..a6f99d65e0af 100644 --- a/atom/browser/api/atom_api_app.h +++ b/atom/browser/api/atom_api_app.h @@ -87,9 +87,6 @@ class App : public AtomBrowserClient::Delegate, bool MakeSingleInstance( const ProcessSingleton::NotificationCallback& callback); std::string GetLocale(); - v8::Local DefaultSession(v8::Isolate* isolate); - - v8::Global default_session_; scoped_ptr process_singleton_; diff --git a/atom/browser/api/lib/app.coffee b/atom/browser/api/lib/app.coffee index 9f9f5811d76a..c2116fb7bca4 100644 --- a/atom/browser/api/lib/app.coffee +++ b/atom/browser/api/lib/app.coffee @@ -1,4 +1,4 @@ -electron = require 'electron' +{deprecate, session, Menu} = require 'electron' {EventEmitter} = require 'events' bindings = process.atomBinding 'app' @@ -8,10 +8,10 @@ app = bindings.app app.__proto__ = EventEmitter.prototype app.setApplicationMenu = (menu) -> - electron.Menu.setApplicationMenu menu + Menu.setApplicationMenu menu app.getApplicationMenu = -> - electron.Menu.getApplicationMenu() + Menu.getApplicationMenu() app.commandLine = appendSwitch: bindings.appendSwitch, @@ -35,7 +35,8 @@ app.getAppPath = -> appPath # Helpers. -app.resolveProxy = (url, callback) -> @defaultSession.resolveProxy url, callback +app.resolveProxy = (url, callback) -> + session.defaultSession.resolveProxy url, callback # Routes the events to webContents. for name in ['login', 'certificate-error', 'select-client-certificate'] @@ -44,7 +45,6 @@ for name in ['login', 'certificate-error', 'select-client-certificate'] webContents.emit name, event, args... # Deprecated. -{deprecate} = electron app.getHomeDir = deprecate 'app.getHomeDir', 'app.getPath', -> @getPath 'home' app.getDataPath = deprecate 'app.getDataPath', 'app.getPath', -> diff --git a/atom/browser/api/lib/browser-window.coffee b/atom/browser/api/lib/browser-window.coffee index 99921372f14c..4cdffae87a60 100644 --- a/atom/browser/api/lib/browser-window.coffee +++ b/atom/browser/api/lib/browser-window.coffee @@ -1,10 +1,12 @@ -{app, ipcMain, deprecate} = require 'electron' +{ipcMain, deprecate} = require 'electron' {EventEmitter} = require 'events' {BrowserWindow} = process.atomBinding 'window' BrowserWindow::__proto__ = EventEmitter.prototype BrowserWindow::_init = -> + {app} = require 'electron' # avoid recursive require. + # Simulate the application menu on platforms other than OS X. if process.platform isnt 'darwin' menu = app.getApplicationMenu() diff --git a/atom/browser/api/lib/session.coffee b/atom/browser/api/lib/session.coffee index e0fc7b6e0bca..6abfe7925e69 100644 --- a/atom/browser/api/lib/session.coffee +++ b/atom/browser/api/lib/session.coffee @@ -4,12 +4,18 @@ bindings = process.atomBinding 'session' PERSIST_PERFIX = 'persist:' +# Returns the Session from |partition| string. exports.fromPartition = (partition='') -> if partition.startsWith PERSIST_PERFIX bindings.fromPartition partition.substr(PERSIST_PERFIX.length), false else bindings.fromPartition partition, true +# Returns the default session. +Object.defineProperty exports, 'defaultSession', + enumerable: true + get: -> exports.fromPartition '' + wrapSession = (session) -> # session is an EventEmitter. session.__proto__ = EventEmitter.prototype From dd8ef33e42e46bf5d80776b77ab457d1761bbc33 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Thu, 19 Nov 2015 21:10:50 +0800 Subject: [PATCH 234/249] docs: webContents.savePage is placed at wrong place --- docs/api/web-contents.md | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/docs/api/web-contents.md b/docs/api/web-contents.md index be22d947c752..2b2efb7d47ba 100644 --- a/docs/api/web-contents.md +++ b/docs/api/web-contents.md @@ -678,17 +678,6 @@ is in 32bit ARGB format). End subscribing for frame presentation events. -## Instance Properties - -`WebContents` objects also have the following properties: - -### `webContents.devToolsWebContents` - -Get the `WebContents` of DevTools for this `WebContents`. - -**Note:** Users should never store this object because it may become `null` -when the DevTools has been closed. - ### `webContents.savePage(fullPath, saveType, callback)` * `fullPath` String - The full file path. @@ -711,3 +700,14 @@ win.webContents.on('did-finish-load', function() { }); }); ``` + +## Instance Properties + +`WebContents` objects also have the following properties: + +### `webContents.devToolsWebContents` + +Get the `WebContents` of DevTools for this `WebContents`. + +**Note:** Users should never store this object because it may become `null` +when the DevTools has been closed. From 44c562ebd9ec14a421b85dd63967bae2f3166373 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Thu, 19 Nov 2015 21:31:39 +0800 Subject: [PATCH 235/249] docs: New session methods --- docs/api/session.md | 79 +++++++++++++++++++++++++++++++++------------ 1 file changed, 58 insertions(+), 21 deletions(-) diff --git a/docs/api/session.md b/docs/api/session.md index 450be7b08e11..b921fc4839bd 100644 --- a/docs/api/session.md +++ b/docs/api/session.md @@ -1,8 +1,10 @@ # session -The `session` object is a property of [`webContents`](web-contents.md) which is -a property of [`BrowserWindow`](browser-window.md). You can access it through an -instance of `BrowserWindow`. For example: +The `session` module can be used to create new `Session` objects. + +You can also access the `session` of existing pages by using the `session` +property of [`webContents`](web-contents.md) which is a property of +[`BrowserWindow`](browser-window.md). ```javascript const BrowserWindow = require('electron').BrowserWindow; @@ -10,12 +12,47 @@ const BrowserWindow = require('electron').BrowserWindow; var win = new BrowserWindow({ width: 800, height: 600 }); win.loadURL("http://github.com"); -var session = win.webContents.session +var ses = win.webContents.session ``` -## Events +## Methods -### Event: 'will-download' +The `session` module has the following methods: + +### session.fromPartition(partition) + +* `partition` String + +Returns a new `Session` instance from `partition` string. + +If `partition` starts with `persist:`, the page will use a persistent session +available to all pages in the app with the same `partition`. if there is no +`persist:` prefix, the page will use an in-memory session. If the `partition` is +empty then default session of the app will be returned. + +## Properties + +The `session` module has the following properties: + +### session.defaultSession + +Returns the default session object of the app. + +## Class: Session + +You can create a `Session` object in the `session` module: + +```javascript +const session = require('electron').session; + +var ses = session.fromPartition('persist:name'); +``` + +### Instance Events + +The following events are available on instances of `Session`: + +#### Event: 'will-download' * `event` Event * `item` [DownloadItem](download-item.md) @@ -34,11 +71,11 @@ session.on('will-download', function(event, item, webContents) { }); ``` -## Methods +### Instance Methods -The `session` object has the following methods: +The following methods are available on instances of `Session`: -### `session.cookies` +#### `ses.cookies` The `cookies` gives you ability to query and modify cookies. For example: @@ -74,7 +111,7 @@ win.webContents.on('did-finish-load', function() { }); ``` -### `session.cookies.get(details, callback)` +#### `ses.cookies.get(details, callback)` `details` Object, properties: @@ -102,7 +139,7 @@ win.webContents.on('did-finish-load', function() { the number of seconds since the UNIX epoch. Not provided for session cookies. -### `session.cookies.set(details, callback)` +#### `ses.cookies.set(details, callback)` `details` Object, properties: @@ -121,23 +158,23 @@ win.webContents.on('did-finish-load', function() { * `callback` Function - function(error) * `error` Error -### `session.cookies.remove(details, callback)` +#### `ses.cookies.remove(details, callback)` -* `details` Object, proprties: +* `details` Object * `url` String - The URL associated with the cookie * `name` String - The name of cookie to remove * `callback` Function - function(error) * `error` Error -### `session.clearCache(callback)` +#### `ses.clearCache(callback)` * `callback` Function - Called when operation is done Clears the session’s HTTP cache. -### `session.clearStorageData([options, ]callback)` +#### `ses.clearStorageData([options, ]callback)` -* `options` Object (optional), proprties: +* `options` Object (optional) * `origin` String - Should follow `window.location.origin`’s representation `scheme://host:port`. * `storages` Array - The types of storages to clear, can contain: @@ -149,7 +186,7 @@ Clears the session’s HTTP cache. Clears the data of web storages. -### `session.setProxy(config, callback)` +#### `ses.setProxy(config, callback)` * `config` String * `callback` Function - Called when operation is done. @@ -187,14 +224,14 @@ proxy-uri = ["://"][":"] URLs. ``` -### `session.setDownloadPath(path)` +#### `ses.setDownloadPath(path)` * `path` String - The download location Sets download saving directory. By default, the download directory will be the `Downloads` under the respective app folder. -### `session.enableNetworkEmulation(options)` +#### `ses.enableNetworkEmulation(options)` * `options` Object * `offline` Boolean - Whether to emulate network outage. @@ -216,12 +253,12 @@ window.webContents.session.enableNetworkEmulation({ window.webContents.session.enableNetworkEmulation({offline: true}); ``` -### `session.disableNetworkEmulation` +#### `ses.disableNetworkEmulation()` Disables any network emulation already active for the `session`. Resets to the original network configuration. -### `session.setCertificateVerifyProc(proc)` +#### `ses.setCertificateVerifyProc(proc)` * `proc` Function From 08c13cf446d509c79770e8ad635f7d4b339092bb Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Thu, 19 Nov 2015 21:32:46 +0800 Subject: [PATCH 236/249] Deprecate app.resolveProxy There is now a public API to get default session, this helper is no longer necessary. --- atom/browser/api/lib/app.coffee | 6 ++---- docs/api/app.md | 8 -------- docs/api/session.md | 8 ++++++++ 3 files changed, 10 insertions(+), 12 deletions(-) diff --git a/atom/browser/api/lib/app.coffee b/atom/browser/api/lib/app.coffee index c2116fb7bca4..a2fdb847e1c5 100644 --- a/atom/browser/api/lib/app.coffee +++ b/atom/browser/api/lib/app.coffee @@ -34,10 +34,6 @@ app.setAppPath = (path) -> app.getAppPath = -> appPath -# Helpers. -app.resolveProxy = (url, callback) -> - session.defaultSession.resolveProxy url, callback - # Routes the events to webContents. for name in ['login', 'certificate-error', 'select-client-certificate'] do (name) -> @@ -51,6 +47,8 @@ app.getDataPath = deprecate 'app.getDataPath', 'app.getPath', -> @getPath 'userData' app.setDataPath = deprecate 'app.setDataPath', 'app.setPath', (path) -> @setPath 'userData', path +app.resolveProxy = deprecate 'app.resolveProxy', 'session.defaultSession.resolveProxy', (url, callback) -> + session.defaultSession.resolveProxy url, callback deprecate.rename app, 'terminate', 'quit' deprecate.event app, 'finish-launching', 'ready', -> setImmediate => # give default app a chance to setup default menu. diff --git a/docs/api/app.md b/docs/api/app.md index d7850c4cb92c..a1d87d2fe993 100644 --- a/docs/api/app.md +++ b/docs/api/app.md @@ -311,14 +311,6 @@ preferred over `name` by Electron. Returns the current application locale. -### `app.resolveProxy(url, callback)` - -* `url` URL -* `callback` Function - -Resolves the proxy information for `url`. The `callback` will be called with -`callback(proxy)` when the request is performed. - ### `app.addRecentDocument(path)` _OS X_ _Windows_ * `path` String diff --git a/docs/api/session.md b/docs/api/session.md index b921fc4839bd..a69c5939ed65 100644 --- a/docs/api/session.md +++ b/docs/api/session.md @@ -224,6 +224,14 @@ proxy-uri = ["://"][":"] URLs. ``` +### `ses.resolveProxy(url, callback)` + +* `url` URL +* `callback` Function + +Resolves the proxy information for `url`. The `callback` will be called with +`callback(proxy)` when the request is performed. + #### `ses.setDownloadPath(path)` * `path` String - The download location From 611f87d17f3fa80529e667199de112954c8d9982 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Thu, 19 Nov 2015 21:42:22 +0800 Subject: [PATCH 237/249] spec: Use session.defaultSession in tests --- spec/api-session-spec.coffee | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/spec/api-session-spec.coffee b/spec/api-session-spec.coffee index bf91bdd6fc77..6d0a8ac167c0 100644 --- a/spec/api-session-spec.coffee +++ b/spec/api-session-spec.coffee @@ -4,7 +4,7 @@ path = require 'path' fs = require 'fs' {ipcRenderer, remote} = require 'electron' -{app, ipcMain, BrowserWindow} = remote.require 'electron' +{app, ipcMain, session, BrowserWindow} = remote describe 'session module', -> @timeout 10000 @@ -35,9 +35,9 @@ describe 'session module', -> done('Can not find cookie') it 'should over-write the existent cookie', (done) -> - app.defaultSession.cookies.set {url: url, name: '1', value: '1'}, (error) -> + session.defaultSession.cookies.set {url: url, name: '1', value: '1'}, (error) -> return done(error) if error - app.defaultSession.cookies.get {url: url}, (error, list) -> + session.defaultSession.cookies.get {url: url}, (error, list) -> return done(error) if error for cookie in list when cookie.name is '1' if cookie.value is '1' @@ -47,11 +47,11 @@ describe 'session module', -> done('Can not find cookie') it 'should remove cookies', (done) -> - app.defaultSession.cookies.set {url: url, name: '2', value: '2'}, (error) -> + session.defaultSession.cookies.set {url: url, name: '2', value: '2'}, (error) -> return done(error) if error - app.defaultSession.cookies.remove {url: url, name: '2'}, (error) -> + session.defaultSession.cookies.remove {url: url, name: '2'}, (error) -> return done(error) if error - app.defaultSession.cookies.get {url: url}, (error, list) -> + session.defaultSession.cookies.get {url: url}, (error, list) -> return done(error) if error for cookie in list when cookie.name is '2' return done('Cookie not deleted') From 1b464c82e1e99dce6d95f0ac302d601c8e268b3d Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Thu, 19 Nov 2015 21:48:45 +0800 Subject: [PATCH 238/249] docs: Put webContents.session under Properties --- docs/api/web-contents.md | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/docs/api/web-contents.md b/docs/api/web-contents.md index 2b2efb7d47ba..a716bdc593a7 100644 --- a/docs/api/web-contents.md +++ b/docs/api/web-contents.md @@ -225,12 +225,6 @@ The usage is the same with [the `login` event of `app`](app.md#event-login). The `webContents` object has the following instance methods: -### `webContents.session` - -Returns the `session` object used by this webContents. - -See [session documentation](session.md) for this object's methods. - ### `webContents.loadURL(url[, options])` * `url` URL @@ -705,6 +699,10 @@ win.webContents.on('did-finish-load', function() { `WebContents` objects also have the following properties: +### `webContents.session` + +Returns the [session](session.md) object used by this webContents. + ### `webContents.devToolsWebContents` Get the `WebContents` of DevTools for this `WebContents`. From f2472274b7604dda90bdf122a2c2718539484268 Mon Sep 17 00:00:00 2001 From: Sota Yamashita Date: Thu, 19 Nov 2015 22:52:37 +0900 Subject: [PATCH 239/249] Rename quick-start.md -> tutorial/quick-start.md --- docs-translations/jp/{ => tutorial}/quick-start.md | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename docs-translations/jp/{ => tutorial}/quick-start.md (100%) diff --git a/docs-translations/jp/quick-start.md b/docs-translations/jp/tutorial/quick-start.md similarity index 100% rename from docs-translations/jp/quick-start.md rename to docs-translations/jp/tutorial/quick-start.md From bee1af3264df67583b44cc99d3c7715f78019fa6 Mon Sep 17 00:00:00 2001 From: Sota Yamashita Date: Thu, 19 Nov 2015 22:54:01 +0900 Subject: [PATCH 240/249] Create README.md --- docs-translations/jp/READE.md | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 docs-translations/jp/READE.md diff --git a/docs-translations/jp/READE.md b/docs-translations/jp/READE.md new file mode 100644 index 000000000000..32b14b0fdd2b --- /dev/null +++ b/docs-translations/jp/READE.md @@ -0,0 +1,3 @@ +# チュートリアル + +* [クイックスタート](tutorial/quick-start.md) From fd3b8ad62304d74b76ddba6d50ea08cd03663151 Mon Sep 17 00:00:00 2001 From: Sota Yamashita Date: Thu, 19 Nov 2015 22:54:40 +0900 Subject: [PATCH 241/249] Rename: READE.md -> README.md --- docs-translations/jp/{READE.md => README.md} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename docs-translations/jp/{READE.md => README.md} (100%) diff --git a/docs-translations/jp/READE.md b/docs-translations/jp/README.md similarity index 100% rename from docs-translations/jp/READE.md rename to docs-translations/jp/README.md From eca98b85fcbabcca9ccb265287cf665da830753f Mon Sep 17 00:00:00 2001 From: Plusb Preco Date: Fri, 20 Nov 2015 02:25:44 +0900 Subject: [PATCH 242/249] Cleanup docs, fix typos --- README-ko.md | 20 +-- .../development/atom-shell-vs-node-webkit.md | 19 ++- .../development/build-instructions-linux.md | 31 ++-- .../development/build-instructions-osx.md | 10 +- .../development/build-instructions-windows.md | 42 +++--- .../development/build-system-overview.md | 28 ++-- .../ko-KR/development/coding-style.md | 36 +++-- .../development/setting-up-symbol-server.md | 36 +++-- .../source-code-directory-structure.md | 31 ++-- docs-translations/ko-KR/styleguide.md | 23 ++- .../tutorial/application-distribution.md | 59 ++++---- .../ko-KR/tutorial/application-packaging.md | 61 ++++---- .../ko-KR/tutorial/debugging-main-process.md | 17 ++- .../desktop-environment-integration.md | 138 +++++++++++------- .../ko-KR/tutorial/devtools-extension.md | 42 ++++-- .../mac-app-store-submission-guide.md | 39 ++--- .../ko-KR/tutorial/online-offline-events.md | 11 +- .../ko-KR/tutorial/quick-start.md | 70 +++++---- .../ko-KR/tutorial/supported-platforms.md | 16 +- .../tutorial/using-native-node-modules.md | 33 +++-- .../tutorial/using-pepper-flash-plugin.md | 8 +- .../tutorial/using-selenium-and-webdriver.md | 33 +++-- 22 files changed, 463 insertions(+), 340 deletions(-) diff --git a/README-ko.md b/README-ko.md index d35ba87f62b7..606d4e973e3e 100644 --- a/README-ko.md +++ b/README-ko.md @@ -8,8 +8,8 @@ :zap: *프레임워크 이름이 Atom Shell에서 Electron으로 변경되었습니다* :zap: -Electron 프레임워크는 JavaScript, HTML 그리고 CSS를 사용하여 Cross-Platform 데스크톱 -어플리케이션을 개발할 수 있도록 해주는 프레임워크입니다. 이 프레임워크는 +Electron 프레임워크는 JavaScript, HTML 그리고 CSS를 사용하여 +Cross-Platform 데스크톱 어플리케이션을 개발할 수 있도록 해주는 프레임워크입니다. [Node.js](https://nodejs.org/)와 [Chromium](http://www.chromium.org)을 기반으로 만들어졌으며 [Atom Editor](https://github.com/atom/atom)에 사용되고 있습니다. @@ -17,17 +17,17 @@ Electron에 대한 중요한 알림을 받고 싶다면 Twitter에서 [@ElectronJS](https://twitter.com/electronjs)를 팔로우 하세요. 이 프로젝트는 [기여자 규약 1.2](http://contributor-covenant.org/version/1/2/0/)을 -준수합니다. 따라서 이 프로젝트의 개발에 참여하려면 이 계약을 지켜야 합니다. -받아들일 수 없는 행위를 발견했을 경우 atom@github.com로 보고 하십시오. +준수합니다. 따라서 이 프로젝트의 개발에 참여하려면 이 계약을 지켜야 합니다. 받아들일 수 +없는 행위를 발견했을 경우 atom@github.com로 보고 하십시오. ## 다운로드 Linux, Windows, OS X 용으로 미리 빌드된 Electron 바이너리와 디버그 심볼이 준비되어 -있습니다. [releases](https://github.com/atom/electron/releases) 페이지에서 -받아 볼 수 있습니다. +있습니다. [releases](https://github.com/atom/electron/releases) 페이지에서 받아 볼 +수 있습니다. -또한 [`npm`](https://docs.npmjs.com/)을 통해 미리 빌드된 Electron 바이너리를 -설치할 수도 있습니다: +또한 [`npm`](https://docs.npmjs.com/)을 통해 미리 빌드된 Electron 바이너리를 설치할 +수도 있습니다: ```sh # $PATH에 `electron` 커맨드를 등록하고 전역에 설치합니다. @@ -70,5 +70,5 @@ API 레퍼런스가 있습니다. Electron을 빌드 하는 방법과 프로젝 - Slack의 [`Atom`](http://atom-slack.herokuapp.com/) 채널 [awesome-electron](https://github.com/sindresorhus/awesome-electron) 프로젝트에 -커뮤니티가 운영중인 유용한 예제 어플리케이션과 도구, 리소스가 있으니 -한번 참고해 보시기 바랍니다. +커뮤니티가 운영중인 유용한 예제 어플리케이션과 도구, 리소스가 있으니 한번 참고해 보시기 +바랍니다. diff --git a/docs-translations/ko-KR/development/atom-shell-vs-node-webkit.md b/docs-translations/ko-KR/development/atom-shell-vs-node-webkit.md index e7dd017fd720..22e8e3756469 100644 --- a/docs-translations/ko-KR/development/atom-shell-vs-node-webkit.md +++ b/docs-translations/ko-KR/development/atom-shell-vs-node-webkit.md @@ -2,17 +2,17 @@ __참고: Electron은 Atom Shell의 새로운 이름입니다.__ -NW.js 처럼 Electron은 JavaScript와 HTML 그리고 Node 통합 환경을 제공함으로써 -웹 페이지에서 저 수준 시스템에 접근할 수 있도록 하여 웹 기반 데스크탑 어플리케이션을 +NW.js 처럼 Electron은 JavaScript와 HTML 그리고 Node 통합 환경을 제공함으로써 웹 +페이지에서 저 수준 시스템에 접근할 수 있도록 하여 웹 기반 데스크탑 어플리케이션을 작성할 수 있도록 하는 프레임워크 입니다. 하지만 Electron과 NW.js는 근본적인 개발흐름의 차이도 있습니다: __1. 어플리케이션의 엔트리 포인트__ -NW.js에선 어플리케이션의 엔트리 포인트로 웹 페이지를 사용합니다. -`package.json`내의 main 필드에 메인 웹 페이지(index.html) URL을 지정하면 -어플리케이션의 메인 윈도우로 열리게 됩니다. +NW.js에선 어플리케이션의 엔트리 포인트로 웹 페이지를 사용합니다. `package.json`내의 +main 필드에 메인 웹 페이지(index.html) URL을 지정하면 어플리케이션의 메인 윈도우로 +열리게 됩니다. Electron에선 JavaScript를 엔트리 포인트로 사용합니다. URL을 직접 제공하는 대신 API를 사용하여 직접 브라우저 창과 HTML 파일을 로드할 수 있습니다. 또한 윈도우의 종료시기를 @@ -31,11 +31,10 @@ Chromium Content 모듈과 종속성 라이브러리들을 포함합니다. 유 __3. Node 통합__ -NW.js는 웹 페이지에서 require를 사용할 수 있도록 Chromium을 패치했습니다. -한편 Electron은 Chromium의 해킹을 방지하기 위해 libuv loop와 각 플랫폼의 -메시지 루프에 통합하는 다른 방법을 채택하였습니다. -[`node_bindings`][node-bindings]의 코드를 보면 이 부분이 어떻게 구현됬는지를 -알 수 있습니다. +NW.js는 웹 페이지에서 require를 사용할 수 있도록 Chromium을 패치했습니다. 한편 +Electron은 Chromium의 해킹을 방지하기 위해 libuv loop와 각 플랫폼의 메시지 루프에 +통합하는 다른 방법을 채택하였습니다. [`node_bindings`][node-bindings]의 코드를 보면 +이 부분이 어떻게 구현됬는지 알 수 있습니다. __4. 다중 컨텍스트__ diff --git a/docs-translations/ko-KR/development/build-instructions-linux.md b/docs-translations/ko-KR/development/build-instructions-linux.md index 7a6a476400a0..c4f161fa56a2 100644 --- a/docs-translations/ko-KR/development/build-instructions-linux.md +++ b/docs-translations/ko-KR/development/build-instructions-linux.md @@ -38,8 +38,8 @@ $ sudo yum install clang dbus-devel gtk2-devel libnotify-devel libgnome-keyring- ## 가상머신을 사용하여 빌드 하는 경우 -만약 Electron을 가상머신으로 빌드 할 계획이라면 해당 가상머신의 스토리지를 -최소 25GB 이상을 확보해 놓아야 합니다. +만약 Electron을 가상머신으로 빌드 할 계획이라면 해당 가상머신의 스토리지를 최소 25GB +이상 확보해 놓아야 합니다. ## 코드 가져오기 @@ -49,11 +49,10 @@ $ git clone https://github.com/atom/electron.git ## 부트 스트랩 -부트스트랩 스크립트는 필수적인 빌드 종속성 라이브러리들을 모두 다운로드하고 -프로젝트 파일을 생성합니다. 스크립트가 정상적으로 작동하기 위해선 -Python 2.7.x 버전이 필요합니다. 아마 다운로드 작업이 상당히 많은 시간을 -소요할 것입니다. 참고로 Electron은 빌드 툴체인으로 `ninja`를 사용하므로 -`Makefile`은 생성되지 않습니다. +부트스트랩 스크립트는 필수적인 빌드 종속성 라이브러리들을 모두 다운로드하고 프로젝트 +파일을 생성합니다. 스크립트가 정상적으로 작동하기 위해선 Python 2.7.x 버전이 +필요합니다. 아마 다운로드 작업이 상당히 많은 시간을 소요할 것입니다. 참고로 Electron은 +`ninja`를 빌드 툴체인으로 사용하므로 `Makefile`은 생성되지 않습니다. ```bash $ cd electron @@ -84,18 +83,18 @@ $ ./script/bootstrap.py -v --target_arch=arm $ ./script/build.py ``` -이 스크립트는 `out/R` 디렉터리에 크기가 매우 큰 Electron 실행 파일을 배치합니다. -파일 크기는 1.3GB를 초과합니다. 이러한 문제가 발생하는 이유는 Release 타겟 바이너리가 -디버그 심볼을 포함하기 때문입니다. 파일 크기를 줄이려면 -`create-dist.py` 스크립트를 실행하세요: +이 스크립트는 `out/R` 디렉터리에 크기가 매우 큰 Electron 실행 파일을 배치합니다. 파일 +크기는 1.3GB를 초과합니다. 이러한 문제가 발생하는 이유는 Release 타겟 바이너리가 +디버그 심볼을 포함하기 때문입니다. 파일 크기를 줄이려면 `create-dist.py` 스크립트를 +실행하세요: ```bash $ ./script/create-dist.py ``` -이 스크립트는 매우 작은 배포판을 `dist` 디렉터리에 생성합니다. -create-dist.py 스크립트를 실행한 이후부턴 1.3GB를 초과하는 공간을 차지하는 -`out/R` 폴더의 바이너리는 삭제해도 됩니다. +이 스크립트는 매우 작은 배포판을 `dist` 디렉터리에 생성합니다. create-dist.py +스크립트를 실행한 이후부턴 1.3GB에 육박하는 공간을 차지하는 `out/R` 폴더의 바이너리는 +삭제해도 됩니다. 또는 `Debug` 타겟만 빌드 할 수 있습니다: @@ -119,8 +118,8 @@ $ ./script/clean.py ## libtinfo.so.5 동적 링크 라이브러리를 로드하는 도중 에러가 발생할 경우 -미리 빌드된 `clang`은 `libtinfo.so.5`로 링크를 시도합니다. -따라서 플랫폼에 따라 적당한 `libncurses` symlink를 추가하세요: +미리 빌드된 `clang`은 `libtinfo.so.5`로 링크를 시도합니다. 따라서 플랫폼에 따라 +적당한 `libncurses` symlink를 추가하세요: ```bash $ sudo ln -s /usr/lib/libncurses.so.5 /usr/lib/libtinfo.so.5 diff --git a/docs-translations/ko-KR/development/build-instructions-osx.md b/docs-translations/ko-KR/development/build-instructions-osx.md index 222d4fc31c4e..9e2a76d31045 100644 --- a/docs-translations/ko-KR/development/build-instructions-osx.md +++ b/docs-translations/ko-KR/development/build-instructions-osx.md @@ -20,9 +20,9 @@ $ git clone https://github.com/atom/electron.git ## 부트 스트랩 -부트스트랩 스크립트는 필수적인 빌드 종속성 라이브러리들을 모두 다운로드하고 -프로젝트 파일을 생성합니다. 참고로 Electron은 빌드 툴체인으로 `ninja`를 사용하므로 -Xcode 프로젝트는 생성되지 않습니다. +부트스트랩 스크립트는 필수적인 빌드 종속성 라이브러리들을 모두 다운로드하고 프로젝트 +파일을 생성합니다. 참고로 Electron은 `ninja`를 빌드 툴체인으로 사용하므로 Xcode +프로젝트는 생성되지 않습니다. ```bash $ cd electron @@ -47,8 +47,8 @@ $ ./script/build.py -c D ## 32비트 지원 -Electron은 현재 OS X 64비트만 지원하고 있습니다. 그리고 앞으로도 OS X 32비트는 -지원할 계획이 없습니다. +Electron은 현재 OS X 64비트만 지원하고 있습니다. 그리고 앞으로도 OS X 32비트는 지원할 +계획이 없습니다. ## 테스트 diff --git a/docs-translations/ko-KR/development/build-instructions-windows.md b/docs-translations/ko-KR/development/build-instructions-windows.md index 69811ac388f7..13bbf47a3a76 100644 --- a/docs-translations/ko-KR/development/build-instructions-windows.md +++ b/docs-translations/ko-KR/development/build-instructions-windows.md @@ -11,18 +11,18 @@ * [Git](http://git-scm.com) 현재 사용하고 있는 PC에 Windows를 설치하지 않았다면 [modern.ie](https://www.modern.ie/en-us/virtualization-tools#downloads)에서 -사용 기한이 정해져있는 무료 가상머신 버전의 Windows를 받아 Electron을 -빌드하는 방법도 있습니다. +사용 기한이 정해져있는 무료 가상머신 버전의 Windows를 받아 Electron을 빌드하는 방법도 +있습니다. -Electron은 모든 빌드를 command-line 스크립트를 통해 빌드합니다. 따라서 빌드에 -Visual Studio를 사용할 수 없습니다. 하지만 여전히 Electron을 개발할 땐 아무 에디터나 -사용할 수 있습니다. 빠른 시일내에 Visual Studio를 이용한 빌드도 지원할 계획입니다. +Electron은 모든 빌드를 command-line 스크립트를 통해 빌드합니다. 따라서 빌드에 Visual +Studio를 사용할 수 없습니다. 하지만 여전히 Electron을 개발할 땐 어떤 에디터든 사용이 +가능합니다. 그리고 빠른 시일내에 Visual Studio를 이용한 빌드도 지원할 계획입니다. -**참고:** Visual Studio가 직접 빌드에 사용되지 않더라도 IDE와 같이 제공된 -빌드 툴체인이 빌드에 **반드시** 사용되므로 여전히 필요합니다. +**참고:** Visual Studio가 직접 빌드에 사용되지 않더라도 IDE와 같이 제공된 빌드 +툴체인이 빌드에 **반드시** 사용되므로 여전히 필요합니다. -**참고:** Visual Studio 2015는 사용할 수 없습니다. -MSVS **2013** 을 사용하고 있는지 확인해주세요. +**참고:** Visual Studio 2015는 사용할 수 없습니다 MSVS **2013** 을 사용하고 있는지 +확인해주세요. ## 코드 가져오기 @@ -32,9 +32,9 @@ $ git clone https://github.com/atom/electron.git ## 부트 스트랩 -부트스트랩 스크립트는 필수적인 빌드 종속성 라이브러리들을 모두 다운로드하고 -프로젝트 파일을 생성합니다. 참고로 Electron은 빌드 툴체인으로 `ninja`를 사용하므로 -Visual Studio 프로젝트는 생성되지 않습니다. +부트스트랩 스크립트는 필수적인 빌드 종속성 라이브러리들을 모두 다운로드하고 프로젝트 +파일을 생성합니다. 참고로 Electron은 `ninja`를 빌드 툴체인으로 사용하므로 Visual +Studio 프로젝트는 생성되지 않습니다. ```powershell $ cd electron @@ -60,8 +60,8 @@ $ python script\build.py -c D ## 64비트 빌드 -64비트를 타겟으로 빌드 하려면 부트스트랩 스크립트를 실행할 때 -`--target_arch=x64` 인자를 같이 넘겨주면 됩니다: +64비트를 타겟으로 빌드 하려면 부트스트랩 스크립트를 실행할 때 `--target_arch=x64` +인자를 같이 넘겨주면 됩니다: ```powershell $ python script\bootstrap.py -v --target_arch=x64 @@ -83,8 +83,8 @@ $ python script\cpplint.py $ python script\test.py ``` -테스트 실행시 `runas`와 같은 네이티브 모듈을 포함하는데 이 모듈은 디버그 빌드에서 -같이 사용할 수 없습니다. 하지만 여전히 릴리즈 빌드에선 사용할 수 있습니다. +테스트 실행시 `runas`와 같은 네이티브 모듈을 포함하는데 이 모듈은 디버그 빌드에서 같이 +사용할 수 없습니다. 하지만 여전히 릴리즈 빌드에선 사용할 수 있습니다. 릴리즈 빌드로 테스트를 실행하려면 다음 커맨드를 사용하면 됩니다: @@ -105,8 +105,8 @@ Visual Studio가 업데이트까지 완벽하게 설치된 최신버전인지 ### Assertion failed: ((handle))->activecnt >= 0 -Cygwin에서 빌드 할 경우 `bootstrap.py` 스크립트가 다음의 에러와 함께 빌드에 -실패할 수 있습니다: +Cygwin에서 빌드 할 경우 `bootstrap.py` 스크립트가 다음의 에러와 함께 빌드에 실패할 수 +있습니다: ``` Assertion failed: ((handle))->activecnt >= 0, file src\win\pipe.c, line 1430 @@ -123,9 +123,9 @@ Traceback (most recent call last): subprocess.CalledProcessError: Command '['npm.cmd', 'install']' returned non-zero exit status 3 ``` -이 버그는 Cygwin Python과 Win32 Node를 같이 사용할 때 발생합니다. -부트스트랩 스크립트에서 Win32 Python을 사용함으로써 이 문제를 해결할 수 있습니다. -`C:\Python27` 디렉터리에 Python이 설치되었다는 가정하에 다음 명령을 실행하면 됩니다: +이 버그는 Cygwin Python과 Win32 Node를 같이 사용할 때 발생합니다. 부트스트랩 +스크립트에서 Win32 Python을 사용함으로써 이 문제를 해결할 수 있습니다. `C:\Python27` +디렉터리에 Python이 설치되었다는 가정하에 다음 명령을 실행하면 됩니다: ```bash $ /cygdrive/c/Python27/python.exe script/bootstrap.py diff --git a/docs-translations/ko-KR/development/build-system-overview.md b/docs-translations/ko-KR/development/build-system-overview.md index 0c35d04d7bd7..71002ff584e4 100644 --- a/docs-translations/ko-KR/development/build-system-overview.md +++ b/docs-translations/ko-KR/development/build-system-overview.md @@ -9,17 +9,17 @@ Electron을 빌드 할 때 `gyp` 파일들은 다음과 같은 규칙을 따릅 * `atom.gyp`는 Electron의 빌드 과정 자체를 정의합니다. * `common.gypi`는 Node가 Chromium과 함께 빌드될 수 있도록 조정한 빌드 설정입니다. -* `vendor/brightray/brightray.gyp`는 `brightray`의 빌드 과정을 정의하고 - Chromium 링킹에 대한 기본적인 설정을 포함합니다. +* `vendor/brightray/brightray.gyp`는 `brightray`의 빌드 과정을 정의하고 Chromium + 링킹에 대한 기본적인 설정을 포함합니다. * `vendor/brightray/brightray.gypi`는 빌드에 대한 일반적인 설정이 포함되어 있습니다. ## 구성요소 빌드 Chromium은 꽤나 큰 프로젝트입니다. 이러한 이유로 인해 최종 링킹 작업은 상당한 시간이 소요될 수 있습니다. 보통 이런 문제는 개발을 어렵게 만듭니다. 우리는 이 문제를 해결하기 -위해 Chromium의 "component build" 방식을 도입했습니다. 이는 각각의 컴포넌트를 -각각 따로 분리하여 공유 라이브러리로 빌드 합니다. 하지만 이 빌드 방식을 사용하면 -링킹 작업은 매우 빨라지지만 실행 파일 크기가 커지고 성능이 저하됩니다. +위해 Chromium의 "component build" 방식을 도입했습니다. 이는 각각의 컴포넌트를 각각 +따로 분리하여 공유 라이브러리로 빌드 합니다. 하지만 이 빌드 방식을 사용하면 링킹 작업은 +매우 빨라지지만 실행 파일 크기가 커지고 성능이 저하됩니다. Electron도 이러한 방식에 상당히 비슷한 접근을 했습니다: `Debug` 빌드 시 바이너리는 공유 라이브러리 버전의 Chromium 컴포넌트를 사용함으로써 @@ -33,15 +33,15 @@ Prebuilt된 모든 Chromium 바이너리들은 부트스트랩 스크립트가 기본적으로 공유 라이브러리와 정적 라이브러리 모두 다운로드되며 최종 전체 파일 크기는 플랫폼에 따라 800MB에서 2GB까지 차지합니다. -기본적으로 (`libchromiumcontent`)는 Amazon Web Service를 통해 다운로드 됩니다. -만약 `LIBCHROMIUMCONTENT_MIRROR` 환경 변수가 설정되어 있으면 부트스트랩은 해당 링크를 +기본적으로 (`libchromiumcontent`)는 Amazon Web Service를 통해 다운로드 됩니다. 만약 +`LIBCHROMIUMCONTENT_MIRROR` 환경 변수가 설정되어 있으면 부트스트랩은 해당 링크를 사용하여 바이너리를 다운로드 합니다. [libchromiumcontent-qiniu-mirror](https://github.com/hokein/libchromiumcontent-qiniu-mirror)는 libchromiumcontent의 미러입니다. 만약 AWS에 접근할 수 없다면 `export LIBCHROMIUMCONTENT_MIRROR=http://7xk3d2.dl1.z0.glb.clouddn.com/` 미러를 통해 다운로드 할 수 있습니다. -만약 빠르게 Electron의 개발 또는 테스트만 하고 싶다면 `--dev` 플래그를 추가하여 -공유 라이브러리만 다운로드할 수 있습니다: +만약 빠르게 Electron의 개발 또는 테스트만 하고 싶다면 `--dev` 플래그를 추가하여 공유 +라이브러리만 다운로드할 수 있습니다: ```bash $ ./script/bootstrap.py --dev @@ -55,15 +55,15 @@ Electron은 `Release`와 `Debug` 빌드가 서로 다른 라이브러리 링크 지원하지 않습니다. 이 문제를 해결하기 위해 Electron은 링크 설정을 제어하는 `gyp` 변수 -`libchromiumcontent_component`를 사용하고 `gyp`를 실행할 때 -단 하나의 타겟만을 생성합니다. +`libchromiumcontent_component`를 사용하고 `gyp`를 실행할 때 단 하나의 타겟만을 +생성합니다. ## 타겟 이름 많은 프로젝트에서 타겟 이름을 `Release` 와 `Debug`를 사용하는데 반해 Electron은 -`R`과 `D`를 대신 사용합니다. 이유는 가끔 알 수 없는 이유(randomly)로 -`Release` 와 `Debug` 중 하나만 빌드 설정에 정의되어 있을때 `gyp`가 크래시를 일으키는데 -이유는 앞서 말한 바와 같이 Electron은 한번에 한개의 타겟만을 생성할 수 있기 때문입니다. +`R`과 `D`를 대신 사용합니다. 이유는 가끔 알 수 없는 이유(randomly)로 `Release` 와 +`Debug` 중 하나만 빌드 설정에 정의되어 있을때 `gyp`가 크래시를 일으키는데 이유는 앞서 +말한 바와 같이 Electron은 한번에 한개의 타겟만을 생성할 수 있기 때문입니다. 이 문제는 개발자에게만 영향을 미칩니다. 만약 단순히 Electron을 rebranding 하기 위해 빌드 하는 것이라면 이 문제에 신경 쓸 필요가 없습니다. diff --git a/docs-translations/ko-KR/development/coding-style.md b/docs-translations/ko-KR/development/coding-style.md index 0dc16ba0ad68..21ee03fd0a1d 100644 --- a/docs-translations/ko-KR/development/coding-style.md +++ b/docs-translations/ko-KR/development/coding-style.md @@ -4,29 +4,35 @@ ## C++과 Python -C++과 Python 스크립트는 Chromium의 [코딩 스타일](http://www.chromium.org/developers/coding-style)을 따릅니다. -파이선 스크립트 `script/cpplint.py`를 사용하여 모든 파일이 해당 코딩스타일에 맞게 코딩 되었는지 확인할 수 있습니다. +C++과 Python 스크립트는 Chromium의 +[코딩 스타일](http://www.chromium.org/developers/coding-style)을 따릅니다. 파이선 +스크립트 `script/cpplint.py`를 사용하여 모든 파일이 해당 코딩스타일에 맞게 코딩 했는지 +확인할 수 있습니다. Python 버전은 2.7을 사용합니다. -C++ 코드는 많은 Chromium의 추상화와 타입을 사용합니다. 따라서 Chromium 코드에 대해 잘 알고 있어야 합니다. -이와 관련하여 시작하기 좋은 장소로 Chromium의 [Important Abstractions and Data Structures] -(https://www.chromium.org/developers/coding-style/important-abstractions-and-data-structures) 문서가 있습니다. -이 문서에선 몇가지 특별한 타입과 스코프 타입(스코프 밖으로 나가면 자동으로 메모리에서 할당을 해제합니다. 스마트 포인터로 보시면 됩니다) -그리고 로깅 메커니즘 등을 언급하고 있습니다. +C++ 코드는 많은 Chromium의 추상화와 타입을 사용합니다. 따라서 Chromium 코드에 대해 잘 +알고 있어야 합니다. 이와 관련하여 시작하기 좋은 장소로 Chromium의 +[Important Abstractions and Data Structures](https://www.chromium.org/developers/coding-style/important-abstractions-and-data-structures) +문서가 있습니다. 이 문서에선 몇가지 특별한 타입과 스코프 타입(스코프 밖으로 나가면 +자동으로 메모리에서 할당을 해제합니다. 스마트 포인터와 같습니다) 그리고 로깅 메커니즘 +등을 언급하고 있습니다. ## CoffeeScript -CoffeeScript의 경우 GitHub의 [스타일 가이드](https://github.com/styleguide/javascript)를 기본으로 따릅니다. -그리고 다음 규칙을 따릅니다: +CoffeeScript의 경우 GitHub의 +[스타일 가이드](https://github.com/styleguide/javascript)를 기본으로 따릅니다. +그리고 추가로 다음 규칙을 따릅니다: * Google의 코딩 스타일에도 맞추기 위해 파일의 끝에는 **절대** 개행을 삽입해선 안됩니다. -* 파일 이름의 공백은 `_`대신에 `-`을 사용하여야 합니다. 예를 들어 `file_name.coffee`를 -`file-name.coffee`로 고쳐야합니다. 왜냐하면 [github/atom](https://github.com/github/atom) 에서 사용되는 모듈의 이름은 -보통 `module-name`형식이기 때문입니다. 이 규칙은 '.coffee' 파일에만 적용됩니다. +* 파일 이름의 공백은 `_`대신에 `-`을 사용하여야 합니다. 예를 들어 +`file_name.coffee`를 `file-name.coffee`로 고쳐야합니다. 왜냐하면 +[github/atom](https://github.com/github/atom)에서 사용되는 모듈의 이름은 보통 +`module-name` 형식이기 때문입니다. 이 규칙은 '.coffee' 파일에만 적용됩니다. ## API 이름 -새로운 API를 만들 땐 getter, setter스타일 대신 jQuery의 one-function스타일을 사용해야 합니다. 예를 들어 -`.getText()`와 `.setText(text)`대신에 `.text([text])`형식으로 설계하면 됩니다. -포럼에 이 문제에 대한 [논의](https://github.com/atom/electron/issues/46)가 있습니다. +새로운 API를 만들 땐 getter, setter스타일 대신 jQuery의 one-function 스타일을 +사용해야 합니다. 예를 들어 `.getText()`와 `.setText(text)`대신에 `.text([text])` +형식으로 설계하면 됩니다. 포럼에 이 문제에 대한 [논의](https://github.com/atom/electron/issues/46)가 +진행되고 있습니다. diff --git a/docs-translations/ko-KR/development/setting-up-symbol-server.md b/docs-translations/ko-KR/development/setting-up-symbol-server.md index ed43e0fae295..bfd347a4a1b7 100644 --- a/docs-translations/ko-KR/development/setting-up-symbol-server.md +++ b/docs-translations/ko-KR/development/setting-up-symbol-server.md @@ -1,29 +1,36 @@ # 디버거에서 디버그 심볼 서버 설정 -디버그 심볼은 디버깅 세션을 더 좋게 개선해 줍니다. 디버그 심볼은 실행 파일과 동적 링크 라이브러리에서 메서드에 대한 정보를 담고 있으며 명료한 함수 호출 스텍 정보를 제공합니다. -심볼 서버는 유저가 크기가 큰 디버깅용 파일을 필수적으로 다운로드 받지 않고도 디버거가 알맞은 심볼, 바이너리 그리고 소스를 자동적으로 로드할 수 있도록 해줍니다. -서버 사용법은 [Microsoft의 심볼 서버](http://support.microsoft.com/kb/311503)와 비슷합니다. 이 문서를 참조하세요. +디버그 심볼은 디버깅 세션을 더 좋게 개선해 줍니다. 디버그 심볼은 실행 파일과 동적 링크 +라이브러리에서 메서드에 대한 정보를 담고 있으며 명료한 함수 호출 스텍 정보를 제공합니다. +심볼 서버는 유저가 크기가 큰 디버깅용 파일을 필수적으로 다운로드 받지 않고도 디버거가 +알맞은 심볼, 바이너리 그리고 소스를 자동적으로 로드할 수 있도록 해줍니다. 서버 사용법은 +[Microsoft의 심볼 서버](http://support.microsoft.com/kb/311503)와 비슷합니다. +사용법을 알아보려면 이 문서를 참조하세요. -참고로 릴리즈된 Electron 빌드는 자체적으로 많은 최적화가 되어 있는 관계로 경우에 따라 디버깅이 쉽지 않을 수 있습니다. -Inlining, tail call 등의 컴파일러 최적화에 의해 디버거가 모든 변수의 컨텐츠를 보여줄 수 없는 경우도 있고 실행 경로가 이상하게 보여질 수 있습니다. -유일한 해결 방법은 최적화되지 않은 로컬 빌드를 하는 것입니다. +참고로 릴리즈된 Electron 빌드는 자체적으로 많은 최적화가 되어 있는 관계로 경우에 따라 +디버깅이 쉽지 않을 수 있습니다. Inlining, tail call 등 컴파일러 최적화에 의해 디버거가 +모든 변수의 컨텐츠를 보여줄 수 없는 경우도 있고 실행 경로가 이상하게 보여지는 경우도 +있습니다. 유일한 해결 방법은 최적화되지 않은 로컬 빌드를 하는 것입니다. -공식적인 Electron의 심볼 서버의 URL은 http://54.249.141.255:8086/atom-shell/symbols 입니다. -일단 이 URL에 직접적으로 접근할 수는 없습니다: 디버깅 툴에 심볼의 경로를 추가해야합니다. -아래의 예제를 참고하면 로컬 캐시 디렉터리는 서버로부터 중복되지 않게 PDB를 가져오는데 사용됩니다. +공식적인 Electron의 심볼 서버의 URL은 +http://54.249.141.255:8086/atom-shell/symbols 입니다. 일단 이 URL에 직접적으로 +접근할 수는 없습니다: 디버깅 툴에 심볼의 경로를 추가해야합니다. 아래의 예제를 참고하면 +로컬 캐시 디렉터리는 서버로부터 중복되지 않게 PDB를 가져오는데 사용됩니다. `c:\code\symbols` 캐시 디렉터리를 사용중인 OS에 맞춰 적당한 경로로 변경하세요. ## Windbg에서 심볼 서버 사용하기 -Windbg 심볼 경로는 구분자와 *(별) 문자로 설정되어 있습니다. -Electron 심볼 서버만을 사용하려면 심볼 경로의 엔트리를 추가해야 합니다 (__참고:__ `c:\code\symbols` 디렉터리 경로를 PC가 원하는 경로로 수정할 수 있습니다): +Windbg 심볼 경로는 구분자와 `*` 문자로 설정되어 있습니다. Electron 심볼 서버만 +사용하려면 심볼 경로의 엔트리를 추가해야 합니다. (__참고:__ `c:\code\symbols` +디렉터리 경로를 PC가 원하는 경로로 수정할 수 있습니다): ``` SRV*c:\code\symbols\*http://54.249.141.255:8086/atom-shell/symbols ``` -Windbg 메뉴 또는 `.sympath` 커맨드를 이용하여 환경에 `_NT_SYMBOL_PATH` 문자열을 설정합니다. -만약 Microsoft의 심볼서버로 부터 심볼을 받아오려면 다음과 같이 리스팅을 먼저 해야합니다: +Windbg 메뉴 또는 `.sympath` 커맨드를 이용하여 환경에 `_NT_SYMBOL_PATH` 문자열을 +설정합니다. 만약 Microsoft의 심볼서버로 부터 심볼을 받아오려면 다음과 같이 리스팅을 +먼저 해야합니다: ``` SRV*c:\code\symbols\*http://msdl.microsoft.com/download/symbols;SRV*c:\code\symbols\*http://54.249.141.255:8086/atom-shell/symbols @@ -36,7 +43,8 @@ SRV*c:\code\symbols\*http://msdl.microsoft.com/download/symbols;SRV*c:\code\symb ## 문제 해결: Symbols will not load -Windbg에서 다음의 커맨드를 입력하여 왜 심볼이 로드되지 않았는지에 대한 오류 내역을 출력합니다: +Windbg에서 다음의 커맨드를 입력하여 왜 심볼이 로드되지 않았는지에 대한 오류 내역을 +출력합니다: ``` > !sym noisy diff --git a/docs-translations/ko-KR/development/source-code-directory-structure.md b/docs-translations/ko-KR/development/source-code-directory-structure.md index f31d0847db75..e0e172d18b4f 100644 --- a/docs-translations/ko-KR/development/source-code-directory-structure.md +++ b/docs-translations/ko-KR/development/source-code-directory-structure.md @@ -1,8 +1,10 @@ # 소스 코드 디렉터리 구조 -Electron의 소스 코드는 몇 개의 파트로 분리되어 있습니다. 그리고 Chromium의 분리 규칙(separation conventions)을 주로 따르고 있습니다. +Electron의 소스 코드는 몇 개의 파트로 분리되어 있습니다. 그리고 Chromium의 분리 +규칙(separation conventions)을 주로 따르고 있습니다. -이미 [Chromium의 멀티 프로세스 아키텍쳐](http://dev.chromium.org/developers/design-documents/multi-process-architecture)에 익숙해져 있다면 소스 코드를 이해하기 쉬울 것입니다. +이미 [Chromium의 멀티 프로세스 아키텍쳐](http://dev.chromium.org/developers/design-documents/multi-process-architecture)에 +익숙해져 있다면 소스 코드를 이해하기 쉬울 것입니다. ## 소스 코드 구조 @@ -10,8 +12,8 @@ Electron의 소스 코드는 몇 개의 파트로 분리되어 있습니다. 그 Electron ├──atom - Electron의 소스코드. | ├── app - 시스템 엔트리 코드. -| ├── browser - 주 윈도우를 포함한 프론트엔드, UI, 그리고 메인 프로세스에 관련된 것들. -| | | 랜더러와 웹 페이지 관리 관련 코드. +| ├── browser - 주 윈도우를 포함한 프론트엔드, UI, 그리고 메인 프로세스에 관련된 것과 +| | 랜더러와 웹 페이지 관리 관련 코드. | | ├── lib - 메인 프로세스 초기화 코드의 자바스크립트 파트. | | ├── ui - 크로스 플랫폼에 대응하는 UI 구현. | | | ├── cocoa - 코코아 특정 소스 코드. @@ -27,8 +29,8 @@ Electron | | ├── lib - 랜더러 프로세스 초기화 코드의 자바스크립트 파트. | | └── api - 랜더러 프로세스 API들의 구현. | | └── lib - API 구현의 자바스크립트 파트. -| └── common - 메인 프로세스와 랜더러 프로세스에서 공유하는 코드. -| | 유틸리티 함수와 node 메시지 루프를 Chromium의 메시지 루프에 통합시킨 코드도 포함. +| └── common - 메인 프로세스와 랜더러 프로세스에서 공유하는 코드. 유틸리티 함수와 +| node 메시지 루프를 Chromium의 메시지 루프에 통합시킨 코드도 포함. | ├── lib - 공통 자바스크립트 초기화 코드. | └── api - 공통 API들의 구현, Electron의 빌트인 모듈 기초 코드들. | └── lib - API 구현의 자바스크립트 파트. @@ -36,16 +38,21 @@ Electron ├── docs - 참조 문서. ├── spec - 자동화된 테스트. ├── atom.gyp - Electron의 빌드 규칙. -└── common.gypi - 컴파일러 설정 및 `node` 와 `breakpad` 등의 구성요소를 위한 빌드 규칙. +└── common.gypi - 컴파일러 설정 및 `node` 와 `breakpad` 등의 구성요소를 위한 빌드 + 규칙. ``` ## 그외 디렉터리 구조 * **script** - 개발목적으로 사용되는 빌드, 패키징, 테스트, 기타등을 실행하는 스크립트. -* **tools** - gyp 파일에서 사용되는 헬퍼 스크립트 `script`와는 다르게 유저로부터 직접 실행되지 않는 스크립트들을 이곳에 넣습니다. -* **vendor** - 소스코드의 서드파티 종속성 코드 소스 코드 디렉터리가 겹쳐 혼란을 일으킬 수 있기 때문에 - 우리는 `third_party`와 같은 Chromium 소스 코드 디렉터리에서 사용된 폴더 이름을 사용하지 않았습니다. +* **tools** - gyp 파일에서 사용되는 헬퍼 스크립트 `script`와는 다르게 유저로부터 직접 + 실행되지 않는 스크립트들을 이곳에 넣습니다. +* **vendor** - 소스코드의 서드파티 종속성 코드 소스 코드 디렉터리가 겹쳐 혼란을 일으킬 + 수 있기 때문에 `third_party`와 같은 Chromium 소스 코드 디렉터리에서 사용된 폴더 + 이름은 사용하지 않았습니다. * **node_modules** - 빌드에 사용되는 node 서드파티 모듈. * **out** - `ninja`의 임시 출력 디렉터리. -* **dist** - 배포용 바이너리를 빌드할 때 사용하는 `script/create-dist.py` 스크립트로부터 만들어지는 임시 디렉터리. -* **external_binaries** - `gyp` 빌드를 지원하지 않아 따로 다운로드된 서드파티 프레임워크 바이너리들. +* **dist** - 배포용 바이너리를 빌드할 때 사용하는 `script/create-dist.py` + 스크립트로부터 만들어지는 임시 디렉터리. +* **external_binaries** - `gyp` 빌드를 지원하지 않아 따로 다운로드된 서드파티 + 프레임워크 바이너리들. diff --git a/docs-translations/ko-KR/styleguide.md b/docs-translations/ko-KR/styleguide.md index 7318c7e3b403..dd02629c1680 100644 --- a/docs-translations/ko-KR/styleguide.md +++ b/docs-translations/ko-KR/styleguide.md @@ -11,15 +11,15 @@ Electron 문서를 작성하는 규칙은 다음과 같습니다. - `h1` 제목은 페이지당 한 개만 사용할 수 있습니다. - 코드 블럭에서 터미널 언어 선택시 `cmd` 대신 `bash`를 사용합니다. (syntax highlighter를 사용하기 위해서) -- 문서의 `h1` 제목은 반드시 현재 객체 이름과 같게 해야 합니다. - (예시: `browser-window` → `BrowserWindow`) +- 문서의 `h1` 제목은 반드시 현재 객체 이름과 같게 해야 합니다. (`browser-window` → + `BrowserWindow`) - 하이픈(-)으로 구분되었건 다르게 구분되었건 예시와 같이 작성합니다. -- 헤더 밑에 헤더를 바로 사용하지 않습니다. 한 줄이라도 좋으니 헤더와 헤더 사이에 - 설명을 추가합니다. +- 헤더 밑에 헤더를 바로 사용하지 않습니다. 한 줄이라도 좋으니 헤더와 헤더 사이에 설명을 + 추가합니다. - 메서드 헤더는 `code backtick` 으로 표시합니다. - 이벤트 헤더는 한 '따옴표'로 표시합니다. -- 리스트를 2 단계 이상 중첩하지 않습니다. (안타깝게도 markdown 랜더러가 이를 - 지원하지 않습니다) +- 리스트를 2 단계 이상 중첩하지 않습니다. (안타깝게도 markdown 랜더러가 이를 지원하지 + 않습니다) - 섹션에 대한 제목을 추가합니다. Events, Class 메서드 그리고 인스턴스 메서드 등 - 어떤 '것'의 사용 결과를 설명할 때 '될 것입니다' 형식을 사용하여 설명합니다. - 이벤트와 메서드를 표기할 땐 `h3` 헤더를 사용합니다. @@ -37,8 +37,8 @@ Electron 문서를 작성하는 규칙은 다음과 같습니다. 아직 번역되지 않은 언어를 추가하려면 (일부분 포함): - 언어의 약어(예: en-US, ja-JP, ko-KR)로 서브 디렉터리를 만듭니다. -- 서브 디렉터리에 `docs` 디렉터리를 복사합니다. 파일 이름과 디렉터리 구조는 - 모두 유지합니다. +- 서브 디렉터리에 `docs` 디렉터리를 복사합니다. 파일 이름과 디렉터리 구조는 모두 + 유지합니다. - 문서를 번역합니다. - 언어 디렉터리 내의 `README.md`에 번역한 문서의 링크를 추가합니다. - 메인(upstream) Electron의 [README](https://github.com/atom/electron#documentation-translations)에 @@ -65,14 +65,13 @@ Electron 문서 구조를 이해하는 데 참고할 수 있는 유용한 도움 메서드 이름은 인수가 무엇을 받는지에 따라 결정됩니다. 선택적 인수는 브라켓([, ])으로 묶어 이 인수가 다른 인수뒤에서 선택적으로 사용될 수 있다는 것을 표시합니다. -메서드 이름 하단에선 각 인수에 대해 자세한 설명을 합니다. -인수의 타입은 일반적인 타입 중 하나를 받거나: +메서드 이름 하단에선 각 인수에 대해 자세한 설명을 합니다. 인수의 타입은: [`String`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String), [`Number`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number), [`Object`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object), [`Array`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array) -와 같은 일반적으로 쓰이는 타입 중 하나를 받거나 Electron의 -[`webContent`](api/web-content.md)같은 커스텀 타입을 받습니다. +와 같은 일반적으로 쓰이는 타입 중 하나를 받거나 Electron의 [`webContent`](api/web-content.md) +같은 커스텀 타입을 받습니다. ### Events diff --git a/docs-translations/ko-KR/tutorial/application-distribution.md b/docs-translations/ko-KR/tutorial/application-distribution.md index 69269500733a..73839f248b5b 100644 --- a/docs-translations/ko-KR/tutorial/application-distribution.md +++ b/docs-translations/ko-KR/tutorial/application-distribution.md @@ -2,10 +2,9 @@ Electron 어플리케이션을 배포하는 방법은 간단합니다. -먼저 폴더 이름을 `app`로 지정한 후 Electron 리소스 디렉터리에 폴더를 통째로 집어넣기만 하면 됩니다. -리소스 디렉터리는 OS X: `Electron.app/Contents/Resources/` Windows와 Linux: `resources/` 입니다. - -예제: +먼저 폴더 이름을 `app`로 지정한 후 Electron 리소스 디렉터리에 폴더를 통째로 집어넣기만 +하면 됩니다. 리소스 디렉터리는 OS X의 경우: `Electron.app/Contents/Resources/` +Windows와 Linux의 경우: `resources/` 입니다. OS X의 경우: @@ -16,7 +15,7 @@ electron/Electron.app/Contents/Resources/app/ └── index.html ``` -Windows 와 Linux의 경우: +Windows와 Linux의 경우: ```text electron/resources/app @@ -25,16 +24,18 @@ electron/resources/app └── index.html ``` -그리고 `Electron.app`을 실행하면(Linux에선 `electron` Windows에선 `electron.exe`입니다) Electron 앱이 실행시킵니다. -최종 사용자에겐 이 `electron` 폴더(Electron.app)를 배포하면 됩니다. +그리고 `Electron.app`을 실행하면(Linux에선 `electron` Windows에선 `electron.exe` +입니다) Electron 앱이 실행됩니다. 최종 사용자에겐 이 `electron` 폴더(Electron.app)를 +배포하면 됩니다. ## asar로 앱 패키징 하기 -소스파일 전체를 복사해서 배포하는 것과는 별개로 [asar](https://github.com/atom/asar) 아카이브를 통해 -어플리케이션의 소스코드가 사용자에게 노출되는 것을 방지할 수 있습니다. +소스파일 전체를 복사해서 배포하는 것과는 별개로 [asar](https://github.com/atom/asar) +아카이브를 통해 어플리케이션의 소스코드가 사용자에게 노출되는 것을 방지할 수 있습니다. -`asar` 아카이브를 사용할 땐 단순히 `app` 폴더 대신에 어플리케이션을 패키징한 `app.asar` 파일로 대체하면됩니다. -Electron은 자동으로 `app`폴더 대신 asar 아카이브를 기반으로 어플리케이션을 실행합니다. +`asar` 아카이브를 사용할 땐 단순히 `app` 폴더 대신에 어플리케이션을 패키징한 +`app.asar` 파일로 대체하면됩니다. Electron은 자동으로 `app`폴더 대신 asar 아카이브를 +기반으로 어플리케이션을 실행합니다. OS X의 경우: @@ -59,22 +60,25 @@ electron/resources/ ### Windows `electron.exe`을 원하는 이름으로 변경할 수 있습니다. -그리고 [rcedit](https://github.com/atom/rcedit) 또는 [ResEdit](http://www.resedit.net)를 사용하여 아이콘을 변경할 수 있습니다. +그리고 [rcedit](https://github.com/atom/rcedit) 또는 +[ResEdit](http://www.resedit.net)를 사용하여 아이콘을 변경할 수 있습니다. ### OS X -`Electron.app`을 원하는 이름으로 변경할 수 있습니다. 그리고 다음 표시된 어플리케이션 내부 파일에서 -`CFBundleDisplayName`, `CFBundleIdentifier` and `CFBundleName` 필드를 원하는 이름으로 변경해야합니다: +`Electron.app`을 원하는 이름으로 변경할 수 있습니다. 그리고 다음 표시된 어플리케이션 +내부 파일에서 `CFBundleDisplayName`, `CFBundleIdentifier` 그리고 `CFBundleName` +필드를 원하는 이름으로 변경해야 합니다: * `Electron.app/Contents/Info.plist` * `Electron.app/Contents/Frameworks/Electron Helper.app/Contents/Info.plist` -또한 helper 앱이 프로세스 모니터에 `Electron Helper`로 나오지 않도록 이름을 변경할 수 있습니다. -하지만 반드시 내부 및 모든 helper 앱의 이름을 변경해야 합니다. +또한 helper 앱이 프로세스 모니터에 `Electron Helper`로 나오지 않도록 이름을 +변경할 수 있습니다. 하지만 반드시 내부 및 모든 helper 앱의 이름을 변경해야 합니다. -어플리케이션 아이콘은 `Electron.app/Contents/Resources/atom.icns`을 원하는 아이콘으로 변경하면 됩니다. +어플리케이션 아이콘은 `Electron.app/Contents/Resources/atom.icns`을 원하는 +아이콘으로 변경하면 됩니다. -원하는 이름으로 바꾼 어플리케이션 예제: +어플리케이션 이름을 원하는 이름으로 변경한 예시: ``` MyApp.app/Contents @@ -98,13 +102,14 @@ MyApp.app/Contents ### Linux -실행파일 `electron`의 이름을 원하는 대로 바꿀 수 있습니다. -리눅스 어플리케이션의 아이콘은 [.desktop](https://developer.gnome.org/integration-guide/stable/desktop-files.html.en) 파일을 사용하여 지정할 수 있습니다. +실행파일 `electron`의 이름을 원하는 대로 바꿀 수 있습니다. 리눅스 어플리케이션의 +아이콘은 [.desktop](https://developer.gnome.org/integration-guide/stable/desktop-files.html.en) +파일을 사용하여 지정할 수 있습니다. -### 역주-자동화 +### 역주-자동화 -어플리케이션 배포시 Electron의 리소스를 일일이 수정하는 것은 매우 귀찮고 복잡합니다. -하지만 이 작업을 자동화 시킬 수 있는 몇가지 방법이 있습니다: +어플리케이션 배포시 Electron의 리소스를 일일이 수정하는 것은 매우 반복적이고 복잡합니다. +하지만 이 작업을 자동화 시킬 수 있는 몇가지 방법이 있습니다: * [electron-builder](https://github.com/loopline-systems/electron-builder) * [electron-packager](https://github.com/maxogden/electron-packager) @@ -135,7 +140,9 @@ $ script/build.py -c Release -t myapp ### grunt-build-atom-shell -Electron의 소스코드를 수정하고 다시 빌드하는 작업은 상당히 복잡합니다. -일일이 소스코드를 수정하는 대신 [grunt-build-atom-shell](https://github.com/paulcbetts/grunt-build-atom-shell)을 사용하여 빌드를 자동화 시킬 수 있습니다. +Electron의 소스코드를 수정하고 다시 빌드하는 작업은 상당히 복잡합니다. 일일이 +소스코드를 수정하는 대신 [grunt-build-atom-shell](https://github.com/paulcbetts/grunt-build-atom-shell)을 +사용하여 빌드를 자동화 시킬 수 있습니다. -이 툴을 사용하면 자동으로 `.gyp`파일을 수정하고 다시 빌드합니다. 그리고 어플리케이션의 네이티브 Node 모듈 또한 새로운 실행파일 이름으로 매치 시킵니다. +이 툴을 사용하면 자동으로 `.gyp`파일을 수정하고 다시 빌드합니다. 그리고 어플리케이션의 +네이티브 Node 모듈 또한 새로운 실행파일 이름으로 일치시킵니다. diff --git a/docs-translations/ko-KR/tutorial/application-packaging.md b/docs-translations/ko-KR/tutorial/application-packaging.md index 9a5e3dfb20e2..a04dfebac9a3 100644 --- a/docs-translations/ko-KR/tutorial/application-packaging.md +++ b/docs-translations/ko-KR/tutorial/application-packaging.md @@ -1,7 +1,8 @@ # 어플리케이션 패키징 -Windows에서 일어나는 긴 경로 이름에 대한 [issues](https://github.com/joyent/node/issues/6960)를 완화하고 `require` 속도를 약간 빠르게 하며 -어플리케이션의 리소스와 소스코드를 좋지 않은 사용자로부터 보호하기 위해 어플리케이션을 [asar][asar] 아카이브로 패키징 할 수 있습니다. +Windows에서 일어나는 긴 경로 이름에 대한 [issues](https://github.com/joyent/node/issues/6960)를 +완화하고 `require` 속도를 약간 빠르게 하며 어플리케이션의 리소스와 소스코드를 좋지 않은 +사용자로부터 보호하기 위해 어플리케이션을 [asar][asar] 아카이브로 패키징 할 수 있습니다. ## `asar` 아카이브 생성 @@ -24,13 +25,15 @@ $ asar pack your-app app.asar ## `asar` 아카이브 사용하기 -Electron은 Node.js로 부터 제공된 Node API와 Chromium으로부터 제공된 Web API 두 가지 API를 가지고 있습니다. -따라서 `asar` 아카이브는 두 API 모두 사용할 수 있도록 지원합니다. +Electron은 Node.js로 부터 제공된 Node API와 Chromium으로부터 제공된 Web API 두 가지 +API를 가지고 있습니다. 따라서 `asar` 아카이브는 두 API 모두 사용할 수 있도록 +지원합니다. ### Node API -Electron에선 `fs.readFile`과 `require` 같은 Node API들을 지원하기 위해 `asar` 아카이브가 가상의 디렉터리 구조를 가지도록 -패치했습니다. 그래서 아카이브 내부 리소스들을 정상적인 파일 시스템처럼 접근할 수 있습니다. +Electron에선 `fs.readFile`과 `require` 같은 Node API들을 지원하기 위해 `asar` +아카이브가 가상의 디렉터리 구조를 가지도록 패치했습니다. 그래서 아카이브 내부 +리소스들을 정상적인 파일 시스템처럼 접근할 수 있습니다. 예를 들어 `/path/to`라는 경로에 `example.asar`라는 아카이브가 있다고 가정하면: @@ -90,9 +93,10 @@ $.get('file:///path/to/example.asar/file.txt', function(data) { ### `asar` 아카이브를 일반 파일로 취급하기 -`asar` 아카이브의 체크섬(checksum)을 검사하는 작업등을 하기 위해선 `asar` 아카이브를 파일 그대로 읽어야 합니다. -이러한 작업을 하기 위해 `original-fs` 빌트인 모듈을 `fs` 모듈 대신에 사용할 수 있습니다. -이 모듈은 `asar` 지원이 빠져있습니다. 즉 파일 그대로를 읽어들입니다: +`asar` 아카이브의 체크섬(checksum)을 검사하는 작업등을 하기 위해선 `asar` 아카이브를 +파일 그대로 읽어야 합니다. 이러한 작업을 하기 위해 `original-fs` 빌트인 모듈을 `fs` +모듈 대신에 사용할 수 있습니다. 이 모듈은 `asar` 지원이 빠져있습니다. 즉 파일 그대로를 +읽어들입니다: ```javascript var originalFs = require('original-fs'); @@ -101,22 +105,26 @@ originalFs.readFileSync('/path/to/example.asar'); ## Node API의 한계 -`asar` 아카이브를 Node API가 최대한 디렉터리 구조로 작동하도록 노력해왔지만 여전히 저수준(low-level nature) Node API 때문에 한계가 있습니다. +`asar` 아카이브를 Node API가 최대한 디렉터리 구조로 작동하도록 노력해왔지만 여전히 +저수준(low-level nature) Node API 때문에 한계가 있습니다. ### 아카이브는 읽기 전용입니다 -아카이브는 수정할 수 없으며 기본적으로는 Node API로 파일을 수정할 수 있지만 `asar` 아카이브에선 작동하지 않습니다. +아카이브는 수정할 수 없으며 기본적으로는 Node API로 파일을 수정할 수 있지만 `asar` +아카이브에선 작동하지 않습니다. ### 아카이브 안의 디렉터리를 작업 경로로 설정하면 안됩니다 -`asar` 아카이브는 디렉터리처럼 사용할 수 있도록 구현되었지만 그것은 실제 파일시스템의 디렉터리가 아닌 가상의 디렉터리입니다. -그런 이유로 몇몇 API에서 지원하는 `cwd` 옵션을 `asar` 아카이브 안의 디렉터리 경로로 지정하면 나중에 문제가 발생할 수 있습니다. +`asar` 아카이브는 디렉터리처럼 사용할 수 있도록 구현되었지만 그것은 실제 파일시스템의 +디렉터리가 아닌 가상의 디렉터리입니다. 그런 이유로 몇몇 API에서 지원하는 `cwd` 옵션을 +`asar` 아카이브 안의 디렉터리 경로로 지정하면 나중에 문제가 발생할 수 있습니다. ### 특정 API로 인한 예외적인 아카이브 압축 해제 -많은 `fs` API가 `asar` 아카이브의 압축을 해제하지 않고 바로 아카이브를 읽거나 정보를 가져올 수 있으나 -몇몇 API는 시스템의 실제 파일의 경로를 기반으로 작동하므로 Electron은 API가 원할하게 작동할 수 있도록 -임시 경로에 해당되는 파일의 압축을 해제합니다. 이 작업은 약간의 오버헤드를 불러 일으킬 수 있습니다. +많은 `fs` API가 `asar` 아카이브의 압축을 해제하지 않고 바로 아카이브를 읽거나 정보를 +가져올 수 있으나 몇몇 API는 시스템의 실제 파일의 경로를 기반으로 작동하므로 Electron은 +API가 원할하게 작동할 수 있도록 임시 경로에 해당되는 파일의 압축을 해제합니다. 이 작업은 +약간의 오버헤드를 불러 일으킬 수 있습니다. 위 예외에 해당하는 API 메서드는 다음과 같습니다: @@ -127,24 +135,27 @@ originalFs.readFileSync('/path/to/example.asar'); ### `fs.stat`의 잘못된 스테이터스 정보 -`fs.stat` 로 부터 반환되는 `Stats` 객체와 비슷한 API들은 `asar` 아카이브를 타겟으로 할 경우 예측된 디렉터리 파일 정보를 가집니다. -왜냐하면 아카이브의 디렉터리 경로는 실제 파일시스템에 존재하지 않기 때문입니다. -그러한 이유로 파일 크기와 파일 타입 등을 확인할 때 `Stats` 객체를 신뢰해선 안됩니다. +`fs.stat` 로 부터 반환되는 `Stats` 객체와 비슷한 API들은 `asar` 아카이브를 타겟으로 +할 경우 예측된 디렉터리 파일 정보를 가집니다. 왜냐하면 아카이브의 디렉터리 경로는 실제 +파일 시스템에 존재하지 않기 때문입니다. 그러한 이유로 파일 크기와 +파일 타입 등을 확인할 때 `Stats` 객체를 신뢰해선 안됩니다. ## `asar` 아카이브에 미리 압축 해제된 파일 추가하기 전술한 바와 같이 몇몇 Node API는 호출 시 해당 파일을 임시폴더에 압축을 해제합니다. -이 방법은 성능문제가 발생할 수 있습니다. 그리고 설계상 백신 소프트웨어에서 잘못 진단하여 바이러스로 판단 할 수도 있습니다. +이 방법은 성능문제가 발생할 수 있습니다. 그리고 설계상 백신 소프트웨어에서 잘못 진단하여 +바이러스로 진단 할 수도 있습니다. -이 문제를 해결하려면 `--unpack` 옵션을 활용하여 파일을 압축이 풀려진 상태로 유지해야 합니다. -다음의 예제는 node 네이티브 모듈의 공유 라이브러리를 unpack 상태로 유지합니다: +이 문제를 해결하려면 `--unpack` 옵션을 통해 파일을 압축이 풀려진 상태로 유지해야 합니다. +다음의 예제는 node 네이티브 모듈의 공유 라이브러리를 압축이 풀려진 상태로 유지합니다: ```bash $ asar pack app app.asar --unpack *.node ``` -커맨드를 실행한 후 같은 디렉터리에 `app.asar` 파일 외에 `app.asar.unpacked` 폴더가 같이 생성됩니다. -이 폴더안에 unpack 옵션에서 설정한 파일들이 압축이 풀린 상태로 포함되어 있습니다. -사용자에게 어플리케이션을 배포할 때 반드시 해당 폴더도 같이 배포해야 합니다. +커맨드를 실행한 후 같은 디렉터리에 `app.asar` 파일 외에 `app.asar.unpacked` 폴더가 +같이 생성됩니다. 이 폴더안에 unpack 옵션에서 설정한 파일들이 압축이 풀려진 상태로 +포함되어 있습니다. 사용자에게 어플리케이션을 배포할 때 반드시 해당 폴더도 같이 배포해야 +합니다. [asar]: https://github.com/atom/asar diff --git a/docs-translations/ko-KR/tutorial/debugging-main-process.md b/docs-translations/ko-KR/tutorial/debugging-main-process.md index b03e2542dcd3..32a6bd00f7ae 100644 --- a/docs-translations/ko-KR/tutorial/debugging-main-process.md +++ b/docs-translations/ko-KR/tutorial/debugging-main-process.md @@ -1,7 +1,8 @@ # 메인 프로세스 디버깅하기 -브라우저 창의 개발자 도구는 웹 페이지 같은 랜더러 프로세스의 스크립트만 디버깅이 가능합니다. -대신 Electron은 메인 프로세스의 디버깅을 위해 `--debug` 과 `--debug-brk` 스위치들을 제공합니다. +브라우저 창의 개발자 도구는 웹 페이지 같은 랜더러 프로세스의 스크립트만 디버깅이 +가능합니다. 대신 Electron은 메인 프로세스의 디버깅을 위해 `--debug` 과 `--debug-brk` +스위치들을 제공합니다. ## 커맨드 라인 스위치(command line switches) @@ -9,7 +10,8 @@ ### `--debug=[port]` -이 스위치를 사용하면 Electron은 지정한 `port`에 V8 디버거 프로토콜을 리스닝합니다. 기본 `port`는 `5858` 입니다. +이 스위치를 사용하면 Electron은 지정한 `port`에 V8 디버거 프로토콜을 리스닝합니다. +기본 `port`는 `5858` 입니다. ### `--debug-brk=[port]` @@ -17,9 +19,9 @@ ## node-inspector로 디버깅 하기 -__참고:__ Electron은 node v0.11.13 버전을 사용합니다. -그리고 현재 node-inspector 유틸리티와 호환성 문제가 있습니다. -추가로 node-inspector 콘솔 내에서 메인 프로세스의 `process` 객체를 탐색할 경우 크래시가 발생할 수 있습니다. +__참고:__ Electron은 node v0.11.13 버전을 사용합니다. 그리고 현재 node-inspector +유틸리티와 호환성 문제가 있습니다. 추가로 node-inspector 콘솔 내에서 메인 프로세스의 +`process` 객체를 탐색할 경우 크래시가 발생할 수 있습니다. ### 1. [node-inspector][node-inspector] 서버 시작 @@ -43,6 +45,7 @@ $ electron --debug-brk=5858 your/app ### 3. 디버그 UI 로드 -Chrome 브라우저에서 http://127.0.0.1:8080/debug?ws=127.0.0.1:8080&port=5858 주소에 접속합니다. (기본포트 또는 지정한 포트로 접속) +Chrome 브라우저에서 http://127.0.0.1:8080/debug?ws=127.0.0.1:8080&port=5858 주소에 +접속합니다. (기본포트 또는 지정한 포트로 접속) [node-inspector]: https://github.com/node-inspector/node-inspector diff --git a/docs-translations/ko-KR/tutorial/desktop-environment-integration.md b/docs-translations/ko-KR/tutorial/desktop-environment-integration.md index 433a6d5fa5a9..1dc5f6613704 100644 --- a/docs-translations/ko-KR/tutorial/desktop-environment-integration.md +++ b/docs-translations/ko-KR/tutorial/desktop-environment-integration.md @@ -1,15 +1,18 @@ # 데스크톱 환경 통합 -어플리케이션 배포의 대상이 되는 서로 다른 운영체제 시스템의 환경에 맞춰 어플리케이션의 기능을 통합할 수 있습니다. -예를 들어 Windows에선 태스크바의 JumpList에 바로가기를 추가할 수 있고 Mac(OS X)에선 dock 메뉴에 커스텀 메뉴를 추가할 수 있습니다. +어플리케이션 배포의 대상이 되는 서로 다른 운영체제 시스템의 환경에 맞춰 어플리케이션의 +기능을 통합할 수 있습니다. 예를 들어 Windows에선 태스크바의 JumpList에 바로가기를 +추가할 수 있고 Mac(OS X)에선 dock 메뉴에 커스텀 메뉴를 추가할 수 있습니다. -이 문서는 Electron API를 이용하여 각 운영체제 시스템의 기능을 활용하는 방법을 설명합니다. +이 문서는 Electron API를 이용하여 각 운영체제 시스템의 기능을 활용하는 방법을 +설명합니다. ## 데스크톱 알림 (Windows, Linux, OS X) -Windows, Linux, OS X 운영체제 모두 기본적으로 어플리케이션에서 유저에게 알림 보낼 수 있는 방법을 제공합니다. -Electron은 HTML5 Notification API](https://notifications.spec.whatwg.org/)를 통해 개발자가 -편리하게 데스크톱 알림을 사용할 수 있는 기능을 제공합니다. 데스크톱 알림은 운영체제의 네이티브 알림 API를 사용하여 표시합니다. +Windows, Linux, OS X 운영체제 모두 기본적으로 어플리케이션에서 유저에게 알림을 보내는 +방법을 제공합니다. Electron은 [HTML5 Notification API](https://notifications.spec.whatwg.org/)를 +통해 개발자가 편리하게 데스크톱 알림을 사용할 수 있는 기능을 제공합니다. 데스크톱 알림은 +운영체제의 네이티브 알림 API를 사용하여 표시합니다. ```javascript var myNotification = new Notification('Title', { @@ -21,17 +24,21 @@ myNotification.onclick = function () { } ``` -위 코드를 통해 생성한 데스크톱 알림은 각 운영체제 모두 비슷한 사용자 경험을 제공합니다. 하지만 몇 가지 다른 점들이 있습니다. +위 코드를 통해 생성한 데스크톱 알림은 각 운영체제 모두 비슷한 사용자 경험을 제공합니다. +하지만 몇 가지 다른 점들이 있습니다. ### Windows * Windows 10에선 "아무 문제 없이 잘" 작동합니다. -* Windows 8.1과 8에선 [Application User Model ID][app-user-model-id]로 바로가기를 만들어 놔야 합니다. -이 바로가기는 반드시 시작 화면에 설치되어 있어야 합니다. 참고로 반드시 시작 화면에 고정 할 필요는 없습니다. -* Windows 7과 그 이하 버전은 데스크톱 알림을 지원하지 않습니다. 혹시 "풍선 팝업 알림" 기능을 찾는다면 [Tray API](tray-balloon)를 사용하세요. +* Windows 8.1과 8에선 [Application User Model ID][app-user-model-id]로 바로가기를 + 만들어 놔야 합니다. 이 바로가기는 반드시 시작 화면에 설치되어 있어야 합니다. 참고로 + 반드시 시작 화면에 고정 할 필요는 없습니다. +* Windows 7과 그 이하 버전은 데스크톱 알림을 지원하지 않습니다. + 혹시 "풍선 팝업 알림" 기능을 찾는다면 [Tray API](tray-balloon)를 사용하세요. -이미지를 데스크톱 알림에 사용하려면 알림 옵션의 `icon` 속성에 로컬 이미지 파일(`png` 권장)을 지정하면 됩니다. -데스크톱 알림은 잘못된 경로를 지정하거나 `http/https` 기반의 URL을 지정해도 이미지가 보이지 않을 뿐 정상 작동합니다. +이미지를 데스크톱 알림에 사용하려면 알림 옵션의 `icon` 속성에 로컬 이미지 파일 +(`png` 권장)을 지정하면 됩니다. 데스크톱 알림은 잘못된 경로를 지정하거나 `http/https` +기반의 URL을 지정해도 이미지가 보이지 않을 뿐 정상 작동합니다. ```javascript new Notification('Title', { @@ -40,12 +47,14 @@ new Notification('Title', { }); ``` -또한 `body`의 최대 길이는 250자 입니다. Windows 개발팀에선 알림 문자열을 200자 이하로 유지하는 것을 권장합니다. +또한 `body`의 최대 길이는 250자 입니다. Windows 개발팀에선 알림 문자열을 200자 이하로 +유지하는 것을 권장합니다. ### Linux 데스크톱 알림의 구현으로 `libnotify`를 사용합니다. 따라서 [Desktop Notifications Specification][notification-spec]을 -따르는 모든 데스크탑 환경에서 데스크톱 알림 기능을 사용할 수 있습니다. Cinnamon, Enlightenment, Unity, GNOME, KDE등을 지원합니다. +따르는 모든 데스크탑 환경에서 데스크톱 알림 기능을 사용할 수 있습니다. Cinnamon, +Enlightenment, Unity, GNOME, KDE등을 지원합니다. ### OS X @@ -53,11 +62,13 @@ OS X에서의 데스크톱 알림은 아주 직관적입니다. 하지만 데스 [Apple's Human Interface guidelines regarding notifications](https://developer.apple.com/library/mac/documentation/UserExperience/Conceptual/OSXHIGuidelines/NotificationCenter.html) 가이드를 고려해야 합니다. -참고로 데스크롭 알림의 최대 길이는 256 바이트 입니다. 길이가 초과할 경우 초과한 글자가 잘립니다. +참고로 데스크롭 알림의 최대 길이는 256 바이트 입니다. 길이가 초과할 경우 초과한 글자가 +잘립니다. ## 최근 사용한 문서 (Windows & OS X) -알다 싶이 Windows와 OS X는 JumpList 또는 dock 메뉴를 통해 최근 문서 리스트에 쉽게 접근할 수 있습니다. +알다 싶이 Windows와 OS X는 JumpList 또는 dock 메뉴를 통해 최근 문서 리스트에 쉽게 +접근할 수 있습니다. __JumpList:__ @@ -67,13 +78,15 @@ __어플리케이션 dock menu:__ -파일을 최근 문서에 추가하려면 [app.addRecentDocument][addrecentdocument] API를 사용할 수 있습니다: +파일을 최근 문서에 추가하려면 [app.addRecentDocument][addrecentdocument] API를 +사용할 수 있습니다: ```javascript app.addRecentDocument('/Users/USERNAME/Desktop/work.type'); ``` -그리고 [app.clearRecentDocuments][clearrecentdocuments] API로 최근 문서 리스트를 비울 수 있습니다: +그리고 [app.clearRecentDocuments][clearrecentdocuments] API로 최근 문서 리스트를 +비울 수 있습니다: ```javascript app.clearRecentDocuments(); @@ -81,11 +94,13 @@ app.clearRecentDocuments(); ### Windows에서 주의할 점 -이 기능을 Windows에서 사용할 땐 운영체제 시스템에 어플리케이션에서 사용하는 파일 확장자가 등록되어 있어야 합니다. -그렇지 않은 경우 파일을 JumpList에 추가해도 추가되지 않습니다. -어플리케이션 등록에 관련된 API의 모든 내용은 [Application Registration][app-registration]에서 찾아볼 수 있습니다. +이 기능을 Windows에서 사용할 땐 운영체제 시스템에 어플리케이션에서 사용하는 파일 +확장자가 등록되어 있어야 합니다. 그렇지 않은 경우 파일을 JumpList에 추가해도 추가되지 +않습니다. 어플리케이션 등록에 관련된 API의 모든 내용은 [Application Registration][app-registration]에서 +찾아볼 수 있습니다. -유저가 JumpList에서 파일을 클릭할 경우 클릭된 파일의 경로가 커맨드 라인 인자로 추가되어 새로운 인스턴스의 어플리케이션이 실행됩니다. +유저가 JumpList에서 파일을 클릭할 경우 클릭된 파일의 경로가 커맨드 라인 인자로 추가되어 +새로운 인스턴스의 어플리케이션이 실행됩니다. ### OS X에서 주의할 점 @@ -100,7 +115,8 @@ __Terminal.app의 dock menu:__ -커스텀 dock menu를 설정하려면 `app.dock.setMenu` API를 사용하면 됩니다. OS X에서만 사용 가능합니다: +커스텀 dock menu를 설정하려면 `app.dock.setMenu` API를 사용하면 됩니다. +OS X에서만 사용 가능합니다: ```javascript const electron = require('electron'); @@ -123,26 +139,30 @@ app.dock.setMenu(dockMenu); Windows에선 JumpList의 `Tasks` 카테고리에 원하는 작업을 설정할 수 있습니다. MSDN에선 해당 기능을 다음과 같이 설명하고 있습니다: -> 어플리케이션 작업은 프로그램의 기능 그리고 주요사양 두가지를 기반으로 유저의 행동을 예측하여 정의합니다. -> 실행할 필요가 없는 어플리케이션 작업은 작동하지 않을 때 반드시 context-free를 유지해야 합니다. -> 작업은 일반 사용자가 프로그램을 실행하거나 이메일 프로그램으로 이메일을 작성하거나 달력을 불러오고 -> 워드 프로세서로 새 문서를 작성, 특정 모드, 부속 명령으로 프로그램을 실행하는 등의 -> 통계적, 일반적으로 가장 많이 사용되는 작업인지를 고려해야 합니다. -> 어플리케이션 작업은 일반 유저가 필요로 하지 않는 고급 기능을 조잡하게 채우거나 등록과 같은 일회성의 작업을 포함해선 안됩니다. -> 작업에 특별 이벤트 또는 업그레이드 등의 홍보성 작업을 추가하면 안됩니다. +> 어플리케이션 작업은 프로그램의 기능 그리고 주요사양 두가지를 기반으로 유저의 행동을 +> 예측하여 정의합니다. 실행할 필요가 없는 어플리케이션 작업은 작동하지 않을 때 반드시 +> context-free를 유지해야 합니다. 작업은 일반 사용자가 프로그램을 실행하거나 이메일 +> 프로그램으로 이메일을 작성하거나 달력을 불러오고, 워드 프로세서로 새 문서를 작성, +> 특정 모드, 부속 명령으로 프로그램을 실행하는 등의 통계적, 일반적으로 가장 많이 +> 사용되는 작업인지를 고려해야 합니다. 어플리케이션 작업은 일반 유저가 필요로 하지 +> 않는 고급 기능을 조잡하게 채우거나 등록과 같은 일회성의 작업을 포함해선 안됩니다. +> 또한 작업에 특별 이벤트 또는 업그레이드 등의 홍보성 작업을 추가하면 안됩니다. > > 작업 리스트는 가능한 한 정적으로 유지되는 것을 적극 권장합니다. > 이것은 동일한 상태 또는 응용 프로그램의 상태에 관계없이 유지되어야 합니다. -> 작업 목록은 동적으로 변경할 수 있지만 몇몇 유저는 예상하지 못한 작업 목록 변경에 혼동할 수 있다는 점을 고려해야 합니다. +> 작업 목록은 동적으로 변경할 수 있지만 몇몇 유저는 예상하지 못한 작업 목록 변경에 +> 혼란을 일으킬 수 있다는 점을 고려해야 합니다. __Internet Explorer의 작업:__ ![IE](http://i.msdn.microsoft.com/dynimg/IC420539.png) -OS X의 dock menu(진짜 메뉴)와는 달리 Windows의 사용자 작업은 어플리케이션 바로 가기처럼 작동합니다. -유저가 작업을 클릭할 때 설정한 인자와 함께 새로운 어플리케이션이 실행됩니다. +OS X의 dock menu(진짜 메뉴)와는 달리 Windows의 사용자 작업은 어플리케이션 바로 +가기처럼 작동합니다. 유저가 작업을 클릭할 때 설정한 인자와 함께 새로운 어플리케이션이 +실행됩니다. -사용자 작업을 설정하려면 [app.setUserTasks][setusertaskstasks] 메서드를 통해 구현할 수 있습니다: +사용자 작업을 설정하려면 [app.setUserTasks][setusertaskstasks] 메서드를 통해 구현할 +수 있습니다: ```javascript app.setUserTasks([ @@ -157,34 +177,39 @@ app.setUserTasks([ ]); ``` -작업 리스트를 비우려면 간단히 `app.setUserTasks` 메서드의 첫번째 인자에 빈 배열을 넣어 호출하면 됩니다: +작업 리스트를 비우려면 간단히 `app.setUserTasks` 메서드의 첫번째 인자에 빈 배열을 넣어 +호출하면 됩니다: ```javascript app.setUserTasks([]); ``` -사용자 작업 리스트는 어플리케이션이 삭제되지 않는 한 종료되어도 태스크바에 보존됩니다. 이러한 이유로 반드시 프로그램 경로와 아이콘 경로를 지정해야 합니다. +사용자 작업 리스트는 어플리케이션이 삭제되지 않는 한 종료되어도 태스크바에 보존됩니다. +이러한 이유로 반드시 프로그램 경로와 아이콘 경로를 지정해야 합니다. -## 섬네일 툴바 +## 미리보기 툴바 -Windows에선 작업 표시줄의 어플리케이션 선택시 나오는 미리보기에 특정한 섬네일 툴바를 추가할 수 있습니다. -이 기능은 유저가 윈도우를 활성화 하지 않고 특정한 커맨드를 실행시킬 수 있도록 할 수 있습니다. +Windows에선 작업 표시줄의 어플리케이션 선택시 나오는 미리보기에 특정한 미리보기 툴바를 +추가할 수 있습니다. 이 기능은 유저가 윈도우를 활성화 하지 않고 특정한 커맨드를 실행시킬 +수 있도록 할 수 있습니다. MSDN의 설명에 의하면: -> 이 툴바는 표준 툴바의 공통 컨트롤과 비슷한 역할을 합니다. 버튼은 최대 7개 까지 만들 수 있습니다. -> 각 버튼의 구조엔 ID, 이미지, 툴팁, 상태등이 정의되어있습니다. 태스크바에 구조가 전달되면 어플리케이션이 -> 상태에 따라 버튼을 숨기거나, 활성화하거나, 비활성화 할 수 있습니다. +> 이 툴바는 표준 툴바의 공통 컨트롤과 비슷한 역할을 합니다. 버튼은 최대 7개 까지 +> 만들 수 있습니다. 각 버튼의 구조엔 ID, 이미지, 툴팁, 상태 등이 정의되어있습니다. +> 작업표시줄에 구조가 전달되면 어플리케이션이 상태에 따라 버튼을 숨기거나, 활성화하거나, +> 비활성화 할 수 있습니다. > -> 예를 들어, 윈도우 미디어 플레이어는(WMP) 기본적으로 -> 미디어 플레이어가 공통적으로 사용하는 재생, 일시정지, 음소거, 정지등의 컨트롤을 포함하고 있습니다. +> 예를 들어, 윈도우 미디어 플레이어는(WMP) 미디어 플레이어가 공통적으로 사용하는 +> 재생, 일시정지, 음소거, 정지등의 컨트롤을 포함하고 있습니다. -__Windows Media Player의 섬네일 툴바:__ +__Windows Media Player의 미리보기 툴바:__ ![player](https://i-msdn.sec.s-msft.com/dynimg/IC420540.png) -[BrowserWindow.setThumbarButtons][setthumbarbuttons] API를 통해 어플리케이션에 섬네일 툴바를 설정할 수 있습니다: +[BrowserWindow.setThumbarButtons][setthumbarbuttons] API를 통해 어플리케이션에 +미리보기 툴바를 설정할 수 있습니다: ```javascript const BrowserWindow = require('electron').BrowserWindow; @@ -209,7 +234,8 @@ win.setThumbarButtons([ ]); ``` -섬네일 툴바를 비우려면 간단히 `BrowserWindow.setThumbarButtons` API에 빈 배열을 전달하면 됩니다: +미리보기 툴바를 비우려면 간단히 `BrowserWindow.setThumbarButtons` API에 빈 배열을 +전달하면 됩니다: ```javascript win.setThumbarButtons([]); @@ -217,7 +243,8 @@ win.setThumbarButtons([]); ## Unity 런처 숏컷 기능 (Linux) -Unity 환경에선 `.desktop` 파일을 수정함으로써 런처에 새로운 커스텀 엔트리를 추가할 수 있습니다. [Adding Shortcuts to a Launcher][unity-launcher] 가이드를 참고하세요. +Unity 환경에선 `.desktop` 파일을 수정함으로써 런처에 새로운 커스텀 엔트리를 추가할 수 +있습니다. [Adding Shortcuts to a Launcher][unity-launcher] 가이드를 참고하세요. __Audacious의 런처 숏컷:__ @@ -226,7 +253,8 @@ __Audacious의 런처 숏컷:__ ## Taskbar progress 기능 (Windows & Unity) Windows에선 태스크바의 어플리케이션 버튼에 progress bar를 추가할 수 있습니다. -이 기능은 사용자가 어플리케이션의 창을 열지 않고도 어플리케이션의 작업의 상태 정보를 시각적으로 보여줄 수 있도록 해줍니다. +이 기능은 사용자가 어플리케이션의 창을 열지 않고도 어플리케이션의 작업의 상태 정보를 +시각적으로 보여줄 수 있도록 해줍니다. 또한 Unity DE도 런처에 progress bar를 부착할 수 있습니다. @@ -238,7 +266,8 @@ __Unity 런처의 progress bar:__ ![Unity Launcher](https://cloud.githubusercontent.com/assets/639601/5081747/4a0a589e-6f0f-11e4-803f-91594716a546.png) -이 기능은 [BrowserWindow.setProgressBar][setprogressbar] API를 사용하여 구현할 수 있습니다: +이 기능은 [BrowserWindow.setProgressBar][setprogressbar] API를 사용하여 구현할 수 +있습니다: ```javascript var window = new BrowserWindow({...}); @@ -247,14 +276,17 @@ window.setProgressBar(0.5); ## 대표 파일 제시 (OS X) -OS X는 창에서 대표 파일을 설정할 수 있습니다. 타이틀바에서 파일 아이콘이 있고, 사용자가 Command-Click 또는 Control-Click 키를 누를 경우 파일 경로 팝업이 보여집니다. -또한 창의 상태도 지정할 수 있습니다. 쉽게 말해 로드된 문서의 수정여부를 타이틀바 파일 아이콘에 표시할 수 있습니다. +OS X는 창에서 대표 파일을 설정할 수 있습니다. 타이틀바에서 파일 아이콘이 있고, 사용자가 +Command-Click 또는 Control-Click 키를 누를 경우 파일 경로 팝업이 보여집니다. 또한 +창의 상태도 지정할 수 있습니다. 다시 말해 로드된 문서의 수정 여부를 제목의 파일 +아이콘에 표시할 수 있습니다. __대표 파일 팝업 메뉴:__ -대표 파일 관련 API는 [BrowserWindow.setRepresentedFilename][setrepresentedfilename] 과 [BrowserWindow.setDocumentEdited][setdocumentedited]를 사용할 수 있습니다: +대표 파일 관련 API는 [BrowserWindow.setRepresentedFilename][setrepresentedfilename] 과 +[BrowserWindow.setDocumentEdited][setdocumentedited]를 사용할 수 있습니다: ```javascript var window = new BrowserWindow({...}); diff --git a/docs-translations/ko-KR/tutorial/devtools-extension.md b/docs-translations/ko-KR/tutorial/devtools-extension.md index 05ec3893ead0..655c6ed7d5c2 100644 --- a/docs-translations/ko-KR/tutorial/devtools-extension.md +++ b/docs-translations/ko-KR/tutorial/devtools-extension.md @@ -1,13 +1,17 @@ # 개발자 도구 확장 기능 -어플리케이션의 디버깅을 쉽게 하기 위해 Electron은 기본적으로 [Chrome DevTools Extension][devtools-extension]을 지원합니다. +어플리케이션의 디버깅을 쉽게 하기 위해 Electron은 기본적으로 +[Chrome DevTools Extension][devtools-extension]을 지원합니다. -개발자 도구 확장 기능은 간단하게 사용할 확장 기능 플러그인의 소스 코드를 다운로드한 후 `BrowserWindow.addDevToolsExtension` API를 이용하여 -어플리케이션 내에 로드할 수 있습니다. 한가지 주의할 점은 확장 기능 사용시 창이 생성될 때 마다 일일이 해당 API를 호출할 필요는 없습니다. +개발자 도구 확장 기능은 간단하게 사용할 확장 기능 플러그인의 소스 코드를 다운로드한 후 +`BrowserWindow.addDevToolsExtension` API를 통해 어플리케이션 내에 로드할 수 있습니다. +한가지 주의할 점은 확장 기능 사용시 창이 생성될 때 마다 일일이 해당 API를 호출할 필요는 +없습니다. -** 주의: 현재 React DevTools은 작동하지 않습니다. https://github.com/atom/electron/issues/915 이슈를 참고하세요! ** +**주의: 현재 React DevTools은 작동하지 않습니다. https://github.com/atom/electron/issues/915 이슈를 참고하세요!** -다음 예제는 [React DevTools Extension](https://github.com/facebook/react-devtools)을 사용합니다. +다음 예제는 [React DevTools Extension](https://github.com/facebook/react-devtools)을 +사용합니다. 먼저 소스코드를 다운로드 받습니다: @@ -16,8 +20,8 @@ $ cd /some-directory $ git clone --recursive https://github.com/facebook/react-devtools.git ``` -[`react-devtools/shells/chrome/Readme.md`](https://github.com/facebook/react-devtools/blob/master/shells/chrome/Readme.md) -를 통해 확장 기능을 개발하는 방법을 알아볼 수 있습니다. +[`react-devtools/shells/chrome/Readme.md`](https://github.com/facebook/react-devtools/blob/master/shells/chrome/Readme.md)를 +통해 확장 기능을 개발하는 방법을 알아볼 수 있습니다. 그리고 개발자 도구에서 다음 코드를 입력하면 확장 기능을 로드할 수 있습니다: @@ -26,7 +30,8 @@ const BrowserWindow = require('electron').remote.BrowserWindow; BrowserWindow.addDevToolsExtension('/some-directory/react-devtools/shells/chrome'); ``` -확장 기능을 언로드 하고 콘솔을 다시 열 때 해당 확장 기능이 로드되지 않도록 하려면 `BrowserWindow.removeDevToolsExtension` API를 사용하면 됩니다: +확장 기능을 언로드 하고 콘솔을 다시 열 때 해당 확장 기능이 로드되지 않도록 하려면 +`BrowserWindow.removeDevToolsExtension` API를 사용하면 됩니다: ```javascript BrowserWindow.removeDevToolsExtension('React Developer Tools'); @@ -34,20 +39,25 @@ BrowserWindow.removeDevToolsExtension('React Developer Tools'); ## 개발자 도구 확장 기능의 구성 형식 -모든 개발자 도구 확장은 완벽히 Chrome 브라우저를 위해 작성되었기 때문에 Electron에서도 로드할 수 있습니다. -하지만 반드시 확장 기능은 소스 코드 디렉터리(폴더) 형태여야 합니다. 그래서 `crx` 등의 포맷으로 패키징된 확장 기능의 경우 -사용자가 직접 해당 패키지의 압축을 풀어서 로드하지 않는 이상 Electron에서 해당 확장 기능의 압축을 풀 방법이 없습니다. +모든 개발자 도구 확장은 완벽히 Chrome 브라우저를 위해 작성되었기 때문에 Electron에서도 +로드할 수 있습니다. 하지만 반드시 확장 기능은 소스 코드 디렉터리(폴더) 형태여야 합니다. +그래서 `crx` 등의 포맷으로 패키징된 확장 기능의 경우 사용자가 직접 해당 패키지의 압축을 +풀어서 로드하지 않는 이상 Electron에서 해당 확장 기능의 압축을 풀 방법이 없습니다. ## 백그라운드 페이지 -현재 Electron은 Chrome에서 지원하는 백그라운드 페이지(background pages)를 지원하지 않습니다. -몇몇 확장 기능은 이 기능에 의존하는 경우가 있는데, 이 때 해당 확장 기능은 Electron에서 작동하지 않을 수 있습니다. +현재 Electron은 Chrome에서 지원하는 백그라운드 페이지(background pages)를 지원하지 +않습니다. 몇몇 확장 기능은 이 기능에 의존하는 경우가 있는데, 이 때 해당 확장 기능은 +Electron에서 작동하지 않을 수 있습니다. ## `chrome.*` API -몇몇 Chrome 확장 기능은 특정 기능을 사용하기 위해 `chrome.*` API를 사용하는데, 이 API들을 구현하기 위해 노력했지만 안타깝게도 아직 모든 API가 구현되지는 않았습니다. +몇몇 Chrome 확장 기능은 특정 기능을 사용하기 위해 `chrome.*` API를 사용하는데, 이 +API들을 구현하기 위해 노력했지만 안타깝게도 아직 모든 API가 구현되지는 않았습니다. -아직 모든 API가 구현되지 않았기 때문에 확장 기능에서 `chrome.devtools.*` 대신 `chrome.*` API를 사용할 경우 확장 기능이 제대로 작동하지 않을 수 있음을 감안해야 합니다. -만약 문제가 발생할 경우 Electron의 GitHub 저장소에 관련 이슈를 올리면 해당 API를 추가하는데 많은 도움이 됩니다. +아직 모든 API가 구현되지 않았기 때문에 확장 기능에서 `chrome.devtools.*` 대신 +`chrome.*` API를 사용할 경우 확장 기능이 제대로 작동하지 않을 수 있음을 감안해야 합니다. +만약 문제가 발생할 경우 Electron의 GitHub 저장소에 관련 이슈를 올리면 해당 API를 +추가하는데 많은 도움이 됩니다. [devtools-extension]: https://developer.chrome.com/extensions/devtools diff --git a/docs-translations/ko-KR/tutorial/mac-app-store-submission-guide.md b/docs-translations/ko-KR/tutorial/mac-app-store-submission-guide.md index 3006808797f7..d0322aa90af4 100644 --- a/docs-translations/ko-KR/tutorial/mac-app-store-submission-guide.md +++ b/docs-translations/ko-KR/tutorial/mac-app-store-submission-guide.md @@ -1,24 +1,26 @@ # Mac 앱 스토어 어플리케이션 제출 가이드 -Electron은 v0.34.0 버전부터 앱 패키지를 Mac App Store(MAS)에 제출할 수 있게 되었습니다. -이 가이드는 어플리케이션을 앱 스토어에 등록하는 방법과 빌드의 한계에 대한 설명을 제공합니다. +Electron은 v0.34.0 버전부터 앱 패키지를 Mac App Store(MAS)에 제출할 수 있게 +되었습니다. 이 가이드는 어플리케이션을 앱 스토어에 등록하는 방법과 빌드의 한계에 대한 +설명을 제공합니다. ## 앱 스토어에 어플리케이션을 등록하는 방법 다음 몇 가지 간단한 절차에 따라 앱 스토어에 어플리케이션을 등록하는 방법을 알아봅니다. -한가지, 이 절차는 제출한 앱이 Apple로부터 승인된다는 것을 확신하지 않습니다. -따라서 여전히 Apple의 [Submitting Your App][submitting-your-app] 가이드를 숙지하고 있어야 하며 -앱 스토어 제출 요구 사항을 확실히 인지하고 있어야합니다. +한가지, 이 절차는 제출한 앱이 Apple로부터 승인된다는 것을 확신하지 않습니다. 따라서 +여전히 Apple의 [Submitting Your App][submitting-your-app] 가이드를 숙지하고 있어야 +하며 앱 스토어 제출 요구 사항을 확실히 인지하고 있어야합니다. ### 인증서 취득 -앱 스토어에 어플리케이션을 제출하려면, 먼저 Apple로부터 인증서를 취득해야 합니다. -취득 방법은 웹에서 찾아볼 수 있는 [가이드][nwjs-guide]를 참고하면 됩니다. +앱 스토어에 어플리케이션을 제출하려면, 먼저 Apple로부터 인증서를 취득해야 합니다. 취득 +방법은 웹에서 찾아볼 수 있는 [가이드][nwjs-guide]를 참고하면 됩니다. ### 앱에 서명하기 -Apple로부터 인증서를 취득했다면, [어플리케이션 배포](application-distribution.md) 문서에 따라 어플리케이션을 패키징한 후 어플리케이션에 서명 합니다. -이 절차는 기본적으로 다른 프로그램과 같습니다. 하지만 키는 Electron 종속성 파일에 각각 따로 서명 해야 합니다. +Apple로부터 인증서를 취득했다면, [어플리케이션 배포](application-distribution.md) +문서에 따라 어플리케이션을 패키징한 후 어플리케이션에 서명 합니다. 이 절차는 기본적으로 +다른 프로그램과 같습니다. 하지만 키는 Electron 종속성 파일에 각각 따로 서명 해야 합니다. 첫번째, 다음 두 자격(plist) 파일을 준비합니다. @@ -77,18 +79,20 @@ codesign -fs "$APP_KEY" --entitlements parent.plist "$APP_PATH" productbuild --component "$APP_PATH" /Applications --sign "$INSTALLER_KEY" "$RESULT_PATH" ``` -만약 OS X의 샌드박스 개념에 대해 처음 접한다면 Apple의 [Enabling App Sandbox][enable-app-sandbox] 문서를 -참고하여 기본적인 개념을 이해해야 합니다. 그리고 자격(plist) 파일에 어플리케이션에서 요구하는 권한의 키를 추가합니다. +만약 OS X의 샌드박스 개념에 대해 처음 접한다면 Apple의 [Enabling App Sandbox][enable-app-sandbox] +문서를 참고하여 기본적인 개념을 이해해야 합니다. 그리고 자격(plist) 파일에 +어플리케이션에서 요구하는 권한의 키를 추가합니다. ### 어플리케이션을 업로드하고 심사용 앱으로 제출 -어플리케이션 서명을 완료한 후 iTunes Connect에 업로드하기 위해 Application Loader를 사용할 수 있습니다. -참고로 업로드하기 전에 [레코드][create-record]를 만들었는지 확인해야 합니다. -그리고 [심사를 위해 앱을 제출][submit-for-review]할 수 있습니다. +어플리케이션 서명을 완료한 후 iTunes Connect에 업로드하기 위해 Application Loader를 +사용할 수 있습니다. 참고로 업로드하기 전에 [레코드][create-record]를 만들었는지 +확인해야 합니다. 그리고 [심사를 위해 앱을 제출][submit-for-review]할 수 있습니다. ## MAS 빌드의 한계 -모든 어플리케이션 샌드박스에 대한 요구 사항을 충족시키기 위해, 다음 모듈들은 MAS 빌드에서 비활성화됩니다: +모든 어플리케이션 샌드박스에 대한 요구 사항을 충족시키기 위해, 다음 모듈들은 MAS +빌드에서 비활성화됩니다: * `crash-reporter` * `auto-updater` @@ -99,8 +103,9 @@ productbuild --component "$APP_PATH" /Applications --sign "$INSTALLER_KEY" "$RES * 특정 접근성 기능이 작동하지 않을 수 있습니다. * 어플리케이션이 DNS의 변경을 감지하지 못할 수 있습니다. -또한 어플리케이션 샌드박스 개념으로 인해 어플리케이션에서 접근할 수 있는 리소스는 엄격하게 제한되어 있습니다. -자세한 내용은 [App Sandboxing][app-sandboxing] 문서를 참고하세요. +또한 어플리케이션 샌드박스 개념으로 인해 어플리케이션에서 접근할 수 있는 리소스는 +엄격하게 제한되어 있습니다. 자세한 내용은 [App Sandboxing][app-sandboxing] 문서를 +참고하세요. **역주:** [Mac 앱 배포 가이드 공식 문서](https://developer.apple.com/osx/distribution/kr/) diff --git a/docs-translations/ko-KR/tutorial/online-offline-events.md b/docs-translations/ko-KR/tutorial/online-offline-events.md index 0b989516a6ab..f66e2e2bbb59 100644 --- a/docs-translations/ko-KR/tutorial/online-offline-events.md +++ b/docs-translations/ko-KR/tutorial/online-offline-events.md @@ -1,6 +1,7 @@ # 온라인/오프라인 이벤트 감지 -온라인/오프라인 이벤트는 다음 예제와 같이 랜더러 프로세스에서 표준 HTML5 API를 이용하여 구현할 수 있습니다. +온라인/오프라인 이벤트는 다음 예제와 같이 랜더러 프로세스에서 표준 HTML5 API를 이용하여 +구현할 수 있습니다. _main.js_ @@ -36,10 +37,12 @@ _online-status.html_ ``` -메인 프로세스에서 이 이벤트를 처리할 필요가 있는 경우 이벤트를 메인 프로세스로 보낼 수 있습니다. -메인 프로세스는 `navigator` 객체를 가지고 있지 않기 때문에 이 이벤트를 직접 사용할 수 없습니다. +메인 프로세스에서 이 이벤트를 처리할 필요가 있는 경우 이벤트를 메인 프로세스로 보낼 수 +있습니다. 메인 프로세스는 `navigator` 객체를 가지고 있지 않기 때문에 이 이벤트를 직접 +사용할 수는 없습니다. -대신 다음 예제와 같이 Electron의 inter-process communication(ipc) 유틸리티를 사용하면 이벤트를 메인 프로세스로 전달할 수 있습니다. +대신 다음 예제와 같이 Electron의 inter-process communication(ipc) 유틸리티를 +사용하면 이벤트를 메인 프로세스로 전달할 수 있습니다. _main.js_ diff --git a/docs-translations/ko-KR/tutorial/quick-start.md b/docs-translations/ko-KR/tutorial/quick-start.md index dea6a343e6bf..8946f44716f2 100644 --- a/docs-translations/ko-KR/tutorial/quick-start.md +++ b/docs-translations/ko-KR/tutorial/quick-start.md @@ -2,38 +2,46 @@ ## 소개 -Electron은 자바스크립트와 함께 제공된 풍부한 네이티브 API를 사용하여 멋진 데스크탑 어플리케이션을 만들 수 있도록 해주는 프레임워크입니다. -이 프레임워크의 Node.js는 웹 서버 개발이 아닌 데스크탑 어플리케이션 개발에 초점을 맞췄습니다. +Electron은 자바스크립트와 함께 제공된 풍부한 네이티브 API를 사용하여 멋진 데스크탑 +어플리케이션을 만들 수 있도록 해주는 프레임워크입니다. 이 프레임워크의 Node.js는 웹 +서버 개발이 아닌 데스크탑 어플리케이션 개발에 초점을 맞췄습니다. -이 말은 Electron이 GUI 라이브러리의 자바스크립트 바인딩이라는 뜻이 아닙니다. -대신, Electron은 웹 페이지의 GUI를 사용합니다. 쉽게 말해 Electron은 자바스크립트를 사용하여 조작하는 작은 Chromium 브라우저로 볼 수 있습니다. +이 말은 Electron이 GUI 라이브러리의 자바스크립트 바인딩이라는 뜻이 아닙니다. 대신, +Electron은 웹 페이지의 GUI를 사용합니다. 쉽게 말해 Electron은 자바스크립트를 사용하여 +조작하는 작은 Chromium 브라우저로 볼 수 있습니다. ### 메인 프로세스 -Electron은 실행될 때 __메인 프로세스__로 불리는 `package.json`의 `main` 스크립트를 호출합니다. -이 스크립트는 메인 프로세스에서 작동합니다. GUI 컴포넌트를 조작하거나 웹 페이지 창을 생성할 수 있습니다. +Electron은 실행될 때 __메인 프로세스__로 불리는 `package.json`의 `main` 스크립트를 +호출합니다. 이 스크립트는 메인 프로세스에서 작동합니다. GUI 컴포넌트를 조작하거나 웹 +페이지 창을 생성할 수 있습니다. ### 랜더러 프로세스 Electron이 웹페이지를 보여줄 때 Chromium의 multi-processes 구조도 같이 사용됩니다. Electron 프로세스 내에서 작동하는 웹 페이지를 __랜더러 프로세스__ 라고 불립니다. -보통 일반 브라우저의 웹 페이지들은 샌드박스가 적용된 환경에서 작동하며 네이티브 리소스에는 접근할 수 없도록 되어 있습니다. -하지만 Electron은 웹 페이지 내에서 Node.js API를 사용하여 low-level 수준으로 운영체제와 상호작용할 수 있습니다. +보통 일반 브라우저의 웹 페이지들은 샌드박스가 적용된 환경에서 작동하며 네이티브 +리소스에는 접근할 수 없도록 되어 있습니다. 하지만 Electron은 웹 페이지 내에서 Node.js +API를 사용하여 low-level 수준으로 운영체제와 상호작용할 수 있습니다. ### 메인 프로세스와 랜더러 프로세스의 차이점 메인 프로세스는 `BrowserWindow` Class를 사용하여 새로운 창을 만들 수 있습니다. -`BrowserWindow` 인스턴스는 따로 분리된 프로세스에서 랜더링 되며 이 프로세스를 랜더러 프로세스라고 합니다. -`BrowserWindow` 인스턴스가 소멸할 때 그 창의 랜더러 프로세스도 같이 소멸합니다. +`BrowserWindow` 인스턴스는 따로 분리된 프로세스에서 랜더링 되며 이 프로세스를 랜더러 +프로세스라고 합니다. `BrowserWindow` 인스턴스가 소멸할 때 그 창의 랜더러 프로세스도 +같이 소멸합니다. -메인 프로세스는 모든 웹 페이지와 랜더러 프로세스를 관리하며 랜더러 프로세스는 각각의 프로세스에 고립되며 웹 페이지의 작동에만 영향을 끼칩니다. +메인 프로세스는 모든 웹 페이지와 랜더러 프로세스를 관리하며 랜더러 프로세스는 각각의 +프로세스에 고립되며 웹 페이지의 작동에만 영향을 끼칩니다. -웹 페이지 내에선 기본적으로 네이티브 GUI와 관련된 API를 호출할 수 없도록 설계 되어 있습니다. -왜냐하면 웹 페이지 내에서 네이티브 GUI 리소스를 관리하는 것은 보안에 취약하고 리소스를 누수시킬 수 있기 때문입니다. -꼭 웹 페이지 내에서 API를 사용해야 한다면 메인 프로세스에서 그 작업을 처리할 수 있도록 메인 프로세스와 통신을 해야 합니다. +웹 페이지 내에선 기본적으로 네이티브 GUI와 관련된 API를 호출할 수 없도록 설계 되어 +있습니다. 왜냐하면 웹 페이지 내에서 네이티브 GUI 리소스를 관리하는 것은 보안에 취약하고 +리소스를 누수시킬 수 있기 때문입니다. 꼭 웹 페이지 내에서 API를 사용해야 한다면 메인 +프로세스에서 그 작업을 처리할 수 있도록 메인 프로세스와 통신을 해야 합니다. -Electron에는 메인 프로세스와 랜더러 프로세스 사이에 통신을 할 수 있도록 [ipc](../api/ipc-renderer.md) 모듈을 제공하고 있습니다. +Electron에는 메인 프로세스와 랜더러 프로세스 사이에 통신을 할 수 있도록 +[ipc](../api/ipc-renderer.md) 모듈을 제공하고 있습니다. 또는 [remote](../api/remote.md) 모듈을 사용하여 RPC 스타일로 통신할 수도 있습니다. ## 첫번째 Electron 앱 만들기 @@ -47,9 +55,9 @@ your-app/ └── index.html ``` -`package.json`은 node 모듈의 package.json과 같습니다. -그리고 `main` 필드에 스크립트 파일을 지정하면 메인 프로세스의 엔트리 포인트로 사용합니다. -예를 들어 사용할 수 있는 `package.json`은 다음과 같습니다: +`package.json`은 node 모듈의 package.json과 같습니다. 그리고 `main` 필드에 스크립트 +파일을 지정하면 메인 프로세스의 엔트리 포인트로 사용합니다. 예를 들어 사용할 수 있는 +`package.json`은 다음과 같습니다: ```json { @@ -59,9 +67,11 @@ your-app/ } ``` -__알림__: 만약 `main` 필드가 `package.json`에 설정되어 있지 않으면 Electron은 자동으로 같은 디렉터리의 `index.js`를 로드합니다. +__알림__: 만약 `main` 필드가 `package.json`에 설정되어 있지 않으면 Electron은 +자동으로 같은 디렉터리의 `index.js`를 로드합니다. -반드시 `main.js`에서 창을 만들고 시스템 이밴트를 처리해야합니다. 대표적인 예제로 다음과 같이 작성할 수 있습니다: +반드시 `main.js`에서 창을 만들고 시스템 이밴트를 처리해야합니다. 대표적인 예제로 +다음과 같이 작성할 수 있습니다: ```javascript const electron = require('electron'); @@ -126,12 +136,14 @@ app.on('ready', function() { ## 앱 실행하기 -앱을 작성한 후 [어플리케이션 배포](application-distribution.md) 가이드를 따라 앱을 패키징 하고 패키징한 앱을 실행할 수 있습니다. -또한 Electron 실행파일을 다운로드 받아 바로 실행해 볼 수도 있습니다. +앱을 작성한 후 [어플리케이션 배포](application-distribution.md) 가이드를 따라 앱을 +패키징 하고 패키징한 앱을 실행할 수 있습니다. 또한 Electron 실행파일을 다운로드 받아 +바로 실행해 볼 수도 있습니다. ### electron-prebuilt 사용 -`npm`을 통해 `electron-prebuilt` 패키지를 전역에 설치하면 간단한 명령으로 앱을 실행할 수 있습니다. +`npm`을 통해 `electron-prebuilt` 패키지를 전역에 설치하면 간단한 명령으로 앱을 +실행할 수 있습니다. 앱 디렉터리 내에서 다음 명령으로 실행할 수 있습니다: @@ -178,13 +190,17 @@ $ ./Electron.app/Contents/MacOS/Electron your-app/ ### 배포용 실행 파일 만들기 -어플리케이션 작성을 모두 끝냈다면 [어플리케이션 배포](application-distribution.md) 가이드를 통해 제작한 앱을 패키징하고 배포할 수 있습니다. +어플리케이션 작성을 모두 끝냈다면 [어플리케이션 배포](application-distribution.md) +가이드를 통해 제작한 앱을 패키징하고 배포할 수 있습니다. ### 미리 작성된 앱 실행하기 -[`atom/electron-quick-start`](https://github.com/atom/electron-quick-start) 저장소를 클론하면 이 문서에서 작성한 예제 앱을 바로 실행해 볼 수 있습니다. +[`atom/electron-quick-start`](https://github.com/atom/electron-quick-start) +저장소를 클론하면 이 문서에서 작성한 예제 앱을 바로 실행해 볼 수 있습니다. -**참고**: 이 예제를 실행시키려면 [Git](https://git-scm.com)과 [Node.js](https://nodejs.org/en/download/)가 필요합니다. (CLI에서 실행 가능한 [npm](https://npmjs.org)이 있어야 합니다) +**참고**: 이 예제를 실행시키려면 [Git](https://git-scm.com)과 +[Node.js](https://nodejs.org/en/download/)가 필요합니다. (CLI에서 실행 가능한 + [npm](https://npmjs.org)이 있어야 합니다) **역주**: `npm`은 보통 Node.js를 설치하면 자동으로 같이 설치됩니다. @@ -195,4 +211,4 @@ $ git clone https://github.com/atom/electron-quick-start $ cd electron-quick-start # 어플리케이션의 종속성 모듈을 설치한 후 실행합니다 $ npm install && npm start -``` \ No newline at end of file +``` diff --git a/docs-translations/ko-KR/tutorial/supported-platforms.md b/docs-translations/ko-KR/tutorial/supported-platforms.md index 7a35da0c129a..3b3a00d72156 100644 --- a/docs-translations/ko-KR/tutorial/supported-platforms.md +++ b/docs-translations/ko-KR/tutorial/supported-platforms.md @@ -8,18 +8,22 @@ OS X는 64비트 바이너리만 제공됩니다. 그리고 최소 OS X 지원 ### Windows -Windows 7 이후 버전만 지원됩니다. Windows Vista에서도 작동할 수 있지만 아직 모든 작동 테스트가 완료되지 않았습니다. +Windows 7 이후 버전만 지원됩니다. Windows Vista에서도 작동할 수 있지만 아직 모든 작동 +테스트가 완료되지 않았습니다. -윈도우용 바이너리는 `x86`과 `x64` 모두 제공됩니다. 그리고 `ARM` 버전 윈도우는 아직 지원하지 않습니다. (역주: 추후 지원할 가능성이 있습니다) +윈도우용 바이너리는 `x86`과 `x64` 모두 제공됩니다. 그리고 `ARM` 버전 윈도우는 아직 +지원하지 않습니다. (역주: 추후 지원할 가능성이 있습니다) ### Linux Ubuntu 12.04 버전에서 빌드된 `ia32`(`i686`), `x64`(`amd64`) 바이너리가 제공됩니다. -그리고 `arm` 버전 바이너리는 ARM v7 hard-float ABI와 Debian Wheezy용 NEON에 맞춰 제공됩니다. +그리고 `arm` 버전 바이너리는 ARM v7 hard-float ABI와 Debian Wheezy용 NEON에 맞춰 +제공됩니다. -미리 빌드된 바이너리가 배포판에서 작동할 수 있는지 여부는 Electron이 빌드된 플랫폼에서 링크된 라이브러리에 따라 달라집니다. -그래서 현재 Linux 바이너리는 Ubuntu 12.04 버전만 정상적인 작동이 보장됩니다. -하지만 다음 플랫폼들은 미리 빌드된 Electron 바이너리가 정상적으로 작동하는 것을 확인했습니다: +미리 빌드된 바이너리가 배포판에서 작동할 수 있는지 여부는 Electron이 빌드된 플랫폼에서 +링크된 라이브러리에 따라 달라집니다. 그래서 현재 Linux 바이너리는 Ubuntu 12.04 버전만 +정상적인 작동이 보장됩니다. 하지만 다음 플랫폼들은 미리 빌드된 Electron 바이너리가 +정상적으로 작동하는 것을 확인했습니다: * Ubuntu 12.04 이후 버전 * Fedora 21 diff --git a/docs-translations/ko-KR/tutorial/using-native-node-modules.md b/docs-translations/ko-KR/tutorial/using-native-node-modules.md index 45c4811aa1a1..d1c3aa167ad6 100644 --- a/docs-translations/ko-KR/tutorial/using-native-node-modules.md +++ b/docs-translations/ko-KR/tutorial/using-native-node-modules.md @@ -1,17 +1,22 @@ # 네이티브 node 모듈 사용하기 -Electron에선 node.js 네이티브 모듈이 지원됩니다. 하지만 Electron은 공식 node.js의 V8 엔진과는 다른 V8 버전을 사용합니다. -이러한 이유로 네이티브 모듈을 사용하기 위해선 Electron의 V8 버전에 맞춰 네이티브 모듈을 다시 빌드하고 헤더를 변경해야 합니다. +Electron에선 node.js 네이티브 모듈이 지원됩니다. 하지만 Electron은 공식 node.js의 +V8 엔진과는 다른 V8 버전을 사용합니다. 이러한 이유로 네이티브 모듈을 사용하기 위해선 +Electron의 V8 버전에 맞춰 네이티브 모듈을 다시 빌드하고 헤더를 변경해야 합니다. ## 네이티브 node 모듈 호환성 네이티브 모듈은 node.js가 새로운 V8 버전을 사용함으로 인해 작동하지 않을 수 있습니다. -사용하는 네이티브 모듈이 Electron에 맞춰 작동할 수 있도록 하려면 Electron에서 사용하는 node.js의 버전을 확인할 필요가 있습니다. -Electron에서 사용하는 node 버전은 [releases](https://github.com/atom/electron/releases)에서 확인할 수 있으며 -`process.version`을 출력하여 버전을 확인할 수도 있습니다. ([시작하기](https://github.com/atom/electron/blob/master/docs/tutorial/quick-start.md)의 예제를 참고하세요) +사용하는 네이티브 모듈이 Electron에 맞춰 작동할 수 있도록 하려면 Electron에서 사용하는 +node.js의 버전을 확인할 필요가 있습니다. Electron에서 사용하는 node 버전은 +[releases](https://github.com/atom/electron/releases)에서 확인할 수 있으며 +`process.version`을 출력하여 버전을 확인할 수도 있습니다. +([시작하기](https://github.com/atom/electron/blob/master/docs/tutorial/quick-start.md)의 +예제를 참고하세요) -혹시 직접 만든 네이티브 모듈이 있다면 [NAN](https://github.com/nodejs/nan/) 모듈을 사용하는 것을 고려해보는 것이 좋습니다. -이 모듈은 다중 버전의 node.js를 지원하기 쉽게 해줍니다. 이를 통해 오래된 모듈을 새 버전의 node.js에 맞게 포팅할 수 있습니다. +혹시 직접 만든 네이티브 모듈이 있다면 [NAN](https://github.com/nodejs/nan/) 모듈을 +사용하는 것을 고려해보는 것이 좋습니다. 이 모듈은 다중 버전의 node.js를 지원하기 쉽게 +만들어 줍니다. 이를 통해 오래된 모듈을 새 버전의 node.js에 맞게 포팅 할 수 있습니다. Electron도 이 모듈을 통해 포팅된 네이티브 모듈을 사용할 수 있습니다. ## 네이티브 모듈을 설치하는 방법 @@ -20,9 +25,11 @@ Electron도 이 모듈을 통해 포팅된 네이티브 모듈을 사용할 수 ### 쉬운 방법 -[`electron-rebuild`](https://github.com/paulcbetts/electron-rebuild) 패키지를 사용하면 빠르고 간단하게 네이티브 모듈을 다시 빌드할 수 있습니다. +[`electron-rebuild`](https://github.com/paulcbetts/electron-rebuild) 패키지를 +사용하면 빠르고 간단하게 네이티브 모듈을 다시 빌드할 수 있습니다. -다음 예제는 `electron-rebuild`를 통해 자동으로 모듈의 헤더를 다운로드하고 네이티브 모듈을 빌드합니다: +다음 예제는 `electron-rebuild`를 통해 자동으로 모듈의 헤더를 다운로드하고 네이티브 +모듈을 빌드합니다: ```sh npm install --save-dev electron-rebuild @@ -49,12 +56,14 @@ HOME=~/.electron-gyp npm install module-name ### `node-gyp`를 이용한 방법 -Node 모듈을 `node-gyp`를 사용하여 Electron을 타겟으로 빌드할 때는 `node-gyp`에 헤더 다운로드 주소와 버전을 알려주어야 합니다: +Node 모듈을 `node-gyp`를 사용하여 Electron을 타겟으로 빌드할 때는 `node-gyp`에 헤더 +다운로드 주소와 버전을 알려주어야 합니다: ```bash $ cd /path-to-module/ $ HOME=~/.electron-gyp node-gyp rebuild --target=0.29.1 --arch=x64 --dist-url=https://atom.io/download/atom-shell ``` -`HOME=~/.electron-gyp`은 변경할 헤더의 위치를 찾습니다. `--target=0.29.1`은 Electron의 버전입니다. -`--dist-url=...`은 헤더를 다운로드 하는 주소입니다. `--arch=x64`는 64비트 시스템을 타겟으로 빌드 한다는 것을 `node-gyp`에게 알려줍니다. +`HOME=~/.electron-gyp`은 변경할 헤더의 위치를 찾습니다. `--target=0.29.1`은 +Electron의 버전입니다. `--dist-url=...`은 헤더를 다운로드 하는 주소입니다. +`--arch=x64`는 64비트 시스템을 타겟으로 빌드 한다는 것을 `node-gyp`에게 알려줍니다. diff --git a/docs-translations/ko-KR/tutorial/using-pepper-flash-plugin.md b/docs-translations/ko-KR/tutorial/using-pepper-flash-plugin.md index cdb6f857cc2e..2f15a3532eea 100644 --- a/docs-translations/ko-KR/tutorial/using-pepper-flash-plugin.md +++ b/docs-translations/ko-KR/tutorial/using-pepper-flash-plugin.md @@ -5,12 +5,14 @@ Pepper 플래시 플러그인을 사용하려면 Pepper 플래시 플러그인 ## 플래시 플러그인 준비하기 -크롬 브라우저의 `chrome://plugins` 페이지에 접속한 후 `세부정보`에서 플래시 플러그인의 위치와 버전을 찾을 수 있습니다. -Electron에서 플래시 플러그인을 지원하기 위해선 이 두 가지를 복사해 와야 합니다. +크롬 브라우저의 `chrome://plugins` 페이지에 접속한 후 `세부정보`에서 플래시 +플러그인의 위치와 버전을 찾을 수 있습니다. Electron에서 플래시 플러그인을 지원하기 +위해선 이 두 가지를 복사해 와야 합니다. ## Electron 스위치 추가 -플러그인을 사용하려면 Electron 커맨드 라인에 `--ppapi-flash-path` 와 `ppapi-flash-version` 플래그를 app의 ready 이벤트가 호출되기 전에 추가해야 합니다. +플러그인을 사용하려면 Electron 커맨드 라인에 `--ppapi-flash-path` 와 +`ppapi-flash-version` 플래그를 app의 ready 이벤트가 호출되기 전에 추가해야 합니다. 그리고 `browser-window`에 `plugins` 스위치도 추가해야합니다. ```javascript diff --git a/docs-translations/ko-KR/tutorial/using-selenium-and-webdriver.md b/docs-translations/ko-KR/tutorial/using-selenium-and-webdriver.md index ae588348acd2..aba16256cf7f 100644 --- a/docs-translations/ko-KR/tutorial/using-selenium-and-webdriver.md +++ b/docs-translations/ko-KR/tutorial/using-selenium-and-webdriver.md @@ -3,17 +3,17 @@ [ChromeDriver - WebDriver for Chrome][chrome-driver]로 부터 인용: > WebDriver는 많은 브라우저에서 웹 앱을 자동적으로 테스트하는 툴입니다. -> 이 툴킷은 웹 페이지를 자동으로 탐색하고 유저 폼을 사용하거나 자바스크립트를 실행하는 등의 작업을 수행할 수 있습니다. -> ChromeDriver는 Chromium의 WebDriver wire 프로토콜 스텐드얼론 서버 구현입니다. -> Chromium 과 WebDriver 팀 멤버에 의해 개발되었습니다. +> 이 툴킷은 웹 페이지를 자동으로 탐색하고 유저 폼을 사용하거나 자바스크립트를 실행하는 +> 등의 작업을 수행할 수 있습니다. ChromeDriver는 Chromium의 WebDriver wire 프로토콜 +> 스텐드얼론 서버 구현입니다. Chromium 과 WebDriver 팀 멤버에 의해 개발되었습니다. -Electron에서 `chromedriver`를 사옹하려면 드라이버에서 Electron을 찾을 수 있도록 해야 하며 -Electron은 Chrome 브라우저와 비슷하다는 점을 기억해야 합니다. +Electron에서 `chromedriver`를 사옹하려면 드라이버에서 Electron을 찾을 수 있도록 해야 +하며 Electron은 Chrome 브라우저와 비슷하다는 점을 기억해야 합니다. ## WebDriverJs 설정하기 -[WebDriverJs](https://code.google.com/p/selenium/wiki/WebDriverJs)는 WebDriver를 사용하여 테스트 할 수 있도록 도와주는 node 패키지입니다. -다음 예제를 참고하세요. +[WebDriverJs](https://code.google.com/p/selenium/wiki/WebDriverJs)는 WebDriver를 +사용하여 테스트 할 수 있도록 도와주는 node 패키지입니다. 다음 예제를 참고하세요. ### 1. 크롬 드라이버 시작 @@ -35,8 +35,9 @@ $ npm install selenium-webdriver ### 3. 크롬 드라이버에 연결 -`selenium-webdriver`를 Electron과 같이 사용하는 방법은 기본적으로 upstream과 같습니다. -한가지 다른점이 있다면 수동으로 크롬 드라이버 연결에 대해 설정하고 Electron 실행파일의 위치를 전달합니다: +`selenium-webdriver`를 Electron과 같이 사용하는 방법은 기본적으로 upstream과 +같습니다. 한가지 다른점이 있다면 수동으로 크롬 드라이버 연결에 대해 설정하고 Electron +실행파일의 위치를 전달합니다: ```javascript const webdriver = require('selenium-webdriver'); @@ -67,7 +68,8 @@ driver.quit(); ## WebdriverIO 설정하기 -[WebdriverIO](http://webdriver.io/)는 웹 드라이버와 함께 테스트를 위해 제공되는 node 패키지입니다. +[WebdriverIO](http://webdriver.io/)는 웹 드라이버와 함께 테스트를 위해 제공되는 +node 패키지입니다. ### 1. 크롬 드라이버 시작 @@ -103,7 +105,7 @@ var options = { }; var client = webdriverio.remote(options); - + client .init() .url('http://google.com') @@ -117,10 +119,11 @@ client ## 작업 환경 -따로 Electron을 다시 빌드하지 않는 경우 간단히 어플리케이션을 Electron의 리소스 디렉터리에 -[배치](application-distribution.md)하여 바로 테스트 할 수 있습니다. +따로 Electron을 다시 빌드하지 않는 경우 간단히 어플리케이션을 Electron의 리소스 +디렉터리에 [배치](application-distribution.md)하여 바로 테스트 할 수 있습니다. -또한, Electron 바이너리의 명령줄 인수에 어플리케이션 폴더를 지정하는 방법으로 실행할 수도 있습니다. -이 방법을 사용하면 어플리케이션 폴더를 Electron의 `resource` 디렉터리로 복사하는 불필요한 과정을 생략할 수 있습니다. +또한, Electron 바이너리의 명령줄 인수에 어플리케이션 폴더를 지정하는 방법으로 실행할 +수도 있습니다. 이 방법을 사용하면 어플리케이션 폴더를 Electron의 `resource` +디렉터리로 복사하는 불필요한 과정을 생략할 수 있습니다. [chrome-driver]: https://sites.google.com/a/chromium.org/chromedriver/ From 65c823407dbd792e4227222b83c110422a1fc179 Mon Sep 17 00:00:00 2001 From: Ben Gotow Date: Thu, 19 Nov 2015 10:04:28 -0800 Subject: [PATCH 243/249] Address feedback --- docs/api/browser-window.md | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/docs/api/browser-window.md b/docs/api/browser-window.md index a78531277e9e..46b7c96ae594 100644 --- a/docs/api/browser-window.md +++ b/docs/api/browser-window.md @@ -68,12 +68,14 @@ It creates a new `BrowserWindow` with native properties as set by the `options`. * `transparent` Boolean - Makes the window [transparent](frameless-window.md). * `type` String - Specifies the type of the window, which applies additional platform-specific properties. - - On Linux, possible types are `desktop`, `dock`, `toolbar`, `splash`, `notification`. - - On Mac OS X: - - `textured`: Adds metal gradient appearance (NSTexturedBackgroundWindowMask) - - `desktop`: Places the window at the desktop background window level (kCGDesktopWindowLevel - 1). - Note that the window will not receive focus, keyboard or mouse events, but - you can use `globalShortcut` to receive input sparingly. + * On Linux, possible types are `desktop`, `dock`, `toolbar`, `splash`, + `notification`. + * On OS X, possible types are `desktop`, `textured`. The `textured` type adds + metal gradient appearance (NSTexturedBackgroundWindowMask). The `desktop` + type places the window at the desktop background window level + (kCGDesktopWindowLevel - 1). Note that desktop window will not receive focus, + keyboard or mouse events, but you can use `globalShortcut` to receive input + sparingly. * `titleBarStyle` String, OS X - specifies the style of window title bar. This option is supported on OS X 10.10 Yosemite and newer. There are three possible values: From 962134c6126330d1d3b2c5a5362e9fc8e7c2c32f Mon Sep 17 00:00:00 2001 From: Plusb Preco Date: Fri, 20 Nov 2015 04:46:05 +0900 Subject: [PATCH 244/249] Cleanup docs * Adjust line wrap to 80 * Fix typos * Improve grammar --- docs-translations/ko-KR/api/accelerator.md | 5 +- docs-translations/ko-KR/api/app.md | 123 ++++++---- docs-translations/ko-KR/api/auto-updater.md | 22 +- docs-translations/ko-KR/api/browser-window.md | 213 +++++++++++------- .../ko-KR/api/chrome-command-line-switches.md | 69 +++--- docs-translations/ko-KR/api/clipboard.md | 9 +- .../ko-KR/api/content-tracing.md | 66 +++--- docs-translations/ko-KR/api/crash-reporter.md | 12 +- docs-translations/ko-KR/api/dialog.md | 83 ++++--- docs-translations/ko-KR/api/download-item.md | 23 +- docs-translations/ko-KR/api/file-object.md | 6 +- .../ko-KR/api/frameless-window.md | 68 +++--- .../ko-KR/api/global-shortcut.md | 16 +- docs-translations/ko-KR/api/ipc-main.md | 13 +- docs-translations/ko-KR/api/ipc-renderer.md | 23 +- docs-translations/ko-KR/api/menu-item.md | 24 +- docs-translations/ko-KR/api/menu.md | 77 ++++--- docs-translations/ko-KR/api/native-image.md | 30 ++- docs-translations/ko-KR/api/power-monitor.md | 5 +- .../ko-KR/api/power-save-blocker.md | 34 ++- docs-translations/ko-KR/api/process.md | 15 +- docs-translations/ko-KR/api/protocol.md | 59 +++-- docs-translations/ko-KR/api/remote.md | 80 ++++--- docs-translations/ko-KR/api/screen.md | 8 +- docs-translations/ko-KR/api/session.md | 74 +++--- docs-translations/ko-KR/api/shell.md | 5 +- docs-translations/ko-KR/api/synopsis.md | 34 +-- docs-translations/ko-KR/api/tray.md | 17 +- docs-translations/ko-KR/api/web-contents.md | 119 +++++----- docs-translations/ko-KR/api/web-frame.md | 21 +- docs-translations/ko-KR/api/web-view-tag.md | 101 +++++---- docs-translations/ko-KR/api/window-open.md | 27 ++- .../development/setting-up-symbol-server.md | 2 +- .../ko-KR/tutorial/application-packaging.md | 4 +- .../tutorial/using-selenium-and-webdriver.md | 2 +- 35 files changed, 896 insertions(+), 593 deletions(-) diff --git a/docs-translations/ko-KR/api/accelerator.md b/docs-translations/ko-KR/api/accelerator.md index 9e72543a4cc6..99b549bbb70d 100644 --- a/docs-translations/ko-KR/api/accelerator.md +++ b/docs-translations/ko-KR/api/accelerator.md @@ -10,8 +10,9 @@ Accelerator는 키보드 단축키를 표현하는 문자열입니다, 여러 ## 플랫폼에 관련하여 주의할 점 -Linux와 Windows에서는 `Command`키가 없으므로 작동하지 않습니다. 대신에 `CommandOrControl`을 -사용하면 OS X의 `Command`와 Linux, Windows의 `Control` 모두 지원할 수 있습니다. +Linux와 Windows에서는 `Command`키가 없으므로 작동하지 않습니다. 대신에 +`CommandOrControl`을 사용하면 OS X의 `Command`와 Linux, Windows의 `Control` 모두 +지원할 수 있습니다. `Super`키는 Windows와 Linux 에서는 `윈도우`키를, OS X에서는 `Cmd`키로 맵핑됩니다. diff --git a/docs-translations/ko-KR/api/app.md b/docs-translations/ko-KR/api/app.md index 51e88c534ff4..8a6914a80fbc 100644 --- a/docs-translations/ko-KR/api/app.md +++ b/docs-translations/ko-KR/api/app.md @@ -18,9 +18,11 @@ app.on('window-all-closed', function() { ### Event: 'will-finish-launching' 어플리케이션이 기본적인 시작 준비를 마치면 발생하는 이벤트입니다. -Windows, Linux 운영체제에서의 `will-finish-launching` 이벤트는 `ready` 이벤트와 동일합니다. -OS X에서의 이벤트는 `NSApplication`의 `applicationWillFinishLaunching`에 대한 알림으로 표현됩니다. -대개 이곳에서 `open-file`과 `open-url` 이벤트 리스너를 설정하고 crash reporter와 auto updater를 시작합니다. +Windows, Linux 운영체제에서의 `will-finish-launching` 이벤트는 `ready` 이벤트와 +동일합니다. OS X에서의 이벤트는 `NSApplication`의 +`applicationWillFinishLaunching`에 대한 알림으로 표현됩니다. 대개 이곳에서 +`open-file`과 `open-url` 이벤트 리스너를 설정하고 crash reporter와 auto updater를 +시작합니다. 대부분의 경우, 모든 것을 `ready` 이벤트 핸들러로 해결해야 합니다. @@ -35,10 +37,12 @@ Electron이 초기화를 끝냈을 때 발생하는 이벤트입니다. 이 이벤트는 어플리케이션이 완전히 종료되지 않았을 때만 발생합니다. 만약 사용자가 `Cmd + Q`를 입력했거나 개발자가 `app.quit()`를 호출했다면, Electron은 먼저 모든 윈도우 창의 종료를 시도하고 `will-quit` 이벤트를 발생시킵니다. -그리고 `will-quit` 이벤트가 발생했을 땐 `window-all-closed` 이벤트가 발생하지 않습니다. +그리고 `will-quit` 이벤트가 발생했을 땐 `window-all-closed` 이벤트가 발생하지 +않습니다. -**역주:** 이 이벤트는 말 그대로 현재 어플리케이션에서 윈도우 창만 완전히 종료됬을 때 발생하는 이벤트 입니다. - 따라서 어플리케이션을 완전히 종료하려면 이 이벤트에서 `app.quit()`를 호출해 주어야 합니다. +**역주:** 이 이벤트는 말 그대로 현재 어플리케이션에서 윈도우 창만 완전히 종료됬을 때 +발생하는 이벤트 입니다. 따라서 어플리케이션을 완전히 종료하려면 이 이벤트에서 +`app.quit()`를 호출해 주어야 합니다. ### Event: 'before-quit' @@ -59,7 +63,8 @@ Returns: 모든 윈도우 창들이 종료되고 어플리케이션이 종료되기 시작할 때 발생하는 이벤트 입니다. `event.preventDefault()` 호출을 통해 어플리케이션의 종료를 방지할 수 있습니다. -`will-quit` 와 `window-all-closed` 이벤트의 차이점을 확인하려면 `window-all-close` 이벤트의 설명을 참고하세요. +`will-quit` 와 `window-all-closed` 이벤트의 차이점을 확인하려면 `window-all-close` +이벤트의 설명을 참고하세요. ### Event: 'quit' @@ -74,9 +79,11 @@ Returns: 사용자가 어플리케이션을 통해 파일을 열고자 할 때 발생하는 이벤트입니다. -`open-file` 이벤트는 보통 어플리케이션이 열려 있을 때 OS가 파일을 열기 위해 어플리케이션을 재사용할 때 발생합니다. -이 이벤트는 파일을 dock에 떨어트릴 때, 어플리케이션이 실행되기 전에도 발생합니다. -따라서 이 이벤트를 제대로 처리하려면 `open-file` 이벤트 핸들러를 어플리케이션이 시작하기 전에 등록해 놓았는지 확실히 확인해야 합니다. (`ready` 이벤트가 발생하기 전에) +`open-file` 이벤트는 보통 어플리케이션이 열려 있을 때 OS가 파일을 열기 위해 +어플리케이션을 재사용할 때 발생합니다. 이 이벤트는 파일을 dock에 떨어트릴 때, +어플리케이션이 실행되기 전에도 발생합니다. 따라서 이 이벤트를 제대로 처리하려면 +`open-file` 이벤트 핸들러를 어플리케이션이 시작하기 전에 등록해 놓았는지 확실히 +확인해야 합니다. (`ready` 이벤트가 발생하기 전에) 이 이벤트를 처리할 땐 반드시 `event.preventDefault()`를 호출해야 합니다. @@ -148,7 +155,8 @@ Returns: `url`은 클라이언트 인증서를 요청하는 탐색 항목에 해당합니다. 그리고 `callback`은 목록에서 필터링된 항목과 함께 호출될 필요가 있습니다. -이 이벤트에서의 `event.preventDefault()` 호출은 초기 인증 때 저장된 데이터를 사용하는 것을 막습니다. +이 이벤트에서의 `event.preventDefault()` 호출은 초기 인증 때 저장된 데이터를 사용하는 +것을 막습니다. ```javascript app.on('select-certificate', function(event, host, url, list, callback) { @@ -201,10 +209,12 @@ GPU가 작동하던 중 크래시가 일어났을 때 발생하는 이벤트입 ### `app.quit()` 모든 윈도우 창 종료를 시도합니다. `before-quit` 이벤트가 먼저 발생합니다. -모든 윈도우 창이 성공적으로 종료되면 `will-quit` 이벤트가 발생하고 기본 동작에 따라 어플리케이션이 종료됩니다. +모든 윈도우 창이 성공적으로 종료되면 `will-quit` 이벤트가 발생하고 기본 동작에 따라 +어플리케이션이 종료됩니다. 이 함수는 모든 `beforeunload`와 `unload` 이벤트 핸들러가 제대로 실행됨을 보장합니다. -`beforeunload` 이벤트 핸들러에서 `false`를 반환했을 때 윈도우 창 종료가 취소 될 수 있습니다. +`beforeunload` 이벤트 핸들러에서 `false`를 반환했을 때 윈도우 창 종료가 취소 될 수 +있습니다. ### `app.exit(exitCode)` @@ -212,7 +222,8 @@ GPU가 작동하던 중 크래시가 일어났을 때 발생하는 이벤트입 `exitCode`와 함께 어플리케이션을 즉시 종료합니다. -모든 윈도우 창은 사용자의 동의 여부에 상관없이 즉시 종료되며 `before-quit` 이벤트와 `will-quit` 이벤트가 발생하지 않습니다. +모든 윈도우 창은 사용자의 동의 여부에 상관없이 즉시 종료되며 `before-quit` 이벤트와 +`will-quit` 이벤트가 발생하지 않습니다. ### `app.getAppPath()` @@ -253,39 +264,43 @@ GPU가 작동하던 중 크래시가 일어났을 때 발생하는 이벤트입 * `path` String `name`에 대한 특정 디렉터리나 파일의 경로인 `path`를 재정의합니다. -만약 지정한 디렉터리의 경로가 존재하지 않으면 디렉터리가 이 메서드를 통해 새로 생성됩니다. -재정의에 실패했을 땐 `Error`를 반환합니다. +만약 지정한 디렉터리의 경로가 존재하지 않으면 디렉터리가 이 메서드를 통해 새로 +생성됩니다. 재정의에 실패했을 땐 `Error`를 반환합니다. 이 메서드는 `app.getPath`에 정의되어 있는 `name`의 경로만 재정의할 수 있습니다. 기본적으로, 웹 페이지의 쿠키와 캐시는 `userData` 디렉터리에 저장됩니다. -만약 이 위치를 변경하고자 한다면, 반드시 `app` 모듈의 `ready` 이벤트가 발생하기 전에 `userData` 경로를 재정의해야 합니다. +만약 이 위치를 변경하고자 한다면, 반드시 `app` 모듈의 `ready` 이벤트가 발생하기 전에 +`userData` 경로를 재정의해야 합니다. ### `app.getVersion()` 로드된 어플리케이션의 버전을 반환합니다. -만약 `package.json` 파일에서 어플리케이션의 버전을 찾을 수 없는 경우, 현재 번들 또는 실행 파일의 버전을 반환합니다. +만약 `package.json` 파일에서 어플리케이션의 버전을 찾을 수 없는 경우, 현재 번들 또는 +실행 파일의 버전을 반환합니다. ### `app.getName()` `package.json`에서 기술된 현재 어플리케이션의 이름을 반환합니다. -npm 모듈 규칙에 따라 대부분의 경우 `package.json`의 `name` 필드는 소문자 이름을 사용합니다. -하지만 Electron은 `name`대신 `productName` 필드를 주로 사용하기 때문에 반드시 이 필드도 같이 지정해야 합니다. -이 필드는 맨 앞글자가 대문자인 어플리케이션 전체 이름을 지정해야 합니다. +npm 모듈 규칙에 따라 대부분의 경우 `package.json`의 `name` 필드는 소문자 이름을 +사용합니다. 하지만 Electron은 `name`대신 `productName` 필드를 주로 사용하기 때문에 +반드시 이 필드도 같이 지정해야 합니다. 이 필드는 맨 앞글자가 대문자인 어플리케이션 +전체 이름을 지정해야 합니다. ### `app.getLocale()` -현재 어플리케이션의 [로케일](https://ko.wikipedia.org/wiki/%EB%A1%9C%EC%BC%80%EC%9D%BC)을 반환합니다. +현재 어플리케이션의 [로케일](https://ko.wikipedia.org/wiki/%EB%A1%9C%EC%BC%80%EC%9D%BC)을 +반환합니다. ### `app.resolveProxy(url, callback)` * `url` URL * `callback` Function -`url`의 프록시 정보를 해석합니다. -`callback`은 요청이 수행되었을 때 `callback(proxy)` 형태로 호출됩니다. +`url`의 프록시 정보를 해석합니다. `callback`은 요청이 수행되었을 때 +`callback(proxy)` 형태로 호출됩니다. ### `app.addRecentDocument(path)` _OS X_ _Windows_ @@ -293,8 +308,8 @@ npm 모듈 규칙에 따라 대부분의 경우 `package.json`의 `name` 필드 최근 문서 목록에 `path`를 추가합니다. -이 목록은 OS에 의해 관리됩니다. -최근 문서 목록은 Windows의 경우 작업 표시줄에서 찾을 수 있고, OS X의 경우 dock 메뉴에서 찾을 수 있습니다. +이 목록은 OS에 의해 관리됩니다. 최근 문서 목록은 Windows의 경우 작업 표시줄에서 찾을 +수 있고, OS X의 경우 dock 메뉴에서 찾을 수 있습니다. ### `app.clearRecentDocuments()` _OS X_ _Windows_ @@ -317,8 +332,9 @@ Windows에서 사용할 수 있는 JumpList의 [Tasks][tasks] 카테고리에 `t * `iconPath` String - JumpList에 표시될 아이콘의 절대 경로. 아이콘을 포함하고 있는 임의의 리소스 파일을 사용할 수 있습니다. 보통 어플리케이션의 아이콘을 그대로 사용하기 위해 `process.execPath`를 지정합니다. -* `iconIndex` Integer - 아이콘 파일의 인덱스. 만약 아이콘 파일이 두 개 이상의 아이콘을 가지고 있을 경우, - 사용할 아이콘의 인덱스를 이 옵션으로 지정해 주어야 합니다. 단, 아이콘을 하나만 포함하고 있는 경우 0을 지정하면 됩니다. +* `iconIndex` Integer - 아이콘 파일의 인덱스. 만약 아이콘 파일이 두 개 이상의 + 아이콘을 가지고 있을 경우, 사용할 아이콘의 인덱스를 이 옵션으로 지정해 주어야 합니다. + 단, 아이콘을 하나만 포함하고 있는 경우 0을 지정하면 됩니다. ### `app.allowNTLMCredentialsForAllDomains(allow)` @@ -326,33 +342,40 @@ Windows에서 사용할 수 있는 JumpList의 [Tasks][tasks] 카테고리에 `t 항상 동적으로 HTTP NTLM 또는 Negotiate 인증에 자격 증명을 보낼 것인지 설정합니다. -기본적으로 Electron은 "로컬 인터넷" 사이트 URL에서 NTLM/Kerberos 자격 증명만을 보냅니다. (같은 도메인 내에서) -그러나 기업 네트워크가 잘못 구성된 경우 종종 작업에 실패할 수 있습니다. -이때 이 메서드를 통해 모든 URL을 허용할 수 있습니다. +기본적으로 Electron은 "로컬 인터넷" 사이트 URL에서 NTLM/Kerberos 자격 증명만을 +보냅니다. (같은 도메인 내에서) 그러나 기업 네트워크가 잘못 구성된 경우 종종 작업에 +실패할 수 있습니다. 이때 이 메서드를 통해 모든 URL을 허용할 수 있습니다. ### `app.makeSingleInstance(callback)` * `callback` Function 현재 어플리케이션을 **Single Instance Application**으로 만들어줍니다. -이 메서드는 어플리케이션이 여러 번 실행됐을 때 다중 인스턴스가 생성되는 대신 한 개의 주 인스턴스만 유지되도록 만들 수 있습니다. -이때 중복 생성된 인스턴스는 주 인스턴스에 신호를 보내고 종료됩니다. +이 메서드는 어플리케이션이 여러 번 실행됐을 때 다중 인스턴스가 생성되는 대신 한 개의 +주 인스턴스만 유지되도록 만들 수 있습니다. 이때 중복 생성된 인스턴스는 주 인스턴스에 +신호를 보내고 종료됩니다. -`callback`은 주 인스턴스가 생성된 이후 또 다른 인스턴스가 생성됐을 때 `callback(argv, workingDirectory)` 형식으로 호출됩니다. -`argv`는 두 번째 인스턴스의 명령줄 인수이며 `workingDirectory`는 현재 작업중인 디렉터리입니다. -보통 대부분의 어플리케이션은 이러한 콜백이 호출될 때 주 윈도우 창을 포커스하고 최소화되어있으면 창 복구를 실행합니다. +`callback`은 주 인스턴스가 생성된 이후 또 다른 인스턴스가 생성됐을 때 +`callback(argv, workingDirectory)` 형식으로 호출됩니다. `argv`는 두 번째 인스턴스의 +명령줄 인수이며 `workingDirectory`는 현재 작업중인 디렉터리입니다. 보통 대부분의 +어플리케이션은 이러한 콜백이 호출될 때 주 윈도우 창을 포커스하고 최소화되어있으면 창 +복구를 실행합니다. `callback`은 `app`의 `ready` 이벤트가 발생한 후 실행됨을 보장합니다. -이 메서드는 현재 실행된 어플리케이션이 주 인스턴스인 경우 `false`를 반환하고 어플리케이션의 로드가 계속 진행 되도록 합니다. -그리고 두 번째 중복된 인스턴스 생성인 경우 `true`를 반환합니다. (다른 인스턴스에 인수가 전달됬을 때) -이 불리언 값을 통해 중복 생성된 인스턴스는 즉시 종료시켜야 합니다. +이 메서드는 현재 실행된 어플리케이션이 주 인스턴스인 경우 `false`를 반환하고 +어플리케이션의 로드가 계속 진행 되도록 합니다. 그리고 두 번째 중복된 인스턴스 생성인 +경우 `true`를 반환합니다. (다른 인스턴스에 인수가 전달됬을 때) 이 불리언 값을 통해 +중복 생성된 인스턴스는 즉시 종료시켜야 합니다. -OS X에선 사용자가 Finder에서 어플리케이션의 두 번째 인스턴스를 열려고 했을 때 자동으로 **Single Instance**화 하고 `open-file`과 `open-url` 이벤트를 발생시킵니다. -그러나 사용자가 어플리케이션을 CLI 터미널에서 실행하면 운영체제 시스템의 싱글 인스턴스 메커니즘이 무시되며 그대로 중복 실행됩니다. -따라서 OS X에서도 이 메서드를 통해 확실히 중복 실행을 방지하는 것이 좋습니다. +OS X에선 사용자가 Finder에서 어플리케이션의 두 번째 인스턴스를 열려고 했을 때 자동으로 +**Single Instance**화 하고 `open-file`과 `open-url` 이벤트를 발생시킵니다. 그러나 +사용자가 어플리케이션을 CLI 터미널에서 실행하면 운영체제 시스템의 싱글 인스턴스 +메커니즘이 무시되며 그대로 중복 실행됩니다. 따라서 OS X에서도 이 메서드를 통해 확실히 +중복 실행을 방지하는 것이 좋습니다. -다음 예제는 두 번째 인스턴스가 생성되었을 때 중복된 인스턴스를 종료하고 주 어플리케이션 인스턴스의 윈도우 창을 활성화 시키는 예제입니다: +다음 예제는 두 번째 인스턴스가 생성되었을 때 중복된 인스턴스를 종료하고 주 어플리케이션 +인스턴스의 윈도우 창을 활성화 시키는 예제입니다: ```javascript var myWindow = null; @@ -386,8 +409,8 @@ app.on('ready', function() { Chrominum의 명령줄에 스위치를 추가합니다. `value`는 추가적인 값을 뜻하며 옵션입니다. -**참고:** 이 메서드는 `process.argv`에 영향을 주지 않습니다. - 개발자들은 보통 Chrominum의 로우 레벨 수준의 동작을 제어하기 위해 주로 사용합니다. +**참고:** 이 메서드는 `process.argv`에 영향을 주지 않습니다. 개발자들은 보통 +Chrominum의 로우 레벨 수준의 동작을 제어하기 위해 주로 사용합니다. ### `app.commandLine.appendArgument(value)` @@ -397,12 +420,14 @@ Chrominum의 명령줄에 인수를 추가합니다. 인수는 올바르게 인 ### `app.dock.bounce([type])` _OS X_ -* `type` String (optional) - `critical` 또는 `informational`을 지정할 수 있습니다. 기본값은 `informational` 입니다. +* `type` String (optional) - `critical` 또는 `informational`을 지정할 수 있습니다. + 기본값은 `informational` 입니다. -`critical`이 전달되면 dock 아이콘이 어플리케이션이 활성화되거나 요청이 중지되기 전까지 통통 튑니다. +`critical`이 전달되면 dock 아이콘이 어플리케이션이 활성화되거나 요청이 중지되기 전까지 +통통 튑니다. -`informational`이 전달되면 dock 아이콘이 1초만 통통 튑니다. -하지만 어플리케이션이 활성화되거나 요청이 중지되기 전까지 요청은 계속 활성화로 유지 됩니다. +`informational`이 전달되면 dock 아이콘이 1초만 통통 튑니다. 하지만 어플리케이션이 +활성화되거나 요청이 중지되기 전까지 요청은 계속 활성화로 유지 됩니다. 또한 요청을 취소할 때 사용할 수 있는 ID를 반환합니다. diff --git a/docs-translations/ko-KR/api/auto-updater.md b/docs-translations/ko-KR/api/auto-updater.md index 1b0d9c032ccc..04593ee57600 100644 --- a/docs-translations/ko-KR/api/auto-updater.md +++ b/docs-translations/ko-KR/api/auto-updater.md @@ -4,7 +4,8 @@ ## 플랫폼별 참고 사항 -`autoUpdater`는 기본적으로 모든 플랫폼에 대해 같은 API를 제공하지만, 여전히 플랫폼별로 약간씩 다른 점이 있습니다. +`autoUpdater`는 기본적으로 모든 플랫폼에 대해 같은 API를 제공하지만, 여전히 플랫폼별로 +약간씩 다른 점이 있습니다. ### OS X @@ -14,16 +15,18 @@ OS X에선 `auto-updater` 모듈이 [Squirrel.Mac][squirrel-mac]를 기반으로 ### Windows -Windows에선 `auto-updater` 모듈을 사용하기 전에 어플리케이션을 사용자의 장치에 설치해야 합니다. -[grunt-electron-installer][installer]를 사용하여 어플리케이션 인스톨러를 만드는 것을 권장합니다. +Windows에선 `auto-updater` 모듈을 사용하기 전에 어플리케이션을 사용자의 장치에 +설치해야 합니다. [grunt-electron-installer][installer]를 사용하여 어플리케이션 +인스톨러를 만드는 것을 권장합니다. Squirrel로 생성된 인스톨러는 [Application User Model ID][app-user-model-id]와 함께 -`com.squirrel.PACKAGE_ID.YOUR_EXE_WITHOUT_DOT_EXE`으로 형식화된 바로가기 아이콘을 생성합니다. -`com.squirrel.slack.Slack` 과 `com.squirrel.code.Code`가 그 예시입니다. -`app.setAppUserModelId` API를 통해 어플리케이션 ID를 동일하게 유지해야 합니다. -그렇지 않으면 Windows 작업 표시줄에 어플리케이션을 고정할 때 제대로 적용되지 않을 수 있습니다. +`com.squirrel.PACKAGE_ID.YOUR_EXE_WITHOUT_DOT_EXE`으로 형식화된 바로가기 아이콘을 +생성합니다. `com.squirrel.slack.Slack` 과 `com.squirrel.code.Code`가 그 예시입니다. +`app.setAppUserModelId` API를 통해 어플리케이션 ID를 동일하게 유지해야 합니다. 그렇지 +않으면 Windows 작업 표시줄에 어플리케이션을 고정할 때 제대로 적용되지 않을 수 있습니다. -서버 사이드 요구 사항 또한 OS X와 다르게 적용됩니다. 자세한 내용은 [Squirrel.Windows][squirrel-windows]를 참고하세요. +서버 사이드 요구 사항 또한 OS X와 다르게 적용됩니다. 자세한 내용은 +[Squirrel.Windows][squirrel-windows]를 참고하세요. ### Linux @@ -78,7 +81,8 @@ Returns: ### `autoUpdater.checkForUpdates()` -서버에 새로운 업데이트가 있는지 요청을 보내 확인합니다. API를 사용하기 전에 `setFeedURL`를 호출해야 합니다. +서버에 새로운 업데이트가 있는지 요청을 보내 확인합니다. API를 사용하기 전에 +`setFeedURL`를 호출해야 합니다. ### `autoUpdater.quitAndInstall()` diff --git a/docs-translations/ko-KR/api/browser-window.md b/docs-translations/ko-KR/api/browser-window.md index 02ae9eb66049..65c550566802 100644 --- a/docs-translations/ko-KR/api/browser-window.md +++ b/docs-translations/ko-KR/api/browser-window.md @@ -16,13 +16,16 @@ win.loadURL('https://github.com'); win.show(); ``` -또한 [Frameless Window](frameless-window.md) API를 사용하여 창 테두리가 없는 윈도우 창을 생성할 수 있습니다. +또한 [Frameless Window](frameless-window.md) API를 사용하여 창 테두리가 없는 윈도우 +창을 생성할 수 있습니다. ## Class: BrowserWindow -`BrowserWindow`는 [EventEmitter](http://nodejs.org/api/events.html#events_class_events_eventemitter)를 상속받은 클래스 입니다. +`BrowserWindow`는 [EventEmitter](http://nodejs.org/api/events.html#events_class_events_eventemitter)를 +상속받은 클래스 입니다. -`BrowserWindow`는 `options`를 통해 네이티브 속성을 포함한 새로운 윈도우 창을 생성합니다. +`BrowserWindow`는 `options`를 통해 네이티브 속성을 포함한 새로운 윈도우 창을 +생성합니다. ### `new BrowserWindow(options)` @@ -33,7 +36,8 @@ win.show(); * `x` Integer - 화면을 기준으로 창 좌측을 오프셋 한 위치. * `y` Integer - 화면을 기준으로 창 상단을 오프셋 한 위치. * `useContentSize` Boolean - `width`와 `height`를 웹 페이지의 크기로 사용합니다. - 이 속성을 사용하면 웹 페이지의 크기에 윈도우 프레임 크기가 추가되므로 실제 창은 조금 더 커질 수 있습니다. + 이 속성을 사용하면 웹 페이지의 크기에 윈도우 프레임 크기가 추가되므로 실제 창은 조금 + 더 커질 수 있습니다. * `center` Boolean - 윈도우 창을 화면 정 중앙에 위치시킵니다. * `minWidth` Integer - 윈도우 창의 최소 가로 너비. * `minHeight` Integer - 윈도우 창의 최소 세로 높이. @@ -46,42 +50,61 @@ win.show(); * `skipTaskbar` Boolean - 작업표시줄 어플리케이션 아이콘 표시 여부. * `kiosk` Boolean - Kiosk(키오스크) 모드. * `title` String - 기본 윈도우 창 제목. -* `icon` [NativeImage](native-image.md) - 윈도우 아이콘, 생략하면 실행 파일의 아이콘이 대신 사용됩니다. +* `icon` [NativeImage](native-image.md) - 윈도우 아이콘, 생략하면 실행 파일의 + 아이콘이 대신 사용됩니다. * `show` Boolean - 윈도우가 생성되면 보여줄지 여부. -* `frame` Boolean - `false`로 지정하면 창을 [Frameless Window](frameless-window.md) 형태로 생성합니다. -* `acceptFirstMouse` Boolean - 윈도우가 비활성화 상태일 때 내부 컨텐츠 클릭 시 활성화 되는 동시에 단일 mouse-down 이벤트를 발생시킬지 여부. +* `frame` Boolean - `false`로 지정하면 창을 [Frameless Window](frameless-window.md) + 형태로 생성합니다. +* `acceptFirstMouse` Boolean - 윈도우가 비활성화 상태일 때 내부 컨텐츠 클릭 시 + 활성화 되는 동시에 단일 mouse-down 이벤트를 발생시킬지 여부. * `disableAutoHideCursor` Boolean - 파이핑중 자동으로 커서를 숨길지 여부. -* `autoHideMenuBar` Boolean - `Alt`를 누르지 않는 한 어플리케이션 메뉴바를 숨길지 여부. -* `enableLargerThanScreen` Boolean - 윈도우 창 크기가 화면 크기보다 크게 재조정 될 수 있는지 여부. -* `backgroundColor` String - 16진수로 표현된 윈도우의 배경 색. `#66CD00` 또는 `#FFF`가 사용될 수 있습니다. +* `autoHideMenuBar` Boolean - `Alt`를 누르지 않는 한 어플리케이션 메뉴바를 숨길지 + 여부. +* `enableLargerThanScreen` Boolean - 윈도우 창 크기가 화면 크기보다 크게 재조정 될 + 수 있는지 여부. +* `backgroundColor` String - 16진수로 표현된 윈도우의 배경 색. `#66CD00` 또는 + `#FFF`가 사용될 수 있습니다. 이 속성은 Linux와 Windows에만 구현되어 있습니다. -* `darkTheme` Boolean - 설정에 상관 없이 무조건 어두운 윈도우 테마를 사용합니다. 몇몇 GTK+3 데스크톱 환경에서만 작동합니다. +* `darkTheme` Boolean - 설정에 상관 없이 무조건 어두운 윈도우 테마를 사용합니다. + 몇몇 GTK+3 데스크톱 환경에서만 작동합니다. * `transparent` Boolean - 윈도우 창을 [투명화](frameless-window.md)합니다. * `type` String - 윈도우 창 종류를 지정합니다. - 사용할 수 있는 창 종류는 `desktop`, `dock`, `toolbar`, `splash`, `notification`와 같습니다. - 이 속성은 Linux에서만 작동합니다. -* `standardWindow` Boolean - OS X의 표준 윈도우를 텍스쳐 윈도우 대신 사용합니다. 기본 값은 `true`입니다. -* `titleBarStyle` String, OS X - 윈도우 타이틀 바 스타일을 지정합니다. 이 속성은 OS X 10.10 Yosemite 이후 버전만 지원합니다. - 다음 3가지 종류의 값을 사용할 수 있습니다: + 사용할 수 있는 창 종류는 `desktop`, `dock`, `toolbar`, `splash`, + `notification`와 같습니다. 이 속성은 Linux에서만 작동합니다. +* `standardWindow` Boolean - OS X의 표준 윈도우를 텍스쳐 윈도우 대신 사용합니다. + 기본 값은 `true`입니다. +* `titleBarStyle` String, OS X - 윈도우 타이틀 바 스타일을 지정합니다. 이 속성은 + OS X 10.10 Yosemite 이후 버전만 지원합니다. 다음 3가지 종류의 값을 사용할 수 + 있습니다: * `default` 또는 미지정: 표준 Mac 회색 불투명 스타일을 사용합니다. * `hidden`: 타이틀 바를 숨기고 컨텐츠 전체를 윈도우 크기에 맞춥니다. 타이틀 바는 없어지지만 표준 창 컨트롤 ("신호등 버튼")은 왼쪽 상단에 유지됩니다. - * `hidden-inset`: `hidden` 타이틀 바 속성과 함께 신호등 버튼이 윈도우 모서리로부터 약간 더 안쪽으로 들어가도록합니다. -* `webPreferences` Object - 웹 페이지 기능을 설정합니다. 사용할 수 있는 속성은 다음과 같습니다: + * `hidden-inset`: `hidden` 타이틀 바 속성과 함께 신호등 버튼이 윈도우 모서리로부터 + 약간 더 안쪽으로 들어가도록합니다. +* `webPreferences` Object - 웹 페이지 기능을 설정합니다. 사용할 수 있는 속성은 + 다음과 같습니다: * `nodeIntegration` Boolean - node(node.js) 통합 여부. 기본값은 `true`입니다. - * `preload` String - 스크립트를 지정하면 페이지 내의 다른 스크립트가 작동하기 전에 로드됩니다. - 여기서 지정한 스크립트는 페이지의 node 통합 활성화 여부에 상관없이 언제나 모든 node API에 접근할 수 있습니다. - 그리고 `preload` 스크립트의 경로는 절대 경로로 지정해야 합니다. + * `preload` String - 스크립트를 지정하면 페이지 내의 다른 스크립트가 작동하기 전에 + 로드됩니다. 여기서 지정한 스크립트는 페이지의 node 통합 활성화 여부에 상관없이 + 언제나 모든 node API에 접근할 수 있습니다. 그리고 `preload` 스크립트의 경로는 + 절대 경로로 지정해야 합니다. * `partition` String - 페이지에서 사용할 세션을 지정합니다. 만약 `partition`이 - `persist:`로 시작하면 페이지는 지속성 세션을 사용하며 다른 모든 앱 내의 페이지에서 같은 `partition`을 사용할 수 있습니다. - 만약 `persist:` 접두어로 시작하지 않으면 페이지는 인-메모리 세션을 사용합니다. 여러 페이지에서 같은 `partition`을 지정하면 - 같은 세션을 공유할 수 있습니다. `partition`을 지정하지 않으면 어플리케이션의 기본 세션이 사용됩니다. - * `zoomFactor` Number - 페이지의 기본 줌 값을 지정합니다. 예를 들어 `300%`를 표현하려면 `3.0`으로 지정합니다. + `persist:`로 시작하면 페이지는 지속성 세션을 사용하며 다른 모든 앱 내의 + 페이지에서 같은 `partition`을 사용할 수 있습니다. 만약 `persist:` 접두어로 + 시작하지 않으면 페이지는 인-메모리 세션을 사용합니다. 여러 페이지에서 같은 + `partition`을 지정하면 같은 세션을 공유할 수 있습니다. `partition`을 지정하지 + 않으면 어플리케이션의 기본 세션이 사용됩니다. + * `zoomFactor` Number - 페이지의 기본 줌 값을 지정합니다. 예를 들어 `300%`를 + 표현하려면 `3.0`으로 지정합니다. * `javascript` Boolean - * `webSecurity` Boolean - `false`로 지정하면 same-origin 정책을 비활성화합니다. (이 속성은 보통 사람에 의해 웹 사이트를 테스트할 때 사용합니다) - 그리고 `allowDisplayingInsecureContent`와 `allowRunningInsecureContent`이 사용자로부터 `true`로 지정되지 않은 경우 `true`로 지정합니다. - * `allowDisplayingInsecureContent` Boolean - https 페이지에서 http URL에서 로드한 이미지 같은 리소스를 표시할 수 있도록 허용합니다. - * `allowRunningInsecureContent` Boolean - https 페이지에서 http URL에서 로드한 JavaScript와 CSS 또는 플러그인을 실행시킬 수 있도록 허용합니다. + * `webSecurity` Boolean - `false`로 지정하면 same-origin 정책을 비활성화합니다. + (이 속성은 보통 사람에 의해 웹 사이트를 테스트할 때 사용합니다) 그리고 + `allowDisplayingInsecureContent`와 `allowRunningInsecureContent`이 + 사용자로부터 `true`로 지정되지 않은 경우 `true`로 지정합니다. + * `allowDisplayingInsecureContent` Boolean - https 페이지에서 http URL에서 + 로드한 이미지 같은 리소스를 표시할 수 있도록 허용합니다. + * `allowRunningInsecureContent` Boolean - https 페이지에서 http URL에서 로드한 + JavaScript와 CSS 또는 플러그인을 실행시킬 수 있도록 허용합니다. * `images` Boolean * `java` Boolean * `textAreasAreResizable` Boolean @@ -93,9 +116,11 @@ win.show(); * `overlayScrollbars` Boolean * `overlayFullscreenVideo` Boolean * `sharedWorker` Boolean - * `directWrite` Boolean - Windows에서 폰트 랜더링을 위해 DirectWrite를 사용하는지를 지정합니다. - * `pageVisibility` Boolean - 현재 윈도우의 가시성을 반영하는 대신 페이지가 visible 또는 hidden 중 지정된 상태를 계속 유지하도록 합니다. - 이 속성을 `true`로 지정하면 DOM 타이머의 스로틀링을 방지할 수 있습니다. + * `directWrite` Boolean - Windows에서 폰트 랜더링을 위해 DirectWrite를 + 사용하는지를 지정합니다. + * `pageVisibility` Boolean - 현재 윈도우의 가시성을 반영하는 대신 페이지가 + visible 또는 hidden 중 지정된 상태를 계속 유지하도록 합니다. 이 속성을 `true`로 + 지정하면 DOM 타이머의 스로틀링을 방지할 수 있습니다. ## Events @@ -109,8 +134,8 @@ Returns: * `event` Event -문서의 제목이 변경될 때 발생하는 이벤트 입니다. -`event.preventDefault()`를 호출하여 네이티브 윈도우의 제목이 변경되는 것을 방지할 수 있습니다. +문서의 제목이 변경될 때 발생하는 이벤트 입니다. `event.preventDefault()`를 호출하여 +네이티브 윈도우의 제목이 변경되는 것을 방지할 수 있습니다. ### Event: 'close' @@ -132,18 +157,19 @@ Electron에선 빈 문자열 또는 `false`를 전달할 경우 윈도우 종료 window.onbeforeunload = function(e) { console.log('I do not want to be closed'); - // 반드시 문자열을 반환해야 하고 사용자에게 페이지 언로드에 대한 확인 창을 보여주는 보통의 브라우저와는 달리 - // Electron은 개발자에게 더 많은 옵션을 제공합니다. + // 반드시 문자열을 반환해야 하고 사용자에게 페이지 언로드에 대한 확인 창을 보여주는 + // 보통의 브라우저와는 달리 Electron은 개발자에게 더 많은 옵션을 제공합니다. // 빈 문자열을 반환하거나 false를 반환하면 페이지 언로드를 방지합니다. - // 또한 dialog API를 통해 사용자에게 어플리케이션을 종료할지에 대한 확인 창을 보여줄 수도 있습니다. + // 또한 dialog API를 통해 사용자에게 어플리케이션을 종료할지에 대한 확인 창을 + // 보여줄 수도 있습니다. e.returnValue = false; }; ``` ### Event: 'closed' -윈도우 종료가 완료된 경우 발생하는 이벤트입니다. -이 이벤트가 발생했을 경우 반드시 윈도우 창의 레퍼런스가 더 이상 사용되지 않도록 제거해야 합니다. +윈도우 종료가 완료된 경우 발생하는 이벤트입니다. 이 이벤트가 발생했을 경우 반드시 +윈도우 창의 레퍼런스가 더 이상 사용되지 않도록 제거해야 합니다. ### Event: 'unresponsive' @@ -209,9 +235,10 @@ __참고__: OS X에선 이 이벤트가 그저 `moved` 이벤트의 별칭(alias ### Event: 'app-command' _Windows_ -[App Command](https://msdn.microsoft.com/en-us/library/windows/desktop/ms646275(v=vs.85).aspx)가 호출됐을 때 발생하는 이벤트입니다. -이 이벤트는 일반적으로 키보드 미디어 키 또는 브라우저 커맨드(기본 동작 키)에 관련되어 있습니다. -예를 들어 Windows에서 작동하는 몇몇 마우스는 "뒤로가기" 같은 동작을 포함하고 있습니다. +[App Command](https://msdn.microsoft.com/en-us/library/windows/desktop/ms646275(v=vs.85).aspx)가 +호출됐을 때 발생하는 이벤트입니다. 이 이벤트는 일반적으로 키보드 미디어 키 또는 +브라우저 커맨드(기본 동작 키)에 관련되어 있습니다. 예를 들어 Windows에서 작동하는 +몇몇 마우스는 "뒤로가기" 같은 동작을 포함하고 있습니다. ```javascript someWindow.on('app-command', function(e, cmd) { @@ -272,9 +299,11 @@ var win = new BrowserWindow({ width: 800, height: 600 }); ### `win.webContents` -윈도우의 `WebContents` 객체입니다. 모든 웹 페이지와 관련된 이벤트와 작업이 이 객체를 통해 수행됩니다. +윈도우의 `WebContents` 객체입니다. 모든 웹 페이지와 관련된 이벤트와 작업이 이 객체를 +통해 수행됩니다. -메서드나 이벤트에 대한 자세한 내용은 [`webContents` 문서](web-contents.md)를 참고하세요. +메서드나 이벤트에 대한 자세한 내용은 [`webContents` 문서](web-contents.md)를 +참고하세요. ### `win.id` @@ -288,15 +317,17 @@ var win = new BrowserWindow({ width: 800, height: 600 }); ### `win.destroy()` -윈도우를 강제로 닫습니다. 웹 페이지의 `unload` 와 `beforeunload` 이벤트는 일어나지 않습니다. -또한 이 윈도우의 `close`도 일어나지 않습니다. 하지만 `closed` 이벤트는 반드시 발생함을 보장합니다. +윈도우를 강제로 닫습니다. 웹 페이지의 `unload` 와 `beforeunload` 이벤트는 일어나지 +않습니다. 또한 이 윈도우의 `close`도 일어나지 않습니다. 하지만 `closed` 이벤트는 +반드시 발생함을 보장합니다. 이 메서드는 렌더러 프로세스가 예기치 않게 크래시가 일어났을 경우에만 사용해야 합니다. ### `win.close()` -윈도우의 종료를 시도합니다. 이 메서드는 사용자가 윈도우의 닫기 버튼을 클릭했을 때와 같은 효과를 냅니다. -웹 페이지는 로드가 취소되고 종료됩니다. 자세한 내용은 [close 이벤트](#event-close)를 참고하세요. +윈도우의 종료를 시도합니다. 이 메서드는 사용자가 윈도우의 닫기 버튼을 클릭했을 때와 +같은 효과를 냅니다. 웹 페이지는 로드가 취소되고 종료됩니다. 자세한 내용은 +[close 이벤트](#event-close)를 참고하세요. ### `win.focus()` @@ -359,19 +390,22 @@ var win = new BrowserWindow({ width: 800, height: 600 }); ### `win.setAspectRatio(aspectRatio[, extraSize])` _OS X_ * `aspectRatio` 유지하려 하는 컨텐츠 뷰 일부의 종횡비 -* `extraSize` Object (optional) - 종횡비를 유지하는 동안 포함되지 않을 엑스트라 크기. 사용 가능한 속성: +* `extraSize` Object (optional) - 종횡비를 유지하는 동안 포함되지 않을 엑스트라 크기. + 사용 가능한 속성: * `width` Integer * `height` Integer -이 메서드는 윈도우의 종횡비를 유지하는 기능을 수행합니다. -엑스트라 크기는 개발자가 픽셀로 특정한 공간이 있을 때 종횡비 계산에서 제외됩니다. -이 API는 윈도우의 크기와 컨텐츠 사이즈의 차이를 이미 고려하고 있습니다. +이 메서드는 윈도우의 종횡비를 유지하는 기능을 수행합니다. 엑스트라 크기는 개발자가 +픽셀로 특정한 공간이 있을 때 종횡비 계산에서 제외됩니다. 이 API는 윈도우의 크기와 +컨텐츠 사이즈의 차이를 이미 고려하고 있습니다. 일반 윈도우에서 작동하는 HD 비디오 플레이어와 관련된 컨트롤을 고려합니다. -만약 15 픽셀의 컨트롤이 왼쪽 가장자리에 있고 25 픽셀의 컨트롤이 오른쪽 가장자리에 있으며 50 픽셀의 컨트롤이 플레이어 밑에 있을 때 -플레이어 자체가 16:9 종횡비(HD의 표준 종횡비는 @1920x1080)를 유지하기 위해선 이 함수를 16/9, [ 40, 50 ] 인수와 함께 호출해야 합니다. -두번째 인수 엑스트라 크기는 존재하는 크기만 관여하고 컨텐츠 뷰 내의 크기는 관여하지 않습니다. -그저 전체 컨텐츠 뷰 내에 있는 모든 엑스트라 너비, 높이 영역이 합해집니다. +만약 15 픽셀의 컨트롤이 왼쪽 가장자리에 있고 25 픽셀의 컨트롤이 오른쪽 가장자리에 +있으며 50 픽셀의 컨트롤이 플레이어 밑에 있을 때 플레이어 자체가 16:9 종횡비(HD의 표준 +종횡비는 @1920x1080)를 유지하기 위해선 이 함수를 16/9, [ 40, 50 ] 인수와 함께 +호출해야 합니다. 두번째 인수 엑스트라 크기는 존재하는 크기만 관여하고 컨텐츠 뷰 내의 +크기는 관여하지 않습니다. 그저 전체 컨텐츠 뷰 내에 있는 모든 엑스트라 너비, 높이 영역이 +합해집니다. ### `win.setBounds(options)` @@ -446,8 +480,8 @@ var win = new BrowserWindow({ width: 800, height: 600 }); * `flag` Boolean -윈도우가 언제나 다른 윈도우들 위에 표시되는지 여부를 지정합니다. -이 설정을 활성화 하면 윈도우는 포커스 될 수 없는 툴박스 윈도우가 아닌 일반 윈도우로 유지됩니다. +윈도우가 언제나 다른 윈도우들 위에 표시되는지 여부를 지정합니다. 이 설정을 활성화 하면 +윈도우는 포커스 될 수 없는 툴박스 윈도우가 아닌 일반 윈도우로 유지됩니다. ### `win.isAlwaysOnTop()` @@ -539,7 +573,8 @@ Windows 메시지 훅을 등록합니다. `callback`은 WndProc에서 메시지 * `edited` Boolean -윈도우의 문서가 변경되었는지 여부를 설정합니다. 그리고 `true`로 설정했을 때 타이틀 바의 아이콘이 회색으로 표시됩니다. +윈도우의 문서가 변경되었는지 여부를 설정합니다. 그리고 `true`로 설정했을 때 타이틀 바의 +아이콘이 회색으로 표시됩니다. ### `win.isDocumentEdited()` _OS X_ @@ -551,17 +586,17 @@ Windows 메시지 훅을 등록합니다. `callback`은 WndProc에서 메시지 ### `win.capturePage([rect, ]callback)` -* `rect` Object (optional) - 캡쳐할 페이지의 영역. 사용할 수 있는 속성은 다음과 같습니다: +* `rect` Object (optional) - 캡쳐할 페이지의 영역. + 사용할 수 있는 속성은 다음과 같습니다: * `x` Integer * `y` Integer * `width` Integer * `height` Integer * `callback` Function -페이지의 스크린샷을 `rect`에 설정한 만큼 캡처합니다. -캡처가 완료되면 `callback`이 `callback(image)` 형식으로 호출됩니다. -`image`는 [NativeImage](native-image.md)의 인스턴스이며 스크린샷 데이터를 담고있습니다. -`rect`를 생략하면 페이지 전체를 캡처합니다. +페이지의 스크린샷을 `rect`에 설정한 만큼 캡처합니다. 캡처가 완료되면 `callback`이 +`callback(image)` 형식으로 호출됩니다. `image`는 [NativeImage](native-image.md)의 +인스턴스이며 스크린샷 데이터를 담고있습니다. `rect`를 생략하면 페이지 전체를 캡처합니다. ### `win.print([options])` @@ -589,23 +624,24 @@ Windows 메시지 훅을 등록합니다. `callback`은 WndProc에서 메시지 * `progress` Double -작업표시줄에 표시되고 있는 어플리케이션 아이콘에 진행 상태를 표시합니다. [0, 1.0] 사이의 값을 지정할 수 있습니다. +작업표시줄에 표시되고 있는 어플리케이션 아이콘에 진행 상태를 표시합니다. [0, 1.0] +사이의 값을 지정할 수 있습니다. 진행 상태가 < 0 이 되면 진행 상태 표시를 제거합니다. 진행 상태가 > 1 이 되면 불확정 상태 표시로 전환합니다. -Linux 플랫폼에선 Unity 데스크톱 환경만 지원합니다. -그리고 이 기능을 사용하려면 `*.desktop` 파일을 생성한 후 `package.json`의 `desktopName` 필드에 파일 이름을 지정해야 합니다. -기본적으로 `app.getName().desktop`을 통해 접근합니다. +Linux 플랫폼에선 Unity 데스크톱 환경만 지원합니다. 그리고 이 기능을 사용하려면 +`*.desktop` 파일을 생성한 후 `package.json`의 `desktopName` 필드에 파일 이름을 +지정해야 합니다. 기본적으로 `app.getName().desktop`을 통해 접근합니다. ### `win.setOverlayIcon(overlay, description)` _Windows 7+_ -* `overlay` [NativeImage](native-image.md) - 작업표시줄 아이콘의 우측 하단에 표시될 아이콘입니다. -`null`로 지정하면 빈 오버레이가 사용됩니다 +* `overlay` [NativeImage](native-image.md) - 작업표시줄 아이콘의 우측 하단에 표시될 +아이콘입니다. `null`로 지정하면 빈 오버레이가 사용됩니다 * `description` String - 접근성 설정에 의한 스크린 리더에 제공될 설명입니다 -현재 작업표시줄 아이콘에 16px 크기의 오버레이를 지정합니다. -보통 이 기능은 어플리케이션의 여러 상태를 사용자에게 소극적으로 알리기 위한 방법으로 사용됩니다. +현재 작업표시줄 아이콘에 16px 크기의 오버레이를 지정합니다. 보통 이 기능은 +어플리케이션의 여러 상태를 사용자에게 소극적으로 알리기 위한 방법으로 사용됩니다. ### `win.setThumbarButtons(buttons)` _Windows 7+_ @@ -615,23 +651,27 @@ Linux 플랫폼에선 Unity 데스크톱 환경만 지원합니다. * `icon` [NativeImage](native-image.md) - 미리보기 툴바에 보여질 아이콘. * `tooltip` String (optional) - 버튼의 툴팁 텍스트. -* `flags` Array (optional) - 버튼의 특정 동작 및 상태 제어. 기본적으로 `enabled`이 사용됩니다. - 이 속성은 다음 문자열들을 포함할 수 있습니다: +* `flags` Array (optional) - 버튼의 특정 동작 및 상태 제어. 기본적으로 `enabled`이 + 사용됩니다. 이 속성은 다음 문자열들을 포함할 수 있습니다: * `enabled` - 사용자가 사용할 수 있도록 버튼이 활성화 됩니다. - * `disabled` - 버튼이 비활성화 됩니다. 버튼은 표시되지만 시각적인 상태는 사용자의 동작에 응답하지 않는 - 비활성화 상태로 표시됩니다. - * `dismissonclick` - 버튼이 클릭되면 작업표시줄 버튼의 미리보기(flyout)가 즉시 종료됩니다. + * `disabled` - 버튼이 비활성화 됩니다. 버튼은 표시되지만 시각적인 상태는 사용자의 + 동작에 응답하지 않는 비활성화 상태로 표시됩니다. + * `dismissonclick` - 버튼이 클릭되면 작업표시줄 버튼의 미리보기(flyout)가 즉시 + 종료됩니다. * `nobackground` - 버튼의 테두리를 표시하지 않습니다. 이미지에만 사용할 수 있습니다. * `hidden` - 버튼을 사용자에게 표시되지 않도록 숨깁니다. - * `noninteractive` - 버튼은 활성화되어 있지만 반응이 제거되며 버튼을 눌러도 눌려지지 않은 상태를 유지합니다. - 이 값은 버튼을 알림의 용도로 사용하기 위해 만들어졌습니다. + * `noninteractive` - 버튼은 활성화되어 있지만 반응이 제거되며 버튼을 눌러도 + 눌려지지 않은 상태를 유지합니다. 이 값은 버튼을 알림의 용도로 사용하기 위해 + 만들어졌습니다. * `click` - Function -윈도우 작업표시줄 버튼 레이아웃의 미리보기 이미지 영역에 미리보기 툴바와 버튼 세트를 지정합니다. -반환되는 `Boolean` 값은 미리보기 툴바가 성공적으로 추가됬는지를 알려줍니다. +윈도우 작업표시줄 버튼 레이아웃의 미리보기 이미지 영역에 미리보기 툴바와 버튼 세트를 +지정합니다. 반환되는 `Boolean` 값은 미리보기 툴바가 성공적으로 추가됬는지를 알려줍니다. -미리보기 이미지 영역의 제한된 크기로 인해 미리보기 툴바에 추가될 수 있는 최대 버튼의 개수는 7개이며 이 이상 추가될 수 없습니다. -플랫폼의 제약으로 인해 미리보기 툴바는 한 번 설정되면 삭제할 수 없습니다. 하지만 이 API에 빈 배열을 전달하여 버튼들을 제거할 수 있습니다. +미리보기 이미지 영역의 제한된 크기로 인해 미리보기 툴바에 추가될 수 있는 최대 버튼의 +개수는 7개이며 이 이상 추가될 수 없습니다. 플랫폼의 제약으로 인해 미리보기 툴바는 한 번 +설정되면 삭제할 수 없습니다. 하지만 이 API에 빈 배열을 전달하여 버튼들을 제거할 수 +있습니다. ### `win.showDefinitionForSelection()` _OS X_ @@ -644,7 +684,8 @@ Linux 플랫폼에선 Unity 데스크톱 환경만 지원합니다. 메뉴 막대 자동 숨김 기능을 활성화 합니다. 숨겨진 메뉴는 사용자가 `Alt` 키를 단일 입력했을 때만 표시됩니다. -메뉴 막대가 이미 표시되고 있을 때 `setAutoHideMenuBar(true)`를 호출한다고 해서 메뉴가 즉시 숨겨지지는 않습니다. +메뉴 막대가 이미 표시되고 있을 때 `setAutoHideMenuBar(true)`를 호출한다고 해서 +메뉴가 즉시 숨겨지지는 않습니다. ### `win.isMenuBarAutoHide()` @@ -654,8 +695,8 @@ Linux 플랫폼에선 Unity 데스크톱 환경만 지원합니다. * `visible` Boolean -메뉴 막대의 표시 여부를 설정합니다. -만약 메뉴 막대 자동 숨김 상태라면 여전히 사용자가 `Alt` 키를 입력하여 메뉴 막대를 표시되도록 할 수 있습니다. +메뉴 막대의 표시 여부를 설정합니다. 만약 메뉴 막대 자동 숨김 상태라면 여전히 사용자가 +`Alt` 키를 입력하여 메뉴 막대를 표시되도록 할 수 있습니다. **역주:** 기본 메뉴 막대를 완전히 없애려면 `win.setMenu(null)`를 호출해야 합니다. 단순히 이 API를 사용하면 여전히 메뉴에 등록된 핫 키가 작동합니다. diff --git a/docs-translations/ko-KR/api/chrome-command-line-switches.md b/docs-translations/ko-KR/api/chrome-command-line-switches.md index d3aa5dd6411b..3c825b1abb13 100644 --- a/docs-translations/ko-KR/api/chrome-command-line-switches.md +++ b/docs-translations/ko-KR/api/chrome-command-line-switches.md @@ -1,8 +1,9 @@ # 크롬 명령줄 스위치 지원 -크롬 명령줄(Command-Line) 스위치는 크롬 브라우저에서 제공되는 추가 옵션이며 Electron에서도 지원합니다. -[app][app]의 [ready][ready]이벤트가 작동하기 전에 [app.commandLine.appendSwitch][append-switch] API를 사용하면 -어플리케이션 내부에서 스위치들을 추가할 수 있습니다: +크롬 명령줄(Command-Line) 스위치는 크롬 브라우저에서 제공되는 추가 옵션이며 +Electron에서도 지원합니다. [app][app]의 [ready][ready]이벤트가 작동하기 전에 +[app.commandLine.appendSwitch][append-switch] API를 사용하면 어플리케이션 내부에서 +스위치를 추가할 수 있습니다: ```javascript const app = require('electron').app; @@ -32,8 +33,8 @@ HTTP 요청 캐시를 비활성화 합니다. ## --js-flags=`flags` -JS 엔진에 지정한 플래그를 전달합니다. -`flags`를 메인 프로세스에서 활성화하고자 한다면, Electron이 시작되기 전에 스위치를 전달해야 합니다. +JS 엔진에 지정한 플래그를 전달합니다. `flags`를 메인 프로세스에서 활성화하고자 한다면, +Electron이 시작되기 전에 스위치를 전달해야 합니다. ```bash $ electron --js-flags="--harmony_proxies --harmony_collections" your-app @@ -41,11 +42,12 @@ $ electron --js-flags="--harmony_proxies --harmony_collections" your-app ## --proxy-server=`address:port` -시스템 설정의 프록시 서버를 무시하고 지정한 서버로 연결합니다. HTTP와 HTTPS 요청에만 적용됩니다. +시스템 설정의 프록시 서버를 무시하고 지정한 서버로 연결합니다. HTTP와 HTTPS 요청에만 +적용됩니다. -시스템 프록시 서버 설정을 무시하고 지정한 서버로 연결합니다. -이 스위치는 HTTP와 HTTPS 그리고 WebSocket 요청에만 적용됩니다. -그리고 모든 프록시 서버가 HTTPS가 WebSocket 요청을 지원하지 않고 있을 수 있으므로 사용시 주의해야 합니다. +시스템 프록시 서버 설정을 무시하고 지정한 서버로 연결합니다. 이 스위치는 HTTP와 HTTPS +그리고 WebSocket 요청에만 적용됩니다. 그리고 모든 프록시 서버가 HTTPS가 WebSocket +요청을 지원하지 않고 있을 수 있으므로 사용시 주의해야 합니다. ## --proxy-pac-url=`url` @@ -53,7 +55,8 @@ $ electron --js-flags="--harmony_proxies --harmony_collections" your-app ## --no-proxy-server -프록시 서버를 사용하지 않습니다. 다른 프록시 서버 플래그 및 설정을 무시하고 언제나 직접 연결을 사용합니다. +프록시 서버를 사용하지 않습니다. 다른 프록시 서버 플래그 및 설정을 무시하고 언제나 직접 +연결을 사용합니다. ## --host-rules=`rules` @@ -61,24 +64,21 @@ Hostname 맵핑 규칙을 설정합니다. (`,`로 구분) 예시: -* `MAP * 127.0.0.1` Forces all hostnames to be mapped to 127.0.0.1 -* `MAP *.google.com proxy` Forces all google.com subdomains to be resolved to - "proxy". -* `MAP test.com [::1]:77` Forces "test.com" to resolve to IPv6 loopback. Will - also force the port of the resulting socket address to be 77. -* `MAP * baz, EXCLUDE www.google.com` Remaps everything to "baz", except for - "www.google.com". - -이 맵핑은 네트워크 요청시의 endpoint를 지정합니다. (TCP 연결과 직접 연결의 호스트 resolver, http 프록시 연결의 `CONNECT`, `SOCKS` 프록시 연결의 endpoint 호스트) +* `MAP * 127.0.0.1` 강제적으로 모든 호스트네임을 127.0.0.1로 맵핑합니다 +* `MAP *.google.com proxy` 강제적으로 모든 google.com의 서브도메인을 "proxy"로 + 연결합니다 +* `MAP test.com [::1]:77` 강제적으로 "test.com"을 IPv6 루프백으로 연결합니다. + 소켓 주소의 포트 또한 77로 고정됩니다. +* `MAP * baz, EXCLUDE www.google.com` "www.google.com"을 제외한 모든 것들을 + "baz"로 맵핑합니다. + +이 맵핑은 네트워크 요청시의 endpoint를 지정합니다. (TCP 연결과 직접 연결의 호스트 +resolver, http 프록시 연결의 `CONNECT`, `SOCKS` 프록시 연결의 endpoint 호스트) ## --host-resolver-rules=`rules` `--host-rules` 플래그와 비슷하지만 이 플래그는 host resolver에만 적용됩니다. -[app]: app.md -[append-switch]: app.md#appcommandlineappendswitchswitch-value -[ready]: app.md#event-ready - ## --ignore-certificate-errors 인증서 에러를 무시합니다. @@ -97,7 +97,8 @@ Net log 이벤트를 활성화하고 `path`에 로그를 기록합니다. ## --ssl-version-fallback-min=`version` -TLS fallback에서 사용할 SSL/TLS 최소 버전을 지정합니다. ("tls1", "tls1.1", "tls1.2") +TLS fallback에서 사용할 SSL/TLS 최소 버전을 지정합니다. ("tls1", "tls1.1", +"tls1.2") ## --cipher-suite-blacklist=`cipher_suites` @@ -107,21 +108,29 @@ SSL 암호화를 비활성화할 대상 목록을 지정합니다. (`,`로 구 Chromium의 로그를 콘솔에 출력합니다. -이 스위치는 어플리케이션이 로드되기 전에 분석 되므로 `app.commandLine.appendSwitch` 메서드에선 사용할 수 없습니다. -하지만 `ELECTRON_ENABLE_LOGGING` 환경 변수를 설정하면 본 스위치를 지정한 것과 같은 효과를 낼 수 있습니다. +이 스위치는 어플리케이션이 로드되기 전에 분석 되므로 `app.commandLine.appendSwitch` +메서드에선 사용할 수 없습니다. 하지만 `ELECTRON_ENABLE_LOGGING` 환경 변수를 설정하면 +본 스위치를 지정한 것과 같은 효과를 낼 수 있습니다. ## --v=`log_level` -기본 V-logging 최대 활성화 레벨을 지정합니다. 기본값은 0입니다. 기본적으로 양수를 레벨로 사용합니다. +기본 V-logging 최대 활성화 레벨을 지정합니다. 기본값은 0입니다. 기본적으로 양수를 +레벨로 사용합니다. 이 스위치는 `--enable-logging` 스위치를 같이 지정해야 작동합니다. ## --vmodule=`pattern` `--v` 옵션에 전달된 값을 덮어쓰고 모듈당 최대 V-logging 레벨을 지정합니다. -예를 들어 `my_module=2,foo*=3`는 `my_module.*`, `foo*.*`와 같은 파일 이름 패턴을 가진 모든 소스 코드들의 로깅 레벨을 각각 2와 3으로 설정합니다. +예를 들어 `my_module=2,foo*=3`는 `my_module.*`, `foo*.*`와 같은 파일 이름 패턴을 +가진 모든 소스 코드들의 로깅 레벨을 각각 2와 3으로 설정합니다. -또한 슬래시(`/`) 또는 백슬래시(`\`)를 포함하는 패턴은 지정한 경로에 대해 패턴을 테스트 합니다. -예를 들어 `*/foo/bar/*=2` 표현식은 `foo/bar` 디렉터리 안의 모든 소스 코드의 로깅 레벨을 2로 지정합니다. +또한 슬래시(`/`) 또는 백슬래시(`\`)를 포함하는 패턴은 지정한 경로에 대해 패턴을 테스트 +합니다. 예를 들어 `*/foo/bar/*=2` 표현식은 `foo/bar` 디렉터리 안의 모든 소스 코드의 +로깅 레벨을 2로 지정합니다. 이 스위치는 `--enable-logging` 스위치를 같이 지정해야 작동합니다. + +[app]: app.md +[append-switch]: app.md#appcommandlineappendswitchswitch-value +[ready]: app.md#event-ready diff --git a/docs-translations/ko-KR/api/clipboard.md b/docs-translations/ko-KR/api/clipboard.md index 01f1945856f3..2a0c98da2c09 100644 --- a/docs-translations/ko-KR/api/clipboard.md +++ b/docs-translations/ko-KR/api/clipboard.md @@ -1,13 +1,15 @@ # clipboard -`clipboard` 모듈은 복사/붙여넣기 작업을 수행하는 방법을 제공합니다. 다음 예제는 클립보드에 문자열을 씁니다: +`clipboard` 모듈은 복사/붙여넣기 작업을 수행하는 방법을 제공합니다. 다음 예제는 +클립보드에 문자열을 씁니다: ```javascript const clipboard = require('electron').clipboard; clipboard.writeText('Example String'); ``` -X Window 시스템에선 selection 클립보드도 존재합니다. 이를 사용하려면 인자 뒤에 `selection` 문자열을 같이 지정해주어야 합니다: +X Window 시스템에선 selection 클립보드도 존재합니다. 이를 사용하려면 인자 뒤에 +`selection` 문자열을 같이 지정해주어야 합니다: ```javascript clipboard.writeText('Example String', 'selection'); @@ -18,7 +20,8 @@ console.log(clipboard.readText('selection')); `clipboard` 모듈은 다음과 같은 메서드를 가지고 있습니다: -**참고:** Experimental 마크가 붙은 API는 실험적인 기능이며 차후 최신 버전에서 제거될 수 있습니다. +**참고:** Experimental 마크가 붙은 API는 실험적인 기능이며 차후 최신 버전에서 제거될 +수 있습니다. ### `clipboard.readText([type])` diff --git a/docs-translations/ko-KR/api/content-tracing.md b/docs-translations/ko-KR/api/content-tracing.md index f5f8b03d294a..ed73ce319f68 100644 --- a/docs-translations/ko-KR/api/content-tracing.md +++ b/docs-translations/ko-KR/api/content-tracing.md @@ -1,7 +1,9 @@ # contentTracing -`content-tracing` 모듈은 Chromium 컨텐츠 모듈단에서 생성된 데이터를 수집하고 추적하는데 사용됩니다. -이 모듈은 웹 인터페이스를 포함하고 있지 않으며 크롬 브라우저에서 `chrome://tracing/` 페이지를 열어 생성된 파일을 로드하면 결과를 볼 수 있습니다. +`content-tracing` 모듈은 Chromium 컨텐츠 모듈단에서 생성된 데이터를 수집하고 +추적하는데 사용됩니다. 이 모듈은 웹 인터페이스를 포함하고 있지 않으며 크롬 +브라우저에서 `chrome://tracing/` 페이지를 열어 생성된 파일을 로드하면 결과를 볼 수 +있습니다. ```javascript const contentTracing = require('electron').contentTracing; @@ -32,7 +34,8 @@ contentTracing.startRecording(options, function() { 카테고리 그룹 세트를 가져옵니다. 카테고리 그룹은 도달된 코드 경로를 변경할 수 있습니다. -모든 child 프로세스가 `getCategories` 요청을 승인하면 `callback`이 한 번 호출되며 인자에 카테고리 그룹의 배열이 전달됩니다. +모든 child 프로세스가 `getCategories` 요청을 승인하면 `callback`이 한 번 호출되며 +인자에 카테고리 그룹의 배열이 전달됩니다. ### `contentTracing.startRecording(options, callback)` @@ -43,12 +46,13 @@ contentTracing.startRecording(options, function() { 모든 프로세스에서 레코딩을 시작합니다. -레코딩은 지역적으로 즉시 실행됩니다. 그리고 비동기로 child 프로세스는 곧 EnableRecording 요청을 받게 됩니다. -모든 child 프로세스가 `startRecording` 요청을 승인하면 `callback`이 한 번 호출됩니다. +레코딩은 지역적으로 즉시 실행됩니다. 그리고 비동기로 child 프로세스는 곧 +EnableRecording 요청을 받게 됩니다. 모든 child 프로세스가 `startRecording` 요청을 +승인하면 `callback`이 한 번 호출됩니다. `categoryFilter`는 어떤 카테고리 그룹이 트레이싱 되어야 하는지 필터링할 수 있습니다. -필터는 `-` 접두사를 통해 특정 카테고리 그룹을 제외할 수 있습니다. -카테고리 패턴은 같은 리스트 내에서 포함과 제외를 함께 사용할 수 없습니다. +필터는 `-` 접두사를 통해 특정 카테고리 그룹을 제외할 수 있습니다. 카테고리 패턴은 같은 +리스트 내에서 포함과 제외를 함께 사용할 수 없습니다. 예제: @@ -56,7 +60,8 @@ contentTracing.startRecording(options, function() { * `test_MyTest*,test_OtherStuff`, * `"-excluded_category1,-excluded_category2` -`traceOptions`은 어떤 종류의 트레이싱을 사용할 수 있는지 지정하고 콤마로 리스트를 구분합니다. +`traceOptions`은 어떤 종류의 트레이싱을 사용할 수 있는지 지정하고 콤마로 리스트를 +구분합니다. 사용할 수 있는 옵션은 다음과 같습니다: @@ -67,12 +72,13 @@ contentTracing.startRecording(options, function() { * `enable-systrace` 첫번째부터 3번째까지의 옵션은 추적 레코딩 모드입니다. 이에 따라 상호 배타적입니다. -만약 레코딩 모드가 한 개 이상 지정되면 마지막 지정한 모드만 사용됩니다. -어떤 모드도 설정되지 않았다면 `record-until-full` 모드가 기본으로 사용됩니다. +만약 레코딩 모드가 한 개 이상 지정되면 마지막 지정한 모드만 사용됩니다. 어떤 모드도 +설정되지 않았다면 `record-until-full` 모드가 기본으로 사용됩니다. 추적 옵션은 `traceOptions`이 파싱되어 적용되기 전까지 다음과 같은 기본값이 사용됩니다. -`record-until-full`이 기본 모드, `enable-sampling`과 `enable-systrace`옵션은 포함되지 않음 +`record-until-full`이 기본 모드, `enable-sampling`과 `enable-systrace`옵션은 +포함되지 않음 ## `contentTracing.stopRecording(resultFilePath, callback)` @@ -81,15 +87,18 @@ contentTracing.startRecording(options, function() { 모든 프로세스에서 레코딩을 중지합니다. -Child 프로세스는 일반적으로 추적 데이터와 희귀한 플러시 그리고 추적 데이터를 메인 프로세스로 보내는 작업에 대해 캐싱 합니다. -이러한 일을 하는 이유는 IPC를 통해 추적 데이터를 보내는 작업은 매우 비싼 연산을 동반하기 때문입니다. -우리는 추적에 의한 런타임 오버헤드를 피하고자 합니다. -그래서 추적이 끝나면 모든 child 프로세스에 보류된 추적 데이터를 플러시 할 것인지 물어봅니다. +Child 프로세스는 일반적으로 추적 데이터와 희귀한 플러시 그리고 추적 데이터를 메인 +프로세스로 보내는 작업에 대해 캐싱 합니다. 이러한 일을 하는 이유는 IPC를 통해 추적 +데이터를 보내는 작업은 매우 비싼 연산을 동반하기 때문입니다. 우리는 추적에 의한 런타임 +오버헤드를 피하고자 합니다. 그래서 추적이 끝나면 모든 child 프로세스에 보류된 추적 +데이터를 플러시 할 것인지 물어봅니다. -모든 child 프로세스가 `stopRecording` 요청을 승인하면 `callback`에 추적 데이터 파일을 포함하여 한 번 호출됩니다. +모든 child 프로세스가 `stopRecording` 요청을 승인하면 `callback`에 추적 데이터 +파일을 포함하여 한 번 호출됩니다. -추적 데이터는 `resultFilePath` 해당 경로가 비어있는 경우에 한 해 해당 경로에 작성되거나 임시 파일에 작성됩니다. -실제 파일 경로는 null이 아닌 이상 `callback`을 통해 전달됩니다. +추적 데이터는 `resultFilePath` 해당 경로가 비어있는 경우에 한 해 해당 경로에 +작성되거나 임시 파일에 작성됩니다. 실제 파일 경로는 null이 아닌 이상 `callback`을 +통해 전달됩니다. ### `contentTracing.startMonitoring(options, callback)` @@ -100,7 +109,8 @@ Child 프로세스는 일반적으로 추적 데이터와 희귀한 플러시 모든 프로세스에서 모니터링을 시작합니다. -모니터링은 지역적으로 즉시 시작됩니다. 그리고 이내 자식 프로세스들이 `startMonitoring` 비동기 요청을 받습니다. +모니터링은 지역적으로 즉시 시작됩니다. 그리고 이내 자식 프로세스들이 +`startMonitoring` 비동기 요청을 받습니다. 모든 자식 프로세스가 `startMonitoring` 요청을 승인하면 `callback`이 한 번 호출됩니다. @@ -119,18 +129,21 @@ Child 프로세스는 일반적으로 추적 데이터와 희귀한 플러시 현재 모니터링 추적 데이터를 가져옵니다. -자식 프로세스들은 일반적으로 추적 데이터를 캐싱하며 드물게 플러시 하거나 메인 프로세스로 추적 데이터를 보냅니다. -왜냐하면 IPC를 통해 추적 데이터를 보내는데에는 많은 자원을 소비하기 때문입니다. -그리고 우리는 추적시 발생하는 불필요한 런타임 오버헤드를 피하고자 합니다. -그래서 추적이 끝나면 반드시 비동기로 자식 프로세스들의 보류된 추적 데이터를 플러시 할 것인지 물어봅니다. +자식 프로세스들은 일반적으로 추적 데이터를 캐싱하며 드물게 플러시 하거나 메인 +프로세스로 추적 데이터를 보냅니다. 왜냐하면 IPC를 통해 추적 데이터를 보내는데에는 +많은 자원을 소비하기 때문입니다. 그리고 우리는 추적시 발생하는 불필요한 런타임 +오버헤드를 피하고자 합니다. 그래서 추적이 끝나면 반드시 비동기로 자식 프로세스들의 +보류된 추적 데이터를 플러시 할 것인지 물어봅니다. -모든 자식 프로세스가 `captureMonitoringSnapshot` 요청을 승인하면 추적 데이터 파일을 포함하는 `callback`이 한 번 호출됩니다. +모든 자식 프로세스가 `captureMonitoringSnapshot` 요청을 승인하면 추적 데이터 파일을 +포함하는 `callback`이 한 번 호출됩니다. ### `contentTracing.getTraceBufferUsage(callback)` * `callback` Function -추적 버퍼 % 전체 상태의 프로세스간 최대치를 가져옵니다. TraceBufferUsage 값이 결정되면 `callback`이 한 번 호출됩니다. +추적 버퍼 % 전체 상태의 프로세스간 최대치를 가져옵니다. TraceBufferUsage 값이 +결정되면 `callback`이 한 번 호출됩니다. ### `contentTracing.setWatchEvent(categoryName, eventName, callback)` @@ -142,4 +155,5 @@ Child 프로세스는 일반적으로 추적 데이터와 희귀한 플러시 ### `contentTracing.cancelWatchEvent()` -Watch 이벤트를 중단합니다. 만약 추적이 활성화되어 있다면 이 메서드는 watch 이벤트 콜백과 race가 일어날 것입니다. +Watch 이벤트를 중단합니다. 만약 추적이 활성화되어 있다면 이 메서드는 watch 이벤트 +콜백과 race가 일어날 것입니다. diff --git a/docs-translations/ko-KR/api/crash-reporter.md b/docs-translations/ko-KR/api/crash-reporter.md index a5d29551571e..a4d42f013366 100644 --- a/docs-translations/ko-KR/api/crash-reporter.md +++ b/docs-translations/ko-KR/api/crash-reporter.md @@ -1,6 +1,7 @@ # crashReporter -`crash-reporter` 모듈은 어플리케이션의 크래시 정보를 자동으로 원격 서버에 업로드하는데 사용합니다. +`crash-reporter` 모듈은 어플리케이션의 크래시 정보를 자동으로 원격 서버에 +업로드하는데 사용합니다. 다음 예제는 윈격 서버에 어플리케이션 크래시 정보를 자동으로 보고하는 예제입니다: @@ -34,12 +35,13 @@ crashReporter.start({ * 크래시 리포트 시 같이 보낼 추가 정보를 지정하는 객체입니다. * 문자열로 된 속성만 정상적으로 보내집니다. * 중첩 객체는 지원되지 않습니다. (Nested objects are not supported) - + 다른 crashReporter API를 사용하기 전에 이 메서드를 먼저 호출해야 합니다. -**참고:** OS X에선 Windows와 Linux의 `breakpad`와 달리 새로운 `crashpad` 클라이언트를 사용합니다. -오류 수집 기능을 활성화 시키려면 오류를 수집하고 싶은 메인 프로세스나 랜더러 프로세스에서 -`crashReporter.start` 메서드를 호출하여 `crashpad`를 초기화 해야합니다. +**참고:** OS X에선 Windows와 Linux의 `breakpad`와 달리 새로운 `crashpad` +클라이언트를 사용합니다. 오류 수집 기능을 활성화 시키려면 오류를 수집하고 싶은 메인 +프로세스나 랜더러 프로세스에서 `crashReporter.start` 메서드를 호출하여 `crashpad`를 +초기화 해야합니다. ### `crashReporter.getLastCrashReport()` diff --git a/docs-translations/ko-KR/api/dialog.md b/docs-translations/ko-KR/api/dialog.md index e7e81240da0f..bb92c1f43e89 100644 --- a/docs-translations/ko-KR/api/dialog.md +++ b/docs-translations/ko-KR/api/dialog.md @@ -1,7 +1,8 @@ # dialog -`dialog` 모듈은 파일 열기, 알림과 같은 네이티브 시스템의 대화 상자를 조작할 때 사용할 수 있는 모듈입니다. -이 모듈을 사용하면 웹 어플리케이션에서 일반 네이티브 어플리케이션과 비슷한 사용자 경험을 제공할 수 있습니다. +`dialog` 모듈은 파일 열기, 알림과 같은 네이티브 시스템의 대화 상자를 조작할 때 사용할 +수 있는 모듈입니다. 이 모듈을 사용하면 웹 어플리케이션에서 일반 네이티브 어플리케이션과 +비슷한 사용자 경험을 제공할 수 있습니다. 다음 예제는 파일과 디렉터리를 다중으로 선택하는 대화 상자를 표시하는 예제입니다: @@ -11,7 +12,8 @@ const dialog = require('electron').dialog; console.log(dialog.showOpenDialog({ properties: [ 'openFile', 'openDirectory', 'multiSelections' ]})); ``` -**OS X 알림**: 대화 상자를 시트처럼 보여지게 하려면 `browserWindow` 인자에 `BrowserWindow` 객체의 참조를 제공하면 됩니다. +**OS X 참고**: 대화 상자를 시트처럼 보여지게 하려면 `browserWindow` 인자에 +`BrowserWindow` 객체의 참조를 제공하면 됩니다. ## Methods @@ -25,15 +27,18 @@ console.log(dialog.showOpenDialog({ properties: [ 'openFile', 'openDirectory', ' * `defaultPath` String * `filters` Array * `properties` Array - 대화 상자가 사용할 기능(모드)이 담긴 배열입니다. - 다음을 포함할 수 있습니다: `openFile`, `openDirectory`, `multiSelections`, `createDirectory` + 다음을 포함할 수 있습니다: `openFile`, `openDirectory`, `multiSelections`, + `createDirectory` * `callback` Function (optional) -사용할 대화 상자의 기능이 담긴 배열입니다. 다음을 포함할 수 있습니다: `openFile`, `openDirectory`, `multiSelections`, `createDirectory` +사용할 대화 상자의 기능이 담긴 배열입니다. 다음을 포함할 수 있습니다: `openFile`, +`openDirectory`, `multiSelections`, `createDirectory` -작업에 성공하면 콜백으로 유저가 선택한 파일의 경로를 포함한 배열을 반환합니다. 그 외엔 `undefined`를 반환합니다. +작업에 성공하면 콜백으로 유저가 선택한 파일의 경로를 포함한 배열을 반환합니다. 그 외의 +경우엔 `undefined`를 반환합니다. -`filters`를 지정하면 유저가 선택 가능한 파일 형식을 지정할 수 있습니다. -유저가 선택할 수 있는 타입에 제한을 두려면 다음과 같이 할 수 있습니다: +`filters`를 지정하면 유저가 선택 가능한 파일 형식을 지정할 수 있습니다. 유저가 선택할 +수 있는 타입에 제한을 두려면 다음과 같이 할 수 있습니다: ```javascript { @@ -46,14 +51,17 @@ console.log(dialog.showOpenDialog({ properties: [ 'openFile', 'openDirectory', ' } ``` -`extensions` 배열은 반드시 와일드카드와 마침표를 제외한 파일 확장자를 포함시켜야 합니다. -(예를 들어 `'png'`는 가능하지만 `'.png'`와 `'*.png'`는 안됩니다) -모든 파일을 보여주려면 `'*'`와 같은 와일드카드를 사용하면 됩니다. (다른 와일드카드는 지원하지 않습니다) +`extensions` 배열은 반드시 와일드카드와 마침표를 제외한 파일 확장자를 포함시켜야 +합니다. (예를 들어 `'png'`는 가능하지만 `'.png'`와 `'*.png'`는 안됩니다) 모든 파일을 +보여주려면 `'*'`와 같은 와일드카드를 사용하면 됩니다. (다른 와일드카드는 지원하지 + 않습니다) -`callback`이 전달되면 메소드가 비동기로 작동되며 결과는 `callback(filenames)`을 통해 전달됩니다. +`callback`이 전달되면 메서드가 비동기로 작동되며 결과는 `callback(filenames)`을 +통해 전달됩니다. -**참고:** Windows와 Linux에선 파일 선택 모드, 디렉터리 선택 모드를 동시에 사용할 수 없습니다. -이러한 이유로 `properties`를 `['openFile', 'openDirectory']`로 설정하면 디렉터리 선택 대화 상자가 표시됩니다. +**참고:** Windows와 Linux에선 파일 선택 모드, 디렉터리 선택 모드를 동시에 사용할 수 +없습니다. 이러한 이유로 `properties`를 `['openFile', 'openDirectory']`로 설정하면 +디렉터리 선택 대화 상자가 표시됩니다. ### `dialog.showSaveDialog([browserWindow][, options][, callback])` @@ -64,43 +72,52 @@ console.log(dialog.showOpenDialog({ properties: [ 'openFile', 'openDirectory', ' * `filters` Array * `callback` Function (optional) -작업에 성공하면 콜백으로 유저가 선택한 파일의 경로를 포함한 배열을 반환합니다. 그 외엔 `undefined`를 반환합니다. +작업에 성공하면 콜백으로 유저가 선택한 파일의 경로를 포함한 배열을 반환합니다. 그 외엔 +`undefined`를 반환합니다. -`filters`를 지정하면 유저가 저장 가능한 파일 형식을 지정할 수 있습니다. 사용 방법은 `dialog.showOpenDialog`의 `filters` 속성과 같습니다. +`filters`를 지정하면 유저가 저장 가능한 파일 형식을 지정할 수 있습니다. 사용 방법은 +`dialog.showOpenDialog`의 `filters` 속성과 같습니다. -`callback`이 전달되면 메소드가 비동기로 작동되며 결과는 `callback(filename)`을 통해 전달됩니다. +`callback`이 전달되면 메서드가 비동기로 작동되며 결과는 `callback(filename)`을 통해 전달됩니다. ### `dialog.showMessageBox([browserWindow][, options][, callback])` * `browserWindow` BrowserWindow * `options` Object - * `type` String - `"none"`, `"info"`, `"error"`, `"question"`, `"warning"` 중 하나를 사용할 수 있습니다. - Windows에선 따로 `icon`을 설정하지 않은 이상 "question"과 "info"는 같은 아이콘으로 표시됩니다. + * `type` String - `"none"`, `"info"`, `"error"`, `"question"`, `"warning"` 중 + 하나를 사용할 수 있습니다. Windows에선 따로 `icon`을 설정하지 않은 이상 + "question"과 "info"는 같은 아이콘으로 표시됩니다. * `buttons` Array - 버튼들의 라벨을 포함한 배열입니다. * `title` String - 대화 상자의 제목입니다. 몇몇 플랫폼에선 보이지 않을 수 있습니다. * `message` String - 대화 상자의 본문 내용입니다. * `detail` String - 메시지의 추가 정보입니다. * `icon` [NativeImage](native-image.md) - * `cancelId` Integer - 유저가 대화 상자의 버튼을 클릭하지 않고 대화 상자를 취소했을 때 반환되는 버튼의 인덱스입니다. - 기본적으로 버튼 리스트가 "cancel" 또는 "no" 라벨을 가지고 있을 때 해당 버튼의 인덱스를 반환합니다. 따로 두 라벨이 지정되지 않은 경우 0을 반환합니다. - OS X와 Windows에선 `cancelId` 지정 여부에 상관없이 "Cancel" 버튼이 언제나 `cancelId`로 지정됩니다. - * `noLink` Boolean - Windows Electron은 "Cancel"이나 "Yes"와 같은 흔히 사용되는 버튼을 찾으려고 시도하고 - 대화 상자 내에서 해당 버튼을 커맨드 링크처럼 만듭니다. 이 기능으로 앱을 좀 더 Modern Windows 앱처럼 만들 수 있습니다. - 이 기능을 원하지 않으면 `noLink`를 true로 지정하면 됩니다. + * `cancelId` Integer - 유저가 대화 상자의 버튼을 클릭하지 않고 대화 상자를 취소했을 + 때 반환되는 버튼의 인덱스입니다. 기본적으로 버튼 리스트가 "cancel" 또는 "no" + 라벨을 가지고 있을 때 해당 버튼의 인덱스를 반환합니다. 따로 두 라벨이 지정되지 + 않은 경우 0을 반환합니다. OS X와 Windows에선 `cancelId` 지정 여부에 상관없이 + "Cancel" 버튼이 언제나 `cancelId`로 지정됩니다. + * `noLink` Boolean - Windows Electron은 "Cancel"이나 "Yes"와 같은 흔히 사용되는 + 버튼을 찾으려고 시도하고 대화 상자 내에서 해당 버튼을 커맨드 링크처럼 만듭니다. + 이 기능으로 앱을 좀 더 Modern Windows 앱처럼 만들 수 있습니다. 이 기능을 원하지 + 않으면 `noLink`를 true로 지정하면 됩니다. * `callback` Function -대화 상자를 표시합니다. `browserWindow`를 지정하면 대화 상자가 완전히 닫힐 때까지 지정한 창을 사용할 수 없습니다. -완료 시 유저가 선택한 버튼의 인덱스를 반환합니다. +대화 상자를 표시합니다. `browserWindow`를 지정하면 대화 상자가 완전히 닫힐 때까지 +지정한 창을 사용할 수 없습니다. 완료 시 유저가 선택한 버튼의 인덱스를 반환합니다. -역주: 부정을 표현하는 "아니오", "취소"와 같은 한글 단어는 지원되지 않습니다. -만약 OS X 또는 Windows에서 "확인", "취소"와 같은 순서로 버튼을 지정하게 될 때 Alt + f4로 해당 대화 상자를 끄게 되면 "확인"을 누른 것으로 판단되어 버립니다. -이를 해결하려면 "Cancel"을 대신 사용하거나 BrowserWindow API를 사용하여 대화 상자를 직접 구현해야합니다. +역주: 부정을 표현하는 "아니오", "취소"와 같은 한글 단어는 지원되지 않습니다. 만약 +OS X 또는 Windows에서 "확인", "취소"와 같은 순서로 버튼을 지정하게 될 때 Alt + f4로 +해당 대화 상자를 끄게 되면 "확인"을 누른 것으로 판단되어 버립니다. 이를 해결하려면 +"Cancel"을 대신 사용하거나 BrowserWindow API를 사용하여 대화 상자를 직접 구현해야 +합니다. -`callback`이 전달되면 메소드가 비동기로 작동되며 결과는 `callback(response)`을 통해 전달됩니다. +`callback`이 전달되면 메서드가 비동기로 작동되며 결과는 `callback(response)`을 통해 +전달됩니다. ### `dialog.showErrorBox(title, content)` 에러 메시지를 보여주는 대화 상자를 표시합니다. -이 API는 `app` 모듈의 `ready` 이벤트가 발생하기 전에 사용할 수 있습니다. -이 메소드는 보통 어플리케이션이 시작되기 전에 특정한 에러를 표시하기 위해 사용됩니다. +이 API는 `app` 모듈의 `ready` 이벤트가 발생하기 전에 사용할 수 있습니다. 이 메서드는 +보통 어플리케이션이 시작되기 전에 특정한 에러를 표시하기 위해 사용됩니다. diff --git a/docs-translations/ko-KR/api/download-item.md b/docs-translations/ko-KR/api/download-item.md index 95a00c857533..a367d0e000bd 100644 --- a/docs-translations/ko-KR/api/download-item.md +++ b/docs-translations/ko-KR/api/download-item.md @@ -1,8 +1,8 @@ # DownloadItem `DownloadItem`은 EventEmitter를 상속받았으며 Electron의 다운로드 아이템을 표현합니다. -이 클래스 객체는 `Session` 모듈의 `will-download` 이벤트에 사용되며 -사용자가 다운로드 아이템을 다룰 수 있도록 도와줍니다. +이 클래스 객체는 `Session` 모듈의 `will-download` 이벤트에 사용되며 사용자가 다운로드 +아이템을 다룰 수 있도록 도와줍니다. ```javascript // 메인 프로세스 @@ -38,9 +38,9 @@ win.webContents.session.on('will-download', function(event, item, webContents) { * `cancelled` - 다운로드가 취소되었습니다. * `interrupted` - 다운로드 중 파일 서버로부터의 연결이 끊겼습니다. -다운로드가 종료될 때 발생하는 이벤트입니다. -이 이벤트는 다운로드 중 문제가 발생하여 중단되거나, 모두 성공적으로 완료된 경우, -`downloadItem.cancel()` 같은 메서드를 통해 취소하는 경우의 종료 작업이 모두 포함됩니다. +다운로드가 종료될 때 발생하는 이벤트입니다. 이 이벤트는 다운로드 중 문제가 발생하여 +중단되거나, 모두 성공적으로 완료된 경우, `downloadItem.cancel()` 같은 메서드를 통해 +취소하는 경우의 종료 작업이 모두 포함됩니다. ## Methods @@ -50,8 +50,9 @@ win.webContents.session.on('will-download', function(event, item, webContents) { * `path` String - 다운로드 아이템을 저장할 파일 경로를 지정합니다. -이 API는 세션의 `will-download` 콜백 함수에서만 사용할 수 있습니다. -사용자가 API를 통해 아무 경로도 설정하지 않을 경우 Electron은 기본 루틴 파일 저장을 실행합니다. (파일 대화 상자를 엽니다) +이 API는 세션의 `will-download` 콜백 함수에서만 사용할 수 있습니다. 사용자가 API를 +통해 아무 경로도 설정하지 않을 경우 Electron은 기본 루틴 파일 저장을 실행합니다. +(파일 대화 상자를 엽니다) ### `downloadItem.pause()` @@ -81,12 +82,14 @@ win.webContents.session.on('will-download', function(event, item, webContents) { 다운로드 아이템의 파일 이름을 표현하는 문자열을 반환합니다. -**참고:** 실제 파일 이름과 로컬 디스크에 저장되는 파일의 이름은 서로 다를 수 있습니다. 예를 들어 -만약 사용자가 파일을 저장할 때 파일 이름을 바꿨다면 실제 파일 이름과 저장 파일 이름은 서로 달라지게 됩니다. +**참고:** 실제 파일 이름과 로컬 디스크에 저장되는 파일의 이름은 서로 다를 수 있습니다. +예를 들어 만약 사용자가 파일을 저장할 때 파일 이름을 바꿨다면 실제 파일 이름과 저장 +파일 이름은 서로 달라지게 됩니다. ### `downloadItem.getTotalBytes()` -현재 아이템의 전체 다운로드 크기를 정수로 반환합니다. 크기가 unknown이면 0을 반환합니다. +현재 아이템의 전체 다운로드 크기를 정수로 반환합니다. 크기가 unknown이면 0을 +반환합니다. ### `downloadItem.getReceivedBytes()` diff --git a/docs-translations/ko-KR/api/file-object.md b/docs-translations/ko-KR/api/file-object.md index 6006220647dd..a2a19a530d4a 100644 --- a/docs-translations/ko-KR/api/file-object.md +++ b/docs-translations/ko-KR/api/file-object.md @@ -1,8 +1,8 @@ # `File` 객체 -DOM의 File 인터페이스는 네이티브 파일을 추상화 합니다. -유저가 직접 HTML5 File API를 이용하여 작업할 때 선택된 파일의 경로를 알 수 있도록 -Electron은 파일의 실제 경로를 담은 `path` 속성을 File 인터페이스에 추가하였습니다. +DOM의 File 인터페이스는 네이티브 파일을 추상화 합니다. 유저가 직접 HTML5 File API를 +이용하여 작업할 때 선택된 파일의 경로를 알 수 있도록 Electron은 파일의 실제 경로를 +담은 `path` 속성을 File 인터페이스에 추가하였습니다. 다음 예제는 앱으로 드래그 앤 드롭한 파일의 실제 경로를 가져옵니다: diff --git a/docs-translations/ko-KR/api/frameless-window.md b/docs-translations/ko-KR/api/frameless-window.md index a10cba190937..e13794e0fdfd 100644 --- a/docs-translations/ko-KR/api/frameless-window.md +++ b/docs-translations/ko-KR/api/frameless-window.md @@ -1,12 +1,14 @@ # Frameless Window -Frameless Window는 [창 테두리](https://developer.mozilla.org/en-US/docs/Glossary/Chrome)가 없는 윈도우를 말합니다. -이 기능은 윈도우 창의 일부분인 툴바와 같이 웹 페이지의 일부분이 아닌 부분을 보이지 않도록 합니다. -[`BrowserWindow`](browser-window.md) 클래스의 옵션에서 설정할 수 있습니다. +Frameless Window는 [창 테두리](https://developer.mozilla.org/en-US/docs/Glossary/Chrome)가 +없는 윈도우를 말합니다. 이 기능은 윈도우 창의 일부분인 툴바와 같이 웹 페이지의 일부분이 +아닌 부분을 보이지 않도록 합니다. [`BrowserWindow`](browser-window.md) 클래스의 +옵션에서 설정할 수 있습니다. ## Frameless Window 만들기 -Frameless Window를 만드려면 [BrowserWindow](browser-window.md) 객체의 `options`에서 `frame` 옵션을 `false`로 지정하면 됩니다: +Frameless Window를 만드려면 [BrowserWindow](browser-window.md) 객체의 +`options` 객체에서 `frame` 옵션을 `false`로 지정하면 됩니다: ```javascript const BrowserWindow = require('electron').BrowserWindow; @@ -15,9 +17,10 @@ var win = new BrowserWindow({ width: 800, height: 600, frame: false }); ### 최신 OS X에서 사용할 수 있는 대안 -OS X 10.10 Yosemite 이후의 최신 버전부터는 테두리가 없는 창을 만들 때 새로운 방법을 사용할 수 있습니다. -`frame` 옵션을 `false`로 지정하여 제목과 창 구성 요소를 모두 비활성화하는 대신 새로운 `title-bar-style` -옵션을 통해 제목만 숨기고 창 구성 요소("흔히 신호등으로 알고 있는")의 기능과 창 크기를 그대로 유지할 수 있습니다: +OS X 10.10 Yosemite 이후의 최신 버전부터는 테두리가 없는 창을 만들 때 새로운 방법을 +사용할 수 있습니다. `frame` 옵션을 `false`로 지정하여 제목과 창 구성 요소를 모두 +비활성화하는 대신 새로운 `title-bar-style` 옵션을 통해 제목만 숨기고 창 구성 요소 +("흔히 신호등으로 알고 있는")의 기능과 창 크기를 그대로 유지할 수 있습니다: ```javascript var win = new BrowserWindow({ 'title-bar-style': 'hidden' }); @@ -25,7 +28,8 @@ var win = new BrowserWindow({ 'title-bar-style': 'hidden' }); ## 투명한 창 만들기 -Frameless Window 창의 배경을 투명하게 만들고 싶다면 `transparent` 옵션을 `true`로 바꿔주기만 하면됩니다: +Frameless Window 창의 배경을 투명하게 만들고 싶다면 `transparent` 옵션을 `true`로 +바꿔주기만 하면됩니다: ```javascript var win = new BrowserWindow({ transparent: true, frame: false }); @@ -33,30 +37,38 @@ var win = new BrowserWindow({ transparent: true, frame: false }); ### API의 한계 -* 투명한 영역을 통과하여 클릭할 수 없습니다. 우리는 이 문제를 해결하기 위해 API를 제공할 예정이었지만 현재로써는 - [upstream 버그](https://code.google.com/p/chromium/issues/detail?id=387234)로 인해 중단된 상태입니다. -* 투명한 창은 크기를 조절할 수 없습니다. `resizable` 속성을 `true`로 할 경우 몇몇 플랫폼에선 크래시가 일어납니다. -* `blur` 필터는 웹 페이지에서만 적용됩니다. 윈도우 아래 컨텐츠에는 블러 효과를 적용할 방법이 없습니다. (예시: 유저의 시스템에 열린 다른 어플리케이션) -* Windows에선 DWM(데스크톱 창 관리자)가 비활성화되어 있을 경우 투명한 창이 작동하지 않습니다. +* 투명한 영역을 통과하여 클릭할 수 없습니다. 우리는 이 문제를 해결하기 위해 API를 + 제공할 예정이었지만 현재로써는 [upstream 버그](https://code.google.com/p/chromium/issues/detail?id=387234)로 + 인해 중단된 상태입니다. +* 투명한 창은 크기를 조절할 수 없습니다. `resizable` 속성을 `true`로 할 경우 몇몇 + 플랫폼에선 크래시가 일어납니다. +* `blur` 필터는 웹 페이지에서만 적용됩니다. 윈도우 아래 컨텐츠에는 블러 효과를 적용할 + 방법이 없습니다. (예시: 유저의 시스템에 열린 다른 어플리케이션) +* Windows에선 DWM(데스크톱 창 관리자)가 비활성화되어 있을 경우 투명한 창이 작동하지 + 않습니다. * Linux를 사용할 경우 [alpha channel doesn't work on some NVidia drivers](https://code.google.com/p/chromium/issues/detail?id=369209) - upstream 버그가 있는 관계로 투명한 창 기능을 사용하려면 CLI 옵션에 `--enable-transparent-visuals --disable-gpu`을 추가해야 합니다. - 이 옵션은 GPU의 사용을 중단하고 윈도우를 생성하는데 ARGB를 사용할 수 있도록 해줍니다. + upstream 버그가 있는 관계로 투명한 창 기능을 사용하려면 CLI 옵션에 + `--enable-transparent-visuals --disable-gpu`을 추가해야 합니다. 이 옵션은 GPU의 + 사용을 중단하고 윈도우를 생성하는데 ARGB를 사용할 수 있도록 해줍니다. * OS X(Mac)에선 네이티브 창에서 보여지는 그림자가 투명한 창에선 보이지 않습니다. ## 드래그 가능 위치 지정 -기본적으로 Frameless Window는 드래그 할 수 없습니다. -어플리케이션의 CSS에서 특정 범위를 `-webkit-app-region: drag`로 지정하면 OS의 기본 타이틀 바 처럼 드래그 되도록 할 수 있습니다. -그리고 `-webkit-app-region: no-drag`를 지정해서 드래그 불가능 영역을 만들 수도 있습니다. 현재 사각형 형태의 범위만 지원합니다. +기본적으로 Frameless Window는 드래그 할 수 없습니다. 어플리케이션의 CSS에서 특정 +범위를 `-webkit-app-region: drag`로 지정하면 OS의 기본 타이틀 바 처럼 드래그 되도록 +할 수 있습니다. 그리고 `-webkit-app-region: no-drag`를 지정해서 드래그 불가능 영역을 +만들 수도 있습니다. 현재 사각형 형태의 범위만 지원합니다. -창 전체를 드래그 가능하게 만드려면 `-webkit-app-region: drag`을 `body`의 스타일에 지정하면 됩니다: +창 전체를 드래그 가능하게 만드려면 `-webkit-app-region: drag`을 `body`의 스타일에 +지정하면 됩니다: ```html ``` -참고로 창 전체를 드래그 영역으로 지정할 경우 사용자가 버튼을 클릭할 수 없게 되므로 버튼은 드래그 불가능 영역으로 지정해야 합니다: +참고로 창 전체를 드래그 영역으로 지정할 경우 사용자가 버튼을 클릭할 수 없게 되므로 +버튼은 드래그 불가능 영역으로 지정해야 합니다: ```css button { @@ -64,13 +76,15 @@ button { } ``` -따로 커스텀 타이틀 바를 만들어 사용할 때는 타이틀 바 내부의 모든 버튼을 드래그 불가능 영역으로 지정해야 합니다. +따로 커스텀 타이틀 바를 만들어 사용할 때는 타이틀 바 내부의 모든 버튼을 드래그 불가 +영역으로 지정해야 합니다. ## 텍스트 선택 -Frameless Window에서 텍스트가 선택되는 드래그 동작은 혼란을 야기할 수 있습니다. -예를 들어 타이틀 바를 드래그 할 때 타이틀 바의 텍스트를 실수로 선택할 수 있습니다. -이를 방지하기 위해 다음과 같이 드래그 영역의 텍스트 선택 기능을 비활성화해야 할 필요가 있습니다: +Frameless Window에서 텍스트가 선택되는 드래그 동작은 혼란을 야기할 수 있습니다. 예를 +들어 타이틀 바를 드래그 할 때 타이틀 바의 텍스트를 실수로 선택할 수 있습니다. 이를 +방지하기 위해 다음과 같이 드래그 영역의 텍스트 선택 기능을 비활성화해야 할 필요가 +있습니다: ```css .titlebar { @@ -81,5 +95,7 @@ Frameless Window에서 텍스트가 선택되는 드래그 동작은 혼란을 ## 컨텍스트 메뉴 -몇몇 플랫폼에선 드래그 가능 영역이 non-client 프레임으로 처리됩니다. 이러한 플랫폼에선 드래그 가능 영역에서 오른쪽 클릭 할 경우 시스템 메뉴가 팝업 됩니다. -이러한 이유로 컨텍스트 메뉴 지정 시 모든 플랫폼에서 정상적으로 작동하게 하려면 커스텀 컨텍스트 메뉴를 드래그 영역 내에 만들어선 안됩니다. +몇몇 플랫폼에선 드래그 가능 영역이 non-client 프레임으로 처리됩니다. 이러한 플랫폼에선 +드래그 가능 영역에서 오른쪽 클릭 할 경우 시스템 메뉴가 팝업 됩니다. 이러한 이유로 +컨텍스트 메뉴 지정 시 모든 플랫폼에서 정상적으로 작동하게 하려면 커스텀 컨텍스트 메뉴를 +드래그 영역 내에 만들어선 안됩니다. diff --git a/docs-translations/ko-KR/api/global-shortcut.md b/docs-translations/ko-KR/api/global-shortcut.md index 2120f73cc5cb..1b8363bcbe70 100644 --- a/docs-translations/ko-KR/api/global-shortcut.md +++ b/docs-translations/ko-KR/api/global-shortcut.md @@ -1,10 +1,12 @@ # global-shortcut -`global-shortcut` 모듈은 운영체제의 전역 키보드 단축키를 등록/해제 하는 방법을 제공합니다. -이 모듈을 사용하여 사용자가 다양한 작업을 편하게 할 수 있도록 단축키를 정의 할 수 있습니다. +`global-shortcut` 모듈은 운영체제의 전역 키보드 단축키를 등록/해제 하는 방법을 +제공합니다. 이 모듈을 사용하여 사용자가 다양한 작업을 편하게 할 수 있도록 단축키를 +정의 할 수 있습니다. -**참고:** 등록된 단축키는 어플리케이션이 백그라운드로 작동(창이 포커스 되지 않음) 할 때도 계속해서 작동합니다. -이 모듈은 `app` 모듈의 `ready` 이벤트 이전에 사용할 수 없습니다. +**참고:** 등록된 단축키는 어플리케이션이 백그라운드로 작동(창이 포커스 되지 않음) 할 +때도 계속해서 작동합니다. 이 모듈은 `app` 모듈의 `ready` 이벤트 이전에 사용할 수 +없습니다. ```javascript const electron = require('electron'); @@ -43,13 +45,15 @@ app.on('will-quit', function() { * `accelerator` [Accelerator](accelerator.md) * `callback` Function -`accelerator`로 표현된 전역 단축키를 등록합니다. 유저로부터 등록된 단축키가 눌렸을 경우 `callback` 함수가 호출됩니다. +`accelerator`로 표현된 전역 단축키를 등록합니다. 유저로부터 등록된 단축키가 눌렸을 +경우 `callback` 함수가 호출됩니다. ### `globalShortcut.isRegistered(accelerator)` * `accelerator` [Accelerator](accelerator.md) -지정된 `accelerator` 단축키가 등록되었는지 여부를 확인합니다. 반환값은 boolean(true, false) 입니다. +지정된 `accelerator` 단축키가 등록되었는지 여부를 확인합니다. 반환값은 boolean값 +입니다. ### `globalShortcut.unregister(accelerator)` diff --git a/docs-translations/ko-KR/api/ipc-main.md b/docs-translations/ko-KR/api/ipc-main.md index fae8aa4d5cf6..2dffcaf79ab1 100644 --- a/docs-translations/ko-KR/api/ipc-main.md +++ b/docs-translations/ko-KR/api/ipc-main.md @@ -1,12 +1,14 @@ # ipcMain -`ipcMain` 모듈은 메인 프로세스에서 사용할 때 랜더러 프로세스(웹 페이지)에서 전달된 동기/비동기 메시지를 주고 받는 방법을 제공합니다. -랜더러 프로세스에서 메시지를 전달하면 이 모듈을 통해 메시지를 받을 수 있습니다. +`ipcMain` 모듈은 메인 프로세스에서 사용할 때 랜더러 프로세스(웹 페이지)에서 전달된 +동기/비동기 메시지를 주고 받는 방법을 제공합니다. 랜더러 프로세스에서 메시지를 전달하면 +이 모듈을 통해 메시지를 받을 수 있습니다. ## 메시지 전송 물론 메시지를 받는 것 말고도 메인 프로세스에서 랜더러 프로세스로 보내는 것도 가능합니다. -자세한 내용은 [webContents.send](web-contents.md#webcontentssendchannel-args)를 참고하세요. +자세한 내용은 [webContents.send](web-contents.md#webcontentssendchannel-args)를 +참고하세요. * 메시지를 전송할 때 이벤트 이름은 `channel`이 됩니다. * 메시지에 동기로 응답할 땐 반드시 `event.returnValue`를 설정해야 합니다. @@ -60,7 +62,8 @@ ipc.send('asynchronous-message', 'ping'); ### `Event.sender` -메시지를 보낸 `webContents` 객체를 반환합니다. `event.sender.send` 메서드를 통해 비동기로 메시지를 전달할 수 있습니다. -자세한 내용은 [webContents.send][webcontents-send]를 참고하세요. +메시지를 보낸 `webContents` 객체를 반환합니다. `event.sender.send` 메서드를 통해 +비동기로 메시지를 전달할 수 있습니다. 자세한 내용은 +[webContents.send][webcontents-send]를 참고하세요. [webcontents-send]: web-contents.md#webcontentssendchannel-args diff --git a/docs-translations/ko-KR/api/ipc-renderer.md b/docs-translations/ko-KR/api/ipc-renderer.md index 28442a29073a..e3b646b42a27 100644 --- a/docs-translations/ko-KR/api/ipc-renderer.md +++ b/docs-translations/ko-KR/api/ipc-renderer.md @@ -1,7 +1,7 @@ # ipcRenderer -`ipcRenderer` 모듈은 랜더러 프로세스에서 메인 프로세스로 동기/비동기 메시지를 주고 받는 방법을 제공합니다. -또한 메인 프로세스로부터 받은 메시지에 응답할 수도 있습니다. +`ipcRenderer` 모듈은 랜더러 프로세스에서 메인 프로세스로 동기/비동기 메시지를 주고 +받는 방법을 제공합니다. 또한 메인 프로세스로부터 받은 메시지에 응답할 수도 있습니다. [ipcMain](ipc-main.md)에서 코드 예제를 확인할 수 있습니다. @@ -25,24 +25,29 @@ * `channel` String - 이벤트 이름 * `arg` (optional) -`channel`을 통해 메인 프로세스에 비동기 메시지를 보냅니다. 그리고 필요에 따라 임의의 인자를 사용할 수도 있습니다. -메인 프로세스는 `ipcMain` 모듈의 `channel` 이벤트를 통해 이벤트를 리스닝 할 수 있습니다. +`channel`을 통해 메인 프로세스에 비동기 메시지를 보냅니다. 그리고 필요에 따라 임의의 +인자를 사용할 수도 있습니다. 메인 프로세스는 `ipcMain` 모듈의 `channel` 이벤트를 통해 +이벤트를 리스닝 할 수 있습니다. ### `ipcRenderer.sendSync(channel[, arg1][, arg2][, ...])` * `channel` String - 이벤트 이름 * `arg` (optional) -`channel`을 통해 메인 프로세스에 동기 메시지를 보냅니다. 그리고 필요에 따라 임의의 인자를 사용할 수도 있습니다. -메인 프로세스는 `ipc`를 통해 `channel` 이벤트를 리스닝 할 수 있습니다. +`channel`을 통해 메인 프로세스에 동기 메시지를 보냅니다. 그리고 필요에 따라 임의의 +인자를 사용할 수도 있습니다. 메인 프로세스는 `ipc`를 통해 `channel` 이벤트를 리스닝 +할 수 있습니다. -메인 프로세스에선 `ipc` 모듈의 `channel` 이벤트를 통해 받은 `event.returnValue`로 회신 할 수 있습니다. +메인 프로세스에선 `ipc` 모듈의 `channel` 이벤트를 통해 받은 `event.returnValue`로 +회신 할 수 있습니다. -__참고:__ 동기 메서드는 모든 랜더러 프로세스의 작업을 일시 중단시킵니다. 사용 목적이 확실하지 않다면 사용하지 않는 것이 좋습니다. +__참고:__ 동기 메서드는 모든 랜더러 프로세스의 작업을 일시 중단시킵니다. 사용 목적이 +확실하지 않다면 사용하지 않는 것이 좋습니다. ### `ipcRenderer.sendToHost(channel[, arg1][, arg2][, ...])` * `channel` String - 이벤트 이름 * `arg` (optional) -`ipcRenderer.send`와 비슷하지만 이벤트를 메인 프로세스 대신 호스트 페이지내의 `` 요소로 보냅니다. +`ipcRenderer.send`와 비슷하지만 이벤트를 메인 프로세스 대신 호스트 페이지내의 +`` 요소로 보냅니다. diff --git a/docs-translations/ko-KR/api/menu-item.md b/docs-translations/ko-KR/api/menu-item.md index dfcc4fcb2413..388df1c7d571 100644 --- a/docs-translations/ko-KR/api/menu-item.md +++ b/docs-translations/ko-KR/api/menu-item.md @@ -1,6 +1,7 @@ # MenuItem -`menu-item` 모듈은 어플리케이션 또는 컨텍스트 [`menu`](menu.md)에 항목 아이템을 추가할 수 있도록 관련 클래스를 제공합니다. +`menu-item` 모듈은 어플리케이션 또는 컨텍스트 [`menu`](menu.md)에 항목 아이템을 +추가할 수 있도록 관련 클래스를 제공합니다. [`menu`](menu.md)에서 예제를 확인할 수 있습니다. @@ -11,9 +12,12 @@ ### new MenuItem(options) * `options` Object - * `click` Function - 메뉴 아이템이 클릭될 때 `click(menuItem, browserWindow)` 형태로 호출 되는 콜백 함수 - * `role` String - 메뉴 아이템의 액션을 정의합니다. 이 속성을 지정하면 `click` 속성이 무시됩니다. - * `type` String - `MenuItem`의 타입 `normal`, `separator`, `submenu`, `checkbox` 또는 `radio` 사용가능 + * `click` Function - 메뉴 아이템이 클릭될 때 `click(menuItem, browserWindow)` + 형태로 호출 되는 콜백 함수 + * `role` String - 메뉴 아이템의 액션을 정의합니다. 이 속성을 지정하면 `click` + 속성이 무시됩니다. + * `type` String - `MenuItem`의 타입 `normal`, `separator`, `submenu`, + `checkbox` 또는 `radio` 사용가능 * `label` String * `sublabel` String * `accelerator` [Accelerator](accelerator.md) @@ -21,11 +25,15 @@ * `enabled` Boolean * `visible` Boolean * `checked` Boolean - * `submenu` Menu - 보조메뉴를 설정합니다. `type`이 `submenu`일 경우 반드시 설정해야합니다. 일반 메뉴 아이템일 경우 생략할 수 있습니다. - * `id` String - 현재 메뉴 아이템에 대해 유일키를 지정합니다. 이 키는 이후 `position` 옵션에서 사용할 수 있습니다. - * `position` String - 미리 지정한 `id`를 이용하여 메뉴 아이템의 위치를 세밀하게 조정합니다. + * `submenu` Menu - 보조메뉴를 설정합니다. `type`이 `submenu`일 경우 반드시 + 설정해야 합니다. 일반 메뉴 아이템일 경우 생략할 수 있습니다. + * `id` String - 현재 메뉴 아이템에 대해 유일키를 지정합니다. 이 키는 이후 + `position` 옵션에서 사용할 수 있습니다. + * `position` String - 미리 지정한 `id`를 이용하여 메뉴 아이템의 위치를 세밀하게 + 조정합니다. -메뉴 아이템을 생성할 때, 다음 목록과 일치하는 표준 동작은 수동으로 직접 구현하는 대신 `role` 속성을 지정하여 고유 OS 경험을 최대한 살릴 수 있습니다. +메뉴 아이템을 생성할 때, 다음 목록과 일치하는 표준 동작은 수동으로 직접 구현하는 대신 +`role` 속성을 지정하여 고유 OS 경험을 최대한 살릴 수 있습니다. `role` 속성은 다음 값을 가질 수 있습니다: diff --git a/docs-translations/ko-KR/api/menu.md b/docs-translations/ko-KR/api/menu.md index d55fa807a362..3c5740de53a4 100644 --- a/docs-translations/ko-KR/api/menu.md +++ b/docs-translations/ko-KR/api/menu.md @@ -1,12 +1,14 @@ # Menu -`menu` 클래스는 어플리케이션 메뉴와 [컨텍스트 메뉴](https://developer.mozilla.org/en-US/docs/Mozilla/Tech/XUL/PopupGuide/ContextMenus)를 만들 때 사용됩니다. -이 모듈은 메인 프로세스용 모듈이지만 `remote` 모듈을 통해 랜더러 프로세스에서도 사용할 수 있습니다. +`menu` 클래스는 어플리케이션 메뉴와 [컨텍스트 메뉴](https://developer.mozilla.org/en-US/docs/Mozilla/Tech/XUL/PopupGuide/ContextMenus)를 +만들 때 사용됩니다. 이 모듈은 메인 프로세스용 모듈이지만 `remote` 모듈을 통해 랜더러 +프로세스에서도 사용할 수 있습니다. 각 메뉴는 여러 개의 [메뉴 아이템](menu-item.md)으로 구성되고 서브 메뉴를 가질 수도 있습니다. -다음 예제는 웹 페이지 내에서 [remote](remote.md) 모듈을 활용하여 동적으로 메뉴를 생성하는 예제입니다. -그리고 유저가 페이지에서 오른쪽 클릭을 할 때마다 마우스 위치에 팝업 형태로 메뉴를 표시합니다: +다음 예제는 웹 페이지 내에서 [remote](remote.md) 모듈을 활용하여 동적으로 메뉴를 +생성하는 예제입니다. 그리고 유저가 페이지에서 오른쪽 클릭을 할 때마다 마우스 위치에 +팝업 형태로 메뉴를 표시합니다: ```html @@ -27,7 +29,8 @@ window.addEventListener('contextmenu', function (e) { ``` -또 하나의 예를 들자면 다음 예제는 랜더러 프로세스에서 template API를 사용하여 어플리케이션 메뉴를 만듭니다: +또 하나의 예를 들자면 다음 예제는 랜더러 프로세스에서 template API를 사용하여 +어플리케이션 메뉴를 만듭니다: ```javascript var template = [ @@ -210,14 +213,15 @@ Menu.setApplicationMenu(menu); * `menu` Menu -지정한 `menu`를 어플리케이션 메뉴로 만듭니다. OS X에선 상단바에 표시되며 Windows와 Linux에선 각 창의 상단에 표시됩니다. +지정한 `menu`를 어플리케이션 메뉴로 만듭니다. OS X에선 상단바에 표시되며 Windows와 +Linux에선 각 창의 상단에 표시됩니다. ### `Menu.sendActionToFirstResponder(action)` _OS X_ * `action` String -`action`을 어플리케이션의 first responder에 전달합니다. -이 메서드는 Cocoa 메뉴 동작을 에뮬레이트 하는데 사용되며 보통 `MenuItem`의 `selector` 속성에 사용됩니다. +`action`을 어플리케이션의 first responder에 전달합니다. 이 메서드는 Cocoa 메뉴 +동작을 에뮬레이트 하는데 사용되며 보통 `MenuItem`의 `selector` 속성에 사용됩니다. **참고:** 이 메서드는 OS X에서만 사용할 수 있습니다. @@ -225,9 +229,11 @@ Menu.setApplicationMenu(menu); * `template` Array -기본적으로 `template`는 [MenuItem](menu-item.md)을 생성할 때 사용하는 `options`의 배열입니다. 사용법은 위에서 설명한 것과 같습니다. +기본적으로 `template`는 [MenuItem](menu-item.md)을 생성할 때 사용하는 `options`의 +배열입니다. 사용법은 위에서 설명한 것과 같습니다. -또한 `template`에는 다른 속성도 추가할 수 있으며 메뉴가 만들어질 때 해당 메뉴 아이템의 프로퍼티로 변환됩니다. +또한 `template`에는 다른 속성도 추가할 수 있으며 메뉴가 만들어질 때 해당 메뉴 아이템의 +프로퍼티로 변환됩니다. ### `Menu.popup([browserWindow, x, y])` @@ -235,9 +241,8 @@ Menu.setApplicationMenu(menu); * `x` Number (optional) * `y` Number (만약 `x`를 지정했을 경우 반드시 `y`도 지정해야 합니다) -메뉴를 `browserWindow` 내부 팝업으로 표시합니다. -옵션으로 메뉴를 표시할 `(x,y)` 좌표를 지정할 수 있습니다. -따로 좌표를 지정하지 않은 경우 마우스 커서 위치에 표시됩니다. +메뉴를 `browserWindow` 내부 팝업으로 표시합니다. 옵션으로 메뉴를 표시할 `(x,y)` +좌표를 지정할 수 있습니다. 따로 좌표를 지정하지 않은 경우 마우스 커서 위치에 표시됩니다. ### `Menu.append(menuItem)` @@ -259,13 +264,14 @@ Menu.setApplicationMenu(menu); ## OS X 어플리케이션 메뉴에 대해 알아 둬야 할 것들 OS X에선 Windows, Linux와 달리 완전히 다른 어플리케이션 메뉴 스타일을 가지고 있습니다. -그래서 어플리케이션을 네이티브처럼 작동할 수 있도록 하기 위해 다음 몇 가지 유의 사항을 숙지해야 합니다. +그래서 어플리케이션을 네이티브처럼 작동할 수 있도록 하기 위해 다음 몇 가지 유의 사항을 +숙지해야 합니다. ### 기본 메뉴 -OS X엔 `Services`나 `Windows`와 같은 많은 시스템 지정 기본 메뉴가 있습니다. -기본 메뉴를 만들려면 반드시 다음 리스트 중 한 가지를 선택하여 메뉴의 `role`로 지정해야 합니다. -그러면 Electron이 자동으로 인식하여 해당 메뉴를 기본 메뉴로 만듭니다: +OS X엔 `Services`나 `Windows`와 같은 많은 시스템 지정 기본 메뉴가 있습니다. 기본 +메뉴를 만들려면 반드시 다음 리스트 중 한 가지를 선택하여 메뉴의 `role`로 지정해야 +합니다. 그러면 Electron이 자동으로 인식하여 해당 메뉴를 기본 메뉴로 만듭니다: * `window` * `help` @@ -273,29 +279,38 @@ OS X엔 `Services`나 `Windows`와 같은 많은 시스템 지정 기본 메뉴 ### 메뉴 아이템 기본 동작 -OS X는 몇가지 메뉴 아이템에 대해 `About xxx`, `Hide xxx`, `Hide Others`와 같은 기본 동작을 제공하고 있습니다. -메뉴 아이템의 기본 동작을 지정하려면 반드시 메뉴 아이템의 `role` 속성을 지정해야 합니다. +OS X는 몇가지 메뉴 아이템에 대해 `About xxx`, `Hide xxx`, `Hide Others`와 같은 +기본 동작을 제공하고 있습니다. 메뉴 아이템의 기본 동작을 지정하려면 반드시 메뉴 +아이템의 `role` 속성을 지정해야 합니다. ### 메인 메뉴의 이름 -OS X에선 지정한 어플리케이션 메뉴에 상관없이 메뉴의 첫번째 라벨은 언제나 어플리케이션의 이름이 됩니다. -어플리케이션 이름을 변경하려면 앱 번들내의 `Info.plist` 파일을 수정해야합니다. -자세한 내용은 [About Information Property List Files][AboutInformationPropertyListFiles] 문서를 참고하세요. +OS X에선 지정한 어플리케이션 메뉴에 상관없이 메뉴의 첫번째 라벨은 언제나 어플리케이션의 +이름이 됩니다. 어플리케이션 이름을 변경하려면 앱 번들내의 `Info.plist` 파일을 수정해야 +합니다. 자세한 내용은 [About Information Property List Files][AboutInformationPropertyListFiles] 문서를 참고하세요. ## 메뉴 아이템 위치 -`Menu.buildFromTemplate`로 메뉴를 만들 때 `position`과 `id`를 사용해서 아이템의 위치를 지정할 수 있습니다. +`Menu.buildFromTemplate`로 메뉴를 만들 때 `position`과 `id`를 사용해서 아이템의 +위치를 지정할 수 있습니다. -`MenuItem`의 `position` 속성은 `[placement]=[id]`와 같은 형식을 가지며 `placement`는 -`before`, `after`, `endof` 속성 중 한가지를 사용할 수 있고 `id`는 메뉴 아이템이 가지는 유일 ID 입니다: +`MenuItem`의 `position` 속성은 `[placement]=[id]`와 같은 형식을 가지며 +`placement`는 `before`, `after`, `endof` 속성 중 한가지를 사용할 수 있고 `id`는 +메뉴 아이템이 가지는 유일 ID 입니다: -* `before` - 이 아이템을 지정한 id 이전의 위치에 삽입합니다. 만약 참조된 아이템이 없을 경우 메뉴의 맨 뒤에 삽입됩니다. -* `after` - 이 아이템을 지정한 id 다음의 위치에 삽입합니다. 만약 참조된 아이템이 없을 경우 메뉴의 맨 뒤에 삽입됩니다. -* `endof` - 이 아이템을 id의 논리 그룹에 맞춰서 각 그룹의 항목 뒤에 삽입합니다. (그룹은 분리자 아이템에 의해 만들어집니다) - 만약 참조된 아이템의 분리자 그룹이 존재하지 않을 경우 지정된 id로 새로운 분리자 그룹을 만든 후 해당 그룹의 뒤에 삽입됩니다. +* `before` - 이 아이템을 지정한 id 이전의 위치에 삽입합니다. 만약 참조된 아이템이 + 없을 경우 메뉴의 맨 뒤에 삽입됩니다. +* `after` - 이 아이템을 지정한 id 다음의 위치에 삽입합니다. 만약 참조된 아이템이 + 없을 경우 메뉴의 맨 뒤에 삽입됩니다. +* `endof` - 이 아이템을 id의 논리 그룹에 맞춰서 각 그룹의 항목 뒤에 삽입합니다. + (그룹은 분리자 아이템에 의해 만들어집니다) 만약 참조된 아이템의 분리자 그룹이 + 존재하지 않을 경우 지정된 id로 새로운 분리자 그룹을 만든 후 해당 그룹의 뒤에 + 삽입됩니다. -위치를 지정한 아이템의 뒤에 위치가 지정되지 않은 아이템이 있을 경우 각 아이템의 위치가 지정되기 전까지 모든 아이템이 위치가 지정된 아이템의 뒤에 삽입됩니다. -따라서 위치를 이동하고 싶은 특정 그룹의 아이템들이 있을 경우 해당 그룹의 맨 첫번째 메뉴 아이템의 위치만을 지정하면 됩니다. +위치를 지정한 아이템의 뒤에 위치가 지정되지 않은 아이템이 있을 경우 각 아이템의 위치가 +지정되기 전까지 모든 아이템이 위치가 지정된 아이템의 뒤에 삽입됩니다. 따라서 위치를 +이동하고 싶은 특정 그룹의 아이템들이 있을 경우 해당 그룹의 맨 첫번째 메뉴 아이템의 +위치만을 지정하면 됩니다. ### 예제 diff --git a/docs-translations/ko-KR/api/native-image.md b/docs-translations/ko-KR/api/native-image.md index 04d3fe57c453..917dbb3a71b8 100644 --- a/docs-translations/ko-KR/api/native-image.md +++ b/docs-translations/ko-KR/api/native-image.md @@ -1,9 +1,10 @@ # nativeImage -Electron은 파일 경로 또는 `nativeImage` 인스턴스를 통해 이미지를 사용할 수 있는 API를 가지고 있습니다. -`null`을 전달할 경우 빈 이미지가 생성됩니다. +Electron은 파일 경로 또는 `nativeImage` 인스턴스를 통해 이미지를 사용할 수 있는 API를 +가지고 있습니다. `null`을 전달할 경우 빈 이미지가 생성됩니다. -예를 들어 트레이 메뉴를 만들거나 윈도우의 아이콘을 설정할 때 다음과 같이 파일 경로를 전달하여 이미지를 사용할 수 있습니다: +예를 들어 트레이 메뉴를 만들거나 윈도우의 아이콘을 설정할 때 다음과 같이 파일 경로를 +전달하여 이미지를 사용할 수 있습니다: ```javascript var appIcon = new Tray('/Users/somebody/images/icon.png'); @@ -26,11 +27,15 @@ var appIcon = new Tray(image); ## 고해상도 이미지 -플랫폼이 high-DPI를 지원하는 경우 `@2x`와 같이 이미지의 파일명 뒤에 접미사를 추가하여 고해상도 이미지로 지정할 수 있습니다. +플랫폼이 high-DPI를 지원하는 경우 `@2x`와 같이 이미지의 파일명 뒤에 접미사를 추가하여 +고해상도 이미지로 지정할 수 있습니다. -예를 들어 `icon.png` 라는 기본 해상도의 이미지를 기준으로 크기를 두 배로 늘린 이미지를 `icon@2x.png` 처럼 지정하면 고해상도 이미지로 처리됩니다. +예를 들어 `icon.png` 라는 기본 해상도의 이미지를 기준으로 크기를 두 배로 늘린 이미지를 +`icon@2x.png` 처럼 지정하면 고해상도 이미지로 처리됩니다. -서로 다른 해상도(DPI)의 이미지를 같이 지원하고 싶다면 다중 해상도의 이미지를 접미사를 붙여 한 폴더에 같이 넣으면 됩니다. 이 이미지를 사용(로드)할 땐 따로 접미사를 붙이지 않습니다: +서로 다른 해상도(DPI)의 이미지를 같이 지원하고 싶다면 다중 해상도의 이미지를 접미사를 +붙여 한 폴더에 같이 넣으면 됩니다. 이 이미지를 사용(로드)할 땐 따로 접미사를 붙이지 +않습니다: ```text images/ @@ -60,14 +65,16 @@ var appIcon = new Tray('/Users/somebody/images/icon.png'); ## 템플릿 이미지 -템플릿 이미지는 검은색과 명확한 색상(알파 채널)으로 이루어져 있습니다. -템플릿 이미지는 단독 이미지로 사용되지 않고 다른 컨텐츠와 혼합되어 최종 외관 만드는데 사용됩니다. +템플릿 이미지는 검은색과 명확한 색상(알파 채널)으로 이루어져 있습니다. 템플릿 이미지는 +단독 이미지로 사용되지 않고 다른 컨텐츠와 혼합되어 최종 외관 만드는데 사용됩니다. -가장 일반적으로 템플릿 이미지는 밝고 어두운 테마 색상으로 변경할 수 있는 메뉴 바 아이콘 등에 사용되고 있습니다. +가장 일반적으로 템플릿 이미지는 밝고 어두운 테마 색상으로 변경할 수 있는 메뉴 바 아이콘 +등에 사용되고 있습니다. **참고:** 템플릿 이미지는 OS X 운영체제만 지원합니다. -템플릿 이미지를 지정하려면 다음 예제와 같이 파일명에 `Template` 문자열을 추가해야 합니다: +템플릿 이미지를 지정하려면 다음 예제와 같이 파일명에 `Template` 문자열을 추가해야 +합니다: * `xxxTemplate.png` * `xxxTemplate@2x.png` @@ -91,7 +98,8 @@ var appIcon = new Tray('/Users/somebody/images/icon.png'); * `buffer` [Buffer][buffer] * `scaleFactor` Double (optional) -`buffer`로부터 이미지를 로드하여 새로운 `nativeImage` 인스턴스를 만듭니다. `scaleFactor`의 기본값은 1.0 입니다. +`buffer`로부터 이미지를 로드하여 새로운 `nativeImage` 인스턴스를 만듭니다. +`scaleFactor`의 기본값은 1.0 입니다. ### `nativeImage.createFromDataURL(dataURL)` diff --git a/docs-translations/ko-KR/api/power-monitor.md b/docs-translations/ko-KR/api/power-monitor.md index e84bd9514330..29a3aabc84a1 100644 --- a/docs-translations/ko-KR/api/power-monitor.md +++ b/docs-translations/ko-KR/api/power-monitor.md @@ -1,8 +1,9 @@ # powerMonitor `power-monitor` 모듈은 PC의 파워 상태를 나타냅니다. (주로 노트북 등에서 사용됩니다) -이 모듈은 메인 프로세스에서만 사용할 수 있으며, (remote 모듈(RPC)을 사용해도 작동이 됩니다) -메인 프로세스의 `app` 모듈에서 `ready` 이벤트를 호출하기 전까지 사용할 수 없습니다. +이 모듈은 메인 프로세스에서만 사용할 수 있으며, (remote 모듈(RPC)을 사용해도 작동이 +됩니다) 메인 프로세스의 `app` 모듈에서 `ready` 이벤트를 호출하기 전까지 사용할 수 +없습니다. 예제: diff --git a/docs-translations/ko-KR/api/power-save-blocker.md b/docs-translations/ko-KR/api/power-save-blocker.md index 3a09591aaf97..560b3fc9cef5 100644 --- a/docs-translations/ko-KR/api/power-save-blocker.md +++ b/docs-translations/ko-KR/api/power-save-blocker.md @@ -1,6 +1,7 @@ # powerSaveBlocker -`powerSaveBlocker` 모듈은 시스템이 저전력(슬립) 모드로 진입하는 것을 막고 앱 시스템과 화면이 항상 활성화 상태를 유지할 수 있도록 하는 몇가지 유틸리티를 제공하는 모듈입니다. +`powerSaveBlocker` 모듈은 시스템이 저전력(슬립) 모드로 진입하는 것을 막고 앱 시스템과 +화면이 항상 활성화 상태를 유지할 수 있도록 하는 몇가지 유틸리티를 제공하는 모듈입니다. 예제: @@ -20,27 +21,36 @@ powerSaveBlocker.stop(id); ### `powerSaveBlocker.start(type)` * `type` String - Power save blocker 종류 - * `prevent-app-suspension` - 저전력 모드 등으로 인한 어플리케이션 작동 중단을 방지합니다. - 시스템을 항시 활성화 상태로 만듭니다. 하지만 화면은 자동으로 꺼질 수 있습니다. 사용 예시: 파일 다운로드, 음악 재생 등. - * `prevent-display-sleep`- 슬립 모드 등으로 인한 어플리케이션의 작동 중단을 방지합니다. - 시스템을 항시 활성화 상태로 만들고 슬립 모드(화면 꺼짐)를 방지합니다. 사용 예시: 비디오 재생 등. + * `prevent-app-suspension` - 저전력 모드 등으로 인한 어플리케이션 작동 중단을 + 방지합니다. 시스템을 항시 활성화 상태로 만듭니다. 하지만 화면은 자동으로 꺼질 수 + 있습니다. 사용 예시: 파일 다운로드, 음악 재생 등. + * `prevent-display-sleep`- 슬립 모드 등으로 인한 어플리케이션의 작동 중단을 + 방지합니다. 시스템을 항시 활성화 상태로 만들고 슬립 모드(화면 꺼짐)를 방지합니다. + 사용 예시: 비디오 재생 등. -시스템이 저전력 모드(슬립)로 진입하는 것을 막기 시작합니다. 정수로 된 식별 ID를 반환합니다. +시스템이 저전력 모드(슬립)로 진입하는 것을 막기 시작합니다. 정수로 된 식별 ID를 +반환합니다. -**참고:** `prevent-display-sleep` 모드는 `prevent-app-suspension` 보다 우선 순위가 높습니다. -두 모드 중 가장 높은 우선 순위의 모드만 작동합니다. 다시 말해 `prevent-display-sleep` 모드는 언제나 `prevent-app-suspension` 모드의 효과를 덮어씌웁니다. +**참고:** `prevent-display-sleep` 모드는 `prevent-app-suspension` 보다 우선 순위가 +높습니다. 두 모드 중 가장 높은 우선 순위의 모드만 작동합니다. 다시 말해 +`prevent-display-sleep` 모드는 언제나 `prevent-app-suspension` 모드의 효과를 +덮어씌웁니다. -예를 들어 A-요청이 `prevent-app-suspension` 모드를 사용하고 B-요청이 `prevent-display-sleep`를 사용하는 API 호출이 있었다 치면 -`prevent-display-sleep` 모드를 사용하는 B의 작동이 중단(stop)되기 전까지 작동하다 B가 중단되면 `prevent-app-suspension` 모드를 사용하는 A가 작동하기 시작합니다. +예를 들어 A-요청이 `prevent-app-suspension` 모드를 사용하고 B-요청이 +`prevent-display-sleep`를 사용하는 API 호출이 있었다 하면 `prevent-display-sleep` +모드를 사용하는 B의 작동이 중단(stop)되기 전까지 작동하다 B가 중단되면 +`prevent-app-suspension` 모드를 사용하는 A가 작동하기 시작합니다. ### `powerSaveBlocker.stop(id)` -* `id` Integer - `powerSaveBlocker.start`로 부터 반환되는 power save blocker 식별 ID. +* `id` Integer - `powerSaveBlocker.start`로부터 반환되는 power save blocker 식별 +ID. 설정한 power save blocker를 중지합니다. ### `powerSaveBlocker.isStarted(id)` -* `id` Integer - `powerSaveBlocker.start`로 부터 반환되는 power save blocker 식별 ID. +* `id` Integer - `powerSaveBlocker.start`로부터 반환되는 power save blocker 식별 +ID. 지정한 id의 `powerSaveBlocker`가 실행 중인지 확인합니다. diff --git a/docs-translations/ko-KR/api/process.md b/docs-translations/ko-KR/api/process.md index c66eb84cfeae..afbc6afd796d 100644 --- a/docs-translations/ko-KR/api/process.md +++ b/docs-translations/ko-KR/api/process.md @@ -2,19 +2,23 @@ Electron의 `process` 객체는 기존의 node와는 달리 약간의 차이점이 있습니다: -* `process.type` String - 프로세스의 타입, `browser` (메인 프로세스) 또는 `renderer`가 됩니다. +* `process.type` String - 프로세스의 타입, `browser` (메인 프로세스) 또는 + `renderer`가 됩니다. * `process.versions['electron']` String - Electron의 버전. * `process.versions['chrome']` String - Chromium의 버전. * `process.resourcesPath` String - JavaScript 소스 코드의 경로. -* `process.mas` Boolean - Mac 앱 스토어용 빌드일 때 `true`로 지정됩니다. 다른 빌드일 땐 `undefined`로 지정됩니다. +* `process.mas` Boolean - Mac 앱 스토어용 빌드일 때 `true`로 지정됩니다. 다른 + 빌드일 땐 `undefined`로 지정됩니다. ## Events ### Event: 'loaded' -Electron 내부 초기화 스크립트의 로드가 완료되고, 웹 페이지나 메인 스크립트를 로드하기 시작할 때 발생하는 이벤트입니다. +Electron 내부 초기화 스크립트의 로드가 완료되고, 웹 페이지나 메인 스크립트를 로드하기 +시작할 때 발생하는 이벤트입니다. -이 이벤트는 preload 스크립트를 통해 node 통합이 꺼져있는 전역 스코프에 node의 전역 심볼들을 다시 추가할 때 사용할 수 있습니다: +이 이벤트는 preload 스크립트를 통해 node 통합이 꺼져있는 전역 스코프에 node의 전역 +심볼들을 다시 추가할 때 사용할 수 있습니다: ```javascript // preload.js @@ -38,4 +42,5 @@ process.once('loaded', function() { * `maxDescriptors` Integer -현재 프로세스의 파일 기술자의 제한 값을 소프트 제한 `maxDescriptors`의 값이나 OS 하드 제한 중 낮은 값으로 설정합니다. +현재 프로세스 파일 디스크립터의 제한 값을 소프트 제한 `maxDescriptors`의 값이나 OS 하드 +제한 중 낮은 값으로 설정합니다. diff --git a/docs-translations/ko-KR/api/protocol.md b/docs-translations/ko-KR/api/protocol.md index f2e4ba3a5b1a..11198123e332 100644 --- a/docs-translations/ko-KR/api/protocol.md +++ b/docs-translations/ko-KR/api/protocol.md @@ -1,6 +1,7 @@ # protocol -`protocol` 모듈은 이미 있는 프로토콜의 동작을 가로채거나 새로운 프로토콜을 만들 수 있는 기능을 제공합니다. +`protocol` 모듈은 이미 있는 프로토콜의 동작을 가로채거나 새로운 프로토콜을 만들 수 +있는 기능을 제공합니다. 다음 예제는 `file://` 프로토콜과 비슷한 일을 하는 커스텀 프로토콜을 설정합니다: @@ -31,8 +32,8 @@ app.on('ready', function() { * `schemes` Array - 표준 스킴으로 등록할 커스텀 스킴 리스트 -표준 `scheme`의 형식은 RFC 3986 [일반 URI 구문](https://tools.ietf.org/html/rfc3986#section-3) 표준을 따릅니다. -이 형식은 `file:`과 `filesystem:`을 포함합니다. +표준 `scheme`의 형식은 RFC 3986 [일반 URI 구문](https://tools.ietf.org/html/rfc3986#section-3) +표준을 따릅니다. 이 형식은 `file:`과 `filesystem:`을 포함합니다. ### `protocol.registerFileProtocol(scheme, handler[, completion])` @@ -40,20 +41,23 @@ app.on('ready', function() { * `handler` Function * `completion` Function (optional) -`scheme`에 파일을 응답으로 보내는 프로토콜을 등록합니다. -`handler`는 `scheme`와 함께 `request`가 생성될 때 `handler(request, callback)` 형식으로 호출됩니다. -`completion` 콜백은 `scheme`가 성공적으로 등록되었을 때 `completion(null)` 형식으로 호출되고 -등록에 실패했을 땐 `completion(error)` 형식으로 에러 내용을 담아 호출됩니다. +`scheme`에 파일을 응답으로 보내는 프로토콜을 등록합니다. `handler`는 `scheme`와 함께 +`request`가 생성될 때 `handler(request, callback)` 형식으로 호출됩니다. +`completion` 콜백은 `scheme`가 성공적으로 등록되었을 때 `completion(null)` 형식으로 +호출되고, 등록에 실패했을 땐 `completion(error)` 형식으로 에러 내용을 담아 호출됩니다. -`request`를 처리할 때 반드시 파일 경로 또는 `path` 속성을 포함하는 객체를 인자에 포함하여 `callback`을 호출해야 합니다. -예: `callback(filePath)` 또는 `callback({path: filePath})`. +`request`를 처리할 때 반드시 파일 경로 또는 `path` 속성을 포함하는 객체를 인자에 +포함하여 `callback`을 호출해야 합니다. 예: `callback(filePath)` 또는 +`callback({path: filePath})`. -만약 `callback`이 아무 인자도 없이 호출되거나 숫자나 `error` 프로퍼티를 가진 객체가 인자로 전달될 경우 -`request`는 지정한 `error` 코드(숫자)를 출력합니다. -사용할 수 있는 에러 코드는 [네트워크 에러 목록](https://code.google.com/p/chromium/codesearch#chromium/src/net/base/net_error_list.h)에서 확인할 수 있습니다. +만약 `callback`이 아무 인자도 없이 호출되거나 숫자나 `error` 프로퍼티를 가진 객체가 +인자로 전달될 경우 `request`는 지정한 `error` 코드(숫자)를 출력합니다. 사용할 수 있는 +에러 코드는 [네트워크 에러 목록](https://code.google.com/p/chromium/codesearch#chromium/src/net/base/net_error_list.h)에서 +확인할 수 있습니다. -기본적으로 `scheme`은 `http:`와 같이 처리됩니다. `file:`과 같이 "일반적인 URI 문법"과는 다르게 인식되는 프로토콜은 -`protocol.registerStandardSchemes`을 사용하여 표준 스킴으로 처리되도록 할 수 있습니다. +기본적으로 `scheme`은 `http:`와 같이 처리됩니다. `file:`과 같이 "일반적인 URI 문법" +과는 다르게 인식되는 프로토콜은 `protocol.registerStandardSchemes`을 사용하여 표준 +스킴으로 처리되도록 할 수 있습니다. ### `protocol.registerBufferProtocol(scheme, handler[, completion])` @@ -61,8 +65,9 @@ app.on('ready', function() { * `handler` Function * `completion` Function (optional) -`scheme`에 `Buffer`를 응답으로 보내는 프로토콜을 등록합니다. -반드시 `Buffer` 또는 `data`, `mimeType`, `chart` 속성을 포함한 객체 중 하나를 인자에 포함하여 `callback`을 호출해야 합니다. +`scheme`에 `Buffer`를 응답으로 보내는 프로토콜을 등록합니다. 반드시 `Buffer` 또는 +`data`, `mimeType`, `chart` 속성을 포함한 객체 중 하나를 인자에 포함하여 +`callback`을 호출해야 합니다. 예제: @@ -81,8 +86,9 @@ protocol.registerBufferProtocol('atom', function(request, callback) { * `handler` Function * `completion` Function (optional) -`scheme`에 `문자열`을 응답으로 보내는 프로토콜을 등록합니다. -반드시 `문자열` 또는 `data`, `mimeType`, `chart` 속성을 포함한 객체 중 하나를 인자에 포함하여 `callback`을 호출해야 합니다. +`scheme`에 `문자열`을 응답으로 보내는 프로토콜을 등록합니다. 반드시 `문자열` 또는 +`data`, `mimeType`, `chart` 속성을 포함한 객체 중 하나를 인자에 포함하여 +`callback`을 호출해야 합니다. ### `protocol.registerHttpProtocol(scheme, handler[, completion])` @@ -90,10 +96,12 @@ protocol.registerBufferProtocol('atom', function(request, callback) { * `handler` Function * `completion` Function (optional) -`scheme`에 HTTP 요청을 응답으로 보내는 프로토콜을 등록합니다. -반드시 `url`, `method`, `referer`, `session` 속성을 포함하는 객체를 인자에 포함하여 `callback`을 호출해야 합니다. +`scheme`에 HTTP 요청을 응답으로 보내는 프로토콜을 등록합니다. 반드시 `url`, +`method`, `referer`, `session` 속성을 포함하는 객체를 인자에 포함하여 `callback`을 +호출해야 합니다. -기본적으로 HTTP 요청은 현재 세션을 재사용합니다. 만약 서로 다른 세션에 요청을 보내고 싶으면 `session`을 `null`로 지정해야 합니다. +기본적으로 HTTP 요청은 현재 세션을 재사용합니다. 만약 서로 다른 세션에 요청을 보내고 +싶으면 `session`을 `null`로 지정해야 합니다. ### `protocol.unregisterProtocol(scheme[, completion])` @@ -107,7 +115,8 @@ protocol.registerBufferProtocol('atom', function(request, callback) { * `scheme` String * `callback` Function -`scheme`에 동작(handler)이 등록되어 있는지 여부를 확인합니다. `callback`으로 결과(boolean)가 반환됩니다. +`scheme`에 동작(handler)이 등록되어 있는지 여부를 확인합니다. `callback`으로 +결과(boolean)가 반환됩니다. ### `protocol.interceptFileProtocol(scheme, handler[, completion])` @@ -131,7 +140,8 @@ protocol.registerBufferProtocol('atom', function(request, callback) { * `handler` Function * `completion` Function (optional) -`scheme` 프로토콜을 가로채고 `handler`를 `Buffer` 전송에 대한 새로운 동작으로 사용합니다. +`scheme` 프로토콜을 가로채고 `handler`를 `Buffer` 전송에 대한 새로운 동작으로 +사용합니다. ### `protocol.interceptHttpProtocol(scheme, handler[, completion])` @@ -139,7 +149,8 @@ protocol.registerBufferProtocol('atom', function(request, callback) { * `handler` Function * `completion` Function (optional) -`scheme` 프로토콜을 가로채고 `handler`를 HTTP 프로토콜의 요청에 대한 새로운 동작으로 사용합니다. +`scheme` 프로토콜을 가로채고 `handler`를 HTTP 프로토콜의 요청에 대한 새로운 동작으로 +사용합니다. ### `protocol.uninterceptProtocol(scheme[, completion])` diff --git a/docs-translations/ko-KR/api/remote.md b/docs-translations/ko-KR/api/remote.md index d8e84f0caed9..935b09865130 100644 --- a/docs-translations/ko-KR/api/remote.md +++ b/docs-translations/ko-KR/api/remote.md @@ -1,11 +1,13 @@ # remote -`remote` 모듈은 메인 프로세스와 랜더러 프로세스(웹 페이지) 사이의 inter-process (IPC) 통신을 간단하게 추상화 한 모듈입니다. +`remote` 모듈은 메인 프로세스와 랜더러 프로세스(웹 페이지) 사이의 inter-process +(IPC) 통신을 간단하게 추상화 한 모듈입니다. -Electron의 메인 프로세스에선 GUI와 관련 있는(`dialog`, `menu`등) 모듈만 사용할 수 있습니다. -랜더러 프로세스에서 이러한 모듈들을 사용하려면 `ipc` 모듈을 통해 메인 프로세스와 inter-process 통신을 해야합니다. -또한, `remote` 모듈을 사용하면 inter-process 통신을 하지 않고도 간단한 API를 통해 직접 메인 프로세스의 모듈과 메서드를 사용할 수 있습니다. -이 개념은 Java의 [RMI][rmi]와 비슷합니다. +Electron의 메인 프로세스에선 GUI와 관련 있는(`dialog`, `menu`등) 모듈만 사용할 수 +있습니다. 랜더러 프로세스에서 이러한 모듈들을 사용하려면 `ipc` 모듈을 통해 메인 +프로세스와 inter-process 통신을 해야합니다. 또한, `remote` 모듈을 사용하면 +inter-process 통신을 하지 않고도 간단한 API를 통해 직접 메인 프로세스의 모듈과 +메서드를 사용할 수 있습니다. 이 개념은 Java의 [RMI][rmi]와 비슷합니다. 다음 예제는 랜더러 프로세스에서 브라우저 창을 만드는 예제입니다: @@ -17,35 +19,44 @@ var win = new BrowserWindow({ width: 800, height: 600 }); win.loadURL('https://github.com'); ``` -**참고:** 반대로 메인 프로세스에서 랜더러 프로세스에 접근 하려면 [webContents.executeJavascript](web-contents.md#webcontentsexecutejavascriptcode-usergesture) 메서드를 사용하면 됩니다. +**참고:** 반대로 메인 프로세스에서 랜더러 프로세스에 접근 하려면 [webContents.executeJavascript](web-contents.md#webcontentsexecutejavascriptcode-usergesture) +메서드를 사용하면 됩니다. ## Remote 객체 -`remote` 모듈로부터 반환된 각 객체(메서드 포함)는 메인 프로세스의 객체를 추상화 한 객체입니다. (우리는 그것을 remote 객체 또는 remote 함수라고 부릅니다) -Remote 모듈의 메서드를 호출하거나, 객체에 접근하거나, 생성자로 객체를 생성하는 등의 작업은 실질적으로 동기형 inter-process 메시지를 보냅니다. +`remote` 모듈로부터 반환된 각 객체(메서드 포함)는 메인 프로세스의 객체를 추상화 한 +객체입니다. (우리는 그것을 remote 객체 또는 remote 함수라고 부릅니다) Remote 모듈의 +메서드를 호출하거나, 객체에 접근하거나, 생성자로 객체를 생성하는 등의 작업은 실질적으로 +동기형 inter-process 메시지를 보냅니다. -위의 예제에서 사용한 두 `BrowserWindow`와 `win`은 remote 객체입니다. 그리고 `new BrowserWindow`이 생성하는 `BrowserWindow` 객체는 랜더러 프로세스에서 생성되지 않습니다. -대신에 이 `BrowserWindow` 객체는 메인 프로세스에서 생성되며 랜더러 프로세스에 `win` 객체와 같이 이에 대응하는 remote 객체를 반환합니다. +위의 예제에서 사용한 두 `BrowserWindow`와 `win`은 remote 객체입니다. 그리고 +`new BrowserWindow`이 생성하는 `BrowserWindow` 객체는 랜더러 프로세스에서 생성되지 +않습니다. 대신에 이 `BrowserWindow` 객체는 메인 프로세스에서 생성되며 랜더러 +프로세스에 `win` 객체와 같이 이에 대응하는 remote 객체를 반환합니다. ## Remote 객체의 생명 주기 -Electron은 랜더러 프로세스의 remote 객체가 살아있는 한(다시 말해서 GC(garbage collection)가 일어나지 않습니다) 대응하는 메인 프로세스의 객체는 릴리즈되지 않습니다. +Electron은 랜더러 프로세스의 remote 객체가 살아있는 한(다시 말해서 GC(garbage +collection)가 일어나지 않습니다) 대응하는 메인 프로세스의 객체는 릴리즈되지 않습니다. Remote 객체가 GC 되려면 대응하는 메인 프로세스 내부 객체의 참조가 해제되어야만 합니다. -만약 remote 객체가 랜더러 프로세스에서 누수가 생겼다면 (예시: 맵에 저장하고 할당 해제하지 않음) 대응하는 메인 프로세스의 객체도 누수가 생깁니다. -그래서 remote 객체를 사용할 땐 메모리 누수가 생기지 않도록 매우 주의해서 사용해야 합니다. +만약 remote 객체가 랜더러 프로세스에서 누수가 생겼다면 (예시: 맵에 저장하고 할당 +해제하지 않음) 대응하는 메인 프로세스의 객체도 누수가 생깁니다. 그래서 remote 객체를 +사용할 땐 메모리 누수가 생기지 않도록 매우 주의해서 사용해야 합니다. 참고로 문자열, 숫자와 같은 원시 값 타입은 복사에 의한 참조로 전달됩니다. ## 메인 프로세스로 콜백 넘기기 -메인 프로세스의 코드는 `remote` 모듈을 통해 랜더러 프로세스가 전달하는 콜백 함수를 받을 수 있습니다. -하지만 이 작업은 반드시 주의를 기울여 사용해야 합니다. +메인 프로세스의 코드는 `remote` 모듈을 통해 랜더러 프로세스가 전달하는 콜백 함수를 +받을 수 있습니다. 하지만 이 작업은 반드시 주의를 기울여 사용해야 합니다. -첫째, 데드락을 피하기 위해 메인 프로세스로 전달된 콜백들은 비동기로 호출됩니다. -이러한 이유로 메인 프로세스로 전달된 콜백들의 반환 값을 내부 함수에서 언제나 정상적으로 받을 것이라고 예측해선 안됩니다. +첫째, 데드락을 피하기 위해 메인 프로세스로 전달된 콜백들은 비동기로 호출됩니다. 이러한 +이유로 메인 프로세스로 전달된 콜백들의 반환 값을 내부 함수에서 언제나 정상적으로 받을 +것이라고 예측해선 안됩니다. -예를 들어 메인 프로세스에서 `Array.map` 같은 메서드를 사용할 때 랜더러 프로세스에서 전달된 함수를 사용해선 안됩니다: +예를 들어 메인 프로세스에서 `Array.map` 같은 메서드를 사용할 때 랜더러 프로세스에서 +전달된 함수를 사용해선 안됩니다: ```javascript // mapNumbers.js 메인 프로세스 @@ -76,10 +87,12 @@ console.log(withRendererCb, withLocalCb) // [true, true, true], [2, 3, 4] 보다시피 랜더러 콜백의 동기 반환 값은 예상되지 않은 처리입니다. 그리고 메인 프로세스에서 처리한 함수의 반환 값과 일치하지 않습니다. -둘째, 콜백들은 메인 프로세스로 전달, 호출된 이후에도 자동으로 함수의 참조가 릴리즈 되지 않습니다. -함수 참조는 메인 프로세스에서 GC가 일어나기 전까지 계속 프로세스에 남아있게 됩니다. +둘째, 콜백들은 메인 프로세스로 전달, 호출된 이후에도 자동으로 함수의 참조가 릴리즈 되지 +않습니다. 함수 참조는 메인 프로세스에서 GC가 일어나기 전까지 계속 프로세스에 남아있게 +됩니다. -다음 코드를 보면 느낌이 올 것입니다. 이 예제는 remote 객체에 `close` 이벤트 콜백을 설치합니다: +다음 코드를 보면 느낌이 올 것입니다. 이 예제는 remote 객체에 `close` 이벤트 콜백을 +설치합니다: ```javascript var remote = require('remote'); @@ -89,19 +102,23 @@ remote.getCurrentWindow().on('close', function() { }); ``` -하지만 이 코드 처럼 이벤트를 명시적으로 제거하지 않는 이상 콜백 함수의 참조가 계속해서 메인 프로세스에 남아있게 됩니다. -만약 명시적으로 콜백을 제거하지 않으면 매 번 창을 새로고침 할 때마다 콜백을 새로 설치합니다. -게다가 이전 콜백이 제거되지 않고 계속해서 쌓이면서 메모리 누수가 발생합니다. +하지만 이 코드 처럼 이벤트를 명시적으로 제거하지 않는 이상 콜백 함수의 참조가 계속해서 +메인 프로세스에 남아있게 됩니다. 만약 명시적으로 콜백을 제거하지 않으면 매 번 창을 +새로고침 할 때마다 콜백을 새로 설치합니다. 게다가 이전 콜백이 제거되지 않고 계속해서 +쌓이면서 메모리 누수가 발생합니다. -설상가상으로 이전에 설치된 콜백의 콘텍스트가 릴리즈 되고 난 후(예: 페이지 새로고침) `close` 이벤트가 발생하면 예외가 발생하고 메인 프로세스가 작동 중지됩니다. +설상가상으로 이전에 설치된 콜백의 콘텍스트가 릴리즈 되고 난 후(예: 페이지 새로고침) +`close` 이벤트가 발생하면 예외가 발생하고 메인 프로세스가 작동 중지됩니다. -이러한 문제를 피하려면 랜더러 프로세스에서 메인 프로세스로 넘긴 함수의 참조를 사용 후 확실하게 제거해야 합니다. -작업 후 이벤트 콜백을 포함하여 책임 있게 함수의 참조를 제거하거나 메인 프로세스에서 랜더러 프로세스가 종료될 때 내부적으로 함수 참조를 제거하도록 설계해야 합니다. +이러한 문제를 피하려면 랜더러 프로세스에서 메인 프로세스로 넘긴 함수의 참조를 사용 후 +확실하게 제거해야 합니다. 작업 후 이벤트 콜백을 포함하여 책임 있게 함수의 참조를 +제거하거나 메인 프로세스에서 랜더러 프로세스가 종료될 때 내부적으로 함수 참조를 +제거하도록 설계해야 합니다. ## 메인 프로세스의 빌트인 모듈에 접근 -메인 프로세스의 빌트인 모듈은 `remote` 모듈에 getter로 등록되어 있습니다. -따라서 `remote` 모듈을 `electron` 모듈처럼 직접 사용할 수 있습니다. +메인 프로세스의 빌트인 모듈은 `remote` 모듈에 getter로 등록되어 있습니다. 따라서 +`remote` 모듈을 `electron` 모듈처럼 직접 사용할 수 있습니다. ```javascript const app = remote.app; @@ -133,6 +150,7 @@ const app = remote.app; ### `remote.process` -메인 프로세스의 `process` 객체를 반환합니다. `remote.getGlobal('process')`와 같습니다. 하지만 캐시 됩니다. +메인 프로세스의 `process` 객체를 반환합니다. `remote.getGlobal('process')`와 +같습니다. 하지만 캐시 됩니다. -[rmi]: http://en.wikipedia.org/wiki/Java_remote_method_invocation \ No newline at end of file +[rmi]: http://en.wikipedia.org/wiki/Java_remote_method_invocation diff --git a/docs-translations/ko-KR/api/screen.md b/docs-translations/ko-KR/api/screen.md index 62b717277300..dfd85fb446e1 100644 --- a/docs-translations/ko-KR/api/screen.md +++ b/docs-translations/ko-KR/api/screen.md @@ -3,10 +3,12 @@ `screen` 모듈은 화면 크기, 디스플레이, 커서 위치 등등의 다양한 정보를 가져옵니다. 이 모듈은 `app` 모듈의 `ready` 이벤트가 발생하기 전까지 사용할 수 없습니다. -`screen`은 [EventEmitter](http://nodejs.org/api/events.html#events_class_events_eventemitter)를 상속 받았습니다. +`screen`은 [EventEmitter](http://nodejs.org/api/events.html#events_class_events_eventemitter)를 +상속 받았습니다. -**참고:** 랜더러 / DevTools에선 이미 DOM 속성이 `window.screen`을 가지고 있으므로 `screen = require('screen')` 형식으로 모듈을 사용할 수 없습니다. -아래의 예제와 같이 `electronScreen` 같은 이름으로 모듈 이름을 대체하여 사용해야 합니다. +**참고:** 랜더러 / DevTools에선 이미 DOM 속성이 `window.screen`을 가지고 있으므로 +`screen = require('screen')` 형식으로 모듈을 사용할 수 없습니다. 아래의 예제와 같이 +`electronScreen` 같은 이름으로 모듈 이름을 대체하여 사용해야 합니다. 다음 예제는 화면 전체를 채우는 윈도우 창을 생성합니다: diff --git a/docs-translations/ko-KR/api/session.md b/docs-translations/ko-KR/api/session.md index 5df45f4ac216..aa5ab2ed3e50 100644 --- a/docs-translations/ko-KR/api/session.md +++ b/docs-translations/ko-KR/api/session.md @@ -1,7 +1,8 @@ # session -`session` 객체는 [`BrowserWindow`](browser-window.md)의 [`webContents`](web-contents.md)의 프로퍼티입니다. -다음과 같이 `BrowserWindow` 인스턴스에서 접근할 수 있습니다: +`session` 객체는 [`BrowserWindow`](browser-window.md)의 +[`webContents`](web-contents.md)의 프로퍼티입니다. 다음과 같이 `BrowserWindow` +인스턴스에서 접근할 수 있습니다: ```javascript var BrowserWindow = require('browser-window'); @@ -43,7 +44,8 @@ session.on('will-download', function(event, item, webContents) { * `callback` Function `hostname`에 대한 `certificate`의 유효성 검증이 실패했을 때 발생하는 이벤트 입니다. -인증서를 신뢰한다면 `event.preventDefault()` 와 `callback(true)`를 호출하여 기본 동작을 방지해야 합니다. +인증서를 신뢰한다면 `event.preventDefault()` 와 `callback(true)`를 호출하여 기본 +동작을 방지해야 합니다. ```javascript session.on('verify-certificate', function(event, hostname, certificate, callback) { @@ -63,7 +65,8 @@ session.on('verify-certificate', function(event, hostname, certificate, callback ### `session.cookies` -`cookies` 속성은 쿠키를 조작하는 방법을 제공합니다. 예를 들어 다음과 같이 할 수 있습니다: +`cookies` 속성은 쿠키를 조작하는 방법을 제공합니다. 예를 들어 다음과 같이 할 수 +있습니다: ```javascript var BrowserWindow = require('browser-window'); @@ -101,7 +104,8 @@ win.webContents.on('did-finish-load', function() { `details` Object, properties: -* `url` String - `url`에 관련된 쿠키를 가져옵니다. 이 속성을 비워두면 모든 url의 쿠키를 가져옵니다. +* `url` String - `url`에 관련된 쿠키를 가져옵니다. 이 속성을 비워두면 모든 url의 + 쿠키를 가져옵니다. * `name` String - 이름을 기준으로 쿠키를 필터링합니다. * `domain` String - `domain`과 일치하는 도메인과 서브 도메인에 대한 쿠키를 가져옵니다. * `path` String - `path`와 일치하는 경로에 대한 쿠키를 가져옵니다. @@ -116,23 +120,29 @@ win.webContents.on('did-finish-load', function() { * `domain` String - 쿠키의 도메인. * `host_only` String - 쿠키가 호스트 전용인가에 대한 여부. * `path` String - 쿠키의 경로. - * `secure` Boolean - 쿠키가 안전한 것으로 표시되는지에 대한 여부. (일반적으로 HTTPS) + * `secure` Boolean - 쿠키가 안전한 것으로 표시되는지에 대한 여부. (일반적으로 + HTTPS) * `http_only` Boolean - 쿠키가 HttpOnly로 표시되는지에 대한 여부. - * `session` Boolean - 쿠키가 세션 쿠키 또는 만료일이 있는 영구 쿠키인지에 대한 여부. - * `expirationDate` Double - (Option) UNIX 시간으로 표시되는 쿠키의 만료일에 대한 초 단위 시간. 세션 쿠키는 지원되지 않음. + * `session` Boolean - 쿠키가 세션 쿠키 또는 만료일이 있는 영구 쿠키인지에 대한 + 여부. + * `expirationDate` Double - (Option) UNIX 시간으로 표시되는 쿠키의 만료일에 + 대한 초 단위 시간. 세션 쿠키는 지원되지 않음. ### `session.cookies.set(details, callback)` `details` Object, properties: -* `url` String - `url`에 관련된 쿠키를 가져옵니다. +* `url` String - `url`에 관련된 쿠키를 가져옵니다. * `name` String - 쿠키의 이름입니다. 기본적으로 비워두면 생략됩니다. * `value` String - 쿠키의 값입니다. 기본적으로 비워두면 생략됩니다. * `domain` String - 쿠키의 도메인입니다. 기본적으로 비워두면 생략됩니다. * `path` String - 쿠키의 경로입니다. 기본적으로 비워두면 생략됩니다. -* `secure` Boolean - 쿠키가 안전한 것으로 표시되는지에 대한 여부입니다. 기본값은 false입니다. -* `session` Boolean - 쿠키가 HttpOnly로 표시되는지에 대한 여부입니다. 기본값은 false입니다. -* `expirationDate` Double - UNIX 시간으로 표시되는 쿠키의 만료일에 대한 초 단위 시간입니다. 생략하면 쿠키는 세션 쿠키가 됩니다. +* `secure` Boolean - 쿠키가 안전한 것으로 표시되는지에 대한 여부입니다. 기본값은 + false입니다. +* `session` Boolean - 쿠키가 HttpOnly로 표시되는지에 대한 여부입니다. 기본값은 + false입니다. +* `expirationDate` Double - UNIX 시간으로 표시되는 쿠키의 만료일에 대한 초 단위 + 시간입니다. 생략하면 쿠키는 세션 쿠키가 됩니다. * `callback` Function - function(error) * `error` Error @@ -154,7 +164,8 @@ win.webContents.on('did-finish-load', function() { ### `session.clearStorageData([options, ]callback)` * `options` Object (optional), proprties: - * `origin` String - `scheme://host:port`와 같은 `window.location.origin` 규칙을 따르는 origin 문자열. + * `origin` String - `scheme://host:port`와 같은 `window.location.origin` 규칙을 + 따르는 origin 문자열. * `storages` Array - 비우려는 스토리지의 종류, 다음과 같은 타입을 포함할 수 있습니다: `appcache`, `cookies`, `filesystem`, `indexdb`, `local storage`, `shadercache`, `websql`, `serviceworkers` @@ -171,7 +182,8 @@ win.webContents.on('did-finish-load', function() { 세션에 사용할 프록시 `config`를 분석하고 프록시를 적용합니다. -세션에 사용할 프록시는 `config`가 PAC 주소일 경우 그대로 적용하고, 다른 형식일 경우 다음 규칙에 따라 적용합니다. +세션에 사용할 프록시는 `config`가 PAC 주소일 경우 그대로 적용하고, 다른 형식일 경우 +다음 규칙에 따라 적용합니다. ``` config = scheme-proxies[";"] @@ -181,27 +193,35 @@ proxy-uri-list = [","] proxy-uri = ["://"][":"] 예시: - "http=foopy:80;ftp=foopy2" -- http:// URL에 "foopy:80" HTTP 프록시를 사용합니다. - "foopy2:80" 는 ftp:// URL에 사용됩니다. + "http=foopy:80;ftp=foopy2" -- http:// URL에 "foopy:80" HTTP 프록시를 + 사용합니다. "foopy2:80" 는 ftp:// URL에 + 사용됩니다. "foopy:80" -- 모든 URL에 "foopy:80" 프록시를 사용합니다. - "foopy:80,bar,direct://" -- 모든 URL에 "foopy:80" HTTP 프록시를 사용합니다. - 문제가 발생하여 "foopy:80"를 사용할 수 없는 경우 "bar"를 대신 사용하여 - 장애를 복구하며 그 다음 문제가 생긴 경우 프록시를 사용하지 않습니다. - "socks4://foopy" -- 모든 URL에 "foopy:1000" SOCKS v4 프록시를 사용합니다. - "http=foopy,socks5://bar.com -- http:// URL에 "foopy" HTTP 프록시를 사용합니다. - 문제가 발생하여 "foopy"를 사용할 수 없는 경우 SOCKS5 "bar.com" + "foopy:80,bar,direct://" -- 모든 URL에 "foopy:80" HTTP 프록시를 + 사용합니다. 문제가 발생하여 "foopy:80"를 + 사용할 수 없는 경우 "bar"를 대신 사용하여 + 장애를 복구하며 그 다음 문제가 생긴 경우 + 프록시를 사용하지 않습니다. + "socks4://foopy" -- 모든 URL에 "foopy:1000" SOCKS v4 프록시를 + 사용합니다. + "http=foopy,socks5://bar.com -- http:// URL에 "foopy" HTTP 프록시를 + 사용합니다. 문제가 발생하여 "foopy"를 + 사용할 수 없는 경우 SOCKS5 "bar.com" 프록시를 대신 사용합니다. - "http=foopy,direct:// -- http:// URL에 "foopy" HTTP 프록시를 사용합니다. - 그리고 문제가 발생하여 "foopy"를 사용할 수 없는 경우 프록시를 사용하지 않습니다. - "http=foopy;socks=foopy2 -- http:// URL에 "foopy" HTTP 프록시를 사용합니다. - 그리고 "socks4://foopy2" 프록시를 다른 모든 URL에 사용합니다. + "http=foopy,direct:// -- http:// URL에 "foopy" HTTP 프록시를 + 사용합니다. 그리고 문제가 발생하여 "foopy"를 + 사용할 수 없는 경우 프록시를 사용하지 않습니다. + "http=foopy;socks=foopy2 -- http:// URL에 "foopy" HTTP 프록시를 + 사용합니다. 그리고 "socks4://foopy2" + 프록시를 다른 모든 URL에 사용합니다. ``` ### `session.setDownloadPath(path)` * `path` String - 다운로드 위치 -다운로드 저장 위치를 지정합니다. 기본 다운로드 위치는 각 어플리케이션 데이터 디렉터리의 `Downloads` 폴더입니다. +다운로드 저장 위치를 지정합니다. 기본 다운로드 위치는 각 어플리케이션 데이터 디렉터리의 +`Downloads` 폴더입니다. ### `session.enableNetworkEmulation(options)` diff --git a/docs-translations/ko-KR/api/shell.md b/docs-translations/ko-KR/api/shell.md index dfcbdea20590..4183d3b2502d 100644 --- a/docs-translations/ko-KR/api/shell.md +++ b/docs-translations/ko-KR/api/shell.md @@ -29,9 +29,10 @@ shell.openExternal('https://github.com'); * `url` String -제공된 외부 프로토콜 URL을 기반으로 데스크톱의 기본 프로그램으로 엽니다. (예를 들어 mailto: URL은 유저의 기본 이메일 에이전트로 URL을 엽니다.) +제공된 외부 프로토콜 URL을 기반으로 데스크톱의 기본 프로그램으로 엽니다. (예를 들어 +mailto: URL은 유저의 기본 이메일 에이전트로 URL을 엽니다.) -역주: 폴더는 'file:\\\\C:\\'와 같이 지정하여 열 수 있습니다. (`\\`로 경로를 표현한 이유는 Escape 문자열을 참고하세요.) +역주: 폴더는 'file:\\\\C:\\'와 같이 지정하여 열 수 있습니다. (Windows의 경우) ### `shell.moveItemToTrash(fullPath)` diff --git a/docs-translations/ko-KR/api/synopsis.md b/docs-translations/ko-KR/api/synopsis.md index 77a8514fbb2e..fd0791cd4a8e 100644 --- a/docs-translations/ko-KR/api/synopsis.md +++ b/docs-translations/ko-KR/api/synopsis.md @@ -1,13 +1,17 @@ # 개요 -Electron은 모든 [Node.js의 built-in 모듈](http://nodejs.org/api/)과 third-party node 모듈을 완벽하게 지원합니다. ([네이티브 모듈](../tutorial/using-native-node-modules.md) 포함) +Electron은 모든 [Node.js의 built-in 모듈](http://nodejs.org/api/)과 third-party +node 모듈을 완벽하게 지원합니다. ([네이티브 모듈](../tutorial/using-native-node-modules.md) +포함) -또한 Electron은 네이티브 데스크톱 어플리케이션을 개발 할 수 있도록 추가적인 built-in 모듈을 제공합니다. -몇몇 모듈은 메인 프로세스에서만 사용할 수 있고 어떤 모듈은 랜더러 프로세스(웹 페이지)에서만 사용할 수 있습니다. -또한 두 프로세스 모두 사용할 수 있는 모듈도 있습니다. +또한 Electron은 네이티브 데스크톱 어플리케이션을 개발 할 수 있도록 추가적인 built-in +모듈을 제공합니다. 몇몇 모듈은 메인 프로세스에서만 사용할 수 있고 어떤 모듈은 랜더러 +프로세스(웹 페이지)에서만 사용할 수 있습니다. 또한 두 프로세스 모두 사용할 수 있는 +모듈도 있습니다. -기본적인 규칙으로 [GUI][gui]와 저 수준 시스템에 관련된 모듈들은 오직 메인 프로세스에서만 사용할 수 있습니다. -[메인 프로세스 vs. 랜더러 프로세스](../tutorial/quick-start.md#메인-프로세스) 컨셉에 익숙해야 모듈을 다루기 쉬우므로 관련 문서를 읽어 보는 것을 권장합니다. +기본적인 규칙으로 [GUI][gui]와 저 수준 시스템에 관련된 모듈들은 오직 메인 +프로세스에서만 사용할 수 있습니다. [메인 프로세스 vs. 랜더러 프로세스](../tutorial/quick-start.md#메인-프로세스) +컨셉에 익숙해야 모듈을 다루기 쉬우므로 관련 문서를 읽어 보는 것을 권장합니다. 메인 프로세스 스크립트는 일반 Node.js 스크립트와 비슷합니다: @@ -24,7 +28,8 @@ app.on('ready', function() { }); ``` -랜더러 프로세스도 예외적인 node module들을 사용할 수 있다는 점을 제외하면 일반 웹 페이지와 크게 다를게 없습니다: +랜더러 프로세스도 예외적인 node module들을 사용할 수 있다는 점을 제외하면 일반 웹 +페이지와 크게 다를게 없습니다: ```html @@ -38,7 +43,8 @@ app.on('ready', function() { ``` -어플리케이션을 실행하려면 [앱 실행하기](../tutorial/quick-start.md#앱 실행하기) 문서를 참고하기 바랍니다. +어플리케이션을 실행하려면 [앱 실행하기](../tutorial/quick-start.md#앱 실행하기) +문서를 참고하기 바랍니다. ## 분리 할당 @@ -49,15 +55,17 @@ app.on('ready', function() { const {app, BrowserWindow} = require('electron') ``` -아직 플레인 자바스크립트를 쓰고 있다면, Chrome이 ES6를 완전히 지원하기 전까지 기다려야 합니다. +아직 플레인 자바스크립트를 쓰고 있다면, Chrome이 ES6를 완전히 지원하기 전까지 기다려야 +합니다. ## 이전 스타일의 빌트인 모듈 비활성화 -v0.35.0 이전 버전에선 빌트인 모듈이 모두 `require('module-name')`같은 형식으로 사용되었습니다. -하지만 [많은 단점][issue-387]이 있기 때문에 현재 변경되었습니다. +v0.35.0 이전 버전에선 빌트인 모듈이 모두 `require('module-name')`같은 형식으로 +사용되었습니다. 하지만 [많은 단점][issue-387]이 있기 때문에 현재 API가 변경되었습니다. 하지만 오래된 앱의 호환성 유지를 위해 아직 구 버전 API를 지원하고 있습니다. -완벽하게 모든 구 버전 API를 비활성화하려면 `ELECTRON_HIDE_INTERNAL_MODULES` 환경 변수를 설정하면 됩니다: +완벽하게 모든 구 버전 API를 비활성화하려면 `ELECTRON_HIDE_INTERNAL_MODULES` 환경 +변수를 설정하면 됩니다: ```javascript process.env.ELECTRON_HIDE_INTERNAL_MODULES = 'true' @@ -72,4 +80,4 @@ require('electron').hideInternalModules() [gui]: https://en.wikipedia.org/wiki/Graphical_user_interface [main-process]: ../tutorial/quick-start.md#메인-프로세스 [desctructuring-assignment]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment -[issue-387]: https://github.com/atom/electron/issues/387 \ No newline at end of file +[issue-387]: https://github.com/atom/electron/issues/387 diff --git a/docs-translations/ko-KR/api/tray.md b/docs-translations/ko-KR/api/tray.md index 7a883b026797..97db97f42607 100644 --- a/docs-translations/ko-KR/api/tray.md +++ b/docs-translations/ko-KR/api/tray.md @@ -1,6 +1,7 @@ # Tray -`Tray`는 OS의 알림 영역에 아이콘을 표시합니다. 보통 컨텍스트 메뉴(context menu)를 같이 사용합니다. +`Tray`는 OS의 알림 영역에 아이콘을 표시합니다. 보통 컨텍스트 메뉴(context menu)를 +같이 사용합니다. ```javascript const electron = require('electron'); @@ -25,13 +26,15 @@ app.on('ready', function(){ __플랫폼별 한계:__ -* Linux에서는 앱 알림 표시기(app indicator)가 지원되면 해당 기능을 사용합니다. 만약 지원하지 않으면 `GtkStatusIcon`을 대신 사용합니다. -* Linux 배포판이 앱 알림 표시기만 지원하고 있다면 `libappindicator1`를 설치하여 트레이 아이콘이 작동하도록 만들 수 있습니다. +* Linux에서는 앱 알림 표시기(app indicator)가 지원되면 해당 기능을 사용합니다. 만약 + 지원하지 않으면 `GtkStatusIcon`을 대신 사용합니다. +* Linux 배포판이 앱 알림 표시기만 지원하고 있다면 `libappindicator1`를 설치하여 + 트레이 아이콘이 작동하도록 만들 수 있습니다. * 앱 알림 표시기는 컨텍스트 메뉴를 가지고 있을 때만 보입니다. -* Linux에서 앱 알림 표시기가 사용될 경우, `clicked` 이벤트는 무시됩니다. +* Linux에서 앱 표시기가 사용될 경우, `click` 이벤트는 무시됩니다. -이러한 이유로 Tray API가 모든 플랫폼에서 똑같이 작동하게 하고 싶다면 `click` 이벤트에 의존해선 안됩니다. -그리고 언제나 컨텍스트 메뉴를 포함해야 합니다. +이러한 이유로 Tray API가 모든 플랫폼에서 똑같이 작동하게 하고 싶다면 `click` 이벤트에 +의존해선 안되며 언제나 컨텍스트 메뉴를 포함해야 합니다. ## Class: Tray @@ -47,7 +50,7 @@ __플랫폼별 한계:__ `Tray` 모듈은 다음과 같은 이벤트를 가지고 있습니다: -**참고:** 몇가지 이벤트는 특정한 플랫폼에서만 작동합니다. +**참고:** 몇몇 이벤트는 특정한 플랫폼에서만 작동합니다. ### Event: 'click' diff --git a/docs-translations/ko-KR/api/web-contents.md b/docs-translations/ko-KR/api/web-contents.md index 1bad5b47e863..edec4d472b22 100644 --- a/docs-translations/ko-KR/api/web-contents.md +++ b/docs-translations/ko-KR/api/web-contents.md @@ -1,8 +1,9 @@ # webContents -`webContents`는 [EventEmitter](http://nodejs.org/api/events.html#events_class_events_eventemitter)를 상속받았습니다. - -웹 페이지의 렌더링과 관리를 책임지며 [`BrowserWindow`](browser-window.md)의 속성입니다. 다음은 `webContents` 객체에 접근하는 예제입니다: +`webContents`는 [EventEmitter](http://nodejs.org/api/events.html#events_class_events_eventemitter)를 +상속받았습니다. 웹 페이지의 렌더링과 관리를 책임지며 +[`BrowserWindow`](browser-window.md)의 속성입니다. 다음은 `webContents` 객체에 +접근하는 예제입니다: ```javascript const BrowserWindow = require('electron').BrowserWindow; @@ -19,7 +20,8 @@ var webContents = win.webContents; ### Event: 'did-finish-load' -탐색 작업이 끝났을 때 발생하는 이벤트입니다. 브라우저의 탭의 스피너가 멈추고 `onload` 이벤트가 발생했을 때를 말합니다. +탐색 작업이 끝났을 때 발생하는 이벤트입니다. 브라우저의 탭의 스피너가 멈추고 `onload` +이벤트가 발생했을 때를 말합니다. ### Event: 'did-fail-load' @@ -30,8 +32,10 @@ Returns: * `errorDescription` String * `validatedURL` String -이 이벤트는 `did-finish-load`와 비슷하나, 로드가 실패했거나 취소되었을 때 발생합니다. 예를 들면 `window.stop()`이 실행되었을 때 발생합니다. -발생할 수 있는 전체 에러 코드의 목록과 설명은 [여기](https://code.google.com/p/chromium/codesearch#chromium/src/net/base/net_error_list.h)서 확인할 수 있습니다. +이 이벤트는 `did-finish-load`와 비슷하나, 로드가 실패했거나 취소되었을 때 발생합니다. +예를 들면 `window.stop()`이 실행되었을 때 발생합니다. 발생할 수 있는 전체 에러 코드의 +목록과 설명은 [여기](https://code.google.com/p/chromium/codesearch#chromium/src/net/base/net_error_list.h)서 +확인할 수 있습니다. ### Event: 'did-frame-finish-load' @@ -126,8 +130,8 @@ Returns: 사용자 또는 페이지가 새로운 페이지로 이동할 때 발생하는 이벤트입니다. `window.location` 객체가 변경되거나 사용자가 페이지의 링크를 클릭했을 때 발생합니다. -이 이벤트는 `webContents.loadURL`과 `webContents.back` 같은 API를 이용하여 프로그램적으로 -시작된 탐색에 대해서는 발생하지 않습니다. +이 이벤트는 `webContents.loadURL`과 `webContents.back` 같은 API를 이용하여 +프로그램적으로 시작된 탐색에 대해서는 발생하지 않습니다. `event.preventDefault()`를 호출하면 탐색을 방지할 수 있습니다. @@ -200,8 +204,9 @@ webContents에서 사용되는 `session`객체를 반환합니다. * `userAgent` String - 요청을 시작한 유저 에이전트. * `extraHeaders` String - "\n"로 구분된 Extra 헤더들. -윈도우에 웹 페이지 `url`을 로드합니다. `url`은 `http://` or `file://`과 같은 프로토콜 접두사를 가지고 있어야 합니다. -만약 반드시 http 캐시를 사용하지 않고 로드해야 하는 경우 `pragma` 헤더를 사용할 수 있습니다. +윈도우에 웹 페이지 `url`을 로드합니다. `url`은 `http://` or `file://`과 같은 +프로토콜 접두사를 가지고 있어야 합니다. 만약 반드시 http 캐시를 사용하지 않고 로드해야 +하는 경우 `pragma` 헤더를 사용할 수 있습니다. ```javascript const options = {"extraHeaders" : "pragma: no-cache\n"} @@ -308,8 +313,9 @@ CSS 코드를 현재 웹 페이지에 삽입합니다. 페이지에서 자바스크립트 코드를 실행합니다. -기본적으로 `requestFullScreen`와 같은 몇몇 HTML API들은 사용자의 조작에 의해서만 호출될 수 있습니다. -`userGesture`를 `true`로 설정하면 이러한 제약을 무시할 수 있습니다. +기본적으로 `requestFullScreen`와 같은 몇몇 HTML API들은 사용자의 조작에 의해서만 +호출될 수 있습니다. `userGesture`를 `true`로 설정하면 이러한 제약을 무시할 수 +있습니다. ### `webContents.setAudioMuted(muted)` @@ -373,14 +379,15 @@ CSS 코드를 현재 웹 페이지에 삽입합니다. * `callback` Function -ServiceWorker가 등록되어있는지 확인하고 `callback`에 대한 응답으로 boolean 값을 반환합니다. +ServiceWorker가 등록되어있는지 확인하고 `callback`에 대한 응답으로 boolean 값을 +반환합니다. ### `webContents.unregisterServiceWorker(callback)` * `callback` Function -ServiceWorker가 존재하면 모두 등록을 해제하고 JS Promise가 만족될 때 `callback`에 대한 -응답으로 boolean을 반환하거나 JS Promise가 만족되지 않을 때 `false`를 반환합니다. +ServiceWorker가 존재하면 모두 등록을 해제하고 JS Promise가 만족될 때 `callback`에 +대한 응답으로 boolean을 반환하거나 JS Promise가 만족되지 않을 때 `false`를 반환합니다. ### `webContents.print([options])` @@ -390,14 +397,16 @@ ServiceWorker가 존재하면 모두 등록을 해제하고 JS Promise가 만족 * `printBackground` Boolean - 웹 페이지의 배경 색과 이미지를 출력합니다. 기본값은 `false`입니다. -윈도우의 웹 페이지를 프린트합니다. `silent`가 `false`로 지정되어있을 땐, Electron이 시스템의 -기본 프린터와 기본 프린터 설정을 가져옵니다. +윈도우의 웹 페이지를 프린트합니다. `silent`가 `false`로 지정되어있을 땐, Electron이 +시스템의 기본 프린터와 기본 프린터 설정을 가져옵니다. 웹 페이지에서 `window.print()`를 호출하는 것은 -`webContents.print({silent: false, printBackground: false})`를 호출하는 것과 같습니다. +`webContents.print({silent: false, printBackground: false})`를 호출하는 것과 +같습니다. -**Note:** Windows에서의 프린터 API는 `pdf.dll`에 의존합니다. -어플리케이션이 print 기능을 사용하지 않는 경우 전체 바이너리 크기를 줄이기 위해 `pdf.dll`을 삭제해도 됩니다. +**참고:** Windows에서의 프린터 API는 `pdf.dll`에 의존합니다. 따라서 어플리케이션이 +print기능을 사용하지 않는 경우 전체 바이너리 크기를 줄이기 위해 `pdf.dll`을 삭제해도 +됩니다. ### `webContents.printToPDF(options, callback)` @@ -423,7 +432,8 @@ ServiceWorker가 존재하면 모두 등록을 해제하고 JS Promise가 만족 * `error` Error * `data` Buffer - PDF 파일 내용. -Chromium의 미리보기 프린팅 커스텀 설정을 이용하여 윈도우의 웹 페이지를 PDF로 프린트합니다. +Chromium의 미리보기 프린팅 커스텀 설정을 이용하여 윈도우의 웹 페이지를 PDF로 +프린트합니다. 기본으로 비어있는 `options`은 다음과 같이 여겨지게 됩니다: @@ -507,8 +517,9 @@ win.webContents.on("did-finish-load", function() { * `channel` String * `arg` (optional) -`channel`을 통하여 렌더러 프로세스에 비동기 메시지를 보냅ㄹ니다. 임의의 아규먼트를 보낼수도 있습니다. -렌더러 프로세스는 `ipcRenderer` 모듈을 통하여 `channel`를 리슨하여 메시지를 처리할 수 있습니다. +`channel`을 통하여 렌더러 프로세스에 비동기 메시지를 보냅니다. 임의의 인수를 보낼수도 +있습니다. 렌더러 프로세스는 `ipcRenderer` 모듈을 통하여 `channel`를 리슨하여 메시지를 +처리할 수 있습니다. 메인 프로세스에서 렌더러 프로세스로 메시지를 보내는 예시 입니다: @@ -545,42 +556,43 @@ app.on('ready', function() { (기본값: `desktop`) * `desktop` * `mobile` -* `screenSize` Object - 에뮬레이트 화면의 크기를 지정합니다 (screenPosition == mobile) +* `screenSize` Object - 에뮬레이트 화면의 크기를 지정합니다 (screenPosition == + mobile) * `width` Integer - 에뮬레이트 화면의 너비를 지정합니다 * `height` Integer - 에뮬레이트 화면의 높이를 지정합니다 -* `viewPosition` Object - 화면에서 뷰의 위치 - (screenPosition == mobile) (기본값: `{x: 0, y: 0}`) +* `viewPosition` Object - 화면에서 뷰의 위치 (screenPosition == mobile) (기본값: + `{x: 0, y: 0}`) * `x` Integer - 좌상단 모서리로부터의 x 축의 오프셋 * `y` Integer - 좌상단 모서리로부터의 y 축의 오프셋 * `deviceScaleFactor` Integer - 디바이스의 스케일 팩터(scale factor)를 지정합니다. - (0일 경우 기본 디바이스 스케일 팩터를 기본으로 사용합니다) (기본값: `0`) -* `viewSize` Object - 에뮬레이트 된 뷰의 크기를 지정합니다 (빈 값은 오버라이드 하지 않는 다는 - 것을 의미합니다) + (0일 경우 기본 디바이스 스케일 팩터를 기본으로 사용합니다. 기본값: `0`) +* `viewSize` Object - 에뮬레이트 된 뷰의 크기를 지정합니다 (빈 값은 덮어쓰지 않는 + 다는 것을 의미합니다) * `width` Integer - 에뮬레이트 된 뷰의 너비를 지정합니다 * `height` Integer - 에뮬레이트 된 뷰의 높이를 지정합니다 -* `fitToView` Boolean - 에뮬레이트의 뷰가 사용 가능한 공간에 맞추어 스케일 다운 될지 여부를 +* `fitToView` Boolean - 에뮬레이트의 뷰가 사용 가능한 공간에 맞추어 스케일 다운될지를 지정합니다 (기본값: `false`) -* `offset` Object - 사용 가능한 공간에서 에뮬레이트 된 뷰의 오프셋을 지정합니다 - (fit to view 모드 외에서) (기본값: `{x: 0, y: 0}`) +* `offset` Object - 사용 가능한 공간에서 에뮬레이트 된 뷰의 오프셋을 지정합니다 (fit + to view 모드 외에서) (기본값: `{x: 0, y: 0}`) * `x` Float - 좌상단 모서리에서 x 축의 오프셋을 지정합니다 * `y` Float - 좌상단 모서리에서 y 축의 오프셋을 지정합니다 -* `scale` Float - 사용 가능한 공간에서 에뮬레이드 된 뷰의 스케일 (fit to view 모드 외에서) - (기본값: `1`) +* `scale` Float - 사용 가능한 공간에서 에뮬레이드 된 뷰의 스케일 (fit to view 모드 + 외에서, 기본값: `1`) -주어진 파라미터로 디바이스 에뮬레이션을 사용합니다. +`parameters`로 디바이스 에뮬레이션을 사용합니다. ### `webContents.disableDeviceEmulation()` -`webContents.enableDeviceEmulation`로 사용가능해진 디바이스 에뮬레이선을 비활성화 합니다. +`webContents.enableDeviceEmulation`로 활성화된 디바이스 에뮬레이선을 비활성화 합니다. ### `webContents.sendInputEvent(event)` * `event` Object - * `type` String (**required**) - 이벤트의 타입. 다음 값들을 사용할 수 있습니다: `mouseDown`, - `mouseUp`, `mouseEnter`, `mouseLeave`, `contextMenu`, `mouseWheel`, - `mouseMove`, `keyDown`, `keyUp`, `char`. - * `modifiers` Array - 이벤트의 수정자(modifier)들에 대한 배열. 다음 값들을 포함 할 수 - 있습니다: `shift`, `control`, `alt`, `meta`, `isKeypad`, `isAutoRepeat`, + * `type` String (**required**) - 이벤트의 타입. 다음 값들을 사용할 수 있습니다: + `mouseDown`, `mouseUp`, `mouseEnter`, `mouseLeave`, `contextMenu`, + `mouseWheel`, `mouseMove`, `keyDown`, `keyUp`, `char`. + * `modifiers` Array - 이벤트의 수정자(modifier)들에 대한 배열. 다음 값들을 포함 + 할 수 있습니다: `shift`, `control`, `alt`, `meta`, `isKeypad`, `isAutoRepeat`, `leftButtonDown`, `middleButtonDown`, `rightButtonDown`, `capsLock`, `numLock`, `left`, `right`. @@ -588,10 +600,11 @@ Input `event`를 웹 페이지로 전송합니다. 키보드 이벤트들에 대해서는 `event` 객체는 다음 속성들을 사용할 수 있습니다: -* `keyCode` Char or String (**required**) - 키보드 이벤트로 보내지는 문자. - 단일 UTF-8 문자를 사용할 수 있고 이벤트를 발생시키는 다음 키 중 하나를 포함할 수 있습니다: - `enter`, `backspace`, `delete`, `tab`, `escape`, `control`, `alt`, `shift`, `end`, - `home`, `insert`, `left`, `up`, `right`, `down`, `pageUp`, `pageDown`, `printScreen` +* `keyCode` Char or String (**required**) - 키보드 이벤트로 보내지는 문자. 단일 + UTF-8 문자를 사용할 수 있고 이벤트를 발생시키는 다음 키 중 하나를 포함할 수 있습니다: + `enter`, `backspace`, `delete`, `tab`, `escape`, `control`, `alt`, `shift`, + `end`, `home`, `insert`, `left`, `up`, `right`, `down`, `pageUp`, `pageDown`, + `printScreen` 마우스 이벤트들에 대해서는 `event` 객체는 다음 속성들을 사용할 수 있습니다: @@ -619,13 +632,14 @@ Input `event`를 웹 페이지로 전송합니다. * `callback` Function -프레젠테이션 이벤트들과 캡쳐된 프레임들에 대한 구독을 시작하면 `callback`이 프레젠테이션 이벤트가 -발생할 때 `callback(frameBuffer)`과 같은 형식으로 호출됩니다. +캡처된 프레임과 프레젠테이션 이벤트를 구독하기 시작합니다. `callback`은 +프레젠테이션 이벤트가 발생했을 때 `callback(frameBuffer)` 형태로 호출됩니다. -`frameBuffer`는 raw 픽셀 데이터를 포함한 `Buffer`입니다. 대부분의 기계에서 픽셀 데이터는 32bit -BGRA 포맷으로 효율적으로 저장됩니다. 하지만 실제 재프리젠테이션은 프로세서의 endianness에 의존성을 -가지고 있습니다(대부분의 현재 프로세스들은 little-endian입니다. big-endian 프로세서들를 가진 -기계들에서 data는 32bit ARGB format입니다). +`frameBuffer`는 raw 픽셀 데이터를 가지고 있는 `Buffer` 객체입니다. 많은 장치에서 +32비트 BGRA 포맷을 사용하여 효율적으로 픽셀 데이터를 저장합니다. 하지만 실질적인 +데이터 저장 방식은 프로세서의 엔디안 방식에 따라서 달라집니다. (따라서 현대의 많은 +프로세서에선 little-endian 방식을 사용하므로 위의 포맷을 그대로 표현합니다. 하지만 +몇몇 프로세서는 big-endian 방식을 사용하는데, 이 경우 32비트 ARGB 포맷을 사용합니다) ### `webContents.endFrameSubscription()` @@ -639,7 +653,8 @@ BGRA 포맷으로 효율적으로 저장됩니다. 하지만 실제 재프리젠 이 `WebContents`에 대한 개발자 도구의 `WebContents`를 가져옵니다. -**Note:** 사용자가 절대로 이 객체를 저장해서는 안 됩니다. 개발자 도구가 닫혔을 때, `null`이 반환될 수 있습니다. +**참고:** 사용자가 절대로 이 객체를 저장해서는 안 됩니다. 개발자 도구가 닫혔을 때, +`null`이 반환될 수 있습니다. ### `webContents.savePage(fullPath, saveType, callback)` diff --git a/docs-translations/ko-KR/api/web-frame.md b/docs-translations/ko-KR/api/web-frame.md index 5b94a9a6ad71..2e4a469b5485 100644 --- a/docs-translations/ko-KR/api/web-frame.md +++ b/docs-translations/ko-KR/api/web-frame.md @@ -1,6 +1,7 @@ # webFrame -`web-frame` 모듈은 현재 웹 페이지의 랜더링 상태를 설정 할 수 있도록 관련 유틸리티를 제공하는 모듈입니다. +`web-frame` 모듈은 현재 웹 페이지의 랜더링 상태를 설정 할 수 있도록 관련 유틸리티를 +제공하는 모듈입니다. 다음 예제는 현재 페이지를 200% 줌 합니다: @@ -18,7 +19,8 @@ webFrame.setZoomFactor(2); * `factor` Number - Zoom 값 -지정한 값으로 페이지를 줌 합니다. 줌 값은 퍼센트를 100으로 나눈 값입니다. (예시: 300% = 3.0) +지정한 값으로 페이지를 줌 합니다. 줌 값은 퍼센트를 100으로 나눈 값입니다. +(예시: 300% = 3.0) ### `webFrame.getZoomFactor()` @@ -28,8 +30,9 @@ webFrame.setZoomFactor(2); * `level` Number - Zoom level -지정한 레벨로 줌 레벨을 변경합니다. 0은 "기본 크기" 입니다. -그리고 각각 레벨 값을 올리거나 내릴 때마다 20%씩 커지거나 작아지고 기본 크기의 50%부터 300%까지 조절 제한이 있습니다. +지정한 레벨로 줌 레벨을 변경합니다. 0은 "기본 크기" 입니다. 그리고 각각 레벨 값을 +올리거나 내릴 때마다 20%씩 커지거나 작아지고 기본 크기의 50%부터 300%까지 조절 제한이 +있습니다. ### `webFrame.getZoomLevel()` @@ -50,7 +53,8 @@ webFrame.setZoomFactor(2); Input field나 text area에 철자 검사(spell checking) 제공자를 설정합니다. -`provider`는 반드시 전달된 단어의 철자가 맞았는지 검사하는 `spellCheck` 메소드를 가지고 있어야 합니다. +`provider`는 반드시 전달된 단어의 철자가 맞았는지 검사하는 `spellCheck` 메소드를 +가지고 있어야 합니다. [node-spellchecker][spellchecker]를 철자 검사 제공자로 사용하는 예제입니다: @@ -68,7 +72,8 @@ webFrame.setSpellCheckProvider("en-US", true, { 지정한 `scheme`을 보안 스킴으로 등록합니다. -보안 스킴은 혼합된 컨텐츠 경고를 발생시키지 않습니다. 예를 들어 `https` 와 `data`는 네트워크 공격자로부터 손상될 가능성이 없기 때문에 보안 스킴이라고 할 수 있습니다. +보안 스킴은 혼합된 컨텐츠 경고를 발생시키지 않습니다. 예를 들어 `https` 와 `data`는 +네트워크 공격자로부터 손상될 가능성이 없기 때문에 보안 스킴이라고 할 수 있습니다. ### `webFrame.registerURLSchemeAsBypassingCSP(scheme)` @@ -77,9 +82,9 @@ webFrame.setSpellCheckProvider("en-US", true, { 현재 페이지 컨텐츠의 보안 정책에 상관없이 `scheme`로부터 리소스가 로드됩니다. ### `webFrame.registerURLSchemeAsPrivileged(scheme)` - + * `scheme` String - + 보안 `scheme`를 지정합니다. 리소스와 ServiceWorker 설정에 대해 보안 정책을 우회합니다. [spellchecker]: https://github.com/atom/node-spellchecker diff --git a/docs-translations/ko-KR/api/web-view-tag.md b/docs-translations/ko-KR/api/web-view-tag.md index 7b3d259fdfc7..4ef7f47c853f 100644 --- a/docs-translations/ko-KR/api/web-view-tag.md +++ b/docs-translations/ko-KR/api/web-view-tag.md @@ -1,24 +1,29 @@ # `` 태그 -`guest` 컨텐츠(웹 페이지)를 Electron 앱 페이지에 삽입하기 위해 `webview` 태그를 사용할 수 있습니다. -게스트 컨텐츠는 `webview` 컨테이너에 담겨 대상 페이지에 삽입되고 해당 페이지에선 게스트 컨텐츠의 배치 및 렌더링 과정을 조작할 수 있습니다. +`guest` 컨텐츠(웹 페이지)를 Electron 앱 페이지에 삽입하기 위해 `webview` 태그를 +사용할 수 있습니다. 게스트 컨텐츠는 `webview` 컨테이너에 담겨 대상 페이지에 삽입되고 +해당 페이지에선 게스트 컨텐츠의 배치 및 렌더링 과정을 조작할 수 있습니다. `iframe`과는 달리 `webview`는 어플리케이션과 분리된 프로세스에서 작동합니다. -이는 웹 페이지와 같은 권한을 가지지 않고 앱과 임베디드(게스트) 컨텐츠간의 모든 상호작용이 비동기로 작동한다는 것을 의미합니다. -따라서 임베디드 컨텐츠로부터 어플리케이션을 안전하게 유지할 수 있습니다. +이는 웹 페이지와 같은 권한을 가지지 않고 앱과 임베디드(게스트) 컨텐츠간의 모든 +상호작용이 비동기로 작동한다는 것을 의미합니다. 따라서 임베디드 컨텐츠로부터 +어플리케이션을 안전하게 유지할 수 있습니다. ## 예제 -웹 페이지를 어플리케이션에 삽입하려면 `webview` 태그를 사용해 원하는 타겟 페이지에 추가하면 됩니다. (게스트 컨텐츠가 앱 페이지에 추가 됩니다) -간단한 예로 `webview` 태그의 `src` 속성에 페이지를 지정하고 css 스타일을 이용해서 컨테이너의 외관을 설정할 수 있습니다: +웹 페이지를 어플리케이션에 삽입하려면 `webview` 태그를 사용해 원하는 타겟 페이지에 +추가하면 됩니다. (게스트 컨텐츠가 앱 페이지에 추가 됩니다) 간단한 예로 `webview` +태그의 `src` 속성에 페이지를 지정하고 css 스타일을 이용해서 컨테이너의 외관을 설정할 +수 있습니다: ```html ``` -게스트 컨텐츠를 조작하기 위해 자바스크립트로 `webview` 태그의 이벤트를 리스닝 하여 응답을 받을 수 있습니다. -다음 예제를 참고하세요: 첫번째 리스너는 페이지 로딩 시작시의 이벤트를 확인하고 두번째 리스너는 페이지의 로딩이 끝난시점을 확인합니다. -그리고 페이지를 로드하는 동안 "loading..." 메시지를 표시합니다. +게스트 컨텐츠를 조작하기 위해 자바스크립트로 `webview` 태그의 이벤트를 리스닝 하여 +응답을 받을 수 있습니다. 다음 예제를 참고하세요: 첫번째 리스너는 페이지 로딩 시작시의 +이벤트를 확인하고 두번째 리스너는 페이지의 로딩이 끝난시점을 확인합니다. 그리고 +페이지를 로드하는 동안 "loading..." 메시지를 표시합니다. ```html