diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 61a8e474099a..516f6289ac0f 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -29,6 +29,7 @@ possible with your report. If you can, please include: * Include screenshots and animated GIFs in your pull request whenever possible. * Follow the CoffeeScript, JavaScript, C++ and Python [coding style defined in docs](/docs/development/coding-style.md). * Write documentation in [Markdown](https://daringfireball.net/projects/markdown). + See the [Documentation Styleguide](/docs/styleguide.md). * Use short, present tense commit messages. See [Commit Message Styleguide](#git-commit-messages-styleguide). ## Styleguides diff --git a/README-ko.md b/README-ko.md index 1b895c159798..83634370eba9 100644 --- a/README-ko.md +++ b/README-ko.md @@ -6,13 +6,15 @@ ### [Electron](https://github.com/atom/electron/) 한국어 참조문서 -:zap: *프레임워크 이름이 Atom Shell에서 Electron으로 바뀌었습니다* :zap: +:zap: *프레임워크 이름이 Atom Shell에서 Electron으로 변경되었습니다* :zap: Electron 프레임워크는 JavaScript, HTML 그리고 CSS를 사용하여 Cross-Platform 데스크톱 어플리케이션을 개발할 수 있도록 해주는 프레임워크입니다. 이 프레임워크는 [io.js](http://iojs.org) 와 [Chromium](http://www.chromium.org)을 기반으로 만들어 졌으며 [Atom Editor](https://github.com/atom/atom)에 사용되고 있습니다. Electron에 대한 중요한 알림을 받고 싶다면 Twitter에서 [@ElectronJS](https://twitter.com/electronjs)를 팔로우 하세요. +이 프로젝트는 기여자 규약 1.2를 준수합니다. 이 프로젝트에 참여할 때 코드를 유지해야 합니다. 받아들일 수 없는 행동은 atom@github.com로 보고 하십시오. + ## 다운로드 Linux, Windows, Mac용으로 미리 빌드된 Electron 바이너리와 디버그 심볼이 준비되어 있습니다. [releases](https://github.com/atom/electron/releases) 페이지에서 받아 볼 수 있습니다. @@ -38,12 +40,19 @@ Electron을 빌드 하는 방법과 프로젝트에 기여하는 방법도 문 ## 참조 문서 (번역) +- [브라질 포르투칼어](https://github.com/atom/electron/tree/master/docs-translations/pt-BR) - [한국어](https://github.com/atom/electron/tree/master/docs-translations/ko) - [일본어](https://github.com/atom/electron/tree/master/docs-translations/jp) - [스페인어](https://github.com/atom/electron/tree/master/docs-translations/es) +- [중국어 간체](https://github.com/atom/electron/tree/master/docs-translations/zh-CN) +- [중국어 번체](https://github.com/atom/electron/tree/master/docs-translations/zh-TW) ## 커뮤니티 -[Atom 포럼내의 `electron` 카테고리](http://discuss.atom.io/category/electron)와 Freenode `#atom-shell` 채팅 채널에서 활발하게 토론이 이어지고 있습니다. +다음 링크를 통해 커뮤니티에 질문을 올리거나 토론을 나누실 수 있습니다: + +- Atom 포럼의 [`electron`](http://discuss.atom.io/category/electron) 카테고리 +- Freenode 채팅의 `#atom-shell` 채널 +- Slack의 [`Atom`](http://atom-slack.herokuapp.com/) 채널 [awesome-electron](https://github.com/sindresorhus/awesome-electron) 프로젝트엔 커뮤니티가 운영중인 유용한 예제 어플리케이션과 도구, 리소스가 있으니 한번 참고해 보시기 바랍니다. diff --git a/README.md b/README.md index 81196554495f..54b6af5fa3fc 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ [![devDependency Status](https://david-dm.org/atom/electron/dev-status.svg)](https://david-dm.org/atom/electron#info=devDependencies) [![Join the Electron Community on Slack](http://atom-slack.herokuapp.com/badge.svg)](http://atom-slack.herokuapp.com/) -:zap: *formerly known as Atom Shell* :zap: +: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 [io.js](http://iojs.org) and @@ -15,7 +15,8 @@ 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). -By participating, you are expected to uphold this code. Please report unacceptable behavior to atom@github.com. +By participating, you are expected to uphold this code. Please report +unacceptable behavior to atom@github.com. ## Downloads @@ -45,6 +46,7 @@ contains documents describing how to build and contribute to Electron. ## Documentation Translations +- [Brazilian Portuguese](https://github.com/atom/electron/tree/master/docs-translations/pt-BR) - [Korean](https://github.com/atom/electron/tree/master/docs-translations/ko) - [Japanese](https://github.com/atom/electron/tree/master/docs-translations/jp) - [Spanish](https://github.com/atom/electron/tree/master/docs-translations/es) @@ -53,7 +55,12 @@ contains documents describing how to build and contribute to Electron. ## Community -There is an [`electron` category on the Atom forums](http://discuss.atom.io/category/electron) -as well as an `#atom-shell` channel on Freenode. +You can ask questions and interact with the community in the following +locations: +- [`electron`](http://discuss.atom.io/category/electron) category on the Atom +forums +- `#atom-shell` channel on Freenode +- [`Atom`](http://atom-slack.herokuapp.com/) channel on Slack -Check out [awesome-electron](https://github.com/sindresorhus/awesome-electron) for a community maintained list of useful example apps, tools and resources. +Check out [awesome-electron](https://github.com/sindresorhus/awesome-electron) +for a community maintained list of useful example apps, tools and resources. diff --git a/atom.gyp b/atom.gyp index c0fc40187984..63defa4273fd 100644 --- a/atom.gyp +++ b/atom.gyp @@ -4,7 +4,7 @@ 'product_name%': 'Electron', 'company_name%': 'GitHub, Inc', 'company_abbr%': 'github', - 'version%': '0.31.2', + 'version%': '0.32.3', }, 'includes': [ 'filenames.gypi', diff --git a/atom/app/atom_content_client.cc b/atom/app/atom_content_client.cc index 1ba1f2031564..e760c01453d4 100644 --- a/atom/app/atom_content_client.cc +++ b/atom/app/atom_content_client.cc @@ -7,6 +7,7 @@ #include #include +#include "atom/common/atom_version.h" #include "atom/common/chrome_version.h" #include "atom/common/options_switches.h" #include "base/command_line.h" @@ -14,6 +15,7 @@ #include "base/strings/string_util.h" #include "content/public/common/content_constants.h" #include "content/public/common/pepper_plugin_info.h" +#include "content/public/common/user_agent.h" #include "ppapi/shared_impl/ppapi_permissions.h" namespace atom { @@ -72,6 +74,12 @@ std::string AtomContentClient::GetProduct() const { return "Chrome/" CHROME_VERSION_STRING; } +std::string AtomContentClient::GetUserAgent() const { + return content::BuildUserAgentFromProduct( + "Chrome/" CHROME_VERSION_STRING " " + ATOM_PRODUCT_NAME "/" ATOM_VERSION_STRING); +} + void AtomContentClient::AddAdditionalSchemes( std::vector* standard_schemes, std::vector* savable_schemes) { diff --git a/atom/app/atom_content_client.h b/atom/app/atom_content_client.h index 279ec7179f49..a6b2f73e7faa 100644 --- a/atom/app/atom_content_client.h +++ b/atom/app/atom_content_client.h @@ -20,6 +20,7 @@ class AtomContentClient : public brightray::ContentClient { protected: // content::ContentClient: std::string GetProduct() const override; + std::string GetUserAgent() const override; void AddAdditionalSchemes( std::vector* standard_schemes, std::vector* savable_schemes) override; diff --git a/atom/app/atom_main_delegate.cc b/atom/app/atom_main_delegate.cc index 02dd11c81ba0..3c7d6b2e7034 100644 --- a/atom/app/atom_main_delegate.cc +++ b/atom/app/atom_main_delegate.cc @@ -38,7 +38,9 @@ bool AtomMainDelegate::BasicStartupComplete(int* exit_code) { #else settings.logging_dest = logging::LOG_TO_SYSTEM_DEBUG_LOG; #endif // defined(DEBUG) -#endif // defined(OS_WIN) +#else // defined(OS_WIN) + settings.logging_dest = logging::LOG_TO_SYSTEM_DEBUG_LOG; +#endif // !defined(OS_WIN) logging::InitLogging(settings); // Logging with pid and timestamp. diff --git a/atom/browser/api/atom_api_app.cc b/atom/browser/api/atom_api_app.cc index c25b3be5f4d6..43b3d82df109 100644 --- a/atom/browser/api/atom_api_app.cc +++ b/atom/browser/api/atom_api_app.cc @@ -19,6 +19,7 @@ #include "atom/browser/api/atom_api_web_contents.h" #include "atom/common/native_mate_converters/callback.h" #include "atom/common/native_mate_converters/file_path_converter.h" +#include "atom/common/node_includes.h" #include "base/command_line.h" #include "base/environment.h" #include "base/files/file_path.h" @@ -34,8 +35,6 @@ #include "base/strings/utf_string_conversions.h" #endif -#include "atom/common/node_includes.h" - using atom::Browser; namespace mate { @@ -168,8 +167,8 @@ void App::OnOpenURL(const std::string& url) { Emit("open-url", url); } -void App::OnActivateWithNoOpenWindows() { - Emit("activate-with-no-open-windows"); +void App::OnActivate(bool has_visible_windows) { + Emit("activate", has_visible_windows); } void App::OnWillFinishLaunching() { diff --git a/atom/browser/api/atom_api_app.h b/atom/browser/api/atom_api_app.h index 040f7e3363a9..255f780e578d 100644 --- a/atom/browser/api/atom_api_app.h +++ b/atom/browser/api/atom_api_app.h @@ -41,7 +41,7 @@ class App : public mate::EventEmitter, void OnQuit() override; void OnOpenFile(bool* prevent_default, const std::string& file_path) override; void OnOpenURL(const std::string& url) override; - void OnActivateWithNoOpenWindows() override; + void OnActivate(bool has_visible_windows) override; void OnWillFinishLaunching() override; void OnFinishLaunching() override; void OnSelectCertificate( diff --git a/atom/browser/api/atom_api_auto_updater.cc b/atom/browser/api/atom_api_auto_updater.cc index 1691ac103e96..250aa3e45f64 100644 --- a/atom/browser/api/atom_api_auto_updater.cc +++ b/atom/browser/api/atom_api_auto_updater.cc @@ -7,11 +7,10 @@ #include "base/time/time.h" #include "atom/browser/auto_updater.h" #include "atom/browser/browser.h" +#include "atom/common/node_includes.h" #include "native_mate/dictionary.h" #include "native_mate/object_template_builder.h" -#include "atom/common/node_includes.h" - namespace atom { namespace api { diff --git a/atom/browser/api/atom_api_content_tracing.cc b/atom/browser/api/atom_api_content_tracing.cc index e4bf33c7b5c5..f29946d1f462 100644 --- a/atom/browser/api/atom_api_content_tracing.cc +++ b/atom/browser/api/atom_api_content_tracing.cc @@ -7,13 +7,12 @@ #include "atom/common/native_mate_converters/callback.h" #include "atom/common/native_mate_converters/file_path_converter.h" +#include "atom/common/node_includes.h" #include "base/bind.h" #include "base/files/file_util.h" #include "content/public/browser/tracing_controller.h" #include "native_mate/dictionary.h" -#include "atom/common/node_includes.h" - using content::TracingController; namespace mate { diff --git a/atom/browser/api/atom_api_cookies.cc b/atom/browser/api/atom_api_cookies.cc index bf56a8dc13bd..4f989eff7275 100644 --- a/atom/browser/api/atom_api_cookies.cc +++ b/atom/browser/api/atom_api_cookies.cc @@ -20,8 +20,6 @@ #include "net/url_request/url_request_context.h" #include "net/url_request/url_request_context_getter.h" -#include "atom/common/node_includes.h" - using atom::api::Cookies; using content::BrowserThread; diff --git a/atom/browser/api/atom_api_cookies.h b/atom/browser/api/atom_api_cookies.h index 12cf4a220979..0c309b3f18ee 100644 --- a/atom/browser/api/atom_api_cookies.h +++ b/atom/browser/api/atom_api_cookies.h @@ -78,7 +78,7 @@ class Cookies : public mate::Wrappable { // Must be called on IO thread. net::CookieStore* GetCookieStore(); - scoped_refptr request_context_getter_; + net::URLRequestContextGetter* request_context_getter_; DISALLOW_COPY_AND_ASSIGN(Cookies); }; diff --git a/atom/browser/api/atom_api_power_monitor.cc b/atom/browser/api/atom_api_power_monitor.cc index 093df2a1d4ef..31b35e10cea8 100644 --- a/atom/browser/api/atom_api_power_monitor.cc +++ b/atom/browser/api/atom_api_power_monitor.cc @@ -5,12 +5,11 @@ #include "atom/browser/api/atom_api_power_monitor.h" #include "atom/browser/browser.h" +#include "atom/common/node_includes.h" #include "base/power_monitor/power_monitor.h" #include "base/power_monitor/power_monitor_device_source.h" #include "native_mate/dictionary.h" -#include "atom/common/node_includes.h" - namespace atom { namespace api { @@ -41,9 +40,9 @@ void PowerMonitor::OnResume() { // static v8::Local PowerMonitor::Create(v8::Isolate* isolate) { if (!Browser::Get()->is_ready()) { - node::ThrowError( + isolate->ThrowException(v8::Exception::Error(mate::StringToV8( isolate, - "Cannot initialize \"power-monitor\" module before app is ready"); + "Cannot initialize \"power-monitor\" module before app is ready"))); return v8::Null(isolate); } diff --git a/atom/browser/api/atom_api_power_save_blocker.cc b/atom/browser/api/atom_api_power_save_blocker.cc index c75901cb1e31..58983e6c846a 100644 --- a/atom/browser/api/atom_api_power_save_blocker.cc +++ b/atom/browser/api/atom_api_power_save_blocker.cc @@ -6,9 +6,9 @@ #include +#include "atom/common/node_includes.h" #include "content/public/browser/power_save_blocker.h" #include "native_mate/dictionary.h" -#include "atom/common/node_includes.h" namespace mate { diff --git a/atom/browser/api/atom_api_protocol.cc b/atom/browser/api/atom_api_protocol.cc index f77f3229ed0a..661ab1b5cbdd 100644 --- a/atom/browser/api/atom_api_protocol.cc +++ b/atom/browser/api/atom_api_protocol.cc @@ -12,9 +12,8 @@ #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 "native_mate/dictionary.h" - #include "atom/common/node_includes.h" +#include "native_mate/dictionary.h" using content::BrowserThread; diff --git a/atom/browser/api/atom_api_protocol.h b/atom/browser/api/atom_api_protocol.h index 966fcd8726b3..9f98eb767309 100644 --- a/atom/browser/api/atom_api_protocol.h +++ b/atom/browser/api/atom_api_protocol.h @@ -66,7 +66,7 @@ class Protocol : public mate::Wrappable { public: CustomProtocolHandler( v8::Isolate* isolate, - scoped_refptr request_context, + net::URLRequestContextGetter* request_context, const Handler& handler) : isolate_(isolate), request_context_(request_context), @@ -83,7 +83,7 @@ class Protocol : public mate::Wrappable { private: v8::Isolate* isolate_; - scoped_refptr request_context_; + net::URLRequestContextGetter* request_context_; Protocol::Handler handler_; DISALLOW_COPY_AND_ASSIGN(CustomProtocolHandler); @@ -172,7 +172,7 @@ class Protocol : public mate::Wrappable { // Convert error code to string. std::string ErrorCodeToString(ProtocolError error); - scoped_refptr request_context_getter_; + net::URLRequestContextGetter* request_context_getter_; // Map that stores the original protocols of schemes. using OriginalProtocolsMap = base::ScopedPtrHashMap< diff --git a/atom/browser/api/atom_api_screen.cc b/atom/browser/api/atom_api_screen.cc index 9f81cf6eeff7..b73bda9ced84 100644 --- a/atom/browser/api/atom_api_screen.cc +++ b/atom/browser/api/atom_api_screen.cc @@ -113,14 +113,16 @@ mate::ObjectTemplateBuilder Screen::GetObjectTemplateBuilder( // static v8::Local Screen::Create(v8::Isolate* isolate) { if (!Browser::Get()->is_ready()) { - node::ThrowError(isolate, - "Cannot initialize \"screen\" module before app is ready"); + isolate->ThrowException(v8::Exception::Error(mate::StringToV8( + isolate, + "Cannot initialize \"screen\" module before app is ready"))); return v8::Null(isolate); } gfx::Screen* screen = gfx::Screen::GetNativeScreen(); if (!screen) { - node::ThrowError(isolate, "Failed to get screen information"); + isolate->ThrowException(v8::Exception::Error(mate::StringToV8( + isolate, "Failed to get screen information"))); return v8::Null(isolate); } diff --git a/atom/browser/api/atom_api_session.cc b/atom/browser/api/atom_api_session.cc index 3ca15ab871fa..f07ab8b78045 100644 --- a/atom/browser/api/atom_api_session.cc +++ b/atom/browser/api/atom_api_session.cc @@ -13,6 +13,7 @@ #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/node_includes.h" #include "base/files/file_path.h" #include "base/prefs/pref_service.h" #include "base/strings/string_util.h" @@ -29,8 +30,6 @@ #include "net/url_request/url_request_context.h" #include "net/url_request/url_request_context_getter.h" -#include "atom/common/node_includes.h" - using content::BrowserThread; using content::StoragePartition; @@ -233,16 +232,16 @@ void SetProxyInIO(net::URLRequestContextGetter* getter, Session::Session(AtomBrowserContext* browser_context) : browser_context_(browser_context) { AttachAsUserData(browser_context); + // Observe DownloadManger to get download notifications. - auto download_manager = - content::BrowserContext::GetDownloadManager(browser_context); - download_manager->AddObserver(this); + content::BrowserContext::GetDownloadManager(browser_context)-> + AddObserver(this); } Session::~Session() { - auto download_manager = - content::BrowserContext::GetDownloadManager(browser_context_); - download_manager->RemoveObserver(this); + content::BrowserContext::GetDownloadManager(browser_context())-> + RemoveObserver(this); + Destroy(); } void Session::OnDownloadCreated(content::DownloadManager* manager, @@ -257,8 +256,16 @@ void Session::OnDownloadCreated(content::DownloadManager* manager, } } +bool Session::IsDestroyed() const { + return !browser_context_; +} + +void Session::Destroy() { + browser_context_ = nullptr; +} + void Session::ResolveProxy(const GURL& url, ResolveProxyCallback callback) { - new ResolveProxyHelper(browser_context_, url, callback); + new ResolveProxyHelper(browser_context(), url, callback); } void Session::ClearCache(const net::CompletionCallback& callback) { @@ -279,7 +286,7 @@ void Session::ClearStorageData(mate::Arguments* args) { } auto storage_partition = - content::BrowserContext::GetStoragePartition(browser_context_, nullptr); + content::BrowserContext::GetStoragePartition(browser_context(), nullptr); storage_partition->ClearData( options.storage_types, options.quota_types, options.origin, content::StoragePartition::OriginMatcherFunction(), @@ -300,7 +307,7 @@ void Session::SetDownloadPath(const base::FilePath& path) { v8::Local Session::Cookies(v8::Isolate* isolate) { if (cookies_.IsEmpty()) { - auto handle = atom::api::Cookies::Create(isolate, browser_context_); + auto handle = atom::api::Cookies::Create(isolate, browser_context()); cookies_.Reset(isolate, handle.ToV8()); } return v8::Local::New(isolate, cookies_); @@ -319,8 +326,7 @@ mate::ObjectTemplateBuilder Session::GetObjectTemplateBuilder( // static mate::Handle Session::CreateFrom( - v8::Isolate* isolate, - AtomBrowserContext* browser_context) { + v8::Isolate* isolate, AtomBrowserContext* browser_context) { auto existing = TrackableObject::FromWrappedClass(isolate, browser_context); if (existing) return mate::CreateHandle(isolate, static_cast(existing)); @@ -330,6 +336,14 @@ mate::Handle Session::CreateFrom( return handle; } +// static +mate::Handle Session::FromPartition( + v8::Isolate* isolate, const std::string& partition, bool in_memory) { + auto browser_context = brightray::BrowserContext::From(partition, in_memory); + return CreateFrom(isolate, + static_cast(browser_context.get())); +} + void SetWrapSession(const WrapSessionCallback& callback) { g_wrap_session = callback; } @@ -348,6 +362,7 @@ void Initialize(v8::Local exports, v8::Local unused, v8::Local context, void* priv) { v8::Isolate* isolate = context->GetIsolate(); mate::Dictionary dict(isolate, exports); + dict.SetMethod("fromPartition", &atom::api::Session::FromPartition); dict.SetMethod("_setWrapSession", &atom::api::SetWrapSession); dict.SetMethod("_clearWrapSession", &atom::api::ClearWrapSession); } diff --git a/atom/browser/api/atom_api_session.h b/atom/browser/api/atom_api_session.h index c06348974ff4..14406e57af5b 100644 --- a/atom/browser/api/atom_api_session.h +++ b/atom/browser/api/atom_api_session.h @@ -37,7 +37,11 @@ class Session: public mate::TrackableObject, static mate::Handle CreateFrom( v8::Isolate* isolate, AtomBrowserContext* browser_context); - AtomBrowserContext* browser_context() const { return browser_context_; } + // Gets the Session of |partition| and |in_memory|. + static mate::Handle FromPartition( + v8::Isolate* isolate, const std::string& partition, bool in_memory); + + AtomBrowserContext* browser_context() const { return browser_context_.get(); } protected: explicit Session(AtomBrowserContext* browser_context); @@ -47,11 +51,15 @@ class Session: public mate::TrackableObject, void OnDownloadCreated(content::DownloadManager* manager, content::DownloadItem* item) override; - // mate::Wrappable implementations: + // mate::Wrappable: mate::ObjectTemplateBuilder GetObjectTemplateBuilder( v8::Isolate* isolate) override; + bool IsDestroyed() const override; private: + // mate::TrackableObject: + void Destroy() override; + void ResolveProxy(const GURL& url, ResolveProxyCallback callback); void ClearCache(const net::CompletionCallback& callback); void ClearStorageData(mate::Arguments* args); @@ -59,9 +67,10 @@ class Session: public mate::TrackableObject, void SetDownloadPath(const base::FilePath& path); v8::Local Cookies(v8::Isolate* isolate); + // Cached object for cookies API. v8::Global cookies_; - AtomBrowserContext* browser_context_; // weak ref + scoped_refptr browser_context_; DISALLOW_COPY_AND_ASSIGN(Session); }; diff --git a/atom/browser/api/atom_api_tray.cc b/atom/browser/api/atom_api_tray.cc index 1382f015a63b..0f5829e19c14 100644 --- a/atom/browser/api/atom_api_tray.cc +++ b/atom/browser/api/atom_api_tray.cc @@ -12,13 +12,12 @@ #include "atom/common/native_mate_converters/gfx_converter.h" #include "atom/common/native_mate_converters/image_converter.h" #include "atom/common/native_mate_converters/string16_converter.h" +#include "atom/common/node_includes.h" #include "native_mate/constructor.h" #include "native_mate/dictionary.h" #include "ui/events/event_constants.h" #include "ui/gfx/image/image.h" -#include "atom/common/node_includes.h" - namespace atom { namespace api { @@ -35,7 +34,8 @@ Tray::~Tray() { // static mate::Wrappable* Tray::New(v8::Isolate* isolate, const gfx::Image& image) { if (!Browser::Get()->is_ready()) { - node::ThrowError(isolate, "Cannot create Tray before app is ready"); + isolate->ThrowException(v8::Exception::Error(mate::StringToV8( + isolate, "Cannot create Tray before app is ready"))); return nullptr; } return new Tray(image); diff --git a/atom/browser/api/atom_api_web_contents.cc b/atom/browser/api/atom_api_web_contents.cc index 7cefe8e45e3d..a24200e5a87d 100644 --- a/atom/browser/api/atom_api_web_contents.cc +++ b/atom/browser/api/atom_api_web_contents.cc @@ -11,6 +11,7 @@ #include "atom/browser/atom_browser_context.h" #include "atom/browser/atom_browser_main_parts.h" #include "atom/browser/native_window.h" +#include "atom/browser/web_contents_preferences.h" #include "atom/browser/web_view_guest_delegate.h" #include "atom/common/api/api_messages.h" #include "atom/common/api/event_emitter_caller.h" @@ -153,31 +154,41 @@ WebContents::WebContents(content::WebContents* web_contents) web_contents->SetUserAgentOverride(GetBrowserContext()->GetUserAgent()); } -WebContents::WebContents(const mate::Dictionary& options) { +WebContents::WebContents(v8::Isolate* isolate, + const mate::Dictionary& options) { + // Whether it is a guest WebContents. bool is_guest = false; options.Get("isGuest", &is_guest); - type_ = is_guest ? WEB_VIEW : BROWSER_WINDOW; - content::BrowserContext* browser_context = - AtomBrowserMainParts::Get()->browser_context(); + // Obtain the session. + std::string partition; + mate::Handle session; + if (options.Get("session", &session)) { + } else if (options.Get("partition", &partition) && !partition.empty()) { + bool in_memory = true; + if (base::StartsWith(partition, "persist:", base::CompareCase::SENSITIVE)) { + in_memory = false; + partition = partition.substr(8); + } + session = Session::FromPartition(isolate, partition, in_memory); + } else { + // Use the default session if not specified. + session = Session::FromPartition(isolate, "", false); + } + session_.Reset(isolate, session.ToV8()); + content::WebContents* web_contents; if (is_guest) { - GURL guest_site; - options.Get("partition", &guest_site); - // use hosts' browser_context when no partition is specified. - if (!guest_site.query().empty()) { - browser_context = AtomBrowserMainParts::Get() - ->GetBrowserContextForPartition(guest_site); - } - auto site_instance = - content::SiteInstance::CreateForURL(browser_context, guest_site); - content::WebContents::CreateParams params(browser_context, site_instance); + content::SiteInstance* site_instance = content::SiteInstance::CreateForURL( + session->browser_context(), GURL("chrome-guest://fake-host")); + content::WebContents::CreateParams params( + session->browser_context(), site_instance); guest_delegate_.reset(new WebViewGuestDelegate); params.guest_delegate = guest_delegate_.get(); web_contents = content::WebContents::Create(params); } else { - content::WebContents::CreateParams params(browser_context); + content::WebContents::CreateParams params(session->browser_context()); web_contents = content::WebContents::Create(params); } @@ -185,6 +196,11 @@ WebContents::WebContents(const mate::Dictionary& options) { AttachAsUserData(web_contents); InitWithWebContents(web_contents); + // Save the preferences. + base::DictionaryValue web_preferences; + mate::ConvertFromV8(isolate, options.GetHandle(), &web_preferences); + new WebContentsPreferences(web_contents, &web_preferences); + web_contents->SetUserAgentOverride(GetBrowserContext()->GetUserAgent()); if (is_guest) { @@ -372,7 +388,7 @@ void WebContents::DidFailProvisionalLoad( int error_code, const base::string16& error_description, bool was_ignored_by_handler) { - Emit("did-fail-load", error_code, error_description); + Emit("did-fail-load", error_code, error_description, validated_url); } void WebContents::DidFailLoad(content::RenderFrameHost* render_frame_host, @@ -380,7 +396,7 @@ void WebContents::DidFailLoad(content::RenderFrameHost* render_frame_host, int error_code, const base::string16& error_description, bool was_ignored_by_handler) { - Emit("did-fail-load", error_code, error_description); + Emit("did-fail-load", error_code, error_description, validated_url); } void WebContents::DidStartLoading() { @@ -489,6 +505,7 @@ void WebContents::NavigationEntryCommitted( } void WebContents::Destroy() { + session_.Reset(); if (type_ == WEB_VIEW && managed_web_contents()) { // When force destroying the "destroyed" event is not emitted. WebContentsDestroyed(); @@ -530,6 +547,10 @@ void WebContents::LoadURL(const GURL& url, const mate::Dictionary& options) { web_contents()->GetController().LoadURLWithParams(params); } +GURL WebContents::GetURL() const { + return web_contents()->GetURL(); +} + base::string16 WebContents::GetTitle() const { return web_contents()->GetTitle(); } @@ -651,10 +672,6 @@ void WebContents::InspectServiceWorker() { } v8::Local WebContents::Session(v8::Isolate* isolate) { - if (session_.IsEmpty()) { - auto handle = Session::CreateFrom(isolate, GetBrowserContext()); - session_.Reset(isolate, handle.ToV8()); - } return v8::Local::New(isolate, session_); } @@ -704,17 +721,19 @@ void WebContents::PrintToPDF(const base::DictionaryValue& setting, PrintToPDF(setting, callback); } -void WebContents::AddWorkSpace(const base::FilePath& path) { +void WebContents::AddWorkSpace(mate::Arguments* args, + const base::FilePath& path) { if (path.empty()) { - node::ThrowError(isolate(), "path cannot be empty"); + args->ThrowError("path cannot be empty"); return; } DevToolsAddFileSystem(path); } -void WebContents::RemoveWorkSpace(const base::FilePath& path) { +void WebContents::RemoveWorkSpace(mate::Arguments* args, + const base::FilePath& path) { if (path.empty()) { - node::ThrowError(isolate(), "path cannot be empty"); + args->ThrowError("path cannot be empty"); return; } DevToolsRemoveFileSystem(path); @@ -800,6 +819,7 @@ mate::ObjectTemplateBuilder WebContents::GetObjectTemplateBuilder( .SetMethod("getId", &WebContents::GetID) .SetMethod("equal", &WebContents::Equal) .SetMethod("_loadUrl", &WebContents::LoadURL) + .SetMethod("_getUrl", &WebContents::GetURL) .SetMethod("getTitle", &WebContents::GetTitle) .SetMethod("isLoading", &WebContents::IsLoading) .SetMethod("isWaitingForResponse", &WebContents::IsWaitingForResponse) @@ -890,7 +910,7 @@ mate::Handle WebContents::CreateFrom( // static mate::Handle WebContents::Create( v8::Isolate* isolate, const mate::Dictionary& options) { - auto handle = mate::CreateHandle(isolate, new WebContents(options)); + auto handle = mate::CreateHandle(isolate, new WebContents(isolate, options)); g_wrap_web_contents.Run(handle.ToV8()); return handle; } diff --git a/atom/browser/api/atom_api_web_contents.h b/atom/browser/api/atom_api_web_contents.h index e75e88fd703e..0001d3e8ef75 100644 --- a/atom/browser/api/atom_api_web_contents.h +++ b/atom/browser/api/atom_api_web_contents.h @@ -48,11 +48,14 @@ class WebContents : public mate::TrackableObject, static mate::Handle Create( v8::Isolate* isolate, const mate::Dictionary& options); - void Destroy(); + // 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); + GURL GetURL() const; base::string16 GetTitle() const; bool IsLoading() const; bool IsWaitingForResponse() const; @@ -85,8 +88,8 @@ class WebContents : public mate::TrackableObject, const PrintToPDFCallback& callback); // DevTools workspace api. - void AddWorkSpace(const base::FilePath& path); - void RemoveWorkSpace(const base::FilePath& path); + void AddWorkSpace(mate::Arguments* args, const base::FilePath& path); + void RemoveWorkSpace(mate::Arguments* args, const base::FilePath& path); // Editing commands. void Undo(); @@ -116,7 +119,7 @@ class WebContents : public mate::TrackableObject, protected: explicit WebContents(content::WebContents* web_contents); - explicit WebContents(const mate::Dictionary& options); + WebContents(v8::Isolate* isolate, const mate::Dictionary& options); ~WebContents(); // mate::Wrappable: diff --git a/atom/browser/api/atom_api_web_view_manager.cc b/atom/browser/api/atom_api_web_view_manager.cc index 221d0d7118b4..e57c5ffb6bb4 100644 --- a/atom/browser/api/atom_api_web_view_manager.cc +++ b/atom/browser/api/atom_api_web_view_manager.cc @@ -3,14 +3,14 @@ // found in the LICENSE file. #include "atom/browser/api/atom_api_web_contents.h" -#include "atom/browser/web_view_constants.h" +#include "atom/browser/web_contents_preferences.h" #include "atom/browser/web_view_manager.h" -#include "atom/common/native_mate_converters/gurl_converter.h" +#include "atom/common/native_mate_converters/value_converter.h" +#include "atom/common/node_includes.h" #include "content/public/browser/browser_context.h" #include "native_mate/dictionary.h" -#include "net/base/filename_util.h" -#include "atom/common/node_includes.h" +using atom::WebContentsPreferences; namespace mate { @@ -26,31 +26,6 @@ struct Converter { } }; -template<> -struct Converter { - static bool FromV8(v8::Isolate* isolate, v8::Local val, - atom::WebViewManager::WebViewInfo* out) { - Dictionary options; - if (!ConvertFromV8(isolate, val, &options)) - return false; - - GURL preload_url; - if (!options.Get(atom::web_view::kPreloadUrl, &preload_url)) - return false; - - if (!preload_url.is_empty() && - !net::FileURLToFilePath(preload_url, &(out->preload_script))) - return false; - - return options.Get(atom::web_view::kNodeIntegration, - &(out->node_integration)) && - options.Get(atom::web_view::kPlugins, &(out->plugins)) && - options.Get(atom::web_view::kPartitionId, &(out->partition_id)) && - options.Get(atom::web_view::kDisableWebSecurity, - &(out->disable_web_security)); - } -}; - } // namespace mate namespace { @@ -69,17 +44,13 @@ void AddGuest(int guest_instance_id, int element_instance_id, content::WebContents* embedder, content::WebContents* guest_web_contents, - atom::WebViewManager::WebViewInfo info) { + const base::DictionaryValue& options) { auto manager = GetWebViewManager(embedder); if (manager) manager->AddGuest(guest_instance_id, element_instance_id, embedder, guest_web_contents); - info.guest_instance_id = guest_instance_id; - info.embedder = embedder; - auto data = new atom::WebViewManager::WebViewInfoUserData(info); - guest_web_contents->SetUserData( - atom::web_view::kWebViewInfoKeyName, data); + WebContentsPreferences::FromWebContents(guest_web_contents)->Merge(options); } void RemoveGuest(content::WebContents* embedder, int guest_instance_id) { diff --git a/atom/browser/api/atom_api_window.cc b/atom/browser/api/atom_api_window.cc index e6d16fe6fa59..1a76c3e5f078 100644 --- a/atom/browser/api/atom_api_window.cc +++ b/atom/browser/api/atom_api_window.cc @@ -13,6 +13,7 @@ #include "atom/common/native_mate_converters/gurl_converter.h" #include "atom/common/native_mate_converters/image_converter.h" #include "atom/common/native_mate_converters/string16_converter.h" +#include "atom/common/options_switches.h" #include "content/public/browser/render_process_host.h" #include "native_mate/constructor.h" #include "native_mate/dictionary.h" @@ -64,9 +65,21 @@ void OnCapturePageDone( Window::Window(v8::Isolate* isolate, const mate::Dictionary& options) { + // Use options['web-preferences'] to create WebContents. + mate::Dictionary web_preferences = mate::Dictionary::CreateEmpty(isolate); + options.Get(switches::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); + // Creates the WebContents used by BrowserWindow. - mate::Dictionary web_contents_options(isolate, v8::Object::New(isolate)); - auto web_contents = WebContents::Create(isolate, web_contents_options); + auto web_contents = WebContents::Create(isolate, web_preferences); web_contents_.Reset(isolate, web_contents.ToV8()); api_web_contents_ = web_contents.get(); @@ -170,21 +183,21 @@ void Window::OnDevToolsFocus() { } void Window::OnDevToolsOpened() { - Emit("devtools-opened"); - v8::Locker locker(isolate()); v8::HandleScope handle_scope(isolate()); auto handle = WebContents::CreateFrom( isolate(), api_web_contents_->GetDevToolsWebContents()); devtools_web_contents_.Reset(isolate(), handle.ToV8()); + + Emit("devtools-opened"); } void Window::OnDevToolsClosed() { - Emit("devtools-closed"); - v8::Locker locker(isolate()); v8::HandleScope handle_scope(isolate()); devtools_web_contents_.Reset(); + + Emit("devtools-closed"); } void Window::OnExecuteWindowsCommand(const std::string& command_name) { @@ -195,8 +208,8 @@ void Window::OnExecuteWindowsCommand(const std::string& command_name) { mate::Wrappable* Window::New(v8::Isolate* isolate, const mate::Dictionary& options) { if (!Browser::Get()->is_ready()) { - node::ThrowError(isolate, - "Cannot create BrowserWindow before app is ready"); + isolate->ThrowException(v8::Exception::Error(mate::StringToV8( + isolate, "Cannot create BrowserWindow before app is ready"))); return nullptr; } return new Window(isolate, options); @@ -207,7 +220,10 @@ bool Window::IsDestroyed() const { } void Window::Destroy() { - window_->CloseContents(nullptr); + if (window_) { + window_->CloseContents(nullptr); + window_.reset(); + } } void Window::Close() { @@ -398,6 +414,10 @@ bool Window::IsWebViewFocused() { return window_->IsWebViewFocused(); } +bool Window::IsDevToolsFocused() { + return window_->IsDevToolsFocused(); +} + void Window::SetRepresentedFilename(const std::string& filename) { window_->SetRepresentedFilename(filename); } @@ -575,6 +595,7 @@ void Window::BuildPrototype(v8::Isolate* isolate, .SetMethod("focusOnWebView", &Window::FocusOnWebView) .SetMethod("blurWebView", &Window::BlurWebView) .SetMethod("isWebViewFocused", &Window::IsWebViewFocused) + .SetMethod("isDevToolsFocused", &Window::IsDevToolsFocused) .SetMethod("capturePage", &Window::CapturePage) .SetMethod("setProgressBar", &Window::SetProgressBar) .SetMethod("setOverlayIcon", &Window::SetOverlayIcon) diff --git a/atom/browser/api/atom_api_window.h b/atom/browser/api/atom_api_window.h index de2f093ea3e1..d60bf0d87ea0 100644 --- a/atom/browser/api/atom_api_window.h +++ b/atom/browser/api/atom_api_window.h @@ -78,8 +78,10 @@ class Window : public mate::TrackableObject, bool IsDestroyed() const override; private: + // mate::TrackableObject: + void Destroy() override; + // APIs for NativeWindow. - void Destroy(); void Close(); bool IsClosed(); void Focus(); @@ -122,6 +124,7 @@ class Window : public mate::TrackableObject, void FocusOnWebView(); void BlurWebView(); bool IsWebViewFocused(); + bool IsDevToolsFocused(); void SetRepresentedFilename(const std::string& filename); std::string GetRepresentedFilename(); void SetDocumentEdited(bool edited); diff --git a/atom/browser/api/lib/app.coffee b/atom/browser/api/lib/app.coffee index b3446e86e23a..f5b137eb0bb2 100644 --- a/atom/browser/api/lib/app.coffee +++ b/atom/browser/api/lib/app.coffee @@ -45,6 +45,7 @@ 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 # Session wrapper. sessionBindings._setWrapSession wrapSession diff --git a/atom/browser/api/lib/browser-window.coffee b/atom/browser/api/lib/browser-window.coffee index 283e99641f47..2a92cfc55f88 100644 --- a/atom/browser/api/lib/browser-window.coffee +++ b/atom/browser/api/lib/browser-window.coffee @@ -45,6 +45,9 @@ BrowserWindow::_init = -> @on 'focus', (event) => app.emit 'browser-window-focus', event, this + # Notify the creation of the window. + app.emit 'browser-window-created', {}, this + BrowserWindow.getFocusedWindow = -> windows = BrowserWindow.getAllWindows() return window for window in windows when window.isFocused() diff --git a/atom/browser/api/lib/navigation-controller.coffee b/atom/browser/api/lib/navigation-controller.coffee index a985931f4716..f78d92c341d6 100644 --- a/atom/browser/api/lib/navigation-controller.coffee +++ b/atom/browser/api/lib/navigation-controller.coffee @@ -16,6 +16,11 @@ class NavigationController constructor: (@webContents) -> @clearHistory() + # webContents may have already navigated to a page. + if @webContents._getUrl() + @currentIndex++ + @history.push @webContents._getUrl() + @webContents.on 'navigation-entry-commited', (event, url, inPage, replaceEntry) => if @inPageIndex > -1 and not inPage # Navigated to a new page, clear in-page mark. diff --git a/atom/browser/api/lib/web-contents.coffee b/atom/browser/api/lib/web-contents.coffee index 1bb82dec1a66..3a2abfb5155f 100644 --- a/atom/browser/api/lib/web-contents.coffee +++ b/atom/browser/api/lib/web-contents.coffee @@ -44,10 +44,8 @@ wrapWebContents = (webContents) -> # Make sure webContents.executeJavaScript would run the code only when the # web contents has been loaded. - webContents.loaded = false - webContents.once 'did-finish-load', -> @loaded = true webContents.executeJavaScript = (code, hasUserGesture=false) -> - if @loaded + if @getUrl() and not @isLoading() @_executeJavaScript code, hasUserGesture else webContents.once 'did-finish-load', @_executeJavaScript.bind(this, code, hasUserGesture) diff --git a/atom/browser/api/trackable_object.cc b/atom/browser/api/trackable_object.cc index ae9fa44230a0..50bfa59e6a7a 100644 --- a/atom/browser/api/trackable_object.cc +++ b/atom/browser/api/trackable_object.cc @@ -29,7 +29,9 @@ class IDUserData : public base::SupportsUserData::Data { } // namespace TrackableObjectBase::TrackableObjectBase() - : weak_map_id_(0), wrapped_(nullptr) { + : weak_map_id_(0), wrapped_(nullptr), weak_factory_(this) { + RegisterDestructionCallback( + base::Bind(&TrackableObjectBase::Destroy, weak_factory_.GetWeakPtr())); } TrackableObjectBase::~TrackableObjectBase() { @@ -61,8 +63,9 @@ int32_t TrackableObjectBase::GetIDFromWrappedClass(base::SupportsUserData* w) { } // static -void TrackableObjectBase::RegisterDestructionCallback(void (*c)()) { - atom::AtomBrowserMainParts::Get()->RegisterDestructionCallback(base::Bind(c)); +void TrackableObjectBase::RegisterDestructionCallback( + const base::Closure& closure) { + atom::AtomBrowserMainParts::Get()->RegisterDestructionCallback(closure); } } // namespace mate diff --git a/atom/browser/api/trackable_object.h b/atom/browser/api/trackable_object.h index 656904cc45d0..8ff7d1c04041 100644 --- a/atom/browser/api/trackable_object.h +++ b/atom/browser/api/trackable_object.h @@ -9,7 +9,9 @@ #include "atom/browser/api/event_emitter.h" #include "atom/common/id_weak_map.h" +#include "base/bind.h" #include "base/memory/scoped_ptr.h" +#include "base/memory/weak_ptr.h" namespace base { class SupportsUserData; @@ -28,6 +30,9 @@ class TrackableObjectBase : public mate::EventEmitter { // Wrap TrackableObject into a class that SupportsUserData. void AttachAsUserData(base::SupportsUserData* wrapped); + // Subclasses should implement this to destroy their native types. + virtual void Destroy() = 0; + protected: ~TrackableObjectBase() override; @@ -39,12 +44,14 @@ class TrackableObjectBase : public mate::EventEmitter { // Register a callback that should be destroyed before JavaScript environment // gets destroyed. - static void RegisterDestructionCallback(void (*callback)()); + static void RegisterDestructionCallback(const base::Closure& closure); int32_t weak_map_id_; base::SupportsUserData* wrapped_; private: + base::WeakPtrFactory weak_factory_; + DISALLOW_COPY_AND_ASSIGN(TrackableObjectBase); }; @@ -85,7 +92,8 @@ class TrackableObject : public TrackableObjectBase { } TrackableObject() { - RegisterDestructionCallback(&TrackableObject::ReleaseAllWeakReferences); + RegisterDestructionCallback( + base::Bind(&TrackableObject::ReleaseAllWeakReferences)); } // Removes this instance from the weak map. diff --git a/atom/browser/atom_browser_client.cc b/atom/browser/atom_browser_client.cc index fad952d53365..e45caceab01e 100644 --- a/atom/browser/atom_browser_client.cc +++ b/atom/browser/atom_browser_client.cc @@ -15,8 +15,7 @@ #include "atom/browser/atom_speech_recognition_manager_delegate.h" #include "atom/browser/browser.h" #include "atom/browser/native_window.h" -#include "atom/browser/web_view_manager.h" -#include "atom/browser/web_view_constants.h" +#include "atom/browser/web_contents_preferences.h" #include "atom/browser/window_list.h" #include "atom/common/options_switches.h" #include "base/command_line.h" @@ -38,6 +37,7 @@ #include "net/ssl/ssl_cert_request_info.h" #include "ppapi/host/ppapi_host.h" #include "ui/base/l10n/l10n_util.h" +#include "v8/include/v8.h" namespace atom { @@ -54,37 +54,6 @@ bool g_suppress_renderer_process_restart = false; // Custom schemes to be registered to standard. std::string g_custom_schemes = ""; -// Find out the owner of the child process according to |process_id|. -enum ProcessOwner { - OWNER_NATIVE_WINDOW, - OWNER_GUEST_WEB_CONTENTS, - OWNER_NONE, // it might be devtools though. -}; - -ProcessOwner GetProcessOwner(int process_id, - NativeWindow** window, - WebViewManager::WebViewInfo* info) { - content::WebContents* web_contents = content::WebContents::FromRenderViewHost( - content::RenderViewHost::FromID(process_id, kDefaultRoutingID)); - if (!web_contents) - return OWNER_NONE; - - // First search for NativeWindow. - *window = NativeWindow::FromWebContents(web_contents); - if (*window) - return OWNER_NATIVE_WINDOW; - - // Then search for guest WebContents. - auto data = static_cast( - web_contents->GetUserData(web_view::kWebViewInfoKeyName)); - if (data) { - *info = data->web_view_info(); - return OWNER_GUEST_WEB_CONTENTS; - } - - return OWNER_NONE; -} - scoped_refptr ImportCertFromFile( const base::FilePath& path) { if (path.empty()) @@ -160,16 +129,7 @@ void AtomBrowserClient::OverrideWebkitPrefs( // Custom preferences of guest page. auto web_contents = content::WebContents::FromRenderViewHost(host); - auto info = static_cast( - web_contents->GetUserData(web_view::kWebViewInfoKeyName)); - if (info) { - prefs->web_security_enabled = !info->web_view_info().disable_web_security; - return; - } - - NativeWindow* window = NativeWindow::FromWebContents(web_contents); - if (window) - window->OverrideWebkitPrefs(prefs); + WebContentsPreferences::OverrideWebkitPrefs(web_contents, prefs); } std::string AtomBrowserClient::GetApplicationLocale() { @@ -225,23 +185,14 @@ void AtomBrowserClient::AppendExtraCommandLineSwitches( if (ContainsKey(pending_processes_, process_id)) process_id = pending_processes_[process_id]; - NativeWindow* window; - WebViewManager::WebViewInfo info; - ProcessOwner owner = GetProcessOwner(process_id, &window, &info); + // Get the WebContents of the render process. + content::WebContents* web_contents = content::WebContents::FromRenderViewHost( + content::RenderViewHost::FromID(process_id, kDefaultRoutingID)); + if (!web_contents) + return; - if (owner == OWNER_NATIVE_WINDOW) { - window->AppendExtraCommandLineSwitches(command_line); - } else if (owner == OWNER_GUEST_WEB_CONTENTS) { - command_line->AppendSwitchASCII( - switches::kGuestInstanceID, base::IntToString(info.guest_instance_id)); - command_line->AppendSwitchASCII( - switches::kNodeIntegration, info.node_integration ? "true" : "false"); - if (info.plugins) - command_line->AppendSwitch(switches::kEnablePlugins); - if (!info.preload_script.empty()) - command_line->AppendSwitchPath( - switches::kPreloadScript, info.preload_script); - } + WebContentsPreferences::AppendExtraCommandLineSwitches( + web_contents, command_line); } void AtomBrowserClient::DidCreatePpapiPlugin( diff --git a/atom/browser/atom_browser_context.cc b/atom/browser/atom_browser_context.cc index 583a6324a8f5..d1ef09e70ff6 100644 --- a/atom/browser/atom_browser_context.cc +++ b/atom/browser/atom_browser_context.cc @@ -56,8 +56,10 @@ std::string RemoveWhitespace(const std::string& str) { } // namespace -AtomBrowserContext::AtomBrowserContext() - : job_factory_(new AtomURLRequestJobFactory) { +AtomBrowserContext::AtomBrowserContext(const std::string& partition, + bool in_memory) + : brightray::BrowserContext(partition, in_memory), + job_factory_(new AtomURLRequestJobFactory) { } AtomBrowserContext::~AtomBrowserContext() { @@ -150,7 +152,7 @@ AtomBrowserContext::GetDownloadManagerDelegate() { content::BrowserPluginGuestManager* AtomBrowserContext::GetGuestManager() { if (!guest_manager_) - guest_manager_.reset(new WebViewManager(this)); + guest_manager_.reset(new WebViewManager); return guest_manager_.get(); } @@ -162,3 +164,13 @@ void AtomBrowserContext::RegisterPrefs(PrefRegistrySimple* pref_registry) { } } // namespace atom + +namespace brightray { + +// static +scoped_refptr BrowserContext::Create( + const std::string& partition, bool in_memory) { + return make_scoped_refptr(new atom::AtomBrowserContext(partition, in_memory)); +} + +} // namespace brightray diff --git a/atom/browser/atom_browser_context.h b/atom/browser/atom_browser_context.h index c1ff613b8c07..c99461ad9a86 100644 --- a/atom/browser/atom_browser_context.h +++ b/atom/browser/atom_browser_context.h @@ -17,8 +17,8 @@ class WebViewManager; class AtomBrowserContext : public brightray::BrowserContext { public: - AtomBrowserContext(); - virtual ~AtomBrowserContext(); + AtomBrowserContext(const std::string& partition, bool in_memory); + ~AtomBrowserContext() override; // brightray::URLRequestContextGetter::Delegate: std::string GetUserAgent() override; @@ -41,7 +41,8 @@ class AtomBrowserContext : public brightray::BrowserContext { scoped_ptr download_manager_delegate_; scoped_ptr guest_manager_; - AtomURLRequestJobFactory* job_factory_; // Weak reference. + // Managed by brightray::BrowserContext. + AtomURLRequestJobFactory* job_factory_; DISALLOW_COPY_AND_ASSIGN(AtomBrowserContext); }; diff --git a/atom/browser/atom_browser_main_parts.cc b/atom/browser/atom_browser_main_parts.cc index 4463115cfee5..a1a1192b2768 100644 --- a/atom/browser/atom_browser_main_parts.cc +++ b/atom/browser/atom_browser_main_parts.cc @@ -13,6 +13,7 @@ #include "atom/browser/node_debugger.h" #include "atom/common/api/atom_bindings.h" #include "atom/common/node_bindings.h" +#include "atom/common/node_includes.h" #include "base/command_line.h" #include "base/thread_task_runner_handle.h" #include "chrome/browser/browser_process.h" @@ -22,27 +23,8 @@ #include "chrome/browser/ui/libgtk2ui/gtk2_util.h" #endif -#include "atom/common/node_includes.h" - namespace atom { -namespace { - -const base::FilePath::CharType kStoragePartitionDirname[] = "Partitions"; - -void GetStoragePartitionConfig(const GURL& partition, - base::FilePath* partition_path, - bool* in_memory, - std::string* id) { - *in_memory = (partition.path() != "/persist"); - net::UnescapeRule::Type flags = - net::UnescapeRule::SPACES | net::UnescapeRule::URL_SPECIAL_CHARS; - *id = net::UnescapeURLComponent(partition.query(), flags); - *partition_path = base::FilePath(kStoragePartitionDirname).AppendASCII(*id); -} - -} // namespace - // static AtomBrowserMainParts* AtomBrowserMainParts::self_ = NULL; @@ -57,8 +39,6 @@ AtomBrowserMainParts::AtomBrowserMainParts() } AtomBrowserMainParts::~AtomBrowserMainParts() { - for (const auto& callback : destruction_callbacks_) - callback.Run(); } // static @@ -67,30 +47,11 @@ AtomBrowserMainParts* AtomBrowserMainParts::Get() { return self_; } -content::BrowserContext* AtomBrowserMainParts::GetBrowserContextForPartition( - const GURL& partition) { - std::string id; - bool in_memory; - base::FilePath partition_path; - GetStoragePartitionConfig(partition, &partition_path, &in_memory, &id); - if (browser_context_map_.contains(id)) - return browser_context_map_.get(id); - - scoped_ptr browser_context(CreateBrowserContext()); - browser_context->Initialize(partition_path.value(), in_memory); - browser_context_map_.set(id, browser_context.Pass()); - return browser_context_map_.get(id); -} - void AtomBrowserMainParts::RegisterDestructionCallback( const base::Closure& callback) { destruction_callbacks_.push_back(callback); } -brightray::BrowserContext* AtomBrowserMainParts::CreateBrowserContext() { - return new AtomBrowserContext(); -} - void AtomBrowserMainParts::PostEarlyInitialization() { brightray::BrowserMainParts::PostEarlyInitialization(); @@ -155,4 +116,14 @@ void AtomBrowserMainParts::PreMainMessageLoopRun() { #endif } +void AtomBrowserMainParts::PostMainMessageLoopRun() { + brightray::BrowserMainParts::PostMainMessageLoopRun(); + + // 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(); +} + } // namespace atom diff --git a/atom/browser/atom_browser_main_parts.h b/atom/browser/atom_browser_main_parts.h index d952f432882f..bcebc86f16ca 100644 --- a/atom/browser/atom_browser_main_parts.h +++ b/atom/browser/atom_browser_main_parts.h @@ -6,11 +6,9 @@ #define ATOM_BROWSER_ATOM_BROWSER_MAIN_PARTS_H_ #include -#include #include #include "base/callback.h" -#include "base/containers/scoped_ptr_hash_map.h" #include "base/timer/timer.h" #include "brightray/browser/browser_main_parts.h" #include "content/public/browser/browser_context.h" @@ -33,10 +31,6 @@ class AtomBrowserMainParts : public brightray::BrowserMainParts { static AtomBrowserMainParts* Get(); - // Returns the BrowserContext associated with the partition. - content::BrowserContext* GetBrowserContextForPartition( - const GURL& partition); - // Register a callback that should be destroyed before JavaScript environment // gets destroyed. void RegisterDestructionCallback(const base::Closure& callback); @@ -44,12 +38,10 @@ class AtomBrowserMainParts : public brightray::BrowserMainParts { Browser* browser() { return browser_.get(); } protected: - // Implementations of brightray::BrowserMainParts. - brightray::BrowserContext* CreateBrowserContext() override; - - // Implementations of content::BrowserMainParts. + // content::BrowserMainParts: void PostEarlyInitialization() override; void PreMainMessageLoopRun() override; + void PostMainMessageLoopRun() override; #if defined(OS_MACOSX) void PreMainMessageLoopStart() override; void PostDestroyThreads() override; @@ -78,10 +70,6 @@ class AtomBrowserMainParts : public brightray::BrowserMainParts { // List of callbacks should be executed before destroying JS env. std::list destruction_callbacks_; - // partition_id => browser_context - base::ScopedPtrHashMap> - browser_context_map_; - static AtomBrowserMainParts* self_; DISALLOW_COPY_AND_ASSIGN(AtomBrowserMainParts); diff --git a/atom/browser/browser.cc b/atom/browser/browser.cc index 3419ecbe330d..9d2a9fc1effb 100644 --- a/atom/browser/browser.cc +++ b/atom/browser/browser.cc @@ -94,8 +94,10 @@ void Browser::OpenURL(const std::string& url) { FOR_EACH_OBSERVER(BrowserObserver, observers_, OnOpenURL(url)); } -void Browser::ActivateWithNoOpenWindows() { - FOR_EACH_OBSERVER(BrowserObserver, observers_, OnActivateWithNoOpenWindows()); +void Browser::Activate(bool has_visible_windows) { + FOR_EACH_OBSERVER(BrowserObserver, + observers_, + OnActivate(has_visible_windows)); } void Browser::WillFinishLaunching() { diff --git a/atom/browser/browser.h b/atom/browser/browser.h index dc412cefb046..d135556b8760 100644 --- a/atom/browser/browser.h +++ b/atom/browser/browser.h @@ -108,8 +108,9 @@ class Browser : public WindowListObserver { // Tell the application to open a url. void OpenURL(const std::string& url); - // Tell the application that application is activated with no open windows. - void ActivateWithNoOpenWindows(); + // Tell the application that application is activated with visible/invisible + // windows. + void Activate(bool has_visible_windows); // Tell the application the loading has been done. void WillFinishLaunching(); diff --git a/atom/browser/browser_observer.h b/atom/browser/browser_observer.h index 20fd08a2e911..45e86e620f84 100644 --- a/atom/browser/browser_observer.h +++ b/atom/browser/browser_observer.h @@ -43,9 +43,9 @@ class BrowserObserver { // Browser is used to open a url. virtual void OnOpenURL(const std::string& url) {} - // The browser is activated with no open windows (usually by clicking on the - // dock icon). - virtual void OnActivateWithNoOpenWindows() {} + // The browser is activated with visible/invisible windows (usually by + // clicking on the dock icon). + virtual void OnActivate(bool has_visible_windows) {} // The browser has finished loading. virtual void OnWillFinishLaunching() {} diff --git a/atom/browser/lib/chrome-extension.coffee b/atom/browser/lib/chrome-extension.coffee index df0d717cd9dd..15f7bfd54c56 100644 --- a/atom/browser/lib/chrome-extension.coffee +++ b/atom/browser/lib/chrome-extension.coffee @@ -32,6 +32,7 @@ getExtensionInfoFromPath = (srcDirectory) -> startPage: page name: manifest.name srcDirectory: srcDirectory + exposeExperimentalAPIs: true extensionInfoMap[manifest.name] # The loaded extensions cache and its persistent path. diff --git a/atom/browser/lib/guest-view-manager.coffee b/atom/browser/lib/guest-view-manager.coffee index 581274699085..1c05b65b2dc0 100644 --- a/atom/browser/lib/guest-view-manager.coffee +++ b/atom/browser/lib/guest-view-manager.coffee @@ -38,29 +38,12 @@ moveLastToFirst = (list) -> getNextInstanceId = (webContents) -> ++nextInstanceId -# Generate URL encoded partition id. -getPartitionId = (partition) -> - # Guest site url will be chrome-guest://fake-host/{persist}?{partitionId} - partitionId = "chrome-guest://fake-host/" - if partition - persist = partition.startsWith('persist:') - if persist - partition = partition.substring('persist:'.length) - partitionId += 'persist?' - else - # Just to differentiate from same persistant ID - partition += "_temp" - partitionId += '?' - partitionId += encodeURIComponent(partition) - return partitionId - # Create a new guest instance. createGuest = (embedder, params) -> webViewManager ?= process.atomBinding 'web_view_manager' id = getNextInstanceId embedder - partitionId = getPartitionId params.partition - guest = webContents.create {isGuest: true, partition: partitionId, embedder} + guest = webContents.create {isGuest: true, partition: params.partition, embedder} guestInstances[id] = {guest, embedder} # Destroy guest when the embedder is gone or navigated. @@ -132,12 +115,13 @@ attachGuest = (embedder, elementInstanceId, guestInstanceId, params) -> return unless guestInstances[oldGuestInstanceId]? destroyGuest embedder, oldGuestInstanceId - webViewManager.addGuest guestInstanceId, elementInstanceId, embedder, guest, - nodeIntegration: params.nodeintegration - plugins: params.plugins - disableWebSecurity: params.disablewebsecurity - preloadUrl: params.preload ? '' - partitionId: getPartitionId(params.partition) + webPreferences = + 'guest-instance-id': guestInstanceId + 'node-integration': params.nodeintegration ? false + 'plugins': params.plugins + 'web-security': !params.disablewebsecurity + webPreferences['preload-url'] = params.preload if params.preload + webViewManager.addGuest guestInstanceId, elementInstanceId, embedder, guest, webPreferences guest.attachParams = params embedderElementsMap[key] = guestInstanceId diff --git a/atom/browser/mac/atom_application_delegate.mm b/atom/browser/mac/atom_application_delegate.mm index 16dcf6fd9523..a18d2fe40fcd 100644 --- a/atom/browser/mac/atom_application_delegate.mm +++ b/atom/browser/mac/atom_application_delegate.mm @@ -52,12 +52,8 @@ - (BOOL)applicationShouldHandleReopen:(NSApplication*)theApplication hasVisibleWindows:(BOOL)flag { atom::Browser* browser = atom::Browser::Get(); - if (flag) { - return YES; - } else { - browser->ActivateWithNoOpenWindows(); - return NO; - } + browser->Activate(static_cast(flag)); + return flag; } @end diff --git a/atom/browser/native_window.cc b/atom/browser/native_window.cc index 96085846bca8..f40f7de8dbc3 100644 --- a/atom/browser/native_window.cc +++ b/atom/browser/native_window.cc @@ -15,12 +15,10 @@ #include "atom/common/native_mate_converters/image_converter.h" #include "atom/common/native_mate_converters/file_path_converter.h" #include "atom/common/options_switches.h" -#include "base/command_line.h" #include "base/files/file_util.h" #include "base/json/json_writer.h" #include "base/prefs/pref_service.h" #include "base/message_loop/message_loop.h" -#include "base/strings/string_number_conversions.h" #include "base/strings/utf_string_conversions.h" #include "brightray/browser/inspectable_web_contents.h" #include "brightray/browser/inspectable_web_contents_view.h" @@ -31,8 +29,6 @@ #include "content/public/browser/render_view_host.h" #include "content/public/browser/render_widget_host_view.h" #include "content/public/common/content_switches.h" -#include "content/public/common/renderer_preferences.h" -#include "content/public/common/web_preferences.h" #include "ipc/ipc_message_macros.h" #include "native_mate/dictionary.h" #include "ui/gfx/codec/png_codec.h" @@ -43,10 +39,6 @@ #include "ui/gfx/screen.h" #include "ui/gl/gpu_switching_manager.h" -#if defined(OS_WIN) -#include "ui/gfx/switches.h" -#endif - using content::NavigationEntry; using content::RenderWidgetHostView; using content::RenderWidgetHost; @@ -57,17 +49,6 @@ namespace atom { namespace { -// Array of available web runtime features. -const char* kWebRuntimeFeatures[] = { - switches::kExperimentalFeatures, - switches::kExperimentalCanvasFeatures, - switches::kSubpixelFontScaling, - switches::kOverlayScrollbars, - switches::kOverlayFullscreenVideo, - switches::kSharedWorker, - switches::kPageVisibility, -}; - // Convert draggable regions in raw format to SkRegion format. Caller is // responsible for deleting the returned SkRegion instance. scoped_ptr DraggableRegionsToSkRegion( @@ -94,9 +75,7 @@ NativeWindow::NativeWindow( transparent_(false), enable_larger_than_screen_(false), is_closed_(false), - node_integration_(true), has_dialog_attached_(false), - zoom_factor_(1.0), aspect_ratio_(0.0), inspectable_web_contents_(inspectable_web_contents), weak_factory_(this) { @@ -105,7 +84,6 @@ NativeWindow::NativeWindow( options.Get(switches::kFrame, &has_frame_); options.Get(switches::kTransparent, &transparent_); options.Get(switches::kEnableLargerThanScreen, &enable_larger_than_screen_); - options.Get(switches::kNodeIntegration, &node_integration_); // Tell the content module to initialize renderer widget with transparent // mode. @@ -114,25 +92,6 @@ NativeWindow::NativeWindow( // Read icon before window is created. options.Get(switches::kIcon, &icon_); - // The "preload" option must be absolute path. - if (options.Get(switches::kPreloadScript, &preload_script_) && - !preload_script_.IsAbsolute()) { - LOG(ERROR) << "Path of \"preload\" script must be absolute."; - preload_script_.clear(); - } - - // Be compatible with old API of "node-integration" option. - std::string old_string_token; - if (options.Get(switches::kNodeIntegration, &old_string_token) && - old_string_token != "disable") - node_integration_ = true; - - // Read the web preferences. - options.Get(switches::kWebPreferences, &web_preferences_); - - // Read the zoom factor before any navigation. - options.Get(switches::kZoomFactor, &zoom_factor_); - WindowList::AddWindow(this); } @@ -290,6 +249,10 @@ bool NativeWindow::IsWebViewFocused() { return host_view && host_view->HasFocus(); } +bool NativeWindow::IsDevToolsFocused() { + return inspectable_web_contents_->GetView()->IsDevToolsViewFocused(); +} + void NativeWindow::CapturePage(const gfx::Rect& rect, const CapturePageCallback& callback) { const auto view = web_contents()->GetRenderWidgetHostView(); @@ -381,81 +344,6 @@ void NativeWindow::RendererResponsive(content::WebContents* source) { FOR_EACH_OBSERVER(NativeWindowObserver, observers_, OnRendererResponsive()); } -void NativeWindow::AppendExtraCommandLineSwitches( - base::CommandLine* command_line) { - // Append --node-integration to renderer process. - command_line->AppendSwitchASCII(switches::kNodeIntegration, - node_integration_ ? "true" : "false"); - - // Append --preload. - if (!preload_script_.empty()) - command_line->AppendSwitchPath(switches::kPreloadScript, preload_script_); - - // Append --zoom-factor. - if (zoom_factor_ != 1.0) - command_line->AppendSwitchASCII(switches::kZoomFactor, - base::DoubleToString(zoom_factor_)); - - if (web_preferences_.IsEmpty()) - return; - - bool b; -#if defined(OS_WIN) - // Check if DirectWrite is disabled. - if (web_preferences_.Get(switches::kDirectWrite, &b) && !b) - command_line->AppendSwitch(::switches::kDisableDirectWrite); -#endif - - // Check if plugins are enabled. - if (web_preferences_.Get("plugins", &b) && b) - command_line->AppendSwitch(switches::kEnablePlugins); - - // This set of options are not availabe in WebPreferences, so we have to pass - // them via command line and enable them in renderer procss. - for (size_t i = 0; i < arraysize(kWebRuntimeFeatures); ++i) { - const char* feature = kWebRuntimeFeatures[i]; - if (web_preferences_.Get(feature, &b)) - command_line->AppendSwitchASCII(feature, b ? "true" : "false"); - } -} - -void NativeWindow::OverrideWebkitPrefs(content::WebPreferences* prefs) { - if (web_preferences_.IsEmpty()) - return; - - bool b; - std::vector list; - if (web_preferences_.Get("javascript", &b)) - prefs->javascript_enabled = b; - if (web_preferences_.Get("images", &b)) - prefs->images_enabled = b; - if (web_preferences_.Get("java", &b)) - prefs->java_enabled = b; - if (web_preferences_.Get("text-areas-are-resizable", &b)) - prefs->text_areas_are_resizable = b; - if (web_preferences_.Get("webgl", &b)) - prefs->experimental_webgl_enabled = b; - if (web_preferences_.Get("webaudio", &b)) - prefs->webaudio_enabled = b; - if (web_preferences_.Get("web-security", &b)) { - prefs->web_security_enabled = b; - prefs->allow_displaying_insecure_content = !b; - prefs->allow_running_insecure_content = !b; - } - if (web_preferences_.Get("allow-displaying-insecure-content", &b)) - prefs->allow_displaying_insecure_content = b; - if (web_preferences_.Get("allow-running-insecure-content", &b)) - prefs->allow_running_insecure_content = b; - if (web_preferences_.Get("extra-plugin-dirs", &list)) { - if (content::PluginService::GetInstance()->NPAPIPluginsSupported()) { - for (size_t i = 0; i < list.size(); ++i) - content::PluginService::GetInstance()->AddExtraPluginDir(list[i]); - } else { - LOG(WARNING) << "NPAPI plugins not supported on this platform"; - } - } -} - void NativeWindow::NotifyWindowClosed() { if (is_closed_) return; diff --git a/atom/browser/native_window.h b/atom/browser/native_window.h index 10889a5ccaf9..f09845aad348 100644 --- a/atom/browser/native_window.h +++ b/atom/browser/native_window.h @@ -19,23 +19,17 @@ #include "content/public/browser/readback_types.h" #include "content/public/browser/web_contents_observer.h" #include "content/public/browser/web_contents_user_data.h" -#include "native_mate/persistent_dictionary.h" #include "ui/gfx/image/image.h" #include "ui/gfx/image/image_skia.h" class SkRegion; -namespace base { -class CommandLine; -} - namespace brightray { class InspectableWebContents; } namespace content { struct NativeWebKeyboardEvent; -struct WebPreferences; } namespace gfx { @@ -154,6 +148,7 @@ class NativeWindow : public content::WebContentsObserver, virtual void FocusOnWebView(); virtual void BlurWebView(); virtual bool IsWebViewFocused(); + virtual bool IsDevToolsFocused(); // Captures the page with |rect|, |callback| would be called when capturing is // done. @@ -189,10 +184,6 @@ class NativeWindow : public content::WebContentsObserver, content::WebContents*, const content::NativeWebKeyboardEvent& event) {} - // Called when renderer process is going to be started. - void AppendExtraCommandLineSwitches(base::CommandLine* command_line); - void OverrideWebkitPrefs(content::WebPreferences* prefs); - // Public API used by platform-dependent delegates and observers to send UI // related notifications. void NotifyWindowClosed(); @@ -282,9 +273,6 @@ class NativeWindow : public content::WebContentsObserver, // The windows has been closed. bool is_closed_; - // Whether node integration is enabled. - bool node_integration_; - // There is a dialog that has been attached to window. bool has_dialog_attached_; @@ -292,15 +280,6 @@ class NativeWindow : public content::WebContentsObserver, // it should be cancelled when we can prove that the window is responsive. base::CancelableClosure window_unresposive_closure_; - // Web preferences. - mate::PersistentDictionary web_preferences_; - - // The script to load before page's JavaScript starts to run. - base::FilePath preload_script_; - - // Page's default zoom factor. - double zoom_factor_; - // Used to maintain the aspect ratio of a view which is inside of the // content view. double aspect_ratio_; diff --git a/atom/browser/native_window_mac.mm b/atom/browser/native_window_mac.mm index 64f7c11f997b..9555914c899d 100644 --- a/atom/browser/native_window_mac.mm +++ b/atom/browser/native_window_mac.mm @@ -357,6 +357,17 @@ NativeWindowMac::NativeWindowMac( styleMask |= NSTexturedBackgroundWindowMask; } + std::string titleBarStyle = "default"; + options.Get(switches::kTitleBarStyle, &titleBarStyle); + + if (base::mac::IsOSYosemiteOrLater()) { + // New title bar styles are available in Yosemite or newer + if ((titleBarStyle == "hidden") || (titleBarStyle == "hidden-inset")) { + styleMask |= NSFullSizeContentViewWindowMask; + styleMask |= NSUnifiedTitleAndToolbarWindowMask; + } + } + window_.reset([[AtomNSWindow alloc] initWithContentRect:cocoa_bounds styleMask:styleMask @@ -382,6 +393,20 @@ NativeWindowMac::NativeWindowMac( // We will manage window's lifetime ourselves. [window_ setReleasedWhenClosed:NO]; + // Configure title bar look on Yosemite or newer + if (base::mac::IsOSYosemiteOrLater()) { + if ((titleBarStyle == "hidden") || (titleBarStyle == "hidden-inset")) { + [window_ setTitlebarAppearsTransparent:YES]; + [window_ setTitleVisibility:NSWindowTitleHidden]; + if (titleBarStyle == "hidden-inset") { + NSToolbar *toolbar = [[NSToolbar alloc] initWithIdentifier:@"titlebarStylingToolbar"]; + toolbar.showsBaselineSeparator = NO; + [window_ setToolbar:toolbar]; + [toolbar release]; + } + } + } + // On OS X the initial window size doesn't include window frame. bool use_content_size = false; options.Get(switches::kUseContentSize, &use_content_size); diff --git a/atom/browser/net/js_asker.h b/atom/browser/net/js_asker.h index 9c45446abcbb..8ec245ee8c4f 100644 --- a/atom/browser/net/js_asker.h +++ b/atom/browser/net/js_asker.h @@ -46,7 +46,7 @@ class JsAsker : public RequestJob { // Called by |CustomProtocolHandler| to store handler related information. void SetHandlerInfo( v8::Isolate* isolate, - scoped_refptr request_context_getter, + net::URLRequestContextGetter* request_context_getter, const JavaScriptHandler& handler) { isolate_ = isolate; request_context_getter_ = request_context_getter; @@ -57,7 +57,7 @@ class JsAsker : public RequestJob { virtual void StartAsync(scoped_ptr options) = 0; net::URLRequestContextGetter* request_context_getter() const { - return request_context_getter_.get(); + return request_context_getter_; } private: @@ -89,7 +89,7 @@ class JsAsker : public RequestJob { } v8::Isolate* isolate_; - scoped_refptr request_context_getter_; + net::URLRequestContextGetter* request_context_getter_; JavaScriptHandler handler_; base::WeakPtrFactory weak_factory_; diff --git a/atom/browser/net/url_request_buffer_job.cc b/atom/browser/net/url_request_buffer_job.cc index 7eb3aaed243c..affc3dd37d25 100644 --- a/atom/browser/net/url_request_buffer_job.cc +++ b/atom/browser/net/url_request_buffer_job.cc @@ -6,13 +6,15 @@ #include +#include "base/strings/string_number_conversions.h" #include "net/base/net_errors.h" namespace atom { URLRequestBufferJob::URLRequestBufferJob( net::URLRequest* request, net::NetworkDelegate* network_delegate) - : JsAsker(request, network_delegate) { + : JsAsker(request, network_delegate), + status_code_(net::HTTP_NOT_IMPLEMENTED) { } void URLRequestBufferJob::StartAsync(scoped_ptr options) { @@ -36,9 +38,28 @@ void URLRequestBufferJob::StartAsync(scoped_ptr options) { data_ = new base::RefCountedBytes( reinterpret_cast(binary->GetBuffer()), binary->GetSize()); + status_code_ = net::HTTP_OK; net::URLRequestSimpleJob::Start(); } +void URLRequestBufferJob::GetResponseInfo(net::HttpResponseInfo* info) { + std::string status("HTTP/1.1 "); + status.append(base::IntToString(status_code_)); + status.append(" "); + status.append(net::GetHttpReasonPhrase(status_code_)); + status.append("\0\0", 2); + net::HttpResponseHeaders* headers = new net::HttpResponseHeaders(status); + + if (!mime_type_.empty()) { + std::string content_type_header(net::HttpRequestHeaders::kContentType); + content_type_header.append(": "); + content_type_header.append(mime_type_); + headers->AddHeader(content_type_header); + } + + info->headers = headers; +} + int URLRequestBufferJob::GetRefCountedData( std::string* mime_type, std::string* charset, diff --git a/atom/browser/net/url_request_buffer_job.h b/atom/browser/net/url_request_buffer_job.h index e6fecdba8301..ab8de7e8f030 100644 --- a/atom/browser/net/url_request_buffer_job.h +++ b/atom/browser/net/url_request_buffer_job.h @@ -9,6 +9,7 @@ #include "atom/browser/net/js_asker.h" #include "base/memory/ref_counted_memory.h" +#include "net/http/http_status_code.h" #include "net/url_request/url_request_simple_job.h" namespace atom { @@ -20,6 +21,9 @@ class URLRequestBufferJob : public JsAsker { // JsAsker: void StartAsync(scoped_ptr options) override; + // URLRequestJob: + void GetResponseInfo(net::HttpResponseInfo* info) override; + // URLRequestSimpleJob: int GetRefCountedData(std::string* mime_type, std::string* charset, @@ -30,6 +34,7 @@ class URLRequestBufferJob : public JsAsker { std::string mime_type_; std::string charset_; scoped_refptr data_; + net::HttpStatusCode status_code_; DISALLOW_COPY_AND_ASSIGN(URLRequestBufferJob); }; diff --git a/atom/browser/net/url_request_string_job.cc b/atom/browser/net/url_request_string_job.cc index 428a87f54b1e..4a631b813eff 100644 --- a/atom/browser/net/url_request_string_job.cc +++ b/atom/browser/net/url_request_string_job.cc @@ -28,6 +28,20 @@ void URLRequestStringJob::StartAsync(scoped_ptr options) { net::URLRequestSimpleJob::Start(); } +void URLRequestStringJob::GetResponseInfo(net::HttpResponseInfo* info) { + std::string status("HTTP/1.1 200 OK"); + net::HttpResponseHeaders* headers = new net::HttpResponseHeaders(status); + + if (!mime_type_.empty()) { + std::string content_type_header(net::HttpRequestHeaders::kContentType); + content_type_header.append(": "); + content_type_header.append(mime_type_); + headers->AddHeader(content_type_header); + } + + info->headers = headers; +} + int URLRequestStringJob::GetData( std::string* mime_type, std::string* charset, diff --git a/atom/browser/net/url_request_string_job.h b/atom/browser/net/url_request_string_job.h index 713185c0cd1d..e40f0d93dab7 100644 --- a/atom/browser/net/url_request_string_job.h +++ b/atom/browser/net/url_request_string_job.h @@ -19,6 +19,9 @@ class URLRequestStringJob : public JsAsker { // JsAsker: void StartAsync(scoped_ptr options) override; + // URLRequestJob: + void GetResponseInfo(net::HttpResponseInfo* info) override; + // URLRequestSimpleJob: int GetData(std::string* mime_type, std::string* charset, diff --git a/atom/browser/resources/mac/Info.plist b/atom/browser/resources/mac/Info.plist index 73facdc7f565..dd4e610d917e 100644 --- a/atom/browser/resources/mac/Info.plist +++ b/atom/browser/resources/mac/Info.plist @@ -17,7 +17,7 @@ CFBundleIconFile atom.icns CFBundleVersion - 0.31.2 + 0.32.3 LSMinimumSystemVersion 10.8.0 NSMainNibFile diff --git a/atom/browser/resources/win/atom.rc b/atom/browser/resources/win/atom.rc index 7e7fea9f2fb3..cf894f6b5c33 100644 --- a/atom/browser/resources/win/atom.rc +++ b/atom/browser/resources/win/atom.rc @@ -56,8 +56,8 @@ END // VS_VERSION_INFO VERSIONINFO - FILEVERSION 0,31,2,0 - PRODUCTVERSION 0,31,2,0 + FILEVERSION 0,32,3,0 + PRODUCTVERSION 0,32,3,0 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -74,12 +74,12 @@ BEGIN BEGIN VALUE "CompanyName", "GitHub, Inc." VALUE "FileDescription", "Electron" - VALUE "FileVersion", "0.31.2" + VALUE "FileVersion", "0.32.3" VALUE "InternalName", "electron.exe" VALUE "LegalCopyright", "Copyright (C) 2015 GitHub, Inc. All rights reserved." VALUE "OriginalFilename", "electron.exe" VALUE "ProductName", "Electron" - VALUE "ProductVersion", "0.31.2" + VALUE "ProductVersion", "0.32.3" VALUE "SquirrelAwareVersion", "1" END END diff --git a/atom/browser/web_contents_preferences.cc b/atom/browser/web_contents_preferences.cc new file mode 100644 index 000000000000..db55eddf7e2d --- /dev/null +++ b/atom/browser/web_contents_preferences.cc @@ -0,0 +1,154 @@ +// Copyright (c) 2015 GitHub, Inc. +// Use of this source code is governed by the MIT license that can be +// found in the LICENSE file. + +#include "atom/browser/web_contents_preferences.h" + +#include + +#include "atom/common/options_switches.h" +#include "base/command_line.h" +#include "base/strings/string_number_conversions.h" +#include "content/public/common/web_preferences.h" +#include "net/base/filename_util.h" + +#if defined(OS_WIN) +#include "ui/gfx/switches.h" +#endif + +DEFINE_WEB_CONTENTS_USER_DATA_KEY(atom::WebContentsPreferences); + +namespace atom { + +namespace { + +// Array of available web runtime features. +const char* kWebRuntimeFeatures[] = { + switches::kExperimentalFeatures, + switches::kExperimentalCanvasFeatures, + switches::kSubpixelFontScaling, + switches::kOverlayScrollbars, + switches::kOverlayFullscreenVideo, + switches::kSharedWorker, + switches::kPageVisibility, +}; + +} // namespace + +WebContentsPreferences::WebContentsPreferences( + content::WebContents* web_contents, + base::DictionaryValue* web_preferences) { + web_preferences_.Swap(web_preferences); + web_contents->SetUserData(UserDataKey(), this); +} + +WebContentsPreferences::~WebContentsPreferences() { +} + +void WebContentsPreferences::Merge(const base::DictionaryValue& extend) { + web_preferences_.MergeDictionary(&extend); +} + +// static +void WebContentsPreferences::AppendExtraCommandLineSwitches( + content::WebContents* web_contents, base::CommandLine* command_line) { + WebContentsPreferences* self = FromWebContents(web_contents); + if (!self) + return; + + base::DictionaryValue& web_preferences = self->web_preferences_; + + bool b; +#if defined(OS_WIN) + // Check if DirectWrite is disabled. + if (web_preferences.GetBoolean(switches::kDirectWrite, &b) && !b) + command_line->AppendSwitch(::switches::kDisableDirectWrite); +#endif + + // Check if plugins are enabled. + if (web_preferences.GetBoolean("plugins", &b) && b) + command_line->AppendSwitch(switches::kEnablePlugins); + + // This set of options are not availabe in WebPreferences, so we have to pass + // them via command line and enable them in renderer procss. + for (size_t i = 0; i < arraysize(kWebRuntimeFeatures); ++i) { + const char* feature = kWebRuntimeFeatures[i]; + if (web_preferences.GetBoolean(feature, &b)) + command_line->AppendSwitchASCII(feature, b ? "true" : "false"); + } + + // Check if we have node integration specified. + bool node_integration = true; + web_preferences.GetBoolean(switches::kNodeIntegration, &node_integration); + // Be compatible with old API of "node-integration" option. + std::string old_token; + if (web_preferences.GetString(switches::kNodeIntegration, &old_token) && + old_token != "disable") + node_integration = true; + command_line->AppendSwitchASCII(switches::kNodeIntegration, + node_integration ? "true" : "false"); + + // The preload script. + base::FilePath::StringType preload; + if (web_preferences.GetString(switches::kPreloadScript, &preload)) { + if (base::FilePath(preload).IsAbsolute()) + command_line->AppendSwitchNative(switches::kPreloadScript, preload); + else + LOG(ERROR) << "preload script must have abosulute path."; + } else if (web_preferences.GetString(switches::kPreloadUrl, &preload)) { + // Translate to file path if there is "preload-url" option. + base::FilePath preload_path; + if (net::FileURLToFilePath(GURL(preload), &preload_path)) + command_line->AppendSwitchPath(switches::kPreloadScript, preload_path); + else + LOG(ERROR) << "preload url must be file:// protocol."; + } + + // The zoom factor. + double zoom_factor = 1.0; + if (web_preferences.GetDouble(switches::kZoomFactor, &zoom_factor) && + zoom_factor != 1.0) + command_line->AppendSwitchASCII(switches::kZoomFactor, + base::DoubleToString(zoom_factor)); + + // --guest-instance-id, which is used to identify guest WebContents. + int guest_instance_id; + if (web_preferences.GetInteger(switches::kGuestInstanceID, + &guest_instance_id)) + command_line->AppendSwitchASCII(switches::kGuestInstanceID, + base::IntToString(guest_instance_id)); +} + +// static +void WebContentsPreferences::OverrideWebkitPrefs( + content::WebContents* web_contents, content::WebPreferences* prefs) { + WebContentsPreferences* self = FromWebContents(web_contents); + if (!self) + return; + + bool b; + if (self->web_preferences_.GetBoolean("javascript", &b)) + prefs->javascript_enabled = b; + if (self->web_preferences_.GetBoolean("images", &b)) + prefs->images_enabled = b; + if (self->web_preferences_.GetBoolean("java", &b)) + prefs->java_enabled = b; + if (self->web_preferences_.GetBoolean("text-areas-are-resizable", &b)) + prefs->text_areas_are_resizable = b; + if (self->web_preferences_.GetBoolean("webgl", &b)) + prefs->experimental_webgl_enabled = b; + if (self->web_preferences_.GetBoolean("webaudio", &b)) + prefs->webaudio_enabled = b; + if (self->web_preferences_.GetBoolean("web-security", &b)) { + prefs->web_security_enabled = b; + prefs->allow_displaying_insecure_content = !b; + prefs->allow_running_insecure_content = !b; + } + if (self->web_preferences_.GetBoolean("allow-displaying-insecure-content", + &b)) + prefs->allow_displaying_insecure_content = b; + if (self->web_preferences_.GetBoolean("allow-running-insecure-content", &b)) + prefs->allow_running_insecure_content = b; +} + +} // namespace atom diff --git a/atom/browser/web_contents_preferences.h b/atom/browser/web_contents_preferences.h new file mode 100644 index 000000000000..83b485f449bc --- /dev/null +++ b/atom/browser/web_contents_preferences.h @@ -0,0 +1,50 @@ +// Copyright (c) 2015 GitHub, Inc. +// Use of this source code is governed by the MIT license that can be +// found in the LICENSE file. + +#ifndef ATOM_BROWSER_WEB_CONTENTS_PREFERENCES_H_ +#define ATOM_BROWSER_WEB_CONTENTS_PREFERENCES_H_ + +#include "base/values.h" +#include "content/public/browser/web_contents_user_data.h" + +namespace base { +class CommandLine; +} + +namespace content { +struct WebPreferences; +} + +namespace atom { + +// Stores and applies the preferences of WebContents. +class WebContentsPreferences + : public content::WebContentsUserData { + public: + // Append command paramters according to |web_contents|'s preferences. + static void AppendExtraCommandLineSwitches( + content::WebContents* web_contents, base::CommandLine* command_line); + + // Modify the WebPreferences according to |web_contents|'s preferences. + static void OverrideWebkitPrefs( + content::WebContents* web_contents, content::WebPreferences* prefs); + + WebContentsPreferences(content::WebContents* web_contents, + base::DictionaryValue* web_preferences); + ~WebContentsPreferences() override; + + // $.extend(|web_preferences_|, |new_web_preferences|). + void Merge(const base::DictionaryValue& new_web_preferences); + + private: + friend class content::WebContentsUserData; + + base::DictionaryValue web_preferences_; + + DISALLOW_COPY_AND_ASSIGN(WebContentsPreferences); +}; + +} // namespace atom + +#endif // ATOM_BROWSER_WEB_CONTENTS_PREFERENCES_H_ diff --git a/atom/browser/web_view_constants.cc b/atom/browser/web_view_constants.cc deleted file mode 100644 index 6f8314cbcf36..000000000000 --- a/atom/browser/web_view_constants.cc +++ /dev/null @@ -1,24 +0,0 @@ -// Copyright (c) 2015 GitHub, Inc. -// Use of this source code is governed by the MIT license that can be -// found in the LICENSE file. - -#include "atom/browser/web_view_constants.h" - -namespace atom { - -namespace web_view { - -const char kPreloadUrl[] = "preloadUrl"; -const char kNodeIntegration[] = "nodeIntegration"; -const char kPlugins[] = "plugins"; -const char kDisableWebSecurity[] = "disableWebSecurity"; -const char kPartitionId[] = "partitionId"; - -const int kDefaultWidth = 300; -const int kDefaultHeight = 300; - -const char kWebViewInfoKeyName[] = "web_view_info"; - -} // namespace web_view - -} // namespace atom diff --git a/atom/browser/web_view_constants.h b/atom/browser/web_view_constants.h deleted file mode 100644 index 0831bdbdf1d4..000000000000 --- a/atom/browser/web_view_constants.h +++ /dev/null @@ -1,27 +0,0 @@ -// Copyright (c) 2015 GitHub, Inc. -// Use of this source code is governed by the MIT license that can be -// found in the LICENSE file. - -#ifndef ATOM_BROWSER_WEB_VIEW_CONSTANTS_H_ -#define ATOM_BROWSER_WEB_VIEW_CONSTANTS_H_ - -namespace atom { - -namespace web_view { - -extern const char kPreloadUrl[]; -extern const char kNodeIntegration[]; -extern const char kPlugins[]; -extern const char kDisableWebSecurity[]; -extern const char kPartitionId[]; - -extern const int kDefaultWidth; -extern const int kDefaultHeight; - -extern const char kWebViewInfoKeyName[]; - -} // namespace web_view - -} // namespace atom - -#endif // ATOM_BROWSER_WEB_VIEW_CONSTANTS_H_ diff --git a/atom/browser/web_view_guest_delegate.cc b/atom/browser/web_view_guest_delegate.cc index a954cea8dc02..8e1810c4a39b 100644 --- a/atom/browser/web_view_guest_delegate.cc +++ b/atom/browser/web_view_guest_delegate.cc @@ -5,7 +5,6 @@ #include "atom/browser/web_view_guest_delegate.h" #include "atom/browser/api/atom_api_web_contents.h" -#include "atom/browser/web_view_constants.h" #include "atom/common/native_mate_converters/gurl_converter.h" #include "content/public/browser/guest_host.h" #include "content/public/browser/render_frame_host.h" @@ -14,6 +13,13 @@ namespace atom { +namespace { + +const int kDefaultWidth = 300; +const int kDefaultHeight = 300; + +} // namespace + WebViewGuestDelegate::WebViewGuestDelegate() : guest_opaque_(true), guest_host_(nullptr), @@ -172,7 +178,7 @@ gfx::Size WebViewGuestDelegate::GetDefaultSize() const { return embedder_web_contents_->GetRenderWidgetHostView() ->GetVisibleViewportSize(); } else { - return gfx::Size(web_view::kDefaultWidth, web_view::kDefaultHeight); + return gfx::Size(kDefaultWidth, kDefaultHeight); } } diff --git a/atom/browser/web_view_manager.cc b/atom/browser/web_view_manager.cc index 9d0b9337599f..d404c1a43680 100644 --- a/atom/browser/web_view_manager.cc +++ b/atom/browser/web_view_manager.cc @@ -5,13 +5,12 @@ #include "atom/browser/web_view_manager.h" #include "atom/browser/atom_browser_context.h" -#include "atom/browser/atom_browser_main_parts.h" #include "content/public/browser/render_process_host.h" #include "content/public/browser/web_contents.h" namespace atom { -WebViewManager::WebViewManager(content::BrowserContext* context) { +WebViewManager::WebViewManager() { } WebViewManager::~WebViewManager() { @@ -21,7 +20,6 @@ void WebViewManager::AddGuest(int guest_instance_id, int element_instance_id, content::WebContents* embedder, content::WebContents* web_contents) { - base::AutoLock auto_lock(lock_); web_contents_embedder_map_[guest_instance_id] = { web_contents, embedder }; // Map the element in embedder to guest. @@ -31,7 +29,6 @@ void WebViewManager::AddGuest(int guest_instance_id, } void WebViewManager::RemoveGuest(int guest_instance_id) { - base::AutoLock auto_lock(lock_); if (!ContainsKey(web_contents_embedder_map_, guest_instance_id)) return; diff --git a/atom/browser/web_view_manager.h b/atom/browser/web_view_manager.h index 20c044849720..ff9a8ecba2ab 100644 --- a/atom/browser/web_view_manager.h +++ b/atom/browser/web_view_manager.h @@ -7,45 +7,14 @@ #include -#include "base/files/file_path.h" -#include "base/supports_user_data.h" -#include "base/synchronization/lock.h" #include "content/public/browser/browser_plugin_guest_manager.h" -#include "content/public/browser/site_instance.h" - -namespace content { -class BrowserContext; -class RenderProcessHost; -} namespace atom { class WebViewManager : public content::BrowserPluginGuestManager { public: - struct WebViewInfo { - int guest_instance_id; - content::WebContents* embedder; - bool node_integration; - bool plugins; - bool disable_web_security; - base::FilePath preload_script; - GURL partition_id; - }; - - class WebViewInfoUserData : public base::SupportsUserData::Data { - public: - explicit WebViewInfoUserData(WebViewInfo info) - : web_view_info_(info) {} - ~WebViewInfoUserData() override {} - - WebViewInfo& web_view_info() { return web_view_info_; } - - private: - WebViewInfo web_view_info_; - }; - - explicit WebViewManager(content::BrowserContext* context); - virtual ~WebViewManager(); + WebViewManager(); + ~WebViewManager() override; void AddGuest(int guest_instance_id, int element_instance_id, @@ -90,8 +59,6 @@ class WebViewManager : public content::BrowserPluginGuestManager { // (embedder_process_id, element_instance_id) => guest_instance_id std::map element_instance_id_to_guest_map_; - base::Lock lock_; - DISALLOW_COPY_AND_ASSIGN(WebViewManager); }; diff --git a/atom/common/api/atom_api_asar.cc b/atom/common/api/atom_api_asar.cc index 24e9ce9b0668..4ea7d8c5c362 100644 --- a/atom/common/api/atom_api_asar.cc +++ b/atom/common/api/atom_api_asar.cc @@ -10,13 +10,12 @@ #include "atom/common/asar/archive.h" #include "atom/common/native_mate_converters/callback.h" #include "atom/common/native_mate_converters/file_path_converter.h" +#include "atom/common/node_includes.h" #include "native_mate/arguments.h" #include "native_mate/dictionary.h" #include "native_mate/object_template_builder.h" #include "native_mate/wrappable.h" -#include "atom/common/node_includes.h" - namespace { class Archive : public mate::Wrappable { diff --git a/atom/common/api/atom_api_shell.cc b/atom/common/api/atom_api_shell.cc index 013c5f5c6c84..a4599ee0c359 100644 --- a/atom/common/api/atom_api_shell.cc +++ b/atom/common/api/atom_api_shell.cc @@ -7,9 +7,8 @@ #include "atom/common/platform_util.h" #include "atom/common/native_mate_converters/file_path_converter.h" #include "atom/common/native_mate_converters/gurl_converter.h" -#include "native_mate/dictionary.h" - #include "atom/common/node_includes.h" +#include "native_mate/dictionary.h" namespace { diff --git a/atom/common/api/atom_api_v8_util.cc b/atom/common/api/atom_api_v8_util.cc index 21f23a97b456..bba3399a8dbd 100644 --- a/atom/common/api/atom_api_v8_util.cc +++ b/atom/common/api/atom_api_v8_util.cc @@ -3,11 +3,10 @@ // found in the LICENSE file. #include "atom/common/api/object_life_monitor.h" +#include "atom/common/node_includes.h" #include "native_mate/dictionary.h" #include "v8/include/v8-profiler.h" -#include "atom/common/node_includes.h" - namespace { v8::Local CreateObjectWithName(v8::Isolate* isolate, diff --git a/atom/common/api/event_emitter_caller.cc b/atom/common/api/event_emitter_caller.cc index 6b0a07ad414a..94eb9ce9e79a 100644 --- a/atom/common/api/event_emitter_caller.cc +++ b/atom/common/api/event_emitter_caller.cc @@ -5,11 +5,10 @@ #include "atom/common/api/event_emitter_caller.h" #include "atom/common/api/locker.h" +#include "atom/common/node_includes.h" #include "base/memory/scoped_ptr.h" #include "third_party/WebKit/public/web/WebScopedMicrotaskSuppression.h" -#include "atom/common/node_includes.h" - namespace mate { namespace internal { diff --git a/atom/common/atom_version.h b/atom/common/atom_version.h index a0b865b0e2a6..8d71e9150540 100644 --- a/atom/common/atom_version.h +++ b/atom/common/atom_version.h @@ -6,8 +6,8 @@ #define ATOM_VERSION_H #define ATOM_MAJOR_VERSION 0 -#define ATOM_MINOR_VERSION 31 -#define ATOM_PATCH_VERSION 2 +#define ATOM_MINOR_VERSION 32 +#define ATOM_PATCH_VERSION 3 #define ATOM_VERSION_IS_RELEASE 1 diff --git a/atom/common/lib/init.coffee b/atom/common/lib/init.coffee index 88b32d8c0254..4bc3e36986c0 100644 --- a/atom/common/lib/init.coffee +++ b/atom/common/lib/init.coffee @@ -37,13 +37,18 @@ wrapWithActivateUvLoop = (func) -> process.activateUvLoop() func.apply this, arguments process.nextTick = wrapWithActivateUvLoop process.nextTick -global.setImmediate = wrapWithActivateUvLoop timers.setImmediate -global.clearImmediate = timers.clearImmediate -# setTimeout needs to update the polling timeout of the event loop, when called -# under Chromium's event loop the node's event loop won't get a chance to update -# the timeout, so we have to force the node's event loop to recalculate the -# timeout in browser process. if process.type is 'browser' + # setTimeout needs to update the polling timeout of the event loop, when + # called under Chromium's event loop the node's event loop won't get a chance + # to update the timeout, so we have to force the node's event loop to + # recalculate the timeout in browser process. global.setTimeout = wrapWithActivateUvLoop timers.setTimeout global.setInterval = wrapWithActivateUvLoop timers.setInterval + global.setImmediate = wrapWithActivateUvLoop timers.setImmediate + global.clearImmediate = wrapWithActivateUvLoop timers.clearImmediate +else + # There are no setImmediate under renderer process by default, so we need to + # manually setup them here. + global.setImmediate = setImmediate + global.clearImmediate = clearImmediate diff --git a/atom/common/node_bindings.cc b/atom/common/node_bindings.cc index 09666a470b6c..5aec200550ad 100644 --- a/atom/common/node_bindings.cc +++ b/atom/common/node_bindings.cc @@ -11,6 +11,7 @@ #include "atom/common/api/locker.h" #include "atom/common/atom_command_line.h" #include "atom/common/native_mate_converters/file_path_converter.h" +#include "atom/common/node_includes.h" #include "base/command_line.h" #include "base/base_paths.h" #include "base/files/file_path.h" @@ -21,8 +22,6 @@ #include "native_mate/dictionary.h" #include "third_party/WebKit/public/web/WebScopedMicrotaskSuppression.h" -#include "atom/common/node_includes.h" - using content::BrowserThread; // Force all builtin modules to be referenced so they can actually run their diff --git a/atom/common/node_includes.h b/atom/common/node_includes.h index 0c4189b2fac3..3876d8622913 100644 --- a/atom/common/node_includes.h +++ b/atom/common/node_includes.h @@ -5,6 +5,8 @@ #ifndef ATOM_COMMON_NODE_INCLUDES_H_ #define ATOM_COMMON_NODE_INCLUDES_H_ +#include "base/logging.h" + // Include common headers for using node APIs. #define BUILDING_NODE_EXTENSION diff --git a/atom/common/options_switches.cc b/atom/common/options_switches.cc index 8f457116ec3a..c70e1ba4afa6 100644 --- a/atom/common/options_switches.cc +++ b/atom/common/options_switches.cc @@ -42,6 +42,9 @@ const char kAcceptFirstMouse[] = "accept-first-mouse"; // Whether window size should include window frame. const char kUseContentSize[] = "use-content-size"; +// The requested title bar style for the window +const char kTitleBarStyle[] = "title-bar-style"; + // The WebPreferences. const char kWebPreferences[] = "web-preferences"; @@ -75,6 +78,9 @@ const char kGuestInstanceID[] = "guest-instance-id"; // Script that will be loaded by guest WebContents before other scripts. const char kPreloadScript[] = "preload"; +// Like --preload, but the passed argument is an URL. +const char kPreloadUrl[] = "preload-url"; + // Whether the window should be transparent. const char kTransparent[] = "transparent"; diff --git a/atom/common/options_switches.h b/atom/common/options_switches.h index 2dd48ee32a1a..e62f3116661a 100644 --- a/atom/common/options_switches.h +++ b/atom/common/options_switches.h @@ -30,6 +30,7 @@ extern const char kAlwaysOnTop[]; extern const char kNodeIntegration[]; extern const char kAcceptFirstMouse[]; extern const char kUseContentSize[]; +extern const char kTitleBarStyle[]; extern const char kWebPreferences[]; extern const char kZoomFactor[]; extern const char kAutoHideMenuBar[]; @@ -41,6 +42,7 @@ extern const char kPpapiFlashPath[]; extern const char kPpapiFlashVersion[]; extern const char kGuestInstanceID[]; extern const char kPreloadScript[]; +extern const char kPreloadUrl[]; extern const char kTransparent[]; extern const char kType[]; extern const char kDisableAutoHideCursor[]; diff --git a/atom/renderer/api/atom_api_renderer_ipc.cc b/atom/renderer/api/atom_api_renderer_ipc.cc index d222f8f73b85..061293e80d03 100644 --- a/atom/renderer/api/atom_api_renderer_ipc.cc +++ b/atom/renderer/api/atom_api_renderer_ipc.cc @@ -5,13 +5,12 @@ #include "atom/common/api/api_messages.h" #include "atom/common/native_mate_converters/string16_converter.h" #include "atom/common/native_mate_converters/value_converter.h" +#include "atom/common/node_includes.h" #include "content/public/renderer/render_view.h" #include "native_mate/dictionary.h" #include "third_party/WebKit/public/web/WebLocalFrame.h" #include "third_party/WebKit/public/web/WebView.h" -#include "atom/common/node_includes.h" - using content::RenderView; using blink::WebLocalFrame; using blink::WebView; @@ -30,7 +29,7 @@ RenderView* GetCurrentRenderView() { return RenderView::FromWebView(view); } -void Send(v8::Isolate* isolate, +void Send(mate::Arguments* args, const base::string16& channel, const base::ListValue& arguments) { RenderView* render_view = GetCurrentRenderView(); @@ -41,10 +40,10 @@ void Send(v8::Isolate* isolate, render_view->GetRoutingID(), channel, arguments)); if (!success) - node::ThrowError(isolate, "Unable to send AtomViewHostMsg_Message"); + args->ThrowError("Unable to send AtomViewHostMsg_Message"); } -base::string16 SendSync(v8::Isolate* isolate, +base::string16 SendSync(mate::Arguments* args, const base::string16& channel, const base::ListValue& arguments) { base::string16 json; @@ -60,7 +59,7 @@ base::string16 SendSync(v8::Isolate* isolate, bool success = render_view->Send(message); if (!success) - node::ThrowError(isolate, "Unable to send AtomViewHostMsg_Message_Sync"); + args->ThrowError("Unable to send AtomViewHostMsg_Message_Sync"); return json; } diff --git a/atom/renderer/atom_render_view_observer.cc b/atom/renderer/atom_render_view_observer.cc index 1f199ea445c6..456ca5ba4b24 100644 --- a/atom/renderer/atom_render_view_observer.cc +++ b/atom/renderer/atom_render_view_observer.cc @@ -13,6 +13,7 @@ #include "atom/common/api/api_messages.h" #include "atom/common/api/event_emitter_caller.h" #include "atom/common/native_mate_converters/value_converter.h" +#include "atom/common/node_includes.h" #include "atom/common/options_switches.h" #include "atom/renderer/atom_renderer_client.h" #include "base/command_line.h" @@ -31,8 +32,6 @@ #include "third_party/WebKit/public/web/WebView.h" #include "ui/base/resource/resource_bundle.h" -#include "atom/common/node_includes.h" - namespace atom { namespace { diff --git a/atom/renderer/atom_renderer_client.cc b/atom/renderer/atom_renderer_client.cc index ef5ac757d9f4..b99372bf816d 100644 --- a/atom/renderer/atom_renderer_client.cc +++ b/atom/renderer/atom_renderer_client.cc @@ -7,11 +7,12 @@ #include #include "atom/common/api/atom_bindings.h" -#include "atom/common/native_mate_converters/callback.h" #include "atom/common/node_bindings.h" +#include "atom/common/node_includes.h" #include "atom/common/options_switches.h" #include "atom/renderer/atom_render_view_observer.h" #include "atom/renderer/guest_view_container.h" +#include "atom/renderer/node_array_buffer_bridge.h" #include "base/command_line.h" #include "chrome/renderer/pepper/pepper_helper.h" #include "chrome/renderer/printing/print_web_view_helper.h" @@ -20,16 +21,12 @@ #include "content/public/renderer/render_frame.h" #include "content/public/renderer/render_frame_observer.h" #include "content/public/renderer/render_thread.h" -#include "third_party/WebKit/public/web/WebArrayBuffer.h" -#include "third_party/WebKit/public/web/WebArrayBufferConverter.h" #include "third_party/WebKit/public/web/WebCustomElement.h" #include "third_party/WebKit/public/web/WebLocalFrame.h" #include "third_party/WebKit/public/web/WebPluginParams.h" #include "third_party/WebKit/public/web/WebKit.h" #include "third_party/WebKit/public/web/WebRuntimeFeatures.h" -#include "atom/common/node_includes.h" - #if defined(OS_WIN) #include #endif @@ -51,37 +48,6 @@ bool IsSwitchEnabled(base::CommandLine* command_line, return true; } -// global.Uint8Array; -v8::Local GetUint8ArrayConstructor( - v8::Isolate* isolate, v8::Local context) { - v8::Local constructor = context->Global()->Get( - mate::StringToV8(isolate, "Uint8Array")); - return v8::Local::Cast(constructor); -} - -// new ArrayBuffer(size); -v8::Local BlinkArrayBufferCreate( - v8::Isolate* isolate, size_t size) { - blink::WebArrayBuffer buffer = blink::WebArrayBuffer::create(size, 1); - return v8::Local::Cast( - blink::WebArrayBufferConverter::toV8Value( - &buffer, isolate->GetCurrentContext()->Global(), isolate)); -} - -// new Uint8Array(array_buffer, offset, size); -v8::Local BlinkUint8ArrayCreate( - v8::Local ab, size_t offset, size_t size) { - v8::Local context = ab->CreationContext(); - v8::Isolate* isolate = context->GetIsolate(); - v8::Local constructor = - GetUint8ArrayConstructor(isolate, context); - v8::Local args[] = { - ab, mate::ConvertToV8(isolate, offset), mate::ConvertToV8(isolate, size) - }; - return v8::Local::Cast(constructor->NewInstance( - context, arraysize(args), args).ToLocalChecked()); -} - // Helper class to forward the messages to the client. class AtomRenderFrameObserver : public content::RenderFrameObserver { public: @@ -120,9 +86,7 @@ void AtomRendererClient::WebKitInitialized() { blink::WebCustomElement::addEmbedderCustomElementName("webview"); blink::WebCustomElement::addEmbedderCustomElementName("browserplugin"); - // Override Node's ArrayBuffer with DOM's ArrayBuffer. - node::Buffer::SetArrayBufferCreator(&BlinkArrayBufferCreate, - &BlinkUint8ArrayCreate); + OverrideNodeArrayBuffer(); node_bindings_->Initialize(); node_bindings_->PrepareMessageLoop(); diff --git a/atom/renderer/lib/web-view/guest-view-internal.coffee b/atom/renderer/lib/web-view/guest-view-internal.coffee index 44db5e304db4..b491184fb8d7 100644 --- a/atom/renderer/lib/web-view/guest-view-internal.coffee +++ b/atom/renderer/lib/web-view/guest-view-internal.coffee @@ -6,7 +6,7 @@ requestId = 0 WEB_VIEW_EVENTS = 'load-commit': ['url', 'isMainFrame'] 'did-finish-load': [] - 'did-fail-load': ['errorCode', 'errorDescription'] + 'did-fail-load': ['errorCode', 'errorDescription', 'validatedUrl'] 'did-frame-finish-load': ['isMainFrame'] 'did-start-loading': [] 'did-stop-loading': [] diff --git a/atom/renderer/node_array_buffer_bridge.cc b/atom/renderer/node_array_buffer_bridge.cc new file mode 100644 index 000000000000..80f2530524d2 --- /dev/null +++ b/atom/renderer/node_array_buffer_bridge.cc @@ -0,0 +1,66 @@ +// Copyright (c) 2015 GitHub, Inc. +// Use of this source code is governed by the MIT license that can be +// found in the LICENSE file. + +#include "atom/renderer/node_array_buffer_bridge.h" + +#include "base/basictypes.h" +#include "atom/common/node_includes.h" +#include "native_mate/converter.h" +#include "third_party/WebKit/public/web/WebArrayBuffer.h" +#include "third_party/WebKit/public/web/WebArrayBufferConverter.h" + +namespace atom { + +namespace { + +// global.Uint8Array; +v8::Local GetUint8ArrayConstructor( + v8::Isolate* isolate, v8::Local context) { + v8::Local constructor = context->Global()->Get( + mate::StringToV8(isolate, "Uint8Array")); + return v8::Local::Cast(constructor); +} + +// new ArrayBuffer(size); +v8::Local BlinkArrayBufferNew( + v8::Isolate* isolate, size_t size) { + blink::WebArrayBuffer buffer = blink::WebArrayBuffer::create(size, 1); + return v8::Local::Cast( + blink::WebArrayBufferConverter::toV8Value( + &buffer, isolate->GetCurrentContext()->Global(), isolate)); +} + +// new ArrayBuffer(data, size); +v8::Local BlinkArrayBufferNewWith( + v8::Isolate* isolate, void* data, size_t size) { + blink::WebArrayBuffer buffer = blink::WebArrayBuffer::createExternal( + data, size); + return v8::Local::Cast( + blink::WebArrayBufferConverter::toV8Value( + &buffer, isolate->GetCurrentContext()->Global(), isolate)); +} + +// new Uint8Array(array_buffer, offset, size); +v8::Local BlinkUint8ArrayNew( + v8::Local ab, size_t offset, size_t size) { + // Use the DOM's Uint8Array constructor to create Uint8Array. + v8::Local context = ab->CreationContext(); + v8::Isolate* isolate = context->GetIsolate(); + v8::Local constructor = + GetUint8ArrayConstructor(isolate, context); + v8::Local args[] = { + ab, mate::ConvertToV8(isolate, offset), mate::ConvertToV8(isolate, size) + }; + return v8::Local::Cast(constructor->NewInstance( + context, arraysize(args), args).ToLocalChecked()); +} + +} // namespace + +void OverrideNodeArrayBuffer() { + node::Buffer::SetArrayBufferCreator( + BlinkArrayBufferNew, BlinkArrayBufferNewWith, BlinkUint8ArrayNew); +} + +} // namespace atom diff --git a/atom/renderer/node_array_buffer_bridge.h b/atom/renderer/node_array_buffer_bridge.h new file mode 100644 index 000000000000..61d180699312 --- /dev/null +++ b/atom/renderer/node_array_buffer_bridge.h @@ -0,0 +1,15 @@ +// Copyright (c) 2015 GitHub, Inc. +// Use of this source code is governed by the MIT license that can be +// found in the LICENSE file. + +#ifndef ATOM_RENDERER_NODE_ARRAY_BUFFER_BRIDGE_H_ +#define ATOM_RENDERER_NODE_ARRAY_BUFFER_BRIDGE_H_ + +namespace atom { + +// Override Node's ArrayBuffer with DOM's ArrayBuffer. +void OverrideNodeArrayBuffer(); + +} // namespace atom + +#endif // ATOM_RENDERER_NODE_ARRAY_BUFFER_BRIDGE_H_ diff --git a/common.gypi b/common.gypi index a95e05620f02..7c41c3616dfb 100644 --- a/common.gypi +++ b/common.gypi @@ -75,6 +75,7 @@ 'xcode_settings': { 'GCC_TREAT_WARNINGS_AS_ERRORS': 'NO', 'WARNING_CFLAGS': [ + '-Wno-unknown-warning-option', '-Wno-parentheses-equality', '-Wno-unused-function', '-Wno-sometimes-uninitialized', diff --git a/docs-translations/es/README-es.md b/docs-translations/es/README-es.md deleted file mode 100644 index 617e66ec6f5b..000000000000 --- a/docs-translations/es/README-es.md +++ /dev/null @@ -1,68 +0,0 @@ -## Guías - -* [Distribución de aplicaciones](tutorial/application-distribution-es.md) -* [Empaquetamiento de aplicaciones](tutorial/application-packaging-es.md) -* [Utilizando módulos nativos](tutorial/using-native-node-modules-es.md) -* [Depurando el proceso principal](tutorial/debugging-main-process-es.md) -* [Utilizando Selenium y WebDriver](tutorial/using-selenium-and-webdriver-es.md) -* [Extensión DevTools](tutorial/devtools-extension-es.md) -* [Utilizando el plugin pepper flash](tutorial/using-pepper-flash-plugin-es.md) - -## Tutoriales - -* [Introducción](tutorial/quick-start.md) -* [Integración con el entorno de escritorio](tutorial/desktop-environment-integration.md) -* [Detección del evento en línea/fuera de línea](tutorial/online-offline-events.md) - -## API - -* [Sinopsis](api/synopsis.md) -* [Proceso](api/process.md) -* [Parámetros CLI soportados (Chrome)](api/chrome-command-line-switches.md) - -Elementos DOM customizados: - -* [Objeto `File`](api/file-object.md) -* [Etiqueta ``](api/web-view-tag.md) -* [Función `window.open`](api/window-open.md) - -Módulos del proceso principal: - -* [app](api/app.md) -* [auto-updater](api/auto-updater.md) -* [browser-window](api/browser-window.md) -* [content-tracing](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) -* [protocol](api/protocol.md) -* [tray](api/tray.md) - -Módulos del renderer (página web): - -* [ipc (renderer)](api/ipc-renderer.md) -* [remote](api/remote.md) -* [web-frame](api/web-frame.md) - -Módulos de ambos procesos: - -* [clipboard](api/clipboard.md) -* [crash-reporter](api/crash-reporter.md) -* [native-image](api/native-image.md) -* [screen](api/screen.md) -* [shell](api/shell.md) - -## Desarrollo - -* [Guía de estilo](development/coding-style.md) -* [Estructura de directorio](development/source-code-directory-structure.md) -* [Diferencias técnicas con NW.js (anteriormente conocido como node-webkit)](development/atom-shell-vs-node-webkit.md) -* [Sistema de compilación](development/build-system-overview.md) -* [Instrucciones de compilación (Mac)](development/build-instructions-osx.md) -* [Instrucciones de compilación (Windows)](development/build-instructions-windows.md) -* [Instrucciones de compilación (Linux)](development/build-instructions-linux.md) -* [Configurando un servidor de símbolos en el depurador](development/setting-up-symbol-server.md) diff --git a/docs-translations/es/README.md b/docs-translations/es/README.md new file mode 100644 index 000000000000..497cc4e05ccf --- /dev/null +++ b/docs-translations/es/README.md @@ -0,0 +1,68 @@ +## Guías + +* [Distribución de aplicaciones](tutorial/application-distribution.md) +* [Empaquetamiento de aplicaciones](tutorial/application-packaging.md) +* [Utilizando módulos nativos](tutorial/using-native-node-modules.md) +* [Depurando el proceso principal](tutorial/debugging-main-process.md) +* [Utilizando Selenium y WebDriver](tutorial/using-selenium-and-webdriver.md) +* [Extensión DevTools](tutorial/devtools-extension.md) +* [Utilizando el plugin pepper flash](tutorial/using-pepper-flash-plugin.md) + +## Tutoriales + +* [Introducción](../../docs/tutorial/quick-start.md) +* [Integración con el entorno de escritorio](../../docs/tutorial/desktop-environment-integration.md) +* [Detección del evento en línea/fuera de línea](../../docs/tutorial/online-offline-events.md) + +## API + +* [Sinopsis](../../docs/api/synopsis.md) +* [Proceso](../../docs/api/process.md) +* [Parámetros CLI soportados (Chrome)](../../docs/api/chrome-command-line-switches.md) + +Elementos DOM customizados: + +* [Objeto `File`](../../docs/api/file-object.md) +* [Etiqueta ``](../../docs/api/web-view-tag.md) +* [Función `window.open`](../../docs/api/window-open.md) + +Módulos del proceso principal: + +* [app](../../docs/api/app.md) +* [auto-updater](../../docs/api/auto-updater.md) +* [browser-window](../../docs/api/browser-window.md) +* [content-tracing](../../docs/api/content-tracing.md) +* [dialog](../../docs/api/dialog.md) +* [global-shortcut](../../docs/api/global-shortcut.md) +* [ipc (main process)](../../docs/api/ipc-main-process.md) +* [menu](../../docs/api/menu.md) +* [menu-item](../../docs/api/menu-item.md) +* [power-monitor](../../docs/api/power-monitor.md) +* [power-save-blocker](../../docs/api/power-save-blocker.md) +* [protocol](../../docs/api/protocol.md) +* [tray](../../docs/api/tray.md) + +Módulos del renderer (página web): + +* [ipc (renderer)](../../docs/api/ipc-renderer.md) +* [remote](../../docs/api/remote.md) +* [web-frame](../../docs/api/web-frame.md) + +Módulos de ambos procesos: + +* [clipboard](../../docs/api/clipboard.md) +* [crash-reporter](../../docs/api/crash-reporter.md) +* [native-image](../../docs/api/native-image.md) +* [screen](../../docs/api/screen.md) +* [shell](../../docs/api/shell.md) + +## Desarrollo + +* [Guía de estilo](../../docs/development/coding-style.md) +* [Estructura de directorio](../../docs/development/source-code-directory-structure.md) +* [Diferencias técnicas con NW.js (anteriormente conocido como node-webkit)](../../docs/development/atom-shell-vs-node-webkit.md) +* [Sistema de compilación](../../docs/development/build-system-overview.md) +* [Instrucciones de compilación (Mac)](../../docs/development/build-instructions-osx.md) +* [Instrucciones de compilación (Windows)](../../docs/development/build-instructions-windows.md) +* [Instrucciones de compilación (Linux)](../../docs/development/build-instructions-linux.md) +* [Configurando un servidor de símbolos en el depurador](../../docs/development/setting-up-symbol-server.md) diff --git a/docs-translations/es/tutorial/application-distribution-es.md b/docs-translations/es/tutorial/application-distribution.md similarity index 100% rename from docs-translations/es/tutorial/application-distribution-es.md rename to docs-translations/es/tutorial/application-distribution.md diff --git a/docs-translations/es/tutorial/application-packaging-es.md b/docs-translations/es/tutorial/application-packaging.md similarity index 100% rename from docs-translations/es/tutorial/application-packaging-es.md rename to docs-translations/es/tutorial/application-packaging.md diff --git a/docs-translations/es/tutorial/debugging-main-process-es.md b/docs-translations/es/tutorial/debugging-main-process.md similarity index 100% rename from docs-translations/es/tutorial/debugging-main-process-es.md rename to docs-translations/es/tutorial/debugging-main-process.md diff --git a/docs-translations/es/tutorial/desktop-environment-integration-es.md b/docs-translations/es/tutorial/desktop-environment-integration.md similarity index 100% rename from docs-translations/es/tutorial/desktop-environment-integration-es.md rename to docs-translations/es/tutorial/desktop-environment-integration.md diff --git a/docs-translations/es/tutorial/devtools-extension-es.md b/docs-translations/es/tutorial/devtools-extension.md similarity index 100% rename from docs-translations/es/tutorial/devtools-extension-es.md rename to docs-translations/es/tutorial/devtools-extension.md diff --git a/docs-translations/es/tutorial/online-offline-events-es.md b/docs-translations/es/tutorial/online-offline-events.md similarity index 100% rename from docs-translations/es/tutorial/online-offline-events-es.md rename to docs-translations/es/tutorial/online-offline-events.md diff --git a/docs-translations/es/tutorial/quick-start-es.md b/docs-translations/es/tutorial/quick-start.md similarity index 100% rename from docs-translations/es/tutorial/quick-start-es.md rename to docs-translations/es/tutorial/quick-start.md diff --git a/docs-translations/es/tutorial/using-native-node-modules-es.md b/docs-translations/es/tutorial/using-native-node-modules.md similarity index 100% rename from docs-translations/es/tutorial/using-native-node-modules-es.md rename to docs-translations/es/tutorial/using-native-node-modules.md diff --git a/docs-translations/es/tutorial/using-pepper-flash-plugin-es.md b/docs-translations/es/tutorial/using-pepper-flash-plugin.md similarity index 100% rename from docs-translations/es/tutorial/using-pepper-flash-plugin-es.md rename to docs-translations/es/tutorial/using-pepper-flash-plugin.md diff --git a/docs-translations/es/tutorial/using-selenium-and-webdriver-es.md b/docs-translations/es/tutorial/using-selenium-and-webdriver.md similarity index 100% rename from docs-translations/es/tutorial/using-selenium-and-webdriver-es.md rename to docs-translations/es/tutorial/using-selenium-and-webdriver.md diff --git a/docs-translations/ko/README.md b/docs-translations/ko/README.md index 2c75fa345cff..2fb242fae906 100644 --- a/docs-translations/ko/README.md +++ b/docs-translations/ko/README.md @@ -2,7 +2,7 @@ * [어플리케이션 배포](tutorial/application-distribution.md) * [어플리케이션 패키징](tutorial/application-packaging.md) -* [네이티브 node 모듈 사용하기](tutorial/using-native-node-modules.md) +* [네이티브 Node 모듈 사용하기](tutorial/using-native-node-modules.md) * [메인 프로세스 디버깅하기](tutorial/debugging-main-process.md) * [Selenium 과 WebDriver 사용하기](tutorial/using-selenium-and-webdriver.md) * [개발자 콘솔 확장기능](tutorial/devtools-extension.md) @@ -12,25 +12,25 @@ * [시작하기](tutorial/quick-start.md) * [데스크톱 환경 통합](tutorial/desktop-environment-integration.md) -* [온라인/오프라인 이벤트](tutorial/online-offline-events.md) +* [온라인/오프라인 이벤트 감지](tutorial/online-offline-events.md) ## API 레퍼런스 * [개요](api/synopsis.md) -* [process](api/process.md) -* [크롬 Command-Line 스위치 지원](api/chrome-command-line-switches.md) +* [Process 객체](api/process.md) +* [크롬 Command Line 스위치 지원](api/chrome-command-line-switches.md) -커스텀 DOM elements: +### 커스텀 DOM elements: * [`File` 객체](api/file-object.md) * [`` 태그](api/web-view-tag.md) -* [`window.open` 메서드](api/window-open.md) +* [`window.open` 함수](api/window-open.md) -메인 프로세스를 위한 모듈들: +### 메인 프로세스를 위한 모듈들: -* [app](api/app.md) +* [app (0% 번역됨)](api/app.md) * [auto-updater](api/auto-updater.md) -* [browser-window](api/browser-window.md) +* [browser-window (0% 번역됨)](api/browser-window.md) * [content-tracing](api/content-tracing.md) * [dialog](api/dialog.md) * [global-shortcut](api/global-shortcut.md) @@ -41,16 +41,16 @@ * [power-save-blocker](api/power-save-blocker.md) * [protocol](api/protocol.md) * [session](api/session.md) -* [webContents](api/web-contents.md) +* [web-contents (0% 번역됨)](api/web-contents.md) * [tray](api/tray.md) -랜더러 프로세스를 위한 모듈들 (웹 페이지): +### 랜더러 프로세스를 위한 모듈들 (웹 페이지): * [ipc (renderer)](api/ipc-renderer.md) * [remote](api/remote.md) * [web-frame](api/web-frame.md) -두 프로세스에서 모두 사용 가능한 모듈들: +### 두 프로세스에서 모두 사용 가능한 모듈들: * [clipboard](api/clipboard.md) * [crash-reporter](api/crash-reporter.md) diff --git a/docs-translations/ko/api/auto-updater.md b/docs-translations/ko/api/auto-updater.md index 1b586d5cdd5d..23f881c32ba8 100644 --- a/docs-translations/ko/api/auto-updater.md +++ b/docs-translations/ko/api/auto-updater.md @@ -38,7 +38,7 @@ Squirrel은 응답을 분석해야 할 책임이 있기 때문에 `Accept: appli 버전 식별자와 다른 기준을 특정하는 업데이트 요청 폼을 서버로 전달하기 위한 공통적인 방법으로 쿼리 인자를 사용하는 방법이 있습니다: ```javascript -// On the main process +// In the main process var app = require('app'); var autoUpdater = require('auto-updater'); autoUpdater.setFeedUrl('http://mycompany.com/myapp/latest?version=' + app.getVersion()); diff --git a/docs-translations/ko/api/content-tracing.md b/docs-translations/ko/api/content-tracing.md index f6010d156f6a..08221fbc7076 100644 --- a/docs-translations/ko/api/content-tracing.md +++ b/docs-translations/ko/api/content-tracing.md @@ -15,7 +15,7 @@ contentTracing.startRecording('*', contentTracing.DEFAULT_OPTIONS, function() { }); }, 5000); }); -`` +``` ## Methods @@ -29,10 +29,11 @@ contentTracing.startRecording('*', contentTracing.DEFAULT_OPTIONS, function() { 모든 child 프로세스가 `getCategories` 요청을 승인하면 `callback`이 한 번 호출되며 인자에 카테고리 그룹의 배열이 전달됩니다. -### `contentTracing.startRecording(categoryFilter, traceOptions, callback)` +### `contentTracing.startRecording(options, callback)` -* `categoryFilter` String -* `traceOptions` String +* `options` Object + * `categoryFilter` String + * `traceOptions` String * `callback` Function 모든 프로세스에서 레코딩을 시작합니다. @@ -85,10 +86,11 @@ Child 프로세스는 일반적으로 추적 데이터와 희귀한 플러시 추적 데이터는 `resultFilePath` 해당 경로가 비어있는 경우에 한 해 해당 경로에 작성되거나 임시 파일에 작성됩니다. 실제 파일 경로는 null이 아닌 이상 `callback`을 통해 전달됩니다. -### `contentTracing.startMonitoring(categoryFilter, traceOptions, callback)` +### `contentTracing.startMonitoring(options, callback)` -* `categoryFilter` String -* `traceOptions` String +* `options` Object + * `categoryFilter` String + * `traceOptions` String * `callback` Function 모든 프로세스에서 모니터링을 시작합니다. diff --git a/docs-translations/ko/api/frameless-window.md b/docs-translations/ko/api/frameless-window.md index a398087e37b4..64422460775f 100644 --- a/docs-translations/ko/api/frameless-window.md +++ b/docs-translations/ko/api/frameless-window.md @@ -13,6 +13,16 @@ var BrowserWindow = require('browser-window'); var win = new BrowserWindow({ width: 800, height: 600, frame: false }); ``` +### 최신 Mac에서 사용할 수 있는 대안 + +OS X 10.10 Yosemite 이후의 최신 버전부터는 테두리가 없는 창을 만들 때 새로운 방법을 사용할 수 있습니다. +`frame` 옵션을 `false`로 지정하여 제목과 창 구성 요소를 모두 비활성화하는 대신 새로운 `title-bar-style` +옵션을 통해 제목만 숨기고 창 구성 요소("흔히 신호등으로 알고 있는")의 기능과 창 크기를 그대로 유지할 수 있습니다: + +```javascript +var BrowserWindow = require('browser-window'); +var win = new BrowserWindow({ width: 800, height: 600, 'title-bar-style': 'hidden' }); + ## 투명한 창 만들기 Frameless Window의 창의 배경을 투명하게 만들고 싶다면 `transparent` 옵션을 `true`로 바꿔주기만 하면됩니다: diff --git a/docs-translations/ko/api/ipc-main-process.md b/docs-translations/ko/api/ipc-main-process.md index 496afd203318..ad4e545ce474 100644 --- a/docs-translations/ko/api/ipc-main-process.md +++ b/docs-translations/ko/api/ipc-main-process.md @@ -6,7 +6,7 @@ ## 메시지 전송 물론 메인 프로세스에서 랜더러 프로세스로 메시지를 보내는 것도 가능합니다. -자세한 내용은 [WebContents.send](browser-window.md#webcontentssendchannel-args)를 참고하세요. +자세한 내용은 [WebContents.send](web-contents.md#webcontentssendchannel-args)를 참고하세요. - 메시지를 전송할 때 이벤트 이름은 `channel`이 됩니다. - 메시지에 동기로 응답할 땐 반드시 `event.returnValue`를 설정해야 합니다. diff --git a/docs-translations/ko/api/menu.md b/docs-translations/ko/api/menu.md index 90ea6539829a..a8ac499f5768 100644 --- a/docs-translations/ko/api/menu.md +++ b/docs-translations/ko/api/menu.md @@ -164,11 +164,11 @@ if (process.platform == 'darwin') { { label: 'Hide Others', accelerator: 'Command+Shift+H', - role: 'hideothers:' + role: 'hideothers' }, { label: 'Show All', - role: 'unhide:' + role: 'unhide' }, { type: 'separator' @@ -295,7 +295,7 @@ OS X에선 지정한 어플리케이션 메뉴에 상관없이 메뉴의 첫번 만약 참조된 아이템의 분리자 그룹이 존재하지 않을 경우 지정된 id로 새로운 분리자 그룹을 만든 후 해당 그룹의 뒤에 삽입됩니다. 위치를 지정한 아이템의 뒤에 위치가 지정되지 않은 아이템이 있을 경우 각 아이템의 위치가 지정되기 전까지 모든 아이템이 위치가 지정된 아이템의 뒤에 삽입됩니다. -이에 따라 위치를 이동하고 싶은 특정 그룹의 아이템들이 있을 경우 해당 그룹의 맨 첫번째 메뉴 아이템의 위치만을 지정하면 됩니다. +따라서 위치를 이동하고 싶은 특정 그룹의 아이템들이 있을 경우 해당 그룹의 맨 첫번째 메뉴 아이템의 위치만을 지정하면 됩니다. ### 예제 diff --git a/docs-translations/ko/api/remote.md b/docs-translations/ko/api/remote.md index 34492a30556f..15c82ff0d21e 100644 --- a/docs-translations/ko/api/remote.md +++ b/docs-translations/ko/api/remote.md @@ -17,7 +17,7 @@ var win = new BrowserWindow({ width: 800, height: 600 }); win.loadUrl('https://github.com'); ``` -**참고:** 반대로 메인 프로세스에서 랜더러 프로세스에 접근 하려면 [webContents.executeJavascript](browser-window.md#webcontents-executejavascript-code) 메서드를 사용하면 됩니다. +**참고:** 반대로 메인 프로세스에서 랜더러 프로세스에 접근 하려면 [webContents.executeJavascript](web-contents.md#webcontentsexecutejavascriptcode-usergesture) 메서드를 사용하면 됩니다. ## Remote 객체 diff --git a/docs-translations/ko/api/session.md b/docs-translations/ko/api/session.md new file mode 100644 index 000000000000..cb912aabb100 --- /dev/null +++ b/docs-translations/ko/api/session.md @@ -0,0 +1,187 @@ +# session + +`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"); + +var session = win.webContents.session +``` + +## Events + +### Event: 'will-download' + +* `event` Event +* `item` Object + * `url` String + * `filename` String + * `mimeType` String + * `hasUserGesture` Boolean +* `webContents` [WebContents](web-contents.md) + +Electron의 `webContents`에서 `item`을 다운로드할 때 발생하는 이벤트입니다. + +`event.preventDefault()` 메서드를 호출하면 다운로드를 취소합니다. + +```javascript +session.on('will-download', function(event, item, webContents) { + event.preventDefault(); + require('request')(item.url, function(data) { + require('fs').writeFileSync('/somewhere', data); + }); +}); +``` + +## Methods + +`session` 객체는 다음과 같은 메서드와 속성을 가지고 있습니다: + +### `session.cookies` + +`cookies` 속성은 쿠키를 조작하는 방법을 제공합니다. 예를 들어 다음과 같이 할 수 있습니다: + +```javascript +var BrowserWindow = require('browser-window'); + +var win = new BrowserWindow({ width: 800, height: 600 }); + +win.loadUrl('https://github.com'); + +win.webContents.on('did-finish-load', function() { + // 모든 쿠키를 가져옵니다. + win.webContents.session.cookies.get({}, function(error, cookies) { + if (error) throw error; + console.log(cookies); + }); + + // Url에 관련된 쿠키를 모두 가져옵니다. + win.webContents.session.cookies.get({ url : "http://www.github.com" }, + function(error, cookies) { + if (error) throw error; + console.log(cookies); + }); + + // 지정한 쿠키 데이터를 설정합니다. + // 동일한 쿠키가 있으면 해당 쿠키를 덮어씁니다. + win.webContents.session.cookies.set( + { url : "http://www.github.com", name : "dummy_name", value : "dummy"}, + function(error, cookies) { + if (error) throw error; + console.log(cookies); + }); +}); +``` + +### `session.cookies.get(details, callback)` + +`details` Object, properties: + +* `url` String - `url`에 관련된 쿠키를 가져옵니다. 이 속성을 비워두면 모든 url의 쿠키를 가져옵니다. +* `name` String - 이름을 기준으로 쿠키를 필터링합니다. +* `domain` String - `domain`과 일치하는 도메인과 서브 도메인에 대한 쿠키를 가져옵니다. +* `path` String - `path`와 일치하는 경로에 대한 쿠키를 가져옵니다. +* `secure` Boolean - 보안 속성을 기준으로 쿠키를 필터링합니다. +* `session` Boolean - 세션 또는 영구 쿠키를 필터링합니다. + +* `callback` Function - function(error, cookies) +* `error` Error +* `cookies` Array - `cookie` 객체의 배열, 속성은 다음과 같습니다: + * `name` String - 쿠키의 이름. + * `value` String - 쿠키의 값. + * `domain` String - 쿠키의 도메인. + * `host_only` String - 쿠키가 호스트 전용인가에 대한 여부. + * `path` String - 쿠키의 경로. + * `secure` Boolean - 쿠키가 안전한 것으로 표시되는지에 대한 여부. (일반적으로 HTTPS) + * `http_only` Boolean - 쿠키가 HttpOnly로 표시되는지에 대한 여부. + * `session` Boolean - 쿠키가 세션 쿠키 또는 만료일이 있는 영구 쿠키인지에 대한 여부. + * `expirationDate` Double - (Option) UNIX 시간으로 표시되는 쿠키의 만료일에 대한 초 단위 시간. 세션 쿠키는 지원되지 않음. + +### `session.cookies.set(details, callback)` + +`details` Object, properties: + +* `url` String - `url`에 관련된 쿠키를 가져옵니다. +* `name` String - 쿠키의 이름입니다. 기본적으로 비워두면 생략됩니다. +* `value` String - 쿠키의 값입니다. 기본적으로 비워두면 생략됩니다. +* `domain` String - 쿠키의 도메인입니다. 기본적으로 비워두면 생략됩니다. +* `path` String - 쿠키의 경로입니다. 기본적으로 비워두면 생략됩니다. +* `secure` Boolean - 쿠키가 안전한 것으로 표시되는지에 대한 여부입니다. 기본값은 false입니다. +* `session` Boolean - 쿠키가 HttpOnly로 표시되는지에 대한 여부입니다. 기본값은 false입니다. +* `expirationDate` Double - UNIX 시간으로 표시되는 쿠키의 만료일에 대한 초 단위 시간입니다. 생략하면 쿠키는 세션 쿠키가 됩니다. + +* `callback` Function - function(error) + * `error` Error + +### `session.cookies.remove(details, callback)` + +* `details` Object, proprties: + * `url` String - 쿠키와 관련된 URL입니다. + * `name` String - 지울 쿠키의 이름입니다. +* `callback` Function - function(error) + * `error` Error + +### `session.clearCache(callback)` + +* `callback` Function - 작업이 완료되면 호출됩니다. + +세션의 HTTP 캐시를 비웁니다. + +### `session.clearStorageData([options, ]callback)` + +* `options` Object (optional), proprties: + * `origin` String - `scheme://host:port`와 같은 `window.location.origin` 규칙을 따르는 origin 문자열. + * `storages` Array - 비우려는 스토리지의 종류, 다음과 같은 타입을 포함할 수 있습니다: + `appcache`, `cookies`, `filesystem`, `indexdb`, `local storage`, + `shadercache`, `websql`, `serviceworkers` + * `quotas` Array - 비우려는 할당의 종류, 다음과 같은 타입을 포함할 수 있습니다: + `temporary`, `persistent`, `syncable`. +* `callback` Function - 작업이 완료되면 호출됩니다. + +웹 스토리지의 데이터를 비웁니다. + +### `session.setProxy(config, callback)` + +* `config` String +* `callback` Function - 작업이 완료되면 호출됩니다. + +세션에 사용할 프록시 `config`를 분석하고 프록시를 적용합니다. + +``` +config = scheme-proxies[";"] +scheme-proxies = ["="] +url-scheme = "http" | "https" | "ftp" | "socks" +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. +``` + +### `session.setDownloadPath(path)` + +* `path` String - 다운로드 위치 + +다운로드 저장 위치를 지정합니다. 기본 다운로드 위치는 각 어플리케이션 데이터 디렉터리의 `Downloads` 폴더입니다. diff --git a/docs-translations/ko/api/web-frame.md b/docs-translations/ko/api/web-frame.md index 9829520901d2..d09114e559c8 100644 --- a/docs-translations/ko/api/web-frame.md +++ b/docs-translations/ko/api/web-frame.md @@ -1,4 +1,4 @@ -# web-frame +# webFrame `web-frame` 모듈은 현재 웹 페이지의 랜더링 상태를 설정 할 수 있도록 관련 유틸리티를 제공하는 모듈입니다. @@ -6,38 +6,43 @@ ```javascript var webFrame = require('web-frame'); + webFrame.setZoomFactor(2); ``` -## webFrame.setZoomFactor(factor) +## Methods + +`web-frame` 모듈은 다음과 같은 메서드를 가지고 있습니다: + +### `webFrame.setZoomFactor(factor)` * `factor` Number - Zoom 값 -지정한 값으로 페이지를 줌 합니다. 줌 값은 퍼센트 / 100입니다. (예시: 300% = 3.0) +지정한 값으로 페이지를 줌 합니다. 줌 값은 퍼센트를 100으로 나눈 값입니다. (예시: 300% = 3.0) -## webFrame.getZoomFactor() +### `webFrame.getZoomFactor()` 현재 줌 값을 반환합니다. -## webFrame.setZoomLevel(level) +### `webFrame.setZoomLevel(level)` * `level` Number - Zoom level 지정한 레벨로 줌 레벨을 변경합니다. 0은 "기본 크기" 입니다. 그리고 각각 레벨 값을 올리거나 내릴 때마다 20%씩 커지거나 작아지고 기본 크기의 50%부터 300%까지 조절 제한이 있습니다. -## webFrame.getZoomLevel() +### `webFrame.getZoomLevel()` 현재 줌 레벨을 반환합니다. -## webFrame.setZoomLevelLimits(minimumLevel, maximumLevel) +### `webFrame.setZoomLevelLimits(minimumLevel, maximumLevel)` * `minimumLevel` Number * `maximumLevel` Number 줌 레벨의 최대, 최소치를 지정합니다. -## webFrame.setSpellCheckProvider(language, autoCorrectWord, provider) +### `webFrame.setSpellCheckProvider(language, autoCorrectWord, provider)` * `language` String * `autoCorrectWord` Boolean @@ -57,7 +62,7 @@ require('web-frame').setSpellCheckProvider("en-US", true, { }); ``` -## webFrame.registerUrlSchemeAsSecure(scheme) +### `webFrame.registerUrlSchemeAsSecure(scheme)` * `scheme` String @@ -65,10 +70,10 @@ require('web-frame').setSpellCheckProvider("en-US", true, { 보안 스킴은 혼합된 컨텐츠 경고를 발생시키지 않습니다. 예를 들어 `https` 와 `data`는 네트워크 공격자로부터 손상될 가능성이 없기 때문에 보안 스킴이라고 할 수 있습니다. -## webFrame.registerUrlSchemeAsBypassingCsp(scheme) +### `webFrame.registerUrlSchemeAsBypassingCsp(scheme)` * `scheme` String -페이지 컨텐츠의 보안 정책에 상관없이 이 `scheme`로부터 리소스가 로드됩니다. +현재 페이지 컨텐츠의 보안 정책에 상관없이 이 `scheme`로부터 리소스가 로드됩니다. [spellchecker]: https://github.com/atom/node-spellchecker diff --git a/docs-translations/ko/api/web-view-tag.md b/docs-translations/ko/api/web-view-tag.md index d2efdf17ea1f..90f5acb9381f 100644 --- a/docs-translations/ko/api/web-view-tag.md +++ b/docs-translations/ko/api/web-view-tag.md @@ -3,9 +3,9 @@ `guest` 컨텐츠(웹 페이지)를 Electron 앱 페이지에 삽입하기 위해 `webview` 태그를 사용할 수 있습니다. 게스트 컨텐츠는 `webview` 컨테이너에 담겨 대상 페이지에 삽입되고 해당 페이지에선 게스트 컨텐츠의 배치 및 렌더링 과정을 조작할 수 있습니다. -`iframe`과 `webview`의 차이는 어플리케이션과 프로세스가 분리되어 돌아간다는 점입니다. -그것은 모든 권한이 웹 페이지와 같지 않고 모든 앱과 임베디드(게스트) 컨텐츠간의 상호작용이 비동기로 작동한다는 것을 의미합니다. -이에 따라 임베디드 컨텐츠로부터 어플리케이션을 안전하게 유지할 수 있습니다. +`iframe`과는 달리 `webview`는 어플리케이션과 분리된 프로세스에서 작동합니다. +이는 웹 페이지와 같은 권한을 가지지 않고 앱과 임베디드(게스트) 컨텐츠간의 모든 상호작용이 비동기로 작동한다는 것을 의미합니다. +따라서 임베디드 컨텐츠로부터 어플리케이션을 안전하게 유지할 수 있습니다. ## 예제 @@ -40,7 +40,9 @@ ## 태그 속성 -### src +`webview` 태그는 다음과 같은 속성을 가지고 있습니다: + +### `src` ```html @@ -52,17 +54,17 @@ `src` 속성은 `data:text/plain,Hello, world!` 같은 data URL도 사용할 수 있습니다. -### autosize +### `autosize` ```html ``` "on" 으로 지정하면 `webview` 컨테이너는 `minwidth`, `minheight`, `maxwidth`, `maxheight`에 맞춰서 자동으로 크기를 조절합니다. -이 조건은 `autosize`가 활성화되어있지 않는 한 따로 영향을 주지 않습니다. +이 속성들은 `autosize`가 활성화되어있지 않는 한 프레임에 영향을 주지 않습니다. `autosize`가 활성화 되어있으면 `webview` 컨테이너의 크기는 각각의 지정한 최대, 최소값에 따라 조절됩니다. -### nodeintegration +### `nodeintegration` ```html @@ -71,7 +73,7 @@ "on"으로 지정하면 `webview` 페이지 내에서 `require`와 `process 객체`같은 node.js API를 사용할 수 있습니다. 이를 지정하면 내부에서 로우레벨 리소스에 접근할 수 있습니다. -### plugins +### `plugins` ```html @@ -79,46 +81,65 @@ "on"으로 지정하면 `webview` 내부에서 브라우저 플러그인을 사용할 수 있습니다. -### preload +### `preload` ```html ``` -게스트 페이지가 로드되기 전에 실행할 스크립트를 지정합니다. +페이지가 로드되기 전에 실행할 스크립트를 지정합니다. 스크립트 URL은 `file:` 또는 `asar:` 프로토콜 중 하나를 반드시 사용해야 합니다. -왜냐하면 `require`를 사용해 게스트 페이지 내에서 스크립트를 로드하기 때문입니다. +왜냐하면 페이지 내에서 `require`를 사용하여 스크립트를 로드하기 때문입니다. -게스트 페이지가 nodeintegration을 활성화 하지 않았어도 지정된 스크립트는 정상적으로 돌아갑니다. +페이지가 nodeintegration을 활성화 하지 않아도 지정한 스크립트는 정상적으로 작동합니다. 하지만 스크립트 내에서 사용할 수 있는 global 객체는 스크립트 작동이 끝나면 삭제됩니다. -### httpreferrer +### `httpreferrer` ```html ``` -게스트 페이지의 referrer URL을 설정합니다. +페이지의 referrer URL을 설정합니다. -### useragent +### `useragent` ```html ``` -게스트 페이지의 `User-Agent`를 설정합니다. 페이지가 로드된 후엔 `setUserAgent` 메소드를 사용해서 변경할 수 있습니다. +페이지의 `User-Agent`를 설정합니다. 페이지가 로드된 후엔 `setUserAgent` 메소드를 사용해서 변경할 수 있습니다. -### disablewebsecurity +### `disablewebsecurity` ```html ``` -"on"으로 지정하면 게스트 페이지의 웹 보안을 해제합니다. +"on"으로 지정하면 페이지의 웹 보안을 해제합니다. -## API +### `partition` -webview 메서드는 페이지 로드가 끝난 뒤에만 사용할 수 있습니다. +```html + + +``` + +페이지에서 사용하는 세션을 설정합니다. +만약 `partition` 속성이 `persist:` 접두사를 시작하면 같은 `partition` 속성을 가진 앱 내 모든 페이지가 공유하는 영구 세션을 사용합니다. +`persist:` 접두사가 없을 경우 페이지는 인 메모리 세션을 사용합니다. +동일한 `partition`을 지정하여 다중 페이지에서 동일한 세션을 공유할 수 있도록 할 수 있습니다. +만약 `partition`이 지정되지 않으면 앱의 기본 세션을 사용합니다. + +이 값은 첫 탐색 이전에만 지정할 수 있습니다. +즉. 작동중인 랜더러 프로세스의 세션은 변경할 수 없습니다. +이후 이 값을 바꾸려고 시도하면 DOM 예외를 발생시킵니다. + +## Methods + +`webview` 태그는 다음과 같은 메서드를 가지고 있습니다: + +**참고:** 태그 객체의 메서드는 페이지 로드가 끝난 뒤에만 사용할 수 있습니다. **예제** ```javascript @@ -127,229 +148,241 @@ webview.addEventListener("dom-ready", function() { }); ``` -### ``.getUrl() +### `.getUrl()` -게스트 페이지의 URL을 반환합니다. +페이지의 URL을 반환합니다. -### ``.getTitle() +### `.getTitle()` -게스트 페이지의 제목을 반환합니다. +페이지의 제목을 반환합니다. -### ``.isLoading() +### `.isLoading()` -페이지가 아직 리소스를 로딩하고 있는지 확인합니다. +페이지가 아직 리소스를 로딩하고 있는지 확인합니다. 불린 값을 반환합니다. -### ``.isWaitingForResponse() +### `.isWaitingForResponse()` -게스트 페이지가 메인 리소스의 첫 응답을 기다리고 있는지 확인합니다. +페이지가 메인 리소스의 첫 응답을 기다리고 있는지 확인합니다. 불린 값을 반환합니다. -### ``.stop() +### `.stop()` 모든 탐색을 취소합니다. -### ``.reload() +### `.reload()` 페이지를 새로고침합니다. -### ``.reloadIgnoringCache() +### `.reloadIgnoringCache()` 캐시를 무시하고 페이지를 새로고침합니다. -### ``.canGoBack() +### `.canGoBack()` -페이지 히스토리를 한 칸 뒤로 가기를 할 수 있는지 확인합니다. +페이지 히스토리를 한 칸 뒤로 가기를 할 수 있는지 확인합니다. 불린 값을 반환합니다. -### ``.canGoForward() +### `.canGoForward()` -페이지 히스토리를 한 칸 앞으로 가기를 할 수 있는지 확인합니다. +페이지 히스토리를 한 칸 앞으로 가기를 할 수 있는지 확인합니다. 불린 값을 반환합니다. -### ``.canGoToOffset(offset) +### `.canGoToOffset(offset)` * `offset` Integer -페이지 히스토리를 `offset` 만큼 이동할 수 있는지 확인합니다. +페이지 히스토리를 `offset` 만큼 이동할 수 있는지 확인합니다. 불린값을 반환합니다. -### ``.clearHistory() +### `.clearHistory()` 탐색 히스토리를 비웁니다. -### ``.goBack() +### `.goBack()` 페이지 뒤로 가기를 실행합니다. -### ``.goForward() +### `.goForward()` 페이지 앞으로 가기를 실행합니다. -### ``.goToIndex(index) +### `.goToIndex(index)` * `index` Integer 페이지를 지정한 `index`로 이동합니다. -### ``.goToOffset(offset) +### `.goToOffset(offset)` * `offset` Integer -현재 페이지로 부터 `offset` 만큼 이동합니다. +페이지로부터 `offset` 만큼 이동합니다. -### ``.isCrashed() +### `.isCrashed()` 랜더러 프로세스가 크래시 됬는지 확인합니다. -### ``.setUserAgent(userAgent) +### `.setUserAgent(userAgent)` * `userAgent` String `User-Agent`를 지정합니다. -### ``.getUserAgent() +### `.getUserAgent()` -현재 페이지의 `User-Agent` 문자열을 가져옵니다. +페이지의 `User-Agent 문자열`을 가져옵니다. -### ``.insertCSS(css) +### `.insertCSS(css)` * `css` String -게스트 페이지에 CSS를 삽입합니다. +페이지에 CSS를 삽입합니다. -### ``.executeJavaScript(code[, userGesture]) +### `.executeJavaScript(code[, userGesture])` * `code` String * `userGesture` Boolean -게스트 페이지에서 자바스크립트 `code`를 실행합니다. +페이지에서 자바스크립트 `code`를 실행합니다. -`userGesture`가 `true`로 설정되어 있으면 `requestFullScreen` HTML API 같이 -유저의 승인이 필요한 API를 유저의 승인을 무시하고 개발자가 API를 직접 사용할 수 있습니다. +만약 `userGesture`가 `true`로 설정되어 있으면 페이지에 유저 제스쳐 컨텍스트를 만듭니다. +이 옵션을 활성화 시키면 `requestFullScreen`와 같은 HTML API에서 유저의 승인을 무시하고 개발자가 API를 바로 사용할 수 있도록 허용합니다. 역주: 기본적으로 브라우저에선 전체화면, 웹캠, 파일 열기등의 API를 사용하려면 유저의 승인(이벤트)이 필요합니다. -### ``.openDevTools() +### `.openDevTools()` -게스트 페이지에 대한 개발자 툴을 엽니다. +페이지에 대한 개발자 콘솔을 엽니다. -### ``.closeDevTools() +### `.closeDevTools()` -게스트 페이지에 대한 개발자 툴을 닫습니다. +페이지에 대한 개발자 콘솔을 닫습니다. -### ``.isDevToolsOpened() +### `.isDevToolsOpened()` -게스트 페이지에 대한 개발자 툴이 열려있는지 확인합니다. +페이지에 대한 개발자 콘솔이 열려있는지 확인합니다. 불린 값을 반환합니다. -### ``.inspectElement(x, y) +### `.inspectElement(x, y)` * `x` Integer * `y` Integer (`x`, `y`) 위치에 있는 엘리먼트를 inspect합니다. -### ``.inspectServiceWorker() +### `.inspectServiceWorker()` -Service worker에 대한 개발자 툴을 엽니다. +Service worker에 대한 개발자 콘솔을 엽니다. -### ``.undo() +### `.undo()` 페이지에서 실행 취소 커맨드를 실행합니다. -### ``.redo() +### `.redo()` 페이지에서 다시 실행 커맨드를 실행합니다. -### ``.cut() +### `.cut()` 페이지에서 잘라내기 커맨드를 실행합니다. -### ``.copy() +### `.copy()` 페이지에서 복사 커맨드를 실행합니다. -### ``.paste() +### `.paste()` 페이지에서 붙여넣기 커맨드를 실행합니다. -### ``.pasteAndMatchStyle() +### `.pasteAndMatchStyle()` 페이지에서 `pasteAndMatchStyle` 편집 커맨드를 실행합니다. -### ``.delete() +### `.delete()` 페이지에서 삭제 커맨드를 실행합니다. -### ``.selectAll() +### `.selectAll()` 페이지에서 전체 선택 커맨드를 실행합니다. -### ``.unselect() +### `.unselect()` 페이지에서 `unselect` 커맨드를 실행합니다. -### ``.replace(text) +### `.replace(text)` * `text` String 페이지에서 `replace` 커맨드를 실행합니다. -### ``.replaceMisspelling(text) +### `.replaceMisspelling(text)` * `text` String 페이지에서 `replaceMisspelling` 커맨드를 실행합니다. -### ``.print([options]) +### `.print([options])` Webview 페이지를 인쇄합니다. `webContents.print([options])` 메서드와 같습니다. -### ``.printToPDF(options, callback) +### `.printToPDF(options, callback)` Webview 페이지를 PDF 형식으로 인쇄합니다. `webContents.printToPDF(options, callback)` 메서드와 같습니다. -### ``.send(channel[, args...]) +### `.send(channel[, args...])` * `channel` String +* `args` (optional) -`channel`을 통해 게스트 페이지에 `args...` 비동기 메시지를 보냅니다. -게스트 페이지에선 `ipc` 모듈의 `channel` 이벤트를 사용하면 이 메시지를 받을 수 있습니다. +`channel`을 통해 페이지에 `args` 비동기 메시지를 보냅니다. +페이지에선 `ipc` 모듈의 `channel` 이벤트를 사용하면 이 메시지를 받을 수 있습니다. -예제는 [WebContents.send](browser-window.md#webcontentssendchannel-args)를 참고하세요. +예제는 [WebContents.send](web-contents.md#webcontentssendchannel-args)를 참고하세요. ## DOM 이벤트 -### load-commit +`webview` 태그는 다음과 같은 DOM 이벤트를 가지고 있습니다: + +### Event: 'load-commit' + +Returns: * `url` String * `isMainFrame` Boolean -Fired when a load has committed. This includes navigation within the current -document as well as subframe document-level loads, but does not include -asynchronous resource loads. +로드가 시작됬을 때 발생하는 이벤트입니다. +이 이벤트는 현재 문서내의 탐색뿐만 아니라 서브 프레임 문서 레벨의 로드도 포함됩니다. +하지만 비동기 리소스 로드는 포함되지 않습니다. -### did-finish-load +### Event: 'did-finish-load' -탐색이 끝나면 발생하는 이벤트입니다. 브라우저 탭의 스피너가 멈추고 `onload` 이벤트가 발생될 때를 생각하면 됩니다. +탐색이 끝나면 발생하는 이벤트입니다. 브라우저 탭의 스피너가 멈추고 `onload` 이벤트가 발생할 때를 생각하면 됩니다. -### did-fail-load +### Event: 'did-fail-load' + +Returns: * `errorCode` Integer * `errorDescription` String +* `validatedUrl` String `did-finish-load`와 비슷합니다. 하지만 이 이벤트는 `window.stop()`과 같은 무언가로 인해 로드에 실패했을 때 발생하는 이벤트입니다. -### did-frame-finish-load +### Event: 'did-frame-finish-load' + +Returns: * `isMainFrame` Boolean 프레임의 탐색이 끝나면 발생하는 이벤트입니다. -### did-start-loading +### Event: 'did-start-loading' 브라우저 탭의 스피너가 돌기 시작할 때 처럼 페이지의 로드가 시작될 때 발생하는 이벤트입니다. -### did-stop-loading +### Event: 'did-stop-loading' 브라우저 탭의 스피너가 멈출 때 처럼 페이지의 로드가 끝나면 발생하는 이벤트입니다. -### did-get-response-details +### Event: 'did-get-response-details' + +Returns: * `status` Boolean * `newUrl` String @@ -362,7 +395,9 @@ asynchronous resource loads. 요청한 리소스에 관해 자세한 내용을 알 수 있을 때 발생하는 이벤트입니다. `status`는 리소스를 다운로드할 소켓 커낵션을 나타냅니다. -### did-get-redirect-request +### Event: 'did-get-redirect-request' + +Returns: * `oldUrl` String * `newUrl` String @@ -370,32 +405,38 @@ asynchronous resource loads. 리소스를 요청하고 받는 도중에 리다이렉트가 생기면 발생하는 이벤트입니다. -### dom-ready +### Event: 'dom-ready' -현재 프레임 문서의 로드가 끝나면 발생하는 이벤트입니다. +프레임 문서의 로드가 끝나면 발생하는 이벤트입니다. -### page-title-set +### Event: 'page-title-set' + +Returns: * `title` String * `explicitSet` Boolean 탐색하는 동안에 페이지의 제목이 설정되면 발생하는 이벤트입니다. `explicitSet`는 파일 URL에서 종합(synthesised)된 제목인 경우 false로 표시됩니다. -### page-favicon-updated +### Event: 'page-favicon-updated' -* `favicons` Array - Array of Urls +Returns: + +* `favicons` Array - URL 배열 페이지가 favicon URL을 받았을 때 발생하는 이벤트입니다. -### enter-html-full-screen +### Event: 'enter-html-full-screen' 페이지가 HTML API에 의해 전체 화면 모드에 돌입했을 때 발생하는 이벤트입니다. -### leave-html-full-screen +### Event: 'leave-html-full-screen' 페이지의 전체 화면 모드가 해제됬을 때 발생하는 이벤트입니다. -### console-message +### Event: 'console-message' + +Returns: * `level` Integer * `message` String @@ -412,14 +453,16 @@ webview.addEventListener('console-message', function(e) { }); ``` -### new-window +### Event: 'new-window' + +Returns: * `url` String * `frameName` String * `disposition` String - Can be `default`, `foreground-tab`, `background-tab`, `new-window` and `other` -게스트 페이지가 새로운 브라우저 창을 생성할 때 발생하는 이벤트입니다. +페이지가 새로운 브라우저 창을 생성할 때 발생하는 이벤트입니다. 다음 예제 코드는 새 URL을 시스템의 기본 브라우저로 여는 코드입니다. @@ -429,11 +472,11 @@ webview.addEventListener('new-window', function(e) { }); ``` -### close +### Event: 'close' -게스트 페이지가 자체적으로 닫힐 때 발생하는 이벤트입니다. +페이지가 자체적으로 닫힐 때 발생하는 이벤트입니다. -다음 예제 코드는 게스트 페이지가 자체적으로 닫힐 때 `webview`를 `about:blank` 페이지로 이동시키는 예제입니다. +다음 예제 코드는 페이지가 자체적으로 닫힐 때 `webview`를 `about:blank` 페이지로 이동시키는 예제입니다. ```javascript webview.addEventListener('close', function() { @@ -441,7 +484,9 @@ webview.addEventListener('close', function() { }); ``` -### ipc-message +### Event: 'ipc-message' + +Returns: * `channel` String * `args` Array @@ -467,21 +512,23 @@ ipc.on('ping', function() { }); ``` -### crashed +### Event: 'crashed' 랜더러 프로세스가 크래시 되었을 때 발생하는 이벤트입니다. -### gpu-crashed +### Event: 'gpu-crashed' GPU 프로세스가 크래시 되었을 때 발생하는 이벤트입니다. -### plugin-crashed +### Event: 'plugin-crashed' + +Returns: * `name` String * `version` String 플러그인 프로세스가 크래시 되었을 때 발생하는 이벤트입니다. -### destroyed +### Event: 'destroyed' WebContents가 파괴될 때 발생하는 이벤트입니다. diff --git a/docs-translations/ko/api/window-open.md b/docs-translations/ko/api/window-open.md index 6d7c0b9fabbe..a4cf3bce5c93 100644 --- a/docs-translations/ko/api/window-open.md +++ b/docs-translations/ko/api/window-open.md @@ -1,20 +1,20 @@ -# `window.open` 메서드 +# `window.open` 함수 -`window.open` 메서드가 호출되면 새 창을 생성하고 `url` 페이지를 불러옵니다. +`window.open` 함수가 호출되면 새 창을 생성하고 `url` 페이지를 불러옵니다. 이 창은 지정한 `url`을 로드하여 만들어진 `BrowserWindow`의 새 인스턴스이며 본래 창 객체 대신 페이지의 컨트롤이 제한된 프록시 객체를 반환합니다. 프록시 객체는 브라우저의 웹 페이지 창과 호환될 수 있도록 일부 제한된 표준 기능만 가지고 있습니다. -창의 모든 컨트롤을 가지려면 `BrowserWindow`를 직접 생성하여 작업해야 합니다. +창의 모든 컨트롤 권한을 가지려면 `BrowserWindow`를 직접 생성해서 사용해야 합니다. -## window.open(url, [frameName[, features]]) +### `window.open(url[, frameName][, features])` * `url` String -* `frameName` String -* `features` String +* `frameName` String (optional) +* `features` String (optional) `BrowserWindowProxy` 클래스의 객체를 반환하는 새로운 윈도우를 생성합니다. -## window.opener.postMessage(message, targetOrigin) +### `window.opener.postMessage(message, targetOrigin)` * `message` String * `targetOrigin` String @@ -23,31 +23,31 @@ ## Class: BrowserWindowProxy -### BrowserWindowProxy.blur() +### `BrowserWindowProxy.blur()` 자식 윈도우의 포커스를 해제합니다. -### BrowserWindowProxy.close() +### `BrowserWindowProxy.close()` 자식 윈도우를 강제로 닫습니다. unload 이벤트가 발생하지 않습니다. Forcefully closes the child window without calling its unload event. -### BrowserWindowProxy.closed +### `BrowserWindowProxy.closed` 자식 윈도우가 닫히면 true로 설정됩니다. -### BrowserWindowProxy.eval(code) +### `BrowserWindowProxy.eval(code)` * `code` String 자식 윈도우에서 특정 스크립트를 실행합니다. -### BrowserWindowProxy.focus() +### `BrowserWindowProxy.focus()` 자식 윈도우에 포커스를 맞춥니다. (창을 맨 앞으로 가져옵니다) -### BrowserWindowProxy.postMessage(message, targetOrigin) +### `BrowserWindowProxy.postMessage(message, targetOrigin)` * `message` String * `targetOrigin` String diff --git a/docs-translations/ko/development/atom-shell-vs-node-webkit.md b/docs-translations/ko/development/atom-shell-vs-node-webkit.md index aa0d3e19058f..ec35a2dbf1f4 100644 --- a/docs-translations/ko/development/atom-shell-vs-node-webkit.md +++ b/docs-translations/ko/development/atom-shell-vs-node-webkit.md @@ -1,15 +1,16 @@ -# NW.js와 기술적으로 다른점 (이전 node-webkit) +# Electron이 NW.js(node-webkit)와 기술적으로 다른점 __주의: Electron은 Atom Shell의 새로운 이름입니다.__ -NW.js 처럼 Electron은 JavaScript와 HTML 그리고 Node 통합환경을 제공함으로써 웹 페이지에서 저수준 시스템에 접근할 수 있는 웹 기반 데스크탑 어플리케이션을 작성할 수 있도록 합니다. +NW.js 처럼 Electron은 JavaScript와 HTML 그리고 Node 통합 환경을 제공함으로써 +웹 페이지에서 저 수준 시스템에 접근할 수 있도록 하여 웹 기반 데스크탑 어플리케이션을 작성할 수 있도록 하는 프레임워크 입니다. 하지만 Electron과 NW.js는 근본적인 개발흐름의 차이도 있습니다: __1. 어플리케이션의 엔트리 포인트__ NW.js에선 어플리케이션의 엔트리 포인트로 웹 페이지를 사용합니다. -`package.json`내의 main 필드에 메인 웹 페이지(index.html) 파일을 지정하면 어플리케이션의 메인 윈도우로 열리게 됩니다. +`package.json`내의 main 필드에 메인 웹 페이지(index.html) URL을 지정하면 어플리케이션의 메인 윈도우로 열리게 됩니다. Electron에선 JavaScript를 엔트리 포인트로 사용합니다. URL을 직접 제공하는 대신 API를 사용하여 직접 브라우저 창과 HTML 파일을 로드할 수 있습니다. 또한 윈도우의 종료시기를 결정하는 이벤트를 리스닝해야합니다. diff --git a/docs-translations/ko/development/build-instructions-linux.md b/docs-translations/ko/development/build-instructions-linux.md index e02c1341f993..cb254a80596d 100644 --- a/docs-translations/ko/development/build-instructions-linux.md +++ b/docs-translations/ko/development/build-instructions-linux.md @@ -1,11 +1,13 @@ # 빌드 설명서 (Linux) +이 가이드는 Linux 운영체제에서 Electron을 빌드하는 방법을 설명합니다. + ## 빌드전 요구사양 * Python 2.7.x. 몇몇 CentOS와 같은 배포판들은 아직도 Python 2.6.x 버전을 사용합니다. 그래서 `python -V`를 통해 버전을 확인해 줄 필요가 있습니다. * Node.js v0.12.x. Node를 설치하는 방법은 여러가지가 있습니다. 그중 하나는 [Node.js](http://nodejs.org) 사이트에서 소스코드를 받아 빌드하는 방법입니다. -이렇게 하면 Node를 일반 유저로 홈 디렉터리에 설치할 수 있습니다. 또는 [NodeSource](https://nodesource.com/blog/nodejs-v012-iojs-and-the-nodesource-linux-repositories)에서 소스 파일을 받아올 수 있습니다. -자세한 내용은 [Node.js 설치 방법](https://github.com/joyent/node/wiki/Installation) 을 참고하세요. + 이렇게 하면 Node를 일반 유저로 홈 디렉터리에 설치할 수 있습니다. 또는 [NodeSource](https://nodesource.com/blog/nodejs-v012-iojs-and-the-nodesource-linux-repositories)에서 소스 파일을 받아올 수 있습니다. + 자세한 내용은 [Node.js 설치 방법](https://github.com/joyent/node/wiki/Installation) 을 참고하세요. * Clang 3.4 또는 최신 버전 * GTK+ 와 libnotify의 개발용 헤더 @@ -54,7 +56,7 @@ $ ./script/bootstrap.py -v ### 크로스 컴파일 -`arm` 아키텍쳐로 빌드 하려면 먼저 종속성 라이브러리를 설치해야 합니다: +`arm` 아키텍쳐로 빌드 하려면 다음 종속성 라이브러리를 설치해야 합니다: ```bash $ sudo apt-get install libc6-dev-armhf-cross linux-libc-dev-armhf-cross \ @@ -84,7 +86,7 @@ $ ./script/create-dist.py ``` 이 스크립트는 매우 작은 배포판을 `dist` 디렉터리에 생성합니다. -create-dist.py 스크립트를 실행한 이후 1.3GB를 초과하는 공간을 차지하는 out/R 폴더의 실행파일 바이너리는 삭제해도 됩니다. +create-dist.py 스크립트를 실행한 이후부턴 1.3GB를 초과하는 공간을 차지하는 `out/R` 폴더의 바이너리는 삭제해도 됩니다. 또는 `Debug` 타겟만 빌드 할 수 있습니다: @@ -109,7 +111,7 @@ $ ./script/clean.py ## libtinfo.so.5 동적 링크 라이브러리를 로드하는 도중 에러가 발생할 경우 미리 빌드된 `clang`은 `libtinfo.so.5`로 링크를 시도합니다. -플랫폼에 따라 적당한 `libncurses` symlink를 추가하세요. +따라서 플랫폼에 따라 적당한 `libncurses` symlink를 추가하세요: ```bash $ sudo ln -s /usr/lib/libncurses.so.5 /usr/lib/libtinfo.so.5 diff --git a/docs-translations/ko/development/build-instructions-mac.md b/docs-translations/ko/development/build-instructions-osx.md similarity index 76% rename from docs-translations/ko/development/build-instructions-mac.md rename to docs-translations/ko/development/build-instructions-osx.md index eeed5a4df4ec..4951b975ae33 100644 --- a/docs-translations/ko/development/build-instructions-mac.md +++ b/docs-translations/ko/development/build-instructions-osx.md @@ -1,12 +1,14 @@ -# 빌드 설명서 (Mac) +# 빌드 설명서 (OS X) + +이 가이드는 OS X 운영체제에서 Electron을 빌드하는 방법을 설명합니다. ## 빌드전 요구 사항 * OS X >= 10.8 * [Xcode](https://developer.apple.com/technologies/tools/) >= 5.1 -* [node.js](http://nodejs.org) (external). +* [node.js](http://nodejs.org) (external) -만약 Homebrew를 이용해 파이선을 설치했다면 다음 파이선 모듈도 같이 설치해야 합니다: +만약 Homebrew를 이용해 파이선을 설치했다면 다음 Python 모듈도 같이 설치해야 합니다: * pyobjc @@ -44,7 +46,7 @@ $ ./script/build.py -c D ## 32비트 지원 -Electron은 현재 OS X 64비트 빌드만 지원하고 있습니다. 그리고 앞으로도 OS X 32비트는 지원할 계획이 없습니다. +Electron은 현재 OS X 64비트만 지원하고 있습니다. 그리고 앞으로도 OS X 32비트는 지원할 계획이 없습니다. ## 테스트 diff --git a/docs-translations/ko/development/build-instructions-windows.md b/docs-translations/ko/development/build-instructions-windows.md index 22734b1ec236..fa165ca153ac 100644 --- a/docs-translations/ko/development/build-instructions-windows.md +++ b/docs-translations/ko/development/build-instructions-windows.md @@ -1,25 +1,29 @@ # 빌드 설명서 (Windows) +이 가이드는 Windows 운영체제에서 Electron을 빌드하는 방법을 설명합니다. + ## 빌드전 요구 사항 * Windows 7 / Server 2008 R2 또는 최신 버전 * Visual Studio 2013 - [VS 2013 커뮤니티 에디션 무료 다운로드](http://www.visualstudio.com/products/visual-studio-community-vs) * [Python 2.7](http://www.python.org/download/releases/2.7/) * [Node.js](http://nodejs.org/download/) -* [git](http://git-scm.com) +* [Git](http://git-scm.com) -현재 Windows를 설치하지 않았다면 [modern.ie](https://www.modern.ie/en-us/virtualization-tools#downloads)에서 +현재 사용하고 있는 PC에 Windows를 설치하지 않았다면 [modern.ie](https://www.modern.ie/en-us/virtualization-tools#downloads)에서 사용 기한이 정해져있는 무료 가상머신 버전의 Windows를 받아 Electron을 빌드하는 방법도 있습니다. -Electron은 전적으로 command-line 스크립트를 사용하여 빌드합니다. 그렇기에 Electron을 개발하는데 아무런 에디터나 사용할 수 있습니다. -하지만 이 말은 Visual Studio를 개발을 위해 사용할 수 없다는 말이 됩니다. 나중에 Visual Studio를 이용한 빌드 방법도 제공할 예정입니다. +Electron은 모든 빌드를 command-line 스크립트를 통해 빌드합니다. 따라서 빌드에 Visual Studio를 사용할 수 없습니다. +하지만 여전히 Electron을 개발할 땐 아무 에디터나 사용할 수 있습니다. 빠른 시일내에 Visual Studio를 이용한 빌드도 지원할 계획입니다. -**참고:** Visual Studio가 빌드에 사용되지 않더라도 제공된 빌드 툴체인이 **필수적으로** 사용되므로 여전히 필요합니다. +**참고:** Visual Studio가 직접 빌드에 사용되지 않더라도 IDE와 같이 제공된 빌드 툴체인이 빌드에 **필수적으로** 사용되므로 여전히 필요합니다. + +**참고:** Visual Studio 2015는 사용할 수 없습니다. MSVS **2013**을 사용하고 있는지 확인해주세요. ## 코드 가져오기 ```powershell -git clone https://github.com/atom/electron.git +$ git clone https://github.com/atom/electron.git ``` ## 부트 스트랩 @@ -28,8 +32,8 @@ git clone https://github.com/atom/electron.git 참고로 Electron은 빌드 툴체인으로 `ninja`를 사용하므로 Visual Studio 프로젝트는 생성되지 않습니다. ```powershell -cd electron -python script\bootstrap.py -v +$ cd electron +$ python script\bootstrap.py -v ``` ## 빌드 하기 @@ -37,13 +41,13 @@ python script\bootstrap.py -v `Release` 와 `Debug` 두 타겟 모두 빌드 합니다: ```powershell -python script\build.py +$ python script\build.py ``` 또는 `Debug` 타겟만 빌드 할 수 있습니다: ```powershell -python script\build.py -c D +$ python script\build.py -c D ``` 빌드가 모두 끝나면 `out/D` (디버그 타겟) 또는 `out/R` (릴리즈 타겟) 디렉터리에서 `electron.exe` 실행 파일을 찾을 수 있습니다. @@ -53,7 +57,7 @@ python script\build.py -c D 64비트를 타겟으로 빌드 하려면 부트스트랩 스크립트를 실행할 때 `--target_arch=x64` 인자를 같이 넘겨주면 됩니다: ```powershell -python script\bootstrap.py -v --target_arch=x64 +$ python script\bootstrap.py -v --target_arch=x64 ``` 다른 빌드 단계도 정확하게 같습니다. @@ -63,13 +67,13 @@ python script\bootstrap.py -v --target_arch=x64 프로젝트 코딩 스타일을 확인하려면: ```powershell -python script\cpplint.py +$ python script\cpplint.py ``` 테스트를 실행하려면: ```powershell -python script\test.py +$ python script\test.py ``` 테스트 실행시 `runas`와 같은 네이티브 모듈을 포함하는데 이 모듈은 디버그 빌드에서 같이 사용할 수 없습니다. @@ -78,7 +82,7 @@ python script\test.py 릴리즈 빌드로 테스트를 실행하려면 다음 커맨드를 사용하면 됩니다: ```powershell -python script\test.py -R +$ python script\test.py -R ``` ## 문제 해결 @@ -110,23 +114,24 @@ Traceback (most recent call last): subprocess.CalledProcessError: Command '['npm.cmd', 'install']' returned non-zero exit status 3 ``` -이 버그는 Cygwin python과 Win32 node를 같이 사용할 때 발생합니다. -부트스트랩 스크립트에서 Win32 python을 사용함으로써 이 문제를 해결할 수 있습니다 (`C:\Python27` 디렉터리에 python이 설치되었다는 것을 가정하면): +이 버그는 Cygwin Python과 Win32 Node를 같이 사용할 때 발생합니다. +부트스트랩 스크립트에서 Win32 Python을 사용함으로써 이 문제를 해결할 수 있습니다. +`C:\Python27` 디렉터리에 Python이 설치되었다는 가정하에 다음 명령을 실행하면 됩니다: ```bash -/cygdrive/c/Python27/python.exe script/bootstrap.py +$ /cygdrive/c/Python27/python.exe script/bootstrap.py ``` ### LNK1181: cannot open input file 'kernel32.lib' -32bit node.js를 다시 설치하세요. +32비트 Node.js를 다시 설치하세요. ### Error: ENOENT, stat 'C:\Users\USERNAME\AppData\Roaming\npm' 간단하게 해당 디렉터리를 생성하면 [문제가 해결될 겁니다](http://stackoverflow.com/a/25095327/102704): ```powershell -mkdir ~\AppData\Roaming\npm +$ mkdir ~\AppData\Roaming\npm ``` ### node-gyp is not recognized as an internal or external command diff --git a/docs-translations/ko/development/build-system-overview.md b/docs-translations/ko/development/build-system-overview.md index 7198fa831b92..34f93a8881bd 100644 --- a/docs-translations/ko/development/build-system-overview.md +++ b/docs-translations/ko/development/build-system-overview.md @@ -3,7 +3,7 @@ Electron은 프로젝트 생성을 위해 `gyp`를 사용하며 `ninja`를 이용하여 빌드합니다. 프로젝트 설정은 `.gyp` 와 `.gypi` 파일에서 볼 수 있습니다. -## gyp 파일들 +## gyp 파일 Electron을 빌드 할 때 `gyp` 파일들은 다음과 같은 규칙을 따릅니다: @@ -15,8 +15,8 @@ Electron을 빌드 할 때 `gyp` 파일들은 다음과 같은 규칙을 따릅 ## 구성요소 빌드 Chromium은 꽤나 큰 프로젝트입니다. 이 때문에 최종 링킹 작업은 상당한 시간이 소요될 수 있습니다. -이러한 문제로 인해 개발 시 빌드 작업을 까다롭게 만듭니다. 이 문제를 해결하기 위해 Chromium은 "component build"를 도입했습니다. -이는 각각의 컴포넌트를 각각 따로 분리하여 공유 라이브러리로 빌드 합니다. 이렇게 되면 링킹작업은 매우 빨라지지만 파일 크기와 성능이 느려집니다. +이 문제는 보통 개발을 어렵게 만듭니다. 우리는 이 문제를 해결하기 위해 Chromium의 "component build" 방식을 도입했습니다. +이는 각각의 컴포넌트를 각각 따로 분리하여 공유 라이브러리로 빌드 합니다. 하지만 이 방식을 사용하면 링킹 작업은 매우 빨라지지만 파일 크기와 성능이 느려집니다. Electron도 상당히 비슷한 접근을 했습니다: `Debug`빌드 시 바이너리는 공유 라이브러리 버전의 Chromium 컴포넌트를 사용해서 링크 속도를 높이고 @@ -28,7 +28,7 @@ Electron도 상당히 비슷한 접근을 했습니다: Prebuilt된 모든 Chromium 바이너리들은 부트스트랩 스크립트가 실행될 때 다운로드됩니다. 기본적으로 공유 라이브러리와 정적 라이브러리 모두 다운로드되며 최종 전체 파일 크기는 플랫폼에 따라 800MB에서 2GB까지 차지합니다. -기본적으로 libchromiumcontent는 Amazon Web Service를 통해 다운로드 됩니다. +기본적으로 (`libchromiumcontent`)는 Amazon Web Service를 통해 다운로드 됩니다. 만약 `LIBCHROMIUMCONTENT_MIRROR` 환경 변수가 설정되어 있으면 부트스트랩은 해당 링크를 사용하여 바이너리를 다운로드 합니다. [libchromiumcontent-qiniu-mirror](https://github.com/hokein/libchromiumcontent-qiniu-mirror)는 libchromiumcontent의 미러입니다. 만약 AWS에 접근할 수 없다면 `export LIBCHROMIUMCONTENT_MIRROR=http://7xk3d2.dl1.z0.glb.clouddn.com/`를 통해 다운로드 할 수 있습니다. @@ -43,9 +43,9 @@ $ ./script/build.py -c D ## 프로젝트 생성 (two-phrase) Electron은 `Release`와 `Debug` 빌드가 서로 다른 라이브러리 링크 방식을 사용합니다. -그러나 `gyp`는 따로 빌드 설정을 분리하여 라이브러리 링크 방식을 정의하는 것을 지원하지 않습니다. +하지만 `gyp`는 따로 빌드 설정을 분리하여 라이브러리 링크 방식을 정의하는 것을 지원하지 않습니다. -이러한 문제를 해결하기 위해 Electron은 링크 설정을 제어하는 `gyp` 변수 `libchromiumcontent_component`를 사용하고 `gyp`를 실행할 때 단 하나의 타겟만을 생성합니다. +이 문제를 해결하기 위해 Electron은 링크 설정을 제어하는 `gyp` 변수 `libchromiumcontent_component`를 사용하고 `gyp`를 실행할 때 단 하나의 타겟만 생성합니다. ## 타겟 이름 diff --git a/docs-translations/ko/development/coding-style.md b/docs-translations/ko/development/coding-style.md index 1b88be8487c1..0dc16ba0ad68 100644 --- a/docs-translations/ko/development/coding-style.md +++ b/docs-translations/ko/development/coding-style.md @@ -1,21 +1,24 @@ # 코딩 스타일 +이 가이드는 Electron의 코딩 스타일에 관해 설명합니다. + ## C++과 Python -C++과 Python스크립트는 Chromium의 [코딩 스타일](http://www.chromium.org/developers/coding-style)을 따릅니다. +C++과 Python 스크립트는 Chromium의 [코딩 스타일](http://www.chromium.org/developers/coding-style)을 따릅니다. 파이선 스크립트 `script/cpplint.py`를 사용하여 모든 파일이 해당 코딩스타일에 맞게 코딩 되었는지 확인할 수 있습니다. -파이선의 버전은 2.7을 사용합니다. +Python 버전은 2.7을 사용합니다. -C++ 코드는 많은 Chromium의 추상화와 타입을 사용합니다. 그래서 이에 대해 잘 알고 있어야 합니다. +C++ 코드는 많은 Chromium의 추상화와 타입을 사용합니다. 따라서 Chromium 코드에 대해 잘 알고 있어야 합니다. 이와 관련하여 시작하기 좋은 장소로 Chromium의 [Important Abstractions and Data Structures] (https://www.chromium.org/developers/coding-style/important-abstractions-and-data-structures) 문서가 있습니다. -이 문서에선 몇가지 특별한 타입과 스코프 타입(스코프 밖으로 나가면 자동으로 메모리에서 할당을 해제합니다. 스마트 포인터로 보시면 됩니다), -로깅 메커니즘 등을 언급하고 있습니다. +이 문서에선 몇가지 특별한 타입과 스코프 타입(스코프 밖으로 나가면 자동으로 메모리에서 할당을 해제합니다. 스마트 포인터로 보시면 됩니다) +그리고 로깅 메커니즘 등을 언급하고 있습니다. ## CoffeeScript -CoffeeScript의 경우 GitHub의 [스타일 가이드](https://github.com/styleguide/javascript)를 따릅니다. 동시에 다음 규칙도 따릅니다: +CoffeeScript의 경우 GitHub의 [스타일 가이드](https://github.com/styleguide/javascript)를 기본으로 따릅니다. +그리고 다음 규칙을 따릅니다: * Google의 코딩 스타일에도 맞추기 위해 파일의 끝에는 **절대** 개행을 삽입해선 안됩니다. * 파일 이름의 공백은 `_`대신에 `-`을 사용하여야 합니다. 예를 들어 `file_name.coffee`를 diff --git a/docs-translations/ko/development/source-code-directory-structure.md b/docs-translations/ko/development/source-code-directory-structure.md index f0c9cde40780..f31d0847db75 100644 --- a/docs-translations/ko/development/source-code-directory-structure.md +++ b/docs-translations/ko/development/source-code-directory-structure.md @@ -1,40 +1,43 @@ # 소스 코드 디렉터리 구조 -## 개요 - -Electron의 소스 코드는 몇 개의 파트로 분리되어 있습니다. 우리는 Chromium의 분리 규칙(separation conventions)을 주로 따르고 있습니다. +Electron의 소스 코드는 몇 개의 파트로 분리되어 있습니다. 그리고 Chromium의 분리 규칙(separation conventions)을 주로 따르고 있습니다. 이미 [Chromium의 멀티 프로세스 아키텍쳐](http://dev.chromium.org/developers/design-documents/multi-process-architecture)에 익숙해져 있다면 소스 코드를 이해하기 쉬울 것입니다. ## 소스 코드 구조 -* **atom** - Electron의 소스코드. - * **app** - 시스템 엔트리 코드. - * **browser** - 주 윈도우를 포함한 프론트엔드, UI, 그리고 메인 프로세스에 관련된 것들. 주 랜더러와 웹 페이지 관리관련 코드. - * **lib** - 메인 프로세스 초기화 코드의 자바스크립트 파트. - * **ui** - 크로스 플랫폼에 대응하는 UI 구현. - * **cocoa** - 코코아 특정 소스 코드. - * **gtk** - GTK+ 특정 소스 코드. - * **win** - Windows GUI 특정 소스 코드. - * **default_app** - 어플리케이션이 제공되지 않으면 기본적으로 사용될 페이지. - * **api** - 메인 프로세스 API들의 구현. - * **lib** - API 구현의 자바스크립트 파트. - * **net** - 네트워크 관련 코드. - * **mac** - Mac 특정 Objective-C 소스 코드. - * **resources** - 아이콘들, 플랫폼 종속성 파일들, 기타 등등. - * **renderer** - 렌더러 프로세스에서 작동하는 코드들. - * **lib** - 렌더러 프로세스 초기화 코드의 자바스크립트 파트. - * **api** - 렌더러 프로세스 API들의 구현. - * **lib** - API 구현의 자바스크립트 파트. - * **common** - 메인 프로세스와 렌더러 프로세스에서 공유하는 코드. 유틸리티 함수와 node 메시지 루프를 Chromium의 메시지 루프에 통합시킨 코드가 포함. - * **lib** - 공통 자바스크립트 초기화 코드. - * **api** - 공통 API들의 구현, Electron의 빌트인 모듈 기초 코드들. - * **lib** - API 구현의 자바스크립트 파트. -* **chromium_src** - 복사된 Chromium 소스 코드. -* **docs** - 참조 문서. -* **spec** - 자동화된 테스트. -* **atom.gyp** - Electron의 빌드 규칙. -* **common.gypi** - 컴파일러 설정 및 `node` 와 `breakpad` 등의 구성요소를 위한 빌드 규칙. +``` +Electron +├──atom - Electron의 소스코드. +| ├── app - 시스템 엔트리 코드. +| ├── browser - 주 윈도우를 포함한 프론트엔드, UI, 그리고 메인 프로세스에 관련된 것들. +| | | 랜더러와 웹 페이지 관리 관련 코드. +| | ├── lib - 메인 프로세스 초기화 코드의 자바스크립트 파트. +| | ├── ui - 크로스 플랫폼에 대응하는 UI 구현. +| | | ├── cocoa - 코코아 특정 소스 코드. +| | | ├── gtk - GTK+ 특정 소스 코드. +| | | └── win - Windows GUI 특정 소스 코드. +| | ├── default_app - 어플리케이션이 제공되지 않으면 기본으로 사용되는 페이지. +| | ├── api - 메인 프로세스 API의 구현. +| | | └── lib - API 구현의 자바스크립트 파트. +| | ├── net - 네트워크 관련 코드. +| | ├── mac - Mac 특정 Objective-C 소스 코드. +| | └── resources - 아이콘들, 플랫폼 종속성 파일들, 기타 등등. +| ├── renderer - 랜더러 프로세스에서 작동하는 코드들. +| | ├── lib - 랜더러 프로세스 초기화 코드의 자바스크립트 파트. +| | └── api - 랜더러 프로세스 API들의 구현. +| | └── lib - API 구현의 자바스크립트 파트. +| └── common - 메인 프로세스와 랜더러 프로세스에서 공유하는 코드. +| | 유틸리티 함수와 node 메시지 루프를 Chromium의 메시지 루프에 통합시킨 코드도 포함. +| ├── lib - 공통 자바스크립트 초기화 코드. +| └── api - 공통 API들의 구현, Electron의 빌트인 모듈 기초 코드들. +| └── lib - API 구현의 자바스크립트 파트. +├── chromium_src - 복사된 Chromium 소스 코드. +├── docs - 참조 문서. +├── spec - 자동화된 테스트. +├── atom.gyp - Electron의 빌드 규칙. +└── common.gypi - 컴파일러 설정 및 `node` 와 `breakpad` 등의 구성요소를 위한 빌드 규칙. +``` ## 그외 디렉터리 구조 @@ -45,4 +48,4 @@ Electron의 소스 코드는 몇 개의 파트로 분리되어 있습니다. 우 * **node_modules** - 빌드에 사용되는 node 서드파티 모듈. * **out** - `ninja`의 임시 출력 디렉터리. * **dist** - 배포용 바이너리를 빌드할 때 사용하는 `script/create-dist.py` 스크립트로부터 만들어지는 임시 디렉터리. -* **external_binaries** - `gyp`를 통한 빌드가 지원하지 않아 따로 다운로드된 서드파티 프레임워크 바이너리들. +* **external_binaries** - `gyp` 빌드를 지원하지 않아 따로 다운로드된 서드파티 프레임워크 바이너리들. diff --git a/docs-translations/ko/styleguide.md b/docs-translations/ko/styleguide.md index 1168556a3d7b..aaa9274cd0b7 100644 --- a/docs-translations/ko/styleguide.md +++ b/docs-translations/ko/styleguide.md @@ -1,6 +1,6 @@ # Electron 문서 스타일 가이드 -[Electron 문서 읽기](#) 와 [Electron 문서 작성하기](#) 중 적당히 필요한 부분을 찾아 참고하세요: +[Electron 문서 읽기](#electron-문서-읽기) 와 [Electron 문서 작성하기](#electron-문서-작성하기) 중 이해가 필요한 부분을 찾아 참고하세요: ## Electron 문서 작성하기 @@ -22,6 +22,19 @@ Electron 문서를 작성하는 규칙은 다음과 같습니다. - 문장의 길이는 한 줄당 80 칸을 유지합니다. - 플랫폼 특정 메서드 헤더는 이탈릭체로 표시합니다. - ```### `method(foo, bar)` _OS X_``` +- 'on' 표현 대신 'in the ___ process' 형식의 표현을 지향합니다. + +### 번역된 참조 문서 + +번역된 Electron의 참조 문서는 `docs-translations` 디렉터리에 있습니다. + +아직 번역되지 않은 언어를 추가하려면 (일부분 포함): + +- 언어의 약어(예: en, ja, ko등)로 서브 디렉터리를 만듭니다. +- 서브 디렉터리에 `docs` 디렉터리를 복사합니다. 파일 이름과 디렉터리 구조는 모두 유지합니다. +- 문서를 번역합니다. +- `README.md`에 번역한 문서의 링크를 추가하고 업데이트 합니다. +- 메인 Electron의 [README](https://github.com/atom/electron#documentation-translations)에 번역된 디렉터리의 링크를 추가합니다. ## Electron 문서 읽기 diff --git a/docs-translations/ko/tutorial/application-distribution.md b/docs-translations/ko/tutorial/application-distribution.md index fac2ae48a140..69269500733a 100644 --- a/docs-translations/ko/tutorial/application-distribution.md +++ b/docs-translations/ko/tutorial/application-distribution.md @@ -1,7 +1,9 @@ # 어플리케이션 배포 -Electron 어플리케이션을 배포하려면 어플리케이션 폴더 이름을 `app`으로 지정한 후 Electron 실행파일의 리소스 디렉터리에 집어넣기만 하면 됩니다. -리소스 디렉터리는 OS X에선 `Electron.app/Contents/Resources/` Windows와 Linux에선 `resources/` 입니다. +Electron 어플리케이션을 배포하는 방법은 간단합니다. + +먼저 폴더 이름을 `app`로 지정한 후 Electron 리소스 디렉터리에 폴더를 통째로 집어넣기만 하면 됩니다. +리소스 디렉터리는 OS X: `Electron.app/Contents/Resources/` Windows와 Linux: `resources/` 입니다. 예제: @@ -32,7 +34,7 @@ electron/resources/app 어플리케이션의 소스코드가 사용자에게 노출되는 것을 방지할 수 있습니다. `asar` 아카이브를 사용할 땐 단순히 `app` 폴더 대신에 어플리케이션을 패키징한 `app.asar` 파일로 대체하면됩니다. -이렇게 하면 Electron은 아카이브를 `app`폴더 대신 asar 아카이브를 기반으로 어플리케이션을 실행합니다. +Electron은 자동으로 `app`폴더 대신 asar 아카이브를 기반으로 어플리케이션을 실행합니다. OS X의 경우: diff --git a/docs-translations/ko/tutorial/application-packaging.md b/docs-translations/ko/tutorial/application-packaging.md index 0f8169089516..d7a96dbb4b43 100644 --- a/docs-translations/ko/tutorial/application-packaging.md +++ b/docs-translations/ko/tutorial/application-packaging.md @@ -8,7 +8,7 @@ Windows에서 일어나는 긴 경로 이름에 대한 [issues](https://github.c [asar][asar] 아카이브는 tar과 비슷한 포맷으로 모든 리소스를 하나의 파일로 만듭니다. 그리고 Electron은 압축해제 없이 임의로 모든 파일을 읽어들일 수 있습니다. -다음 몇가지 단계를 통해 어플리케이션을 `asar` 아카이브로 압축할 수 있습니다: +간단한 작업을 통해 어플리케이션을 `asar` 아카이브로 압축할 수 있습니다: ### 1. asar 유틸리티 설치 @@ -24,13 +24,13 @@ $ asar pack your-app app.asar ## `asar` 아카이브 사용하기 -Electron은 Node.js로 부터 제공된 Node API와 Chromium으로부터 제공된 Web API 두가지의 API를 가지고 있습니다. -두 API 모두 `asar`에서 읽어들일 수 있도록 지원합니다. +Electron은 Node.js로 부터 제공된 Node API와 Chromium으로부터 제공된 Web API 두 가지 API를 가지고 있습니다. +따라서 `asar` 아카이브는 두 API 모두 사용할 수 있도록 지원합니다. ### Node API Electron에선 `fs.readFile`과 `require` 같은 Node API들을 지원하기 위해 `asar` 아카이브가 가상의 디렉터리 구조를 가지도록 -패치했습니다. 그래서 아카이브 내부에서 리소스들을 정상적인 파일 시스템처럼 접근할 수 있습니다. +패치했습니다. 그래서 아카이브 내부 리소스들을 정상적인 파일 시스템처럼 접근할 수 있습니다. 예를 들어 `/path/to`라는 경로에 `example.asar`라는 아카이브가 있다고 가정하면: diff --git a/docs-translations/ko/tutorial/debugging-main-process.md b/docs-translations/ko/tutorial/debugging-main-process.md index dcaf6bc9bf36..c11f3db04f3a 100644 --- a/docs-translations/ko/tutorial/debugging-main-process.md +++ b/docs-translations/ko/tutorial/debugging-main-process.md @@ -1,13 +1,15 @@ # 메인 프로세스 디버깅하기 -브라우저 창의 개발자 콘솔은 랜더러 프로세스의 스크립트만 디버깅이 가능합니다. (다시말해 웹 페이지) -메인 프로세스의 디버깅 방법을 제공하기 위해 Electron은 `--debug` 과 `--debug-brk` 스위치들을 제공합니다. +브라우저 창의 개발자 콘솔은 웹 페이지 같은 랜더러 프로세스의 스크립트만 디버깅이 가능합니다. +대신 Electron은 메인 프로세스의 디버깅을 위해 `--debug` 과 `--debug-brk` 스위치들을 제공합니다. ## 커맨드 라인 스위치(command line switches) +다음 스위치들을 사용하여 Electron의 메인 프로세스를 디버깅 할 수 있습니다: + ### `--debug=[port]` -이 스위치를 사용하면 Electron은 지정한 `port`에 V8 디버거 프로토콜을 리스닝합니다. `port`는 `5858`이 기본적으로 사용됩니다. +이 스위치를 사용하면 Electron은 지정한 `port`에 V8 디버거 프로토콜을 리스닝합니다. 기본 `port`는 `5858` 입니다. ### `--debug-brk=[port]` @@ -15,8 +17,9 @@ ## node-inspector로 디버깅 하기 -__주의:__ Electron은 node v0.11.13 버전을 사용합니다. node-inspector는 현재 아주 잘 작동하지 않습니다. -그리고 메인 프로세스의 `process`를 node-inspector 콘솔 내에서 검사할 경우 크래시가 발생할 수 있습니다. +__참고:__ Electron은 node v0.11.13 버전을 사용합니다. +그리고 현재 node-inspector 유틸리티와 호환성 문제가 있습니다. +추가로 node-inspector 콘솔 내에서 메인 프로세스의 `process` 객체를 탐색할 경우 크래시가 발생할 수 있습니다. ### 1. [node-inspector][node-inspector] 서버 시작 diff --git a/docs-translations/ko/tutorial/desktop-environment-integration.md b/docs-translations/ko/tutorial/desktop-environment-integration.md index 50b142f0bda1..94f0ffa013a7 100644 --- a/docs-translations/ko/tutorial/desktop-environment-integration.md +++ b/docs-translations/ko/tutorial/desktop-environment-integration.md @@ -7,7 +7,7 @@ ## 최근 사용한 문서 (Windows & OS X) -Windows와 OS X는 dock menu나 JumpList등을 통하여 최근 문서 리스트에 쉽게 접근할 수 있습니다. +알다 싶이 Windows와 OS X는 JumpList 또는 dock 메뉴를 통해 최근 문서 리스트에 쉽게 접근할 수 있습니다. __JumpList:__ @@ -88,10 +88,10 @@ __Internet Explorer의 작업:__ ![IE](http://i.msdn.microsoft.com/dynimg/IC420539.png) -OS X의 말 그대로 메뉴로 작동하는 dock menu 와는 달리 Windows의 사용자 작업은 어플리케이션 바로가기처럼 작동합니다. -유저가 작업을 클릭할 시 설정한 인자와 함께 새로운 어플리케이션이 실행됩니다. +OS X의 dock menu(진짜 메뉴)와는 달리 Windows의 사용자 작업은 어플리케이션 바로 가기처럼 작동합니다. +유저가 작업을 클릭할 때 설정한 인자와 함께 새로운 어플리케이션이 실행됩니다. -사용자 작업을 설정하려면 [app.setUserTasks][setusertaskstasks] API를 사용하여 구현할 수 있습니다: +사용자 작업을 설정하려면 [app.setUserTasks][setusertaskstasks] 메서드를 통해 구현할 수 있습니다: ```javascript var app = require('app'); @@ -166,7 +166,7 @@ win.setThumbarButtons([]); ## Unity 런처 숏컷 기능 (Linux) -Unity 환경에선 `.desktop` 파일을 수정함으로써 런처에 새로운 커스텀 엔트리를 추가할 수 있습니다. [Adding shortcuts to a launcher][unity-launcher] 가이드를 참고하세요. +Unity 환경에선 `.desktop` 파일을 수정함으로써 런처에 새로운 커스텀 엔트리를 추가할 수 있습니다. [Adding Shortcuts to a Launcher][unity-launcher] 가이드를 참고하세요. __Audacious의 런처 숏컷:__ diff --git a/docs-translations/ko/tutorial/devtools-extension.md b/docs-translations/ko/tutorial/devtools-extension.md index 81ebed413429..e6a9b559c35f 100644 --- a/docs-translations/ko/tutorial/devtools-extension.md +++ b/docs-translations/ko/tutorial/devtools-extension.md @@ -2,8 +2,8 @@ 어플리케이션의 디버깅을 쉽게 하기 위해 Electron은 기본적으로 [Chrome DevTools Extension][devtools-extension]을 지원합니다. -개발자 콘솔 확장기능은 간단하게 사용할 확장기능 플러그인의 소스코드를 다운로드한 후 `BrowserWindow.addDevToolsExtension` API를 이용하여 -어플리케이션 내에 로드할 수 있습니다. 한가지 주의할 점은 확장기능 사용시 창이 생성될 때 마다 일일이 해당 API를 호출할 필요는 없습니다. +개발자 콘솔 확장 기능은 간단하게 사용할 확장 기능 플러그인의 소스 코드를 다운로드한 후 `BrowserWindow.addDevToolsExtension` API를 이용하여 +어플리케이션 내에 로드할 수 있습니다. 한가지 주의할 점은 확장 기능 사용시 창이 생성될 때 마다 일일이 해당 API를 호출할 필요는 없습니다. 예시로 [React DevTools Extension](https://github.com/facebook/react-devtools)을 사용합니다. @@ -14,34 +14,34 @@ $ cd /some-directory $ git clone --recursive https://github.com/facebook/react-devtools.git ``` -그리고 개발자 콘솔이 열린 창에서 다음의 코드를 콘솔에 입력하면 확장기능을 로드할 수 있습니다: +그리고 개발자 콘솔이 열린 창에서 다음의 코드를 콘솔에 입력하면 확장 기능을 로드할 수 있습니다: ```javascript require('remote').require('browser-window').addDevToolsExtension('/some-directory/react-devtools'); ``` -확장기능을 unload 하고 콘솔을 다시 열 때 해당 확장기능이 로드되지 않도록 하려면 `BrowserWindow.removeDevToolsExtension` API를 사용하면 됩니다: +확장 기능을 unload 하고 콘솔을 다시 열 때 해당 확장 기능이 로드되지 않도록 하려면 `BrowserWindow.removeDevToolsExtension` API를 사용하면 됩니다: ```javascript require('remote').require('browser-window').removeDevToolsExtension('React Developer Tools'); ``` -## 개발자 콘솔 확장기능의 구성 형식 +## 개발자 콘솔 확장 기능의 구성 형식 -완벽하게 모든 개발자 콘솔 확장은 Chrome 브라우저를 위해 작성되었기 때문에 Electron에서도 로드할 수 있습니다. -하지만 반드시 확장기능은 소스코드 그대로의 디렉터리(폴더) 형태여야 합니다. 그래서 `crx` 등의 포맷으로 패키징된 확장기능의 경우 -사용자가 직접 해당 패키지의 압축을 풀어서 로드하지 않는 이상은 Electron에서 해당 확장기능의 압축을 풀 방법이 없습니다. +모든 개발자 콘솔 확장은 완벽히 Chrome 브라우저를 위해 작성되었기 때문에 Electron에서도 로드할 수 있습니다. +하지만 반드시 확장 기능은 소스코드 그대로의 디렉터리(폴더) 형태여야 합니다. 그래서 `crx` 등의 포맷으로 패키징된 확장 기능의 경우 +사용자가 직접 해당 패키지의 압축을 풀어서 로드하지 않는 이상은 Electron에서 해당 확장 기능의 압축을 풀 방법이 없습니다. ## 백그라운드 페이지 현재 Electron은 Chrome에서 지원하는 백그라운드 페이지(background pages)를 지원하지 않습니다. -몇몇 확장기능은 이 기능에 의존하는 경우가 있는데 이 경우 해당 확장기능은 Electron에서 작동하지 않을 수 있습니다. +몇몇 확장 기능은 이 기능에 의존하는 경우가 있는데 이 경우 해당 확장 기능은 Electron에서 작동하지 않을 수 있습니다. ## `chrome.*` API -몇몇 Chrome 확장기능은 특정 기능을 사용하기 위해 `chrome.*` API를 사용하는데, Electron에선 이 API들을 구현하기 위해 노력했지만 안타깝게도 아직 모든 API가 구현되지는 않았습니다. +몇몇 Chrome 확장 기능은 특정 기능을 사용하기 위해 `chrome.*` API를 사용하는데, 이 API들을 구현하기 위해 노력했지만 안타깝게도 아직 모든 API가 구현되지는 않았습니다. -아직 모든 API가 구현되지 않았기 때문에 확장기능에서 `chrome.devtools.*` 대신 `chrome.*` API를 사용할 경우 확장기능이 제대로 작동하지 않을 수 있음을 감안해야 합니다. -만약 문제가 발생할 경우 Electron의 GitHub repo에 이슈를 올리면 해당 API를 추가하는데 많은 도움이 됩니다. +아직 모든 API가 구현되지 않았기 때문에 확장 기능에서 `chrome.devtools.*` 대신 `chrome.*` API를 사용할 경우 확장 기능이 제대로 작동하지 않을 수 있음을 감안해야 합니다. +만약 문제가 발생할 경우 Electron의 GitHub 저장소에 관련 이슈를 올리면 해당 API를 추가하는데 많은 도움이 됩니다. [devtools-extension]: https://developer.chrome.com/extensions/devtools diff --git a/docs-translations/ko/tutorial/online-offline-events.md b/docs-translations/ko/tutorial/online-offline-events.md index 3ccf20c7d568..cc8ae4855d55 100644 --- a/docs-translations/ko/tutorial/online-offline-events.md +++ b/docs-translations/ko/tutorial/online-offline-events.md @@ -1,4 +1,4 @@ -# 온라인/오프라인 이벤트 +# 온라인/오프라인 이벤트 감지 온라인/오프라인 이벤트는 다음 예제와 같이 랜더러 프로세스에서 표준 HTML5 API를 이용하여 구현할 수 있습니다. @@ -35,8 +35,8 @@ _online-status.html_ ``` -물론 필요하다면 이 이벤트를 메인 프로세스로 보낼 수도 있습니다. -하지만 메인 프로세스는 `navigator` 객체를 가지고 있지 않기 때문에 이 이벤트를 직접 사용할 수 없습니다. +메인 프로세스에서 이 이벤트를 처리할 필요가 있는 경우 이벤트를 메인 프로세스로 보낼 수 있습니다. +메인 프로세스는 `navigator` 객체를 가지고 있지 않기 때문에 이 이벤트를 직접 사용할 수 없습니다. 대신 다음 예제와 같이 Electron의 inter-process communication(ipc) 유틸리티를 사용하면 이벤트를 메인 프로세스로 전달할 수 있습니다. diff --git a/docs-translations/ko/tutorial/quick-start.md b/docs-translations/ko/tutorial/quick-start.md index 37b48d993342..8c2e043061ec 100644 --- a/docs-translations/ko/tutorial/quick-start.md +++ b/docs-translations/ko/tutorial/quick-start.md @@ -27,15 +27,14 @@ Electron 프로세스 내에서 작동하는 웹 페이지를 __랜더러 프로 `BrowserWindow` 인스턴스는 따로 분리된 프로세스에서 랜더링 되며 이 프로세스를 랜더러 프로세스라고 합니다. `BrowserWindow` 인스턴스가 소멸할 때 그 창의 랜더러 프로세스도 같이 소멸합니다. -메인 프로세스는 모든 웹 페이지와 랜더러 프로세스를 관리하며 -랜더러 프로세스는 각각의 프로세스에 고립되며 웹 페이지의 작동에만 영향을 끼칩니다. +메인 프로세스는 모든 웹 페이지와 랜더러 프로세스를 관리하며 랜더러 프로세스는 각각의 프로세스에 고립되며 웹 페이지의 작동에만 영향을 끼칩니다. -웹 페이지 내에서 네이티브 GUI 리소스를 관리하는 것은 보안에 취약하고 리소스를 누수시킬 수 있기 때문에 -기본적으로 웹 페이지 내에서는 네이티브 GUI와 관련된 API를 호출할 수 없도록 되어 있습니다. -만약 웹 페이지 내에서 GUI작업이 필요하다면 메인 프로세스에서 그 작업을 할 수 있도록 메인 프로세스와 통신을 해야합니다. +웹 페이지 내에선 기본적으로 네이티브 GUI와 관련된 API를 호출할 수 없도록 설계 되어 있습니다. +왜냐하면 웹 페이지 내에서 네이티브 GUI 리소스를 관리하는 것은 보안에 취약하고 리소스를 누수시킬 수 있기 때문입니다. +꼭 웹 페이지 내에서 API를 사용해야 한다면 메인 프로세스에서 그 작업을 처리할 수 있도록 메인 프로세스와 통신을 해야 합니다. -Electron에는 메인 프로세스와 랜더러 프로세스간에 통신을 할 수 있도록 [ipc](../api/ipc-renderer.md) 모듈을 제공하고 있습니다. -또한 [remote](../api/remote.md) 모듈을 사용하여 RPC 스타일로 통신할 수도 있습니다. +Electron에는 메인 프로세스와 랜더러 프로세스 사이에 통신을 할 수 있도록 [ipc](../api/ipc-renderer.md) 모듈을 제공하고 있습니다. +또는 [remote](../api/remote.md) 모듈을 사용하여 RPC 스타일로 통신할 수도 있습니다. ## 첫번째 Electron 앱 만들기 @@ -49,7 +48,7 @@ your-app/ ``` `package.json`은 node 모듈의 package.json과 같습니다. -그리고 `main` 필드에 스크립트 파일을 집어넣어 메인 프로세스로 사용할 엔트리 포인트를 지정할 수 있습니다. +그리고 `main` 필드에 스크립트 파일을 지정하면 메인 프로세스의 엔트리 포인트로 사용합니다. 예를 들어 사용할 수 있는 `package.json`은 다음과 같습니다: ```json @@ -129,7 +128,7 @@ app.on('ready', function() { ### electron-prebuilt -`npm`을 통해 `electron-prebuilt` 패키지를 전역에 설치하면 간단한 명령으로 앱을 실행해 볼 수 있습니다. +`npm`을 통해 `electron-prebuilt` 패키지를 전역에 설치하면 간단한 명령으로 앱을 실행할 수 있습니다. 앱 디렉터리 내에서 이렇게 실행합니다: @@ -176,4 +175,4 @@ $ ./Electron.app/Contents/MacOS/Electron your-app/ ### 배포용 파일 만들기 -어플리케이션 작성을 완료했다면 [어플리케이션 배포](application-distribution.md) 가이드를 통해 본격적으로 제작한 앱을 배포할 수 있습니다. \ No newline at end of file +어플리케이션 작성을 완료했다면 [어플리케이션 배포](application-distribution.md) 가이드를 통해 제작한 앱을 본격적으로 배포할 수 있습니다. \ No newline at end of file diff --git a/docs-translations/ko/tutorial/using-native-node-modules.md b/docs-translations/ko/tutorial/using-native-node-modules.md index 4584ebd460fe..913c300be881 100644 --- a/docs-translations/ko/tutorial/using-native-node-modules.md +++ b/docs-translations/ko/tutorial/using-native-node-modules.md @@ -6,7 +6,7 @@ Electron에선 node.js 네이티브 모듈이 지원됩니다. 하지만 Electro ## 네이티브 node 모듈 호환성 Node v0.11.x 버전부터는 V8 API의 중대한 변경이 있었습니다. 하지만 대부분의 네이티브 모듈은 Node v0.10.x 버전을 타겟으로 작성 되었기 때문에 -새로운 Node 또는 io.js 버전에서 작동하지 않을 수 있습니다. Electron은 내부적으로 __io.js v3.1.0__ 버전을 사용하기 때문에 이러한 호환성 문제가 발생할 수 있습니다. +새로운 Node 또는 io.js 버전에서 작동하지 않을 수 있습니다. Electron은 내부적으로 __io.js v3.1.0__ 버전을 사용하기 때문에 호환성 문제가 발생할 수 있습니다. 이 문제를 해결하기 위해선 모듈이 v0.11.x 또는 최신 버전을 지원할 수 있도록 변경해야 합니다. 현재 [많은 모듈들](https://www.npmjs.org/browse/depended/nan)이 안정적으로 두 버전 모두 지원하고 있지만 오래된 모듈의 경우 여전히 Node v0.10.x 버전만을 지원하고 있습니다. @@ -14,16 +14,19 @@ Node v0.11.x 버전부터는 V8 API의 중대한 변경이 있었습니다. 하 ## 네이티브 모듈 설치하는 방법 +네이티브 모듈을 설치하는 방법은 세 가지 종류가 있습니다. + ### 쉬운 방법 [`electron-rebuild`](https://github.com/paulcbetts/electron-rebuild) 패키지를 사용하면 빠르고 간단하게 네이티브 모듈을 다시 빌드할 수 있습니다. -간단한 절차를 통해 자동으로 헤더를 다운로드하고 네이티브 모듈을 빌드할 수 있습니다: + +다음 예제는 `electron-rebuild`를 통해 자동으로 모듈의 헤더를 다운로드하고 네이티브 모듈을 빌드합니다: ```sh npm install --save-dev electron-rebuild -# 필요한 네이티브 모듈을 `npm install`로 설치한 후 다음 작업을 실행하세요: -./node_modules/.bin/electron-rebuild +# 필요한 네이티브 모듈을 `npm install`로 설치한 후 다음 명령을 실행하세요: +node ./node_modules/.bin/electron-rebuild ``` ### node-gyp을 이용한 방법 diff --git a/docs-translations/ko/tutorial/using-pepper-flash-plugin.md b/docs-translations/ko/tutorial/using-pepper-flash-plugin.md index 4577bc296fea..f47f20d8a71e 100644 --- a/docs-translations/ko/tutorial/using-pepper-flash-plugin.md +++ b/docs-translations/ko/tutorial/using-pepper-flash-plugin.md @@ -1,7 +1,7 @@ # Pepper 플래시 플러그인 사용하기 -작업에 필요한 경우 pepper 플래시 플러그인을 사용할 수 있습니다. -Electron에서 pepper 플래시 플러그인을 사용하기 위해선 따로 pepper 플래시 플러그인의 위치를 지정해 주어야합니다. +Electron은 Pepper 플래시 플러그인을 지원합니다. +Pepper 플래시 플러그인을 사용하려면 Pepper 플래시 플러그인의 위치를 지정해야 합니다. ## 플래시 플러그인 준비하기 @@ -10,7 +10,7 @@ Electron에서 플래시 플러그인을 지원하기 위해선 이 두 가지 ## Electron 스위치 추가 -플러그인을 사용하기 위해 직접적으로 `--ppapi-flash-path` 와 `ppapi-flash-version` 플래그를 ready 이벤트가 호출되기 전에 추가해야합니다. +플러그인을 사용하려면 Electron 커맨드 라인에 `--ppapi-flash-path` 와 `ppapi-flash-version` 플래그를 app의 ready 이벤트가 호출되기 전에 추가해야 합니다. 그리고 `browser-window`에 `plugins` 스위치도 추가해야합니다. ```javascript @@ -20,8 +20,6 @@ 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. @@ -54,7 +52,9 @@ app.on('ready', function() { ``` ## `` 태그를 이용하여 플러그인을 활성화 + `plugins` 속성을 `` 태그에 추가합니다. + ```html ``` diff --git a/docs-translations/ko/tutorial/using-selenium-and-webdriver.md b/docs-translations/ko/tutorial/using-selenium-and-webdriver.md index a29e8e2214ef..33dc6311ce35 100644 --- a/docs-translations/ko/tutorial/using-selenium-and-webdriver.md +++ b/docs-translations/ko/tutorial/using-selenium-and-webdriver.md @@ -7,13 +7,13 @@ > ChromeDriver는 Chromium의 WebDriver wire 프로토콜 스텐드얼론 서버 구현입니다. > Chromium 과 WebDriver 팀 멤버에 의해 개발되었습니다. -Electron과 `chromedriver`를 같이 사옹하려면 드라이버에서 Electron을 찾을 수 있도록 해야 하고 +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. 크롬 드라이버 시작 @@ -25,7 +25,7 @@ Starting ChromeDriver (v2.10.291558) on port 9515 Only local connections are allowed. ``` -포트 `9515`는 나중에 사용하므로 기억해 놓읍시다 +포트 `9515`는 나중에 사용하므로 기억해 놓습니다. ### 2. WebDriverJS 설치 @@ -35,7 +35,7 @@ $ npm install selenium-webdriver ### 3. 크롬 드라이버에 연결 -`selenium-webdriver`를 Electron과 같이 사용할 땐 기본적으로 upstream과 같습니다. +`selenium-webdriver`를 Electron과 같이 사용하는 방법은 기본적으로 upstream과 같습니다. 한가지 다른점이 있다면 수동으로 크롬 드라이버 연결에 대해 설정하고 Electron 실행파일의 위치를 전달합니다: ```javascript @@ -45,7 +45,7 @@ var driver = new webdriver.Builder() // 작동하고 있는 크롬 드라이버의 포트 "9515"를 사용합니다. .usingServer('http://localhost:9515') .withCapabilities({chromeOptions: { - // 여기에 사용중인 Electron 바이너리의 경로를 기재하세요. + // 여기에 사용중인 Electron 바이너리의 경로를 지정하세요. binary: '/Path-to-Your-App.app/Contents/MacOS/Atom'}}) .forBrowser('electron') .build(); @@ -88,11 +88,11 @@ $ npm install webdriverio ```javascript var webdriverio = require('webdriverio'); var options = { - host: "localhost", // Use localhost as chrome driver server - port: 9515, // "9515" is the port opened by chrome driver. + host: "localhost", // localhost에서 작동중인 크롬 드라이버 서버를 사용합니다. + port: 9515, // 연결할 크롬 드라이버 서버의 포트를 설정합니다. desiredCapabilities: { browserName: 'chrome', - chromeOptions: {binary: '/Path-to-Your-App.app/Electron'} // Path to your Electron binary. + chromeOptions: {binary: '/Path-to-Your-App.app/Electron'} // Electron 바이너리의 위치 } }; diff --git a/docs-translations/pt-BR/README.md b/docs-translations/pt-BR/README.md new file mode 100644 index 000000000000..88fb26a5ea54 --- /dev/null +++ b/docs-translations/pt-BR/README.md @@ -0,0 +1,70 @@ +## Guias + +* [Distribuir Aplicação](tutorial/application-distribution.md) +* [Empacotamento da aplicação](tutorial/application-packaging.md) +* [Usando módulos nativos](../../docs/tutorial/using-native-node-modules.md) +* [Depuração do processo principal](../../docs/tutorial/debugging-main-process.md) +* [Usando Selenium e WebDriver](../../docs/tutorial/using-selenium-and-webdriver.md) +* [Extensão DevTools](../../docs/tutorial/devtools-extension.md) +* [Usando o plugin papper flash](../../docs/tutorial/using-pepper-flash-plugin.md) + +## Tutoriais + +* [Introdução](../../docs/tutorial/quick-start.md) +* [A integração com o ambiente de desenvolvimento](../../docs/tutorial/desktop-environment-integration.md) +* [Evento de detecção on-line/off-line](../../docs/tutorial/online-offline-events.md) + +## API - Referencias + +* [Sinopse](../../docs/api/synopsis.md) +* [Processos](../../docs/api/process.md) +* [Parâmetros CLI suportados (Chrome)](../../docs/api/chrome-command-line-switches.md) + +DOM elementos personalizados: + +* [Objeto `File`](../../docs/api/file-object.md) +* [Tag ``](../../docs/api/web-view-tag.md) +* [Função `window.open`](../../docs/api/window-open.md) + +Os principais módulos: + +* [app](../../docs/api/app.md) +* [auto-updater](../../docs/api/auto-updater.md) +* [browser-window](../../docs/api/browser-window.md) +* [content-tracing](../../docs/api/content-tracing.md) +* [dialog](../../docs/api/dialog.md) +* [global-shortcut](../../docs/api/global-shortcut.md) +* [ipc (main process)](../../docs/api/ipc-main-process.md) +* [menu](../../docs/api/menu.md) +* [menu-item](../../docs/api/menu-item.md) +* [power-monitor](../../docs/api/power-monitor.md) +* [power-save-blocker](../../docs/api/power-save-blocker.md) +* [protocol](../../docs/api/protocol.md) +* [session](../../docs/api/session.md) +* [webContents](../../docs/api/web-contents.md) +* [tray](../../docs/api/tray.md) + +Módulos do renderizador (web page): + +* [ipc (renderer)](../../docs/api/ipc-renderer.md) +* [remote](../../docs/api/remote.md) +* [web-frame](../../docs/api/web-frame.md) + +Módulos de ambos os processos: + +* [clipboard](../../docs/api/clipboard.md) +* [crash-reporter](../../docs/api/crash-reporter.md) +* [native-image](../../docs/api/native-image.md) +* [screen](../../docs/api/screen.md) +* [shell](../../docs/api/shell.md) + +## Desenvolvimento + +* [Estilo de código](../../docs/development/coding-style.md) +* [Estrutura de diretórios padrão](../../docs/development/source-code-directory-structure.md) +* [Diferenças técnicas do NW.js (antigo node-webkit)](../../docs/development/atom-shell-vs-node-webkit.md) +* [Visão geral do build](../../docs/development/build-system-overview.md) +* [Instrução de build (Mac)](../../docs/development/build-instructions-osx.md) +* [Instrução de build (Windows)](../../docs/development/build-instructions-windows.md) +* [Instrução de build (Linux)](../../docs/development/build-instructions-linux.md) +* [Configurando um symbol server no debugger](../../docs/development/setting-up-symbol-server.md) \ No newline at end of file diff --git a/docs-translations/pt-BR/styleguide.md b/docs-translations/pt-BR/styleguide.md new file mode 100644 index 000000000000..817fa3c81e39 --- /dev/null +++ b/docs-translations/pt-BR/styleguide.md @@ -0,0 +1,77 @@ +# Styleguide do Electron + +Localize a seção apropriada para a sua tarefa: [Lendo a documentação do Electron](#) +ou [Escrevendo documentação para o Electron](#). + +## Escrevendo documentação para o Electron + +Estas são as formas que escrevemos a documentação do Electron. + +- No Máximo um `h1` por página. +- Usar `bash` ao invés de` cmd` em blocos de código (por causa do syntax highlighter). +- Títulos `h1` deve coincidir com o nome do objeto (i.e. `browser-window` → +`BrowserWindow`). +- Nomes de arquivos separados por hífen. +- Adicionar pelo menos uma descrição a cada frase. +- Métodos de cabeçalhos são envolto em `code`. +- Cabeçalhos de eventos são envolto em single 'quotation' marks. +- Não há listas com identação com mais de 2 níveis (por causa do markdown). +- Adicione títulos nas seções: Events, Class Methods e Instance Methods. +- Use 'will' ao invéis de 'would' ao descrever os resultados. +- Eventos e métodos são com cabeçalhos `h3`. +- Argumentos opcionais escritos como `function (required[, optional])`. +- Argumentos opcionais são indicados quando chamado na lista. +- Comprimento da linha é de 80 caracteres com colunas quebradas. +- Métodos específicos para uma plataforma são postos em itálico seguindo o cabeçalho do método. + - ```### `method(foo, bar)` _OS X_``` + +## Lendo a documentação do Electron + +Aqui estão algumas dicas de como entender a sintaxe da documentacão do Electron. + +### Métodos + +Um exemplo de [method](https://developer.mozilla.org/en-US/docs/Glossary/Method) +documentação: + +--- + +`methodName(required[, optional]))` + +* `require` String, **required** +* `optional` Integer + +--- + +O nome do método é seguido pelos seus argumentos. Argumentos opcionais são +simbolizada por colchetes que cercam o argumento opcional, bem como a vírgula +requerido se este argumento opcional segue outro argumento. + +Abaixo o método é para obter informações detalhadas sobre cada um dos argumentos. O tipo +de argumento é simbolizada por qualquer um dos tipos mais comuns: [`String`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String), [` Number`](https : //developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number), [`Object`](https://developer.mozilla.org/en-US/docs/Web/JavaScript Referência/Global_Objects/Object), [`Array`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array) +ou um tipo personalizado como o de Electron [`webContent`](api/web-content.md). + +### Eventos + +Um exemplo de [evento](https://developer.mozilla.org/en-US/docs/Web/API/Event) +documentação: + +--- + +Event: 'wake-up' + +Returns: + +* `time` String + +--- + +O evento é uma cadeia que é utilizada após um `.on` em um método listner. Se ela retorna +-lhe um valor e seu tipo é observado abaixo. Se você quiser um método para esctuar e responder +crie algo parecido com o exemplo abaixo: + +```javascript +Alarm.on('wake-up', function(time) { + console.log(time) +}) +``` \ No newline at end of file diff --git a/docs-translations/pt-BR/tutorial/application-distribution.md b/docs-translations/pt-BR/tutorial/application-distribution.md new file mode 100644 index 000000000000..41f2457c408b --- /dev/null +++ b/docs-translations/pt-BR/tutorial/application-distribution.md @@ -0,0 +1,118 @@ +# Distribuição de aplicações + +Para distribuir sua aplicação com o Electron, você deve nomear o diretório que contém sua aplicação como +`app` e dentro deste diretório colocar os recursos que você está utilizando (no OSX +`Electron.app/Contents/Resources/`, +no Linux e no Windows é em `resources/`): + +No OSX: + +```text +electron/Electron.app/Contents/Resources/app/ +├── package.json +├── main.js +└── index.html +``` + +No Windows e Linux: + +```text +electron/resources/app +├── package.json +├── main.js +└── index.html +``` + +Logo após execute `Electron.app` (ou `electron` no Linux e `electron.exe` no Windows), +e o Electron iniciaria a aplicação. O diretório `electron` será utilizado para criar a distribuição para +usuários finais. + +## Empacotando sua aplicação em um arquivo. + +Além de copiar todos os seus arquivos fontes para a distribuição, você também pode +empacotar seu aplicativo em um arquivo [asar](https://github.com/atom/asar) para evitar +de expor seu código fonte aos usuários finais. + +Para usar um arquivo `asar` ao invés da pasta `app` você precisa mudar o nome do +arquivo para `app.asar` e colocá-lo sob o diretório de recursos do Electron como +mostrado abaixo, então o Electron vai ler o arquivo e iniciar a aplicação a partir dele. + +No OSX: + +```text +electron/Electron.app/Contents/Resources/ +└── app.asar +``` + +No Windows e Linux: + +```text +electron/resources/ +└── app.asar +``` + +Mais detalhes podem ser encontrados em [Empacotamento da aplicação](../../../docs/tutorial/application-packaging.md). + +## Renomeando a marca Electron na sua distribuição + +Depois de empacotar seu aplicativo Electron, você vai querer renomear a marca Electron +antes de distribuí-lo aos usuários. + +### Janelas + +Você pode renomear `electron.exe` para o nome que desejar e editar o seu ícone e outras +informações com ferramentas como [rcedit](https://github.com/atom/rcedit) ou +[ResEdit](http://www.resedit.net). + +### OS X + +Você pode renomear `Electron.app` para o nome que desejar e também pode mudar o nome +do `CFBundleDisplayName`, `CFBundleIdentifier` e os campos em `CFBundleName` +nos seguinte arquivos: + +* `Electron.app/Contents/Info.plist` +* `Electron.app/Contents/frameworks/Electron Helper.app/Contents/Info.plist` + +Você também pode renomear o arquivo de ajuda para evitar a exibição de `Electron Helper` no +Monitor de Atividades, mas certifique-se de também renomear o arquivo de ajuda no executável do +aplicativo. + +A estrutura de uma aplicação renomada seria assim: + +``` +MyApp.app/Contents +├── Info.plist +├── MacOS/ +│   └── MyApp +└── Frameworks/ + ├── MyApp Helper EH.app + | ├── Info.plist + | └── MacOS/ + |    └── MyApp Helper EH + ├── MyApp Helper NP.app + | ├── Info.plist + | └── MacOS/ + |    └── MyApp Helper NP + └── MyApp Helper.app + ├── Info.plist + └── MacOS/ +    └── MyApp Helper +``` + +### Linux + +Você pode renomear o executável `electron` para o nome que desejar. + +## Renomeando a marca Electron do código fonte. + +Também é possível fazer renomear a marca Electron do código fonte, alterando o nome do produto e +reconstruí-lo a partir da fonte, para fazer isso você precisa modificar o arquivo `atom.gyp`. + +### grunt-build-atom-shell + +A modificação do código fonte do Electron para ganhar a sua marca pode ser muito complexa, por isso, +uma tarefa para o Grunt foi criado e irá cuidar desta tarefa automaticamente para você: +[grunt-build-atom-shell](https://github.com/paulcbetts/grunt-build-atom-shell). + +Esta tarefa irá automaticamente editar o arquivo `.gyp`, compilar o código +e reconstruir os módulos nativos da aplicação para utilizar o novo nome. \ No newline at end of file diff --git a/docs-translations/pt-BR/tutorial/application-packaging.md b/docs-translations/pt-BR/tutorial/application-packaging.md new file mode 100644 index 000000000000..f55cbb2f7d64 --- /dev/null +++ b/docs-translations/pt-BR/tutorial/application-packaging.md @@ -0,0 +1,158 @@ +# Empacotamento da aplicação + +Para proteger os recursos e o código fonte da sua aplicação você pode optar por +empacotar a sua aplicação em um arquivo [asar](https://github.com/atom/asar), isto é possível com poucas +alterações em seu código. + +## Gerando um arquivo `asar` + +Um arquivo [asar][asar] é um formato parecido com tar ou zip bem simples que concatena arquivos +em um único arquivo. O Electron pode ler arquivos arbitrários a partir dele sem descompacatar +o arquivo inteiro. + +Passos para empacotar a sua aplicação em um arquivo `asar`: + +### 1. Instale o utilitário asar + +```bash +$ npm install -g asar +``` + +### 2. Empacote a sua aplicação + +```bash +$ asar pack your-app app.asar +``` + +## Usando arquivos `asar` + +No Electron existem dois conjuntos de APIs: Node APIs fornecidas pelo Node.js e Web +APIs fornecidas pelo Chromium. Ambas as APIs suportam a leitura de arquivos `asar`. + +### Node API + +As API's do Node como `fs.readFile` e `require` tratam os pacotes `asar` +como diretórios virtuais e os arquivos dentro dele como arquivos normais. + +Por exemplo, temos um arquivo `example.asar` sob `/path/to`: + +```bash +$ asar list /path/to/example.asar +/app.js +/file.txt +/dir/module.js +/static/index.html +/static/main.css +/static/jquery.min.js +``` + +Lendo um arquivo em pacote `asar`: + +```javascript +var fs = require('fs'); +fs.readFileSync('/path/to/example.asar/file.txt'); +``` + +Listando todos os arquivos a partir da raiz: + +```javascript +var fs = require('fs'); +fs.readdirSync('/path/to/example.asar'); +``` + +Utilizando um módulo dentro do pacote `asar`: + +```javascript +require('/path/to/example.asar/dir/module.js'); +``` + +Você também pode renderizar uma página web apartir de um arquivo `asar` utilizando o módulo `BrowserWindow`: + +```javascript +var BrowserWindow = require('browser-window'); +var win = new BrowserWindow({width: 800, height: 600}); +win.loadUrl('file:///path/to/example.asar/static/index.html'); +``` + +### API Web + +Em uma página web, arquivos em um pacote `asar` pode ser solicitado com o protocolo `file:`. +Como a API Node, arquivos `asar` são tratadas como diretórios. + +Por exemplo, para obter um arquivo com `$ .get`: + +```html + +``` + +### Tratando um pacote `asar` como um arquivo normal + +Para alguns casos, precisamos verificar o checksum de um pacote `asar`, para fazer isto, precisamos ler +o arquivo `asar` como um arquivo normal. Para isto, você pode usar o built-in +`original-fs` que fornece a API `fs`, sem apoio a arquivos asar`: + +```javascript +var originalFs = require('original-fs'); +originalFs.readFileSync('/path/to/example.asar'); +``` + +## Limitaçõs na API Node + +Mesmo fazendo grandes esforços para pacotes `asar` ser tratado no Node como diretórios, +ainda existem limitações devido a natureza de baixo nível do Node + +### Arquivos `asar` são somente leitura + +Os arquivos `asar` não podem ser modificados. + +### Diretório de trabalho não pode ser comportar como diretório de arquivos + +Embora pacotes `asar` são tratadas como diretórios, não há +diretórios reais no sistema de arquivos, assim você nunca pode definir o diretório de trabalho para +diretórios em pacotes `asar`, passando-os como a opção `cwd` de algumas APIs +também irá causar erros. + +### Descompactação extra em algumas APIs + +A maioria das APIs `fs` pode ler um arquivo ou obter informações de um arquivo a partir de pacotes `asar` +sem descompacta-lo, mas para algumas APIs da rota real o Electron irá extrair o arquivo necessário para um +arquivo temporário e passar o caminho do arquivo temporário para as APIs, +isso adiciona um pouco de sobrecarga para essas APIs. + +APIs que requer descompactação extras são: + +* `child_process.execFile` +* `fs.open` +* `fs.openSync` +* `process.dlopen` - Usado por `require` em módulos nativos + +### Falsas informações de status do módulo `fs.stat` + +O objeto `Stats` retornado por` fs.stat` e outras funções relacionadas não são informações confiáveis, +você não deve confiar no objeto `Stats` exceto para obter o +tamanho do arquivo e verificação de tipo de arquivo. + +## Adicionando arquivos em um pacote `asar` + +Como dito acima, algumas APIs deo Node irá descompactar o arquivo para quando o filesystem +requsistar, além dos problemas de desempenho, ele também pode levar a falsos alertas +de vírus. + +Para contornar isso, você pode descompactar alguns arquivos usando a +opção `--unpack`, um exemplo de exclusão de bibliotecas compartilhadas de módulos nativos +é: + +```bash +$ asar pack app app.asar --unpack *.node +``` + +Depois de executar o comando, além do `app.asar`, há também +`app.asar.unpacked` pasta gerada que contém os arquivos descompactados, você +deve copiá-lo juntamente com `app.asar` quando enviá-lo para os usuários. + +Mais informações no repositório [asar](https://github.com/atom/asar) \ No newline at end of file diff --git a/docs-translations/zh-CN/api/accelerator.md b/docs-translations/zh-CN/api/accelerator.md new file mode 100644 index 000000000000..8858d18e856e --- /dev/null +++ b/docs-translations/zh-CN/api/accelerator.md @@ -0,0 +1,46 @@ +# Accelerator + +An accelerator is a string that represents a keyboard shortcut. It can contain +multiple modifiers and key codes, combined by the `+` character. + +Examples: + +* `Command+A` +* `Ctrl+Shift+Z` + +## Platform notice + +On Linux and Windows, the `Command` key does not have any effect so +use `CommandOrControl` which represents `Command` on OS X and `Control` on +Linux and Windows to define some accelerators. + +The `Super` key is mapped to the `Windows` key on Windows and Linux and +`Cmd` on OS X. + +## Available modifiers + +* `Command` (or `Cmd` for short) +* `Control` (or `Ctrl` for short) +* `CommandOrControl` (or `CmdOrCtrl` for short) +* `Alt` +* `Shift` +* `Super` + +## Available key codes + +* `0` to `9` +* `A` to `Z` +* `F1` to `F24` +* Punctuations like `~`, `!`, `@`, `#`, `$`, etc. +* `Plus` +* `Space` +* `Backspace` +* `Delete` +* `Insert` +* `Return` (or `Enter` as alias) +* `Up`, `Down`, `Left` and `Right` +* `Home` and `End` +* `PageUp` and `PageDown` +* `Escape` (or `Esc` for short) +* `VolumeUp`, `VolumeDown` and `VolumeMute` +* `MediaNextTrack`, `MediaPreviousTrack`, `MediaStop` and `MediaPlayPause` diff --git a/docs-translations/zh-CN/api/global-shortcut.md b/docs-translations/zh-CN/api/global-shortcut.md new file mode 100644 index 000000000000..ff0b28832a10 --- /dev/null +++ b/docs-translations/zh-CN/api/global-shortcut.md @@ -0,0 +1,60 @@ +# global-shortcut + +`global-shortcut` 模块可以便捷的为您设置(注册/注销)各种自定义操作的快捷键. + +**Note**: 使用此模块注册的快捷键是系统全局的(QQ截图那种), 不要在应用模块(app module)响应 `ready` +消息前使用此模块(注册快捷键). + +```javascript +var app = require('app'); +var globalShortcut = require('global-shortcut'); + +app.on('ready', function() { + // Register a 'ctrl+x' shortcut listener. + var ret = globalShortcut.register('ctrl+x', function() { + console.log('ctrl+x is pressed'); + }) + + if (!ret) { + console.log('registration failed'); + } + + // Check whether a shortcut is registered. + console.log(globalShortcut.isRegistered('ctrl+x')); +}); + +app.on('will-quit', function() { + // Unregister a shortcut. + globalShortcut.unregister('ctrl+x'); + + // Unregister all shortcuts. + globalShortcut.unregisterAll(); +}); +``` + +## Methods + +`global-shortcut` 模块包含以下函数: + +### `globalShortcut.register(accelerator, callback)` + +* `accelerator` [Accelerator](accelerator.md) +* `callback` Function + +注册 `accelerator` 快捷键. 当用户按下注册的快捷键时将会调用 `callback` 函数. + +### `globalShortcut.isRegistered(accelerator)` + +* `accelerator` [Accelerator](accelerator.md) + +查询 `accelerator` 快捷键是否已经被注册过了,将会返回 `true`(已被注册) 或 `false`(未注册). + +### `globalShortcut.unregister(accelerator)` + +* `accelerator` [Accelerator](accelerator.md) + +注销全局快捷键 `accelerator`. + +### `globalShortcut.unregisterAll()` + +注销本应用注册的所有全局快捷键. diff --git a/docs-translations/zh-CN/api/shell.md b/docs-translations/zh-CN/api/shell.md new file mode 100644 index 000000000000..a30334dcdc9c --- /dev/null +++ b/docs-translations/zh-CN/api/shell.md @@ -0,0 +1,45 @@ +# shell + +`shell` 模块提供了集成其他桌面客户端的关联功能. + + +在用户默认浏览器中打开URL的示例: + +```javascript +var shell = require('shell'); + +shell.openExternal('https://github.com'); +``` + +## Methods + +`shell` 模块包含以下函数: + +### `shell.showItemInFolder(fullPath)` + +* `fullPath` String + +打开文件所在文件夹,一般情况下还会选中它. + +### `shell.openItem(fullPath)` + +* `fullPath` String + +以默认打开方式打开文件. + +### `shell.openExternal(url)` + +* `url` String + +以系统默认设置打开外部协议.(例如,mailto: somebody@somewhere.io会打开用户默认的邮件客户端) + + +### `shell.moveItemToTrash(fullPath)` + +* `fullPath` String + +删除指定路径文件,并返回此操作的状态值(boolean类型). + +### `shell.beep()` + +播放 beep 声音. diff --git a/docs-translations/zh-CN/tutorial/quick-start.md b/docs-translations/zh-CN/tutorial/quick-start.md index fe54cbe9e308..165c30142e72 100644 --- a/docs-translations/zh-CN/tutorial/quick-start.md +++ b/docs-translations/zh-CN/tutorial/quick-start.md @@ -11,16 +11,16 @@ Electron 可以让你使用纯 JavaScript 调用丰富的原生 APIs 来创造 ## 渲染进程 由于 Electron 使用 Chromium 来展示页面,所以 Chromium 的多进程结构也被充分利用。每个 Electron 的页面都在运行着自己的进程,这样的进程我们称之为**渲染进程**。 -在一般浏览器中,网页通常会在沙盒环境下运行,并且不允许访问原生资源。然后,Electron 用户拥有在网页中调用 io.js 的 APIs 的能力,从而创造出低等的、与操作系统的交互。 +在一般浏览器中,网页通常会在沙盒环境下运行,并且不允许访问原生资源。然而,Electron 用户拥有在网页中调用 io.js 的 APIs 的能力,可以与底层操作系统直接交互。 ## 主进程与渲染进程的区别 -主进程使用 BroswerWindow 实例创建网页。每个 BroswerWindow 实例都在自己的渲染进程里运行着一个网页。当一个 BroswerWindow 实例被销毁,相应的渲染进程也会被终止。 +主进程使用 BroswerWindow 实例创建网页。每个 BroswerWindow 实例都在自己的渲染进程里运行着一个网页。当一个 BroswerWindow 实例被销毁后,相应的渲染进程也会被终止。 主进程管理所有页面和与之对应的渲染进程。每个渲染进程都是相互独立的,并且只关心他们自己的网页。 -由于在网页里管理原生 GUI 资源是非常危险而且容易造成资源泄露的,所以在网页面调用 GUI 相关的 APIs 是不被允许的。如果你想在网页里使用 GUI 操作,其对应的渲染进程必须与主进程进行通讯,请求主进程进行相关的 GUI 操作。 +由于在网页里管理原生 GUI 资源是非常危险而且容易造成资源泄露,所以在网页面调用 GUI 相关的 APIs 是不被允许的。如果你想在网页里使用 GUI 操作,其对应的渲染进程必须与主进程进行通讯,请求主进程进行相关的 GUI 操作。 -在 Electron,我们提供用于在主进程与渲染进程之间通讯的 [ipc][1] 模块。并且也有一个远程进程调用风格的通讯模块 [remote][2]。 +在 Electron,我们提供用于在主进程与渲染进程之间通讯的 [ipc][1] 模块。并且也有一个远程进程调用风格的通讯模块 [remote][2]。 # 打造你第一个 Electron 应用 大体上,一个 Electron 应用的目录结构如下: @@ -133,4 +133,4 @@ $ ./Electron.app/Contents/MacOS/Electron your-app/ [1]: https://github.com/atom/electron/blob/master/docs-translations/zh-CN/api/ipc-renderer.md [2]: https://github.com/atom/electron/blob/master/docs-translations/zh-CN/api/remote.md [3]: https://github.com/atom/electron/releases - [4]: https://github.com/atom/electron/blob/master/docs-translations/zh-CN/tutorial/application-distribution.md \ No newline at end of file + [4]: https://github.com/atom/electron/blob/master/docs-translations/zh-CN/tutorial/application-distribution.md diff --git a/docs-translations/zh-TW/README.md b/docs-translations/zh-TW/README.md index 7c954034f21d..cc75ba51c144 100644 --- a/docs-translations/zh-TW/README.md +++ b/docs-translations/zh-TW/README.md @@ -2,8 +2,8 @@ * [應用程式發布](tutorial/application-distribution.md) * [應用程式打包](tutorial/application-packaging.md) -* [使用原生模組](tutorial/using-native-node-modules.md) -* [Debug 主行程](tutorial/debugging-main-process.md) +* [使用原生 node 模組](tutorial/using-native-node-modules.md) +* [主行程 Debug](tutorial/debugging-main-process.md) * [使用 Selenium 和 WebDriver](tutorial/using-selenium-and-webdriver.md) * [DevTools 擴充](tutorial/devtools-extension.md) * [使用 Pepper Flash 套件](tutorial/using-pepper-flash-plugin.md) @@ -22,7 +22,7 @@ 客製的 DOM 元素: -* [`File`對象](api/file-object.md) +* [`File`物件](api/file-object.md) * [``物件](api/web-view-tag.md) * [`window.open`函數](api/window-open.md) diff --git a/docs-translations/zh-TW/api/file-object.md b/docs-translations/zh-TW/api/file-object.md new file mode 100644 index 000000000000..4f523c489516 --- /dev/null +++ b/docs-translations/zh-TW/api/file-object.md @@ -0,0 +1,28 @@ +# `File` object + +DOM's File 介面提供一個將本地文件抽象化,並可以讓使用者對本地文件直接使用 HTML5 檔案 API +Electron 可以添加一個 `path` 屬性至 `File` 接口進而顯示檔案在檔案系統內的真實路徑。 + +範例,獲得一個檔案之真實路徑,將檔案拖拉至應用程式 (dragged-onto-the-app): + +```html +
+ Drag your file here +
+ + +``` diff --git a/docs-translations/zh-TW/api/ipc-main-process.md b/docs-translations/zh-TW/api/ipc-main-process.md new file mode 100644 index 000000000000..00e73efb4fc4 --- /dev/null +++ b/docs-translations/zh-TW/api/ipc-main-process.md @@ -0,0 +1,69 @@ +# ipc (主行程) + +當在主行程裡使用 `ipc` 模組,這個模組負責處理來自渲染行程(網頁)的非同步與同步訊息。 +來自渲染器的訊息將會被注入到這個模組裡。 + +## 傳送訊息 + +同樣的也可以透過主行程來傳送訊息到渲染行程,更多資訊請參考 [WebContents.send](browser-window.md#webcontentssendchannel-args) + +- 當傳送一個訊息, 事件名稱為 `channel` +- 回覆同步訊息,你需要設定 `event.returnValue` +- 送出一個非同步訊息回給發送端,你可以使用 `event.sender.send(...)` + +這裏是一個傳送和處理訊息的範例,在渲染行程與主行程之間: + +```javascript +// 在主行程裡 +var ipc = require('ipc'); +ipc.on('asynchronous-message', function(event, arg) { + console.log(arg); // 輸出 "ping" + event.sender.send('asynchronous-reply', 'pong'); +}); + +ipc.on('synchronous-message', function(event, arg) { + console.log(arg); // 輸出 "ping" + event.returnValue = 'pong'; +}); +``` + +```javascript +// 在渲染行程裡 (網頁). +var ipc = require('ipc'); +console.log(ipc.sendSync('synchronous-message', 'ping')); // 輸出 "pong" + +ipc.on('asynchronous-reply', function(arg) { + console.log(arg); // 輸出 "pong" +}); +ipc.send('asynchronous-message', 'ping'); +``` + +## 聆聽訊息 + +`ipc` 模組擁有下列幾個方法去聆聽事件: + +### `ipc.on(channel, callback)` + +* `channel` String - 事件名稱 +* `callback` Function + +當一個事件發生 `callback` 會帶著 `event` 物件和一個訊息 `arg` + +## IPC 事件 + +`event` 物件被傳入 `callback` 具有以下幾個方法: + +### `Event.returnValue` + +設定這個值可以回傳一個同步訊息 + +### `Event.sender` + +回傳 `WebContents` 可以送出訊息 + +### `Event.sender.send(channel[, arg1][, arg2][, ...])` + +* `channel` String - 事件名稱 +* `arg` (選用) + +此傳送訊息是非同步的訊息,至渲染行程,可以是一個一系列的參數 `arg` 可以是任何型態。 diff --git a/docs-translations/zh-TW/api/power-monitor.md b/docs-translations/zh-TW/api/power-monitor.md new file mode 100644 index 000000000000..e38dee3212da --- /dev/null +++ b/docs-translations/zh-TW/api/power-monitor.md @@ -0,0 +1,36 @@ +# power-monitor + +`power-monitor` 模組用來監看電源狀態的改變。你只能在主行程 (main process) 裡面使用。 +你應該要等到 `ready` 在 `app` 模組裡的事件被觸發 (emit),再使用這個模組。 + +舉例來說: + +```javascript +var app = require('app'); + +app.on('ready', function() { + require('power-monitor').on('suspend', function() { + console.log('The system is going to sleep'); + }); +}); +``` + +## 事件 (Events) + +`power-monitor` 模組會觸發 (emits) 以下幾個事件: + +### 事件: 'suspend' + +當系統進入 睡眠 (suspend) 時觸發。 + +### 事件: 'resume' + +當系統 resume 時觸發。 + +### 事件: 'on-ac' + +當系統改變使用交流電源 (AC) 時觸發。 + +### 事件: 'on-battery' + +當系統改變使用電池店員時觸發。 diff --git a/docs-translations/zh-TW/api/power-save-blocker.md b/docs-translations/zh-TW/api/power-save-blocker.md new file mode 100644 index 000000000000..a652751c0bb8 --- /dev/null +++ b/docs-translations/zh-TW/api/power-save-blocker.md @@ -0,0 +1,47 @@ +# powerSaveBlocker + +`power-save-blocker` 模組是用來防止系統進入省電模式 low-power (sleep) mode +因此讓應用程式可以保持系統和螢幕的活躍 (active)。 + +舉例來說: + +```javascript +var powerSaveBlocker = require('power-save-blocker'); + +var id = powerSaveBlocker.start('prevent-display-sleep'); +console.log(powerSaveBlocker.isStarted(id)); + +powerSaveBlocker.stop(id); +``` + +## 方法 (Methods) + +`power-save-blocker` 模組有以下幾個方法: + +### `powerSaveBlocker.start(type)` + +* `type` String - Power save blocker type. + * `prevent-app-suspension` - 防止一個應用程式進入睡眠 (suspended)。 將保持系統活躍, + 但允許螢幕被關閉。 使用案例:下載一個檔案或是播放音樂。 + * `prevent-display-sleep`- 防止螢幕進入睡眠。將保持系統和螢幕的活躍。 + 使用案例:播放影片 + +當防止系統進入省電模式 low-power (sleep) mode 。 會回傳一個識別的整數來代表 power save blocker + +**注意:** `prevent-display-sleep` 比 `prevent-app-suspension` 擁有較高的優先權。 +只有高的優先全力才會有效,換句話說 `prevent-display-sleep` 總是會優先於 `prevent-app-suspension` + +例如,一個 API 呼叫 A 請求去做 `prevent-app-suspension`,而另外一個 B 請求去做 `prevent-display-sleep` + `prevent-display-sleep` 將會被使用,直到 B 停止他的請求,`prevent-app-suspension` 才會被使用。 + +### `powerSaveBlocker.stop(id)` + +* `id` Integer - power save blocker 會回傳 id 透過 `powerSaveBlocker.start`. + +將指定的 id 停止 power save blocker + +### `powerSaveBlocker.isStarted(id)` + +* `id` Integer - power save blocker 會回傳 id 透過 `powerSaveBlocker.start`. + +不管對應的 `powerSaveBlocker` 是否已經啟動,將會回傳一個布林值 (boolean) diff --git a/docs-translations/zh-TW/api/process.md b/docs-translations/zh-TW/api/process.md new file mode 100644 index 000000000000..a4f45352b9c4 --- /dev/null +++ b/docs-translations/zh-TW/api/process.md @@ -0,0 +1,23 @@ +# process + +在 Electron 裡的 `process` 物件具有以下幾個與 upstream node 的不同點: + +* `process.type` String - Process 的型態,可以是 `browser` (i.e. 主行程) 或 `renderer`. +* `process.versions['electron']` String - Electron 的版本 +* `process.versions['chrome']` String - Chromium 的版本 +* `process.resourcesPath` String - JavaScript 源碼的路徑 + +# 方法 (Methods) + +`process` 物件具有以下的方法: + +### `process.hang` + +會導致目前行程的主執行緒停住 + +## process.setFdLimit(maxDescriptors) _OS X_ _Linux_ + +* `maxDescriptors` Integer + +設置文件描述符 (file descriptor) soft limit `maxDescriptors` 或 OS hard +limit ,以較低者為準當目前的行程。 diff --git a/docs-translations/zh-TW/api/shell.md b/docs-translations/zh-TW/api/shell.md new file mode 100644 index 000000000000..3f3c9ae951c2 --- /dev/null +++ b/docs-translations/zh-TW/api/shell.md @@ -0,0 +1,46 @@ +# shell + +`shell` 模組提供一些整合桌面應用的功能。 + + +一個範例示範如何利用使用者的預設瀏覽器開啟 URL: + +```javascript +var shell = require('shell'); + +shell.openExternal('https://github.com'); +``` + +## Methods + +`shell` 模組有以下幾個方法: + +### `shell.showItemInFolder(fullPath)` + +* `fullPath` String + +顯示在檔案管理中指定的檔案,如果可以的話,選擇該檔案。 + +### `shell.openItem(fullPath)` + +* `fullPath` String + +打開指定的檔案,在桌面的預設方式。 +Open the given file in the desktop's default manner. + +### `shell.openExternal(url)` + +* `url` String + +打開一個指定的外部協定 URL 在桌面的預設方式。(舉例來說 mailto: URLs 會打開使用者的預設信箱) + + +### `shell.moveItemToTrash(fullPath)` + +* `fullPath` String + +移動指定檔案至垃圾桶,並會對這個操作回傳一個 boolean 狀態 + +### `shell.beep()` + +播放 beep 聲音。 diff --git a/docs-translations/zh-TW/api/synopsis.md b/docs-translations/zh-TW/api/synopsis.md new file mode 100644 index 000000000000..484f5e353847 --- /dev/null +++ b/docs-translations/zh-TW/api/synopsis.md @@ -0,0 +1,41 @@ +# Synopsis + +所有的 [Node.js's 內建模組](http://nodejs.org/api/) 都可以在 Electron 使用,而且 +第三方的 node 模組同樣的全部支援(包含[原生模組](../tutorial/using-native-node-modules.md)) + +Electron 也提供一些額外的內建模組用來開發原生桌面應用程式,一些模組只可以使用在主行程上 +(main process) 一些只可以使用在渲染行程 (renderer process) 上 (網頁) ,另外還有一些 +模組在兩邊的行程都可以使用。 + +基本的規則是: 如果一個模組是 [GUI](https://zh.wikipedia.org/wiki/%E5%9B%BE%E5%BD%A2%E7%94%A8%E6%88%B7%E7%95%8C%E9%9D%A2) +或者是 low-level 與系統相關的,那麼它就應該只能在主行程上使用 (main process) 你必須要對熟悉 [main process vs. renderer process](../tutorial/quick-start.md#the-main-process) 的觀念,才能去使用這些模組。 + +主行程 (main process) 腳本是一個像一般 Node.js 的腳本: + +```javascript +var app = require('app'); +var BrowserWindow = require('browser-window'); + +var window = null; + +app.on('ready', function() { + window = new BrowserWindow({width: 800, height: 600}); + window.loadUrl('https://github.com'); +}); +``` + +渲染行程 (renderer process) 跟一般正常的網頁沒有差別,而且還能有使用 node 模組的能力: + +```html + + + + + + +``` + +執行你的應用程式,請閱讀[Run your app](../tutorial/quick-start.md#run-your-app). diff --git a/docs/README.md b/docs/README.md index 5d6d825d1bcb..b2f95fe4b579 100644 --- a/docs/README.md +++ b/docs/README.md @@ -1,32 +1,32 @@ ## Guides -* [Application distribution](tutorial/application-distribution.md) -* [Application packaging](tutorial/application-packaging.md) -* [Using native node modules](tutorial/using-native-node-modules.md) -* [Debugging main process](tutorial/debugging-main-process.md) +* [Application Distribution](tutorial/application-distribution.md) +* [Application Packaging](tutorial/application-packaging.md) +* [Using Native Node Modules](tutorial/using-native-node-modules.md) +* [Debugging Main Process](tutorial/debugging-main-process.md) * [Using Selenium and WebDriver](tutorial/using-selenium-and-webdriver.md) -* [DevTools extension](tutorial/devtools-extension.md) -* [Using pepper flash plugin](tutorial/using-pepper-flash-plugin.md) +* [DevTools Extension](tutorial/devtools-extension.md) +* [Using Pepper Flash Plugin](tutorial/using-pepper-flash-plugin.md) ## Tutorials -* [Quick start](tutorial/quick-start.md) -* [Desktop environment integration](tutorial/desktop-environment-integration.md) -* [Online/offline event detection](tutorial/online-offline-events.md) +* [Quick Start](tutorial/quick-start.md) +* [Desktop Environment Integration](tutorial/desktop-environment-integration.md) +* [Online/Offline Event Detection](tutorial/online-offline-events.md) -## API references +## API References * [Synopsis](api/synopsis.md) -* [Process object](api/process.md) -* [Supported Chrome command line switches](api/chrome-command-line-switches.md) +* [Process Object](api/process.md) +* [Supported Chrome Command Line Switches](api/chrome-command-line-switches.md) -Custom DOM elements: +### Custom DOM Elements: -* [`File` object](api/file-object.md) -* [`` tag](api/web-view-tag.md) -* [`window.open` function](api/window-open.md) +* [`File` Object](api/file-object.md) +* [`` Tag](api/web-view-tag.md) +* [`window.open` Function](api/window-open.md) -Modules for the main process: +### Modules for the Main Process: * [app](api/app.md) * [auto-updater](api/auto-updater.md) @@ -41,16 +41,16 @@ Modules for the main process: * [power-save-blocker](api/power-save-blocker.md) * [protocol](api/protocol.md) * [session](api/session.md) -* [webContents](api/web-contents.md) +* [web-contents](api/web-contents.md) * [tray](api/tray.md) -Modules for the renderer process (web page): +### Modules for the Renderer Process (Web Page): * [ipc (renderer)](api/ipc-renderer.md) * [remote](api/remote.md) * [web-frame](api/web-frame.md) -Modules for both processes: +### Modules for Both Processes: * [clipboard](api/clipboard.md) * [crash-reporter](api/crash-reporter.md) @@ -60,11 +60,11 @@ Modules for both processes: ## Development -* [Coding style](development/coding-style.md) -* [Source code directory structure](development/source-code-directory-structure.md) -* [Technical differences to NW.js (formerly node-webkit)](development/atom-shell-vs-node-webkit.md) -* [Build system overview](development/build-system-overview.md) -* [Build instructions (Mac)](development/build-instructions-osx.md) -* [Build instructions (Windows)](development/build-instructions-windows.md) -* [Build instructions (Linux)](development/build-instructions-linux.md) -* [Setting up symbol server in debugger](development/setting-up-symbol-server.md) +* [Coding Style](development/coding-style.md) +* [Source Code Directory Structure](development/source-code-directory-structure.md) +* [Technical Differences to NW.js (formerly node-webkit)](development/atom-shell-vs-node-webkit.md) +* [Build System Overview](development/build-system-overview.md) +* [Build Instructions (Mac)](development/build-instructions-osx.md) +* [Build Instructions (Windows)](development/build-instructions-windows.md) +* [Build Instructions (Linux)](development/build-instructions-linux.md) +* [Setting Up Symbol Server in debugger](development/setting-up-symbol-server.md) diff --git a/docs/api/app.md b/docs/api/app.md index 07b26f2c5663..85ad873de30d 100644 --- a/docs/api/app.md +++ b/docs/api/app.md @@ -94,11 +94,15 @@ must be registered to be opened by your application. You should call `event.preventDefault()` if you want to handle this event. -### Event: 'activate-with-no-open-windows' +### Event: 'activate' _OS X_ -Emitted when the application is activated while there are no open windows, which -usually happens when the user has closed all of the application's windows and -then clicks on the application's dock icon. +Returns: + +* `event` Event +* `hasVisibleWindows` Bool + +Emitted when the application is activated, which usually happens when clicks on +the applications's dock icon. ### Event: 'browser-window-blur' @@ -118,6 +122,15 @@ Returns: Emitted when a [browserWindow](browser-window.md) gets focused. +### Event: 'browser-window-created' + +Returns: + +* `event` Event +* `window` BrowserWindow + +Emitted when a new [browserWindow](browser-window.md) is created. + ### Event: 'select-certificate' Emitted when a client certificate is requested. @@ -152,7 +165,7 @@ Emitted when the gpu process crashes. The `app` object has the following methods: -**Note** Some methods are only available on specific operating systems and are labeled as such. +**Note:** Some methods are only available on specific operating systems and are labeled as such. ### `app.quit()` diff --git a/docs/api/auto-updater.md b/docs/api/auto-updater.md index 3901e1be2062..9734f592c8fe 100644 --- a/docs/api/auto-updater.md +++ b/docs/api/auto-updater.md @@ -53,7 +53,7 @@ server that you are requesting updates from. A common approach is to use query parameters, like this: ```javascript -// On the main process +// In the main process var app = require('app'); var autoUpdater = require('auto-updater'); autoUpdater.setFeedUrl('http://mycompany.com/myapp/latest?version=' + app.getVersion()); diff --git a/docs/api/browser-window.md b/docs/api/browser-window.md index e9d2c7f6feb8..29171a2ec504 100644 --- a/docs/api/browser-window.md +++ b/docs/api/browser-window.md @@ -46,10 +46,8 @@ Properties `width` and `height` are required. * `always-on-top` 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 also be hidden on OS X. + set to `false` the fullscreen button will be hidden or disabled on OS X. * `skip-taskbar` Boolean - Whether to show the window in taskbar. -* `zoom-factor` Number - The default zoom factor of the page, `3.0` represents -`300%`. * `kiosk` Boolean - The kiosk mode. * `title` String - Default window title. * `icon` [NativeImage](native-image.md) - The window icon, when omitted on @@ -57,8 +55,6 @@ Properties `width` and `height` are required. * `show` Boolean - Whether window should be shown when created. * `frame` Boolean - Specify `false` to create a [Frameless Window](frameless-window.md). -* `node-integration` Boolean - Whether node integration is enabled. Default - is `true`. * `accept-first-mouse` 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. @@ -68,22 +64,42 @@ Properties `width` and `height` are required. than screen. * `dark-theme` Boolean - Forces using dark theme for the window, only works on some GTK+3 desktop environments. -* `preload` String - Specifies a script that will be loaded before other - scripts run in the window. This script will always have access to node APIs - no matter whether node integration is turned on for the window, and the path - of `preload` script has to be absolute path. * `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. + 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 + bar. + * `hidden` results in a hidden title bar and a full size content window, yet + the title bar still has the standard window controls ("traffic lights") in + 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 + 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. + * `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 + `300%`. * `javascript` Boolean * `web-security` 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 `true` if these two options are not - set by user. + same-origin policy (Usually using testing websites by people), and set + `allow_displaying_insecure_content` and `allow_running_insecure_content` to + `true` if these two options are not set by user. * `allow-displaying-insecure-content` Boolean - Allow an https page to display content like images from http URLs. * `allow-running-insecure-content` Boolean - Allow a https page to run @@ -93,13 +109,7 @@ Properties `width` and `height` are required. * `text-areas-are-resizable` Boolean * `webgl` Boolean * `webaudio` Boolean - * `plugins` Boolean - Whether plugins should be enabled, currently only - `NPAPI` plugins are supported. - * `extra-plugin-dirs` Array - Array of paths that would be searched for - plugins. Note that if you want to add a directory under your app, you - should use `__dirname` or `process.resourcesPath` to join the paths to - make them absolute, using relative paths would make Electron search - under current working directory. + * `plugins` Boolean - Whether plugins should be enabled. * `experimental-features` Boolean * `experimental-canvas-features` Boolean * `subpixel-font-scaling` Boolean @@ -117,7 +127,7 @@ Properties `width` and `height` are required. The `BrowserWindow` object emits the following events: -+**Note** Some events are only available on specific operating systems and are labeled as such. +**Note:** Some events are only available on specific operating systems and are labeled as such. ### Event: 'page-title-updated' @@ -224,15 +234,15 @@ Emitted when the window leaves full screen state triggered by html api. ### Event: 'devtools-opened' -Emitted when devtools is opened. +Emitted when DevTools is opened. ### Event: 'devtools-closed' -Emitted when devtools is closed. +Emitted when DevTools is closed. ### Event: 'devtools-focused' -Emitted when devtools is focused / opened. +Emitted when DevTools is focused / opened. ### Event: 'app-command' _Windows_ @@ -263,7 +273,7 @@ Returns the window that is focused in this application. ### `BrowserWindow.fromWebContents(webContents)` -* `webContents` [WebContents](#webcontents) +* `webContents` [WebContents](web-contents.md) Find a window according to the `webContents` it owns. @@ -277,7 +287,7 @@ Find a window according to its ID. * `path` String -Adds devtools extension located at `path`, and returns extension's name. +Adds DevTools extension located at `path`, and returns extension's name. The extension will be remembered so you only need to call this API once, this API is not for programming use. @@ -286,13 +296,11 @@ API is not for programming use. * `name` String -Remove the devtools extension whose name is `name`. +Remove the DevTools extension whose name is `name`. -## Instance Methods +## Instance Properties -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. +Objects created with `new BrowserWindow` have the following properties: ```javascript var BrowserWindow = require('browser-window'); @@ -302,7 +310,7 @@ var win = new BrowserWindow({ width: 800, height: 600 }); ``` -### `win.webContents()` +### `win.webContents` The `WebContents` object this window owns, all web page related events and operations will be done via it. @@ -313,16 +321,30 @@ events. **Note:** Users should never store this object because it may become `null` when the renderer process (web page) has crashed. -### `win.devToolsWebContents()` +### `win.devToolsWebContents` -Get the `WebContents` of devtools for this window. +Get the `WebContents` of DevTools for this window. **Note:** Users should never store this object because it may become `null` -when the devtools has been closed. +when the DevTools has been closed. -### `win.id()` +### `win.id` -Get the unique ID of this window. +The unique ID of this window. + +## Instance Methods + +Objects created with `new BrowserWindow` have the following instance methods: + +**Note:** Some methods are only available on specific operating systems and are labeled as such. + +```javascript +var BrowserWindow = require('browser-window'); + +// In this example `win` is our instance +var win = new BrowserWindow({ width: 800, height: 600 }); + +``` ### `win.destroy()` @@ -577,7 +599,7 @@ Whether the window's document has been edited. ### `win.openDevTools([options])` * `options` Object (optional). Properties: - * `detach` Boolean - opens devtools in a new window + * `detach` Boolean - opens DevTools in a new window Opens the developer tools. @@ -591,7 +613,11 @@ Returns whether the developer tools are opened. ### `win.toggleDevTools()` -Toggle the developer tools. +Toggles the developer tools. + +### `win.isDevToolsFocused()` + +Returns whether the developer tools is focused. ### `win.inspectElement(x, y)` diff --git a/docs/api/frameless-window.md b/docs/api/frameless-window.md index a326bbd8c196..8d64a6fcd7c8 100644 --- a/docs/api/frameless-window.md +++ b/docs/api/frameless-window.md @@ -13,6 +13,20 @@ var BrowserWindow = require('browser-window'); var win = new BrowserWindow({ width: 800, height: 600, frame: false }); ``` +### Alternatives on Mac + +On Mac OS X 10.10 Yosemite and newer, there's an alternative way to specify +a chromeless window. Instead of setting `frame` to `false` which disables +both the titlebar and window controls, you may want to have the title bar +hidden and your content extend to the full window size, yet still preserve +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' }); +``` + ## Transparent window By setting the `transparent` option to `true`, you can also make the frameless diff --git a/docs/api/global-shortcut.md b/docs/api/global-shortcut.md index f9ca654cf50a..adba06e1adcf 100644 --- a/docs/api/global-shortcut.md +++ b/docs/api/global-shortcut.md @@ -4,7 +4,7 @@ The `global-shortcut` module can register/unregister a global keyboard shortcut with the operating system so that you can customize the operations for various shortcuts. -**Note**: The shortcut is global; it will work even if the app does +**Note:** The shortcut is global; it will work even if the app does not have the keyboard focus. You should not use this module until the `ready` event of the app module is emitted. diff --git a/docs/api/ipc-main-process.md b/docs/api/ipc-main-process.md index bbb581fcfc9b..98d9c3c22d43 100644 --- a/docs/api/ipc-main-process.md +++ b/docs/api/ipc-main-process.md @@ -7,7 +7,7 @@ a renderer will be emitted to this module. ## Sending Messages It is also possible to send messages from the main process to the renderer -process, see [WebContents.send](browser-window.md#webcontentssendchannel-args) +process, see [WebContents.send](web-contents.md#webcontentssendchannel-args) for more information. - When sending a message, the event name is the `channel`. diff --git a/docs/api/ipc-renderer.md b/docs/api/ipc-renderer.md index 3adb0bc95476..752af2ebe293 100644 --- a/docs/api/ipc-renderer.md +++ b/docs/api/ipc-renderer.md @@ -4,7 +4,7 @@ The `ipc` 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 +**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 [ipc (main process)](ipc-main-process.md) for code examples. @@ -13,7 +13,7 @@ See [ipc (main process)](ipc-main-process.md) for code examples. The `ipc` module has the following methods for sending messages: -**Note**: When using these methods to send a `message` you must also listen +**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). ### `ipc.send(channel[, arg1][, arg2][, ...])` diff --git a/docs/api/menu.md b/docs/api/menu.md index 49d6361bcf0b..f48b07e7e40a 100644 --- a/docs/api/menu.md +++ b/docs/api/menu.md @@ -170,11 +170,11 @@ if (process.platform == 'darwin') { { label: 'Hide Others', accelerator: 'Command+Shift+H', - role: 'hideothers:' + role: 'hideothers' }, { label: 'Show All', - role: 'unhide:' + role: 'unhide' }, { type: 'separator' diff --git a/docs/api/native-image.md b/docs/api/native-image.md index c00ec3a9458a..df2bb96ff9da 100644 --- a/docs/api/native-image.md +++ b/docs/api/native-image.md @@ -74,7 +74,7 @@ mixed with other content to create the desired final appearance. The most common case is to use template images for a menu bar icon so it can adapt to both light and dark menu bars. -**Note**: Template image is only supported on OS X. +**Note:** Template image is only supported on OS X. To mark an image as a template image, its filename should end with the word `Template`. For example: diff --git a/docs/api/power-monitor.md b/docs/api/power-monitor.md index c9a33cc1a128..6ffb910e164d 100644 --- a/docs/api/power-monitor.md +++ b/docs/api/power-monitor.md @@ -1,7 +1,7 @@ # power-monitor The `power-monitor` module is used to monitor power state changes. You can -only use it on the main process. You should not use this module until the `ready` +only use it in the main process. You should not use this module until the `ready` event of the `app` module is emitted. For example: diff --git a/docs/api/remote.md b/docs/api/remote.md index ccb16b4b3cc3..1c5c831a1790 100644 --- a/docs/api/remote.md +++ b/docs/api/remote.md @@ -20,8 +20,8 @@ var win = new BrowserWindow({ width: 800, height: 600 }); win.loadUrl('https://github.com'); ``` -**Note**: for the reverse (access the renderer process from the main process), -you can use [webContents.executeJavascript](browser-window.md#webcontents-executejavascript-code). +**Note:** for the reverse (access the renderer process from the main process), +you can use [webContents.executeJavascript](web-contents.md#webcontentsexecutejavascriptcode-usergesture). ## Remote Objects diff --git a/docs/api/screen.md b/docs/api/screen.md index c22530ca8d0a..934e3eaf5a70 100644 --- a/docs/api/screen.md +++ b/docs/api/screen.md @@ -6,7 +6,7 @@ position, etc. You should not use this module until the `ready` event of the `screen` is an [EventEmitter](http://nodejs.org/api/events.html#events_class_events_eventemitter). -**Note**: In the renderer / DevTools, `window.screen` is a reserved +**Note:** In the renderer / DevTools, `window.screen` is a reserved DOM property, so writing `var screen = require('screen')` will not work. In our examples below, we use `atomScreen` as the variable name instead. diff --git a/docs/api/synopsis.md b/docs/api/synopsis.md index 21f4ff2aa4de..85d9e3f8dfa6 100644 --- a/docs/api/synopsis.md +++ b/docs/api/synopsis.md @@ -5,13 +5,13 @@ Electron and third-party node modules also fully supported as well (including the [native modules](../tutorial/using-native-node-modules.md)). Electron also provides some extra built-in modules for developing native -desktop applications. Some modules are only available on the main process, some +desktop applications. Some modules are only available in the main process, some are only available in the renderer process (web page), and some can be used in both processes. The basic rule is: if a module is [GUI](https://en.wikipedia.org/wiki/Graphical_user_interface) or low-level -system related, then it should be only available on the main process. You need +system related, then it should be only available in the main process. You need to be familiar with the concept of [main process vs. renderer process](../tutorial/quick-start.md#the-main-process) scripts to be able to use those modules. diff --git a/docs/api/tray.md b/docs/api/tray.md index a673307804a7..528705acb325 100644 --- a/docs/api/tray.md +++ b/docs/api/tray.md @@ -123,7 +123,7 @@ Emitted when dragged files are dropped in the tray icon. The `Tray` module has the following methods: -**Note**: Some methods are only available on specific operating systems and are +**Note:** Some methods are only available on specific operating systems and are labeled as such. ### `Tray.destroy()` diff --git a/docs/api/web-contents.md b/docs/api/web-contents.md index 89afae43d1c0..92d91d170e4a 100644 --- a/docs/api/web-contents.md +++ b/docs/api/web-contents.md @@ -32,6 +32,7 @@ Returns: * `event` Event * `errorCode` Integer * `errorDescription` 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. @@ -426,13 +427,13 @@ win.webContents.on("did-finish-load", function() { * `path` String -Adds the specified path to devtools workspace. +Adds the specified path to DevTools workspace. ### `webContents.removeWorkSpace(path)` * `path` String -Removes the specified path from devtools workspace. +Removes the specified path from DevTools workspace. ### `webContents.send(channel[, args...])` @@ -445,7 +446,7 @@ page can handle it by listening to the `channel` event of the `ipc` module. An example of sending messages from the main process to the renderer process: ```javascript -// On the main process. +// In the main process. var window = null; app.on('ready', function() { window = new BrowserWindow({width: 800, height: 600}); @@ -472,6 +473,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 on the main process. + 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. diff --git a/docs/api/web-view-tag.md b/docs/api/web-view-tag.md index c1b1f705e95b..4647413b5a43 100644 --- a/docs/api/web-view-tag.md +++ b/docs/api/web-view-tag.md @@ -138,22 +138,22 @@ If "on", the guest page will have web security disabled. ``` -Sets the storage partition used by the `webview`. If the storage partition ID starts with `persist:`, -the `webview` will use a persistent storage partition available to all `webview` in the app with -the same storage partition ID. if there is no `persist:` prefix, the `webview` will -use an in-memory storage partition. By assigning the same partition ID, multiple `webview` -can share the same storage partition. If the storage partition ID is unset then default storage -of the app will be used. +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. -This value can only be modified before the first navigation, since the storage partition of an active -renderer process cannot change. Subsequent attempts to modify the value will fail with a -DOM exception. +This value can only be modified before the first navigation, since the session +of an active renderer process cannot change. Subsequent attempts to modify the +value will fail with a DOM exception. ## Methods The `webview` tag has the following methods: -**Note**: The webview element must be loaded before using the methods. +**Note:** The webview element must be loaded before using the methods. **Example** ```javascript @@ -260,15 +260,15 @@ user action, can take advantage of this option for automation. ### `.openDevTools()` -Opens a devtools window for guest page. +Opens a DevTools window for guest page. ### `.closeDevTools()` -Closes the devtools window of guest page. +Closes the DevTools window of guest page. ### `.isDevToolsOpened()` -Returns a boolean whether guest page has a devtools window attached. +Returns a boolean whether guest page has a DevTools window attached. ### `.inspectElement(x, y)` @@ -279,7 +279,7 @@ Starts inspecting element at position (`x`, `y`) of guest page. ### `.inspectServiceWorker()` -Opens the devtools for the service worker context present in the guest page. +Opens the DevTools for the service worker context present in the guest page. ### `.setAudioMuted(muted)` @@ -355,7 +355,7 @@ Prints webview's web page as PDF, Same with `webContents.printToPDF(options, cal 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. -See [WebContents.send](browser-window.md#webcontentssendchannel-args) for +See [WebContents.send](web-contents.md#webcontentssendchannel-args) for examples. ## DOM events @@ -384,6 +384,7 @@ Returns: * `errorCode` Integer * `errorDescription` 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. diff --git a/docs/styleguide.md b/docs/styleguide.md index 23c590e64211..77c90467ca93 100644 --- a/docs/styleguide.md +++ b/docs/styleguide.md @@ -1,7 +1,7 @@ # Electron Documentation Styleguide -Find the appropriate section for your task: [reading Electron documentation](#) -or [writing Electron documentation](#). +Find the appropriate section for your task: [reading Electron documentation](#reading-electron-documentation) +or [writing Electron documentation](#writing-electron-documentation). ## Writing Electron Documentation @@ -25,6 +25,22 @@ These are the ways that we construct the Electron documentation. - Line length is 80-column wrapped. - Platform specific methods are noted in italics following method header. - ```### `method(foo, bar)` _OS X_``` +- Prefer 'in the ___ process' over 'on' + +### Documentation Translations + +Translations of the Electron docs are located within the `docs-translations` +directory. + +To add another set (or partial set): + +- Create a subdirectory named by language abbreviation. +- Within that subdirectory, duplicate the `docs` directory, keeping the + names of directories and files same. +- Translate the files. +- Update the `README.md` within your language directory to link to the files + you have translated. +- Add a link to your translation directory on the main Electron [README](https://github.com/atom/electron#documentation-translations). ## Reading Electron Documentation diff --git a/docs/tutorial/debugging-main-process.md b/docs/tutorial/debugging-main-process.md index f4e345a2f3a5..38c6e61ffcde 100644 --- a/docs/tutorial/debugging-main-process.md +++ b/docs/tutorial/debugging-main-process.md @@ -1,6 +1,6 @@ # Debugging the Main Process -The browser window devtools can only debug the renderer process scripts (i.e. +The browser window DevTools can only debug the renderer process scripts (i.e. the web pages). In order to provide a way to debug the scripts from the main process, Electron has provided the `--debug` and `--debug-brk` switches. diff --git a/docs/tutorial/using-native-node-modules.md b/docs/tutorial/using-native-node-modules.md index 4d61f70cf6db..c338494cde2b 100644 --- a/docs/tutorial/using-native-node-modules.md +++ b/docs/tutorial/using-native-node-modules.md @@ -31,7 +31,7 @@ which handles the manual steps of downloading headers and building native module npm install --save-dev electron-rebuild # Every time you run npm install, run this -./node_modules/.bin/electron-rebuild +node ./node_modules/.bin/electron-rebuild ``` ### The node-gyp Way diff --git a/filenames.gypi b/filenames.gypi index 2f97d01507e8..461c812753c9 100644 --- a/filenames.gypi +++ b/filenames.gypi @@ -226,14 +226,14 @@ 'atom/browser/ui/x/window_state_watcher.h', 'atom/browser/ui/x/x_window_utils.cc', 'atom/browser/ui/x/x_window_utils.h', - 'atom/browser/web_view_constants.cc', - 'atom/browser/web_view_constants.h', + 'atom/browser/web_contents_preferences.cc', + 'atom/browser/web_contents_preferences.h', + 'atom/browser/web_dialog_helper.cc', + 'atom/browser/web_dialog_helper.h', 'atom/browser/web_view_guest_delegate.cc', 'atom/browser/web_view_guest_delegate.h', 'atom/browser/web_view_manager.cc', 'atom/browser/web_view_manager.h', - 'atom/browser/web_dialog_helper.cc', - 'atom/browser/web_dialog_helper.h', 'atom/browser/window_list.cc', 'atom/browser/window_list.h', 'atom/browser/window_list_observer.h', @@ -324,6 +324,8 @@ 'atom/renderer/atom_renderer_client.h', 'atom/renderer/guest_view_container.cc', 'atom/renderer/guest_view_container.h', + 'atom/renderer/node_array_buffer_bridge.cc', + 'atom/renderer/node_array_buffer_bridge.h', 'atom/utility/atom_content_utility_client.cc', 'atom/utility/atom_content_utility_client.h', 'chromium_src/chrome/browser/browser_process.cc', diff --git a/script/bootstrap.py b/script/bootstrap.py index 293d3dc2dd10..d5ad41a61c59 100755 --- a/script/bootstrap.py +++ b/script/bootstrap.py @@ -162,13 +162,16 @@ def create_chrome_version_h(): version = f.read() with open(template_file, 'r') as f: template = f.read() - if sys.platform in ['win32', 'cygwin']: - open_mode = 'wb+' - else: - open_mode = 'w+' - with open(target_file, open_mode) as f: - content = template.replace('{PLACEHOLDER}', version.strip()) - if f.read() != content: + content = template.replace('{PLACEHOLDER}', version.strip()) + + # We update the file only if the content has changed (ignoring line ending + # differences). + should_write = True + if os.path.isfile(target_file): + with open(target_file, 'r') as f: + should_write = f.read().replace('r', '') != content.replace('r', '') + if should_write: + with open(target_file, 'w') as f: f.write(content) diff --git a/script/cibuild b/script/cibuild index 38ce06969a22..08d59385c9e0 100755 --- a/script/cibuild +++ b/script/cibuild @@ -71,7 +71,7 @@ def main(): run_script('upload.py') else: run_script('build.py', ['-c', 'D']) - if (is_travis or PLATFORM == 'linux') and target_arch == 'x64': + if PLATFORM != 'win32' and target_arch == 'x64': run_script('test.py', ['--ci']) run_script('clean.py') diff --git a/script/lib/config.py b/script/lib/config.py index 3fed12000b48..0df68bd773bf 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://github-janky-artifacts.s3.amazonaws.com/libchromiumcontent' -LIBCHROMIUMCONTENT_COMMIT = 'f5489a774b719e9e979675c17b99ed45a05aacf7' +LIBCHROMIUMCONTENT_COMMIT = '8482fe555913dea3bde8a74f754524e2cfb02bc5' PLATFORM = { 'cygwin': 'win32', diff --git a/script/upload-index-json.py b/script/upload-index-json.py index dfcbc835915c..671408fa9219 100755 --- a/script/upload-index-json.py +++ b/script/upload-index-json.py @@ -8,7 +8,7 @@ from lib.util import atom_gyp, execute, s3put, scoped_cwd SOURCE_ROOT = os.path.abspath(os.path.dirname(os.path.dirname(__file__))) -OUT_DIR = os.path.join(SOURCE_ROOT, 'out', 'R') +OUT_DIR = os.path.join(SOURCE_ROOT, 'out', 'D') PROJECT_NAME = atom_gyp()['project_name%'] PRODUCT_NAME = atom_gyp()['product_name%'] diff --git a/spec/api-app-spec.coffee b/spec/api-app-spec.coffee index 5c6591cadf50..38ef22ac80bd 100644 --- a/spec/api-app-spec.coffee +++ b/spec/api-app-spec.coffee @@ -26,19 +26,30 @@ describe 'app module', -> assert.equal app.getName(), 'test-name' app.setName 'Electron Test' - describe 'focus/blur event', -> + describe 'BrowserWindow events', -> w = null - beforeEach -> - w.destroy() if w? - w = new BrowserWindow(show: false, width: 400, height: 400) afterEach -> w.destroy() if w? w = null - it 'should emit focus event', (done) -> + + it 'should emit browser-window-focus event when window is focused', (done) -> + app.once 'browser-window-focus', (e, window) -> + assert.equal w.id, window.id + done() + w = new BrowserWindow(show: false) + w.emit 'focus' + + it 'should emit browser-window-blur event when window is blured', (done) -> app.once 'browser-window-blur', (e, window) -> assert.equal w.id, window.id done() - app.once 'browser-window-focus', (e, window) -> - assert.equal w.id, window.id - w.emit 'blur' - w.emit 'focus' + w = new BrowserWindow(show: false) + w.emit 'blur' + + it 'should emit browser-window-created event when window is created', (done) -> + app.once 'browser-window-created', (e, window) -> + setImmediate -> + assert.equal w.id, window.id + done() + w = new BrowserWindow(show: false) + w.emit 'blur' diff --git a/spec/api-browser-window-spec.coffee b/spec/api-browser-window-spec.coffee index fa7a8ae33a9c..3e4e2d5db5e2 100644 --- a/spec/api-browser-window-spec.coffee +++ b/spec/api-browser-window-spec.coffee @@ -4,6 +4,7 @@ path = require 'path' remote = require 'remote' http = require 'http' url = require 'url' +os = require 'os' BrowserWindow = remote.require 'browser-window' @@ -160,6 +161,22 @@ describe 'browser-window module', -> assert.equal size[0], 400 assert.equal size[1], 400 + describe '"title-bar-style" option', -> + return if process.platform isnt 'darwin' + return if parseInt(os.release().split('.')[0]) < 14 # only run these tests on Yosemite or newer + + it 'creates browser window with hidden title bar', -> + w.destroy() + w = new BrowserWindow(show: false, width: 400, height: 400, 'title-bar-style': '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') + contentSize = w.getContentSize() + assert.equal contentSize[1], 400 + describe '"enable-larger-than-screen" option', -> return if process.platform is 'linux' @@ -182,15 +199,36 @@ describe 'browser-window module', -> assert.equal after[0], size.width assert.equal after[1], size.height - describe '"preload" options', -> - it 'loads the script before other scripts in window', (done) -> - preload = path.join fixtures, 'module', 'set-global.js' - remote.require('ipc').once 'preload', (event, test) -> - assert.equal(test, 'preload') - done() - w.destroy() - w = new BrowserWindow(show: false, width: 400, height: 400, preload: preload) - w.loadUrl 'file://' + path.join(fixtures, 'api', 'preload.html') + describe '"web-preferences" option', -> + afterEach -> + remote.require('ipc').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) -> + assert.equal(test, 'preload') + done() + w.destroy() + w = new BrowserWindow + show: false + 'web-preferences': + preload: preload + 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) -> + assert.equal(test, 'undefined') + done() + w.destroy() + w = new BrowserWindow + show: false + 'web-preferences': + preload: preload + 'node-integration': false + w.loadUrl 'file://' + path.join(fixtures, 'api', 'blank.html') describe 'beforeunload handler', -> it 'returning true would not prevent close', (done) -> diff --git a/spec/api-crash-reporter-spec.coffee b/spec/api-crash-reporter-spec.coffee index 6cd714215354..60b630bc2ffc 100644 --- a/spec/api-crash-reporter-spec.coffee +++ b/spec/api-crash-reporter-spec.coffee @@ -18,9 +18,14 @@ describe 'crash-reporter module', -> # It is not working on 64bit Windows. return if process.platform is 'win32' and process.arch is 'x64' + # The crash-reporter test is not reliable on CI machine. + isCI = remote.process.argv[2] == '--ci' + return if isCI + it 'should send minidump when renderer crashes', (done) -> - @timeout 60000 + @timeout 120000 server = http.createServer (req, res) -> + server.close() form = new formidable.IncomingForm() process.throwDeprecation = false form.parse req, (error, fields, files) -> @@ -37,7 +42,6 @@ describe 'crash-reporter module', -> assert files['upload_file_minidump']['name']? res.end('abc-123-def') - server.close() done() # Server port is generated randomly for the first run, it will be reused # when page is refreshed. diff --git a/spec/api-protocol-spec.coffee b/spec/api-protocol-spec.coffee index f540a63ec406..02fd8d5e402a 100644 --- a/spec/api-protocol-spec.coffee +++ b/spec/api-protocol-spec.coffee @@ -318,6 +318,19 @@ describe 'protocol module', -> error: (xhr, errorType, error) -> done(error) + it 'can set content-type', (done) -> + handler = (request, callback) -> + callback({mimeType: 'application/json', data: '{"value": 1}'}) + protocol.interceptStringProtocol 'http', handler, (error) -> + $.ajax + url: 'http://fake-host' + success: (data) -> + assert.equal typeof(data), 'object' + assert.equal data.value, 1 + done() + error: (xhr, errorType, error) -> + done(error) + describe 'protocol.interceptBufferProtocol', -> it 'can intercept http protocol', (done) -> handler = (request, callback) -> callback(new Buffer(text)) diff --git a/spec/chromium-spec.coffee b/spec/chromium-spec.coffee index c594a97f3b83..2c42cd9a4cf0 100644 --- a/spec/chromium-spec.coffee +++ b/spec/chromium-spec.coffee @@ -36,12 +36,23 @@ describe 'chromium feature', -> describe 'window.open', -> it 'returns a BrowserWindowProxy object', -> - b = window.open 'about:blank', 'test', 'show=no' + b = window.open 'about:blank', '', 'show=no' assert.equal b.closed, false assert.equal b.constructor.name, 'BrowserWindowProxy' b.close() + it 'accepts "node-integration" as feature', (done) -> + listener = (event) -> + window.removeEventListener 'message', listener + b.close() + assert.equal event.data, 'undefined' + done() + window.addEventListener 'message', listener + b = window.open "file://#{fixtures}/pages/window-opener-node.html", '', 'node-integration=no,show=no' + describe 'window.opener', -> + @timeout 10000 + ipc = remote.require 'ipc' url = "file://#{fixtures}/pages/window-opener.html" w = null @@ -52,25 +63,28 @@ describe 'chromium feature', -> it 'is null for main window', (done) -> ipc.on 'opener', (event, opener) -> - done(if opener is null then undefined else opener) + assert.equal opener, null + done() BrowserWindow = remote.require 'browser-window' w = new BrowserWindow(show: false) w.loadUrl url it 'is not null for window opened by window.open', (done) -> - b = window.open url, 'test2', 'show=no' ipc.on 'opener', (event, opener) -> b.close() done(if opener isnt null then undefined else opener) + b = window.open url, '', 'show=no' describe 'window.opener.postMessage', -> it 'sets source and origin correctly', (done) -> - b = window.open "file://#{fixtures}/pages/window-opener-postMessage.html", 'test', 'show=no' - window.addEventListener 'message', (event) -> + listener = (event) -> + window.removeEventListener 'message', listener b.close() assert.equal event.source.guestId, b.guestId assert.equal event.origin, 'file://' done() + window.addEventListener 'message', listener + b = window.open "file://#{fixtures}/pages/window-opener-postMessage.html", '', 'show=no' describe 'creating a Uint8Array under browser side', -> it 'does not crash', -> diff --git a/spec/fixtures/api/blank.html b/spec/fixtures/api/blank.html new file mode 100644 index 000000000000..accfb421446d --- /dev/null +++ b/spec/fixtures/api/blank.html @@ -0,0 +1,5 @@ + + + diff --git a/spec/fixtures/api/preload.html b/spec/fixtures/api/preload.html index 22dee23444fa..ece481f92413 100644 --- a/spec/fixtures/api/preload.html +++ b/spec/fixtures/api/preload.html @@ -3,7 +3,7 @@ diff --git a/spec/fixtures/module/preload-node-off.js b/spec/fixtures/module/preload-node-off.js new file mode 100644 index 000000000000..9020f4513a10 --- /dev/null +++ b/spec/fixtures/module/preload-node-off.js @@ -0,0 +1,7 @@ +setImmediate(function() { + try { + console.log([typeof process, typeof setImmediate, typeof global].join(' ')); + } catch (e) { + console.log(e.message); + } +}); diff --git a/spec/fixtures/module/send-later.js b/spec/fixtures/module/send-later.js new file mode 100644 index 000000000000..fce96b84b787 --- /dev/null +++ b/spec/fixtures/module/send-later.js @@ -0,0 +1,4 @@ +var ipc = require('ipc'); +window.onload = function() { + ipc.send('answer', typeof window.process); +} diff --git a/spec/fixtures/pages/window-opener-node.html b/spec/fixtures/pages/window-opener-node.html new file mode 100644 index 000000000000..118603c82d3b --- /dev/null +++ b/spec/fixtures/pages/window-opener-node.html @@ -0,0 +1,7 @@ + + + + + diff --git a/spec/node-spec.coffee b/spec/node-spec.coffee index 5ec2bb05e906..94174c38b743 100644 --- a/spec/node-spec.coffee +++ b/spec/node-spec.coffee @@ -133,3 +133,11 @@ describe 'node feature', -> b = new Buffer(p.innerText) assert.equal b.toString(), 'Jøhänñéß' assert.equal Buffer.byteLength(p.innerText), 13 + + describe 'process.stdout', -> + it 'should not throw exception', -> + process.stdout + + # Not reliable on some machines + xit 'should have isTTY defined', -> + assert.equal typeof(process.stdout.isTTY), 'boolean' diff --git a/spec/static/main.js b/spec/static/main.js index d8b53167c5e2..38ba7cc089de 100644 --- a/spec/static/main.js +++ b/spec/static/main.js @@ -2,7 +2,6 @@ var app = require('app'); var ipc = require('ipc'); var dialog = require('dialog'); var BrowserWindow = require('browser-window'); -var Menu = require('menu'); var window = null; process.port = 0; // will be used by crash-reporter spec. @@ -10,6 +9,11 @@ process.port = 0; // will be used by crash-reporter spec. app.commandLine.appendSwitch('js-flags', '--expose_gc'); app.commandLine.appendSwitch('ignore-certificate-errors'); +// 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) { event.sender.send('message', arg); }); @@ -47,93 +51,6 @@ app.on('window-all-closed', function() { }); app.on('ready', function() { - var template = [ - { - label: 'Atom', - submenu: [ - { - label: 'Quit', - accelerator: 'CommandOrControl+Q', - click: function(item, window) { app.quit(); } - }, - ], - }, - { - label: 'Edit', - submenu: [ - { - label: 'Undo', - accelerator: 'CommandOrControl+Z', - selector: 'undo:', - }, - { - label: 'Redo', - accelerator: 'CommandOrControl+Shift+Z', - selector: 'redo:', - }, - { - type: 'separator', - }, - { - label: 'Cut', - accelerator: 'CommandOrControl+X', - selector: 'cut:', - }, - { - label: 'Copy', - accelerator: 'CommandOrControl+C', - selector: 'copy:', - }, - { - label: 'Paste', - accelerator: 'CommandOrControl+V', - selector: 'paste:', - }, - { - label: 'Select All', - accelerator: 'CommandOrControl+A', - selector: 'selectAll:', - }, - ] - }, - { - label: 'View', - submenu: [ - { - label: 'Reload', - accelerator: 'CommandOrControl+R', - click: function(item, window) { window.restart(); } - }, - { - label: 'Enter Fullscreen', - click: function(item, window) { window.setFullScreen(true); } - }, - { - label: 'Toggle DevTools', - accelerator: 'Alt+CommandOrControl+I', - click: function(item, window) { window.toggleDevTools(); } - }, - ] - }, - { - label: 'Window', - submenu: [ - { - label: 'Open', - accelerator: 'CommandOrControl+O', - }, - { - label: 'Close', - accelerator: 'CommandOrControl+W', - click: function(item, window) { window.close(); } - }, - ] - }, - ]; - - var menu = Menu.buildFromTemplate(template); - app.setApplicationMenu(menu); - // Test if using protocol module would crash. require('protocol').registerStringProtocol('test-if-crashes', function() {}); diff --git a/spec/webview-spec.coffee b/spec/webview-spec.coffee index fe281510b40e..e4b40c28ebeb 100644 --- a/spec/webview-spec.coffee +++ b/spec/webview-spec.coffee @@ -3,15 +3,15 @@ path = require 'path' http = require 'http' describe ' tag', -> + @timeout 10000 + fixtures = path.join __dirname, 'fixtures' webview = null - beforeEach -> webview = new WebView - afterEach -> - document.body.removeChild webview + document.body.removeChild(webview) if document.body.contains(webview) describe 'src attribute', -> it 'specifies the page to load', (done) -> @@ -84,6 +84,14 @@ describe ' tag', -> webview.src = "file://#{fixtures}/pages/e.html" document.body.appendChild webview + it 'preload script can still use "process" in required modules when nodeintegration is off', (done) -> + webview.addEventListener 'console-message', (e) -> + assert.equal e.message, 'object function object' + done() + webview.setAttribute 'preload', "#{fixtures}/module/preload-node-off.js" + webview.src = "file://#{fixtures}/api/blank.html" + document.body.appendChild webview + it 'receives ipc message in preload script', (done) -> message = 'boom!' listener = (e) -> @@ -160,7 +168,7 @@ describe ' tag', -> assert.equal e.message, 'undefined undefined undefined undefined' done() webview.src = "file://#{fixtures}/pages/c.html" - webview.partition = "test" + webview.partition = 'test1' document.body.appendChild webview it 'inserts node symbols when set', (done) -> @@ -169,7 +177,7 @@ describe ' tag', -> done() webview.setAttribute 'nodeintegration', 'on' webview.src = "file://#{fixtures}/pages/d.html" - webview.partition = "test" + webview.partition = 'test2' document.body.appendChild webview it 'isolates storage for different id', (done) -> @@ -180,7 +188,7 @@ describe ' tag', -> window.localStorage.setItem 'test', 'one' webview.addEventListener 'console-message', listener webview.src = "file://#{fixtures}/pages/partition/one.html" - webview.partition = "test" + webview.partition = 'test3' document.body.appendChild webview it 'uses current session storage when no id is provided', (done) -> diff --git a/vendor/brightray b/vendor/brightray index 4d8f5d879d48..d385c9b1b88d 160000 --- a/vendor/brightray +++ b/vendor/brightray @@ -1 +1 @@ -Subproject commit 4d8f5d879d484db54895c3456ded3a3d3246415d +Subproject commit d385c9b1b88da3ba1b5426861ec7c63e8c884135 diff --git a/vendor/native_mate b/vendor/native_mate index 8ca005eb4159..b7387da0854b 160000 --- a/vendor/native_mate +++ b/vendor/native_mate @@ -1 +1 @@ -Subproject commit 8ca005eb41591f583ebab804945311903f866ad6 +Subproject commit b7387da0854b20d376fdae0d93a01f83d080668d diff --git a/vendor/node b/vendor/node index 8253eb682526..4098d45fbb82 160000 --- a/vendor/node +++ b/vendor/node @@ -1 +1 @@ -Subproject commit 8253eb68252639db471090edb059eaa4fea4ce46 +Subproject commit 4098d45fbb822370c19d2fe7b88162759db4eb96