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/ diff --git a/README-ko.md b/README-ko.md index c8a3e6c59fb7..606d4e973e3e 100644 --- a/README-ko.md +++ b/README-ko.md @@ -8,18 +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를 준수합니다. 이 프로젝트에 참여할 때 코드를 유지해야 합니다. 받아들일 수 없는 행동은 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 바이너리를 받을 수도 있습니다: +또한 [`npm`](https://docs.npmjs.com/)을 통해 미리 빌드된 Electron 바이너리를 설치할 +수도 있습니다: ```sh # $PATH에 `electron` 커맨드를 등록하고 전역에 설치합니다. @@ -35,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을 빌드 하는 방법과 프로젝트에 기여하는법 또한 문서에 +포함되어 있으니 참고하시기 바랍니다. ## 참조 문서 (번역) @@ -49,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/category/electron) 카테고리 -- Freenode 채팅의 `#atom-shell` 채널 +- Atom 포럼의 [`electron`](http://discuss.atom.io/c/electron) 카테고리 +- 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/README.md b/README.md index dd03f7099e10..beb96b4e5c2a 100644 --- a/README.md +++ b/README.md @@ -7,20 +7,20 @@ :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/) 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. ## 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 @@ -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 diff --git a/atom.gyp b/atom.gyp index d4b4f67b6310..9d667410523e 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.35.1', }, 'includes': [ 'filenames.gypi', diff --git a/atom/app/atom_main_delegate.cc b/atom/app/atom_main_delegate.cc index e4ac7cfc0a99..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); } @@ -102,13 +105,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); diff --git a/atom/browser/api/atom_api_app.cc b/atom/browser/api/atom_api_app.cc index c79dea9f7c5c..697d6eca6aab 100644 --- a/atom/browser/api/atom_api_app.cc +++ b/atom/browser/api/atom_api_app.cc @@ -7,18 +7,17 @@ #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" #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/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" @@ -26,8 +25,10 @@ #include "base/files/file_path.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/browser/render_frame_host.h" #include "content/public/common/content_switches.h" #include "native_mate/dictionary.h" #include "native_mate/object_template_builder.h" @@ -63,21 +64,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 @@ -101,12 +87,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; } @@ -132,8 +128,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,18 +141,29 @@ 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() { + 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); } @@ -201,26 +206,62 @@ 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"); } -void App::OnSelectCertificate( +void App::OnLogin(LoginHandler* login_handler) { + v8::Locker locker(isolate()); + v8::HandleScope handle_scope(isolate()); + bool prevent_default = Emit( + "login", + WebContents::CreateFrom(isolate(), login_handler->GetWebContents()), + login_handler->request(), + login_handler->auth_info(), + base::Bind(&PassLoginInformation, make_scoped_refptr(login_handler))); + + // Default behavior is to always cancel the auth. + if (!prevent_default) + login_handler->CancelAuth(); +} + +void App::AllowCertificateError( + int pid, + int fid, + int cert_error, + const net::SSLInfo& ssl_info, + const GURL& request_url, + content::ResourceType resource_type, + bool overridable, + bool strict_enforcement, + bool expired_previous_decision, + const base::Callback& callback, + content::CertificateRequestResultType* request) { + auto rfh = content::RenderFrameHost::FromID(pid, fid); + auto web_contents = content::WebContents::FromRenderFrameHost(rfh); + + v8::Locker locker(isolate()); + v8::HandleScope handle_scope(isolate()); + bool prevent_default = Emit("certificate-error", + WebContents::CreateFrom(isolate(), web_contents), + request_url, + net::ErrorToString(cert_error), + ssl_info.cert, + callback); + + // Deny the certificate by default. + if (!prevent_default) + *request = content::CERTIFICATE_REQUEST_RESULT_TYPE_DENY; +} + +void App::SelectClientCertificate( content::WebContents* web_contents, net::SSLCertRequestInfo* cert_request_info, scoped_ptr delegate) { std::shared_ptr shared_delegate(delegate.release()); bool prevent_default = - Emit("select-certificate", - api::WebContents::CreateFrom(isolate(), web_contents), + Emit("select-client-certificate", + WebContents::CreateFrom(isolate(), web_contents), cert_request_info->host_and_port.ToString(), cert_request_info->client_certs, base::Bind(&OnClientCertificateSelected, @@ -266,13 +307,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()); @@ -283,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()) @@ -317,6 +344,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)) @@ -327,6 +355,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)) @@ -334,12 +364,10 @@ 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) - .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 94cd9bbc68f9..a6f99d65e0af 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,7 +48,22 @@ class App : public mate::EventEmitter, void OnActivate(bool has_visible_windows) override; void OnWillFinishLaunching() override; void OnFinishLaunching() override; - void OnSelectCertificate( + void OnLogin(LoginHandler* login_handler) override; + + // content::ContentBrowserClient: + void AllowCertificateError( + int render_process_id, + int render_frame_id, + int cert_error, + const net::SSLInfo& ssl_info, + const GURL& request_url, + content::ResourceType resource_type, + bool overridable, + bool strict_enforcement, + bool expired_previous_decision, + const base::Callback& callback, + content::CertificateRequestResultType* request) override; + void SelectClientCertificate( content::WebContents* web_contents, net::SSLCertRequestInfo* cert_request_info, scoped_ptr delegate) override; @@ -66,14 +83,10 @@ 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); std::string GetLocale(); - v8::Local DefaultSession(v8::Isolate* isolate); - - v8::Global default_session_; scoped_ptr process_singleton_; 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 ec4dcd84b285..7dd271304a43 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" @@ -102,7 +103,7 @@ int64 DownloadItem::GetTotalBytes() { return download_item_->GetTotalBytes(); } -const GURL& DownloadItem::GetUrl() { +const GURL& DownloadItem::GetURL() { return download_item_->GetURL(); } @@ -115,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(), @@ -151,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) @@ -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_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_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_protocol.cc b/atom/browser/api/atom_api_protocol.cc index 661ab1b5cbdd..b1ad7981377a 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/net_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 { @@ -52,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) @@ -62,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_session.cc b/atom/browser/api/atom_api_session.cc index 5bb96710f226..27e1521f3d3f 100644 --- a/atom/browser/api/atom_api_session.cc +++ b/atom/browser/api/atom_api_session.cc @@ -9,12 +9,15 @@ #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/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" +#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" @@ -354,6 +357,17 @@ void Session::DisableNetworkEmulation() { base::Passed(&conditions))); } +void Session::SetCertVerifyProc(v8::Local val, + mate::Arguments* args) { + AtomCertVerifier::VerifyProc proc; + if (!(val->IsNull() || mate::ConvertFromV8(args->isolate(), val, &proc))) { + args->ThrowError("Must pass null or function"); + return; + } + + browser_context_->cert_verifier()->SetVerifyProc(proc); +} + v8::Local Session::Cookies(v8::Isolate* isolate) { if (cookies_.IsEmpty()) { auto handle = atom::api::Cookies::Create(isolate, browser_context()); @@ -372,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); } @@ -395,14 +410,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 +434,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_session.h b/atom/browser/api/atom_api_session.h index 39712f6c8486..01dc0a408a8c 100644 --- a/atom/browser/api/atom_api_session.h +++ b/atom/browser/api/atom_api_session.h @@ -72,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/api/atom_api_tray.cc b/atom/browser/api/atom_api_tray.cc index 0f5829e19c14..5e32657f008a 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,17 +67,33 @@ void Tray::OnBalloonShow() { } void Tray::OnBalloonClicked() { - Emit("balloon-clicked"); + Emit("balloon-click"); } void Tray::OnBalloonClosed() { Emit("balloon-closed"); } +void Tray::OnDrop() { + Emit("drop"); +} + void Tray::OnDropFiles(const std::vector& files) { Emit("drop-files", files); } +void Tray::OnDragEntered() { + Emit("drag-enter"); +} + +void Tray::OnDragExited() { + Emit("drag-leave"); +} + +void Tray::OnDragEnded() { + Emit("drag-end"); +} + bool Tray::IsDestroyed() const { return !tray_icon_; } @@ -145,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_tray.h b/atom/browser/api/atom_api_tray.h index dc9302597cf3..d8d6dcead16c 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; @@ -48,12 +48,18 @@ class Tray : public mate::EventEmitter, 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; - 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); diff --git a/atom/browser/api/atom_api_web_contents.cc b/atom/browser/api/atom_api_web_contents.cc index 900c3e65a376..066ca9cc7b65 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" @@ -46,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" @@ -169,11 +171,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; @@ -266,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()); @@ -404,6 +405,15 @@ void WebContents::RendererResponsive(content::WebContents* source) { owner_window()->RendererResponsive(source); } +bool WebContents::HandleContextMenu(const content::ContextMenuParams& 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; +} + 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. @@ -594,10 +604,6 @@ void WebContents::Destroy() { } } -bool WebContents::IsAlive() const { - return web_contents() != NULL; -} - int WebContents::GetID() const { return web_contents()->GetRenderProcessHost()->GetID(); } @@ -648,10 +654,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(); @@ -990,16 +992,15 @@ 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) - .SetMethod("_getUrl", &WebContents::GetURL) + .SetMethod("_loadURL", &WebContents::LoadURL) + .SetMethod("_getURL", &WebContents::GetURL) .SetMethod("getTitle", &WebContents::GetTitle) .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) @@ -1061,7 +1062,7 @@ mate::ObjectTemplateBuilder WebContents::GetObjectTemplateBuilder( } bool WebContents::IsDestroyed() const { - return !IsAlive(); + return !web_contents(); } AtomBrowserContext* WebContents::GetBrowserContext() const { @@ -1112,14 +1113,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 @@ -1133,7 +1138,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/atom_api_web_contents.h b/atom/browser/api/atom_api_web_contents.h index 7fa8951106b2..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); @@ -189,6 +188,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; diff --git a/atom/browser/api/atom_api_window.cc b/atom/browser/api/atom_api_window.cc index 45b57f5307be..7f5b78a79780 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,22 +61,82 @@ void OnCapturePageDone( callback.Run(gfx::Image::CreateFrom1xBitmap(bitmap)); } +// 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) +// 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()) + return v8::Null(isolate); + else + return buffer.ToLocalChecked(); +} +#endif + } // namespace 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); + 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); @@ -192,7 +253,9 @@ void Window::OnExecuteWindowsCommand(const std::string& command_name) { #if defined(OS_WIN) 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(isolate(), static_cast(&w_param), sizeof(WPARAM)), + ToBuffer(isolate(), static_cast(&l_param), sizeof(LPARAM))); } } #endif @@ -221,10 +284,6 @@ void Window::Close() { window_->Close(); } -bool Window::IsClosed() { - return window_->IsClosed(); -} - void Window::Focus() { window_->Focus(true); } @@ -559,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 870f8e134216..4161584206a7 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: @@ -90,7 +89,6 @@ class Window : public mate::TrackableObject, // APIs for NativeWindow. void Close(); - bool IsClosed(); void Focus(); bool IsFocused(); void Show(); @@ -150,12 +148,10 @@ class Window : public mate::TrackableObject, void SetAspectRatio(double aspect_ratio, mate::Arguments* args); #if defined(OS_WIN) - typedef base::Callback MessageCallback; - typedef std::map MessageCallbackMap; - MessageCallbackMap messages_callback_map_; + typedef base::Callback, + v8::Local)> MessageCallback; - bool HookWindowMessage(UINT message, - const MessageCallback& callback); + bool HookWindowMessage(UINT message, const MessageCallback& callback); bool IsWindowMessageHooked(UINT message); void UnhookWindowMessage(UINT message); void UnhookAllWindowMessages(); @@ -171,6 +167,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/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()); } diff --git a/atom/browser/api/lib/app.coffee b/atom/browser/api/lib/app.coffee index 18c80dc2b1f4..a2fdb847e1c5 100644 --- a/atom/browser/api/lib/app.coffee +++ b/atom/browser/api/lib/app.coffee @@ -1,30 +1,17 @@ -EventEmitter = require('events').EventEmitter +{deprecate, session, Menu} = require 'electron' +{EventEmitter} = require 'events' bindings = process.atomBinding 'app' -sessionBindings = process.atomBinding 'session' downloadItemBindings = process.atomBinding 'download_item' app = bindings.app app.__proto__ = EventEmitter.prototype -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 - # 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() - app.setApplicationMenu = (menu) -> - require('menu').setApplicationMenu menu + Menu.setApplicationMenu menu app.getApplicationMenu = -> - require('menu').getApplicationMenu() + Menu.getApplicationMenu() app.commandLine = appendSwitch: bindings.appendSwitch, @@ -47,22 +34,40 @@ app.setAppPath = (path) -> app.getAppPath = -> appPath -# 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 -app.resolveProxy = -> @defaultSession.resolveProxy.apply @defaultSession, arguments -app.on 'activate', (event, hasVisibleWindows) -> @emit 'activate-with-no-open-windows' if not hasVisibleWindows +# 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... -# Session wrapper. -sessionBindings._setWrapSession wrapSession -process.once 'exit', sessionBindings._clearWrapSession +# 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 +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. + @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. +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' + deprecate.rename downloadItem, 'getUrl', 'getURL' downloadItemBindings._setWrapDownloadItem wrapDownloadItem -process.once 'exit', downloadItemBindings._clearWrapDownloadItem # Only one App object pemitted. module.exports = app 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/auto-updater.coffee b/atom/browser/api/lib/auto-updater.coffee index 41b78a00d7e0..28df59fbc3db 100644 --- a/atom/browser/api/lib/auto-updater.coffee +++ b/atom/browser/api/lib/auto-updater.coffee @@ -1,7 +1,12 @@ -switch process.platform - when 'win32' - module.exports = require './auto-updater/auto-updater-win' - when 'darwin' - module.exports = require './auto-updater/auto-updater-mac' +{deprecate} = require 'electron' + +autoUpdater = + 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' + +# Deprecated. +deprecate.rename autoUpdater, 'setFeedUrl', 'setFeedURL' + +module.exports = autoUpdater 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/atom/browser/api/lib/auto-updater/auto-updater-win.coffee b/atom/browser/api/lib/auto-updater/auto-updater-win.coffee index a9a61d8efe3f..e7cb194ffcf4 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' @@ -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 6ffba50d34cb..4cdffae87a60 100644 --- a/atom/browser/api/lib/browser-window.coffee +++ b/atom/browser/api/lib/browser-window.coffee @@ -1,11 +1,12 @@ -EventEmitter = require('events').EventEmitter -app = require 'app' -ipc = require 'ipc' +{ipcMain, deprecate} = require 'electron' +{EventEmitter} = require 'events' -BrowserWindow = process.atomBinding('window').BrowserWindow +{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() @@ -14,7 +15,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(...) @@ -70,33 +71,35 @@ BrowserWindow.fromDevToolsWebContents = (webContents) -> return window for window in windows when window.devToolsWebContents?.equal 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::loadURL = -> @webContents.loadURL.apply @webContents, arguments +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.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, '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' +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/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 new file mode 100644 index 000000000000..3f7d9b1a13fe --- /dev/null +++ b/atom/browser/api/lib/exports/electron.coffee @@ -0,0 +1,55 @@ +# 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' + session: + enumerable: true + get: -> require '../session' + 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-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..8019a385dd90 100644 --- a/atom/browser/api/lib/ipc.coffee +++ b/atom/browser/api/lib/ipc.coffee @@ -1,3 +1,6 @@ -EventEmitter = require('events').EventEmitter +{deprecate, ipcMain} = require 'electron' -module.exports = new EventEmitter +# This module is deprecated, we mirror everything from ipcMain. +deprecate.warn 'ipc module', 'ipcMain module' + +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 f78d92c341d6..d0c539a99db5 100644 --- a/atom/browser/api/lib/navigation-controller.coffee +++ b/atom/browser/api/lib/navigation-controller.coffee @@ -1,15 +1,15 @@ -ipc = require 'ipc' +{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. # 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,11 +59,11 @@ class NavigationController reload: -> @pendingIndex = @currentIndex - @webContents._loadUrl @getUrl(), {} + @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 @@ -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/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/session.coffee b/atom/browser/api/lib/session.coffee new file mode 100644 index 000000000000..6abfe7925e69 --- /dev/null +++ b/atom/browser/api/lib/session.coffee @@ -0,0 +1,23 @@ +{EventEmitter} = require 'events' + +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 + +bindings._setWrapSession wrapSession diff --git a/atom/browser/api/lib/tray.coffee b/atom/browser/api/lib/tray.coffee index 1c225ddd403c..db26ab5b7ed1 100644 --- a/atom/browser/api/lib/tray.coffee +++ b/atom/browser/api/lib/tray.coffee @@ -1,14 +1,19 @@ -EventEmitter = require('events').EventEmitter -bindings = process.atomBinding 'tray' +{deprecate} = require 'electron' +{EventEmitter} = require 'events' -Tray = bindings.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/browser/api/lib/web-contents.coffee b/atom/browser/api/lib/web-contents.coffee index 3a2abfb5155f..335928dcea81 100644 --- a/atom/browser/api/lib/web-contents.coffee +++ b/atom/browser/api/lib/web-contents.coffee @@ -1,7 +1,7 @@ -EventEmitter = require('events').EventEmitter -NavigationController = require './navigation-controller' +{EventEmitter} = require 'events' +{deprecate, ipcMain, session, NavigationController, Menu} = require 'electron' + binding = process.atomBinding 'web_contents' -ipc = require 'ipc' nextId = 0 getNextId = -> ++nextId @@ -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) @@ -59,11 +59,20 @@ 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) -> + 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 = @@ -106,7 +115,6 @@ wrapWebContents = (webContents) -> @_printToPDF printingSetting, callback binding._setWrapWebContents wrapWebContents -process.once 'exit', binding._clearWrapWebContents module.exports.create = (options={}) -> binding.create(options) 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/atom_browser_client.cc b/atom/browser/atom_browser_client.cc index 4969ce47a679..38fdc0e19f9e 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() { @@ -208,6 +207,26 @@ content::QuotaPermissionContext* return new AtomQuotaPermissionContext; } +void AtomBrowserClient::AllowCertificateError( + int render_process_id, + int render_frame_id, + int cert_error, + const net::SSLInfo& ssl_info, + const GURL& request_url, + content::ResourceType resource_type, + bool overridable, + bool strict_enforcement, + bool expired_previous_decision, + const base::Callback& callback, + content::CertificateRequestResultType* request) { + if (delegate_) { + delegate_->AllowCertificateError( + render_process_id, render_frame_id, cert_error, ssl_info, request_url, + resource_type, overridable, strict_enforcement, + expired_previous_decision, callback, request); + } +} + void AtomBrowserClient::SelectClientCertificate( content::WebContents* web_contents, net::SSLCertRequestInfo* cert_request_info, @@ -222,10 +241,10 @@ void AtomBrowserClient::SelectClientCertificate( return; } - if (!cert_request_info->client_certs.empty()) - Browser::Get()->ClientCertificateSelector(web_contents, - cert_request_info, - delegate.Pass()); + if (!cert_request_info->client_certs.empty() && delegate_) { + delegate_->SelectClientCertificate( + web_contents, cert_request_info, delegate.Pass()); + } } void AtomBrowserClient::ResourceDispatcherHostCreated() { diff --git a/atom/browser/atom_browser_client.h b/atom/browser/atom_browser_client.h index ee4700456cc6..75e17494593b 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. @@ -54,6 +57,18 @@ class AtomBrowserClient : public brightray::BrowserClient, int child_process_id) override; void DidCreatePpapiPlugin(content::BrowserPpapiHost* browser_host) override; content::QuotaPermissionContext* CreateQuotaPermissionContext() override; + void AllowCertificateError( + int render_process_id, + int render_frame_id, + int cert_error, + const net::SSLInfo& ssl_info, + const GURL& request_url, + content::ResourceType resource_type, + bool overridable, + bool strict_enforcement, + bool expired_previous_decision, + const base::Callback& callback, + content::CertificateRequestResultType* request) override; void SelectClientCertificate( content::WebContents* web_contents, net::SSLCertRequestInfo* cert_request_info, @@ -74,6 +89,8 @@ class AtomBrowserClient : public brightray::BrowserClient, scoped_ptr resource_dispatcher_host_delegate_; + Delegate* delegate_; + DISALLOW_COPY_AND_ASSIGN(AtomBrowserClient); }; diff --git a/atom/browser/atom_browser_context.cc b/atom/browser/atom_browser_context.cc index 6cfb160489fc..08c799962728 100644 --- a/atom/browser/atom_browser_context.cc +++ b/atom/browser/atom_browser_context.cc @@ -6,8 +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" @@ -60,6 +61,7 @@ std::string RemoveWhitespace(const std::string& str) { AtomBrowserContext::AtomBrowserContext(const std::string& partition, bool in_memory) : brightray::BrowserContext(partition, in_memory), + cert_verifier_(new AtomCertVerifier), job_factory_(new AtomURLRequestJobFactory), allow_ntlm_everywhere_(false) { } @@ -158,6 +160,10 @@ content::BrowserPluginGuestManager* AtomBrowserContext::GetGuestManager() { return guest_manager_.get(); } +net::CertVerifier* AtomBrowserContext::CreateCertVerifier() { + return cert_verifier_; +} + 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..d3d7735c810d 100644 --- a/atom/browser/atom_browser_context.h +++ b/atom/browser/atom_browser_context.h @@ -12,6 +12,7 @@ namespace atom { class AtomDownloadManagerDelegate; +class AtomCertVerifier; class AtomURLRequestJobFactory; class WebViewManager; @@ -27,6 +28,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; @@ -39,6 +41,8 @@ class AtomBrowserContext : public brightray::BrowserContext { void AllowNTLMCredentialsForAllDomains(bool should_allow); + AtomCertVerifier* cert_verifier() const { return cert_verifier_; } + AtomURLRequestJobFactory* job_factory() const { return job_factory_; } private: @@ -46,6 +50,7 @@ class AtomBrowserContext : public brightray::BrowserContext { scoped_ptr guest_manager_; // Managed by brightray::BrowserContext. + AtomCertVerifier* cert_verifier_; AtomURLRequestJobFactory* job_factory_; bool allow_ntlm_everywhere_; diff --git a/atom/browser/atom_browser_main_parts.cc b/atom/browser/atom_browser_main_parts.cc index 5fae5bfdbedd..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) @@ -128,11 +142,23 @@ 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. 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 diff --git a/atom/browser/atom_browser_main_parts.h b/atom/browser/atom_browser_main_parts.h index 65b142157dc1..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,11 +45,11 @@ 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) void PreMainMessageLoopStart() override; - void PostDestroyThreads() override; #endif private: @@ -56,6 +59,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_; @@ -63,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/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]; } 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/browser.cc b/atom/browser/browser.cc index 79ebe91a87e6..c77f359760c9 100644 --- a/atom/browser/browser.cc +++ b/atom/browser/browser.cc @@ -7,10 +7,9 @@ #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" -#include "net/ssl/ssl_cert_request_info.h" namespace atom { @@ -45,6 +44,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; @@ -89,10 +109,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) { @@ -123,15 +139,8 @@ 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)); } void Browser::NotifyAndShutdown() { diff --git a/atom/browser/browser.h b/atom/browser/browser.h index bae281d4d370..e46624b158df 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 { @@ -29,6 +29,8 @@ class MenuModel; namespace atom { +class LoginHandler; + // This class is used for control application-wide operations. class Browser : public WindowListObserver { public: @@ -40,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(); @@ -64,6 +69,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 { @@ -98,8 +106,10 @@ 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); + // 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. @@ -116,11 +126,8 @@ 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); void AddObserver(BrowserObserver* obs) { observers_.AddObserver(obs); 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_observer.h b/atom/browser/browser_observer.h index 45e86e620f84..f6d76bc13fb3 100644 --- a/atom/browser/browser_observer.h +++ b/atom/browser/browser_observer.h @@ -7,19 +7,10 @@ #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; + class BrowserObserver { public: // The browser is about to close all windows. @@ -51,11 +42,8 @@ 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) {} protected: virtual ~BrowserObserver() {} diff --git a/atom/browser/browser_win.cc b/atom/browser/browser_win.cc index b861af945421..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; @@ -56,7 +59,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,16 +69,21 @@ 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(); } +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))) 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,10 +125,13 @@ 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); - SetCurrentProcessExplicitAppUserModelID(app_user_model_id_.c_str()); +PCWSTR Browser::GetAppUserModelID() { + if (app_user_model_id_.empty()) { + SetAppUserModelID(ReplaceStringPlaceholders( + kAppUserModelIDFormat, base::UTF8ToUTF16(GetName()), nullptr)); + } + + return app_user_model_id_.c_str(); } std::string Browser::GetExecutableFileVersion() const { diff --git a/atom/browser/default_app/default_app.js b/atom/browser/default_app/default_app.js index 2378902b44ec..2ec765d0d691 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; @@ -12,9 +13,9 @@ 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.loadURL('file://' + __dirname + '/index.html'); mainWindow.focus(); }); 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 @@ ``` -또 하나의 예를 들자면 다음 예제는 랜더러 프로세스에서 template API를 사용하여 어플리케이션 메뉴를 만듭니다: +또 하나의 예를 들자면 다음 예제는 랜더러 프로세스에서 template API를 사용하여 +어플리케이션 메뉴를 만듭니다: ```javascript var template = [ @@ -130,14 +133,14 @@ var template = [ submenu: [ { label: 'Learn More', - click: function() { require('shell').openExternal('http://electron.atom.io') } + click: function() { require('electron').shell.openExternal('http://electron.atom.io') } }, ] }, ]; if (process.platform == 'darwin') { - var name = require('app').getName(); + var name = require('electron').app.getName(); template.unshift({ label: name, submenu: [ @@ -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 485ab7bc71d4..917dbb3a71b8 100644 --- a/docs-translations/ko-KR/api/native-image.md +++ b/docs-translations/ko-KR/api/native-image.md @@ -1,19 +1,19 @@ -# NativeImage +# nativeImage -Electron은 파일 경로 또는 `NativeImage` 인스턴스를 통해 이미지를 사용할 수 있는 API를 가지고 있습니다. -`null`을 전달할 경우 빈 이미지가 생성됩니다. +Electron은 파일 경로 또는 `nativeImage` 인스턴스를 통해 이미지를 사용할 수 있는 API를 +가지고 있습니다. `null`을 전달할 경우 빈 이미지가 생성됩니다. -예를 들어 트레이 메뉴를 만들거나 윈도우의 아이콘을 설정할 때 다음과 같이 파일 경로를 전달하여 이미지를 사용할 수 있습니다: +예를 들어 트레이 메뉴를 만들거나 윈도우의 아이콘을 설정할 때 다음과 같이 파일 경로를 +전달하여 이미지를 사용할 수 있습니다: ```javascript var appIcon = new Tray('/Users/somebody/images/icon.png'); var window = new BrowserWindow({icon: '/Users/somebody/images/window.png'}); ``` -이 예제는 클립보드로부터 가져온 `NativeImage`로 트레이 메뉴를 생성합니다: +이 예제는 클립보드로부터 가져온 `nativeImage`로 트레이 메뉴를 생성합니다: ```javascript -var clipboard = require('clipboard'); var image = clipboard.readImage(); var appIcon = new Tray(image); ``` @@ -27,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/ @@ -61,53 +65,56 @@ var appIcon = new Tray('/Users/somebody/images/icon.png'); ## 템플릿 이미지 -템플릿 이미지는 검은색과 명확한 색상(알파 채널)으로 이루어져 있습니다. -템플릿 이미지는 단독 이미지로 사용되지 않고 다른 컨텐츠와 혼합되어 최종 외관 만드는데 사용됩니다. +템플릿 이미지는 검은색과 명확한 색상(알파 채널)으로 이루어져 있습니다. 템플릿 이미지는 +단독 이미지로 사용되지 않고 다른 컨텐츠와 혼합되어 최종 외관 만드는데 사용됩니다. -가장 일반적으로 템플릿 이미지는 밝고 어두운 테마 색상으로 변경할 수 있는 메뉴 바 아이콘 등에 사용되고 있습니다. +가장 일반적으로 템플릿 이미지는 밝고 어두운 테마 색상으로 변경할 수 있는 메뉴 바 아이콘 +등에 사용되고 있습니다. **참고:** 템플릿 이미지는 OS X 운영체제만 지원합니다. -템플릿 이미지를 지정하려면 다음 예제와 같이 파일명에 `Template` 문자열을 추가해야 합니다: +템플릿 이미지를 지정하려면 다음 예제와 같이 파일명에 `Template` 문자열을 추가해야 +합니다: * `xxxTemplate.png` * `xxxTemplate@2x.png` ## Methods -`NativeImage` 클래스는 다음과 같은 메서드를 가지고 있습니다: +`nativeImage` 클래스는 다음과 같은 메서드를 가지고 있습니다: -### `NativeImage.createEmpty()` +### `nativeImage.createEmpty()` -빈 `NativeImage` 인스턴스를 만듭니다. +빈 `nativeImage` 인스턴스를 만듭니다. -### `NativeImage.createFromPath(path)` +### `nativeImage.createFromPath(path)` * `path` String -`path`로부터 이미지를 로드하여 새로운 `NativeImage` 인스턴스를 만듭니다. +`path`로부터 이미지를 로드하여 새로운 `nativeImage` 인스턴스를 만듭니다. -### `NativeImage.createFromBuffer(buffer[, scaleFactor])` +### `nativeImage.createFromBuffer(buffer[, scaleFactor])` * `buffer` [Buffer][buffer] * `scaleFactor` Double (optional) -`buffer`로부터 이미지를 로드하여 새로운 `NativeImage` 인스턴스를 만듭니다. `scaleFactor`는 1.0이 기본입니다. +`buffer`로부터 이미지를 로드하여 새로운 `nativeImage` 인스턴스를 만듭니다. +`scaleFactor`의 기본값은 1.0 입니다. -### `NativeImage.createFromDataUrl(dataUrl)` +### `nativeImage.createFromDataURL(dataURL)` -* `dataUrl` String +* `dataURL` String -`dataUrl`로부터 이미지를 로드하여 새로운 `NativeImage` 인스턴스를 만듭니다. +`dataURL`로부터 이미지를 로드하여 새로운 `nativeImage` 인스턴스를 만듭니다. ## Instance Methods `nativeImage` 인스턴스 객체에서 사용할 수 있는 메서드 입니다: ```javascript -var NativeImage = require('native-image'); +const nativeImage = require('electron').nativeImage; -var image = NativeImage.createFromPath('/Users/somebody/images/icon.png'); +var image = nativeImage.createFromPath('/Users/somebody/images/icon.png'); ``` ### `image.toPng()` @@ -120,7 +127,7 @@ var image = NativeImage.createFromPath('/Users/somebody/images/icon.png'); `JPEG` 이미지를 인코딩한 데이터를 [Buffer][buffer]로 반환합니다. -### `image.toDataUrl()` +### `image.toDataURL()` 이미지를 data URL로 반환합니다. diff --git a/docs-translations/ko-KR/api/power-monitor.md b/docs-translations/ko-KR/api/power-monitor.md index 990bf54e48c0..29a3aabc84a1 100644 --- a/docs-translations/ko-KR/api/power-monitor.md +++ b/docs-translations/ko-KR/api/power-monitor.md @@ -1,8 +1,9 @@ -# power-monitor +# powerMonitor `power-monitor` 모듈은 PC의 파워 상태를 나타냅니다. (주로 노트북 등에서 사용됩니다) -이 모듈은 메인 프로세스에서만 사용할 수 있으며, (remote 모듈(RPC)을 사용해도 작동이 됩니다) -메인 프로세스의 `app` 모듈에서 `ready` 이벤트를 호출하기 전까지 사용할 수 없습니다. +이 모듈은 메인 프로세스에서만 사용할 수 있으며, (remote 모듈(RPC)을 사용해도 작동이 +됩니다) 메인 프로세스의 `app` 모듈에서 `ready` 이벤트를 호출하기 전까지 사용할 수 +없습니다. 예제: @@ -10,7 +11,7 @@ var app = require('app'); app.on('ready', function() { - require('power-monitor').on('suspend', function() { + require('electron').powerMonitor.on('suspend', function() { console.log('절전모드로 진입합니다!'); }); }); diff --git a/docs-translations/ko-KR/api/power-save-blocker.md b/docs-translations/ko-KR/api/power-save-blocker.md index 0521a82b0e70..560b3fc9cef5 100644 --- a/docs-translations/ko-KR/api/power-save-blocker.md +++ b/docs-translations/ko-KR/api/power-save-blocker.md @@ -1,11 +1,12 @@ # powerSaveBlocker -`power-save-blocker` 모듈은 시스템이 저전력(슬립) 모드로 진입하는 것을 막고 앱 시스템과 화면이 항상 활성화 상태를 유지할 수 있도록 하는 몇가지 유틸리티를 제공하는 모듈입니다. +`powerSaveBlocker` 모듈은 시스템이 저전력(슬립) 모드로 진입하는 것을 막고 앱 시스템과 +화면이 항상 활성화 상태를 유지할 수 있도록 하는 몇가지 유틸리티를 제공하는 모듈입니다. 예제: ```javascript -var powerSaveBlocker = require('power-save-blocker'); +const powerSaveBlocker = require('electron').powerSaveBlocker; var id = powerSaveBlocker.start('prevent-display-sleep'); console.log(powerSaveBlocker.isStarted(id)); @@ -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 d79963239585..a85ac1428ca6 100644 --- a/docs-translations/ko-KR/api/protocol.md +++ b/docs-translations/ko-KR/api/protocol.md @@ -1,15 +1,17 @@ # protocol -`protocol` 모듈은 이미 있는 프로토콜의 동작을 가로채거나 새로운 프로토콜을 만들 수 있는 기능을 제공합니다. +`protocol` 모듈은 이미 있는 프로토콜의 동작을 가로채거나 새로운 프로토콜을 만들 수 +있는 기능을 제공합니다. 다음 예제는 `file://` 프로토콜과 비슷한 일을 하는 커스텀 프로토콜을 설정합니다: ```javascript -var app = require('app'); -var path = require('path'); +const electron = require('electron'); +const app = electron.app; +const path = require('path'); app.on('ready', function() { - var protocol = require('protocol'); + var protocol = electron.protocol; protocol.registerFileProtocol('atom', function(request, callback) { var url = request.url.substr(7); callback({path: path.normalize(__dirname + '/' + url)}); @@ -30,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])` @@ -39,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])` @@ -60,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`을 호출해야 합니다. 예제: @@ -80,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])` @@ -89,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`, `referrer`, `session` 속성을 포함하는 객체를 인자에 포함하여 `callback`을 +호출해야 합니다. -기본적으로 HTTP 요청은 현재 세션을 재사용합니다. 만약 서로 다른 세션에 요청을 보내고 싶으면 `session`을 `null`로 지정해야 합니다. +기본적으로 HTTP 요청은 현재 세션을 재사용합니다. 만약 서로 다른 세션에 요청을 보내고 +싶으면 `session`을 `null`로 지정해야 합니다. ### `protocol.unregisterProtocol(scheme[, completion])` @@ -106,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])` @@ -130,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])` @@ -138,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 756acd429a1b..935b09865130 100644 --- a/docs-translations/ko-KR/api/remote.md +++ b/docs-translations/ko-KR/api/remote.md @@ -1,51 +1,62 @@ # remote -`remote` 모듈은 메인 프로세스와 랜더러 프로세스(웹 페이지) 사이의 inter-process (IPC) 통신을 간단하게 추상화 한 모듈입니다. +`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 통신을 하지 않고도 간단한 API를 통해 직접 메인 프로세스의 모듈과 +메서드를 사용할 수 있습니다. 이 개념은 Java의 [RMI][rmi]와 비슷합니다. 다음 예제는 랜더러 프로세스에서 브라우저 창을 만드는 예제입니다: ```javascript -var remote = require('remote'); -var BrowserWindow = remote.require('browser-window'); +const remote = require('electron').remote; +const BrowserWindow = remote.BrowserWindow; var win = new BrowserWindow({ width: 800, height: 600 }); -win.loadUrl('https://github.com'); +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,14 +102,27 @@ remote.getCurrentWindow().on('close', function() { }); ``` -하지만 이 코드 처럼 이벤트를 명시적으로 제거하지 않는 이상 콜백 함수의 참조가 계속해서 메인 프로세스에 남아있게 됩니다. -만약 명시적으로 콜백을 제거하지 않으면 매 번 창을 새로고침 할 때마다 콜백을 새로 설치합니다. -게다가 이전 콜백이 제거되지 않고 계속해서 쌓이면서 메모리 누수가 발생합니다. +하지만 이 코드 처럼 이벤트를 명시적으로 제거하지 않는 이상 콜백 함수의 참조가 계속해서 +메인 프로세스에 남아있게 됩니다. 만약 명시적으로 콜백을 제거하지 않으면 매 번 창을 +새로고침 할 때마다 콜백을 새로 설치합니다. 게다가 이전 콜백이 제거되지 않고 계속해서 +쌓이면서 메모리 누수가 발생합니다. -설상가상으로 이전에 설치된 콜백의 콘텍스트가 릴리즈 되고 난 후(예: 페이지 새로고침) `close` 이벤트가 발생하면 예외가 발생하고 메인 프로세스가 작동 중지됩니다. +설상가상으로 이전에 설치된 콜백의 콘텍스트가 릴리즈 되고 난 후(예: 페이지 새로고침) +`close` 이벤트가 발생하면 예외가 발생하고 메인 프로세스가 작동 중지됩니다. -이러한 문제를 피하려면 랜더러 프로세스에서 메인 프로세스로 넘긴 함수의 참조를 사용 후 확실하게 제거해야 합니다. -작업 후 이벤트 콜백을 포함하여 책임 있게 함수의 참조를 제거하거나 메인 프로세스에서 랜더러 프로세스가 종료될 때 내부적으로 함수 참조를 제거하도록 설계해야 합니다. +이러한 문제를 피하려면 랜더러 프로세스에서 메인 프로세스로 넘긴 함수의 참조를 사용 후 +확실하게 제거해야 합니다. 작업 후 이벤트 콜백을 포함하여 책임 있게 함수의 참조를 +제거하거나 메인 프로세스에서 랜더러 프로세스가 종료될 때 내부적으로 함수 참조를 +제거하도록 설계해야 합니다. + +## 메인 프로세스의 빌트인 모듈에 접근 + +메인 프로세스의 빌트인 모듈은 `remote` 모듈에 getter로 등록되어 있습니다. 따라서 +`remote` 모듈을 `electron` 모듈처럼 직접 사용할 수 있습니다. + +```javascript +const app = remote.app; +``` ## Methods @@ -124,4 +150,7 @@ remote.getCurrentWindow().on('close', function() { ### `remote.process` -메인 프로세스의 `process` 객체를 반환합니다. `remote.getGlobal('process')`와 같습니다. 하지만 캐시 됩니다. +메인 프로세스의 `process` 객체를 반환합니다. `remote.getGlobal('process')`와 +같습니다. 하지만 캐시 됩니다. + +[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 c65540eba228..dfd85fb446e1 100644 --- a/docs-translations/ko-KR/api/screen.md +++ b/docs-translations/ko-KR/api/screen.md @@ -3,21 +3,24 @@ `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` 같은 이름으로 모듈 이름을 대체하여 사용해야 합니다. 다음 예제는 화면 전체를 채우는 윈도우 창을 생성합니다: ```javascript -var app = require('app'); -var BrowserWindow = require('browser-window'); +const electron = require('electron'); +const app = electron.app; +const BrowserWindow = electron.BrowserWindow; var mainWindow; app.on('ready', function() { - var electronScreen = require('screen'); + var electronScreen = electron.screen; var size = electronScreen.getPrimaryDisplay().workAreaSize; mainWindow = new BrowserWindow({ width: size.width, height: size.height }); }); diff --git a/docs-translations/ko-KR/api/session.md b/docs-translations/ko-KR/api/session.md index b5cd79cbb93e..aa5ab2ed3e50 100644 --- a/docs-translations/ko-KR/api/session.md +++ b/docs-translations/ko-KR/api/session.md @@ -1,13 +1,14 @@ # 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'); var win = new BrowserWindow({ width: 800, height: 600 }); -win.loadUrl("http://github.com"); +win.loadURL("http://github.com"); var session = win.webContents.session ``` @@ -27,26 +28,52 @@ Electron의 `webContents`에서 `item`을 다운로드할 때 발생하는 이 ```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); }); }); ``` +### 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` 객체는 다음과 같은 메서드와 속성을 가지고 있습니다: ### `session.cookies` -`cookies` 속성은 쿠키를 조작하는 방법을 제공합니다. 예를 들어 다음과 같이 할 수 있습니다: +`cookies` 속성은 쿠키를 조작하는 방법을 제공합니다. 예를 들어 다음과 같이 할 수 +있습니다: ```javascript var BrowserWindow = require('browser-window'); 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() { // 모든 쿠키를 가져옵니다. @@ -77,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`와 일치하는 경로에 대한 쿠키를 가져옵니다. @@ -92,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 @@ -130,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` @@ -147,7 +182,8 @@ win.webContents.on('did-finish-load', function() { 세션에 사용할 프록시 `config`를 분석하고 프록시를 적용합니다. -세션에 사용할 프록시는 `config`가 PAC 주소일 경우 그대로 적용하고, 다른 형식일 경우 다음 규칙에 따라 적용합니다. +세션에 사용할 프록시는 `config`가 PAC 주소일 경우 그대로 적용하고, 다른 형식일 경우 +다음 규칙에 따라 적용합니다. ``` config = scheme-proxies[";"] @@ -157,32 +193,35 @@ 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)` * `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 a84436f78071..4183d3b2502d 100644 --- a/docs-translations/ko-KR/api/shell.md +++ b/docs-translations/ko-KR/api/shell.md @@ -5,7 +5,7 @@ 다음 예제는 설정된 URL을 유저의 기본 브라우저로 엽니다: ```javascript -var shell = require('shell'); +const shell = require('electron').shell; shell.openExternal('https://github.com'); ``` @@ -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 3b1633da6d5d..fd0791cd4a8e 100644 --- a/docs-translations/ko-KR/api/synopsis.md +++ b/docs-translations/ko-KR/api/synopsis.md @@ -1,40 +1,83 @@ # 개요 -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](https://en.wikipedia.org/wiki/Graphical_user_interface)와 저 수준 시스템에 관련된 모듈들은 오직 메인 프로세스에서만 사용할 수 있습니다. -[메인 프로세스 vs. 랜더러 프로세스](../tutorial/quick-start.md#메인 프로세스) 컨셉에 익숙해야 이 모듈들을 사용하기 쉬우므로 관련 문서를 읽어 보는 것을 권장합니다. +기본적인 규칙으로 [GUI][gui]와 저 수준 시스템에 관련된 모듈들은 오직 메인 +프로세스에서만 사용할 수 있습니다. [메인 프로세스 vs. 랜더러 프로세스](../tutorial/quick-start.md#메인-프로세스) +컨셉에 익숙해야 모듈을 다루기 쉬우므로 관련 문서를 읽어 보는 것을 권장합니다. 메인 프로세스 스크립트는 일반 Node.js 스크립트와 비슷합니다: ```javascript -var app = require('app'); -var BrowserWindow = require('browser-window'); +const electron = require('electron'); +const app = electron.app; +const BrowserWindow = electron.BrowserWindow; var window = null; app.on('ready', function() { window = new BrowserWindow({width: 800, height: 600}); - window.loadUrl('https://github.com'); + window.loadURL('https://github.com'); }); ``` -랜더러 프로세스도 예외적인 node module들을 사용할 수 있다는 점을 제외하면 일반 웹 페이지와 크게 다를게 없습니다: +랜더러 프로세스도 예외적인 node module들을 사용할 수 있다는 점을 제외하면 일반 웹 +페이지와 크게 다를게 없습니다: ```html - - - + + + ``` -어플리케이션을 실행하려면 [앱 실행하기](../tutorial/quick-start.md#앱 실행하기) 문서를 참고하기 바랍니다. +어플리케이션을 실행하려면 [앱 실행하기](../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를 지원하고 있습니다. + +완벽하게 모든 구 버전 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 diff --git a/docs-translations/ko-KR/api/tray.md b/docs-translations/ko-KR/api/tray.md index cd821f581b32..97db97f42607 100644 --- a/docs-translations/ko-KR/api/tray.md +++ b/docs-translations/ko-KR/api/tray.md @@ -1,11 +1,13 @@ # Tray -`Tray`는 OS의 알림 영역에 아이콘을 표시합니다. 보통 컨텍스트 메뉴(context menu)를 같이 사용합니다. +`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(){ @@ -24,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가 모든 플랫폼에서 똑같이 작동하게 하고 싶다면 `clicked` 이벤트에 의존해선 안됩니다. -그리고 언제나 컨텍스트 메뉴를 포함해야 합니다. +이러한 이유로 Tray API가 모든 플랫폼에서 똑같이 작동하게 하고 싶다면 `click` 이벤트에 +의존해선 안되며 언제나 컨텍스트 메뉴를 포함해야 합니다. ## Class: Tray @@ -46,9 +50,9 @@ __플랫폼별 한계:__ `Tray` 모듈은 다음과 같은 이벤트를 가지고 있습니다: -**참고:** 몇가지 이벤트는 특정한 플랫폼에서만 작동합니다. +**참고:** 몇몇 이벤트는 특정한 플랫폼에서만 작동합니다. -### Event: 'clicked' +### Event: 'click' * `event` Event * `altKey` Boolean @@ -65,7 +69,7 @@ __플랫폼별 한계:__ __주의:__ `bounds`는 OS X 와 Windows에서만 작동합니다. -### Event: 'right-clicked' _OS X_ _Windows_ +### Event: 'right-click' _OS X_ _Windows_ * `event` Event * `altKey` Boolean @@ -80,7 +84,7 @@ __주의:__ `bounds`는 OS X 와 Windows에서만 작동합니다. 트레이 아이콘을 오른쪽 클릭될 때 호출 됩니다. -### Event: 'double-clicked' _OS X_ _Windows_ +### Event: 'double-click' _OS X_ _Windows_ * `event` Event * `altKey` Boolean @@ -97,15 +101,19 @@ __주의:__ `bounds`는 OS X 와 Windows에서만 작동합니다. ### Event: 'balloon-show' _Windows_ -알림풍선이 보여질 때 발생하는 이벤트입니다. +풍선 팝업이 보여질 때 발생하는 이벤트입니다. -### Event: 'balloon-clicked' _Windows_ +### Event: 'balloon-click' _Windows_ -알림풍선이 클릭될 때 발생하는 이벤트입니다. +풍선 팝업이 클릭될 때 발생하는 이벤트입니다. ### Event: 'balloon-closed' _Windows_ -알림풍선이 시간이 지나 사라지거나 유저가 클릭하여 닫을 때 발생하는 이벤트입니다. +풍선 팝업이 시간이 지나 사라지거나 유저가 클릭하여 닫을 때 발생하는 이벤트입니다. + +### Event: 'drop' _OS X_ + +드래그 가능한 아이템이 트레이 아이콘에 드롭되면 발생하는 이벤트입니다. ### Event: 'drop-files' _OS X_ @@ -114,6 +122,18 @@ __주의:__ `bounds`는 OS X 와 Windows에서만 작동합니다. 트레이 아이콘에 파일이 드롭되면 발생하는 이벤트입니다. +### Event: 'drag-enter' _OS X_ + +트레이 아이콘에 드래그 작업이 시작될 때 발생하는 이벤트입니다. + +### Event: 'drag-leave' _OS X_ + +트레이 아이콘에 드래그 작업이 종료될 때 발생하는 이벤트입니다. + +### Event: 'drag-end' _OS X_ + +트레이 아이콘에 드래그 작업이 종료되거나 다른 위치에서 종료될 때 발생하는 이벤트입니다. + ## Methods `Tray` 모듈은 다음과 같은 메서드를 가지고 있습니다: @@ -152,7 +172,8 @@ __주의:__ `bounds`는 OS X 와 Windows에서만 작동합니다. * `highlight` Boolean -트레이 아이콘을 클릭했을 때 하이라이트 될지 설정합니다. +트레이 아이콘이 클릭됐을 때 아이콘의 배경이 파란색으로 하이라이트 될지 여부를 지정합니다. +기본값은 true입니다. ### `Tray.displayBalloon(options)` _Windows_ @@ -161,7 +182,7 @@ __주의:__ `bounds`는 OS X 와 Windows에서만 작동합니다. * `title` String * `content` String -트레이에 알림풍선을 생성합니다. +트레이에 풍선 팝업을 생성합니다. ### `Tray.popContextMenu([position])` _OS X_ _Windows_ diff --git a/docs-translations/ko-KR/api/web-contents.md b/docs-translations/ko-KR/api/web-contents.md new file mode 100644 index 000000000000..edec4d472b22 --- /dev/null +++ b/docs-translations/ko-KR/api/web-contents.md @@ -0,0 +1,680 @@ +# webContents + +`webContents`는 [EventEmitter](http://nodejs.org/api/events.html#events_class_events_eventemitter)를 +상속받았습니다. 웹 페이지의 렌더링과 관리를 책임지며 +[`BrowserWindow`](browser-window.md)의 속성입니다. 다음은 `webContents` 객체에 +접근하는 예제입니다: + +```javascript +const BrowserWindow = require('electron').BrowserWindow; + +var win = new BrowserWindow({width: 800, height: 1500}); +win.loadURL("http://github.com"); + +var webContents = win.webContents; +``` + +## Events + +`webContents` 객체는 다음과 같은 이벤트들을 발생시킵니다: + +### Event: 'did-finish-load' + +탐색 작업이 끝났을 때 발생하는 이벤트입니다. 브라우저의 탭의 스피너가 멈추고 `onload` +이벤트가 발생했을 때를 말합니다. + +### Event: 'did-fail-load' + +Returns: + +* `event` Event +* `errorCode` Integer +* `errorDescription` String +* `validatedURL` String + +이 이벤트는 `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' + +Returns: + +* `event` Event +* `isMainFrame` Boolean + +프레임(Frame)이 탐색을 끝냈을 때 발생하는 이벤트입니다. + +### Event: 'did-start-loading' + +브라우저 탭의 스피너가 회전을 시작한 때와 같은 시점에 대응하는 이벤트입니다. + +### Event: 'did-stop-loading' + +브라우저 탭의 스피너가 회전을 멈추었을 때와 같은 시점에 대응하는 이벤트입니다. + +### Event: 'did-get-response-details' + +Returns: + +* `event` Event +* `status` Boolean +* `newURL` String +* `originalURL` String +* `httpResponseCode` Integer +* `requestMethod` String +* `referrer` String +* `headers` Object + +요청한 리소스에 관련된 자세한 정보를 사용할 수 있을 때 발생하는 이벤트입니다. +`status`는 리소스를 다운로드하기 위한 소켓 연결을 나타냅니다. + +### Event: 'did-get-redirect-request' + +Returns: + +* `event` Event +* `oldURL` String +* `newURL` String +* `isMainFrame` Boolean +* `httpResponseCode` Integer +* `requestMethod` String +* `referrer` String +* `headers` Object + +리소스를 요청하는 동안에 리다이렉트 응답을 받았을 때 발생하는 이벤트입니다. + +### Event: 'dom-ready' + +Returns: + +* `event` Event + +주어진 프레임의 문서가 로드되었을 때 발생하는 이벤트입니다. + +### Event: 'page-favicon-updated' + +Returns: + +* `event` Event +* `favicons` Array - URL 배열 + +페이지가 favicon(파비콘) URL을 받았을 때 발생하는 이벤트입니다. + +### Event: 'new-window' + +Returns: + +* `event` Event +* `url` String +* `frameName` String +* `disposition` String - `default`, `foreground-tab`, `background-tab`, + `new-window`, `other`중 하나일 수 있습니다. +* `options` Object - 새로운 `BrowserWindow` 객체를 만들 때 사용되는 옵션 객체입니다. + +페이지가 `url`에 대하여 새로운 윈도우를 열기위해 요청한 경우 발생하는 이벤트입니다. +`window.open`이나 ``과 같은 외부 링크에 의해 요청될 수 있습니다. + +기본값으로 `BrowserWindow`는 `url`을 기반으로 생성됩니다. + +`event.preventDefault()`를 호출하면 새로운 창이 생성되는 것을 방지할 수 있습니다. + +### Event: 'will-navigate' + +Returns: + +* `event` Event +* `url` String + +사용자 또는 페이지가 새로운 페이지로 이동할 때 발생하는 이벤트입니다. +`window.location` 객체가 변경되거나 사용자가 페이지의 링크를 클릭했을 때 발생합니다. + +이 이벤트는 `webContents.loadURL`과 `webContents.back` 같은 API를 이용하여 +프로그램적으로 시작된 탐색에 대해서는 발생하지 않습니다. + +`event.preventDefault()`를 호출하면 탐색을 방지할 수 있습니다. + +### Event: 'crashed' + +렌더러 프로세스가 예기치 못하게 종료되었을 때 발생되는 이벤트입니다. + +### Event: 'plugin-crashed' + +Returns: + +* `event` Event +* `name` String +* `version` String + +플러그인 프로세스가 예기치 못하게 종료되었을 때 발생되는 이벤트입니다. + +### Event: 'destroyed' + +`webContents`가 소멸될 때 발생되는 이벤트입니다. + +### Event: 'devtools-opened' + +개발자 도구가 열렸을 때 발생되는 이벤트입니다. + +### Event: 'devtools-closed' + +개발자 도구가 닫혔을 때 발생되는 이벤트입니다. + +### Event: 'devtools-focused' + +개발자 도구에 포커스가 가거나 개발자 도구가 열렸을 때 발생되는 이벤트입니다. + +### 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 + +`webContents`가 기본 인증을 수행하길 원할 때 발생되는 이벤트입니다. + +[`app`의 `login`이벤트](app.md#event-login)와 사용 방법은 같습니다. + +## Instance Methods + +`webContents`객체는 다음과 같은 인스턴스 메서드들을 가지고 있습니다. + +### `webContents.session` + +webContents에서 사용되는 `session`객체를 반환합니다. + +[session 문서](session.md)에서 이 객체의 메서드들을 확인할 수 있습니다. + +### `webContents.loadURL(url[, options])` + +* `url` URL +* `options` Object (optional), 속성들: + * `httpReferrer` String - HTTP Referrer url. + * `userAgent` String - 요청을 시작한 유저 에이전트. + * `extraHeaders` String - "\n"로 구분된 Extra 헤더들. + +윈도우에 웹 페이지 `url`을 로드합니다. `url`은 `http://` or `file://`과 같은 +프로토콜 접두사를 가지고 있어야 합니다. 만약 반드시 http 캐시를 사용하지 않고 로드해야 +하는 경우 `pragma` 헤더를 사용할 수 있습니다. + +```javascript +const options = {"extraHeaders" : "pragma: no-cache\n"} +webContents.loadURL(url, options) +``` + +### `webContents.getURL()` + +현재 웹 페이지의 URL을 반환합니다. + +```javascript +var win = new BrowserWindow({width: 800, height: 600}); +win.loadURL("http://github.com"); + +var currentURL = win.webContents.getURL(); +``` + +### `webContents.getTitle()` + +현재 웹 페이지의 제목을 반환합니다. + +### `webContents.isLoading()` + +현재 웹 페이지가 리소스를 로드중인지 여부를 반환합니다. + +### `webContents.isWaitingForResponse()` + +현재 웹 페이지가 페이지의 메인 리소스로부터 첫 응답을 기다리고있는지 여부를 반환합니다. + +### `webContents.stop()` + +대기중인 탐색 작업을 모두 멈춥니다. + +### `webContents.reload()` + +현재 웹 페이지를 새로고침합니다. + +### `webContents.reloadIgnoringCache()` + +현재 웹 페이지의 캐시를 무시한 채로 새로고침합니다. + +### `webContents.canGoBack()` + +브라우저가 이전 웹 페이지로 돌아갈 수 있는지 여부를 반환합니다. + +### `webContents.canGoForward()` + +브라우저가 다음 웹 페이지로 이동할 수 있는지 여부를 반환합니다. + +### `webContents.canGoToOffset(offset)` + +* `offset` Integer + +웹 페이지가 `offset`로 이동할 수 있는지 여부를 반환합니다. + +### `webContents.clearHistory()` + +탐색 기록을 삭제합니다. + +### `webContents.goBack()` + +브라우저가 이전 웹 페이지로 이동하게 합니다. + +### `webContents.goForward()` + +브라우저가 다음 웹 페이지로 이동하게 합니다. + +### `webContents.goToIndex(index)` + +* `index` Integer + +브라우저가 지정된 절대 웹 페이지 인덱스로 탐색하게 합니다. + +### `webContents.goToOffset(offset)` + +* `offset` Integer + +"current entry"에서 지정된 offset으로 탐색합니다. + +### `webContents.isCrashed()` + +렌더러 프로세스가 예기치 않게 종료되었는지 여부를 반환합니다. + +### `webContents.setUserAgent(userAgent)` + +* `userAgent` String + +현재 웹 페이지의 유저 에이전트를 덮어씌웁니다. + +### `webContents.getUserAgent()` + +현재 웹 페이지의 유저 에이전트 문자열을 반환합니다. + +### `webContents.insertCSS(css)` + +* `css` String + +CSS 코드를 현재 웹 페이지에 삽입합니다. + +### `webContents.executeJavaScript(code[, userGesture])` + +* `code` String +* `userGesture` Boolean (optional) + +페이지에서 자바스크립트 코드를 실행합니다. + +기본적으로 `requestFullScreen`와 같은 몇몇 HTML API들은 사용자의 조작에 의해서만 +호출될 수 있습니다. `userGesture`를 `true`로 설정하면 이러한 제약을 무시할 수 +있습니다. + +### `webContents.setAudioMuted(muted)` + ++ `muted` Boolean + +현재 웹 페이지의 소리를 음소거합니다. + +### `webContents.isAudioMuted()` + +현재 페이지가 음소거 되어있는지 여부를 반환합니다. + +### `webContents.undo()` + +웹 페이지에서 `undo` 편집 커맨드를 실행합니다. + +### `webContents.redo()` + +웹 페이지에서 `redo` 편집 커맨드를 실행합니다. + +### `webContents.cut()` + +웹 페이지에서 `cut` 편집 커맨드를 실행합니다. + +### `webContents.copy()` + +웹 페이지에서 `copy` 편집 커맨드를 실행합니다. + +### `webContents.paste()` + +웹 페이지에서 `paste` 편집 커맨드를 실행합니다. + +### `webContents.pasteAndMatchStyle()` + +웹 페이지에서 `pasteAndMatchStyle` 편집 커맨드를 실행합니다. + +### `webContents.delete()` + +웹 페이지에서 `delete` 편집 커맨드를 실행합니다. + +### `webContents.selectAll()` + +웹 페이지에서 `selectAll` 편집 커맨드를 실행합니다. + +### `webContents.unselect()` + +웹 페이지에서 `unselect` 편집 커맨드를 실행합니다. + +### `webContents.replace(text)` + +* `text` String + +웹 페이지에서 `replace` 편집 커맨드를 실행합니다. + +### `webContents.replaceMisspelling(text)` + +* `text` String + +웹 페이지에서 `replaceMisspelling` 편집 커맨드를 실행합니다. + +### `webContents.hasServiceWorker(callback)` + +* `callback` Function + +ServiceWorker가 등록되어있는지 확인하고 `callback`에 대한 응답으로 boolean 값을 +반환합니다. + +### `webContents.unregisterServiceWorker(callback)` + +* `callback` Function + +ServiceWorker가 존재하면 모두 등록을 해제하고 JS Promise가 만족될 때 `callback`에 +대한 응답으로 boolean을 반환하거나 JS Promise가 만족되지 않을 때 `false`를 반환합니다. + +### `webContents.print([options])` + +`options` Object (optional), properties: + +* `silent` Boolean - 사용자에게 프린트 설정을 묻지 않습니다. 기본값을 `false`입니다. +* `printBackground` Boolean - 웹 페이지의 배경 색과 이미지를 출력합니다. 기본값은 + `false`입니다. + +윈도우의 웹 페이지를 프린트합니다. `silent`가 `false`로 지정되어있을 땐, Electron이 +시스템의 기본 프린터와 기본 프린터 설정을 가져옵니다. + +웹 페이지에서 `window.print()`를 호출하는 것은 +`webContents.print({silent: false, printBackground: false})`를 호출하는 것과 +같습니다. + +**참고:** Windows에서의 프린터 API는 `pdf.dll`에 의존합니다. 따라서 어플리케이션이 +print기능을 사용하지 않는 경우 전체 바이너리 크기를 줄이기 위해 `pdf.dll`을 삭제해도 +됩니다. + +### `webContents.printToPDF(options, callback)` + +`options` Object, properties: + +* `marginsType` Integer - 사용할 마진의 종류를 지정합니다. + * 0 - default + * 1 - none + * 2 - minimum +* `pageSize` String - 생성되는 PDF의 페이지 크기를 지정합니다. + * `A4` + * `A3` + * `Legal` + * `Letter` + * `Tabloid` +* `printBackground` Boolean - CSS 배경을 프린트할지 여부를 정합니다. +* `printSelectionOnly` Boolean - 선택된 영역만 프린트할지 여부를 정합니다. +* `landscape` Boolean - landscape을 위해선 `true`를, portrait를 위해선 `false`를 + 사용합니다. + +`callback` Function - `function(error, data) {}` + +* `error` Error +* `data` Buffer - PDF 파일 내용. + +Chromium의 미리보기 프린팅 커스텀 설정을 이용하여 윈도우의 웹 페이지를 PDF로 +프린트합니다. + +기본으로 비어있는 `options`은 다음과 같이 여겨지게 됩니다: + +```javascript +{ + marginsType: 0, + printBackground: false, + printSelectionOnly: false, + landscape: false +} +``` + +```javascript +const BrowserWindow = require('electron').BrowserWindow; +const fs = require('fs'); + +var win = new BrowserWindow({width: 800, height: 600}); +win.loadURL("http://github.com"); + +win.webContents.on("did-finish-load", function() { + // Use default printing options + win.webContents.printToPDF({}, function(error, data) { + if (error) throw error; + fs.writeFile("/tmp/print.pdf", data, function(error) { + if (error) + throw error; + console.log("Write PDF successfully."); + }) + }) +}); +``` + +### `webContents.addWorkSpace(path)` + +* `path` String + +특정 경로를 개발자 도구의 워크스페이스에 추가합니다. + +### `webContents.removeWorkSpace(path)` + +* `path` String + +특정 경로를 개발자 도구의 워크스페이스에서 제거합니다. + +### `webContents.openDevTools([options])` + +* `options` Object (optional). Properties: + * `detach` Boolean - 새 창에서 개발자 도구를 엽니다. + +개발자 도구를 엽니다. + +### `webContents.closeDevTools()` + +개발자 도구를 닫습니다. + +### `webContents.isDevToolsOpened()` + +개발자 도구가 열려있는지 여부를 반환합니다. + +### `webContents.toggleDevTools()` + +개발자 도구를 토글합니다. + +### `webContents.isDevToolsFocused()` + +개발자 도구에 포커스가 가있는지 여부를 반화합니다. + +### `webContents.inspectElement(x, y)` + +* `x` Integer +* `y` Integer + +(`x`, `y`)위치의 엘레먼트를 조사합니다. + +### `webContents.inspectServiceWorker()` + +서비스 워커 컨텍스트(service worker context)를 위한 개발자 도구를 엽니다. + +### `webContents.send(channel[, arg1][, arg2][, ...])` + +* `channel` String +* `arg` (optional) + +`channel`을 통하여 렌더러 프로세스에 비동기 메시지를 보냅니다. 임의의 인수를 보낼수도 +있습니다. 렌더러 프로세스는 `ipcRenderer` 모듈을 통하여 `channel`를 리슨하여 메시지를 +처리할 수 있습니다. + +메인 프로세스에서 렌더러 프로세스로 메시지를 보내는 예시 입니다: + +```javascript +// In the main process. +var window = null; +app.on('ready', function() { + window = new BrowserWindow({width: 800, height: 600}); + window.loadURL('file://' + __dirname + '/index.html'); + window.webContents.on('did-finish-load', function() { + window.webContents.send('ping', 'whoooooooh!'); + }); +}); +``` + +```html + + + + + + +``` + +### `webContents.enableDeviceEmulation(parameters)` + +`parameters` Object, properties: + +* `screenPosition` String - 에뮬레이트 할 화면 종료를 지정합니다 + (기본값: `desktop`) + * `desktop` + * `mobile` +* `screenSize` Object - 에뮬레이트 화면의 크기를 지정합니다 (screenPosition == + mobile) + * `width` Integer - 에뮬레이트 화면의 너비를 지정합니다 + * `height` Integer - 에뮬레이트 화면의 높이를 지정합니다 +* `viewPosition` Object - 화면에서 뷰의 위치 (screenPosition == mobile) (기본값: + `{x: 0, y: 0}`) + * `x` Integer - 좌상단 모서리로부터의 x 축의 오프셋 + * `y` Integer - 좌상단 모서리로부터의 y 축의 오프셋 +* `deviceScaleFactor` Integer - 디바이스의 스케일 팩터(scale factor)를 지정합니다. + (0일 경우 기본 디바이스 스케일 팩터를 기본으로 사용합니다. 기본값: `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`) + +`parameters`로 디바이스 에뮬레이션을 사용합니다. + +### `webContents.disableDeviceEmulation()` + +`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`, + `leftButtonDown`, `middleButtonDown`, `rightButtonDown`, `capsLock`, + `numLock`, `left`, `right`. + +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` + +마우스 이벤트들에 대해서는 `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` 객체입니다. 많은 장치에서 +32비트 BGRA 포맷을 사용하여 효율적으로 픽셀 데이터를 저장합니다. 하지만 실질적인 +데이터 저장 방식은 프로세서의 엔디안 방식에 따라서 달라집니다. (따라서 현대의 많은 +프로세서에선 little-endian 방식을 사용하므로 위의 포맷을 그대로 표현합니다. 하지만 +몇몇 프로세서는 big-endian 방식을 사용하는데, 이 경우 32비트 ARGB 포맷을 사용합니다) + +### `webContents.endFrameSubscription()` + +프레임 프레젠테이션 이벤트들에 대한 구독을 중지합니다. + +## Instance Properties + +`WebContents`객체들은 다음 속성들을 가지고 있습니다: + +### `webContents.devToolsWebContents` + +이 `WebContents`에 대한 개발자 도구의 `WebContents`를 가져옵니다. + +**참고:** 사용자가 절대로 이 객체를 저장해서는 안 됩니다. 개발자 도구가 닫혔을 때, +`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"); + }); +}); +``` diff --git a/docs-translations/ko-KR/api/web-frame.md b/docs-translations/ko-KR/api/web-frame.md index d09114e559c8..2e4a469b5485 100644 --- a/docs-translations/ko-KR/api/web-frame.md +++ b/docs-translations/ko-KR/api/web-frame.md @@ -1,11 +1,12 @@ # webFrame -`web-frame` 모듈은 현재 웹 페이지의 랜더링 상태를 설정 할 수 있도록 관련 유틸리티를 제공하는 모듈입니다. +`web-frame` 모듈은 현재 웹 페이지의 랜더링 상태를 설정 할 수 있도록 관련 유틸리티를 +제공하는 모듈입니다. 다음 예제는 현재 페이지를 200% 줌 합니다: ```javascript -var webFrame = require('web-frame'); +var webFrame = require('electron').webFrame; webFrame.setZoomFactor(2); ``` @@ -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,30 +53,38 @@ webFrame.setZoomFactor(2); Input field나 text area에 철자 검사(spell checking) 제공자를 설정합니다. -`provider`는 반드시 전달된 단어의 철자가 맞았는지 검사하는 `spellCheck` 메소드를 가지고 있어야 합니다. +`provider`는 반드시 전달된 단어의 철자가 맞았는지 검사하는 `spellCheck` 메소드를 +가지고 있어야 합니다. [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 지정한 `scheme`을 보안 스킴으로 등록합니다. -보안 스킴은 혼합된 컨텐츠 경고를 발생시키지 않습니다. 예를 들어 `https` 와 `data`는 네트워크 공격자로부터 손상될 가능성이 없기 때문에 보안 스킴이라고 할 수 있습니다. +보안 스킴은 혼합된 컨텐츠 경고를 발생시키지 않습니다. 예를 들어 `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 69b94465aede..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 - + alertOnlineStatus(); + + ``` -메인 프로세스에서 이 이벤트를 처리할 필요가 있는 경우 이벤트를 메인 프로세스로 보낼 수 있습니다. -메인 프로세스는 `navigator` 객체를 가지고 있지 않기 때문에 이 이벤트를 직접 사용할 수 없습니다. +메인 프로세스에서 이 이벤트를 처리할 필요가 있는 경우 이벤트를 메인 프로세스로 보낼 수 +있습니다. 메인 프로세스는 `navigator` 객체를 가지고 있지 않기 때문에 이 이벤트를 직접 +사용할 수는 없습니다. -대신 다음 예제와 같이 Electron의 inter-process communication(ipc) 유틸리티를 사용하면 이벤트를 메인 프로세스로 전달할 수 있습니다. +대신 다음 예제와 같이 Electron의 inter-process communication(ipc) 유틸리티를 +사용하면 이벤트를 메인 프로세스로 전달할 수 있습니다. _main.js_ ```javascript -var app = require('app'); -var ipc = require('ipc'); -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'); }); -ipc.on('online-status-changed', function(event, status) { +ipcMain.on('online-status-changed', function(event, status) { console.log(status); }); ``` @@ -63,18 +68,18 @@ _online-status.html_ ```html - - - + updateOnlineStatus(); + + ``` diff --git a/docs-translations/ko-KR/tutorial/quick-start.md b/docs-translations/ko-KR/tutorial/quick-start.md index 5c2cc80f4060..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,16 +67,19 @@ your-app/ } ``` -__알림__: 만약 `main` 필드가 `package.json`에 설정되어 있지 않으면 Electron은 자동으로 같은 디렉터리의 `index.js`를 로드합니다. +__알림__: 만약 `main` 필드가 `package.json`에 설정되어 있지 않으면 Electron은 +자동으로 같은 디렉터리의 `index.js`를 로드합니다. -반드시 `main.js`에서 창을 만들고 시스템 이밴트를 처리해야합니다. 대표적인 예제로 다음과 같이 작성할 수 있습니다: +반드시 `main.js`에서 창을 만들고 시스템 이밴트를 처리해야합니다. 대표적인 예제로 +다음과 같이 작성할 수 있습니다: ```javascript -var app = require('app'); // 어플리케이션 기반을 조작 하는 모듈. -var BrowserWindow = require('browser-window'); // 네이티브 브라우저 창을 만드는 모듈. +const electron = require('electron'); +const app = electron.app; // 어플리케이션 기반을 조작 하는 모듈. +const BrowserWindow = electron.BrowserWindow; // 네이티브 브라우저 창을 만드는 모듈. // Electron 개발자에게 crash-report를 보냄. -require('crash-reporter').start(); +electron.crashReporter.start(); // 윈도우 객체를 전역에 유지합니다. 만약 이렇게 하지 않으면 // 자바스크립트 GC가 일어날 때 창이 멋대로 닫혀버립니다. @@ -90,9 +101,9 @@ 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(); // 창이 닫히면 호출됩니다. @@ -125,12 +136,14 @@ app.on('ready', function() { ## 앱 실행하기 -앱을 작성한 후 [어플리케이션 배포](application-distribution.md) 가이드를 따라 앱을 패키징 하고 패키징한 앱을 실행할 수 있습니다. -또한 Electron 실행파일을 다운로드 받아 바로 실행해 볼 수도 있습니다. +앱을 작성한 후 [어플리케이션 배포](application-distribution.md) 가이드를 따라 앱을 +패키징 하고 패키징한 앱을 실행할 수 있습니다. 또한 Electron 실행파일을 다운로드 받아 +바로 실행해 볼 수도 있습니다. ### electron-prebuilt 사용 -`npm`을 통해 `electron-prebuilt` 패키지를 전역에 설치하면 간단한 명령으로 앱을 실행할 수 있습니다. +`npm`을 통해 `electron-prebuilt` 패키지를 전역에 설치하면 간단한 명령으로 앱을 +실행할 수 있습니다. 앱 디렉터리 내에서 다음 명령으로 실행할 수 있습니다: @@ -177,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를 설치하면 자동으로 같이 설치됩니다. @@ -194,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 0691fefc864d..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,15 +25,20 @@ 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 # 필요한 네이티브 모듈을 `npm install`로 설치한 후 다음 명령을 실행하세요: ./node_modules/.bin/electron-rebuild + +# Windows에서 문제가 발생하면 다음 명령을 대신 실행하세요: +.\node_modules\.bin\electron-rebuild.cmd ``` ### `npm`을 이용한 방법 @@ -46,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 f47f20d8a71e..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,33 +5,20 @@ 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 -var app = require('app'); -var BrowserWindow = require('browser-window'); - -// Report crashes to our server. -require('crash-reporter').start(); - -var mainWindow = null; - -// Quit when all windows are closed. -app.on('window-all-closed', function() { - if (process.platform != 'darwin') { - app.quit(); - } -}); - // 플래시 플러그인의 위치를 설정합니다. // Windows의 경우, /path/to/pepflashplayer.dll -// Mac의 경우, /path/to/PepperFlashPlayer.plugin +// OS X의 경우, /path/to/PepperFlashPlayer.plugin // Linux의 경우, /path/to/libpepflashplayer.so app.commandLine.appendSwitch('ppapi-flash-path', '/path/to/libpepflashplayer.so'); @@ -46,7 +33,7 @@ app.on('ready', function() { 'plugins': true } }); - mainWindow.loadUrl('file://' + __dirname + '/index.html'); + mainWindow.loadURL('file://' + __dirname + '/index.html'); // Something else }); ``` 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..d0684e0cfe10 100644 --- a/docs-translations/ko-KR/tutorial/using-selenium-and-webdriver.md +++ b/docs-translations/ko-KR/tutorial/using-selenium-and-webdriver.md @@ -1,19 +1,19 @@ # Selenium 과 WebDriver 사용하기 -[ChromeDriver - WebDriver for Chrome][chrome-driver]로 부터 인용: +[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,18 +35,22 @@ $ npm install selenium-webdriver ### 3. 크롬 드라이버에 연결 -`selenium-webdriver`를 Electron과 같이 사용하는 방법은 기본적으로 upstream과 같습니다. -한가지 다른점이 있다면 수동으로 크롬 드라이버 연결에 대해 설정하고 Electron 실행파일의 위치를 전달합니다: +`selenium-webdriver`를 Electron과 같이 사용하는 방법은 기본적으로 upstream과 +같습니다. 한가지 다른점이 있다면 수동으로 크롬 드라이버 연결에 대해 설정하고 Electron +실행파일의 위치를 전달합니다: ```javascript -var webdriver = require('selenium-webdriver'); +const 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(); @@ -64,7 +68,8 @@ driver.quit(); ## WebdriverIO 설정하기 -[WebdriverIO](http://webdriver.io/)는 웹 드라이버와 함께 테스트를 위해 제공되는 node 패키지입니다. +[WebdriverIO](http://webdriver.io/)는 웹 드라이버와 함께 테스트를 위해 제공되는 +node 패키지입니다. ### 1. 크롬 드라이버 시작 @@ -86,18 +91,21 @@ $ npm install webdriverio ### 3. 크롬 드라이버에 연결 ```javascript -var webdriverio = require('webdriverio'); +const webdriverio = require('webdriverio'); var options = { host: "localhost", // localhost에서 작동중인 크롬 드라이버 서버를 사용합니다. 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/ + } } }; var client = webdriverio.remote(options); - + client .init() .url('http://google.com') @@ -109,9 +117,13 @@ client .end(); ``` -## 작업환경 +## 작업 환경 -따로 Electron을 다시 빌드하지 않는 경우 간단히 어플리케이션을 Electron의 리소스 디렉터리에 -[배치](application-distribution.md)하여 바로 테스트 할 수 있습니다. +따로 Electron을 다시 빌드하지 않는 경우 간단히 어플리케이션을 Electron의 리소스 +디렉터리에 [배치](application-distribution.md)하여 바로 테스트 할 수 있습니다. + +또한, Electron 바이너리의 명령줄 인수에 어플리케이션 폴더를 지정하는 방법으로 실행할 +수도 있습니다. 이 방법을 사용하면 어플리케이션 폴더를 Electron의 `resource` +디렉터리로 복사하는 불필요한 과정을 생략할 수 있습니다. [chrome-driver]: https://sites.google.com/a/chromium.org/chromedriver/ 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. 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/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-translations/zh-CN/README.md b/docs-translations/zh-CN/README.md index 6085cbfb2c65..5c4303a0a6f8 100644 --- a/docs-translations/zh-CN/README.md +++ b/docs-translations/zh-CN/README.md @@ -62,7 +62,7 @@ ## 开发 * [编码规范](development/coding-style.md) -* [源码文件结构](development/source-code-directory-structure.md) +* [源码目录结构](development/source-code-directory-structure.md) * [与 NW.js (原名 node-webkit) 在技术上的差异](development/atom-shell-vs-node-webkit.md) * [构建系统概况](development/build-system-overview.md) * [构建步骤 (Mac)](development/build-instructions-mac.md) diff --git a/docs-translations/zh-CN/development/atom-shell-vs-node-webkit.md b/docs-translations/zh-CN/development/atom-shell-vs-node-webkit.md index cf6859d50645..9774580eeb7b 100644 --- a/docs-translations/zh-CN/development/atom-shell-vs-node-webkit.md +++ b/docs-translations/zh-CN/development/atom-shell-vs-node-webkit.md @@ -20,10 +20,12 @@ __2. 构建系统__ __3. Node 集成__ -在 NW.js,网页中的 Node 集成需要通过给 Chromium 打补丁来实现。但在 Electron 中,我们选择了另一种方式:通过各个平台的消息循环与 libuv 的循环集成,避免了直接在 Chromium 上做改动。你可以看 [`node_bindings`](../../atom/common/) 来了解这是如何完成的。 +在 NW.js,网页中的 Node 集成需要通过给 Chromium 打补丁来实现。但在 Electron 中,我们选择了另一种方式:通过各个平台的消息循环与 libuv 的循环集成,避免了直接在 Chromium 上做改动。你可以看 [`node_bindings`][node-bindings] 来了解这是如何完成的。 __4. 多上下文__ 如果你是有经验的 NW.js 用户,你应该会熟悉 Node 上下文和 web 上下文的概念。这些概念的产生源于 NW.js 的实现方式。 通过使用 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/zh-CN/development/source-code-directory-structure.md b/docs-translations/zh-CN/development/source-code-directory-structure.md new file mode 100644 index 000000000000..fd3676c2e988 --- /dev/null +++ b/docs-translations/zh-CN/development/source-code-directory-structure.md @@ -0,0 +1,53 @@ +# 源码目录结构 + +Electron 的源代码主要依据 Chromium 的拆分约定被拆成了许多部分。 + +为了更好地理解源代码,您可能需要了解一下 +[Chromium 的多进程架构](http://dev.chromium.org/developers/design-documents/multi-process-architecture)。 + +## 源代码的结构 + +``` +Electron +├──atom - Electron 的源代码 +| ├── app - 系统入口代码 +| ├── browser - 包含了主窗口、UI 和其他所有与主进程有关的东西,它会告诉渲染进程如何管理页面 +| |   ├── lib - 主进程初始化代码中 JavaScript 部分的代码 +| | ├── ui - 不同平台上 UI 部分的实现 +| | | ├── cocoa - Cocoa 部分的源代码 +| | | ├── gtk - GTK+ 部分的源代码 +| | | └── win - Windows GUI 部分的源代码 +| | ├── default_app - 在没有指定 app 的情况下 Electron 启动时默认显示的页面 +| | ├── api - 主进程 API 的实现 +| | | └── lib - API 实现中 Javascript 部分的代码 +| | ├── net - 网络相关的代码 +| | ├── mac - 与 Mac 有关的 Objective-C 代码 +| | └── resources - 图标,平台相关的文件等 +| ├── renderer - 运行在渲染进程中的代码 +| | ├── lib - 渲染进程初始化代码中 JavaScript 部分的代码 +| | └── api - 渲染进程 API 的实现 +| | └── lib - API 实现中 Javascript 部分的代码 +| └── common - 同时被主进程和渲染进程用到的代码,包括了一些用来将 node 的事件循环 +| | 整合到 Chromium 的事件循环中时用到的工具函数和代码 +| ├── lib - 同时被主进程和渲染进程使用到的 Javascript 初始化代码 +| └── api - 同时被主进程和渲染进程使用到的 API 的实现以及 Electron 内置模块的基础设施 +| └── lib - API 实现中 Javascript 部分的代码 +├── chromium_src - 从 Chromium 项目中拷贝来的代码 +├── docs - 英语版本的文档 +├── docs-translations - 各种语言版本的文档翻译 +├── spec - 自动化测试 +├── atom.gyp - Electron 的构建规则 +└── common.gypi - 为诸如 `node` 和 `breakpad` 等其他组件准备的编译设置和构建规则 +``` + +## 其他目录的结构 + +* **script** - 用于诸如构建、打包、测试等开发用途的脚本 +* **tools** - 在 gyp 文件中用到的工具脚本,但与 `script` 目录不同, + 该目录中的脚本不应该被用户直接调用 +* **vendor** - 第三方依赖项的源代码,为了防止人们将它与 Chromium 源码中的同名目录相混淆, + 在这里我们不使用 `third_party` 作为目录名 +* **node_modules** - 在构建中用到的第三方 node 模块 +* **out** - `ninja` 的临时输出目录 +* **dist** - 由脚本 `script/create-dist.py` 创建的临时发布目录 +* **external_binaries** - 下载的不支持通过 `gyp` 构建的预编译第三方框架 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 +``` diff --git a/docs/README.md b/docs/README.md index 754048f5e3f3..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 process)](api/ipc-main-process.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 bb1509b68688..a1d87d2fe993 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(); }); @@ -131,32 +131,92 @@ Returns: Emitted when a new [browserWindow](browser-window.md) is created. -### Event: 'select-certificate' - -Emitted when a client certificate is requested. +### Event: 'certificate-error' Returns: * `event` Event -* `webContents` [WebContents](browser-window.md#class-webcontents) -* `url` String -* `certificateList` [Objects] - * `data` PEM encoded data - * `issuerName` Issuer's Common Name +* `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 -app.on('select-certificate', function(event, host, url, list, callback) { - event.preventDefault(); - callback(list[0]); -}) +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: + +* `event` Event +* `webContents` [WebContents](web-contents.md) +* `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 `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-client-certificate', function(event, webContents, url, list, callback) { + event.preventDefault(); + callback(list[0]); +}) +``` + +### 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' Emitted when the gpu process crashes. @@ -177,6 +237,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. @@ -198,9 +267,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. +* `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)` @@ -237,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 @@ -344,6 +410,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. @@ -404,3 +476,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 diff --git a/docs/api/auto-updater.md b/docs/api/auto-updater.md index 7649f0f10489..fa4f92cb936d 100644 --- a/docs/api/auto-updater.md +++ b/docs/api/auto-updater.md @@ -4,27 +4,34 @@ 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 -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 user's machine before you can use -the auto-updater, 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 server-side setup is also different from OS X, you can read the documents of +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. ### 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 @@ -60,7 +67,7 @@ Returns: * `releaseNotes` String * `releaseName` String * `releaseDate` Date -* `updateUrl` String +* `updateURL` String Emitted when an update has been downloaded. @@ -70,7 +77,7 @@ On Windows only `releaseName` is available. The `autoUpdater` object has the following methods: -### `autoUpdater.setFeedUrl(url)` +### `autoUpdater.setFeedURL(url)` * `url` String @@ -79,15 +86,16 @@ 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.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. +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 diff --git a/docs/api/browser-window.md b/docs/api/browser-window.md index d7bf5be374d4..52b1bb8d5c5e 100644 --- a/docs/api/browser-window.md +++ b/docs/api/browser-window.md @@ -4,14 +4,14 @@ 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() { win = null; }); -win.loadUrl('https://github.com'); +win.loadURL('https://github.com'); win.show(); ``` @@ -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,29 @@ 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 - textured window. Defaults to `true`. -* `title-bar-style` String, OS X - specifies the style of window title bar. +* `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 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: * `default` or not specified results in the standard gray opaque Mac title @@ -81,44 +86,48 @@ 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 - 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:` 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. @@ -232,7 +241,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 @@ -291,11 +300,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 +322,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 @@ -552,7 +550,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 @@ -560,19 +558,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. @@ -594,7 +592,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. @@ -624,9 +622,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/chrome-command-line-switches.md b/docs/api/chrome-command-line-switches.md index 69e785f79e72..c1adf3c425f8 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'); @@ -31,10 +31,21 @@ 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 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` 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..aae5306523ae 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('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/api/crash-reporter.md b/docs/api/crash-reporter.md index 64a3b2cf748d..6c66a855f753 100644 --- a/docs/api/crash-reporter.md +++ b/docs/api/crash-reporter.md @@ -6,12 +6,12 @@ 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', 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,12 +57,12 @@ 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'. * `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 0fadfa37f80c..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,4 +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. +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/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/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-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..cdbc0ce34eec --- /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. +const ipcMain = require('electron').ipcMain; +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). +const ipcRenderer = require('electron').ipcRenderer; +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..01f0bb3a83dd 100644 --- a/docs/api/ipc-renderer.md +++ b/docs/api/ipc-renderer.md @@ -1,52 +1,54 @@ -# 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 `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 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/menu.md b/docs/api/menu.md index cabd04ca8550..1d819682160b 100644 --- a/docs/api/menu.md +++ b/docs/api/menu.md @@ -16,9 +16,9 @@ the user right clicks the page: ```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 diff --git a/docs/api/tray.md b/docs/api/tray.md index 528705acb325..f230c324ec08 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(){ @@ -30,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 @@ -52,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 @@ -69,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 @@ -84,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 @@ -103,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. @@ -112,6 +113,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` @@ -119,6 +124,18 @@ closes it. Emitted when dragged files are dropped in the tray icon. +### Event: 'drag-enter' _OS X_ + +Emitted when a drag operation enters the tray icon. + +### Event: 'drag-leave' _OS X_ + +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: @@ -158,7 +175,8 @@ Sets the title displayed aside of the tray icon in the status bar. * `highlight` Boolean -Sets whether the tray icon is highlighted when it is clicked. +Sets whether the tray icon's background becomes highlighted (in blue) +when the tray icon is clicked. Defaults to true. ### `Tray.displayBalloon(options)` _Windows_ diff --git a/docs/api/web-contents.md b/docs/api/web-contents.md index 3113356e34b4..a716bdc593a7 100644 --- a/docs/api/web-contents.md +++ b/docs/api/web-contents.md @@ -8,10 +8,10 @@ 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"); +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. @@ -167,17 +167,65 @@ 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: + +* `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: -### `webContents.session` - -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: @@ -186,21 +234,25 @@ 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://`. - -### `webContents.getUrl()` +e.g. the `http://` or `file://`. If the load should bypass http cache then +use the `pragma` header to achieve it. ```javascript -var BrowserWindow = require('browser-window'); - -var win = new BrowserWindow({width: 800, height: 600}); -win.loadUrl("http://github.com"); - -var currentUrl = win.webContents.getUrl(); +const options = {"extraHeaders" : "pragma: no-cache\n"} +webContents.loadURL(url, options) ``` +### `webContents.getURL()` + 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(); +``` + ### `webContents.getTitle()` Returns the title of the current web page. @@ -424,11 +476,11 @@ 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"); +win.loadURL("http://github.com"); win.webContents.on("did-finish-load", function() { // Use default printing options @@ -489,13 +541,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: @@ -504,7 +557,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!'); }); @@ -516,7 +569,7 @@ app.on('ready', function() { @@ -524,13 +577,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: @@ -571,7 +617,7 @@ Disable device emulation enabled by `webContents.enableDeviceEmulation`. * `event` Object * `type` String (**required**) - The type of the event, can be `mouseDown`, `mouseUp`, `mouseEnter`, `mouseLeave`, `contextMenu`, `mouseWheel`, - `keyDown`, `keyUp`, `char`. + `mouseMove`, `keyDown`, `keyUp`, `char`. * `modifiers` Array - An array of modifiers of the event, can include `shift`, `control`, `alt`, `meta`, `isKeypad`, `isAutoRepeat`, `leftButtonDown`, `middleButtonDown`, `rightButtonDown`, `capsLock`, @@ -581,8 +627,11 @@ Sends an input `event` to the page. For keyboard events, the `event` object also have following properties: -* `keyCode` String (**required**) - A single character that will be sent as - keyboard event. Can be any UTF-8 character. +* `keyCode` Char or String (**required**) - The character that will be sent + as the keyboard event. Can be a single UTF-8 character, or the name of the + key that generates the event. Accepted key names are `enter`, `backspace`, + `delete`, `tab`, `escape`, `control`, `alt`, `shift`, `end`, `home`, `insert`, + `left`, `up`, `right`, `down`, `pageUp`, `pageDown`, `printScreen` For mouse events, the `event` object also have following properties: @@ -623,17 +672,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. @@ -647,7 +685,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) { @@ -656,3 +694,18 @@ win.webContents.on('did-finish-load', function() { }); }); ``` + +## Instance Properties + +`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`. + +**Note:** Users should never store this object because it may become `null` +when the DevTools has been closed. diff --git a/docs/api/web-frame.md b/docs/api/web-frame.md index 33597543b773..38c5e30db43f 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,14 +59,14 @@ 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)); } }); ``` -### `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 3fda3a98edb5..47a3050a0429 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. @@ -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. @@ -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 @@ -401,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. @@ -427,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 @@ -441,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. @@ -465,7 +466,7 @@ url. Returns: -* `favicons` Array - Array of Urls. +* `favicons` Array - Array of URLs. Fired when page receives favicon urls. @@ -514,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); }); ``` @@ -554,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/development/atom-shell-vs-node-webkit.md b/docs/development/atom-shell-vs-node-webkit.md index c1fffa304ab5..76fa5d57d289 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`][node-bindings] code for how that was done. __4. Multi-context__ @@ -46,3 +46,5 @@ of how NW.js was implemented. By using the [multi-context](http://strongloop.com/strongblog/whats-new-node-js-v0-12-multiple-context-execution/) feature of Node, Electron doesn't introduce a new JavaScript context in web pages. + +[node-bindings]: https://github.com/atom/electron/tree/master/atom/common diff --git a/docs/tutorial/application-packaging.md b/docs/tutorial/application-packaging.md index 0cf3a6b596f4..45973e49eaa9 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,9 +71,9 @@ 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'); +win.loadURL('file:///path/to/example.asar/static/index.html'); ``` ### Web API diff --git a/docs/tutorial/desktop-environment-integration.md b/docs/tutorial/desktop-environment-integration.md index 78067f3d8a12..6e570ee71f92 100644 --- a/docs/tutorial/desktop-environment-integration.md +++ b/docs/tutorial/desktop-environment-integration.md @@ -8,6 +8,67 @@ 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 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 myNotification = 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 [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. + +### Linux + +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. + +### 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 @@ -25,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'); ``` @@ -43,7 +103,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 @@ -63,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: [ @@ -110,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, @@ -154,12 +216,13 @@ __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 +const BrowserWindow = require('electron').BrowserWindow; +const path = require('path'); -``` -var BrowserWindow = require('browser-window'); -var path = require('path'); var win = new BrowserWindow({ width: 800, height: 600 @@ -188,8 +251,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:__ @@ -252,3 +315,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 +[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/ diff --git a/docs/tutorial/devtools-extension.md b/docs/tutorial/devtools-extension.md index 20ba7031d8ad..7c7ea7d64a24 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: @@ -22,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.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/mac-app-store-submission-guide.md b/docs/tutorial/mac-app-store-submission-guide.md index 113185918803..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. @@ -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. diff --git a/docs/tutorial/online-offline-events.md b/docs/tutorial/online-offline-events.md index 88f9a32f2ec6..d143118e0158 100644 --- a/docs/tutorial/online-offline-events.md +++ b/docs/tutorial/online-offline-events.md @@ -6,13 +6,14 @@ 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'); + onlineStatusWindow.loadURL('file://' + __dirname + '/online-status.html'); }); ``` @@ -21,18 +22,18 @@ _online-status.html_ ```html - - - + alertOnlineStatus(); + + ``` @@ -45,17 +46,18 @@ to the main process and handled as needed, as shown in the following example. _main.js_ ```javascript -var app = require('app'); -var ipc = require('ipc'); -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'); }); -ipc.on('online-status-changed', function(event, status) { +ipcMain.on('online-status-changed', function(event, status) { console.log(status); }); ``` @@ -65,18 +67,18 @@ _online-status.html_ ```html - - - + updateOnlineStatus(); + + ``` diff --git a/docs/tutorial/quick-start.md b/docs/tutorial/quick-start.md index b023deccda52..4c61413436dd 100644 --- a/docs/tutorial/quick-start.md +++ b/docs/tutorial/quick-start.md @@ -78,11 +78,12 @@ The `main.js` should create windows and handle system events, a typical example being: ```javascript -var app = require('app'); // Module to control application life. -var BrowserWindow = require('browser-window'); // Module to create native browser window. +const electron = require('electron'); +const app = electron.app; // Module to control application life. +const BrowserWindow = electron.BrowserWindow; // Module to create native browser window. // Report crashes to our server. -require('crash-reporter').start(); +electron.crashReporter.start(); // Keep a global reference of the window object, if you don't, the window will // be closed automatically when the JavaScript object is garbage collected. @@ -104,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-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 diff --git a/docs/tutorial/using-pepper-flash-plugin.md b/docs/tutorial/using-pepper-flash-plugin.md index 5c8820c2fad4..a9918b220ac0 100644 --- a/docs/tutorial/using-pepper-flash-plugin.md +++ b/docs/tutorial/using-pepper-flash-plugin.md @@ -19,26 +19,9 @@ before the app ready event. Also, add the `plugins` switch of `browser-window`. For example: ```javascript -var app = require('app'); -var BrowserWindow = require('browser-window'); - -// Report crashes to our server. -require('crash-reporter').start(); - -// Keep a global reference of the window object, if you don't, the window will -// be closed automatically when the javascript object is GCed. -var mainWindow = null; - -// Quit when all windows are closed. -app.on('window-all-closed', function() { - if (process.platform != 'darwin') { - app.quit(); - } -}); - // 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'); @@ -53,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/docs/tutorial/using-selenium-and-webdriver.md b/docs/tutorial/using-selenium-and-webdriver.md index b87f8f11dac9..035dabdfe79f 100644 --- a/docs/tutorial/using-selenium-and-webdriver.md +++ b/docs/tutorial/using-selenium-and-webdriver.md @@ -41,14 +41,17 @@ upstream, except that you have to manually specify how to connect chrome driver and where to find Electron's binary: ```javascript -var webdriver = require('selenium-webdriver'); +const 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(); @@ -90,13 +93,16 @@ $ npm install webdriverio ### 3. Connect to chrome driver ```javascript -var webdriverio = require('webdriverio'); +const webdriverio = require('webdriverio'); var options = { host: "localhost", // Use localhost as chrome driver server 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/ diff --git a/filenames.gypi b/filenames.gypi index e6d180d652e1..7157079178ee 100644 --- a/filenames.gypi +++ b/filenames.gypi @@ -9,22 +9,24 @@ ], '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-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', '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', 'atom/browser/api/lib/menu.coffee', 'atom/browser/api/lib/menu-item.coffee', 'atom/browser/api/lib/navigation-controller.coffee', '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', @@ -37,6 +39,8 @@ '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/exports/electron.coffee', 'atom/common/api/lib/native-image.coffee', 'atom/common/api/lib/shell.coffee', 'atom/common/lib/init.coffee', @@ -49,7 +53,9 @@ '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', 'atom/renderer/api/lib/screen.coffee', 'atom/renderer/api/lib/web-frame.coffee', @@ -136,8 +142,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', @@ -150,6 +154,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', @@ -166,6 +172,10 @@ '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_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', @@ -253,6 +263,8 @@ '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', @@ -302,13 +314,18 @@ '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/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', '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', @@ -405,6 +422,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', diff --git a/script/bootstrap.py b/script/bootstrap.py index d5ad41a61c59..ef48c1f8023f 100755 --- a/script/bootstrap.py +++ b/script/bootstrap.py @@ -39,7 +39,9 @@ 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 +71,14 @@ 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.') + parser.add_argument('--libcc_static_library_path', required=False, + help='The static library path of libchromiumcontent.') return parser.parse_args() @@ -91,15 +101,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 += ['--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/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/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', 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' 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': diff --git a/spec/api-app-spec.coffee b/spec/api-app-spec.coffee index 4b1a04e00827..490727488d99 100644 --- a/spec/api-app-spec.coffee +++ b/spec/api-app-spec.coffee @@ -1,7 +1,6 @@ assert = require 'assert' -remote = require 'remote' -app = remote.require 'app' -BrowserWindow = remote.require 'browser-window' +{remote} = require 'electron' +{app, BrowserWindow} = remote.require 'electron' describe 'app module', -> describe 'app.getVersion()', -> diff --git a/spec/api-browser-window-spec.coffee b/spec/api-browser-window-spec.coffee index 1218d27b7fd7..00437ae412ba 100644 --- a/spec/api-browser-window-spec.coffee +++ b/spec/api-browser-window-spec.coffee @@ -1,12 +1,12 @@ assert = require 'assert' fs = require 'fs' path = require 'path' -remote = require 'remote' http = require 'http' url = require 'url' os = require 'os' -BrowserWindow = remote.require 'browser-window' +{remote, screen} = require 'electron' +{ipcMain, BrowserWindow} = remote.require 'electron' isCI = remote.process.argv[2] == '--ci' @@ -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', -> @@ -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 @@ -191,7 +191,7 @@ describe 'browser-window module', -> assert.equal after[1], -10 it 'can set the window larger than screen', -> - size = require('screen').getPrimaryDisplay().size + size = screen.getPrimaryDisplay().size size.width += 100 size.height += 100 w.setSize size.width, size.height @@ -201,55 +201,55 @@ describe 'browser-window module', -> describe '"web-preferences" option', -> afterEach -> - remote.require('ipc').removeAllListeners('answer') + ipcMain.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) -> + ipcMain.once 'answer', (event, test) -> assert.equal(test, 'preload') done() w.destroy() w = new BrowserWindow show: false - 'web-preferences': + 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) -> preload = path.join fixtures, 'module', 'send-later.js' - remote.require('ipc').once 'answer', (event, test) -> + ipcMain.once 'answer', (event, test) -> assert.equal(test, 'undefined') done() w.destroy() w = new BrowserWindow show: false - 'web-preferences': + webPreferences: preload: preload - 'node-integration': false - w.loadUrl 'file://' + path.join(fixtures, 'api', 'blank.html') + nodeIntegration: false + 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 ddb38825e35f..19da3fc75f1b 100644 --- a/spec/api-clipboard-spec.coffee +++ b/spec/api-clipboard-spec.coffee @@ -1,8 +1,8 @@ assert = require 'assert' -clipboard = require 'clipboard' -nativeImage = require 'native-image' path = require 'path' +{clipboard, nativeImage} = require 'electron' + describe 'clipboard module', -> fixtures = path.resolve __dirname, 'fixtures' @@ -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 9aedb0c8ea1e..676dbf9d6929 100644 --- a/spec/api-crash-reporter-spec.coffee +++ b/spec/api-crash-reporter-spec.coffee @@ -2,11 +2,10 @@ assert = require 'assert' 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' +{remote} = require 'electron' +{app, crashReporter, BrowserWindow} = remote.require 'electron' describe 'crash-reporter module', -> fixtures = path.resolve __dirname, 'fixtures' @@ -24,12 +23,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 formidable.IncomingForm() - process.throwDeprecation = false + form = new multiparty.Form() form.parse req, (error, fields, files) -> - process.throwDeprecation = true + # 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' @@ -38,8 +40,7 @@ describe 'crash-reporter module', -> assert.equal fields['extra2'], 'extra2' 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']? + assert.equal fields['_version'], app.getVersion() res.end('abc-123-def') done() @@ -53,5 +54,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} - w.loadUrl url + if process.platform is 'darwin' + 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 142f06c00ff3..a8d2a65cdef7 100644 --- a/spec/api-ipc-spec.coffee +++ b/spec/api-ipc-spec.coffee @@ -1,9 +1,8 @@ assert = require 'assert' -ipc = require 'ipc' path = require 'path' -remote = require 'remote' -BrowserWindow = remote.require 'browser-window' +{ipcRenderer, remote} = require 'electron' +{ipcMain, BrowserWindow} = remote.require 'electron' comparePaths = (path1, path2) -> if process.platform is 'win32' @@ -17,8 +16,8 @@ describe 'ipc module', -> describe 'remote.require', -> it 'should returns same object for the same module', -> - dialog1 = remote.require 'dialog' - dialog2 = remote.require 'dialog' + dialog1 = remote.require 'electron' + dialog2 = remote.require 'electron' assert.equal dialog1, dialog2 it 'should work when object contains id property', -> @@ -70,21 +69,34 @@ 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) -> + ipcRenderer.once 'message', (event, message) -> assert.deepEqual message, obj done() - ipc.send 'message', obj + ipcRenderer.send 'message', obj describe 'ipc.sendSync', -> it 'can be replied by setting event.returnValue', -> - msg = ipc.sendSync 'echo', 'test' + msg = ipcRenderer.sendSync 'echo', 'test' assert.equal msg, 'test' 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) -> + ipcMain.once 'send-sync-message', (event) -> 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', -> + 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() diff --git a/spec/api-menu-spec.coffee b/spec/api-menu-spec.coffee index f51d8580cc52..f23face228a9 100644 --- a/spec/api-menu-spec.coffee +++ b/spec/api-menu-spec.coffee @@ -1,8 +1,7 @@ assert = require 'assert' -remote = require 'remote' -Menu = remote.require 'menu' -MenuItem = remote.require 'menu-item' +{remote} = require 'electron' +{Menu, MenuItem} = remote.require 'electron' describe 'menu module', -> describe 'Menu.buildFromTemplate', -> diff --git a/spec/api-protocol-spec.coffee b/spec/api-protocol-spec.coffee index 02fd8d5e402a..d160512cd736 100644 --- a/spec/api-protocol-spec.coffee +++ b/spec/api-protocol-spec.coffee @@ -1,8 +1,9 @@ assert = require 'assert' http = require 'http' path = require 'path' -remote = require 'remote' -protocol = remote.require 'protocol' + +{remote} = require 'electron' +{protocol} = remote.require 'electron' describe 'protocol module', -> protocolName = 'sp' @@ -23,9 +24,12 @@ 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 url: "#{protocolName}://fake-host" success: (data) -> @@ -36,6 +40,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 +53,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 +72,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 +84,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 +96,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 +111,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 +123,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 +135,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 +154,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 +166,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 +178,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 +191,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 +203,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 +223,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 +235,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 +247,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) -> @@ -285,9 +305,12 @@ 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 url: 'http://fake-host' success: (data) -> @@ -298,6 +321,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 +334,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 +347,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 +361,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) -> diff --git a/spec/api-screen-spec.coffee b/spec/api-screen-spec.coffee index 341524fca81b..59ef49631cbc 100644 --- a/spec/api-screen-spec.coffee +++ b/spec/api-screen-spec.coffee @@ -1,5 +1,6 @@ assert = require 'assert' -screen = require 'screen' + +{screen} = require 'electron' describe 'screen module', -> describe 'screen.getCursorScreenPoint()', -> diff --git a/spec/api-session-spec.coffee b/spec/api-session-spec.coffee index 9e083d27c0f7..6d0a8ac167c0 100644 --- a/spec/api-session-spec.coffee +++ b/spec/api-session-spec.coffee @@ -1,10 +1,10 @@ assert = require 'assert' -remote = require 'remote' http = require 'http' path = require 'path' fs = require 'fs' -app = remote.require 'app' -BrowserWindow = remote.require 'browser-window' + +{ipcRenderer, remote} = require 'electron' +{app, ipcMain, session, BrowserWindow} = remote describe 'session module', -> @timeout 10000 @@ -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 @@ -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') @@ -60,12 +60,11 @@ 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.on 'count', (event, count) -> + 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://", @@ -78,7 +77,6 @@ describe 'session module', -> # A 5 MB mock pdf. mockPDF = new Buffer 1024 * 1024 * 5 contentDisposition = 'inline; filename="mock.pdf"' - ipc = require 'ipc' downloadFilePath = path.join fixtures, 'mock.pdf' downloadServer = http.createServer (req, res) -> res.writeHead 200, { @@ -92,10 +90,9 @@ describe 'session module', -> it 'can download successfully', (done) -> downloadServer.listen 0, '127.0.0.1', -> {port} = downloadServer.address() - ipc.sendSync 'set-download-option', false - w.loadUrl "#{url}:#{port}" - ipc.once 'download-done', (state, url, mimeType, receivedBytes, - totalBytes, disposition, filename) -> + ipcRenderer.sendSync 'set-download-option', false + 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' assert.equal url, "http://127.0.0.1:#{port}/" @@ -110,10 +107,9 @@ describe 'session module', -> it 'can cancel download', (done) -> downloadServer.listen 0, '127.0.0.1', -> {port} = downloadServer.address() - ipc.sendSync 'set-download-option', true - w.loadUrl "#{url}:#{port}/" - ipc.once 'download-done', (state, url, mimeType, receivedBytes, - totalBytes, disposition, filename) -> + ipcRenderer.sendSync 'set-download-option', true + 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' assert.equal mimeType, 'application/pdf' diff --git a/spec/asar-spec.coffee b/spec/asar-spec.coffee index 75f0cec63adb..ad480a582525 100644 --- a/spec/asar-spec.coffee +++ b/spec/asar-spec.coffee @@ -3,6 +3,9 @@ child_process = require 'child_process' fs = require 'fs' path = require 'path' +{nativeImage, remote} = require 'electron' +{ipcMain, BrowserWindow} = remote.require 'electron' + describe 'asar package', -> fixtures = path.join __dirname, 'fixtures' @@ -406,9 +409,6 @@ describe 'asar package', -> describe 'asar protocol', -> url = require 'url' - remote = require 'remote' - ipc = remote.require 'ipc' - BrowserWindow = remote.require 'browser-window' it 'can request a file in package', (done) -> p = path.resolve fixtures, 'asar', 'a.asar', 'file1' @@ -445,26 +445,26 @@ describe 'asar package', -> it 'sets __dirname correctly', (done) -> after -> w.destroy() - ipc.removeAllListeners 'dirname' + ipcMain.removeAllListeners 'dirname' w = new BrowserWindow(show: false, width: 400, height: 400) p = path.resolve fixtures, 'asar', 'web.asar', 'index.html' u = url.format protocol: 'file', slashed: true, pathname: p - ipc.once 'dirname', (event, dirname) -> + 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 -> w.destroy() - ipc.removeAllListeners 'ping' + ipcMain.removeAllListeners 'ping' 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 - ipc.once 'ping', (event, message) -> + w.loadURL u + ipcMain.once 'ping', (event, message) -> assert.equal message, 'pong' done() @@ -496,10 +496,10 @@ describe 'asar package', -> describe 'native-image', -> it 'reads image from asar archive', -> p = path.join fixtures, 'asar', 'logo.asar', 'logo.png' - logo = require('native-image').createFromPath p + logo = nativeImage.createFromPath p assert.deepEqual logo.getSize(), {width: 55, height: 55} it 'reads image from asar archive with unpacked files', -> p = path.join fixtures, 'asar', 'unpack.asar', 'atom.png' - logo = require('native-image').createFromPath p + logo = nativeImage.createFromPath p assert.deepEqual logo.getSize(), {width: 1024, height: 1024} diff --git a/spec/chromium-spec.coffee b/spec/chromium-spec.coffee index a034f9378235..435f7bbbe3e5 100644 --- a/spec/chromium-spec.coffee +++ b/spec/chromium-spec.coffee @@ -3,8 +3,9 @@ http = require 'http' https = require 'https' path = require 'path' ws = require 'ws' -remote = require 'remote' -BrowserWindow = remote.require 'browser-window' + +{remote} = require 'electron' +{BrowserWindow} = remote.require 'electron' describe 'chromium feature', -> fixtures = path.resolve __dirname, 'fixtures' @@ -42,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) -> @@ -70,7 +71,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) -> @@ -95,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/beforeunload-false.html b/spec/fixtures/api/beforeunload-false.html index b5a04781103a..e34a1945dd95 100644 --- a/spec/fixtures/api/beforeunload-false.html +++ b/spec/fixtures/api/beforeunload-false.html @@ -3,7 +3,7 @@ diff --git a/spec/fixtures/api/preload.html b/spec/fixtures/api/preload.html index ece481f92413..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 d6fe83f907e1..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 152045ad2a6b..7239786ec90e 100755 Binary files a/spec/fixtures/asar/script.asar and b/spec/fixtures/asar/script.asar differ diff --git a/spec/fixtures/asar/web.asar b/spec/fixtures/asar/web.asar index 0c7a788e759d..1e9db65b8128 100644 Binary files a/spec/fixtures/asar/web.asar and b/spec/fixtures/asar/web.asar differ diff --git a/spec/fixtures/module/preload-ipc.js b/spec/fixtures/module/preload-ipc.js index 9b6e0201248e..ed95055c1249 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) { - 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 fce96b84b787..13f02452db1c 100644 --- a/spec/fixtures/module/send-later.js +++ b/spec/fixtures/module/send-later.js @@ -1,4 +1,4 @@ -var ipc = require('ipc'); +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 aa95546a9c11..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 7ae4edf4ce29..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 b5029d638926..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 15bfef49c4da..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 99e6c3e98382..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 1fd38bc7211f..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 226b57dbd709..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').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/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/index.html b/spec/static/index.html index 879d769860ed..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'); // 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 5b10bb6d43d7..be3690cd9e7d 100644 --- a/spec/static/main.js +++ b/spec/static/main.js @@ -1,41 +1,44 @@ -var app = require('app'); -var ipc = require('ipc'); -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. 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 // 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; }); @@ -53,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', @@ -64,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', @@ -78,14 +81,14 @@ 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) { + ipcMain.on('set-download-option', function(event, need_cancel) { window.webContents.session.once('will-download', function(e, item, webContents) { item.setSavePath(downloadFilePath); item.on('done', function(e, state) { window.webContents.send('download-done', state, - item.getUrl(), + item.getURL(), item.getMimeType(), item.getReceivedBytes(), item.getTotalBytes(), diff --git a/vendor/brightray b/vendor/brightray index 49a86c123f4c..d4fab33427eb 160000 --- a/vendor/brightray +++ b/vendor/brightray @@ -1 +1 @@ -Subproject commit 49a86c123f4cc43f4dca886ded612104a8a1fec6 +Subproject commit d4fab33427eb728a553896527f1931887ce6d9d9 diff --git a/vendor/native_mate b/vendor/native_mate index b7387da0854b..93984941005b 160000 --- a/vendor/native_mate +++ b/vendor/native_mate @@ -1 +1 @@ -Subproject commit b7387da0854b20d376fdae0d93a01f83d080668d +Subproject commit 93984941005bab194a2d47aff655d525c064efcb 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