diff --git a/.node-version b/.node-version index 346d9cae72c6..339cbf236a73 100644 --- a/.node-version +++ b/.node-version @@ -1 +1 @@ -v5.1.1 +v5.10.0 diff --git a/atom/app/atom_main_delegate.cc b/atom/app/atom_main_delegate.cc index 221d59c1619c..0a298308ad0b 100644 --- a/atom/app/atom_main_delegate.cc +++ b/atom/app/atom_main_delegate.cc @@ -98,10 +98,6 @@ void AtomMainDelegate::PreSandboxStartup() { std::string process_type = command_line->GetSwitchValueASCII( switches::kProcessType); - if (process_type == switches::kUtilityProcess) { - AtomContentUtilityClient::PreSandboxStartup(); - } - // Only append arguments for browser process. if (!IsBrowserProcess(command_line)) return; diff --git a/atom/browser/api/atom_api_web_contents.cc b/atom/browser/api/atom_api_web_contents.cc index 610d958ca1ea..abad4add4fb0 100644 --- a/atom/browser/api/atom_api_web_contents.cc +++ b/atom/browser/api/atom_api_web_contents.cc @@ -13,12 +13,15 @@ #include "atom/browser/atom_browser_client.h" #include "atom/browser/atom_browser_context.h" #include "atom/browser/atom_browser_main_parts.h" +#include "atom/browser/atom_security_state_model_client.h" #include "atom/browser/native_window.h" +#include "atom/browser/net/atom_network_delegate.h" #include "atom/browser/web_contents_permission_helper.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" +#include "atom/common/color_util.h" #include "atom/common/mouse_util.h" #include "atom/common/native_mate_converters/blink_converter.h" #include "atom/common/native_mate_converters/callback.h" @@ -276,6 +279,8 @@ WebContents::WebContents(v8::Isolate* isolate, // Intialize permission helper. WebContentsPermissionHelper::CreateForWebContents(web_contents); + // Intialize security state client. + AtomSecurityStateModelClient::CreateForWebContents(web_contents); web_contents->SetUserAgentOverride(GetBrowserContext()->GetUserAgent()); @@ -546,28 +551,21 @@ void WebContents::DidFinishLoad(content::RenderFrameHost* render_frame_host, void WebContents::DidFailProvisionalLoad( content::RenderFrameHost* render_frame_host, const GURL& url, - int error_code, - const base::string16& error_description, + int code, + const base::string16& description, bool was_ignored_by_handler) { bool is_main_frame = !render_frame_host->GetParent(); - Emit("did-fail-provisional-load", - error_code, - error_description, - url, - is_main_frame); + Emit("did-fail-provisional-load", code, description, url, is_main_frame); + Emit("did-fail-load", code, description, url, is_main_frame); } void WebContents::DidFailLoad(content::RenderFrameHost* render_frame_host, - const GURL& validated_url, + const GURL& url, int error_code, const base::string16& error_description, bool was_ignored_by_handler) { bool is_main_frame = !render_frame_host->GetParent(); - Emit("did-fail-load", - error_code, - error_description, - validated_url, - is_main_frame); + Emit("did-fail-load", error_code, error_description, url, is_main_frame); } void WebContents::DidStartLoading() { @@ -587,7 +585,8 @@ void WebContents::DidGetResourceResponseStart( details.http_response_code, details.method, details.referrer, - details.headers.get()); + details.headers.get(), + ResourceTypeToString(details.resource_type)); } void WebContents::DidGetRedirectForResourceRequest( @@ -633,6 +632,10 @@ void WebContents::DidUpdateFaviconURL( Emit("page-favicon-updated", unique_urls); } +void WebContents::DevToolsReloadPage() { + Emit("devtools-reload-page"); +} + void WebContents::DevToolsFocused() { Emit("devtools-focused"); } @@ -748,12 +751,19 @@ void WebContents::LoadURL(const GURL& url, const mate::Dictionary& options) { params.override_user_agent = content::NavigationController::UA_OVERRIDE_TRUE; web_contents()->GetController().LoadURLWithParams(params); - // Set the background color of RenderViewHost to transparent so it doesn't - // override the background color set by the user. + // Set the background color of RenderWidgetHostView. // We have to call it right after LoadURL because the RenderViewHost is only // created after loading a page. const auto view = web_contents()->GetRenderWidgetHostView(); - view->SetBackgroundColor(SK_ColorTRANSPARENT); + WebContentsPreferences* web_preferences = + WebContentsPreferences::FromWebContents(web_contents()); + std::string color_name; + if (web_preferences->web_preferences()->GetString(options::kBackgroundColor, + &color_name)) { + view->SetBackgroundColor(ParseHexColor(color_name)); + } else { + view->SetBackgroundColor(SK_ColorTRANSPARENT); + } // For the same reason we can only disable hidden here. const auto host = static_cast( diff --git a/atom/browser/api/atom_api_web_contents.h b/atom/browser/api/atom_api_web_contents.h index ee5a25b26660..0cb2a348e170 100644 --- a/atom/browser/api/atom_api_web_contents.h +++ b/atom/browser/api/atom_api_web_contents.h @@ -251,6 +251,9 @@ class WebContents : public mate::TrackableObject, void MediaStoppedPlaying(const MediaPlayerId& id) override; void DidChangeThemeColor(SkColor theme_color) override; + // brightray::InspectableWebContentsDelegate: + void DevToolsReloadPage() override; + // brightray::InspectableWebContentsViewDelegate: void DevToolsFocused() override; void DevToolsOpened() override; diff --git a/atom/browser/atom_browser_main_parts.cc b/atom/browser/atom_browser_main_parts.cc index 25338c0df174..335e0576fcbc 100644 --- a/atom/browser/atom_browser_main_parts.cc +++ b/atom/browser/atom_browser_main_parts.cc @@ -136,9 +136,8 @@ void AtomBrowserMainParts::PreMainMessageLoopRun() { // Start idle gc. gc_timer_.Start( FROM_HERE, base::TimeDelta::FromMinutes(1), - base::Bind(base::IgnoreResult(&v8::Isolate::IdleNotification), - base::Unretained(js_env_->isolate()), - 1000)); + base::Bind(&v8::Isolate::LowMemoryNotification, + base::Unretained(js_env_->isolate()))); brightray::BrowserMainParts::PreMainMessageLoopRun(); bridge_task_runner_->MessageLoopIsReady(); diff --git a/atom/browser/atom_security_state_model_client.cc b/atom/browser/atom_security_state_model_client.cc new file mode 100644 index 000000000000..911849c5c2d1 --- /dev/null +++ b/atom/browser/atom_security_state_model_client.cc @@ -0,0 +1,105 @@ +// Copyright (c) 2016 GitHub, Inc. +// Use of this source code is governed by the MIT license that can be +// found in the LICENSE file. + +#include "atom/browser/atom_security_state_model_client.h" + +#include "content/public/browser/cert_store.h" +#include "content/public/browser/navigation_entry.h" +#include "content/public/browser/web_contents.h" +#include "content/public/common/origin_util.h" +#include "content/public/common/ssl_status.h" +#include "net/cert/x509_certificate.h" + +DEFINE_WEB_CONTENTS_USER_DATA_KEY(atom::AtomSecurityStateModelClient); + +using security_state::SecurityStateModel; + +namespace atom { + +namespace { + +SecurityStateModel::SecurityLevel GetSecurityLevelForSecurityStyle( + content::SecurityStyle style) { + switch (style) { + case content::SECURITY_STYLE_UNKNOWN: + return SecurityStateModel::NONE; + case content::SECURITY_STYLE_UNAUTHENTICATED: + return SecurityStateModel::NONE; + case content::SECURITY_STYLE_AUTHENTICATION_BROKEN: + return SecurityStateModel::SECURITY_ERROR; + case content::SECURITY_STYLE_WARNING: + return SecurityStateModel::SECURITY_WARNING; + case content::SECURITY_STYLE_AUTHENTICATED: + return SecurityStateModel::SECURE; + } + return SecurityStateModel::NONE; +} + +} // namespace + +AtomSecurityStateModelClient::AtomSecurityStateModelClient( + content::WebContents* web_contents) + : web_contents_(web_contents), + security_state_model_(new SecurityStateModel()) { + security_state_model_->SetClient(this); +} + +AtomSecurityStateModelClient::~AtomSecurityStateModelClient() { +} + +const SecurityStateModel::SecurityInfo& +AtomSecurityStateModelClient::GetSecurityInfo() const { + return security_state_model_->GetSecurityInfo(); +} + +bool AtomSecurityStateModelClient::RetrieveCert( + scoped_refptr* cert) { + content::NavigationEntry* entry = + web_contents_->GetController().GetVisibleEntry(); + if (!entry) + return false; + return content::CertStore::GetInstance()->RetrieveCert( + entry->GetSSL().cert_id, cert); +} + +bool AtomSecurityStateModelClient::UsedPolicyInstalledCertificate() { + return false; +} + +bool AtomSecurityStateModelClient::IsOriginSecure(const GURL& url) { + return content::IsOriginSecure(url); +} + +void AtomSecurityStateModelClient::GetVisibleSecurityState( + SecurityStateModel::VisibleSecurityState* state) { + content::NavigationEntry* entry = + web_contents_->GetController().GetVisibleEntry(); + if (!entry || + entry->GetSSL().security_style == content::SECURITY_STYLE_UNKNOWN) { + *state = SecurityStateModel::VisibleSecurityState(); + return; + } + + state->initialized = true; + state->url = entry->GetURL(); + const content::SSLStatus& ssl = entry->GetSSL(); + state->initial_security_level = + GetSecurityLevelForSecurityStyle(ssl.security_style); + state->cert_id = ssl.cert_id; + state->cert_status = ssl.cert_status; + state->connection_status = ssl.connection_status; + state->security_bits = ssl.security_bits; + state->sct_verify_statuses.clear(); + for (const auto& sct : ssl.signed_certificate_timestamp_ids) + state->sct_verify_statuses.push_back(sct.status); + state->displayed_mixed_content = + (ssl.content_status & content::SSLStatus::DISPLAYED_INSECURE_CONTENT) + ? true + : false; + state->ran_mixed_content = + (ssl.content_status & content::SSLStatus::RAN_INSECURE_CONTENT) ? true + : false; +} + +} // namespace atom diff --git a/atom/browser/atom_security_state_model_client.h b/atom/browser/atom_security_state_model_client.h new file mode 100644 index 000000000000..cc943eb7f949 --- /dev/null +++ b/atom/browser/atom_security_state_model_client.h @@ -0,0 +1,42 @@ +// Copyright (c) 2016 GitHub, Inc. +// Use of this source code is governed by the MIT license that can be +// found in the LICENSE file. + +#ifndef ATOM_BROWSER_ATOM_SECURITY_STATE_MODEL_CLIENT_H_ +#define ATOM_BROWSER_ATOM_SECURITY_STATE_MODEL_CLIENT_H_ + +#include "components/security_state/security_state_model.h" +#include "components/security_state/security_state_model_client.h" +#include "content/public/browser/web_contents_user_data.h" + +namespace atom { + +class AtomSecurityStateModelClient + : public security_state::SecurityStateModelClient, + public content::WebContentsUserData { + public: + ~AtomSecurityStateModelClient() override; + + const security_state::SecurityStateModel::SecurityInfo& + GetSecurityInfo() const; + + // security_state::SecurityStateModelClient: + void GetVisibleSecurityState( + security_state::SecurityStateModel::VisibleSecurityState* state) override; + bool RetrieveCert(scoped_refptr* cert) override; + bool UsedPolicyInstalledCertificate() override; + bool IsOriginSecure(const GURL& url) override; + + private: + explicit AtomSecurityStateModelClient(content::WebContents* web_contents); + friend class content::WebContentsUserData; + + content::WebContents* web_contents_; + scoped_ptr security_state_model_; + + DISALLOW_COPY_AND_ASSIGN(AtomSecurityStateModelClient); +}; + +} // namespace atom + +#endif // ATOM_BROWSER_ATOM_SECURITY_STATE_MODEL_CLIENT_H_ diff --git a/atom/browser/common_web_contents_delegate.cc b/atom/browser/common_web_contents_delegate.cc index 62e854ac5655..4bebf7480b89 100644 --- a/atom/browser/common_web_contents_delegate.cc +++ b/atom/browser/common_web_contents_delegate.cc @@ -10,9 +10,11 @@ #include "atom/browser/atom_browser_context.h" #include "atom/browser/atom_javascript_dialog_manager.h" +#include "atom/browser/atom_security_state_model_client.h" #include "atom/browser/native_window.h" #include "atom/browser/ui/file_dialog.h" #include "atom/browser/web_dialog_helper.h" +#include "atom/common/atom_constants.h" #include "base/files/file_util.h" #include "base/prefs/pref_service.h" #include "base/prefs/scoped_user_pref_update.h" @@ -25,6 +27,8 @@ #include "content/public/browser/render_process_host.h" #include "content/public/browser/render_view_host.h" #include "content/public/browser/render_widget_host.h" +#include "content/public/browser/security_style_explanation.h" +#include "content/public/browser/security_style_explanations.h" #include "storage/browser/fileapi/isolated_context.h" #if defined(TOOLKIT_VIEWS) @@ -36,6 +40,7 @@ #endif using content::BrowserThread; +using security_state::SecurityStateModel; namespace atom { @@ -140,6 +145,24 @@ std::set GetAddedFileSystemPaths( return result; } +content::SecurityStyle SecurityLevelToSecurityStyle( + SecurityStateModel::SecurityLevel security_level) { + switch (security_level) { + case SecurityStateModel::NONE: + return content::SECURITY_STYLE_UNAUTHENTICATED; + case SecurityStateModel::SECURITY_WARNING: + case SecurityStateModel::SECURITY_POLICY_WARNING: + return content::SECURITY_STYLE_WARNING; + case SecurityStateModel::EV_SECURE: + case SecurityStateModel::SECURE: + return content::SECURITY_STYLE_AUTHENTICATED; + case SecurityStateModel::SECURITY_ERROR: + return content::SECURITY_STYLE_AUTHENTICATION_BROKEN; + } + + return content::SECURITY_STYLE_UNKNOWN; +} + } // namespace CommonWebContentsDelegate::CommonWebContentsDelegate() @@ -265,6 +288,90 @@ bool CommonWebContentsDelegate::IsFullscreenForTabOrPending( return html_fullscreen_; } +content::SecurityStyle CommonWebContentsDelegate::GetSecurityStyle( + content::WebContents* web_contents, + content::SecurityStyleExplanations* explanations) { + auto model_client = + AtomSecurityStateModelClient::FromWebContents(web_contents); + + const SecurityStateModel::SecurityInfo& security_info = + model_client->GetSecurityInfo(); + + const content::SecurityStyle security_style = + SecurityLevelToSecurityStyle(security_info.security_level); + + explanations->ran_insecure_content_style = + SecurityLevelToSecurityStyle( + SecurityStateModel::kRanInsecureContentLevel); + explanations->displayed_insecure_content_style = + SecurityLevelToSecurityStyle( + SecurityStateModel::kDisplayedInsecureContentLevel); + + explanations->scheme_is_cryptographic = security_info.scheme_is_cryptographic; + if (!security_info.scheme_is_cryptographic) + return security_style; + + if (security_info.sha1_deprecation_status == + SecurityStateModel::DEPRECATED_SHA1_MAJOR) { + explanations->broken_explanations.push_back( + content::SecurityStyleExplanation( + kSHA1Certificate, + kSHA1MajorDescription, + security_info.cert_id)); + } else if (security_info.sha1_deprecation_status == + SecurityStateModel::DEPRECATED_SHA1_MINOR) { + explanations->unauthenticated_explanations.push_back( + content::SecurityStyleExplanation( + kSHA1Certificate, + kSHA1MinorDescription, + security_info.cert_id)); + } + + explanations->ran_insecure_content = + security_info.mixed_content_status == + SecurityStateModel::RAN_MIXED_CONTENT || + security_info.mixed_content_status == + SecurityStateModel::RAN_AND_DISPLAYED_MIXED_CONTENT; + explanations->displayed_insecure_content = + security_info.mixed_content_status == + SecurityStateModel::DISPLAYED_MIXED_CONTENT || + security_info.mixed_content_status == + SecurityStateModel::RAN_AND_DISPLAYED_MIXED_CONTENT; + + if (net::IsCertStatusError(security_info.cert_status)) { + std::string error_string = net::ErrorToString( + net::MapCertStatusToNetError(security_info.cert_status)); + + content::SecurityStyleExplanation explanation( + kCertificateError, + "There are issues with the site's certificate chain " + error_string, + security_info.cert_id); + + if (net::IsCertStatusMinorError(security_info.cert_status)) + explanations->unauthenticated_explanations.push_back(explanation); + else + explanations->broken_explanations.push_back(explanation); + } else { + if (security_info.sha1_deprecation_status == + SecurityStateModel::NO_DEPRECATED_SHA1) { + explanations->secure_explanations.push_back( + content::SecurityStyleExplanation( + kValidCertificate, + kValidCertificateDescription, + security_info.cert_id)); + } + } + + if (security_info.is_secure_protocol_and_ciphersuite) { + explanations->secure_explanations.push_back( + content::SecurityStyleExplanation( + kSecureProtocol, + kSecureProtocolDescription)); + } + + return security_style; +} + void CommonWebContentsDelegate::DevToolsSaveToFile( const std::string& url, const std::string& content, bool save_as) { base::FilePath path; diff --git a/atom/browser/common_web_contents_delegate.h b/atom/browser/common_web_contents_delegate.h index 61ff63793df5..699d00e18bce 100644 --- a/atom/browser/common_web_contents_delegate.h +++ b/atom/browser/common_web_contents_delegate.h @@ -76,6 +76,9 @@ class CommonWebContentsDelegate void ExitFullscreenModeForTab(content::WebContents* source) override; bool IsFullscreenForTabOrPending( const content::WebContents* source) const override; + content::SecurityStyle GetSecurityStyle( + content::WebContents* web_contents, + content::SecurityStyleExplanations* explanations) override; // brightray::InspectableWebContentsDelegate: void DevToolsSaveToFile(const std::string& url, diff --git a/atom/browser/native_window.cc b/atom/browser/native_window.cc index 9762351de228..d7ed86165b9f 100644 --- a/atom/browser/native_window.cc +++ b/atom/browser/native_window.cc @@ -162,8 +162,8 @@ void NativeWindow::InitFromOptions(const mate::Dictionary& options) { std::string color; if (options.Get(options::kBackgroundColor, &color)) { SetBackgroundColor(color); - } else if (has_frame()) { - // For window with frame, use white as default background. + } else if (!transparent()) { + // For normal window, use white as default background. SetBackgroundColor("#FFFF"); } std::string title("Electron"); diff --git a/atom/browser/native_window_mac.mm b/atom/browser/native_window_mac.mm index 3c76cbe25a57..b24e828e578d 100644 --- a/atom/browser/native_window_mac.mm +++ b/atom/browser/native_window_mac.mm @@ -807,9 +807,14 @@ bool NativeWindowMac::IsKiosk() { } void NativeWindowMac::SetBackgroundColor(const std::string& color_name) { - base::ScopedCFTypeRef color = - skia::CGColorCreateFromSkColor(ParseHexColor(color_name)); - [[[window_ contentView] layer] setBackgroundColor:color]; + SkColor color = ParseHexColor(color_name); + base::ScopedCFTypeRef cgcolor = + skia::CGColorCreateFromSkColor(color); + [[[window_ contentView] layer] setBackgroundColor:cgcolor]; + + const auto view = web_contents()->GetRenderWidgetHostView(); + if (view) + view->SetBackgroundColor(color); } void NativeWindowMac::SetHasShadow(bool has_shadow) { diff --git a/atom/browser/native_window_views.cc b/atom/browser/native_window_views.cc index 59d3556d05e3..93e43661302e 100644 --- a/atom/browser/native_window_views.cc +++ b/atom/browser/native_window_views.cc @@ -15,6 +15,7 @@ #include "base/strings/utf_string_conversions.h" #include "brightray/browser/inspectable_web_contents.h" #include "brightray/browser/inspectable_web_contents_view.h" +#include "content/public/browser/browser_thread.h" #include "content/public/browser/native_web_keyboard_event.h" #include "native_mate/dictionary.h" #include "ui/aura/window_tree_host.h" @@ -780,10 +781,12 @@ void NativeWindowViews::OnWidgetActivationChanged( if (widget != window_.get()) return; - if (active) - NotifyWindowFocus(); - else - NotifyWindowBlur(); + // Post the notification to next tick. + content::BrowserThread::PostTask( + content::BrowserThread::UI, FROM_HERE, + base::Bind(active ? &NativeWindow::NotifyWindowFocus : + &NativeWindow::NotifyWindowBlur, + GetWeakPtr())); if (active && inspectable_web_contents() && !inspectable_web_contents()->IsDevToolsViewShowing()) diff --git a/atom/browser/net/atom_network_delegate.cc b/atom/browser/net/atom_network_delegate.cc index 91b63fada359..86bfe12079ad 100644 --- a/atom/browser/net/atom_network_delegate.cc +++ b/atom/browser/net/atom_network_delegate.cc @@ -5,20 +5,18 @@ #include "atom/browser/net/atom_network_delegate.h" #include +#include #include "atom/common/native_mate_converters/net_converter.h" #include "base/stl_util.h" #include "base/strings/string_util.h" #include "content/public/browser/browser_thread.h" -#include "content/public/browser/resource_request_info.h" #include "net/url_request/url_request.h" using content::BrowserThread; namespace atom { -namespace { - const char* ResourceTypeToString(content::ResourceType type) { switch (type) { case content::RESOURCE_TYPE_MAIN_FRAME: @@ -40,6 +38,11 @@ const char* ResourceTypeToString(content::ResourceType type) { } } +namespace { + +using ResponseHeadersContainer = + std::pair*, const std::string&>; + void RunSimpleListener(const AtomNetworkDelegate::SimpleListener& listener, scoped_ptr details) { return listener.Run(*(details.get())); @@ -170,10 +173,15 @@ void ReadFromResponseObject(const base::DictionaryValue& response, } void ReadFromResponseObject(const base::DictionaryValue& response, - scoped_refptr* headers) { + const ResponseHeadersContainer& container) { const base::DictionaryValue* dict; + std::string status_line; + if (!response.GetString("statusLine", &status_line)) + status_line = container.second; if (response.GetDictionary("responseHeaders", &dict)) { + auto headers = container.first; *headers = new net::HttpResponseHeaders(""); + (*headers)->ReplaceStatusLine(status_line); for (base::DictionaryValue::Iterator it(*dict); !it.IsAtEnd(); it.Advance()) { @@ -263,7 +271,8 @@ int AtomNetworkDelegate::OnHeadersReceived( request, callback, original, override, allowed); return HandleResponseEvent( - kOnHeadersReceived, request, callback, override, original); + kOnHeadersReceived, request, callback, + std::make_pair(override, original->GetStatusLine()), original); } void AtomNetworkDelegate::OnBeforeRedirect(net::URLRequest* request, diff --git a/atom/browser/net/atom_network_delegate.h b/atom/browser/net/atom_network_delegate.h index 4f55f7c09863..ee159df60f13 100644 --- a/atom/browser/net/atom_network_delegate.h +++ b/atom/browser/net/atom_network_delegate.h @@ -15,6 +15,7 @@ #include "net/base/net_errors.h" #include "net/http/http_request_headers.h" #include "net/http/http_response_headers.h" +#include "content/public/browser/resource_request_info.h" namespace extensions { class URLPattern; @@ -24,6 +25,8 @@ namespace atom { using URLPatterns = std::set; +const char* ResourceTypeToString(content::ResourceType type); + class AtomNetworkDelegate : public brightray::NetworkDelegate { public: using ResponseCallback = base::Callback; diff --git a/atom/browser/web_contents_preferences.cc b/atom/browser/web_contents_preferences.cc index f36e7c076dca..05286a2d3ba4 100644 --- a/atom/browser/web_contents_preferences.cc +++ b/atom/browser/web_contents_preferences.cc @@ -8,6 +8,7 @@ #include #include +#include "atom/browser/native_window.h" #include "atom/common/native_mate_converters/value_converter.h" #include "atom/common/options_switches.h" #include "base/command_line.h" @@ -131,20 +132,28 @@ void WebContentsPreferences::AppendExtraCommandLineSwitches( // --guest-instance-id, which is used to identify guest WebContents. int guest_instance_id; if (web_preferences.GetInteger(options::kGuestInstanceID, &guest_instance_id)) - command_line->AppendSwitchASCII(switches::kGuestInstanceID, - base::IntToString(guest_instance_id)); + command_line->AppendSwitchASCII(switches::kGuestInstanceID, + base::IntToString(guest_instance_id)); // Pass the opener's window id. int opener_id; if (web_preferences.GetInteger(options::kOpenerID, &opener_id)) - command_line->AppendSwitchASCII(switches::kOpenerID, - base::IntToString(opener_id)); + command_line->AppendSwitchASCII(switches::kOpenerID, + base::IntToString(opener_id)); // Enable blink features. std::string blink_features; if (web_preferences.GetString(options::kBlinkFeatures, &blink_features)) - command_line->AppendSwitchASCII(::switches::kEnableBlinkFeatures, - blink_features); + command_line->AppendSwitchASCII(::switches::kEnableBlinkFeatures, + blink_features); + + // The initial visibility state. + NativeWindow* window = NativeWindow::FromWebContents(web_contents); + if (window) { + bool visible = window->IsVisible() && !window->IsMinimized(); + if (!visible) // Default state is visible. + command_line->AppendSwitch("hidden-page"); + } } // static diff --git a/atom/common/atom_constants.cc b/atom/common/atom_constants.cc index dacda3c816c8..f66c947aa24c 100644 --- a/atom/common/atom_constants.cc +++ b/atom/common/atom_constants.cc @@ -6,6 +6,22 @@ namespace atom { -const char* kCORSHeader = "Access-Control-Allow-Origin: *"; +const char kCORSHeader[] = "Access-Control-Allow-Origin: *"; + +const char kSHA1Certificate[] = "SHA-1 Certificate"; +const char kSHA1MajorDescription[] = + "The certificate for this site expires in 2017 or later, " + "and the certificate chain contains a certificate signed using SHA-1."; +const char kSHA1MinorDescription[] = + "The certificate for this site expires in 2016, " + "and the certificate chain contains a certificate signed using SHA-1."; +const char kCertificateError[] = "Certificate Error"; +const char kValidCertificate[] = "Valid Certificate"; +const char kValidCertificateDescription[] = + "The connection to this site is using a valid, trusted server certificate."; +const char kSecureProtocol[] = "Secure TLS connection"; +const char kSecureProtocolDescription[] = + "The connection to this site is using a strong protocol version " + "and cipher suite."; } // namespace atom diff --git a/atom/common/atom_constants.h b/atom/common/atom_constants.h index e0d42e83eef9..b67b7b2e4ae5 100644 --- a/atom/common/atom_constants.h +++ b/atom/common/atom_constants.h @@ -8,7 +8,17 @@ namespace atom { // Header to ignore CORS. -extern const char* kCORSHeader; +extern const char kCORSHeader[]; + +// Strings describing Chrome security policy for DevTools security panel. +extern const char kSHA1Certificate[]; +extern const char kSHA1MajorDescription[]; +extern const char kSHA1MinorDescription[]; +extern const char kCertificateError[]; +extern const char kValidCertificate[]; +extern const char kValidCertificateDescription[]; +extern const char kSecureProtocol[]; +extern const char kSecureProtocolDescription[]; } // namespace atom diff --git a/atom/common/platform_util_linux.cc b/atom/common/platform_util_linux.cc index 1e437b866cc0..9811c8760d06 100644 --- a/atom/common/platform_util_linux.cc +++ b/atom/common/platform_util_linux.cc @@ -13,7 +13,9 @@ namespace { -bool XDGUtil(const std::string& util, const std::string& arg) { +bool XDGUtil(const std::string& util, + const std::string& arg, + const bool wait_for_exit) { std::vector argv; argv.push_back(util); argv.push_back(arg); @@ -30,6 +32,11 @@ bool XDGUtil(const std::string& util, const std::string& arg) { if (!process.IsValid()) return false; + if (!wait_for_exit) { + base::EnsureProcessGetsReaped(process.Pid()); + return true; + } + int exit_code = -1; if (!process.WaitForExit(&exit_code)) return false; @@ -37,12 +44,12 @@ bool XDGUtil(const std::string& util, const std::string& arg) { return (exit_code == 0); } -bool XDGOpen(const std::string& path) { - return XDGUtil("xdg-open", path); +bool XDGOpen(const std::string& path, const bool wait_for_exit) { + return XDGUtil("xdg-open", path, wait_for_exit); } -bool XDGEmail(const std::string& email) { - return XDGUtil("xdg-email", email); +bool XDGEmail(const std::string& email, const bool wait_for_exit) { + return XDGUtil("xdg-email", email, wait_for_exit); } } // namespace @@ -57,22 +64,24 @@ void ShowItemInFolder(const base::FilePath& full_path) { if (!base::DirectoryExists(dir)) return; - XDGOpen(dir.value()); + XDGOpen(dir.value(), true); } void OpenItem(const base::FilePath& full_path) { - XDGOpen(full_path.value()); + XDGOpen(full_path.value(), true); } bool OpenExternal(const GURL& url, bool activate) { + // Don't wait for exit, since we don't want to wait for the browser/email + // client window to close before returning if (url.SchemeIs("mailto")) - return XDGEmail(url.spec()); + return XDGEmail(url.spec(), false); else - return XDGOpen(url.spec()); + return XDGOpen(url.spec(), false); } bool MoveItemToTrash(const base::FilePath& full_path) { - return XDGUtil("gvfs-trash", full_path.value()); + return XDGUtil("gvfs-trash", full_path.value(), true); } void Beep() { diff --git a/atom/renderer/atom_render_view_observer.cc b/atom/renderer/atom_render_view_observer.cc index bbaea351378b..96dffbd512a6 100644 --- a/atom/renderer/atom_render_view_observer.cc +++ b/atom/renderer/atom_render_view_observer.cc @@ -27,6 +27,7 @@ #include "third_party/WebKit/public/web/WebFrame.h" #include "third_party/WebKit/public/web/WebLocalFrame.h" #include "third_party/WebKit/public/web/WebKit.h" +#include "third_party/WebKit/public/web/WebScriptSource.h" #include "third_party/WebKit/public/web/WebView.h" #include "ui/base/resource/resource_bundle.h" #include "native_mate/dictionary.h" @@ -88,6 +89,9 @@ void AtomRenderViewObserver::DidCreateDocumentElement( blink::WebLocalFrame* frame) { document_created_ = true; + // Make sure every page will get a script context created. + frame->executeScript(blink::WebScriptSource("void 0")); + // Read --zoom-factor from command line. std::string zoom_factor_str = base::CommandLine::ForCurrentProcess()-> GetSwitchValueASCII(switches::kZoomFactor); diff --git a/atom/utility/atom_content_utility_client.cc b/atom/utility/atom_content_utility_client.cc index 2e591f2c6a8d..aff567fbcaab 100644 --- a/atom/utility/atom_content_utility_client.cc +++ b/atom/utility/atom_content_utility_client.cc @@ -37,7 +37,7 @@ int64_t AtomContentUtilityClient::max_ipc_message_size_ = AtomContentUtilityClient::AtomContentUtilityClient() : filter_messages_(false) { #if defined(OS_WIN) - handlers_.push_back(new PrintingHandlerWin()); + handlers_.push_back(new printing::PrintingHandlerWin()); #endif } @@ -71,11 +71,4 @@ void AtomContentUtilityClient::OnStartupPing() { // Don't release the process, we assume further messages are on the way. } -// static -void AtomContentUtilityClient::PreSandboxStartup() { -#if defined(OS_WIN) - PrintingHandlerWin::PreSandboxStartup(); -#endif -} - } // namespace atom diff --git a/atom/utility/atom_content_utility_client.h b/atom/utility/atom_content_utility_client.h index 229ae3f91765..ba0fef471a11 100644 --- a/atom/utility/atom_content_utility_client.h +++ b/atom/utility/atom_content_utility_client.h @@ -31,8 +31,6 @@ class AtomContentUtilityClient : public content::ContentUtilityClient { void UtilityThreadStarted() override; bool OnMessageReceived(const IPC::Message& message) override; - static void PreSandboxStartup(); - static void set_max_ipc_message_size_for_test(int64_t max_message_size) { max_ipc_message_size_ = max_message_size; } diff --git a/chromium_src/chrome/utility/printing_handler_win.cc b/chromium_src/chrome/utility/printing_handler_win.cc index 805cd6e343c8..b0bbac523671 100644 --- a/chromium_src/chrome/utility/printing_handler_win.cc +++ b/chromium_src/chrome/utility/printing_handler_win.cc @@ -10,11 +10,14 @@ #include "base/scoped_native_library.h" #include "chrome/common/print_messages.h" #include "content/public/utility/utility_thread.h" +#include "pdf/pdf.h" #include "printing/emf_win.h" #include "printing/page_range.h" #include "printing/pdf_render_settings.h" #include "ui/gfx/gdi_util.h" +namespace printing { + namespace { bool Send(IPC::Message* message) { @@ -25,114 +28,12 @@ void ReleaseProcessIfNeeded() { content::UtilityThread::Get()->ReleaseProcessIfNeeded(); } -class PdfFunctions { - public: - PdfFunctions() : get_pdf_doc_info_func_(NULL), - render_pdf_to_dc_func_(NULL) {} - - bool Init() { - base::FilePath module_path; - if (!PathService::Get(base::DIR_MODULE, &module_path)) - return false; - base::FilePath::StringType name(FILE_PATH_LITERAL("pdf.dll")); - pdf_lib_.Reset(base::LoadNativeLibrary(module_path.Append(name), NULL)); - if (!pdf_lib_.is_valid()) { - LOG(WARNING) << "Couldn't load PDF plugin"; - return false; - } - - get_pdf_doc_info_func_ = - reinterpret_cast( - pdf_lib_.GetFunctionPointer("GetPDFDocInfo")); - LOG_IF(WARNING, !get_pdf_doc_info_func_) << "Missing GetPDFDocInfo"; - - render_pdf_to_dc_func_ = - reinterpret_cast( - pdf_lib_.GetFunctionPointer("RenderPDFPageToDC")); - LOG_IF(WARNING, !render_pdf_to_dc_func_) << "Missing RenderPDFPageToDC"; - - if (!get_pdf_doc_info_func_ || !render_pdf_to_dc_func_) { - Reset(); - } - - return IsValid(); - } - - bool IsValid() const { - return pdf_lib_.is_valid(); - } - - void Reset() { - pdf_lib_.Reset(NULL); - } - - bool GetPDFDocInfo(const void* pdf_buffer, - int buffer_size, - int* page_count, - double* max_page_width) { - if (!get_pdf_doc_info_func_) - return false; - return get_pdf_doc_info_func_(pdf_buffer, buffer_size, page_count, - max_page_width); - } - - bool RenderPDFPageToDC(const void* pdf_buffer, - int buffer_size, - int page_number, - HDC dc, - int dpi, - int bounds_origin_x, - int bounds_origin_y, - int bounds_width, - int bounds_height, - bool fit_to_bounds, - bool stretch_to_bounds, - bool keep_aspect_ratio, - bool center_in_bounds, - bool autorotate) { - if (!render_pdf_to_dc_func_) - return false; - return render_pdf_to_dc_func_(pdf_buffer, buffer_size, page_number, - dc, dpi, bounds_origin_x, - bounds_origin_y, bounds_width, bounds_height, - fit_to_bounds, stretch_to_bounds, - keep_aspect_ratio, center_in_bounds, - autorotate); - } - - private: - // Exported by PDF plugin. - typedef bool (*GetPDFDocInfoProc)(const void* pdf_buffer, - int buffer_size, int* page_count, - double* max_page_width); - typedef bool (*RenderPDFPageToDCProc)( - const void* pdf_buffer, int buffer_size, int page_number, HDC dc, - int dpi, int bounds_origin_x, int bounds_origin_y, - int bounds_width, int bounds_height, bool fit_to_bounds, - bool stretch_to_bounds, bool keep_aspect_ratio, bool center_in_bounds, - bool autorotate); - - RenderPDFPageToDCProc render_pdf_to_dc_func_; - GetPDFDocInfoProc get_pdf_doc_info_func_; - - base::ScopedNativeLibrary pdf_lib_; - - DISALLOW_COPY_AND_ASSIGN(PdfFunctions); -}; - -base::LazyInstance g_pdf_lib = LAZY_INSTANCE_INITIALIZER; - } // namespace PrintingHandlerWin::PrintingHandlerWin() {} PrintingHandlerWin::~PrintingHandlerWin() {} -// static -void PrintingHandlerWin::PreSandboxStartup() { - g_pdf_lib.Get().Init(); -} - bool PrintingHandlerWin::OnMessageReceived(const IPC::Message& message) { bool handled = true; IPC_BEGIN_MESSAGE_MAP(PrintingHandlerWin, message) @@ -149,7 +50,7 @@ bool PrintingHandlerWin::OnMessageReceived(const IPC::Message& message) { void PrintingHandlerWin::OnRenderPDFPagesToMetafile( IPC::PlatformFileForTransit pdf_transit, - const printing::PdfRenderSettings& settings) { + const PdfRenderSettings& settings) { pdf_rendering_settings_ = settings; base::File pdf_file = IPC::PlatformFileForTransitToFile(pdf_transit); int page_count = LoadPDF(pdf_file.Pass()); @@ -174,9 +75,6 @@ void PrintingHandlerWin::OnRenderPDFPagesToMetafileStop() { } int PrintingHandlerWin::LoadPDF(base::File pdf_file) { - if (!g_pdf_lib.Get().IsValid()) - return 0; - int64_t length64 = pdf_file.GetLength(); if (length64 <= 0 || length64 > std::numeric_limits::max()) return 0; @@ -187,8 +85,8 @@ int PrintingHandlerWin::LoadPDF(base::File pdf_file) { return 0; int total_page_count = 0; - if (!g_pdf_lib.Get().GetPDFDocInfo( - &pdf_data_.front(), pdf_data_.size(), &total_page_count, NULL)) { + if (!chrome_pdf::GetPDFDocInfo(&pdf_data_.front(), pdf_data_.size(), + &total_page_count, nullptr)) { return 0; } return total_page_count; @@ -197,7 +95,7 @@ int PrintingHandlerWin::LoadPDF(base::File pdf_file) { bool PrintingHandlerWin::RenderPdfPageToMetafile(int page_number, base::File output_file, float* scale_factor) { - printing::Emf metafile; + Emf metafile; metafile.Init(); // We need to scale down DC to fit an entire page into DC available area. @@ -216,7 +114,7 @@ bool PrintingHandlerWin::RenderPdfPageToMetafile(int page_number, // The underlying metafile is of type Emf and ignores the arguments passed // to StartPage. metafile.StartPage(gfx::Size(), gfx::Rect(), 1); - if (!g_pdf_lib.Get().RenderPDFPageToDC( + if (!chrome_pdf::RenderPDFPageToDC( &pdf_data_.front(), pdf_data_.size(), page_number, @@ -237,3 +135,5 @@ bool PrintingHandlerWin::RenderPdfPageToMetafile(int page_number, metafile.FinishDocument(); return metafile.SaveTo(&output_file); } + +} // printing diff --git a/chromium_src/chrome/utility/printing_handler_win.h b/chromium_src/chrome/utility/printing_handler_win.h index 5b8c5e970f15..e7fcc5bed158 100644 --- a/chromium_src/chrome/utility/printing_handler_win.h +++ b/chromium_src/chrome/utility/printing_handler_win.h @@ -12,10 +12,10 @@ #include "printing/pdf_render_settings.h" namespace printing { + class PdfRenderSettings; struct PwgRasterSettings; struct PageRange; -} // Dispatches IPCs for printing. class PrintingHandlerWin : public UtilityMessageHandler { @@ -26,12 +26,10 @@ class PrintingHandlerWin : public UtilityMessageHandler { // IPC::Listener: bool OnMessageReceived(const IPC::Message& message) override; - static void PrintingHandlerWin::PreSandboxStartup(); - private: // IPC message handlers. void OnRenderPDFPagesToMetafile(IPC::PlatformFileForTransit pdf_transit, - const printing::PdfRenderSettings& settings); + const PdfRenderSettings& settings); void OnRenderPDFPagesToMetafileGetPage( int page_number, IPC::PlatformFileForTransit output_file); @@ -43,9 +41,11 @@ class PrintingHandlerWin : public UtilityMessageHandler { float* scale_factor); std::vector pdf_data_; - printing::PdfRenderSettings pdf_rendering_settings_; + PdfRenderSettings pdf_rendering_settings_; DISALLOW_COPY_AND_ASSIGN(PrintingHandlerWin); }; +} // namespace printing + #endif // CHROME_UTILITY_PRINTING_HANDLER_WIN_H_ diff --git a/docs-translations/ko-KR/api/auto-updater.md b/docs-translations/ko-KR/api/auto-updater.md index e5121d0f9b1d..e699108a649c 100644 --- a/docs-translations/ko-KR/api/auto-updater.md +++ b/docs-translations/ko-KR/api/auto-updater.md @@ -2,8 +2,14 @@ 이 모듈은 `Squirrel` 자동 업데이트 프레임워크의 인터페이스를 제공합니다. -[electron-release-server](https://github.com/ArekSredzki/electron-release-server)를 -포크하면 어플리케이션을 배포하기 위한 멀티 플랫폼 릴리즈 서버를 손쉽게 구축할 수 있습니다. +다음 프로젝트 중 하나를 택하여 사용하면, 어플리케이션을 배포하기 위한 멀티 플랫폼 +릴리즈 서버를 손쉽게 구축할 수 있습니다: + +- [electron-release-server][electron-release-server]: *완벽하게 모든 기능을 +지원하는 electron 어플리케이션을 위한 자가 호스트 릴리즈 서버입니다. auto-updater와 +호환됩니다* +- [squirrel-updates-server][squirrel-updates-server]: *GitHub 릴리즈를 사용하는 +Squirrel.Mac 와 Squirrel.Windows를 위한 간단한 node.js 기반 서버입니다* ## 플랫폼별 참고 사항 @@ -16,6 +22,9 @@ OS X에선 `auto-updater` 모듈이 [Squirrel.Mac][squirrel-mac]를 기반으로 따라서 이 모듈을 작동시키기 위해 특별히 준비해야 할 작업은 없습니다. 서버 사이드 요구 사항은 [서버 지원][server-support]을 참고하세요. +**참고:** Mac OS X에서 자동 업데이트를 지원하려면 반드시 사인이 되어있어야 합니다. +이것은 `Squirrel.Mac`의 요구사항입니다. + ### Windows Windows에선 `auto-updater` 모듈을 사용하기 전에 어플리케이션을 사용자의 장치에 @@ -95,5 +104,7 @@ Returns: [squirrel-mac]: https://github.com/Squirrel/Squirrel.Mac [server-support]: https://github.com/Squirrel/Squirrel.Mac#server-support [squirrel-windows]: https://github.com/Squirrel/Squirrel.Windows -[installer]: https://github.com/atom/grunt-electron-installer +[installer]: https://github.com/electron/grunt-electron-installer [app-user-model-id]: https://msdn.microsoft.com/en-us/library/windows/desktop/dd378459(v=vs.85).aspx +[electron-release-server]: https://github.com/ArekSredzki/electron-release-server +[squirrel-updates-server]: https://github.com/Aluxian/squirrel-updates-server diff --git a/docs-translations/ko-KR/api/browser-window.md b/docs-translations/ko-KR/api/browser-window.md index e93956b6fd8c..45b7d3083087 100644 --- a/docs-translations/ko-KR/api/browser-window.md +++ b/docs-translations/ko-KR/api/browser-window.md @@ -173,6 +173,8 @@ win.show(); * `defaultMonospaceFontSize` Integer - 기본값 `13`. * `minimumFontSize` Integer - 기본값 `0`. * `defaultEncoding` String - 기본값 `ISO-8859-1`. +* `backgroundThrottling` Boolean - 페이지가 백그라운드 상태에 진입할 때 애니메이션과 + 타이머에 스로틀을 적용할지 여부입니다. 기본값은 `true`입니다. ## Events diff --git a/docs-translations/ko-KR/api/crash-reporter.md b/docs-translations/ko-KR/api/crash-reporter.md index c1437571d3f2..382fcd5924bf 100644 --- a/docs-translations/ko-KR/api/crash-reporter.md +++ b/docs-translations/ko-KR/api/crash-reporter.md @@ -20,7 +20,7 @@ crashReporter.start({ 있습니다: * [socorro](https://github.com/mozilla/socorro) -* [mini-breakpad-server](https://github.com/atom/mini-breakpad-server) +* [mini-breakpad-server](https://github.com/electron/mini-breakpad-server) ## Methods @@ -43,7 +43,7 @@ crashReporter.start({ **참고:** OS X에선 Windows와 Linux의 `breakpad`와 달리 새로운 `crashpad` 클라이언트를 사용합니다. 오류 수집 기능을 활성화 시키려면 오류를 수집하고 싶은 메인 프로세스나 랜더러 프로세스에서 `crashReporter.start` 메서드를 호출하여 `crashpad`를 -초기화 해야합니다. +초기화해야 합니다. ### `crashReporter.getLastCrashReport()` diff --git a/docs-translations/ko-KR/api/frameless-window.md b/docs-translations/ko-KR/api/frameless-window.md index 3d3e63312c74..7bcdeb4a60bc 100644 --- a/docs-translations/ko-KR/api/frameless-window.md +++ b/docs-translations/ko-KR/api/frameless-window.md @@ -1,6 +1,6 @@ # Frameless Window -Frameless Window는 [창 테두리](https://developer.mozilla.org/en-US/docs/Glossary/Chrome)가 +Frameless Window는 [창 테두리](https://developer.mozilla.org/ko/docs/Glossary/Chrome)가 없는 윈도우를 말합니다. 이 기능은 윈도우의 일부분인 툴바와 같이 웹 페이지의 일부분이 아닌 부분을 보이지 않도록 합니다. [`BrowserWindow`](browser-window.md) 클래스의 옵션에서 설정할 수 있습니다. diff --git a/docs-translations/ko-KR/api/menu.md b/docs-translations/ko-KR/api/menu.md index 7f1a5af16c63..7ab9c6c02aa7 100644 --- a/docs-translations/ko-KR/api/menu.md +++ b/docs-translations/ko-KR/api/menu.md @@ -1,6 +1,6 @@ # Menu -`menu` 클래스는 어플리케이션 메뉴와 [컨텍스트 메뉴](https://developer.mozilla.org/en-US/docs/Mozilla/Tech/XUL/PopupGuide/ContextMenus)를 +`menu` 클래스는 어플리케이션 메뉴와 [컨텍스트 메뉴](https://developer.mozilla.org/ko/docs/Mozilla/Tech/XUL/PopupGuide/ContextMenus)를 만들 때 사용됩니다. 이 모듈은 메인 프로세스용 모듈이지만 `remote` 모듈을 통해 랜더러 프로세스에서도 사용할 수 있습니다. @@ -382,4 +382,4 @@ OS X에선 지정한 어플리케이션 메뉴에 상관없이 메뉴의 첫번 ``` [AboutInformationPropertyListFiles]: https://developer.apple.com/library/ios/documentation/general/Reference/InfoPlistKeyReference/Articles/AboutInformationPropertyListFiles.html -[setMenu]: https://github.com/electron/electron/blob/master/docs-translations/ko-KR/api/browser-window.md#winsetmenumenu-linux-windows +[setMenu]: ./browser-window.md#winsetmenumenu-linux-windows diff --git a/docs-translations/ko-KR/api/remote.md b/docs-translations/ko-KR/api/remote.md index 3a09084acdef..ab05d838cc59 100644 --- a/docs-translations/ko-KR/api/remote.md +++ b/docs-translations/ko-KR/api/remote.md @@ -5,7 +5,7 @@ Electron의 메인 프로세스에선 GUI와 관련 있는(`dialog`, `menu`등) 모듈만 사용할 수 있습니다. 랜더러 프로세스에서 이러한 모듈들을 사용하려면 `ipc` 모듈을 통해 메인 -프로세스와 inter-process 통신을 해야합니다. 또한, `remote` 모듈을 사용하면 +프로세스와 inter-process 통신을 해야 합니다. 또한, `remote` 모듈을 사용하면 inter-process 통신을 하지 않고도 간단한 API를 통해 직접 메인 프로세스의 모듈과 메서드를 사용할 수 있습니다. 이 개념은 Java의 [RMI][rmi]와 비슷합니다. @@ -34,7 +34,7 @@ win.loadURL('https://github.com'); 않습니다. 대신에 이 `BrowserWindow` 객체는 메인 프로세스에서 생성되며 랜더러 프로세스에 `win` 객체와 같이 이에 대응하는 remote 객체를 반환합니다. -참고로 remote를 통해선 [enumerable 속성](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Enumerability_and_ownership_of_properties)을 +참고로 remote를 통해선 [enumerable 속성](https://developer.mozilla.org/ko/docs/Web/JavaScript/Enumerability_and_ownership_of_properties)을 가진 프로퍼티에만 접근할 수 있습니다. ## Remote 객체의 생명 주기 diff --git a/docs-translations/ko-KR/api/synopsis.md b/docs-translations/ko-KR/api/synopsis.md index b392f206c136..47771b23ceb1 100644 --- a/docs-translations/ko-KR/api/synopsis.md +++ b/docs-translations/ko-KR/api/synopsis.md @@ -78,5 +78,5 @@ require('electron').hideInternalModules() ``` [gui]: https://en.wikipedia.org/wiki/Graphical_user_interface -[destructuring-assignment]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment +[destructuring-assignment]: https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment [issue-387]: https://github.com/electron/electron/issues/387 diff --git a/docs-translations/ko-KR/api/tray.md b/docs-translations/ko-KR/api/tray.md index 28a44199c00e..b0293d40fcb3 100644 --- a/docs-translations/ko-KR/api/tray.md +++ b/docs-translations/ko-KR/api/tray.md @@ -11,7 +11,7 @@ const Tray = electron.Tray; var appIcon = null; app.on('ready', function(){ - appIcon = new Tray('/path/to/my/icon'); // 현재 어플리케이션 디렉터리를 기준으로 하려면 `__dirname + '/images/tray.png'` 형식으로 입력해야합니다. + appIcon = new Tray('/path/to/my/icon'); // 현재 어플리케이션 디렉터리를 기준으로 하려면 `__dirname + '/images/tray.png'` 형식으로 입력해야 합니다. var contextMenu = Menu.buildFromTemplate([ { label: 'Item1', type: 'radio' }, { label: 'Item2', type: 'radio' }, diff --git a/docs-translations/ko-KR/api/web-contents.md b/docs-translations/ko-KR/api/web-contents.md index 2c066a941105..3e19fcd66bc8 100644 --- a/docs-translations/ko-KR/api/web-contents.md +++ b/docs-translations/ko-KR/api/web-contents.md @@ -67,6 +67,7 @@ Returns: * `requestMethod` String * `referrer` String * `headers` Object +* `resourceType` String 요청한 리소스에 관련된 자세한 정보를 사용할 수 있을 때 발생하는 이벤트입니다. `status`는 리소스를 다운로드하기 위한 소켓 연결을 나타냅니다. diff --git a/docs-translations/ko-KR/api/web-view-tag.md b/docs-translations/ko-KR/api/web-view-tag.md index a40a22070f36..314cc3449761 100644 --- a/docs-translations/ko-KR/api/web-view-tag.md +++ b/docs-translations/ko-KR/api/web-view-tag.md @@ -17,9 +17,15 @@ 수 있습니다: ```html - + ``` +주의할 점은 `webview` 태그의 스타일은 전통적인 flexbox 레이아웃을 사용했을 때 자식 +`object` 요소가 해당 `webview` 컨테이너의 전체 높이와 넓이를 확실히 채우도록 +내부적으로 `display:flex;`를 사용합니다. (v0.36.11 부터) 따라서 인라인 레이아웃을 +위해 `display:inline-flex;`를 쓰지 않는 한, 기본 `display:flex;` CSS 속성을 +덮어쓰지 않도록 주의해야 합니다. + 게스트 컨텐츠를 조작하기 위해 자바스크립트로 `webview` 태그의 이벤트를 리스닝 하여 응답을 받을 수 있습니다. 다음 예제를 참고하세요: 첫번째 리스너는 페이지 로딩 시작시의 이벤트를 확인하고 두번째 리스너는 페이지의 로딩이 끝난시점을 확인합니다. 그리고 @@ -495,6 +501,7 @@ Returns: * `requestMethod` String * `referrer` String * `headers` Object +* `resourceType` String 요청한 리소스에 관해 자세한 내용을 알 수 있을 때 발생하는 이벤트입니다. `status`는 리소스를 다운로드할 소켓 커낵션을 나타냅니다. diff --git a/docs-translations/ko-KR/development/atom-shell-vs-node-webkit.md b/docs-translations/ko-KR/development/atom-shell-vs-node-webkit.md index f59c7ceb70bc..21972d2f38ae 100644 --- a/docs-translations/ko-KR/development/atom-shell-vs-node-webkit.md +++ b/docs-translations/ko-KR/development/atom-shell-vs-node-webkit.md @@ -16,7 +16,7 @@ main 필드에 메인 웹 페이지(index.html) URL을 지정하면 어플리케 Electron에선 JavaScript를 엔트리 포인트로 사용합니다. URL을 직접 제공하는 대신 API를 사용하여 직접 브라우저 창과 HTML 파일을 로드할 수 있습니다. 또한 윈도우의 종료시기를 -결정하는 이벤트를 리스닝해야합니다. +결정하는 이벤트를 리스닝해야 합니다. Electron은 Node.js 런타임과 비슷하게 작동합니다. Electron의 API는 저수준이기에 브라우저 테스팅을 위해 [PhantomJS](http://phantomjs.org/)를 사용할 수도 있습니다. diff --git a/docs-translations/ko-KR/development/coding-style.md b/docs-translations/ko-KR/development/coding-style.md index cb3e68ce25bc..9c15f677fe29 100644 --- a/docs-translations/ko-KR/development/coding-style.md +++ b/docs-translations/ko-KR/development/coding-style.md @@ -26,17 +26,17 @@ C++ 코드는 많은 Chromium의 추상화와 타입을 사용합니다. 따라 * [표준](http://npm.im/standard) JavaScript 코딩 스타일을 사용합니다. * Google의 코딩 스타일에도 맞추기 위해 파일의 끝에는 **절대** 개행을 삽입해선 안됩니다. * 파일 이름의 공백은 `_`대신에 `-`을 사용하여야 합니다. 예를 들어 -`file_name.js`를 `file-name.js`로 고쳐야합니다. 왜냐하면 +`file_name.js`를 `file-name.js`로 고쳐야 합니다. 왜냐하면 [github/atom](https://github.com/github/atom)에서 사용되는 모듈의 이름은 보통 `module-name` 형식이기 때문입니다. 이 규칙은 '.js' 파일에만 적용됩니다. * 적절한 곳에 새로운 ES6/ES2015 문법을 사용해도 됩니다. - * [`const`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/const) + * [`const`](https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Statements/const) 는 requires와 다른 상수에 사용합니다 - * [`let`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/let) + * [`let`](https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Statements/let) 은 변수를 정의할 때 사용합니다 - * [Arrow functions](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions) + * [Arrow functions](https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Functions/Arrow_functions) 는 `function () { }` 표현 대신에 사용합니다 - * [Template literals](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals) + * [Template literals](https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Template_literals) 는 `+`로 문자열을 합치는 대신 사용합니다. ## API 이름 diff --git a/docs-translations/ko-KR/development/setting-up-symbol-server.md b/docs-translations/ko-KR/development/setting-up-symbol-server.md index e2bcd173a4bc..abfda6851bfc 100644 --- a/docs-translations/ko-KR/development/setting-up-symbol-server.md +++ b/docs-translations/ko-KR/development/setting-up-symbol-server.md @@ -14,7 +14,7 @@ 공식적인 Electron의 심볼 서버의 URL은 http://54.249.141.255:8086/atom-shell/symbols 입니다. 일단 이 URL에 직접적으로 -접근할 수는 없습니다: 디버깅 툴에 심볼의 경로를 추가해야합니다. 아래의 예제를 참고하면 +접근할 수는 없습니다: 디버깅 툴에 심볼의 경로를 추가해야 합니다. 아래의 예제를 참고하면 로컬 캐시 디렉터리는 서버로부터 중복되지 않게 PDB를 가져오는데 사용됩니다. `c:\code\symbols` 캐시 디렉터리를 사용중인 OS에 맞춰 적당한 경로로 변경하세요. @@ -30,7 +30,7 @@ SRV*c:\code\symbols\*http://54.249.141.255:8086/atom-shell/symbols Windbg 메뉴 또는 `.sympath` 커맨드를 이용하여 환경에 `_NT_SYMBOL_PATH` 문자열을 설정합니다. 만약 Microsoft의 심볼서버로부터 심볼을 받아오려면 다음과 같이 리스팅을 -먼저 해야합니다: +먼저해야 합니다: ``` SRV*c:\code\symbols\*http://msdl.microsoft.com/download/symbols;SRV*c:\code\symbols\*http://54.249.141.255:8086/atom-shell/symbols diff --git a/docs-translations/ko-KR/faq/electron-faq.md b/docs-translations/ko-KR/faq/electron-faq.md index ea9953fcd4cd..5382372bfbbc 100644 --- a/docs-translations/ko-KR/faq/electron-faq.md +++ b/docs-translations/ko-KR/faq/electron-faq.md @@ -147,7 +147,7 @@ npm uninstall -g electron [memory-management]: https://developer.mozilla.org/ko/docs/Web/JavaScript/Memory_Management [variable-scope]: https://msdn.microsoft.com/library/bzt2dkta(v=vs.94).aspx [electron-module]: https://www.npmjs.com/package/electron -[storage]: https://developer.mozilla.org/en-US/docs/Web/API/Storage -[local-storage]: https://developer.mozilla.org/en-US/docs/Web/API/Window/localStorage -[session-storage]: https://developer.mozilla.org/en-US/docs/Web/API/Window/sessionStorage -[indexed-db]: https://developer.mozilla.org/en-US/docs/Web/API/IndexedDB_API +[storage]: https://developer.mozilla.org/ko/docs/Web/API/Storage +[local-storage]: https://developer.mozilla.org/ko/docs/Web/API/Window/localStorage +[session-storage]: https://developer.mozilla.org/ko/docs/Web/API/Window/sessionStorage +[indexed-db]: https://developer.mozilla.org/ko/docs/Web/API/IndexedDB_API diff --git a/docs-translations/ko-KR/styleguide.md b/docs-translations/ko-KR/styleguide.md index 12dae10ec94d..91aa233dd4d3 100644 --- a/docs-translations/ko-KR/styleguide.md +++ b/docs-translations/ko-KR/styleguide.md @@ -50,7 +50,7 @@ Electron 문서 구조를 이해하는 데 참고할 수 있는 유용한 도움 ### Methods -[Method](https://developer.mozilla.org/en-US/docs/Glossary/Method) 문서의 +[Method](https://developer.mozilla.org/ko/docs/Glossary/Method) 문서의 예제입니다: --- @@ -66,16 +66,16 @@ Electron 문서 구조를 이해하는 데 참고할 수 있는 유용한 도움 묶어 이 인수가 다른 인수뒤에서 선택적으로 사용될 수 있다는 것을 표시합니다. 메서드 이름 하단에선 각 인수에 대해 자세한 설명을 합니다. 인수의 타입은: -[`String`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String), -[`Number`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number), -[`Object`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object), -[`Array`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array) +[`String`](https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/String), +[`Number`](https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Number), +[`Object`](https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Object), +[`Array`](https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Array) 와 같은 일반적으로 쓰이는 타입 중 하나를 받거나 Electron의 [`webContent`](api/web-content.md) 같은 커스텀 타입을 받습니다. ### Events -[Event](https://developer.mozilla.org/en-US/docs/Web/API/Event) 문서의 예제입니다: +[Event](https://developer.mozilla.org/ko/docs/Web/API/Event) 문서의 예제입니다: --- diff --git a/docs-translations/ko-KR/tutorial/application-distribution.md b/docs-translations/ko-KR/tutorial/application-distribution.md index 7072d7c4d952..445a9dda21d4 100644 --- a/docs-translations/ko-KR/tutorial/application-distribution.md +++ b/docs-translations/ko-KR/tutorial/application-distribution.md @@ -30,7 +30,7 @@ electron/resources/app ## asar로 앱 패키징 하기 -소스파일 전체를 복사해서 배포하는 것과는 별개로 [asar](https://github.com/atom/asar) +소스파일 전체를 복사해서 배포하는 것과는 별개로 [asar](https://github.com/electron/asar) 아카이브를 통해 어플리케이션의 소스코드가 사용자에게 노출되는 것을 방지할 수 있습니다. `asar` 아카이브를 사용할 땐 단순히 `app` 폴더 대신에 어플리케이션을 패키징한 diff --git a/docs-translations/ko-KR/tutorial/application-packaging.md b/docs-translations/ko-KR/tutorial/application-packaging.md index 9183f0eafe96..a33e2eef96cf 100644 --- a/docs-translations/ko-KR/tutorial/application-packaging.md +++ b/docs-translations/ko-KR/tutorial/application-packaging.md @@ -179,4 +179,4 @@ $ asar pack app app.asar --unpack *.node 포함되어 있습니다. 사용자에게 어플리케이션을 배포할 때 반드시 해당 폴더도 같이 배포해야 합니다. -[asar]: https://github.com/atom/asar +[asar]: https://github.com/electron/asar diff --git a/docs-translations/ko-KR/tutorial/mac-app-store-submission-guide.md b/docs-translations/ko-KR/tutorial/mac-app-store-submission-guide.md index ee70114fad19..43d707b7942f 100644 --- a/docs-translations/ko-KR/tutorial/mac-app-store-submission-guide.md +++ b/docs-translations/ko-KR/tutorial/mac-app-store-submission-guide.md @@ -17,7 +17,7 @@ Electron은 v0.34.0 버전부터 앱 패키지를 Mac App Store(MAS)에 제출 다음 몇 가지 간단한 절차에 따라 앱 스토어에 어플리케이션을 등록하는 방법을 알아봅니다. 한가지, 이 절차는 제출한 앱이 Apple로부터 승인되는 것을 보장하지 않습니다. 따라서 여전히 Apple의 [Submitting Your App][submitting-your-app] 가이드를 숙지하고 있어야 -하며 앱 스토어 제출 요구 사항을 확실히 인지하고 있어야합니다. +하며 앱 스토어 제출 요구 사항을 확실히 인지하고 있어야 합니다. ### 인증서 취득 diff --git a/docs-translations/ko-KR/tutorial/using-native-node-modules.md b/docs-translations/ko-KR/tutorial/using-native-node-modules.md index ed00d7ae6083..e153b265b634 100644 --- a/docs-translations/ko-KR/tutorial/using-native-node-modules.md +++ b/docs-translations/ko-KR/tutorial/using-native-node-modules.md @@ -11,7 +11,7 @@ Electron의 V8 버전에 맞춰 네이티브 모듈을 다시 빌드하고 헤 node.js의 버전을 확인할 필요가 있습니다. Electron에서 사용하는 node 버전은 [releases](https://github.com/electron/electron/releases)에서 확인할 수 있으며 `process.version`을 출력하여 버전을 확인할 수도 있습니다. -([시작하기](https://github.com/electron/electron/blob/master/docs/tutorial/quick-start.md)의 +([시작하기](./quick-start.md)의 예제를 참고하세요) 혹시 직접 만든 네이티브 모듈이 있다면 [NAN](https://github.com/nodejs/nan/) 모듈을 diff --git a/docs-translations/ko-KR/tutorial/using-pepper-flash-plugin.md b/docs-translations/ko-KR/tutorial/using-pepper-flash-plugin.md index 2f15a3532eea..1437bbde92c9 100644 --- a/docs-translations/ko-KR/tutorial/using-pepper-flash-plugin.md +++ b/docs-translations/ko-KR/tutorial/using-pepper-flash-plugin.md @@ -13,7 +13,7 @@ Pepper 플래시 플러그인을 사용하려면 Pepper 플래시 플러그인 플러그인을 사용하려면 Electron 커맨드 라인에 `--ppapi-flash-path` 와 `ppapi-flash-version` 플래그를 app의 ready 이벤트가 호출되기 전에 추가해야 합니다. -그리고 `browser-window`에 `plugins` 스위치도 추가해야합니다. +그리고 `browser-window`에 `plugins` 스위치도 추가해야 합니다. ```javascript // 플래시 플러그인의 위치를 설정합니다. diff --git a/docs-translations/zh-CN/api/process.md b/docs-translations/zh-CN/api/process.md index d07741247aa5..7e8173dfb3b3 100644 --- a/docs-translations/zh-CN/api/process.md +++ b/docs-translations/zh-CN/api/process.md @@ -31,7 +31,7 @@ process.once('loaded', function() { ### `process.noAsar` -设置它为 `true` 可以使 `asar` 文件在node的内置模块中实效. +设置它为 `true` 可以使 `asar` 文件在node的内置模块中失效. ## 方法 @@ -45,4 +45,4 @@ process.once('loaded', function() { * `maxDescriptors` Integer -设置文件描述符软限制于 `maxDescriptors` 或硬限制与os, 无论它是否低于当前进程. \ No newline at end of file +设置文件描述符软限制于 `maxDescriptors` 或硬限制与os, 无论它是否低于当前进程. diff --git a/docs-translations/zh-CN/api/web-contents.md b/docs-translations/zh-CN/api/web-contents.md index 89d72f77aa74..54b9c56dcc6c 100644 --- a/docs-translations/zh-CN/api/web-contents.md +++ b/docs-translations/zh-CN/api/web-contents.md @@ -63,6 +63,7 @@ var webContents = win.webContents; * `requestMethod` String * `referrer` String * `headers` Object +* `resourceType` String 当有关请求资源的详细信息可用的时候发出事件. `status` 标识了 socket链接来下载资源. diff --git a/docs-translations/zh-CN/api/web-view-tag.md b/docs-translations/zh-CN/api/web-view-tag.md index e1e31f6f5a02..a1348c4d5882 100644 --- a/docs-translations/zh-CN/api/web-view-tag.md +++ b/docs-translations/zh-CN/api/web-view-tag.md @@ -457,6 +457,7 @@ Returns: * `requestMethod` String * `referrer` String * `headers` Object +* `resourceType` String 当获得返回详情的时候触发. diff --git a/docs-translations/zh-CN/tutorial/application-distribution.md b/docs-translations/zh-CN/tutorial/application-distribution.md index f3cf3692b5db..2dca19342ad5 100644 --- a/docs-translations/zh-CN/tutorial/application-distribution.md +++ b/docs-translations/zh-CN/tutorial/application-distribution.md @@ -27,7 +27,7 @@ electron/resources/app ## 将你的应用程序打包成一个文件 -除了通过拷贝所有的资源文件来分发你的应用程序之外,你可以可以通过打包你的应用程序为一个 [asar](https://github.com/atom/asar) 库文件以避免暴露你的源代码。 +除了通过拷贝所有的资源文件来分发你的应用程序之外,你可以通过打包你的应用程序为一个 [asar](https://github.com/atom/asar) 库文件以避免暴露你的源代码。 为了使用一个 `asar` 库文件代替 `app` 文件夹,你需要修改这个库文件的名字为 `app.asar` , 然后将其放到 Electron 的资源文件夹下,然后 Electron 就会试图读取这个库文件并从中启动。 diff --git a/docs-translations/zh-CN/tutorial/online-offline-events.md b/docs-translations/zh-CN/tutorial/online-offline-events.md index 7389afa4c9e5..d61f7378b967 100644 --- a/docs-translations/zh-CN/tutorial/online-offline-events.md +++ b/docs-translations/zh-CN/tutorial/online-offline-events.md @@ -3,10 +3,11 @@ *main.js* ```javascript -var app = require('app'); -var BrowserWindow = require('browser-window'); -var onlineStatusWindow; +const electron = require('electron'); +const app = electron.app; +const BrowserWindow = electron.BrowserWindow; +var onlineStatusWindow; app.on('ready', function() { onlineStatusWindow = new BrowserWindow({ width: 0, height: 0, show: false }); onlineStatusWindow.loadURL('file://' + __dirname + '/online-status.html'); @@ -36,17 +37,18 @@ app.on('ready', function() { *main.js* ```javascript -var app = require('app'); -var ipc = require('ipc'); -var BrowserWindow = require('browser-window'); -var onlineStatusWindow; +const electron = require('electron'); +const app = electron.app; +const ipcMain = electron.ipcMain; +const BrowserWindow = electron.BrowserWindow; +var onlineStatusWindow; app.on('ready', function() { onlineStatusWindow = new BrowserWindow({ width: 0, height: 0, show: false }); onlineStatusWindow.loadURL('file://' + __dirname + '/online-status.html'); }); -ipc.on('online-status-changed', function(event, status) { +ipcMain.on('online-status-changed', function(event, status) { console.log(status); }); ``` @@ -57,9 +59,9 @@ ipc.on('online-status-changed', function(event, status) { + + diff --git a/spec/fixtures/pages/webview-no-script.html b/spec/fixtures/pages/webview-no-script.html new file mode 100644 index 000000000000..00b8f21bde70 --- /dev/null +++ b/spec/fixtures/pages/webview-no-script.html @@ -0,0 +1,5 @@ + + + + + diff --git a/spec/webview-spec.js b/spec/webview-spec.js index 0d32138906e3..10758a0a4365 100644 --- a/spec/webview-spec.js +++ b/spec/webview-spec.js @@ -2,7 +2,7 @@ const assert = require('assert') const path = require('path') const http = require('http') const url = require('url') -const {app, session} = require('electron').remote +const {app, session, ipcMain, BrowserWindow} = require('electron').remote describe(' tag', function () { this.timeout(10000) @@ -20,6 +20,15 @@ describe(' tag', function () { } }) + it('works without script tag in page', function (done) { + let w = new BrowserWindow({show: false}) + ipcMain.once('pong', function () { + w.destroy() + done() + }) + w.loadURL('file://' + fixtures + '/pages/webview-no-script.html') + }) + describe('src attribute', function () { it('specifies the page to load', function (done) { webview.addEventListener('console-message', function (e) { @@ -155,6 +164,18 @@ describe(' tag', function () { webview.src = 'file://' + fixtures + '/pages/e.html' document.body.appendChild(webview) }) + + it('works without script tag in page', function (done) { + var listener = function (e) { + assert.equal(e.message, 'function object object') + webview.removeEventListener('console-message', listener) + done() + } + webview.addEventListener('console-message', listener) + webview.setAttribute('preload', fixtures + '/module/preload.js') + webview.src = 'file://' + fixtures + '/pages/base-page.html' + document.body.appendChild(webview) + }) }) describe('httpreferrer attribute', function () { @@ -763,4 +784,33 @@ describe(' tag', function () { document.body.appendChild(webview) }) }) + + describe('did-get-response-details event', function () { + it('emits for the page and its resources', function (done) { + // expected {fileName: resourceType} pairs + var expectedResources = { + 'did-get-response-details.html': 'mainFrame', + 'logo.png': 'image' + } + var responses = 0; + webview.addEventListener('did-get-response-details', function (event) { + responses++ + var fileName = event.newURL.slice(event.newURL.lastIndexOf('/') + 1) + var expectedType = expectedResources[fileName] + assert(!!expectedType, `Unexpected response details for ${event.newURL}`) + assert(typeof event.status === 'boolean', 'status should be boolean') + assert.equal(event.httpResponseCode, 200) + assert.equal(event.requestMethod, 'GET') + assert(typeof event.referrer === 'string', 'referrer should be string') + assert(!!event.headers, 'headers should be present') + assert(typeof event.headers === 'object', 'headers should be object') + assert.equal(event.resourceType, expectedType, 'Incorrect resourceType') + if (responses === Object.keys(expectedResources).length) { + done() + } + }) + webview.src = 'file://' + path.join(fixtures, 'pages', 'did-get-response-details.html') + document.body.appendChild(webview) + }) + }) }) diff --git a/vendor/brightray b/vendor/brightray index 242feb1c8175..7b037805e0db 160000 --- a/vendor/brightray +++ b/vendor/brightray @@ -1 +1 @@ -Subproject commit 242feb1c817565de6592e9e672c136635bfff453 +Subproject commit 7b037805e0dbb5976bdca5808f0ef4c937db1f6e