diff --git a/.gitignore b/.gitignore index 93753bed576..9043489a81c 100644 --- a/.gitignore +++ b/.gitignore @@ -1,11 +1,33 @@ .DS_Store +.env +.npmrc .tags* +.vs/ +.vscode/ +*.log +*.pyc +*.sln +*.swp +*.VC.db +*.VC.VC.opendb +*.vcxproj +*.vcxproj.filters +*.vcxproj.user +*.xcodeproj /.idea/ +/brightray/brightray.opensdf +/brightray/brightray.sdf +/brightray/brightray.sln +/brightray/brightray.suo +/brightray/brightray.v12.suo +/brightray/brightray.vcxproj* +/brightray/brightray.xcodeproj/ /build/ /dist/ /external_binaries/ +/node_modules /out/ -/vendor/download/ +/vendor/.gclient /vendor/debian_jessie_amd64-sysroot/ /vendor/debian_jessie_arm-sysroot/ /vendor/debian_jessie_arm64-sysroot/ @@ -13,9 +35,7 @@ /vendor/debian_wheezy_amd64-sysroot/ /vendor/debian_wheezy_arm-sysroot/ /vendor/debian_wheezy_i386-sysroot/ -/vendor/python_26/ -/vendor/npm/ -/vendor/llvm/ +/vendor/download/ /vendor/llvm-build/ /vendor/.gclient node_modules/ @@ -39,3 +59,7 @@ node_modules/ /brightray/brightray.v12.suo /brightray/brightray.xcodeproj/ .env +/vendor/llvm/ +/vendor/node/deps/node-inspect/.npmrc +/vendor/npm/ +/vendor/python_26/ diff --git a/appveyor.yml b/appveyor.yml index b093d2a2126..ce0baaf989b 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -20,6 +20,6 @@ branches: only: - master -# disable build and test pahses +# disable build and test phases build: off test: off diff --git a/atom/app/atom_main.cc b/atom/app/atom_main.cc index 9c255db5fb2..76a62399d6e 100644 --- a/atom/app/atom_main.cc +++ b/atom/app/atom_main.cc @@ -34,7 +34,7 @@ namespace { -const char* kRunAsNode = "ELECTRON_RUN_AS_NODE"; +const auto kRunAsNode = "ELECTRON_RUN_AS_NODE"; bool IsEnvSet(const char* name) { #if defined(OS_WIN) @@ -56,6 +56,30 @@ int APIENTRY wWinMain(HINSTANCE instance, HINSTANCE, wchar_t* cmd, int) { bool run_as_node = IsEnvSet(kRunAsNode); +#ifdef _DEBUG + // Don't display assert dialog boxes in CI test runs + static const auto kCI = "ELECTRON_CI"; + bool is_ci = IsEnvSet(kCI); + if (!is_ci) { + for (int i = 0; i < argc; ++i) { + if (!_wcsicmp(wargv[i], L"--ci")) { + is_ci = true; + _putenv_s(kCI, "1"); // set flag for child processes + break; + } + } + } + if (is_ci) { + _CrtSetReportMode(_CRT_ERROR, _CRTDBG_MODE_DEBUG | _CRTDBG_MODE_FILE); + _CrtSetReportFile(_CRT_ERROR, _CRTDBG_FILE_STDERR); + + _CrtSetReportMode(_CRT_ASSERT, _CRTDBG_MODE_DEBUG | _CRTDBG_MODE_FILE); + _CrtSetReportFile(_CRT_ASSERT, _CRTDBG_FILE_STDERR); + + _set_error_mode(_OUT_TO_STDERR); + } +#endif + // Make sure the output is printed to console. if (run_as_node || !IsEnvSet("ELECTRON_NO_ATTACH_CONSOLE")) base::RouteStdioToConsole(false); diff --git a/atom/app/atom_main_delegate.cc b/atom/app/atom_main_delegate.cc index 0507d5dafa5..fdf76f3cb29 100644 --- a/atom/app/atom_main_delegate.cc +++ b/atom/app/atom_main_delegate.cc @@ -154,7 +154,9 @@ content::ContentBrowserClient* AtomMainDelegate::CreateContentBrowserClient() { content::ContentRendererClient* AtomMainDelegate::CreateContentRendererClient() { if (base::CommandLine::ForCurrentProcess()->HasSwitch( - switches::kEnableSandbox)) { + switches::kEnableSandbox) || + !base::CommandLine::ForCurrentProcess()->HasSwitch( + ::switches::kNoSandbox)) { renderer_client_.reset(new AtomSandboxedRendererClient); } else { renderer_client_.reset(new AtomRendererClient); diff --git a/atom/browser/api/atom_api_app.cc b/atom/browser/api/atom_api_app.cc index b223f9e3f82..06d4dd8aaf5 100644 --- a/atom/browser/api/atom_api_app.cc +++ b/atom/browser/api/atom_api_app.cc @@ -35,6 +35,7 @@ #include "chrome/browser/icon_manager.h" #include "chrome/common/chrome_paths.h" #include "content/browser/gpu/compositor_util.h" +#include "content/browser/gpu/gpu_data_manager_impl.h" #include "content/public/browser/browser_accessibility_state.h" #include "content/public/browser/browser_child_process_host.h" #include "content/public/browser/child_process_data.h" @@ -852,6 +853,17 @@ void App::DisableHardwareAcceleration(mate::Arguments* args) { content::GpuDataManager::GetInstance()->DisableHardwareAcceleration(); } +void App::DisableDomainBlockingFor3DAPIs(mate::Arguments* args) { + if (Browser::Get()->is_ready()) { + args->ThrowError( + "app.disableDomainBlockingFor3DAPIs() can only be called " + "before app is ready"); + return; + } + content::GpuDataManagerImpl::GetInstance() + ->DisableDomainBlockingFor3DAPIsForTesting(); +} + bool App::IsAccessibilitySupportEnabled() { auto ax_state = content::BrowserAccessibilityState::GetInstance(); return ax_state->IsAccessibleBrowser(); @@ -1131,6 +1143,8 @@ void App::BuildPrototype( &App::IsAccessibilitySupportEnabled) .SetMethod("disableHardwareAcceleration", &App::DisableHardwareAcceleration) + .SetMethod("disableDomainBlockingFor3DAPIs", + &App::DisableDomainBlockingFor3DAPIs) .SetMethod("getFileIcon", &App::GetFileIcon) .SetMethod("getAppMetrics", &App::GetAppMetrics) .SetMethod("getGPUFeatureStatus", &App::GetGPUFeatureStatus) diff --git a/atom/browser/api/atom_api_app.h b/atom/browser/api/atom_api_app.h index a6c4ef0bebd..694a3e30473 100644 --- a/atom/browser/api/atom_api_app.h +++ b/atom/browser/api/atom_api_app.h @@ -169,6 +169,7 @@ class App : public AtomBrowserClient::Delegate, void ReleaseSingleInstance(); bool Relaunch(mate::Arguments* args); void DisableHardwareAcceleration(mate::Arguments* args); + void DisableDomainBlockingFor3DAPIs(mate::Arguments* args); bool IsAccessibilitySupportEnabled(); Browser::LoginItemSettings GetLoginItemSettings(mate::Arguments* args); #if defined(USE_NSS_CERTS) diff --git a/atom/browser/api/atom_api_web_contents.cc b/atom/browser/api/atom_api_web_contents.cc index f27c37ab891..a23d2817b87 100644 --- a/atom/browser/api/atom_api_web_contents.cc +++ b/atom/browser/api/atom_api_web_contents.cc @@ -993,6 +993,10 @@ void WebContents::LoadURL(const GURL& url, const mate::Dictionary& options) { return; } + if (guest_delegate_ && !guest_delegate_->IsAttached()) { + return; + } + content::NavigationController::LoadURLParams params(url); GURL http_referrer; diff --git a/atom/browser/api/atom_api_window.cc b/atom/browser/api/atom_api_window.cc index f48026ea937..34366e2db5d 100644 --- a/atom/browser/api/atom_api_window.cc +++ b/atom/browser/api/atom_api_window.cc @@ -10,6 +10,7 @@ #include "atom/browser/api/atom_api_web_contents.h" #include "atom/browser/browser.h" #include "atom/browser/native_window.h" +#include "atom/browser/web_contents_preferences.h" #include "atom/common/native_mate_converters/callback.h" #include "atom/common/native_mate_converters/file_path_converter.h" #include "atom/common/native_mate_converters/gfx_converter.h" @@ -77,30 +78,43 @@ v8::Local ToBuffer(v8::Isolate* isolate, void* val, int size) { Window::Window(v8::Isolate* isolate, v8::Local wrapper, const mate::Dictionary& options) { mate::Handle web_contents; - // If no WebContents was passed to the constructor, create it from options. - if (!options.Get("webContents", &web_contents)) { - // Use options.webPreferences to create WebContents. - mate::Dictionary web_preferences = mate::Dictionary::CreateEmpty(isolate); - options.Get(options::kWebPreferences, &web_preferences); - // Copy the backgroundColor to webContents. - v8::Local value; - if (options.Get(options::kBackgroundColor, &value)) - web_preferences.Set(options::kBackgroundColor, value); + // Use options.webPreferences in WebContents. + mate::Dictionary web_preferences = mate::Dictionary::CreateEmpty(isolate); + options.Get(options::kWebPreferences, &web_preferences); - v8::Local transparent; - if (options.Get("transparent", &transparent)) - web_preferences.Set("transparent", transparent); + // Copy the backgroundColor to webContents. + v8::Local value; + if (options.Get(options::kBackgroundColor, &value)) + web_preferences.Set(options::kBackgroundColor, value); + + v8::Local transparent; + if (options.Get("transparent", &transparent)) + web_preferences.Set("transparent", transparent); #if defined(ENABLE_OSR) - // Offscreen windows are always created frameless. - bool offscreen; - if (web_preferences.Get("offscreen", &offscreen) && offscreen) { - auto window_options = const_cast(options); - window_options.Set(options::kFrame, false); - } + // Offscreen windows are always created frameless. + bool offscreen; + if (web_preferences.Get("offscreen", &offscreen) && offscreen) { + auto window_options = const_cast(options); + window_options.Set(options::kFrame, false); + } #endif + if (options.Get("webContents", &web_contents)) { + // Set webPreferences from options if using an existing webContents. + // These preferences will be used when the webContent launches new + // render processes. + auto* existing_preferences = + WebContentsPreferences::FromWebContents(web_contents->web_contents()); + base::DictionaryValue web_preferences_dict; + if (mate::ConvertFromV8(isolate, web_preferences.GetHandle(), + &web_preferences_dict)) { + existing_preferences->web_preferences()->Clear(); + existing_preferences->Merge(web_preferences_dict); + } + + } else { // Creates the WebContents used by BrowserWindow. web_contents = WebContents::Create(isolate, web_preferences); } diff --git a/atom/browser/atom_browser_client.cc b/atom/browser/atom_browser_client.cc index 065909dc40f..61c97f2c35c 100644 --- a/atom/browser/atom_browser_client.cc +++ b/atom/browser/atom_browser_client.cc @@ -38,6 +38,7 @@ #include "content/public/browser/resource_dispatcher_host.h" #include "content/public/browser/site_instance.h" #include "content/public/browser/web_contents.h" +#include "content/public/common/content_switches.h" #include "content/public/common/url_constants.h" #include "content/public/common/web_preferences.h" #include "net/ssl/ssl_cert_request_info.h" @@ -78,9 +79,10 @@ AtomBrowserClient::~AtomBrowserClient() { content::WebContents* AtomBrowserClient::GetWebContentsFromProcessID( int process_id) { - // If the process is a pending process, we should use the old one. + // If the process is a pending process, we should use the web contents + // for the frame host passed into OverrideSiteInstanceForNavigation. if (base::ContainsKey(pending_processes_, process_id)) - process_id = pending_processes_[process_id]; + return pending_processes_[process_id]; // Certain render process will be created with no associated render view, // for example: ServiceWorker. @@ -230,19 +232,20 @@ void AtomBrowserClient::OverrideSiteInstanceForNavigation( content::BrowserThread::UI, FROM_HERE, base::Bind(&Noop, base::RetainedRef(site_instance))); - // Remember the original renderer process of the pending renderer process. - auto current_process = current_instance->GetProcess(); + // Remember the original web contents for the pending renderer process. auto pending_process = (*new_instance)->GetProcess(); - pending_processes_[pending_process->GetID()] = current_process->GetID(); + pending_processes_[pending_process->GetID()] = + content::WebContents::FromRenderFrameHost(render_frame_host);; // Clear the entry in map when process ends. - current_process->AddObserver(this); + pending_process->AddObserver(this); } void AtomBrowserClient::AppendExtraCommandLineSwitches( base::CommandLine* command_line, int process_id) { - std::string process_type = command_line->GetSwitchValueASCII("type"); - if (process_type != "renderer") + std::string process_type = + command_line->GetSwitchValueASCII(::switches::kProcessType); + if (process_type != ::switches::kRendererProcess) return; // Copy following switches to child process. @@ -275,11 +278,9 @@ void AtomBrowserClient::AppendExtraCommandLineSwitches( } content::WebContents* web_contents = GetWebContentsFromProcessID(process_id); - if (!web_contents) - return; - - WebContentsPreferences::AppendExtraCommandLineSwitches( - web_contents, command_line); + if (web_contents) + WebContentsPreferences::AppendExtraCommandLineSwitches( + web_contents, command_line); } void AtomBrowserClient::DidCreatePpapiPlugin( @@ -419,12 +420,7 @@ void AtomBrowserClient::WebNotificationAllowed( void AtomBrowserClient::RenderProcessHostDestroyed( content::RenderProcessHost* host) { int process_id = host->GetID(); - for (const auto& entry : pending_processes_) { - if (entry.first == process_id || entry.second == process_id) { - pending_processes_.erase(entry.first); - break; - } - } + pending_processes_.erase(process_id); RemoveProcessPreferences(process_id); } diff --git a/atom/browser/atom_browser_client.h b/atom/browser/atom_browser_client.h index d48865504f6..e4b7eae5d85 100644 --- a/atom/browser/atom_browser_client.h +++ b/atom/browser/atom_browser_client.h @@ -130,8 +130,8 @@ class AtomBrowserClient : public brightray::BrowserClient, bool RendererUsesNativeWindowOpen(int process_id); bool RendererDisablesPopups(int process_id); - // pending_render_process => current_render_process. - std::map pending_processes_; + // pending_render_process => web contents. + std::map pending_processes_; std::map process_preferences_; std::map render_process_host_pids_; diff --git a/atom/browser/atom_resource_dispatcher_host_delegate.cc b/atom/browser/atom_resource_dispatcher_host_delegate.cc index 12038ff1bf5..53d91b4be95 100644 --- a/atom/browser/atom_resource_dispatcher_host_delegate.cc +++ b/atom/browser/atom_resource_dispatcher_host_delegate.cc @@ -87,8 +87,11 @@ void OnPdfResourceIntercepted( // by the webui page. // chrome://pdf-viewer/index.html?src=https://somepage/123.pdf content::NavigationController::LoadURLParams params( - GURL(base::StringPrintf("%sindex.html?%s=%s", kPdfViewerUIOrigin, - kPdfPluginSrc, original_url.spec().c_str()))); + GURL(base::StringPrintf( + "%sindex.html?%s=%s", + kPdfViewerUIOrigin, + kPdfPluginSrc, + net::EscapeUrlEncodedData(original_url.spec(), false).c_str()))); web_contents->GetController().LoadURLWithParams(params); } diff --git a/atom/browser/atom_web_ui_controller_factory.cc b/atom/browser/atom_web_ui_controller_factory.cc index ef8b2785ae5..d113e656084 100644 --- a/atom/browser/atom_web_ui_controller_factory.cc +++ b/atom/browser/atom_web_ui_controller_factory.cc @@ -11,6 +11,7 @@ #include "base/strings/string_split.h" #include "base/strings/string_util.h" #include "content/public/browser/web_contents.h" +#include "net/base/escape.h" namespace atom { @@ -52,9 +53,15 @@ AtomWebUIControllerFactory::CreateWebUIControllerForURL(content::WebUI* web_ui, base::StringPairs toplevel_params; base::SplitStringIntoKeyValuePairs(url.query(), '=', '&', &toplevel_params); std::string stream_id, src; + + const net::UnescapeRule::Type unescape_rules = + net::UnescapeRule::SPACES | net::UnescapeRule::PATH_SEPARATORS | + net::UnescapeRule::URL_SPECIAL_CHARS_EXCEPT_PATH_SEPARATORS | + net::UnescapeRule::REPLACE_PLUS_WITH_SPACE; + for (const auto& param : toplevel_params) { if (param.first == kPdfPluginSrc) { - src = param.second; + src = net::UnescapeURLComponent(param.second, unescape_rules); } } if (url.has_ref()) { diff --git a/atom/browser/native_window_mac.h b/atom/browser/native_window_mac.h index e3c5525b849..3dfb88d5398 100644 --- a/atom/browser/native_window_mac.h +++ b/atom/browser/native_window_mac.h @@ -133,6 +133,8 @@ class NativeWindowMac : public NativeWindow, bool zoom_to_page_width() const { return zoom_to_page_width_; } + bool fullscreen_window_title() const { return fullscreen_window_title_; } + protected: // Return a vector of non-draggable regions that fill a window of size // |width| by |height|, but leave gaps where the window should be draggable. @@ -177,6 +179,8 @@ class NativeWindowMac : public NativeWindow, bool zoom_to_page_width_; + bool fullscreen_window_title_; + NSInteger attention_request_id_; // identifier from requestUserAttention // The presentation options before entering kiosk mode. diff --git a/atom/browser/native_window_mac.mm b/atom/browser/native_window_mac.mm index 8e28553d71c..2719c672954 100644 --- a/atom/browser/native_window_mac.mm +++ b/atom/browser/native_window_mac.mm @@ -172,6 +172,7 @@ bool ScopedDisableResize::disable_resize_ = false; @private atom::NativeWindowMac* shell_; bool is_zooming_; + int level_; } - (id)initWithShell:(atom::NativeWindowMac*)shell; @end @@ -182,6 +183,7 @@ bool ScopedDisableResize::disable_resize_ = false; if ((self = [super init])) { shell_ = shell; is_zooming_ = false; + level_ = [shell_->GetNativeWindow() level]; } return self; } @@ -301,11 +303,19 @@ bool ScopedDisableResize::disable_resize_ = false; shell_->NotifyWindowMoved(); } +- (void)windowWillMiniaturize:(NSNotification*)notification { + NSWindow* window = shell_->GetNativeWindow(); + // store the current status window level to be restored in windowDidDeminiaturize + level_ = [window level]; + [window setLevel:NSNormalWindowLevel]; +} + - (void)windowDidMiniaturize:(NSNotification*)notification { shell_->NotifyWindowMinimize(); } - (void)windowDidDeminiaturize:(NSNotification*)notification { + [shell_->GetNativeWindow() setLevel:level_]; shell_->NotifyWindowRestore(); } @@ -345,7 +355,9 @@ bool ScopedDisableResize::disable_resize_ = false; base::mac::IsAtLeastOS10_10() && // FIXME(zcbenz): Showing titlebar for hiddenInset window is weird under // fullscreen mode. - shell_->title_bar_style() != atom::NativeWindowMac::HIDDEN_INSET) { + // Show title if fullscreen_window_title flag is set + (shell_->title_bar_style() != atom::NativeWindowMac::HIDDEN_INSET || + shell_->fullscreen_window_title())) { [window setTitleVisibility:NSWindowTitleVisible]; } @@ -369,7 +381,8 @@ bool ScopedDisableResize::disable_resize_ = false; NSWindow* window = shell_->GetNativeWindow(); if ((shell_->transparent() || !shell_->has_frame()) && base::mac::IsAtLeastOS10_10() && - shell_->title_bar_style() != atom::NativeWindowMac::HIDDEN_INSET) { + (shell_->title_bar_style() != atom::NativeWindowMac::HIDDEN_INSET || + shell_->fullscreen_window_title())) { [window setTitleVisibility:NSWindowTitleHidden]; } @@ -804,6 +817,7 @@ NativeWindowMac::NativeWindowMac( is_kiosk_(false), was_fullscreen_(false), zoom_to_page_width_(false), + fullscreen_window_title_(false), attention_request_id_(0), title_bar_style_(NORMAL) { int width = 800, height = 600; @@ -949,6 +963,8 @@ NativeWindowMac::NativeWindowMac( options.Get(options::kZoomToPageWidth, &zoom_to_page_width_); + options.Get(options::kFullscreenWindowTitle, &fullscreen_window_title_); + // Enable the NSView to accept first mouse event. bool acceptsFirstMouse = false; options.Get(options::kAcceptFirstMouse, &acceptsFirstMouse); diff --git a/atom/browser/native_window_views.cc b/atom/browser/native_window_views.cc index bf2ab84a9f7..94e2f09c964 100644 --- a/atom/browser/native_window_views.cc +++ b/atom/browser/native_window_views.cc @@ -374,7 +374,8 @@ bool NativeWindowViews::IsFocused() { } void NativeWindowViews::Show() { - if (is_modal() && NativeWindow::parent()) + if (is_modal() && NativeWindow::parent() && + !window_->native_widget_private()->IsVisible()) static_cast(NativeWindow::parent())->SetEnabled(false); window_->native_widget_private()->ShowWithWindowState(GetRestoredState()); diff --git a/atom/browser/resources/mac/Info.plist b/atom/browser/resources/mac/Info.plist index c02639ad0a0..843f87fc3fe 100644 --- a/atom/browser/resources/mac/Info.plist +++ b/atom/browser/resources/mac/Info.plist @@ -17,9 +17,9 @@ CFBundleIconFile electron.icns CFBundleVersion - 1.7.4 + 1.7.5 CFBundleShortVersionString - 1.7.4 + 1.7.5 LSApplicationCategoryType public.app-category.developer-tools LSMinimumSystemVersion diff --git a/atom/browser/resources/win/atom.rc b/atom/browser/resources/win/atom.rc index f5c02b0ab01..6436b4ae0cc 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 1,7,4,0 - PRODUCTVERSION 1,7,4,0 + FILEVERSION 1,7,5,0 + PRODUCTVERSION 1,7,5,0 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -74,12 +74,12 @@ BEGIN BEGIN VALUE "CompanyName", "GitHub, Inc." VALUE "FileDescription", "Electron" - VALUE "FileVersion", "1.7.4" + VALUE "FileVersion", "1.7.5" VALUE "InternalName", "electron.exe" VALUE "LegalCopyright", "Copyright (C) 2015 GitHub, Inc. All rights reserved." VALUE "OriginalFilename", "electron.exe" VALUE "ProductName", "Electron" - VALUE "ProductVersion", "1.7.4" + VALUE "ProductVersion", "1.7.5" VALUE "SquirrelAwareVersion", "1" END END diff --git a/atom/browser/ui/file_dialog.h b/atom/browser/ui/file_dialog.h index 6f33c46f202..79353d03a5d 100644 --- a/atom/browser/ui/file_dialog.h +++ b/atom/browser/ui/file_dialog.h @@ -30,6 +30,7 @@ enum FileDialogProperty { FILE_DIALOG_SHOW_HIDDEN_FILES = 1 << 4, FILE_DIALOG_PROMPT_TO_CREATE = 1 << 5, FILE_DIALOG_NO_RESOLVE_ALIASES = 1 << 6, + FILE_DIALOG_TREAT_PACKAGE_APP_AS_DIRECTORY = 1 << 7, }; typedef base::Callback extensions; + int valid_type_count = 0; + std::string description; + for (const auto& accept_type : accept_types) { std::string ascii_type = base::UTF16ToASCII(accept_type); + auto old_extension_size = extensions.size(); + if (ascii_type[0] == '.') { // If the type starts with a period it is assumed to be a file extension, // like `.txt`, // so we just have to add it to the list. @@ -130,9 +135,19 @@ file_dialog::Filters GetFileTypesFromAcceptType( // Skip the first character. extensions.push_back(extension.substr(1)); } else { - // For MIME Type, `audio/*, vidio/*, image/* + if (ascii_type == "image/*") + description = "Image Files"; + else if (ascii_type == "audio/*") + description = "Audio Files"; + else if (ascii_type == "video/*") + description = "Video Files"; + + // For MIME Type, `audio/*, video/*, image/* net::GetExtensionsForMimeType(ascii_type, &extensions); } + + if (extensions.size() > old_extension_size) + valid_type_count++; } // If no valid exntesion is added, return empty filters. @@ -140,6 +155,13 @@ file_dialog::Filters GetFileTypesFromAcceptType( return filters; filters.push_back(file_dialog::Filter()); + + if (valid_type_count > 1 || + (valid_type_count == 1 && description.empty() && extensions.size() > 1)) + description = "Custom Files"; + + filters[0].first = description; + for (const auto& extension : extensions) { #if defined(OS_WIN) filters[0].second.push_back(base::UTF16ToASCII(extension)); @@ -147,6 +169,12 @@ file_dialog::Filters GetFileTypesFromAcceptType( filters[0].second.push_back(extension); #endif } + + // Allow all files when extension is specified. + filters.push_back(file_dialog::Filter()); + filters.back().first = "All Files"; + filters.back().second.push_back("*"); + return filters; } diff --git a/atom/browser/web_view_guest_delegate.cc b/atom/browser/web_view_guest_delegate.cc index 2d16504c59f..1fc79a6a342 100644 --- a/atom/browser/web_view_guest_delegate.cc +++ b/atom/browser/web_view_guest_delegate.cc @@ -28,6 +28,7 @@ WebViewGuestDelegate::WebViewGuestDelegate() guest_host_(nullptr), auto_size_enabled_(false), is_full_page_plugin_(false), + attached_(false), api_web_contents_(nullptr) {} WebViewGuestDelegate::~WebViewGuestDelegate() { @@ -110,7 +111,12 @@ void WebViewGuestDelegate::DidFinishNavigation( } } +void WebViewGuestDelegate::DidDetach() { + attached_ = false; +} + void WebViewGuestDelegate::DidAttach(int guest_proxy_routing_id) { + attached_ = true; api_web_contents_->Emit("did-attach"); embedder_zoom_controller_ = WebContentsZoomController::FromWebContents(embedder_web_contents_); diff --git a/atom/browser/web_view_guest_delegate.h b/atom/browser/web_view_guest_delegate.h index 0d97d809506..2e2941b5a35 100644 --- a/atom/browser/web_view_guest_delegate.h +++ b/atom/browser/web_view_guest_delegate.h @@ -47,6 +47,9 @@ class WebViewGuestDelegate : public content::BrowserPluginGuestDelegate, // and normal sizes. void SetSize(const SetSizeParams& params); + // Return true if attached. + bool IsAttached() const { return attached_; } + protected: // content::WebContentsObserver: void DidFinishNavigation( @@ -54,6 +57,7 @@ class WebViewGuestDelegate : public content::BrowserPluginGuestDelegate, // content::BrowserPluginGuestDelegate: void DidAttach(int guest_proxy_routing_id) final; + void DidDetach() final; content::WebContents* GetOwnerWebContents() const final; void GuestSizeChanged(const gfx::Size& new_size) final; void SetGuestHost(content::GuestHost* guest_host) final; @@ -116,6 +120,9 @@ class WebViewGuestDelegate : public content::BrowserPluginGuestDelegate, // Whether the guest view is inside a plugin document. bool is_full_page_plugin_; + // Whether attached. + bool attached_; + api::WebContents* api_web_contents_; DISALLOW_COPY_AND_ASSIGN(WebViewGuestDelegate); diff --git a/atom/common/atom_version.h b/atom/common/atom_version.h index 20fd4dd6a02..1c4692059f4 100644 --- a/atom/common/atom_version.h +++ b/atom/common/atom_version.h @@ -7,7 +7,7 @@ #define ATOM_MAJOR_VERSION 1 #define ATOM_MINOR_VERSION 7 -#define ATOM_PATCH_VERSION 4 +#define ATOM_PATCH_VERSION 5 #define ATOM_VERSION_IS_RELEASE 1 diff --git a/atom/common/options_switches.cc b/atom/common/options_switches.cc index f63c1d95d0b..8822c55f9a4 100644 --- a/atom/common/options_switches.cc +++ b/atom/common/options_switches.cc @@ -48,6 +48,9 @@ const char kUseContentSize[] = "useContentSize"; // Whether window zoom should be to page width. const char kZoomToPageWidth[] = "zoomToPageWidth"; +// Whether always show title text in full screen is enabled. +const char kFullscreenWindowTitle[] = "fullscreenWindowTitle"; + // The requested title bar style for the window const char kTitleBarStyle[] = "titleBarStyle"; diff --git a/atom/common/options_switches.h b/atom/common/options_switches.h index 171583ec2a8..171e6b5a79f 100644 --- a/atom/common/options_switches.h +++ b/atom/common/options_switches.h @@ -35,6 +35,7 @@ extern const char kAlwaysOnTop[]; extern const char kAcceptFirstMouse[]; extern const char kUseContentSize[]; extern const char kZoomToPageWidth[]; +extern const char kFullscreenWindowTitle[]; extern const char kTitleBarStyle[]; extern const char kTabbingIdentifier[]; extern const char kAutoHideMenuBar[]; diff --git a/atom/renderer/atom_sandboxed_renderer_client.cc b/atom/renderer/atom_sandboxed_renderer_client.cc index aa4780fa15b..223cc4792e1 100644 --- a/atom/renderer/atom_sandboxed_renderer_client.cc +++ b/atom/renderer/atom_sandboxed_renderer_client.cc @@ -216,7 +216,7 @@ void AtomSandboxedRendererClient::InvokeIpcCallback( auto callback_value = binding->Get(callback_key); DCHECK(callback_value->IsFunction()); // set by sandboxed_renderer/init.js auto callback = v8::Handle::Cast(callback_value); - ignore_result(callback->Call(context, binding, args.size(), &args[0])); + ignore_result(callback->Call(context, binding, args.size(), args.data())); } } // namespace atom diff --git a/brightray/brightray.gypi b/brightray/brightray.gypi index c0dc92b98c1..83406e4c8e0 100644 --- a/brightray/brightray.gypi +++ b/brightray/brightray.gypi @@ -92,8 +92,6 @@ 'Common_Base': { 'abstract': 1, 'defines': [ - # We are using Release version libchromiumcontent: - 'NDEBUG', # Needed by gin: 'V8_USE_EXTERNAL_STARTUP_DATA', # From skia_for_chromium_defines.gypi: @@ -189,6 +187,7 @@ # Use this instead of "NDEBUG" to determine whether we are in # Debug build, because "NDEBUG" is already used by Chromium. 'DEBUG', + '_DEBUG', # Require when using libchromiumcontent. 'COMPONENT_BUILD', 'GURL_DLL', @@ -198,15 +197,32 @@ ], 'msvs_settings': { 'VCCLCompilerTool': { - 'RuntimeLibrary': '2', # /MD (nondebug DLL) + 'RuntimeLibrary': '3', # /MDd (debug DLL) 'Optimization': '0', # 0 = /Od # See http://msdn.microsoft.com/en-us/library/8wtf2dfz(VS.71).aspx 'BasicRuntimeChecks': '3', # 3 = all checks enabled, 0 = off }, + 'VCLinkerTool': { + 'OptimizeReferences': 2, # /OPT:REF + 'EnableCOMDATFolding': 2, # /OPT:ICF + }, }, + 'conditions': [ + ['OS=="linux"', { + 'defines': [ + '_GLIBCXX_DEBUG', + ], + 'cflags': [ + '-g', + ], + }], # OS=="linux" + ], }, # Debug_Base 'Release_Base': { 'abstract': 1, + 'defines': [ + 'NDEBUG', + ], 'msvs_settings': { 'VCCLCompilerTool': { 'RuntimeLibrary': '2', # /MD (nondebug DLL) diff --git a/docs-translations/fr-FR/tutorial/electron-versioning.md b/docs-translations/fr-FR/tutorial/electron-versioning.md index 1c30cffaa4c..bec3f01b8e0 100644 --- a/docs-translations/fr-FR/tutorial/electron-versioning.md +++ b/docs-translations/fr-FR/tutorial/electron-versioning.md @@ -1,14 +1,14 @@ # Versionage d'Electron -Si vous êtes un développeur Node expérimenté, vous êtes sûrement au courant de `semver` - et pourrez l'utiliser pour donner à vos systèmes de gestion de dépendences seulement des lignes directrices générales plutôt que des numéros de version fixes. En raison d'une forte dépendence avec Node et +Si vous êtes un développeur Node expérimenté, vous êtes sûrement au courant de `semver` - et pourrez l'utiliser pour donner à vos systèmes de gestion de dépendances seulement des lignes directrices générales plutôt que des numéros de version fixes. En raison d'une forte dépendence avec Node et Chromium, Electron est dans une position quelque peu difficile et ne suit pas semver. Vous devez donc toujours faire référence à une version spécifique d'Electron. -Les numéros de version sont mis à jour selon les règle suivantes: +Les numéros de version sont mis à jour selon les règles suivantes: * Majeur: Pour les gros changements entrainant des ruptures dans l'API d'Electron - Si vous passez de la version `0.37.0` à `1.0.0`, vous devrez effectuer une migration de votre application. -* Mineur: Pour des changements majeurs de Chrome et des changements mineur de Node; ou des changements important d'Electron - si vous mettez à jour de `1.0.0` vers `1.1.0`, le plus gros de votre application fonctionnera, seul de petits changements seront à effectuer. +* Mineur: Pour des changements majeurs de Chrome et des changements mineurs de Node; ou des changements importants d'Electron - si vous mettez à jour de `1.0.0` vers `1.1.0`, le plus gros de votre application fonctionnera, seuls de petits changements seront à effectuer. * Patch: Pour de nouvelles fonctionalités et des résolutions de bugs - si vous passez de la version `1.0.0` à `1.0.1`, votre application continuera de s'exécuter telle quelle. -Si vous utilisez `electron` ou `electron-prebuilt`, nous vous recommandons de fixer le numéro de version (`1.1.0` instead of `^1.1.0`) pour être sûr que toutes les mises à jour d'Electron sont une opération manuelle faite par vous, le développeur. +Si vous utilisez `electron` ou `electron-prebuilt`, nous vous recommandons de fixer le numéro de version (`1.1.0` au lieu de `^1.1.0`) pour être sûr que toutes les mises à jour d'Electron sont une opération manuelle faite par vous, le développeur. diff --git a/docs-translations/fr-FR/tutorial/quick-start.md b/docs-translations/fr-FR/tutorial/quick-start.md index 33fdc5e6fdc..4a59dbde729 100644 --- a/docs-translations/fr-FR/tutorial/quick-start.md +++ b/docs-translations/fr-FR/tutorial/quick-start.md @@ -21,7 +21,7 @@ pages Web. Puisque Electron utilise Chromium pour afficher des pages Web, Chromium Multi-process architecture est également utilisé. Chaque page Web d'Electron -fonctionne avec son propre processus, qui est appelé __le processus de rendu.__. +fonctionne avec son propre processus, qui est appelé __le processus de rendu__. Dans les navigateurs normaux, les pages Web sont habituellement exécutées dans un environnement aux ressources indépendantes. Les utilisateurs d'électrons @@ -33,17 +33,17 @@ un système d'exploitation de niveau inférieur d'interactions. Le processus principal crée des pages Web en créant des instances `BrowserWindow`. Chaque instance `BrowserWindow` exécute la page Web dans son propre processus de rendu. Lorsqu'une occurrence `BrowserWindow` est détruite, le processus -de rendu correspondant est également terminée. +de rendu correspondant est également terminé. Le processus principal gère toutes les pages Web et leur processus rendu correspondant. Chaque processus de rendu est isolé et ne se soucie que de la page Web en cours d'exécution. Dans les pages Web, l'appel des API relatives aux GUI natives n'est pas autorisé -car la gestion des ressources natives GUI dans les pages Web sont très dangereuse, +car la gestion des ressources natives GUI dans les pages Web est très dangereuse, il est facile de perdre des ressources. Si vous souhaitez effectuer des opérations GUI dans une page Web, le Processus de la page Web doit communiquer avec le -processus principal pour lui demander d'effectur ces opérations. +processus principal pour lui demander d'effectuer ces opérations. Dans Electron, nous avons plusieurs façons de communiquer entre le processus principal et le processeurs. Comme [`ipcRenderer`] (../ api / ipc-renderer.md) et [`IpcMain`] @@ -106,7 +106,7 @@ function createWindow () { // Émis lorsque la fenêtre est fermée. win.on('closed', () => { - // Déréférencer l'objet fenêtre, habituellement vous stocker des fenêtres + // Déréférencer l'objet fenêtre, habituellement vous stockez des fenêtres // dans un tableau si votre application prend en charge plusieurs fenêtres, // c'est l'heure où vous devez supprimer l'élément correspondant. win = null diff --git a/docs-translations/fr-FR/tutorial/security.md b/docs-translations/fr-FR/tutorial/security.md index d398a07436c..e879aab716d 100644 --- a/docs-translations/fr-FR/tutorial/security.md +++ b/docs-translations/fr-FR/tutorial/security.md @@ -1,26 +1,26 @@ # Securité, Application Natives, et Votre Responsabilité En tant que développeurs Web, nous avons l'habitude de bénéficier d'une sécurité élevée au niveau du navigateur - les -risques associés au code que nous écrivons sont relativement faibles. Nos sites internet ont des droit limités au sein +risques associés au code que nous écrivons sont relativement faibles. Nos sites internet ont des droits limités au sein d'une sandbox, et nous faisons confiance à nos utilisateurs pour utiliser des navigateurs créés par de grosses équipes d'ingénieurs capables de réagir rapidement lorsqu'une faille de sécurité est découverte. Quand on travaille avec Electron, il est important de comprendre qu'Electron n'est pas un navigateur web. -Il vous permet de construire des applications de bureau riches de fonctionnalités au travers de technologies web familaires, -mais votre code a beaucoup plus de possibilités. Javascript peut accéder au système de fichier, au shell, et plus. +Il vous permet de construire des applications de bureau riches de fonctionnalités au travers de technologies web familières, +mais votre code a beaucoup plus de possibilités. Javascript peut accéder au système de fichiers, au shell, et plus. Cela vous permet de construire des applications natives de haute qualité, mais les problèmes de sécurité sont inhérents à toutes ces possibilités. Avec ça en tête, soyez conscient qu'afficher du contenu arbitraire depuis des sources extérieures pose un gros risque au niveau de la sécurité qu'Electron ne peut gérer. -En fait, les applications utilisant Electron les plus populaires (Atom, Slack, Visual Studio Code, ...etc) affichent principalement du contenu local (ou de confiance, il s'agit alors de contenu distant sécurisé sans intégration avec Node) - si votre application exécute du code depuis une source extérieur, il est de votre responsabilité de vous assurer que ce code n'est pas malveillant. +En fait, les applications utilisant Electron les plus populaires (Atom, Slack, Visual Studio Code, ...etc) affichent principalement du contenu local (ou de confiance, il s'agit alors de contenu distant sécurisé sans intégration avec Node) - si votre application exécute du code depuis une source extérieure, il est de votre responsabilité de vous assurer que ce code n'est pas malveillant. -## Problèmes de sécurités liés à Chromium et mises à jour +## Problèmes de sécurité liés à Chromium et mises à jour -Tandis qu'Electron essai de supporter les nouvelles versions de Chromium dès que possible, -les developpeurs doivent garder à l'esprit que le fait de mettre à jour l'application est une tâche laborieuse durant laquelle plusieurs douzaines, voir plusieurs centaines de fichiers doivent être modifiés à la main. -Selon les ressources et les contributions actuelles, Electron ne fonctionnera pas toujours avec la dernière version de Chromium, un délai de quelques jours voir quelques semaines est à prévoir. +Tandis qu'Electron essaie de supporter les nouvelles versions de Chromium dès que possible, +les developpeurs doivent garder à l'esprit que le fait de mettre à jour l'application est une tâche laborieuse durant laquelle plusieurs douzaines, voire plusieurs centaines de fichiers doivent être modifiés à la main. +Selon les ressources et les contributions actuelles, Electron ne fonctionnera pas toujours avec la dernière version de Chromium, un délai de quelques jours voire quelques semaines est à prévoir. -Nous pensons que notre système actuel de mises à jour du composant Chromium correspond à +Nous pensons que notre système actuel de mises à jour du composant Chromium correspond à un équilibre approprié entre les ressources dont nous disposons et les besoins de la majorité des applications construites autour du framework. Les Pull requests et les contributions supportant cet effort sont toujours les bienvenues. @@ -45,7 +45,7 @@ Il ne s'agit pas d'une liste exhaustive, mais au moins, pour palier aux problèm * Définir une [`Content-Security-Policy`](http://www.html5rocks.com/en/tutorials/security/content-security-policy/) , et utiliser des règles strictes (i.e. `script-src 'self'`) * [Surcharger et désactiver `eval`](https://github.com/nylas/N1/blob/0abc5d5defcdb057120d726b271933425b75b415/static/index.js#L6-L8) -, qui permet à des chaines de caractères d'être exécutées comme du code. +, qui permet à des chaînes de caractères d'être exécutées comme du code. * Ne pas assigner `allowRunningInsecureContent` à true. * Ne pas activer `experimentalFeatures` ou `experimentalCanvasFeatures` à moins d'être sûr ce que vous faites. * Ne pas utiliser `blinkFeatures` à moins d'être sûr ce que vous faites. diff --git a/docs-translations/fr-FR/tutorial/supported-platforms.md b/docs-translations/fr-FR/tutorial/supported-platforms.md index 78b666c89a7..cdf3849da6f 100644 --- a/docs-translations/fr-FR/tutorial/supported-platforms.md +++ b/docs-translations/fr-FR/tutorial/supported-platforms.md @@ -19,7 +19,7 @@ Les binaires précompilés `ia32` (`i686`) et `x64` (`amd64`) d'Electron sont co Ubuntu 12.04, le binaire `arm` est compilé à partir d'une version ARM v7 hard-float ABI et NEON pour Debian Wheezy. -Pour que les binaires pré-compilés puissent s'exécuter sur une certaine distribution, il faut que cette distribution inclut les librairies dont Electron a besoin. C'est à dire que seulement Ubuntu 12.04 est guaranti de fonctionner, même si les plateformes suivantes sont aussi verifiées et capables d'exécuter les binaires pré-compilés d'Electron: +Pour que les binaires pré-compilés puissent s'exécuter sur une certaine distribution, il faut que cette distribution inclut les librairies dont Electron a besoin. C'est à dire que seulement Ubuntu 12.04 est garanti de fonctionner, même si les plateformes suivantes sont aussi verifiées et capables d'exécuter les binaires pré-compilés d'Electron: * Ubuntu 12.04 et suivantes * Fedora 21 diff --git a/docs-translations/jp/README.md b/docs-translations/jp/README.md index 93f64c4db03..315b9b4fd91 100644 --- a/docs-translations/jp/README.md +++ b/docs-translations/jp/README.md @@ -26,6 +26,7 @@ _リンクになっていないリストは未翻訳のものです。_ * [Pepper Flashプラグインを使用する](tutorial/using-pepper-flash-plugin.md) * [Widevine CDMプラグインを使用する](tutorial/using-widevine-cdm-plugin.md) * [継続的インテグレーションシステムによるテスト(Travis, Jenkins)](tutorial/testing-on-headless-ci.md) +* [キーボードショートカット](tutorial/keyboard-shortcuts.md) # チュートリアル diff --git a/docs-translations/jp/tutorial/keyboard-shortcuts.md b/docs-translations/jp/tutorial/keyboard-shortcuts.md new file mode 100644 index 00000000000..507a219623e --- /dev/null +++ b/docs-translations/jp/tutorial/keyboard-shortcuts.md @@ -0,0 +1,89 @@ +# Keyboard Shortcuts + +> ローカル、グローバルのキーボードショートカットを設定します + +## ローカルショートカット + +[Menu] モジュールの設定により、アプリケーションにフォーカスがあるときのキーボードショートカットを設定できます。 +[MenuItem] を作成するときの [`accelerator`] プロパティで設定します。 + +```js +const {Menu, MenuItem} = require('electron') +const menu = new Menu() + +menu.append(new MenuItem({ + label: 'Print', + accelerator: 'CmdOrCtrl+P', + click: () => { console.log('time to print stuff') } +})) +``` + +キーの組み合わせをユーザのOSに基づいて変えることも簡単です。 + +```js +{ + accelerator: process.platform === 'darwin' ? 'Alt+Cmd+I' : 'Ctrl+Shift+I' +} +``` + +## グローバルショートカット + +[globalShortcut] モジュールを使うことで、アプリケーションにフォーカスがないときのキーボードイベントを検知することができます。 + +```js +const {app, globalShortcut} = require('electron') + +app.on('ready', () => { + globalShortcut.register('CommandOrControl+X', () => { + console.log('CommandOrControl+X is pressed') + }) +}) +``` + +## BrowserWindow でのキーボードショートカット + +もしキーボードショートカットイベントを [BrowserWindow] でハンドリングしたい場合は、rendererプロセスの中でwindowオブジェクトの`keyup` と `keydown` のイベントリスナーを使ってください。 + +```js +window.addEventListener('keyup', doSomething, true) +``` + +第3引数にtrueを指定した場合には、リスナーは常に他のリスナーが起動する前にキーイベントを受け取るようになります。そのため、 `stopPropagation()` を呼び出すことができないことに注意してください。 + +[`before-input-event`](web-contents.md#event-before-input-event) イベントは表示しているページの `keydown` and `keyup` イベントが発生する前に発行されます。 +メニューに表示がないショートカットも補足することができます。 + +もし自前でショートカットキーの判定を実装したくない場合には、[mousetrap] のような高度なキー検出を行うライブラリーがあります。 + +```js +Mousetrap.bind('4', () => { console.log('4') }) +Mousetrap.bind('?', () => { console.log('show shortcuts!') }) +Mousetrap.bind('esc', () => { console.log('escape') }, 'keyup') + +// combinations +Mousetrap.bind('command+shift+k', () => { console.log('command shift k') }) + +// map multiple combinations to the same callback +Mousetrap.bind(['command+k', 'ctrl+k'], () => { + console.log('command k or control k') + + // return false to prevent default behavior and stop event from bubbling + return false +}) + +// gmail style sequences +Mousetrap.bind('g i', () => { console.log('go to inbox') }) +Mousetrap.bind('* a', () => { console.log('select all') }) + +// konami code! +Mousetrap.bind('up up down down left right left right b a enter', () => { + console.log('konami code') +}) +``` + +[Menu]: ../api/menu.md +[MenuItem]: ../api/menu-item.md +[globalShortcut]: ../api/global-shortcut.md +[`accelerator`]: ../api/accelerator.md +[BrowserWindow]: ../api/browser-window.md +[mousetrap]: https://github.com/ccampbell/mousetrap diff --git a/docs-translations/pt-BR/api/browser-window.md b/docs-translations/pt-BR/api/browser-window.md index 8080cf5f90a..ddcc4c8a096 100644 --- a/docs-translations/pt-BR/api/browser-window.md +++ b/docs-translations/pt-BR/api/browser-window.md @@ -227,15 +227,15 @@ Acha uma janela de acordo com o seu ID. * `path` String -Adiciona a extenção DevTools localizada no endereço `path`, e retorna o nome da extenção. +Adiciona a extensão DevTools localizada no endereço `path`, e retorna o nome da extensão. -A extenção será lembrada, então você só precisa chamar esta API uma vez, esta API não é para uso de programação. +A extensão será lembrada, então você só precisa chamar esta API uma vez, esta API não é para uso de programação. ### `BrowserWindow.removeDevToolsExtension(name)` * `name` String -Remove a extenção DevTools cujo nome é `name`. +Remove a extensão DevTools cujo nome é `name`. ## Propriedades de Instância diff --git a/docs-translations/pt-BR/api/synopsis.md b/docs-translations/pt-BR/api/synopsis.md index 4661f2c2ca6..97191d5f1bd 100644 --- a/docs-translations/pt-BR/api/synopsis.md +++ b/docs-translations/pt-BR/api/synopsis.md @@ -20,7 +20,7 @@ app.on('ready', () => { }) ``` -O processo renderizador não é diferente de uma página web comum, exceto pela possiblidade de usar módulos node: +O processo renderizador não é diferente de uma página web comum, exceto pela possibilidade de usar módulos node: ```html diff --git a/docs-translations/pt-BR/development/build-instructions-linux.md b/docs-translations/pt-BR/development/build-instructions-linux.md index 3a439902a6c..67d2c8ff10f 100644 --- a/docs-translations/pt-BR/development/build-instructions-linux.md +++ b/docs-translations/pt-BR/development/build-instructions-linux.md @@ -1,6 +1,6 @@ # Instruções de Build (Linux) -Siga as orientações abaixo pra fazer o build do Electron no Linux. +Siga as orientações abaixo para fazer o build do Electron no Linux. ## Pré-requisitos diff --git a/docs-translations/pt-BR/development/coding-style.md b/docs-translations/pt-BR/development/coding-style.md index acfdf7e3dbd..9e0e3283759 100644 --- a/docs-translations/pt-BR/development/coding-style.md +++ b/docs-translations/pt-BR/development/coding-style.md @@ -18,9 +18,9 @@ Para CoffeeScript, seguimos o [Guia de Estilo] (https://github.com/styleguide/ja * Os arquivos **NÃO DEVEM** terminar com uma nova linha, porque queremos corresponder aos padrões de estilo Google. * Os nomes dos arquivos devem ser concatenados com `-` em vez de `_`, por exemplo, `file-name.coffee` em vez de `file_name.coffee`, porque no [github/atom](https://github.com/github/atom) os nomes dos módulos são geralmente da forma `module-name`. Esta regra só se aplica aos arquivos com extensão `.coffee`. -* +* ## Nomes de APIs -Ao criar uma nova API, devemos preferencialmente utilizar métodos getters e setters em vez do +Ao criar uma API, devemos preferencialmente utilizar métodos getters e setters em vez do estilo de uma função única do jQuery. Por exemplo, `.getText()` e `.setText(text)` são preferenciais a `.text([text])`. Existe uma [discussão](https://github.com/electron/electron/issues/46) sobre este assunto. diff --git a/docs-translations/pt-BR/development/source-code-directory-structure.md b/docs-translations/pt-BR/development/source-code-directory-structure.md index 77c01d79113..091ce7682eb 100644 --- a/docs-translations/pt-BR/development/source-code-directory-structure.md +++ b/docs-translations/pt-BR/development/source-code-directory-structure.md @@ -1,6 +1,6 @@ # Estrutura de Diretórios do Código-Fonte -O código-fonte do Electron é separado em algumas partes, seguindo principalmente as convenções de separação do chromium. +O código-fonte do Electron é separado em algumas partes, seguindo principalmente as convenções de separação do chromium. Você pode se familiarizar com a [arquitetura de multiprocessamento ](http://dev.chromium.org/developers/design-documents/multi-process-architecture) do Chromium para entender melhor o código-fonte. @@ -11,13 +11,13 @@ Você pode se familiarizar com a [arquitetura de multiprocessamento ](http://dev Electron ├──atom - Código fonte do Electron. | ├── app - Código de inicialização. -| ├── browser - A interface incluíndo a janela principal, UI, e todas as coisas do processo principal. Ele se comunica com o renderizador para gerenciar as páginas web. +| ├── browser - A interface incluindo a janela principal, UI, e todas as coisas do processo principal. Ele se comunica com o renderizador para gerenciar as páginas web. | |   ├── lib - Código Javascript para inicializar o processo principal. | | ├── ui - Implementação da UI para plataformas distintas. | | | ├── cocoa - Código-fonte específico do cocoa . | | | ├── gtk - Código-font específico do GTK+. | | | └── win - Código-fonte específico do Windows GUI. -| | ├── default_app - A página padrão é mostrada quando +| | ├── default_app - A página padrão é mostrada quando | | | Electron inicializa sem fornecer um app. | | ├── api - Implementação do processo principal das APIs | | | └── lib - Código Javascript, parte da implementação da API. @@ -26,9 +26,9 @@ Electron | | └── resources - Icones, arquivos dependentes da plataforma, etc. | ├── renderer - Código que é executado no processo de renderização. | | ├── lib - Parte do código Javascript de inicialização do renderizador. -| | └── api - Implementação das APIs para o processo de renderizaçãp. +| | └── api - Implementação das APIs para o processo de renderização. | | └── lib - Código Javascript, parte da implementação da API. -| └── common - Código que utiliza ambos os processos, o principal e o de rendezição, +| └── common - Código que utiliza ambos os processos, o principal e o de renderização, | ele inclui algumas funções utilitárias e códigos para integrar com ciclo de mensagens do node no ciclo de mensagens do Chromium. | ├── lib - Código Javascript comum para a inicialização. | └── api - A implementação de APIs comuns e fundamentação dos diff --git a/docs-translations/pt-BR/project/CODE_OF_CONDUCT.md b/docs-translations/pt-BR/project/CODE_OF_CONDUCT.md index c7649302674..9a7ecdf62ae 100644 --- a/docs-translations/pt-BR/project/CODE_OF_CONDUCT.md +++ b/docs-translations/pt-BR/project/CODE_OF_CONDUCT.md @@ -2,13 +2,13 @@ ## Nosso Compromisso -No interesse de promover um ambiente aberto e acolhedor, nos como colaboradores e mantenedores comprometidos a fazer participação em nosso projeto e nossa comunidade uma experiência livre de assédio para todos, independentemente da idade, estatura, deficiência, etnia, identidade de gênero e expressão, nivel de experiência, nacionalidade, aparência pessoal, raça, religião ou identidade sexual e orientação. +No interesse de promover um ambiente aberto e acolhedor, nos como colaboradores e mantenedores comprometidos a fazer participação em nosso projeto e nossa comunidade uma experiência livre de assédio para todos, independentemente da idade, estatura, deficiência, etnia, identidade de gênero e expressão, nível de experiência, nacionalidade, aparência pessoal, raça, religião ou identidade sexual e orientação. ## Nossos Padrões Exemplos de comportamento que contribui para criar um ambiente positivo incluem: -* Usar uma linguagem de boas-vindas e incluisiva +* Usar uma linguagem de boas-vindas e inclusiva * Ser respeitoso com diferentes pontos de vista e experiências * Graciosamente aceitar críticas construtivas * Incidindo sobre o que é melhor para a comunidade @@ -17,7 +17,7 @@ Exemplos de comportamento que contribui para criar um ambiente positivo incluem: Exemplos de comportamento inaceitável pelos participantes incluem: * O uso de linguagem sexualizada ou imagens e atenção sexual indesejada ou avanços -* Trolando, comentários depreciativos, e ataques insultantes/pessoais ou politicos +* Trolando, comentários depreciativos, e ataques insultantes/pessoais ou políticos * Assédio público ou privado * A publicação de outras informações privadas, tais como um endereço físico ou eletrônico, sem permissão explícita * Outra conduta que possa ser razoavelmente considerada inadequada em um ambiente profissional @@ -26,7 +26,7 @@ Exemplos de comportamento inaceitável pelos participantes incluem: Mantenedores do projeto são responsáveis por esclarecer as normas do comportamento aceitável e espera-se que as medidas corretivas adequadas e justas em resposta a todas as instâncias do comportamento inaceitável. -Mantenedores do projeto têm o direito e a responsabilidade de remover, editar, ou rejeitar comentários, commits, código, edição de wiki, issues e outras contribuições que não estão alinhadas a este Código de Conduta, ou proibir temporária ou permamentemente qualquer colaborador por outros comportamentos que considerem inapropriado, ameaçador, ofensivo ou prejudicial. +Mantenedores do projeto têm o direito e a responsabilidade de remover, editar, ou rejeitar comentários, commits, código, edição de wiki, issues e outras contribuições que não estão alinhadas a este Código de Conduta, ou proibir temporária ou permanentemente qualquer colaborador por outros comportamentos que considerem inapropriado, ameaçador, ofensivo ou prejudicial. ## Escopo @@ -36,7 +36,7 @@ Este Código de Conduta aplica-se tanto dentro dos espaços do projeto e em espa Instânicas de assédio ou comportamento abusivo, de outro modo inaceitáveis podem ser relatados em contato com a equipe do projeto em [electron@github.com](mailto:electron@github.com). Todas as reclamações serão analisadas e investigadas e irá resultar em uma resposta que for considerada necessária e adequada ás circunstâncias. A equipe do projeto é obrigada a manter a confidencialidade no que diz respeito ao relato de um incidente. Mais detalhes das políticas de aplicação específicas podem ser publicadas separadamente. -Mantenedores de projetos que não seguem ou fazem comprir o Código de Conduta de boa-fé podem enfrentar repercussões temporárias ou permanentes, conforme determinado por outros membros da liderança do projeto. +Mantenedores de projetos que não seguem ou fazem cumprir o Código de Conduta de boa-fé podem enfrentar repercussões temporárias ou permanentes, conforme determinado por outros membros da liderança do projeto. ## Atribuição diff --git a/docs-translations/pt-BR/styleguide.md b/docs-translations/pt-BR/styleguide.md index f4236a46cba..6294585a5bb 100644 --- a/docs-translations/pt-BR/styleguide.md +++ b/docs-translations/pt-BR/styleguide.md @@ -27,7 +27,7 @@ Estas são as formas que escrevemos a documentação do Electron. ## Lendo a documentação do Electron -Aqui estão algumas dicas de como entender a sintaxe da documentacão do Electron. +Aqui estão algumas dicas de como entender a sintaxe da documentação do Electron. ### Métodos @@ -74,4 +74,4 @@ crie algo parecido com o exemplo abaixo: Alarm.on('wake-up', function (time) { console.log(time) }) -``` \ No newline at end of file +``` diff --git a/docs-translations/pt-BR/tutorial/accessibility.md b/docs-translations/pt-BR/tutorial/accessibility.md index f4168c6c9aa..8e39a42f9e4 100644 --- a/docs-translations/pt-BR/tutorial/accessibility.md +++ b/docs-translations/pt-BR/tutorial/accessibility.md @@ -28,6 +28,6 @@ Em Devtron há uma nova guia de acessibilidade que permitirá auditar uma págin ![devtron screenshot](https://cloud.githubusercontent.com/assets/1305617/17156618/9f9bcd72-533f-11e6-880d-389115f40a2a.png) -Ambas as ferramentas estão usando a biblioteca [Accessibility Developer Tools](https://github.com/GoogleChrome/accessibility-developer-tools) construída pela Google for Chrome. Você pode aprender mais sobre as regras de auditoria da biblioteca de acessibilidade no [wiki do repositório](https://github.com/GoogleChrome/accessibility-developer-tools/wiki/Audit-Rules). +Ambas as ferramentas estão usando a biblioteca [Accessibility Developer Tools](https://github.com/GoogleChrome/accessibility-developer-tools) construída pela Google para o Chrome. Você pode aprender mais sobre as regras de auditoria da biblioteca de acessibilidade no [wiki do repositório](https://github.com/GoogleChrome/accessibility-developer-tools/wiki/Audit-Rules). Se você souber de outras ferramentas de acessibilidade para o Electron, adicione-as à [documentação de acessibilidade](https://electron.atom.io/docs/tutorial/accessibility) através de um pull request. diff --git a/docs-translations/pt-BR/tutorial/application-packaging.md b/docs-translations/pt-BR/tutorial/application-packaging.md index 7ea11f694af..612384607da 100644 --- a/docs-translations/pt-BR/tutorial/application-packaging.md +++ b/docs-translations/pt-BR/tutorial/application-packaging.md @@ -7,7 +7,7 @@ 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 +em um único arquivo. O Electron pode ler arquivos arbitrários a partir dele sem descompactar o arquivo inteiro. Passos para empacotar a sua aplicação em um arquivo `asar`: @@ -133,7 +133,7 @@ APIs que requer descompactação extras são: ### 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, +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. diff --git a/docs-translations/pt-BR/tutorial/desktop-environment-integration.md b/docs-translations/pt-BR/tutorial/desktop-environment-integration.md index 55465005662..214f5c8269d 100644 --- a/docs-translations/pt-BR/tutorial/desktop-environment-integration.md +++ b/docs-translations/pt-BR/tutorial/desktop-environment-integration.md @@ -1,7 +1,7 @@ # Integração com o ambiente desktop Diferentes sistemas operacionais possuem diferentes formas de integrar -aplicacões desktop em seus ambientes. Por exemplo, no Windows, as aplicações podem +aplicações desktop em seus ambientes. Por exemplo, no Windows, as aplicações podem inserir atalhos no JumpList da barra de tarefas, no Mac, aplicações podem implementar um menu customizado na dock. diff --git a/docs-translations/pt-BR/tutorial/security.md b/docs-translations/pt-BR/tutorial/security.md index c566756c736..308dc4a9e55 100644 --- a/docs-translations/pt-BR/tutorial/security.md +++ b/docs-translations/pt-BR/tutorial/security.md @@ -8,13 +8,13 @@ Com isso em mente, estar ciente de que a exibição de conteúdo arbitrário de ## Chromium Security Issues e Upgrades -Enquanto Electron se esforça para suportar novas versões do Chromium, logo que possível, os desenvolvedores devem estar cientes de que a atualização é um empreendimento importante - envolvendo dezenas de mãos ou mesmo centenas de arquivos. Dados os recursos e contribuições disponíveis hoje, Electron muitas vezes não vai estar na mais recente versão do Chromium, ficando para trás, quer por dias ou semanas. +Enquanto Electron se esforça para suportar novas versões do Chromium, logo que possível, os desenvolvedores devem estar cientes que a atualização é um empreendimento importante - envolvendo dezenas de mãos ou mesmo centenas de arquivos. Dados os recursos e contribuições disponíveis hoje, Electron muitas vezes não vai estar na mais recente versão do Chromium, ficando para trás, quer por dias ou semanas. -Nós sentimos que nosso sistema atual de atualizar o componente do Chromium estabelece um equilíbrio adequado entre os recursos que temos disponíveis e as necessidades da maioria das aplicações contruídas em cima do framework. Nós definitivamente estamos interessados em saber mais sobre casos de uso específicos de pessoas que constroem coisas em cima do Electron. Pull requests e contribuições para apoiar este esforço são sempre muito bem-vindas. +Nós sentimos que nosso sistema atual de atualizar o componente do Chromium estabelece um equilíbrio adequado entre os recursos que temos disponíveis e as necessidades da maioria das aplicações construídas em cima do framework. Nós definitivamente estamos interessados em saber mais sobre casos de uso específicos de pessoas que constroem coisas em cima do Electron. Pull requests e contribuições para apoiar este esforço são sempre muito bem-vindas. -## Igonorando o Conselho Acima +## Ignorando o Conselho Acima -Um probema de segurança existe sempre que você receba um código a partir de um destino remoto e o executa locamente. Como exemplo, considere um site remoto que está sendo exibido dentro de uma janela do navegador. Se um atacante de alguma forma consegue mudar esse conteúdo (seja por atacar a fonte diretamente, ou por estar entre seu aplicativo e o destino real), eles serão capazes de executar código nativo na máquina do usuário. +Um problema de segurança existe sempre que você receba um código a partir de um destino remoto e o executa localmente. Como exemplo, considere um site remoto que está sendo exibido dentro de uma janela do navegador. Se um atacante de alguma forma consegue mudar esse conteúdo (seja por atacar a fonte diretamente, ou por estar entre seu aplicativo e o destino real), eles serão capazes de executar código nativo na máquina do usuário. > :warning: Sobre nenhuma circunstância você deve carregar e executar código remoto com integração com Node. Em vez disso, use somente arquivos locais (embalados juntamente com a sua aplicação) para executar código Node. Para exibir o conteúdo remoto, use a tag `webview` e certifique-se de desativar o `nodeIntegration`. diff --git a/docs-translations/pt-BR/tutorial/supported-platforms.md b/docs-translations/pt-BR/tutorial/supported-platforms.md index 1db405257da..59b0df0698a 100644 --- a/docs-translations/pt-BR/tutorial/supported-platforms.md +++ b/docs-translations/pt-BR/tutorial/supported-platforms.md @@ -4,17 +4,17 @@ As plataformas suportadas por Electron são: ### macOS -Somente binarios em 64bit são construidos para macOS e a versão mínima suportada é macOS 10.9. +Somente binários em 64bit são construídos para macOS e a versão mínima suportada é macOS 10.9. ### Windows -Suporte para Windows 7 ou superior, versões anteriores não são suportados (e não ira funcionar) +Suporte para Windows 7 ou superior, versões anteriores não são suportados (e não ira funcionar) - Binarios em `x86` e `amd64` (x64) são construidos para Windows. Atencão: Versão `ARM` do Windows não é suportada agora. +Binários em `x86` e `amd64` (x64) são construídos para Windows. Atenção: Versão `ARM` do Windows não é suportada agora. ### Linux -Binario pré-construido `ia32`(`i686`) e binario `x64`(`amd64`) são construidas no Ubuntu 12.04, binario `arm` está construido contra ARM v7 com hard-float ABI e NEION para Debian Wheezy. +Binario pré-construído `ia32`(`i686`) e binario `x64`(`amd64`) são construídas no Ubuntu 12.04, binario `arm` está construído contra ARM v7 com hard-float ABI e NEION para Debian Wheezy. -Se o pré-compilador poderá ser executado por uma distribuição, depende se a distruibuicão inclui as blibliotecas que o Eletron está vinculando na plataforma de construcão, por este motivo apenas Ubuntu 12.04 é garantido para funcionar corretamente, mas as seguintes distribuições foram verificados com o pre-compilador: +Se o pré-compilador poderá ser executado por uma distribuição, depende se a distribuição inclui as bibliotecas que o Eletron está vinculando na plataforma de construção, por este motivo apenas Ubuntu 12.04 é garantido para funcionar corretamente, mas as seguintes distribuições foram verificados com o pre-compilador: * Ubuntu 12.04 ou superior diff --git a/docs-translations/pt-BR/tutorial/using-native-node-modules.md b/docs-translations/pt-BR/tutorial/using-native-node-modules.md index 9ffaabedd03..86abe1a5d1d 100644 --- a/docs-translations/pt-BR/tutorial/using-native-node-modules.md +++ b/docs-translations/pt-BR/tutorial/using-native-node-modules.md @@ -17,7 +17,7 @@ página [releases](https://github.com/electron/electron/releases) ou usando por exemplo). Considere usar [NAN](https://github.com/nodejs/nan/) para seus próprios -módulos, caso isso facilite o suporte da múltiplas versões do Node. Isso é +módulos, caso isso facilite o suporte das múltiplas versões do Node. Isso é também de grande ajuda para fazer a portabilidade dos módulos antigos para as versões mais novas do Node, assim podendo trabalhar com o Electron. diff --git a/docs-translations/pt-BR/tutorial/using-pepper-flash-plugin.md b/docs-translations/pt-BR/tutorial/using-pepper-flash-plugin.md index a8ee528fc3b..fe0feac5aba 100644 --- a/docs-translations/pt-BR/tutorial/using-pepper-flash-plugin.md +++ b/docs-translations/pt-BR/tutorial/using-pepper-flash-plugin.md @@ -31,7 +31,7 @@ app.on('window-all-closed', function () { if (process.platform !== 'darwin') app.quit() }) -// Epecifica o caminho do flash. +// Especifica o caminho do flash. // No Windows, deve ser /path/to/pepflashplayer.dll // No macOS, /path/to/PepperFlashPlayer.plugin // No Linux, /path/to/libpepflashplayer.so diff --git a/docs-translations/tr-TR/README.md b/docs-translations/tr-TR/README.md index ac11a02f4d3..eedd9f375a7 100644 --- a/docs-translations/tr-TR/README.md +++ b/docs-translations/tr-TR/README.md @@ -58,7 +58,7 @@ Bir problem(issue) bildirmeden önce sıkça sorulan sorulara göz atın: * [webContents](https://github.com/electron/electron/tree/master/docs/api/web-contents.md) * [Tray](https://github.com/electron/electron/tree/master/docs/api/tray.md) -### Renderer Process Modülelri (Web Page): +### Renderer Process Modülleri (Web Page): * [desktopCapturer](https://github.com/electron/electron/tree/master/docs/api/desktop-capturer.md) * [ipcRenderer](https://github.com/electron/electron/tree/master/docs/api/ipc-renderer.md) diff --git a/docs/api/app.md b/docs/api/app.md index 82ae0e50f2f..3ac9ca211b6 100644 --- a/docs/api/app.md +++ b/docs/api/app.md @@ -772,6 +772,14 @@ Disables hardware acceleration for current app. This method can only be called before app is ready. +### `app.disableDomainBlockingFor3DAPIs()` + +By default, Chromium disables 3D APIs (e.g. WebGL) until restart on a per +domain basis if the GPU processes crashes too frequently. This function +disables that behaviour. + +This method can only be called before app is ready. + ### `app.getAppMemoryInfo()` _Deprecated_ Returns [`ProcessMetric[]`](structures/process-metric.md): Array of `ProcessMetric` objects that correspond to memory and cpu usage statistics of all the processes associated with the app. @@ -919,9 +927,6 @@ Enables mixed sandbox mode on the app. This method can only be called before app is ready. -**Note:** The devtools will no longer open after mixed sandbox mode has been -enabled (i.e `openDevTools` becomes a no-op). - ### `app.dock.bounce([type])` _macOS_ * `type` String (optional) - Can be `critical` or `informational`. The default is diff --git a/docs/api/auto-updater.md b/docs/api/auto-updater.md index 9c743a0376d..075f0bf9338 100644 --- a/docs/api/auto-updater.md +++ b/docs/api/auto-updater.md @@ -39,9 +39,9 @@ This is a requirement of `Squirrel.Mac`. On Windows, you have to install your app into a user's machine before you can use the `autoUpdater`, so it is recommended that you use the -[electron-winstaller][installer-lib], [electron-builder][electron-builder-lib] or the [grunt-electron-installer][installer] package to generate a Windows installer. +[electron-winstaller][installer-lib], [electron-forge][electron-forge-lib] or the [grunt-electron-installer][installer] package to generate a Windows installer. -When using [electron-winstaller][installer-lib] or [electron-builder][electron-builder-lib] make sure you do not try to update your app [the first time it runs](https://github.com/electron/windows-installer#handling-squirrel-events) (Also see [this issue for more info](https://github.com/electron/electron/issues/7155)). It's also recommended to use [electron-squirrel-startup](https://github.com/mongodb-js/electron-squirrel-startup) to get desktop shortcuts for your app. +When using [electron-winstaller][installer-lib] or [electron-forge][electron-forge-lib] make sure you do not try to update your app [the first time it runs](https://github.com/electron/windows-installer#handling-squirrel-events) (Also see [this issue for more info](https://github.com/electron/electron/issues/7155)). It's also recommended to use [electron-squirrel-startup](https://github.com/mongodb-js/electron-squirrel-startup) to get desktop shortcuts for your app. The installer generated with Squirrel will create a shortcut icon with an [Application User Model ID][app-user-model-id] in the format of @@ -50,8 +50,9 @@ The installer generated with Squirrel will create a shortcut icon with an same ID for your app with `app.setAppUserModelId` API, otherwise Windows will not be able to pin your app properly in task bar. -The server-side setup is also different from macOS. You can read the documents of -[Squirrel.Windows][squirrel-windows] to get more details. +Unlike Squirrel.Mac, Windows can host updates on S3 or any other static file host. +You can read the documents of [Squirrel.Windows][squirrel-windows] to get more details +about how Squirrel.Windows works. ### Linux @@ -131,7 +132,7 @@ from the normal quit event sequence. [squirrel-windows]: https://github.com/Squirrel/Squirrel.Windows [installer]: https://github.com/electron/grunt-electron-installer [installer-lib]: https://github.com/electron/windows-installer -[electron-builder-lib]: https://github.com/electron-userland/electron-builder +[electron-forge-lib]: https://github.com/electron-userland/electron-forge [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/api/browser-view.md b/docs/api/browser-view.md index ac05101a37f..4b0d2d473cd 100644 --- a/docs/api/browser-view.md +++ b/docs/api/browser-view.md @@ -1,4 +1,4 @@ -## Class: BrowserView +# Class: BrowserView > Create and control views. diff --git a/docs/api/browser-window-proxy.md b/docs/api/browser-window-proxy.md index 2bf5a15f748..e2a2421cd09 100644 --- a/docs/api/browser-window-proxy.md +++ b/docs/api/browser-window-proxy.md @@ -50,4 +50,4 @@ The `BrowserWindowProxy` object has the following instance properties: #### `win.closed` -A Boolean that is set to true after the child window gets closed. +A `Boolean` that is set to true after the child window gets closed. diff --git a/docs/api/browser-window.md b/docs/api/browser-window.md index f5b81207890..0bae5146e7b 100644 --- a/docs/api/browser-window.md +++ b/docs/api/browser-window.md @@ -225,6 +225,9 @@ It creates a new `BrowserWindow` with native properties as set by the `options`. display unless hovered over in the top left of the window. These custom buttons prevent issues with mouse events that occur with the standard window toolbar buttons. **Note:** This option is currently experimental. + * `fullscreenWindowTitle` Boolean (optional) - Shows the title in the + tile bar in full screen mode on macOS for all `titleBarStyle` options. + Default is `false`. * `thickFrame` Boolean (optional) - Use `WS_THICKFRAME` style for frameless windows on Windows, which adds standard window frame. Setting it to `false` will remove window shadow and window animations. Default is `true`. @@ -336,7 +339,9 @@ It creates a new `BrowserWindow` with native properties as set by the `options`. 'Electron Isolated Context' entry in the combo box at the top of the Console tab. **Note:** This option is currently experimental and may change or be removed in future Electron releases. - * `nativeWindowOpen` Boolean (optional) - Whether to use native `window.open()`. Defaults to `false`. + * `nativeWindowOpen` Boolean (optional) - Whether to use native + `window.open()`. Defaults to `false`. **Note:** This option is currently + experimental. * `webviewTag` Boolean (optional) - Whether to enable the [`` tag](webview-tag.md). Defaults to the value of the `nodeIntegration` option. **Note:** The `preload` script configured for the `` will have node integration diff --git a/docs/api/client-request.md b/docs/api/client-request.md index e9f9047d565..fc43226ec8a 100644 --- a/docs/api/client-request.md +++ b/docs/api/client-request.md @@ -143,7 +143,7 @@ Emitted when there is redirection and the mode is `manual`. Calling #### `request.chunkedEncoding` -A Boolean specifying whether the request will use HTTP chunked transfer encoding +A `Boolean` specifying whether the request will use HTTP chunked transfer encoding or not. Defaults to false. The property is readable and writable, however it can be set only before the first write operation as the HTTP headers are not yet put on the wire. Trying to set the `chunkedEncoding` property after the first write @@ -184,7 +184,7 @@ before first write. Trying to call it after the first write will throw an error. string, it is converted into a Buffer using the specified encoding. * `encoding` String (optional) - Used to convert string chunks into Buffer objects. Defaults to 'utf-8'. -* `callback` Function (optional) - Called after the write operation ends. +* `callback` Function (optional) - Called after the write operation ends. `callback` is essentially a dummy function introduced in the purpose of keeping similarity with the Node.js API. It is called asynchronously in the next tick diff --git a/docs/api/dialog.md b/docs/api/dialog.md index bc756741b84..c99a4cf2950 100644 --- a/docs/api/dialog.md +++ b/docs/api/dialog.md @@ -46,6 +46,8 @@ The `dialog` module has the following methods: * `noResolveAliases` - Disable the automatic alias (symlink) path resolution. Selected aliases will now return the alias path instead of their target path. _macOS_ + * `treatPackageAsDirectory` - Treat packages, such as `.app` folders, + as a directory instead of a file. _macOS_ * `message` String (optional) _macOS_ - Message to display above input boxes. * `callback` Function (optional) diff --git a/docs/api/file-object.md b/docs/api/file-object.md index d451513c02f..9c582065f91 100644 --- a/docs/api/file-object.md +++ b/docs/api/file-object.md @@ -15,19 +15,17 @@ Example of getting a real path from a dragged-onto-the-app file: ``` diff --git a/docs/api/incoming-message.md b/docs/api/incoming-message.md index f047aaa7e41..bf4e8d20059 100644 --- a/docs/api/incoming-message.md +++ b/docs/api/incoming-message.md @@ -43,15 +43,15 @@ An `IncomingMessage` instance has the following readable properties: #### `response.statusCode` -An Integer indicating the HTTP response status code. +An `Integer` indicating the HTTP response status code. #### `response.statusMessage` -A String representing the HTTP status message. +A `String` representing the HTTP status message. #### `response.headers` -An Object representing the response HTTP headers. The `headers` object is +An `Object` representing the response HTTP headers. The `headers` object is formatted as follows: * All header names are lowercased. @@ -60,15 +60,15 @@ formatted as follows: #### `response.httpVersion` -A String indicating the HTTP protocol version number. Typical values are '1.0' +A `String` indicating the HTTP protocol version number. Typical values are '1.0' or '1.1'. Additionally `httpVersionMajor` and `httpVersionMinor` are two Integer-valued readable properties that return respectively the HTTP major and minor version numbers. #### `response.httpVersionMajor` -An Integer indicating the HTTP protocol major version number. +An `Integer` indicating the HTTP protocol major version number. #### `response.httpVersionMinor` -An Integer indicating the HTTP protocol minor version number. +An `Integer` indicating the HTTP protocol minor version number. diff --git a/docs/api/menu-item.md b/docs/api/menu-item.md index a7486f3003c..49e68cc606e 100644 --- a/docs/api/menu-item.md +++ b/docs/api/menu-item.md @@ -93,17 +93,17 @@ The following properties are available on instances of `MenuItem`: #### `menuItem.enabled` -A Boolean indicating whether the item is enabled, this property can be +A `Boolean` indicating whether the item is enabled, this property can be dynamically changed. #### `menuItem.visible` -A Boolean indicating whether the item is visible, this property can be +A `Boolean` indicating whether the item is visible, this property can be dynamically changed. #### `menuItem.checked` -A Boolean indicating whether the item is checked, this property can be +A `Boolean` indicating whether the item is checked, this property can be dynamically changed. A `checkbox` menu item will toggle the `checked` property on and off when @@ -116,8 +116,8 @@ You can add a `click` function for additional behavior. #### `menuItem.label` -A String representing the menu items visible label +A `String` representing the menu items visible label #### `menuItem.click` -A Function that is fired when the MenuItem receives a click event +A `Function` that is fired when the MenuItem receives a click event diff --git a/docs/api/menu.md b/docs/api/menu.md index 6480c73cd00..a6ca5461d42 100644 --- a/docs/api/menu.md +++ b/docs/api/menu.md @@ -1,4 +1,4 @@ -## Class: Menu +# Class: Menu > Create native application menus and context menus. @@ -101,7 +101,7 @@ Inserts the `menuItem` to the `pos` position of the menu. #### `menu.items` -A MenuItem[] array containing the menu's items. +A `MenuItem[]` array containing the menu's items. Each `Menu` consists of multiple [`MenuItem`](menu-item.md)s and each `MenuItem` can have a submenu. diff --git a/docs/api/notification.md b/docs/api/notification.md index 64f094ff745..90361026682 100644 --- a/docs/api/notification.md +++ b/docs/api/notification.md @@ -31,13 +31,13 @@ Returns `Boolean` - Whether or not desktop notifications are supported on the cu * `options` Object * `title` String - A title for the notification, which will be shown at the top of the notification window when it is shown - * `subtitle` String - A subtitle for the notification, which will be displayed below the title. _macOS_ + * `subtitle` String - (optional) A subtitle for the notification, which will be displayed below the title. _macOS_ * `body` String - The body text of the notification, which will be displayed below the title or subtitle * `silent` Boolean - (optional) Whether or not to emit an OS notification noise when showing the notification * `icon` [NativeImage](native-image.md) - (optional) An icon to use in the notification * `hasReply` Boolean - (optional) Whether or not to add an inline reply option to the notification. _macOS_ * `replyPlaceholder` String - (optional) The placeholder to write in the inline reply input field. _macOS_ - * `actions` [NotificationAction[]](structures/notification-action.md) - Actions to add to the notification. Please read the available actions and limitations in the `NotificationAction` documentation _macOS_ + * `actions` [NotificationAction[]](structures/notification-action.md) - (optional) Actions to add to the notification. Please read the available actions and limitations in the `NotificationAction` documentation _macOS_ ### Instance Events diff --git a/docs/api/touch-bar.md b/docs/api/touch-bar.md index 914c22086a5..de50e5a03ba 100644 --- a/docs/api/touch-bar.md +++ b/docs/api/touch-bar.md @@ -1,4 +1,4 @@ -## Class: TouchBar +# Class: TouchBar > Create TouchBar layouts for native macOS applications @@ -6,7 +6,7 @@ Process: [Main](../tutorial/quick-start.md#main-process) ### `new TouchBar(options)` _Experimental_ -* `options` - Object +* `options` Object * `items` ([TouchBarButton](touch-bar-button.md) | [TouchBarColorPicker](touch-bar-color-picker.md) | [TouchBarGroup](touch-bar-group.md) | [TouchBarLabel](touch-bar-label.md) | [TouchBarPopover](touch-bar-popover.md) | [TouchBarScrubber](touch-bar-scrubber.md) | [TouchBarSegmentedControl](touch-bar-segmented-control.md) | [TouchBarSlider](touch-bar-slider.md) | [TouchBarSpacer](touch-bar-spacer.md))[] * `escapeItem` ([TouchBarButton](touch-bar-button.md) | [TouchBarColorPicker](touch-bar-color-picker.md) | [TouchBarGroup](touch-bar-group.md) | [TouchBarLabel](touch-bar-label.md) | [TouchBarPopover](touch-bar-popover.md) | [TouchBarScrubber](touch-bar-scrubber.md) | [TouchBarSegmentedControl](touch-bar-segmented-control.md) | [TouchBarSlider](touch-bar-slider.md) | [TouchBarSpacer](touch-bar-spacer.md)) (optional) @@ -26,7 +26,7 @@ The following properties are available on instances of `TouchBar`: #### `touchBar.escapeItem` -The `TouchBarItem` that will replace the "esc" button on the touch bar when set. +The `TouchBarButton` that will replace the "esc" button on the touch bar when set. Setting to `null` restores the default "esc" button. Changing this value immediately updates the escape item in the touch bar. diff --git a/docs/api/web-contents.md b/docs/api/web-contents.md index 3c85a693306..72743dfcbbf 100644 --- a/docs/api/web-contents.md +++ b/docs/api/web-contents.md @@ -1335,11 +1335,11 @@ Returns `Integer` - The `pid` of the associated renderer process. #### `contents.id` -A Integer representing the unique ID of this WebContents. +A `Integer` representing the unique ID of this WebContents. #### `contents.session` -A Session object ([session](session.md)) used by this webContents. +A [`Session`](session.md) used by this webContents. #### `contents.hostWebContents` diff --git a/docs/development/debugging-instructions-macos.md b/docs/development/debugging-instructions-macos.md index 054909773f6..594f9c50322 100644 --- a/docs/development/debugging-instructions-macos.md +++ b/docs/development/debugging-instructions-macos.md @@ -88,7 +88,7 @@ which will show you that the app is currently setting the name to "Electron". ``` To do a source level single step in the currently selected thread, execute `step` (or `s`). -This would take you into into `name_override_.empty()`. To proceed and do a step over, +This would take you into `name_override_.empty()`. To proceed and do a step over, run `next` (or `n`). ```bash diff --git a/docs/faq.md b/docs/faq.md index abeac23f76e..d8c74e07c60 100644 --- a/docs/faq.md +++ b/docs/faq.md @@ -1,5 +1,20 @@ # Electron FAQ +## Why am I having trouble installing Electron? + +When running `npm install electron`, some users occasionally encounter +installation errors. + +In almost all cases, these errors are the result of network problems and not +actual issues with the `electron` npm package. Errors like `ELIFECYCLE`, +`EAI_AGAIN`, `ECONNRESET`, and `ETIMEDOUT` are all indications of such +network problems. The best resolution is to try switching networks, or +just wait a bit and try installing again. + +You can also attempt to download Electron directly from +[electron/electron/releases](https://github.com/electron/electron/releases) +if installing via `npm` is failing. + ## When will Electron upgrade to latest Chrome? The Chrome version of Electron is usually bumped within one or two weeks after diff --git a/docs/glossary.md b/docs/glossary.md index 3a82be15925..415a401a191 100644 --- a/docs/glossary.md +++ b/docs/glossary.md @@ -88,6 +88,10 @@ free software licenses, and is a widely-used alternative to commercial proprietary products like InstallShield. [electron-builder] supports NSIS as a build target. +## OSR + +Off-screen rendering. + ### process A process is an instance of a computer program that is being executed. Electron @@ -155,7 +159,7 @@ embedded content. [autoUpdater]: api/auto-updater.md [electron-builder]: https://github.com/electron-userland/electron-builder [libchromiumcontent]: #libchromiumcontent -[Mac App Store Submission Guide]: tutorials/mac-app-store-submission-guide.md +[Mac App Store Submission Guide]: tutorial/mac-app-store-submission-guide.md [main]: #main-process [renderer]: #renderer-process [Using Native Node Modules]: tutorial/using-native-node-modules.md diff --git a/docs/tutorial/mac-app-store-submission-guide.md b/docs/tutorial/mac-app-store-submission-guide.md index 4551935d6cc..10c59906a2b 100644 --- a/docs/tutorial/mac-app-store-submission-guide.md +++ b/docs/tutorial/mac-app-store-submission-guide.md @@ -215,6 +215,17 @@ more details. See the [Enabling User-Selected File Access documentation][user-selected] for more details. +## Known issues + +### `shell.openItem(filePath)` + +This will fail when the app is signed for distribution in the Mac App Store. +Subscribe to [#9005](https://github.com/electron/electron/issues/9005) for updates. + +#### Workaround + +`shell.openExternal('file://' + filePath)` will open the file in the default application as long as the extension is associated with an installed app. + ## Cryptographic Algorithms Used by Electron Depending on the country and region you are located, Mac App Store may require diff --git a/docs/tutorial/windows-store-guide.md b/docs/tutorial/windows-store-guide.md index c25ee9bd4c7..609ade80136 100644 --- a/docs/tutorial/windows-store-guide.md +++ b/docs/tutorial/windows-store-guide.md @@ -134,7 +134,7 @@ that mode, the CLI will install and run your application in blank Windows Contai to determine what modifications your application is exactly doing to the operating system. -Before running the CLI for the, you will have to setup the "Windows Desktop App +Before running the CLI for the first time, you will have to setup the "Windows Desktop App Converter". This will take a few minutes, but don't worry - you only have to do this once. Download and Desktop App Converter from [here][app-converter]. You will receive two files: `DesktopAppConverter.zip` and `BaseImage-14316.wim`. diff --git a/electron.gyp b/electron.gyp index d0922e0ea0c..c4be1be62c3 100644 --- a/electron.gyp +++ b/electron.gyp @@ -4,7 +4,7 @@ 'product_name%': 'Electron', 'company_name%': 'GitHub, Inc', 'company_abbr%': 'github', - 'version%': '1.7.4', + 'version%': '1.7.5', 'js2c_input_dir': '<(SHARED_INTERMEDIATE_DIR)/js2c', }, 'includes': [ diff --git a/lib/browser/api/dialog.js b/lib/browser/api/dialog.js index 96446180476..1ddc65bc3fa 100644 --- a/lib/browser/api/dialog.js +++ b/lib/browser/api/dialog.js @@ -11,7 +11,8 @@ const fileDialogProperties = { createDirectory: 1 << 3, showHiddenFiles: 1 << 4, promptToCreate: 1 << 5, - noResolveAliases: 1 << 6 + noResolveAliases: 1 << 6, + treatPackageAsDirectory: 1 << 7 } const messageBoxTypes = ['none', 'info', 'warning', 'error', 'question'] diff --git a/lib/browser/guest-window-manager.js b/lib/browser/guest-window-manager.js index 99bcacf5cb8..bd9473dda87 100644 --- a/lib/browser/guest-window-manager.js +++ b/lib/browser/guest-window-manager.js @@ -11,7 +11,9 @@ const frameToGuest = new Map() const inheritedWebPreferences = new Map([ ['contextIsolation', true], ['javascript', false], + ['nativeWindowOpen', true], ['nodeIntegration', false], + ['sandbox', true], ['webviewTag', false] ]) @@ -78,19 +80,8 @@ const setupGuest = function (embedder, frameName, guest, options) { embedder.send('ELECTRON_GUEST_WINDOW_MANAGER_WINDOW_CLOSED_' + guestId) embedder.removeListener('render-view-deleted', closedByEmbedder) } - if (!options.webPreferences.sandbox) { - // These events should only be handled when the guest window is opened by a - // non-sandboxed renderer for two reasons: - // - // - `render-view-deleted` is emitted when the popup is closed by the user, - // and that will eventually result in NativeWindow::NotifyWindowClosed - // using a dangling pointer since `destroy()` would have been called by - // `closeByEmbedded` - // - No need to emit `ELECTRON_GUEST_WINDOW_MANAGER_WINDOW_CLOSED_` since - // there's no renderer code listening to it., - embedder.once('render-view-deleted', closedByEmbedder) - guest.once('closed', closedByUser) - } + embedder.once('render-view-deleted', closedByEmbedder) + guest.once('closed', closedByUser) if (frameName) { frameToGuest.set(frameName, guest) guest.frameName = frameName diff --git a/lib/renderer/chrome-api.js b/lib/renderer/chrome-api.js index 4bd69d0be16..1b509178f49 100644 --- a/lib/renderer/chrome-api.js +++ b/lib/renderer/chrome-api.js @@ -173,7 +173,7 @@ exports.injectTo = function (extensionId, isBackgroundPage, context) { onMessage: chrome.runtime.onMessage } - chrome.storage = require('./extensions/storage') + chrome.storage = require('./extensions/storage').setup(extensionId) chrome.pageAction = { show () {}, diff --git a/lib/renderer/content-scripts-injector.js b/lib/renderer/content-scripts-injector.js index e4a801110f6..7d0f3400922 100644 --- a/lib/renderer/content-scripts-injector.js +++ b/lib/renderer/content-scripts-injector.js @@ -5,9 +5,9 @@ const {runInThisContext} = require('vm') // https://developer.chrome.com/extensions/match_patterns const matchesPattern = function (pattern) { if (pattern === '') return true - const regexp = new RegExp('^' + pattern.replace(/\*/g, '.*') + '$') - return location.href.match(regexp) + const url = `${location.protocol}//${location.host}${location.pathname}` + return url.match(regexp) } // Run the code with chrome API integrated. @@ -26,9 +26,7 @@ const runContentScript = function (extensionId, url, code) { // Run injected scripts. // https://developer.chrome.com/extensions/content_scripts const injectContentScript = function (extensionId, script) { - for (const match of script.matches) { - if (!matchesPattern(match)) return - } + if (!script.matches.some(matchesPattern)) return for (const {url, code} of script.js) { const fire = runContentScript.bind(window, extensionId, url, code) diff --git a/lib/renderer/extensions/storage.js b/lib/renderer/extensions/storage.js index d1a8d880a60..2920a2860e0 100644 --- a/lib/renderer/extensions/storage.js +++ b/lib/renderer/extensions/storage.js @@ -1,88 +1,131 @@ -const getStorage = (storageType) => { - const data = window.localStorage.getItem(`__chrome.storage.${storageType}__`) - if (data != null) { - return JSON.parse(data) - } else { - return {} - } +const fs = require('fs') +const path = require('path') +const { remote } = require('electron') +const { app } = remote + +const getChromeStoragePath = (storageType, extensionId) => { + return path.join( + app.getPath('userData'), `/Chrome Storage/${extensionId}-${storageType}.json`) } -const setStorage = (storageType, storage) => { - const json = JSON.stringify(storage) - window.localStorage.setItem(`__chrome.storage.${storageType}__`, json) -} - -const scheduleCallback = (items, callback) => { - setTimeout(function () { - callback(items) +const mkdirp = (dir, callback) => { + fs.mkdir(dir, (error) => { + if (error && error.code === 'ENOENT') { + mkdirp(path.dirname(dir), (error) => { + if (!error) { + mkdirp(dir, callback) + } + }) + } else if (error && error.code === 'EEXIST') { + callback(null) + } else { + callback(error) + } }) } -const getStorageManager = (storageType) => { +const readChromeStorageFile = (storageType, extensionId, cb) => { + const filePath = getChromeStoragePath(storageType, extensionId) + fs.readFile(filePath, 'utf8', (err, data) => { + if (err && err.code === 'ENOENT') { + return cb(null, null) + } + cb(err, data) + }) +} + +const writeChromeStorageFile = (storageType, extensionId, data, cb) => { + const filePath = getChromeStoragePath(storageType, extensionId) + + mkdirp(path.dirname(filePath), err => { + if (err) { /* we just ignore the errors of mkdir or mkdirp */ } + fs.writeFile(filePath, data, cb) + }) +} + +const getStorage = (storageType, extensionId, cb) => { + readChromeStorageFile(storageType, extensionId, (err, data) => { + if (err) throw err + if (!cb) throw new TypeError('No callback provided') + + if (data !== null) { + cb(JSON.parse(data)) + } else { + cb({}) + } + }) +} + +const setStorage = (storageType, extensionId, storage, cb) => { + const json = JSON.stringify(storage) + writeChromeStorageFile(storageType, extensionId, json, err => { + if (err) throw err + if (cb) cb() + }) +} + +const getStorageManager = (storageType, extensionId) => { return { get (keys, callback) { - const storage = getStorage(storageType) - if (keys == null) return scheduleCallback(storage, callback) + getStorage(storageType, extensionId, storage => { + if (keys == null) return callback(storage) - let defaults = {} - switch (typeof keys) { - case 'string': - keys = [keys] - break - case 'object': - if (!Array.isArray(keys)) { - defaults = keys - keys = Object.keys(keys) - } - break - } - if (keys.length === 0) return scheduleCallback({}, callback) + let defaults = {} + switch (typeof keys) { + case 'string': + keys = [keys] + break + case 'object': + if (!Array.isArray(keys)) { + defaults = keys + keys = Object.keys(keys) + } + break + } + if (keys.length === 0) return callback({}) - let items = {} - keys.forEach(function (key) { - var value = storage[key] - if (value == null) value = defaults[key] - items[key] = value + let items = {} + keys.forEach(function (key) { + var value = storage[key] + if (value == null) value = defaults[key] + items[key] = value + }) + callback(items) }) - scheduleCallback(items, callback) }, set (items, callback) { - const storage = getStorage(storageType) + getStorage(storageType, extensionId, storage => { + Object.keys(items).forEach(function (name) { + storage[name] = items[name] + }) - Object.keys(items).forEach(function (name) { - storage[name] = items[name] + setStorage(storageType, extensionId, storage, callback) }) - - setStorage(storageType, storage) - - setTimeout(callback) }, remove (keys, callback) { - const storage = getStorage(storageType) + getStorage(storageType, extensionId, storage => { + if (!Array.isArray(keys)) { + keys = [keys] + } + keys.forEach(function (key) { + delete storage[key] + }) - if (!Array.isArray(keys)) { - keys = [keys] - } - keys.forEach(function (key) { - delete storage[key] + setStorage(storageType, extensionId, storage, callback) }) - - setStorage(storageType, storage) - - setTimeout(callback) }, clear (callback) { - setStorage(storageType, {}) - - setTimeout(callback) + setStorage(storageType, extensionId, {}, callback) } } } module.exports = { - sync: getStorageManager('sync'), - local: getStorageManager('local') + setup: extensionId => ({ + sync: getStorageManager('sync', extensionId), + local: getStorageManager('local', extensionId) + }) } diff --git a/lib/renderer/window-setup.js b/lib/renderer/window-setup.js index 31767a290d4..b94eace5aec 100644 --- a/lib/renderer/window-setup.js +++ b/lib/renderer/window-setup.js @@ -127,6 +127,10 @@ module.exports = (ipcRenderer, guestInstanceId, openerId, hiddenPage, usesNative return null } } + + if (openerId != null) { + window.opener = getOrCreateProxy(ipcRenderer, openerId) + } } window.alert = function (message, title) { @@ -142,10 +146,6 @@ module.exports = (ipcRenderer, guestInstanceId, openerId, hiddenPage, usesNative throw new Error('prompt() is and will not be supported.') } - if (openerId != null) { - window.opener = getOrCreateProxy(ipcRenderer, openerId) - } - ipcRenderer.on('ELECTRON_GUEST_WINDOW_POSTMESSAGE', function (event, sourceId, message, sourceOrigin) { // Manually dispatch event instead of using postMessage because we also need to // set event.source. diff --git a/package.json b/package.json index c3a4547881e..f0fd42c5485 100644 --- a/package.json +++ b/package.json @@ -1,16 +1,18 @@ { "name": "electron", - "version": "1.7.4", + "version": "1.7.5", "repository": "https://github.com/electron/electron", "description": "Build cross platform desktop apps with JavaScript, HTML, and CSS", "devDependencies": { "asar": "^0.11.0", "browserify": "^13.1.0", + "check-for-leaks": "^1.0.2", "dotenv-safe": "^4.0.4", "electabul": "~0.0.4", "electron-docs-linter": "^2.3.3", "electron-typescript-definitions": "^1.2.7", "github": "^9.2.0", + "husky": "^0.14.3", "request": "^2.68.0", "standard": "^8.4.0", "standard-markdown": "^4.0.0", @@ -47,6 +49,8 @@ "create-typescript-definitions": "npm run create-api-json && electron-typescript-definitions --in=out/electron-api.json --out=out/electron.d.ts", "preinstall": "node -e 'process.exit(0)'", "publish-to-npm": "node ./script/publish-to-npm.js", + "prepack": "check-for-leaks", + "prepush": "check-for-leaks", "release": "./script/upload.py -p", "repl": "python ./script/start.py --interactive", "start": "python ./script/start.py", diff --git a/script/update-external-binaries.py b/script/update-external-binaries.py index 9754399433f..94cdb4e9ce6 100755 --- a/script/update-external-binaries.py +++ b/script/update-external-binaries.py @@ -8,7 +8,7 @@ from lib.config import get_target_arch from lib.util import safe_mkdir, rm_rf, extract_zip, tempdir, download -VERSION = 'v1.2.0' +VERSION = 'v1.2.1' SOURCE_ROOT = os.path.abspath(os.path.dirname(os.path.dirname(__file__))) FRAMEWORKS_URL = 'http://github.com/electron/electron-frameworks/releases' \ '/download/' + VERSION diff --git a/spec/api-app-spec.js b/spec/api-app-spec.js index 8932ac87faa..1df816807dd 100644 --- a/spec/api-app-spec.js +++ b/spec/api-app-spec.js @@ -641,10 +641,21 @@ describe('app module', function () { assert.equal(argv.noSandbox.includes('--enable-sandbox'), false) assert.equal(argv.noSandbox.includes('--no-sandbox'), true) + assert.equal(argv.noSandboxDevtools, true) + assert.equal(argv.sandboxDevtools, true) + done() }) }) }) }) }) + + describe('disableDomainBlockingFor3DAPIs() API', function () { + it('throws when called after app is ready', function () { + assert.throws(function () { + app.disableDomainBlockingFor3DAPIs() + }, /before app is ready/) + }) + }) }) diff --git a/spec/api-browser-window-spec.js b/spec/api-browser-window-spec.js index a7c153235c8..d378850d88e 100644 --- a/spec/api-browser-window-spec.js +++ b/spec/api-browser-window-spec.js @@ -615,6 +615,22 @@ describe('BrowserWindow module', function () { }) }) + describe('BrowserWindow.alwaysOnTop() resets level on minimize', function () { + if (process.platform !== 'darwin') { + return + } + + it('resets the windows level on minimize', function () { + assert.equal(w.isAlwaysOnTop(), false) + w.setAlwaysOnTop(true, 'screen-saver') + assert.equal(w.isAlwaysOnTop(), true) + w.minimize() + assert.equal(w.isAlwaysOnTop(), false) + w.restore() + assert.equal(w.isAlwaysOnTop(), true) + }) + }) + describe('BrowserWindow.setAutoHideCursor(autoHide)', () => { if (process.platform !== 'darwin') { it('is not available on non-macOS platforms', () => { @@ -989,6 +1005,7 @@ describe('BrowserWindow module', function () { preload: preload } }) + ipcRenderer.send('set-web-preferences-on-next-new-window', w.webContents.id, 'preload', preload) let htmlPath = path.join(fixtures, 'api', 'sandbox.html?window-open') const pageUrl = 'file://' + htmlPath w.loadURL(pageUrl) @@ -1019,6 +1036,7 @@ describe('BrowserWindow module', function () { preload: preload } }) + ipcRenderer.send('set-web-preferences-on-next-new-window', w.webContents.id, 'preload', preload) let htmlPath = path.join(fixtures, 'api', 'sandbox.html?window-open-external') const pageUrl = 'file://' + htmlPath let popupWindow @@ -1050,6 +1068,43 @@ describe('BrowserWindow module', function () { }) }) + it('should inherit the sandbox setting in opened windows', function (done) { + w.destroy() + w = new BrowserWindow({ + show: false, + webPreferences: { + sandbox: true + } + }) + + const preloadPath = path.join(fixtures, 'api', 'new-window-preload.js') + ipcRenderer.send('set-web-preferences-on-next-new-window', w.webContents.id, 'preload', preloadPath) + ipcMain.once('answer', (event, args) => { + assert.equal(args.includes('--enable-sandbox'), true) + done() + }) + w.loadURL(`file://${path.join(fixtures, 'api', 'new-window.html')}`) + }) + + it('should open windows with the options configured via new-window event listeners', function (done) { + w.destroy() + w = new BrowserWindow({ + show: false, + webPreferences: { + sandbox: true + } + }) + + const preloadPath = path.join(fixtures, 'api', 'new-window-preload.js') + ipcRenderer.send('set-web-preferences-on-next-new-window', w.webContents.id, 'preload', preloadPath) + ipcRenderer.send('set-web-preferences-on-next-new-window', w.webContents.id, 'foo', 'bar') + ipcMain.once('answer', (event, args, webPreferences) => { + assert.equal(webPreferences.foo, 'bar') + done() + }) + w.loadURL(`file://${path.join(fixtures, 'api', 'new-window.html')}`) + }) + it('should set ipc event sender correctly', function (done) { w.destroy() w = new BrowserWindow({ @@ -1310,6 +1365,68 @@ describe('BrowserWindow module', function () { }) w.loadURL('file://' + path.join(fixtures, 'api', 'native-window-open-native-addon.html')) }) + + it('should inherit the nativeWindowOpen setting in opened windows', function (done) { + w.destroy() + w = new BrowserWindow({ + show: false, + webPreferences: { + nativeWindowOpen: true + } + }) + + const preloadPath = path.join(fixtures, 'api', 'new-window-preload.js') + ipcRenderer.send('set-web-preferences-on-next-new-window', w.webContents.id, 'preload', preloadPath) + ipcMain.once('answer', (event, args) => { + assert.equal(args.includes('--native-window-open'), true) + done() + }) + w.loadURL(`file://${path.join(fixtures, 'api', 'new-window.html')}`) + }) + + it('should open windows with the options configured via new-window event listeners', function (done) { + w.destroy() + w = new BrowserWindow({ + show: false, + webPreferences: { + nativeWindowOpen: true + } + }) + + const preloadPath = path.join(fixtures, 'api', 'new-window-preload.js') + ipcRenderer.send('set-web-preferences-on-next-new-window', w.webContents.id, 'preload', preloadPath) + ipcRenderer.send('set-web-preferences-on-next-new-window', w.webContents.id, 'foo', 'bar') + ipcMain.once('answer', (event, args, webPreferences) => { + assert.equal(webPreferences.foo, 'bar') + done() + }) + w.loadURL(`file://${path.join(fixtures, 'api', 'new-window.html')}`) + }) + + it('retains the original web preferences when window.location is changed to a new origin', async function () { + await serveFileFromProtocol('foo', path.join(fixtures, 'api', 'window-open-location-change.html')) + await serveFileFromProtocol('bar', path.join(fixtures, 'api', 'window-open-location-final.html')) + + w.destroy() + w = new BrowserWindow({ + show: true, + webPreferences: { + nodeIntegration: false, + nativeWindowOpen: true + } + }) + + return new Promise((resolve, reject) => { + ipcRenderer.send('set-web-preferences-on-next-new-window', w.webContents.id, 'preload', path.join(fixtures, 'api', 'window-open-preload.js')) + ipcMain.once('answer', (event, args, typeofProcess) => { + assert.equal(args.includes('--node-integration=false'), true) + assert.equal(args.includes('--native-window-open'), true) + assert.equal(typeofProcess, 'undefined') + resolve() + }) + w.loadURL(`file://${path.join(fixtures, 'api', 'window-open-location-open.html')}`) + }) + }) }) }) @@ -2690,3 +2807,20 @@ const isScaleFactorRounding = () => { // Return true if scale factor is odd number above 2 return scaleFactor > 2 && scaleFactor % 2 === 1 } + +function serveFileFromProtocol (protocolName, filePath) { + return new Promise((resolve, reject) => { + protocol.registerBufferProtocol(protocolName, (request, callback) => { + callback({ + mimeType: 'text/html', + data: fs.readFileSync(filePath) + }) + }, (error) => { + if (error != null) { + reject(error) + } else { + resolve() + } + }) + }) +} diff --git a/spec/chromium-spec.js b/spec/chromium-spec.js index e4a9f04d78e..2f9f2b2795a 100644 --- a/spec/chromium-spec.js +++ b/spec/chromium-spec.js @@ -982,6 +982,15 @@ describe('chromium feature', function () { protocol: 'file', slashes: true }) + const pdfSourceWithParams = url.format({ + pathname: path.join(fixtures, 'assets', 'cat.pdf').replace(/\\/g, '/'), + query: { + a: 1, + b: 2 + }, + protocol: 'file', + slashes: true + }) function createBrowserWindow ({plugins}) { w = new BrowserWindow({ @@ -1009,6 +1018,24 @@ describe('chromium feature', function () { w.webContents.loadURL(pdfSource) }) + it('opens a pdf link given params, the query string should be escaped', function (done) { + createBrowserWindow({plugins: true}) + ipcMain.once('pdf-loaded', function (event, state) { + assert.equal(state, 'success') + done() + }) + w.webContents.on('page-title-updated', function () { + const parsedURL = url.parse(w.webContents.getURL(), true) + assert.equal(parsedURL.protocol, 'chrome:') + assert.equal(parsedURL.hostname, 'pdf-viewer') + assert.equal(parsedURL.query.src, pdfSourceWithParams) + assert.equal(parsedURL.query.b, undefined) + assert.equal(parsedURL.search, `?src=${pdfSource}%3Fa%3D1%26b%3D2`) + assert.equal(w.webContents.getTitle(), 'cat.pdf') + }) + w.webContents.loadURL(pdfSourceWithParams) + }) + it('should download a pdf when plugins are disabled', function (done) { createBrowserWindow({plugins: false}) ipcRenderer.sendSync('set-download-option', false, false) diff --git a/spec/fixtures/api/mixed-sandbox-app/main.js b/spec/fixtures/api/mixed-sandbox-app/main.js index a71c593f513..19b69e0189b 100644 --- a/spec/fixtures/api/mixed-sandbox-app/main.js +++ b/spec/fixtures/api/mixed-sandbox-app/main.js @@ -34,13 +34,16 @@ app.once('ready', () => { const argv = { sandbox: null, - noSandbox: null + noSandbox: null, + sandboxDevtools: null, + noSandboxDevtools: null } let connected = false function finish () { - if (connected && argv.sandbox != null && argv.noSandbox != null) { + if (connected && argv.sandbox != null && argv.noSandbox != null && + argv.noSandboxDevtools != null && argv.sandboxDevtools != null) { client.once('end', () => { app.exit(0) }) @@ -54,6 +57,18 @@ app.once('ready', () => { finish() }) + noSandboxWindow.webContents.once('devtools-opened', () => { + argv.noSandboxDevtools = true + finish() + }) + noSandboxWindow.webContents.openDevTools() + + sandboxWindow.webContents.once('devtools-opened', () => { + argv.sandboxDevtools = true + finish() + }) + sandboxWindow.webContents.openDevTools() + ipcMain.on('argv', (event, value) => { if (event.sender === sandboxWindow.webContents) { argv.sandbox = value diff --git a/spec/fixtures/api/native-window-open-native-addon.html b/spec/fixtures/api/native-window-open-native-addon.html index c1f75872ef9..9a3f20468c7 100644 --- a/spec/fixtures/api/native-window-open-native-addon.html +++ b/spec/fixtures/api/native-window-open-native-addon.html @@ -2,8 +2,21 @@ diff --git a/spec/fixtures/api/new-window-preload.js b/spec/fixtures/api/new-window-preload.js new file mode 100644 index 00000000000..0364593734e --- /dev/null +++ b/spec/fixtures/api/new-window-preload.js @@ -0,0 +1,4 @@ +const {ipcRenderer, remote} = require('electron') + +ipcRenderer.send('answer', process.argv, remote.getCurrentWindow().webContents.getWebPreferences()) +window.close() diff --git a/spec/fixtures/api/new-window.html b/spec/fixtures/api/new-window.html new file mode 100644 index 00000000000..96ab169975a --- /dev/null +++ b/spec/fixtures/api/new-window.html @@ -0,0 +1,14 @@ + + + + + + + + + + diff --git a/spec/fixtures/api/window-open-location-change.html b/spec/fixtures/api/window-open-location-change.html new file mode 100644 index 00000000000..fbb87c9f678 --- /dev/null +++ b/spec/fixtures/api/window-open-location-change.html @@ -0,0 +1,15 @@ + + + + + + + + foo + + + diff --git a/spec/fixtures/api/window-open-location-final.html b/spec/fixtures/api/window-open-location-final.html new file mode 100644 index 00000000000..0814c3262c1 --- /dev/null +++ b/spec/fixtures/api/window-open-location-final.html @@ -0,0 +1,10 @@ + + + + + + + + bar + + diff --git a/spec/fixtures/api/window-open-location-open.html b/spec/fixtures/api/window-open-location-open.html new file mode 100644 index 00000000000..95b65652a0a --- /dev/null +++ b/spec/fixtures/api/window-open-location-open.html @@ -0,0 +1,12 @@ + + + + + + + + + + diff --git a/spec/fixtures/api/window-open-preload.js b/spec/fixtures/api/window-open-preload.js new file mode 100644 index 00000000000..09b89285739 --- /dev/null +++ b/spec/fixtures/api/window-open-preload.js @@ -0,0 +1,8 @@ +const {ipcRenderer} = require('electron') + +setImmediate(function () { + if (window.location.toString() === 'bar://page') { + ipcRenderer.send('answer', process.argv, typeof global.process) + window.close() + } +}) diff --git a/spec/static/main.js b/spec/static/main.js index 3d1f7c0a95b..b1af3706543 100644 --- a/spec/static/main.js +++ b/spec/static/main.js @@ -264,6 +264,12 @@ ipcMain.on('prevent-next-new-window', (event, id) => { webContents.fromId(id).once('new-window', event => event.preventDefault()) }) +ipcMain.on('set-web-preferences-on-next-new-window', (event, id, key, value) => { + webContents.fromId(id).once('new-window', (event, url, frameName, disposition, options) => { + options.webPreferences[key] = value + }) +}) + ipcMain.on('prevent-next-will-attach-webview', (event) => { event.sender.once('will-attach-webview', event => event.preventDefault()) }) diff --git a/vendor/libchromiumcontent b/vendor/libchromiumcontent index 8c6594630d5..7a9d4a1c9c2 160000 --- a/vendor/libchromiumcontent +++ b/vendor/libchromiumcontent @@ -1 +1 @@ -Subproject commit 8c6594630d5ea493ceac21dbdd11376377d2e09c +Subproject commit 7a9d4a1c9c265468dd54005f6c1920b2cc2c8ec3