From b42e6583f7f4aeaecaf707365915cc7b9427a1ea Mon Sep 17 00:00:00 2001 From: Felix Rieseberg Date: Fri, 3 Jun 2016 14:30:55 -0700 Subject: [PATCH 001/126] :art: Log a warning if an extension has already been loaded MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit If an extension has already been loaded (for instance because it’s persisted), `addDevToolsExtension` will return nothing, which is confusing. This adds a little `console.warn` to educate people about what’s happening. Closes #5854 --- docs/api/browser-window.md | 6 +++++- lib/browser/chrome-extension.js | 2 ++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/docs/api/browser-window.md b/docs/api/browser-window.md index ecdbece771b70..fc558515fdc40 100644 --- a/docs/api/browser-window.md +++ b/docs/api/browser-window.md @@ -380,7 +380,11 @@ Find a window according to its ID. Adds DevTools extension located at `path`, and returns extension's name. The extension will be remembered so you only need to call this API once, this -API is not for programming use. +API is not for programming use. If you try to add an extension that has already +been loaded, this method will not return and instead log a warning to the +console. + +Method will also not return if the extension's manifest is missing or incomplete. ### `BrowserWindow.removeDevToolsExtension(name)` diff --git a/lib/browser/chrome-extension.js b/lib/browser/chrome-extension.js index 775a31d2d03ec..e480d88f9a9b1 100644 --- a/lib/browser/chrome-extension.js +++ b/lib/browser/chrome-extension.js @@ -38,6 +38,8 @@ const getManifestFromPath = function (srcDirectory) { }) }) return manifest + } else if (manifest && manifest.name) { + console.warn(`Attempted to load extension "${manifest.name}", but extension was already loaded!`) } } From 506bc4db4ce2742dc8c23d6ac9ed3fa7f1aca967 Mon Sep 17 00:00:00 2001 From: sourenaraya Date: Sun, 5 Jun 2016 20:39:10 +1000 Subject: [PATCH 002/126] Fix shared data example since `remote` module unaviable --- docs/faq/electron-faq.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/faq/electron-faq.md b/docs/faq/electron-faq.md index cefc5a54a2c7a..1e96d47c21075 100644 --- a/docs/faq/electron-faq.md +++ b/docs/faq/electron-faq.md @@ -30,7 +30,7 @@ use HTML5 APIs which are already available in browsers. Good candidates are Or you can use the IPC system, which is specific to Electron, to store objects in the main process as a global variable, and then to access them from the -renderers through the `remote` module: +renderers through the `remote` property of `electron` module: ```javascript // In the main process. @@ -41,12 +41,12 @@ global.sharedObject = { ```javascript // In page 1. -require('remote').getGlobal('sharedObject').someProperty = 'new value'; +require('electron').remote.getGlobal('sharedObject').someProperty = 'new value'; ``` ```javascript // In page 2. -console.log(require('remote').getGlobal('sharedObject').someProperty); +console.log(require('electron').remote.getGlobal('sharedObject').someProperty); ``` ## My app's window/tray disappeared after a few minutes. From eb62abcc2346ac0d5d7f589ec49a831ca377baeb Mon Sep 17 00:00:00 2001 From: Felix Rieseberg Date: Sun, 5 Jun 2016 18:30:49 -0700 Subject: [PATCH 003/126] :art: Log a warning if an extension's manifest cannot be parsed Also logs a clean warning if an extension's manifest is incomplete, missing, or can otherwise not be parsed. --- lib/browser/chrome-extension.js | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/lib/browser/chrome-extension.js b/lib/browser/chrome-extension.js index e480d88f9a9b1..05368f9541df0 100644 --- a/lib/browser/chrome-extension.js +++ b/lib/browser/chrome-extension.js @@ -20,7 +20,15 @@ const generateExtensionIdFromName = function (name) { // Create or get manifest object from |srcDirectory|. const getManifestFromPath = function (srcDirectory) { - const manifest = JSON.parse(fs.readFileSync(path.join(srcDirectory, 'manifest.json'))) + let manifest + + try { + manifest = JSON.parse(fs.readFileSync(path.join(srcDirectory, 'manifest.json'))) + } catch (err) { + console.warn(`Attempted to load extension from ${srcDirectory}, but parsing the manifest failed.`) + console.warn('Error encountered:', err) + } + if (!manifestNameMap[manifest.name]) { const extensionId = generateExtensionIdFromName(manifest.name) console.log(extensionId) From bd1eae86a1acd3d6946314dd46e55c07123ae2aa Mon Sep 17 00:00:00 2001 From: Daniel Pham Date: Sat, 4 Jun 2016 11:23:35 -0400 Subject: [PATCH 004/126] Add 'delete' and 'pasteandmatchstyle' roles --- atom/browser/ui/cocoa/atom_menu_controller.mm | 2 +- docs/api/menu-item.md | 2 ++ lib/browser/api/menu-item.js | 1 + 3 files changed, 4 insertions(+), 1 deletion(-) diff --git a/atom/browser/ui/cocoa/atom_menu_controller.mm b/atom/browser/ui/cocoa/atom_menu_controller.mm index 24098914b7cbb..642721e6bd35c 100644 --- a/atom/browser/ui/cocoa/atom_menu_controller.mm +++ b/atom/browser/ui/cocoa/atom_menu_controller.mm @@ -33,7 +33,7 @@ { @selector(copy:), "copy" }, { @selector(paste:), "paste" }, { @selector(delete:), "delete" }, - { @selector(pasteAndMatchStyle:), "paste-and-match-style" }, + { @selector(pasteAndMatchStyle:), "pasteandmatchstyle" }, { @selector(selectAll:), "selectall" }, { @selector(performMiniaturize:), "minimize" }, { @selector(performClose:), "close" }, diff --git a/docs/api/menu-item.md b/docs/api/menu-item.md index b67032271e61d..c12b14cc0bc50 100644 --- a/docs/api/menu-item.md +++ b/docs/api/menu-item.md @@ -46,7 +46,9 @@ The `role` property can have following values: * `cut` * `copy` * `paste` +* `pasteandmatchstyle` * `selectall` +* `delete` * `minimize` - Minimize current window * `close` - Close current window diff --git a/lib/browser/api/menu-item.js b/lib/browser/api/menu-item.js index f50e0ed84e522..4d2737d0fa981 100644 --- a/lib/browser/api/menu-item.js +++ b/lib/browser/api/menu-item.js @@ -11,6 +11,7 @@ rolesMap = { cut: 'cut', copy: 'copy', paste: 'paste', + pasteandmatchstyle: 'pasteAndMatchStyle', selectall: 'selectAll', minimize: 'minimize', close: 'close', From 8cca8d66e31e3fcd55d66f161bf5ecb3c22e85c8 Mon Sep 17 00:00:00 2001 From: sethlu Date: Mon, 6 Jun 2016 09:51:48 +0800 Subject: [PATCH 005/126] Update Chinese translation --- .../mac-app-store-submission-guide.md | 103 +++++++++++------- 1 file changed, 61 insertions(+), 42 deletions(-) diff --git a/docs-translations/zh-CN/tutorial/mac-app-store-submission-guide.md b/docs-translations/zh-CN/tutorial/mac-app-store-submission-guide.md index e7c7af817aa9b..bf326169fb724 100644 --- a/docs-translations/zh-CN/tutorial/mac-app-store-submission-guide.md +++ b/docs-translations/zh-CN/tutorial/mac-app-store-submission-guide.md @@ -1,26 +1,36 @@ # Mac App Store 应用提交向导 -自从 v0.34.0, Electron 就允许提交应用包到 Mac App Store -(MAS) . 这个向导提供的信息有 : 如何提交应用和 MAS 构建的限制. +自从 v0.34.0,Electron 就允许提交应用包到 Mac App Store +(MAS)。这个向导提供的信息有: 如何提交应用和 MAS 构建的限制。 -__注意:__ 从 v0.36.0,当应用成为沙箱之后,会有一个 bug 阻止 GPU 进程开启 , 所以在这个 bug 修复之前,建议使用 v0.35.x .更多查看 [issue #3871][issue-3871] . - -__注意:__ 提交应用到 Mac App Store 需要参加 [Apple Developer -Program][developer-program] , 这需要花钱. +__注意:__ 提交应用到 Mac App Store 需要参加 [Apple Developer +Program][developer-program],这需要额外花费。 ## 如何提交 -下面步骤介绍了一个简单的提交应用到商店方法.然而,这些步骤不能保证你的应用被 Apple 接受;你仍然需要阅读 Apple 的 [Submitting Your App][submitting-your-app] 关于如何满足 Mac App Store 要求的向导. +下面步骤介绍了一个简单的提交应用到商店方法。然而,这些步骤不能保证你的应用被 Apple 接受;你仍然需要阅读 Apple 的 [Submitting Your App][submitting-your-app] 关于如何满足 Mac App Store 要求的向导。 ### 获得证书 -为了提交应用到商店,首先需要从 Apple 获得一个证书.可以遵循 [existing guides][nwjs-guide]. +为了提交应用到商店,首先需要从 Apple 获得一个证书。可以遵循 [现有向导][nwjs-guide]。 -### App 签名 +### 软件签名 -获得证书之后,你可以使用 [Application Distribution](application-distribution.md) 打包你的应用, 然后前往提交你的应用.这个步骤基本上和其他程序一样,但是这 key 一个个的标识 Electron 的每个依赖. +获得证书之后,你可以使用 [应用部署](application-distribution.md) 打包你的应用,之后进行提交。 -首先,你需要准备2个授权文件 . +首先,你需要在软件包内的 `Info.plist` 中增添一项 `ElectronTeamID`: + +```xml + + + ... + ElectronTeamID + TEAM_ID + + +``` + +之后,你需要准备2个授权文件。 `child.plist`: @@ -46,67 +56,76 @@ Program][developer-program] , 这需要花钱. com.apple.security.app-sandbox + com.apple.security.application-groups + TEAM_ID.your.bundle.id ``` -然后使用下面的脚本标识你的应用 : +请注意上述 `TEAM_ID` 对应开发者账户的 Team ID,`your.bundle.id` 对应软件打包时使用的 Bundle ID。 + +然后使用下面的脚本签名你的应用: ```bash #!/bin/bash -# Name of your app. +# 应用名称 APP="YourApp" -# The path of you app to sign. -APP_PATH="/path/to/YouApp.app" -# The path to the location you want to put the signed package. +# 应用路径 +APP_PATH="/path/to/YourApp.app" +# 生成安装包路径 RESULT_PATH="~/Desktop/$APP.pkg" -# The name of certificates you requested. +# 开发者应用签名证书 APP_KEY="3rd Party Mac Developer Application: Company Name (APPIDENTITY)" INSTALLER_KEY="3rd Party Mac Developer Installer: Company Name (APPIDENTITY)" +# 授权文件路径 +CHILD_PLIST="/path/to/child.plist" +PARENT_PLIST="/path/to/parent.plist" FRAMEWORKS_PATH="$APP_PATH/Contents/Frameworks" -codesign --deep -fs "$APP_KEY" --entitlements child.plist "$FRAMEWORKS_PATH/Electron Framework.framework/Versions/A" -codesign --deep -fs "$APP_KEY" --entitlements child.plist "$FRAMEWORKS_PATH/$APP Helper.app/" -codesign --deep -fs "$APP_KEY" --entitlements child.plist "$FRAMEWORKS_PATH/$APP Helper EH.app/" -codesign --deep -fs "$APP_KEY" --entitlements child.plist "$FRAMEWORKS_PATH/$APP Helper NP.app/" -if [ -d "$FRAMEWORKS_PATH/Squirrel.framework/Versions/A" ]; then - # Signing a non-MAS build. - codesign --deep -fs "$APP_KEY" --entitlements child.plist "$FRAMEWORKS_PATH/Mantle.framework/Versions/A" - codesign --deep -fs "$APP_KEY" --entitlements child.plist "$FRAMEWORKS_PATH/ReactiveCocoa.framework/Versions/A" - codesign --deep -fs "$APP_KEY" --entitlements child.plist "$FRAMEWORKS_PATH/Squirrel.framework/Versions/A" -fi -codesign -fs "$APP_KEY" --entitlements parent.plist "$APP_PATH" +codesign -s "$APP_KEY" -f --entitlements "$CHILD_PLIST" "$FRAMEWORKS_PATH/Electron Framework.framework/Versions/A/Electron Framework" +codesign -s "$APP_KEY" -f --entitlements "$CHILD_PLIST" "$FRAMEWORKS_PATH/Electron Framework.framework/Versions/A/Libraries/libffmpeg.dylib" +codesign -s "$APP_KEY" -f --entitlements "$CHILD_PLIST" "$FRAMEWORKS_PATH/Electron Framework.framework/Versions/A/Libraries/libnode.dylib" +codesign -s "$APP_KEY" -f --entitlements "$CHILD_PLIST" "$FRAMEWORKS_PATH/Electron Framework.framework" +codesign -s "$APP_KEY" -f --entitlements "$CHILD_PLIST" "$FRAMEWORKS_PATH/$APP Helper.app/Contents/MacOS/$APP Helper" +codesign -s "$APP_KEY" -f --entitlements "$CHILD_PLIST" "$FRAMEWORKS_PATH/$APP Helper.app/" +codesign -s "$APP_KEY" -f --entitlements "$CHILD_PLIST" "$FRAMEWORKS_PATH/$APP Helper EH.app/Contents/MacOS/$APP Helper EH" +codesign -s "$APP_KEY" -f --entitlements "$CHILD_PLIST" "$FRAMEWORKS_PATH/$APP Helper EH.app/" +codesign -s "$APP_KEY" -f --entitlements "$CHILD_PLIST" "$FRAMEWORKS_PATH/$APP Helper NP.app/Contents/MacOS/$APP Helper NP" +codesign -s "$APP_KEY" -f --entitlements "$CHILD_PLIST" "$FRAMEWORKS_PATH/$APP Helper NP.app/" +codesign -s "$APP_KEY" -f --entitlements "$CHILD_PLIST" "$APP_PATH/Contents/MacOS/$APP" +codesign -s "$APP_KEY" -f --entitlements "$PARENT_PLIST" "$APP_PATH" productbuild --component "$APP_PATH" /Applications --sign "$INSTALLER_KEY" "$RESULT_PATH" ``` -如果你是 OS X 下的应用沙箱使用新手,应当仔细阅读 Apple 的 [Enabling App Sandbox][enable-app-sandbox] 来有一点基础,然后向授权文件添加你的应用需要的许可 keys . -### 上传你的应用并检查提交 +如果你是 OS X 下的应用沙箱使用新手,应当仔细阅读 Apple 的 [Enabling App Sandbox][enable-app-sandbox] 了解一些基础,然后在授权文件 (entitlements files) 内添加你的应用需要的许可。 + +### 上传你的应用并检查提交 -在签名应用之后,可以使用应用 Loader 来上传到 iTunes 链接处理 , 确保在上传之前你已经 [created a record][create-record]. 然后你能 [submit your app for review][submit-for-review]. +在签名应用之后,你可以使用 Application Loader 上传软件到 iTunes Connect 进行处理。请确保在上传之前你已经 [创建应用记录][create-record],再 [提交进行审核][submit-for-review]。 -## MAS构建限制 +## MAS 构建限制 -为了让你的应用沙箱满足所有条件,在 MAS 构建的时候,下面的模块被禁用了 : +为了让你的应用满足沙箱的所有条件,在 MAS 构建的时候,下面的模块已被禁用: * `crashReporter` * `autoUpdater` 并且下面的行为也改变了: -* 一些机子的视频采集功能无效. -* 某些特征不可访问. -* Apps 不可识别 DNS 改变. +* 一些视频采集功能无效。 +* 某些辅助功能无法访问。 +* 应用无法检测 DNS 变化。 -也由于应用沙箱的使用方法,应用可以访问的资源被严格限制了 ; 阅读更多信息 [App Sandboxing][app-sandboxing] . +也由于应用沙箱的使用方法,应用可以访问的资源被严格限制了;阅读更多信息 [App Sandboxing][app-sandboxing]。 ## Electron 使用的加密算法 -取决于你所在地方的国家和地区 , Mac App Store 或许需要记录你应用的加密算法 , 甚至要求你提交一个 U.S 加密注册(ERN) 许可的复印件. +取决于你所在地方的国家和地区,Mac App Store 或许需要记录你应用的加密算法,甚至要求你提交一个 U.S. 加密注册 (ERN) 许可的复印件。 -Electron 使用下列加密算法: +Electron 使用下列加密算法: * AES - [NIST SP 800-38A](http://csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf), [NIST SP 800-38D](http://csrc.nist.gov/publications/nistpubs/800-38D/SP-800-38D.pdf), [RFC 3394](http://www.ietf.org/rfc/rfc3394.txt) * HMAC - [FIPS 198-1](http://csrc.nist.gov/publications/fips/fips198-1/FIPS-198-1_final.pdf) @@ -132,9 +151,9 @@ Electron 使用下列加密算法: * RC5 - http://people.csail.mit.edu/rivest/Rivest-rc5rev.pdf * RIPEMD - [ISO/IEC 10118-3](http://webstore.ansi.org/RecordDetail.aspx?sku=ISO%2FIEC%2010118-3:2004) -如何获取 ERN 许可, 可看这篇文章: [How to legally +如何获取 ERN 许可, 可看这篇文章:[How to legally submit an app to Apple’s App Store when it uses encryption (or how to obtain an -ERN)][ern-tutorial]. +ERN)][ern-tutorial]。 [developer-program]: https://developer.apple.com/support/compare-memberships/ [submitting-your-app]: https://developer.apple.com/library/mac/documentation/IDEs/Conceptual/AppDistributionGuide/SubmittingYourApp/SubmittingYourApp.html @@ -144,4 +163,4 @@ ERN)][ern-tutorial]. [submit-for-review]: https://developer.apple.com/library/ios/documentation/LanguagesUtilities/Conceptual/iTunesConnect_Guide/Chapters/SubmittingTheApp.html [app-sandboxing]: https://developer.apple.com/app-sandboxing/ [issue-3871]: https://github.com/electron/electron/issues/3871 -[ern-tutorial]: https://carouselapps.com/2015/12/15/legally-submit-app-apples-app-store-uses-encryption-obtain-ern/ \ No newline at end of file +[ern-tutorial]: https://carouselapps.com/2015/12/15/legally-submit-app-apples-app-store-uses-encryption-obtain-ern/ From adec511891bdfd7e4f5323c1076779a0cf4db0d6 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Mon, 6 Jun 2016 15:22:01 +0900 Subject: [PATCH 006/126] Update to Chrome 51.0.2704.79 --- atom/common/chrome_version.h | 2 +- script/lib/config.py | 2 +- vendor/brightray | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/atom/common/chrome_version.h b/atom/common/chrome_version.h index f84f6ac15516e..4f4a46bc8b676 100644 --- a/atom/common/chrome_version.h +++ b/atom/common/chrome_version.h @@ -8,7 +8,7 @@ #ifndef ATOM_COMMON_CHROME_VERSION_H_ #define ATOM_COMMON_CHROME_VERSION_H_ -#define CHROME_VERSION_STRING "51.0.2704.63" +#define CHROME_VERSION_STRING "51.0.2704.79" #define CHROME_VERSION "v" CHROME_VERSION_STRING #endif // ATOM_COMMON_CHROME_VERSION_H_ diff --git a/script/lib/config.py b/script/lib/config.py index 43423e5143681..63dec7211e146 100644 --- a/script/lib/config.py +++ b/script/lib/config.py @@ -8,7 +8,7 @@ BASE_URL = os.getenv('LIBCHROMIUMCONTENT_MIRROR') or \ 'https://s3.amazonaws.com/github-janky-artifacts/libchromiumcontent' -LIBCHROMIUMCONTENT_COMMIT = '8f2a0aa0a9dd107e4d574cc9d552781c55c86bab' +LIBCHROMIUMCONTENT_COMMIT = 'c86ebfb5278e0ec1a8cff1f8eb4da3c6a8cfa8f7' PLATFORM = { 'cygwin': 'win32', diff --git a/vendor/brightray b/vendor/brightray index 9ccab3c9a87cc..1b57d5860be32 160000 --- a/vendor/brightray +++ b/vendor/brightray @@ -1 +1 @@ -Subproject commit 9ccab3c9a87cc57b4a37c4a03e17b589ac81d6ae +Subproject commit 1b57d5860be3271d5e2a14b3a3b8027b04b30bcb From 32b692b60c36dbfe145d649417ca6939af79187a Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Mon, 6 Jun 2016 16:53:32 +0900 Subject: [PATCH 007/126] Fix NativeWindow::Focus not moving focus to window Chromium's implementation is somehow not working as expected, the new implementation follows the behavior of wmctrl. --- atom/browser/native_window_views.cc | 28 ++++++++++++++++++++++++++-- 1 file changed, 26 insertions(+), 2 deletions(-) diff --git a/atom/browser/native_window_views.cc b/atom/browser/native_window_views.cc index e699892d4ac59..6a0919635f3e1 100644 --- a/atom/browser/native_window_views.cc +++ b/atom/browser/native_window_views.cc @@ -89,6 +89,21 @@ bool IsAltModifier(const content::NativeWebKeyboardEvent& event) { (modifiers == (Modifiers::AltKey | Modifiers::IsRight)); } +#if defined(USE_X11) +int SendClientEvent(XDisplay* display, ::Window window, const char* msg) { + XEvent event = {}; + event.xclient.type = ClientMessage; + event.xclient.send_event = True; + event.xclient.message_type = XInternAtom(display, msg, False); + event.xclient.window = window; + event.xclient.format = 32; + XSendEvent(display, DefaultRootWindow(display), False, + SubstructureRedirectMask | SubstructureNotifyMask, &event); + XFlush(display); + return True; +} +#endif + class NativeWindowClientView : public views::ClientView { public: NativeWindowClientView(views::Widget* widget, @@ -298,10 +313,19 @@ void NativeWindowViews::CloseImmediately() { } void NativeWindowViews::Focus(bool focus) { - if (focus) + if (focus) { +#if defined(OS_WIN) window_->Activate(); - else +#elif defined(USE_X11) + // The "Activate" implementation of Chromium is not reliable on Linux. + ::Window window = GetAcceleratedWidget(); + XDisplay* xdisplay = gfx::GetXDisplay(); + SendClientEvent(xdisplay, window, "_NET_ACTIVE_WINDOW"); + XMapRaised(xdisplay, window); +#endif + } else { window_->Deactivate(); + } } bool NativeWindowViews::IsFocused() { From 02cfe30df9fce5e8465d6f502782d7013cabb9ca Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Mon, 6 Jun 2016 20:19:55 +0900 Subject: [PATCH 008/126] Add app.disableHardwareAcceleration() API --- atom/browser/api/atom_api_app.cc | 13 ++++++++++++- atom/browser/api/atom_api_app.h | 2 +- docs/api/app.md | 6 ++++++ 3 files changed, 19 insertions(+), 2 deletions(-) diff --git a/atom/browser/api/atom_api_app.cc b/atom/browser/api/atom_api_app.cc index 5d4aafca69992..87f960a87824b 100644 --- a/atom/browser/api/atom_api_app.cc +++ b/atom/browser/api/atom_api_app.cc @@ -447,6 +447,15 @@ bool App::Relaunch(mate::Arguments* js_args) { return relauncher::RelaunchApp(argv); } +void App::DisableHardwareAcceleration(mate::Arguments* args) { + if (Browser::Get()->is_ready()) { + args->ThrowError("app.disableHardwareAcceleration() can only be called " + "before app is ready"); + return; + } + content::GpuDataManager::GetInstance()->DisableHardwareAcceleration(); +} + #if defined(USE_NSS_CERTS) void App::ImportCertificate( const base::DictionaryValue& options, @@ -528,7 +537,9 @@ void App::BuildPrototype( #endif .SetMethod("makeSingleInstance", &App::MakeSingleInstance) .SetMethod("releaseSingleInstance", &App::ReleaseSingleInstance) - .SetMethod("relaunch", &App::Relaunch); + .SetMethod("relaunch", &App::Relaunch) + .SetMethod("disableHardwareAcceleration", + &App::DisableHardwareAcceleration); } } // namespace api diff --git a/atom/browser/api/atom_api_app.h b/atom/browser/api/atom_api_app.h index e2bcb4583dda0..ba274deb9ccdc 100644 --- a/atom/browser/api/atom_api_app.h +++ b/atom/browser/api/atom_api_app.h @@ -111,7 +111,7 @@ class App : public AtomBrowserClient::Delegate, const ProcessSingleton::NotificationCallback& callback); void ReleaseSingleInstance(); bool Relaunch(mate::Arguments* args); - + void DisableHardwareAcceleration(mate::Arguments* args); #if defined(USE_NSS_CERTS) void ImportCertificate(const base::DictionaryValue& options, const net::CompletionCallback& callback); diff --git a/docs/api/app.md b/docs/api/app.md index becd6039c757e..1f72dba2ca0ba 100644 --- a/docs/api/app.md +++ b/docs/api/app.md @@ -561,6 +561,12 @@ Imports the certificate in pkcs12 format into the platform certificate store. `callback` is called with the `result` of import operation, a value of `0` indicates success while any other value indicates failure according to chromium [net_error_list](https://code.google.com/p/chromium/codesearch#chromium/src/net/base/net_error_list.h). +### `app.disableHardwareAcceleration()` + +Disables hardware acceleration for current app. + +This method can only be called before app is ready. + ### `app.commandLine.appendSwitch(switch[, value])` Append a switch (with optional `value`) to Chromium's command line. From 3edde9143ba2964f0b44d9fd057eeea0d4e5764e Mon Sep 17 00:00:00 2001 From: jpittner Date: Mon, 6 Jun 2016 13:46:34 +0200 Subject: [PATCH 009/126] Update using-native-node-modules.md Explains how native modules to be signed and packaged. --- docs/tutorial/using-native-node-modules.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/docs/tutorial/using-native-node-modules.md b/docs/tutorial/using-native-node-modules.md index f73c1cde1f022..82c9009c92218 100644 --- a/docs/tutorial/using-native-node-modules.md +++ b/docs/tutorial/using-native-node-modules.md @@ -65,3 +65,8 @@ The `HOME=~/.electron-gyp` changes where to find development headers. The `--target=0.29.1` is version of Electron. The `--dist-url=...` specifies where to download the headers. The `--arch=x64` says the module is built for 64bit system. + +### Packaging and signing apps with native modules + +Native modules need to be signed. If using electron-osx-sign, be sure to include the path to the built binaries in the argument list (eg electron-osx-sign yourapp/YourApp.app yourapp/YourApp.app/Contents/Resources/app/node_modules/nativemodule/build/release/nativemodule). Also note that native modules may have intermediate files produced which should not be included (as they would also need to be signed). Add --ignore=.+\.o$ to your electron-packager build step to ignore these files (their unsigned inclusion will result in the ITMS-90135 error). + From a906336b1e2af4936655513d20908ecde248083b Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Mon, 6 Jun 2016 13:03:01 -0700 Subject: [PATCH 010/126] Don't log extension id --- lib/browser/chrome-extension.js | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/browser/chrome-extension.js b/lib/browser/chrome-extension.js index 05368f9541df0..d3c76ce797be6 100644 --- a/lib/browser/chrome-extension.js +++ b/lib/browser/chrome-extension.js @@ -31,7 +31,6 @@ const getManifestFromPath = function (srcDirectory) { if (!manifestNameMap[manifest.name]) { const extensionId = generateExtensionIdFromName(manifest.name) - console.log(extensionId) manifestMap[extensionId] = manifestNameMap[manifest.name] = manifest Object.assign(manifest, { srcDirectory: srcDirectory, From d6311daea3f304f188f53dc33ccfbcbd2934c138 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Mon, 6 Jun 2016 14:36:01 -0700 Subject: [PATCH 011/126] Add failing spec for chrome.runtime.id --- spec/api-browser-window-spec.js | 6 +++--- spec/fixtures/devtools-extensions/foo/index.html | 5 ++++- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/spec/api-browser-window-spec.js b/spec/api-browser-window-spec.js index 8af2fb8265741..11b954d2d07a8 100644 --- a/spec/api-browser-window-spec.js +++ b/spec/api-browser-window-spec.js @@ -863,7 +863,7 @@ describe('browser-window module', function () { w.webContents.openDevTools({mode: 'bottom'}) ipcMain.once('answer', function (event, message) { - assert.equal(message, 'extension loaded') + assert.equal(message.runtimeId, 'foo') done() }) }) @@ -873,8 +873,8 @@ describe('browser-window module', function () { it('creates the extension', function (done) { w.webContents.openDevTools({mode: 'undocked'}) - ipcMain.once('answer', function (event, message) { - assert.equal(message, 'extension loaded') + ipcMain.once('answer', function (event, message, extensionId) { + assert.equal(message.runtimeId, 'foo') done() }) }) diff --git a/spec/fixtures/devtools-extensions/foo/index.html b/spec/fixtures/devtools-extensions/foo/index.html index 4e7439422e47c..1b9d1b8cb9b4a 100644 --- a/spec/fixtures/devtools-extensions/foo/index.html +++ b/spec/fixtures/devtools-extensions/foo/index.html @@ -4,7 +4,10 @@ From 61ce19ba7e293788f9d8a393611aae3f60784714 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Mon, 6 Jun 2016 14:42:07 -0700 Subject: [PATCH 012/126] Set chrome.runtime.id --- lib/renderer/chrome-api.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/renderer/chrome-api.js b/lib/renderer/chrome-api.js index 61fce14c5ba91..17c3f5bfbd1ae 100644 --- a/lib/renderer/chrome-api.js +++ b/lib/renderer/chrome-api.js @@ -99,6 +99,8 @@ exports.injectTo = function (extensionId, isBackgroundPage, context) { }) chrome.runtime = { + id: extensionId, + getURL: function (path) { return url.format({ protocol: 'chrome-extension', From 5fc64aea3886bc8bfaa0c6a3c52478f9b7f4fe8e Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Tue, 7 Jun 2016 10:26:53 +0900 Subject: [PATCH 013/126] docs: Move "Sign Native Modules" to MAS Guide --- .../mac-app-store-submission-guide.md | 20 +++++++++++++++++++ docs/tutorial/using-native-node-modules.md | 5 ----- 2 files changed, 20 insertions(+), 5 deletions(-) diff --git a/docs/tutorial/mac-app-store-submission-guide.md b/docs/tutorial/mac-app-store-submission-guide.md index d240cc13371bb..b2c08e8849f97 100644 --- a/docs/tutorial/mac-app-store-submission-guide.md +++ b/docs/tutorial/mac-app-store-submission-guide.md @@ -120,6 +120,24 @@ If you are new to app sandboxing under OS X, you should also read through Apple's [Enabling App Sandbox][enable-app-sandbox] to have a basic idea, then add keys for the permissions needed by your app to the entitlements files. +Apart from manually signing your app, you can also choose to use the +[electron-osx-sign][electron-osx-sign] module to do the job. + +#### Sign Native Modules + +Native modules used in your app also need to be signed. If using +electron-osx-sign, be sure to include the path to the built binaries in the +argument list: + +```bash +electron-osx-sign YourApp.app YourApp.app/Contents/Resources/app/node_modules/nativemodule/build/release/nativemodule +``` + +Also note that native modules may have intermediate files produced which should +not be included (as they would also need to be signed). If you use +[electron-packager][electron-packager], add `--ignore=.+\.o$` to build step to +ignore these files. + ### Upload Your App After signing your app, you can use Application Loader to upload it to iTunes @@ -189,6 +207,8 @@ ERN)][ern-tutorial]. [nwjs-guide]: https://github.com/nwjs/nw.js/wiki/Mac-App-Store-%28MAS%29-Submission-Guideline#first-steps [enable-app-sandbox]: https://developer.apple.com/library/ios/documentation/Miscellaneous/Reference/EntitlementKeyReference/Chapters/EnablingAppSandbox.html [create-record]: https://developer.apple.com/library/ios/documentation/LanguagesUtilities/Conceptual/iTunesConnect_Guide/Chapters/CreatingiTunesConnectRecord.html +[electron-osx-sign]: https://github.com/electron-userland/electron-osx-sign +[electron-packager]: https://github.com/electron-userland/electron-packager [submit-for-review]: https://developer.apple.com/library/ios/documentation/LanguagesUtilities/Conceptual/iTunesConnect_Guide/Chapters/SubmittingTheApp.html [app-sandboxing]: https://developer.apple.com/app-sandboxing/ [ern-tutorial]: https://carouselapps.com/2015/12/15/legally-submit-app-apples-app-store-uses-encryption-obtain-ern/ diff --git a/docs/tutorial/using-native-node-modules.md b/docs/tutorial/using-native-node-modules.md index 82c9009c92218..f73c1cde1f022 100644 --- a/docs/tutorial/using-native-node-modules.md +++ b/docs/tutorial/using-native-node-modules.md @@ -65,8 +65,3 @@ The `HOME=~/.electron-gyp` changes where to find development headers. The `--target=0.29.1` is version of Electron. The `--dist-url=...` specifies where to download the headers. The `--arch=x64` says the module is built for 64bit system. - -### Packaging and signing apps with native modules - -Native modules need to be signed. If using electron-osx-sign, be sure to include the path to the built binaries in the argument list (eg electron-osx-sign yourapp/YourApp.app yourapp/YourApp.app/Contents/Resources/app/node_modules/nativemodule/build/release/nativemodule). Also note that native modules may have intermediate files produced which should not be included (as they would also need to be signed). Add --ignore=.+\.o$ to your electron-packager build step to ignore these files (their unsigned inclusion will result in the ITMS-90135 error). - From 1a22caabe8f8ce2b34a9e5add2d7c2f207b8082d Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Tue, 7 Jun 2016 13:55:25 +0900 Subject: [PATCH 014/126] docs: Update the code sample of screen module * We should not require it before the ready event; * There is no need to use electronScreen as name in the main process. --- docs/api/screen.md | 32 +++++++++++++++----------------- 1 file changed, 15 insertions(+), 17 deletions(-) diff --git a/docs/api/screen.md b/docs/api/screen.md index 7dd6203316d2f..440c99ac3f039 100644 --- a/docs/api/screen.md +++ b/docs/api/screen.md @@ -9,44 +9,42 @@ emitted (by invoking or requiring it). **Note:** In the renderer / DevTools, `window.screen` is a reserved DOM property, so writing `let {screen} = require('electron')` will not work. -In our examples below, we use `electronScreen` as the variable name instead. + An example of creating a window that fills the whole screen: ```javascript -const {app, BrowserWindow, screen: electronScreen} = require('electron'); +const electron = require('electron') +const {app, BrowserWindow} = electron -let win; +let win app.on('ready', () => { - const {width, height} = electronScreen.getPrimaryDisplay().workAreaSize; - win = new BrowserWindow({width, height}); + const {width, height} = electron.screen.getPrimaryDisplay().workAreaSize + win = new BrowserWindow({width, height}) }); ``` Another example of creating a window in the external display: ```javascript -const {app, BrowserWindow, screen: electronScreen} = require('electron'); +const electron = require('electron') +const {app, BrowserWindow} = require('electron') -let win; +let win app.on('ready', () => { - let displays = electronScreen.getAllDisplays(); - let externalDisplay = null; - for (let i in displays) { - if (displays[i].bounds.x !== 0 || displays[i].bounds.y !== 0) { - externalDisplay = displays[i]; - break; - } - } + let displays = electron.screen.getAllDisplays() + let externalDisplay = displays.find((display) => { + return display.bounds.x !== 0 || display.bounds.y !== 0 + }) if (externalDisplay) { win = new BrowserWindow({ x: externalDisplay.bounds.x + 50, y: externalDisplay.bounds.y + 50 - }); + }) } -}); +}) ``` ## The `Display` object From 3c873736d7014a6f3c07c95552384f55b65b214f Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Tue, 7 Jun 2016 15:56:19 +0900 Subject: [PATCH 015/126] Add update-target-url event --- atom/browser/api/atom_api_web_contents.cc | 5 +++++ atom/browser/api/atom_api_web_contents.h | 1 + docs/api/web-contents.md | 9 +++++++++ docs/api/web-view-tag.md | 8 ++++++++ lib/browser/guest-view-manager.js | 3 ++- lib/renderer/web-view/guest-view-internal.js | 9 +++++---- 6 files changed, 30 insertions(+), 5 deletions(-) diff --git a/atom/browser/api/atom_api_web_contents.cc b/atom/browser/api/atom_api_web_contents.cc index 9d93d980be4a6..c33b9f1d9bd96 100644 --- a/atom/browser/api/atom_api_web_contents.cc +++ b/atom/browser/api/atom_api_web_contents.cc @@ -389,6 +389,11 @@ void WebContents::ActivateContents(content::WebContents* source) { Emit("activate"); } +void WebContents::UpdateTargetURL(content::WebContents* source, + const GURL& url) { + Emit("update-target-url", url); +} + bool WebContents::IsPopupOrPanel(const content::WebContents* source) const { return type_ == BROWSER_WINDOW; } diff --git a/atom/browser/api/atom_api_web_contents.h b/atom/browser/api/atom_api_web_contents.h index 85c43f1486aa0..dfaac8791fb4c 100644 --- a/atom/browser/api/atom_api_web_contents.h +++ b/atom/browser/api/atom_api_web_contents.h @@ -182,6 +182,7 @@ class WebContents : public mate::TrackableObject, const gfx::Rect& pos) override; void CloseContents(content::WebContents* source) override; void ActivateContents(content::WebContents* contents) override; + void UpdateTargetURL(content::WebContents* source, const GURL& url) override; bool IsPopupOrPanel(const content::WebContents* source) const override; void HandleKeyboardEvent( content::WebContents* source, diff --git a/docs/api/web-contents.md b/docs/api/web-contents.md index c3f1f82366c77..b9ff9d7c48638 100644 --- a/docs/api/web-contents.md +++ b/docs/api/web-contents.md @@ -288,6 +288,15 @@ a meta tag: ``` +### Event: 'update-target-url' + +Returns: + +* `event` Event +* `url` String + +Emitted when mouse moves over a link or the keyboard moves the focus to a link. + ### Event: 'cursor-changed' Returns: diff --git a/docs/api/web-view-tag.md b/docs/api/web-view-tag.md index f99bb4fdb5a18..d00f64d4eb53e 100644 --- a/docs/api/web-view-tag.md +++ b/docs/api/web-view-tag.md @@ -782,6 +782,14 @@ Emitted when a page's theme color changes. This is usually due to encountering a ``` +### Event: 'update-target-url' + +Returns: + +* `url` String + +Emitted when mouse moves over a link or the keyboard moves the focus to a link. + ### Event: 'devtools-opened' Emitted when DevTools is opened. diff --git a/lib/browser/guest-view-manager.js b/lib/browser/guest-view-manager.js index 6876a8d22c12e..c5c075b28bb77 100644 --- a/lib/browser/guest-view-manager.js +++ b/lib/browser/guest-view-manager.js @@ -36,7 +36,8 @@ var supportedWebViewEvents = [ 'media-started-playing', 'media-paused', 'found-in-page', - 'did-change-theme-color' + 'did-change-theme-color', + 'update-target-url' ] var nextInstanceId = 0 diff --git a/lib/renderer/web-view/guest-view-internal.js b/lib/renderer/web-view/guest-view-internal.js index 7432444c6da6f..c4741fc1b77ff 100644 --- a/lib/renderer/web-view/guest-view-internal.js +++ b/lib/renderer/web-view/guest-view-internal.js @@ -27,15 +27,16 @@ var WEB_VIEW_EVENTS = { 'crashed': [], 'gpu-crashed': [], 'plugin-crashed': ['name', 'version'], - 'media-started-playing': [], - 'media-paused': [], - 'did-change-theme-color': ['themeColor'], 'destroyed': [], 'page-title-updated': ['title', 'explicitSet'], 'page-favicon-updated': ['favicons'], 'enter-html-full-screen': [], 'leave-html-full-screen': [], - 'found-in-page': ['result'] + 'media-started-playing': [], + 'media-paused': [], + 'found-in-page': ['result'], + 'did-change-theme-color': ['themeColor'], + 'update-target-url': ['url'] } var DEPRECATED_EVENTS = { From b444211d6f96cf9738f5097bd6deb86790de2544 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Tue, 7 Jun 2016 17:26:26 +0900 Subject: [PATCH 016/126] Fix title of frameless window showing as empty under fullscreen --- atom/browser/native_window_mac.h | 3 +++ atom/browser/native_window_mac.mm | 17 +++++++++++++++-- 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/atom/browser/native_window_mac.h b/atom/browser/native_window_mac.h index c1694c3c784ac..52ebcbcb9c51f 100644 --- a/atom/browser/native_window_mac.h +++ b/atom/browser/native_window_mac.h @@ -139,6 +139,9 @@ class NativeWindowMac : public NativeWindow { // The presentation options before entering kiosk mode. NSApplicationPresentationOptions kiosk_options_; + // The window title, for frameless windows we only set title when fullscreen. + std::string title_; + // Force showing the buttons for frameless window. bool force_show_buttons_; diff --git a/atom/browser/native_window_mac.mm b/atom/browser/native_window_mac.mm index 8bc4052f85386..2b88b180694dd 100644 --- a/atom/browser/native_window_mac.mm +++ b/atom/browser/native_window_mac.mm @@ -193,10 +193,16 @@ - (void)windowWillEnterFullScreen:(NSNotification*)notification { - (void)windowDidEnterFullScreen:(NSNotification*)notification { shell_->NotifyWindowEnterFullScreen(); + // For frameless window we don't set title for normal mode since the title + // bar is expected to be empty, but after entering fullscreen mode we have + // to set one, because title bar is visible here. + NSWindow* window = shell_->GetNativeWindow(); + if (shell_->transparent() || !shell_->has_frame()) + [window setTitle:base::SysUTF8ToNSString(shell_->GetTitle())]; + // Restore the native toolbar immediately after entering fullscreen, if we do // this before leaving fullscreen, traffic light buttons will be jumping. if (shell_->should_hide_native_toolbar_in_fullscreen()) { - NSWindow* window = shell_->GetNativeWindow(); base::scoped_nsobject toolbar( [[NSToolbar alloc] initWithIdentifier:@"titlebarStylingToolbar"]); [toolbar setShowsBaselineSeparator:NO]; @@ -209,6 +215,11 @@ - (void)windowDidEnterFullScreen:(NSNotification*)notification { } - (void)windowWillExitFullScreen:(NSNotification*)notification { + // Restore the title bar to empty. + NSWindow* window = shell_->GetNativeWindow(); + if (shell_->transparent() || !shell_->has_frame()) + [window setTitle:@""]; + // Turn off the style for toolbar. if (shell_->should_hide_native_toolbar_in_fullscreen()) shell_->SetStyleMask(false, NSFullSizeContentViewWindowMask); @@ -781,6 +792,8 @@ - (void)drawRect:(NSRect)dirtyRect { } void NativeWindowMac::SetTitle(const std::string& title) { + title_ = title; + // We don't want the title to show in transparent or frameless window. if (transparent() || !has_frame()) return; @@ -789,7 +802,7 @@ - (void)drawRect:(NSRect)dirtyRect { } std::string NativeWindowMac::GetTitle() { - return base::SysNSStringToUTF8([window_ title]); + return title_; } void NativeWindowMac::FlashFrame(bool flash) { From 7e5f9fef52469e832c39311f8226f106b24648a6 Mon Sep 17 00:00:00 2001 From: jf_jiang Date: Tue, 7 Jun 2016 18:52:01 +0900 Subject: [PATCH 017/126] update Quick Start Page[zh-CN] Based on electron ver 1.1.3 update Quick Start Page[Simplified Chinese]. --- .../zh-CN/tutorial/quick-start.md | 122 ++++++++++++------ 1 file changed, 80 insertions(+), 42 deletions(-) diff --git a/docs-translations/zh-CN/tutorial/quick-start.md b/docs-translations/zh-CN/tutorial/quick-start.md index d267d31460515..3156f3dd08d14 100644 --- a/docs-translations/zh-CN/tutorial/quick-start.md +++ b/docs-translations/zh-CN/tutorial/quick-start.md @@ -1,7 +1,6 @@ # 快速入门 -## 简介 -Electron 可以让你使用纯 JavaScript 调用丰富的原生 APIs 来创造桌面应用。你可以把它看作是专注于桌面应用而不是 web 服务器的,io.js 的一个变体。 +Electron 可以让你使用纯 JavaScript 调用丰富的原生 APIs 来创造桌面应用。你可以把它看作一个专注于桌面应用的 Node.js 的变体,而不是 Web 服务器。 这不意味着 Electron 是绑定了 GUI 库的 JavaScript。相反,Electron 使用 web 页面作为它的 GUI,所以你能把它看作成一个被 JavaScript 控制的,精简版的 Chromium 浏览器。 @@ -14,13 +13,13 @@ Electron 可以让你使用纯 JavaScript 调用丰富的原生 APIs 来创造 在一般浏览器中,网页通常会在沙盒环境下运行,并且不允许访问原生资源。然而,Electron 用户拥有在网页中调用 io.js 的 APIs 的能力,可以与底层操作系统直接交互。 ## 主进程与渲染进程的区别 -主进程使用 BrowserWindow 实例创建网页。每个 BrowserWindow 实例都在自己的渲染进程里运行着一个网页。当一个 BrowserWindow 实例被销毁后,相应的渲染进程也会被终止。 +主进程使用 `BrowserWindow` 实例创建页面。每个 `BrowserWindow` 实例都在自己的渲染进程里运行页面。当一个 `BrowserWindow` 实例被销毁后,相应的渲染进程也会被终止。 -主进程管理所有页面和与之对应的渲染进程。每个渲染进程都是相互独立的,并且只关心他们自己的网页。 +主进程管理所有页面和与之对应的渲染进程。每个渲染进程都是相互独立的,并且只关心他们自己的页面。 -由于在网页里管理原生 GUI 资源是非常危险而且容易造成资源泄露,所以在网页面调用 GUI 相关的 APIs 是不被允许的。如果你想在网页里使用 GUI 操作,其对应的渲染进程必须与主进程进行通讯,请求主进程进行相关的 GUI 操作。 +由于在页面里管理原生 GUI 资源是非常危险而且容易造成资源泄露,所以在页面调用 GUI 相关的 APIs 是不被允许的。如果你想在网页里使用 GUI 操作,其对应的渲染进程必须与主进程进行通讯,请求主进程进行相关的 GUI 操作。 -在 Electron,我们提供用于在主进程与渲染进程之间通讯的 [ipc][1] 模块。并且也有一个远程进程调用风格的通讯模块 [remote][2]。 +在 Electron,我们提供几种方法用于主进程和渲染进程之间的通讯。像 `[ipcRenderer][1]` 和 `[ipcMain][2]` 模块用于发送消息, `[remote][3]` 模块用于 RPC 方式通讯。这些内容都可以在一个 FAQ 中查看 `[how to share data between web pages][4]`。 # 打造你第一个 Electron 应用 大体上,一个 Electron 应用的目录结构如下: @@ -42,53 +41,72 @@ your-app/ `main.js` 应该用于创建窗口和处理系统事件,一个典型的例子如下: ```javascript -var app = require('app'); // 控制应用生命周期的模块。 -var BrowserWindow = require('browser-window'); // 创建原生浏览器窗口的模块 - -// 保持一个对于 window 对象的全局引用,不然,当 JavaScript 被 GC, -// window 会被自动地关闭 -var mainWindow = null; - -// 当所有窗口被关闭了,退出。 -app.on('window-all-closed', function() { - // 在 OS X 上,通常用户在明确地按下 Cmd + Q 之前 - // 应用会保持活动状态 - if (process.platform != 'darwin') { - app.quit(); - } -}); +const electron = require('electron'); +// 控制应用生命周期的模块。 +const {app} = electron; +// 创建原生浏览器窗口的模块。 +const {BrowserWindow} = electron; + +// 保持一个对于 window 对象的全局引用,如果你不这样做, +// 当 JavaScript 对象被垃圾回收, window 会被自动地关闭 +let win; -// 当 Electron 完成了初始化并且准备创建浏览器窗口的时候 -// 这个方法就被调用 -app.on('ready', function() { +function createWindow() { // 创建浏览器窗口。 - mainWindow = new BrowserWindow({width: 800, height: 600}); + win = new BrowserWindow({width: 800, height: 600}); - // 加载应用的 index.html - mainWindow.loadURL('file://' + __dirname + '/index.html'); + // 加载应用的 index.html。 + win.loadURL(`file://${__dirname}/index.html`); - // 打开开发工具 - mainWindow.openDevTools(); + // 启用开发工具。 + win.webContents.openDevTools(); - // 当 window 被关闭,这个事件会被发出 - mainWindow.on('closed', function() { + // 当 window 被关闭,这个事件会被触发。 + win.on('closed', () => { // 取消引用 window 对象,如果你的应用支持多窗口的话, // 通常会把多个 window 对象存放在一个数组里面, - // 但这次不是。 - mainWindow = null; + // 与此同时,你应该删除相应的元素。 + win = null; }); +} + +// This method will be called when Electron has finished +// initialization and is ready to create browser windows. +// Some APIs can only be used after this event occurs. +app.on('ready', createWindow); + +// Quit when all windows are closed. +app.on('window-all-closed', () => { + // On OS X it is common for applications and their menu bar + // to stay active until the user quits explicitly with Cmd + Q + if (process.platform !== 'darwin') { + app.quit(); + } +}); + +app.on('activate', () => { + // On OS X it's common to re-create a window in the app when the + // dock icon is clicked and there are no other windows open. + if (win === null) { + createWindow(); + } }); + +// In this file you can include the rest of your app's specific main process +// code. You can also put them in separate files and require them here. ``` 最后,你想展示的 `index.html` : ```html + Hello World!

Hello World!

- We are using io.js + We are using node , + Chrome , and Electron . @@ -97,8 +115,9 @@ app.on('ready', function() { # 运行你的应用 一旦你创建了最初的 `main.js`, `index.html` 和 `package.json` 这几个文件,你可能会想尝试在本地运行并测试,看看是不是和期望的那样正常运行。 -## electron-prebuild -如果你已经用 `npm` 全局安装了 `electron-prebuilt`,你只需要按照如下方式直接运行你的应用: +## electron-prebuilt +`[electron-prebuilt][5]` 是一个 `npm` 模块,包含所使用的 Electron 预编译版本。 +如果你已经用 `npm` 全局安装了它,你只需要按照如下方式直接运行你的应用: ```bash electron . ``` @@ -121,13 +140,32 @@ $ ./electron/electron your-app/ ```bash $ ./Electron.app/Contents/MacOS/Electron your-app/ ``` -`Electron.app` 里面是 Electron 发布包,你可以在[这里][3]下载到。 +`Electron.app` 里面是 Electron 发布包,你可以在 `[这里][6]` 下载到。 # 以发行版本运行 -在你完成了你的应用后,你可以按照[应用部署][4]指导发布一个版本,并且以已经打包好的形式运行应用。 +在你完成了你的应用后,你可以按照 `[应用部署][7]` 指导发布一个版本,并且以已经打包好的形式运行应用。 + +# 参照下面例子 +复制并且运行这个库 `[atom/electron-quick-start][8]`。 +*注意:*运行时需要你的系统已经安装了 `[Git][9]` 和 `[Node.js][10]`(包含 `[npm][11]`)。 - [1]: https://github.com/electron/electron/blob/master/docs-translations/zh-CN/api/ipc-main-process.md - [2]: https://github.com/electron/electron/blob/master/docs-translations/zh-CN/api/remote.md - [3]: https://github.com/electron/electron/releases - [4]: https://github.com/electron/electron/blob/master/docs-translations/zh-CN/tutorial/application-distribution.md +```bash +# Clone the repository +$ git clone https://github.com/electron/electron-quick-start +# Go into the repository +$ cd electron-quick-start +# Install dependencies and run the app +$ npm install && npm start +``` + [1]: https://github.com/electron/electron/blob/v1.1.3/docs/api/ipc-renderer.md + [2]: https://github.com/electron/electron/blob/v1.1.3/docs/api/ipc-main.md + [3]: https://github.com/electron/electron/blob/v1.1.3/docs/api/remote.md + [4]: https://github.com/electron/electron/blob/v1.1.3/docs/faq/electron-faq.md#how-to-share-data-between-web-pages + [5]: https://github.com/electron-userland/electron-prebuilt + [6]: https://github.com/electron/electron/releases + [7]: https://github.com/electron/electron/blob/v1.1.3/docs/tutorial/application-distribution.md + [8]: https://github.com/electron/electron-quick-start + [9]: https://git-scm.com/ + [10]: https://nodejs.org/en/download/ + [11]: https://www.npmjs.com/ \ No newline at end of file From ece468681f8e8b2f5cd715f3ae2ac17a1af60537 Mon Sep 17 00:00:00 2001 From: jf_jiang Date: Tue, 7 Jun 2016 18:57:45 +0900 Subject: [PATCH 018/126] fix outside link --- docs-translations/zh-CN/tutorial/quick-start.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/docs-translations/zh-CN/tutorial/quick-start.md b/docs-translations/zh-CN/tutorial/quick-start.md index 3156f3dd08d14..9faddf1bb09e6 100644 --- a/docs-translations/zh-CN/tutorial/quick-start.md +++ b/docs-translations/zh-CN/tutorial/quick-start.md @@ -19,7 +19,7 @@ Electron 可以让你使用纯 JavaScript 调用丰富的原生 APIs 来创造 由于在页面里管理原生 GUI 资源是非常危险而且容易造成资源泄露,所以在页面调用 GUI 相关的 APIs 是不被允许的。如果你想在网页里使用 GUI 操作,其对应的渲染进程必须与主进程进行通讯,请求主进程进行相关的 GUI 操作。 -在 Electron,我们提供几种方法用于主进程和渲染进程之间的通讯。像 `[ipcRenderer][1]` 和 `[ipcMain][2]` 模块用于发送消息, `[remote][3]` 模块用于 RPC 方式通讯。这些内容都可以在一个 FAQ 中查看 `[how to share data between web pages][4]`。 +在 Electron,我们提供几种方法用于主进程和渲染进程之间的通讯。像 [ipcRenderer][1] 和 [ipcMain][2] 模块用于发送消息, [remote][3] 模块用于 RPC 方式通讯。这些内容都可以在一个 FAQ 中查看 [how to share data between web pages][4]。 # 打造你第一个 Electron 应用 大体上,一个 Electron 应用的目录结构如下: @@ -116,7 +116,7 @@ app.on('activate', () => { 一旦你创建了最初的 `main.js`, `index.html` 和 `package.json` 这几个文件,你可能会想尝试在本地运行并测试,看看是不是和期望的那样正常运行。 ## electron-prebuilt -`[electron-prebuilt][5]` 是一个 `npm` 模块,包含所使用的 Electron 预编译版本。 +[electron-prebuilt][5] 是一个 `npm` 模块,包含所使用的 Electron 预编译版本。 如果你已经用 `npm` 全局安装了它,你只需要按照如下方式直接运行你的应用: ```bash electron . @@ -140,15 +140,15 @@ $ ./electron/electron your-app/ ```bash $ ./Electron.app/Contents/MacOS/Electron your-app/ ``` -`Electron.app` 里面是 Electron 发布包,你可以在 `[这里][6]` 下载到。 +`Electron.app` 里面是 Electron 发布包,你可以在 [这里][6] 下载到。 # 以发行版本运行 -在你完成了你的应用后,你可以按照 `[应用部署][7]` 指导发布一个版本,并且以已经打包好的形式运行应用。 +在你完成了你的应用后,你可以按照 [应用部署][7] 指导发布一个版本,并且以已经打包好的形式运行应用。 # 参照下面例子 -复制并且运行这个库 `[atom/electron-quick-start][8]`。 +复制并且运行这个库 [atom/electron-quick-start][8]。 -*注意:*运行时需要你的系统已经安装了 `[Git][9]` 和 `[Node.js][10]`(包含 `[npm][11]`)。 +*注意:*运行时需要你的系统已经安装了 [Git][9] 和 [Node.js][10](包含 [npm][11])。 ```bash # Clone the repository From 219bc2fc510b2b9ea8681b313f51b76d0f282f94 Mon Sep 17 00:00:00 2001 From: VReality64 Date: Tue, 7 Jun 2016 19:19:21 +0900 Subject: [PATCH 019/126] Update Korean documentation translation to a latest version --- docs-translations/ko-KR/api/ipc-renderer.md | 8 ++--- docs-translations/ko-KR/api/web-contents.md | 15 ++++++++ .../tutorial/application-distribution.md | 34 +++++-------------- .../ko-KR/tutorial/quick-start.md | 2 +- 4 files changed, 28 insertions(+), 31 deletions(-) diff --git a/docs-translations/ko-KR/api/ipc-renderer.md b/docs-translations/ko-KR/api/ipc-renderer.md index 3584d41b556d5..a112e0ba44846 100644 --- a/docs-translations/ko-KR/api/ipc-renderer.md +++ b/docs-translations/ko-KR/api/ipc-renderer.md @@ -12,7 +12,7 @@ `ipcRenderer`는 다음과 같은 이벤트 리스닝 메서드를 가지고 있습니다: -### `ipcMain.on(channel, listener)` +### `ipcRenderer.on(channel, listener)` * `channel` String * `listener` Function @@ -20,7 +20,7 @@ `channel`에 대해 이벤트를 리스닝합니다. 새로운 메시지가 도착하면 `listener`가 `listener(event, args...)` 형식으로 호출됩니다. -### `ipcMain.once(channel, listener)` +### `ipcRenderer.once(channel, listener)` * `channel` String * `listener` Function @@ -28,7 +28,7 @@ 이벤트에 대해 한 번만 작동하는 `listener` 함수를 등록합니다. 이 `listener`는 등록된 후 `channel`에 보내지는 메시지에 한해 호출됩니다. 호출된 이후엔 리스너가 삭제됩니다. -### `ipcMain.removeListener(channel, listener)` +### `ipcRenderer.removeListener(channel, listener)` * `channel` String * `listener` Function @@ -39,7 +39,7 @@ 지정한 `channel`에 대한 리스너를 저장하는 배열에서 지정한 `listener`를 삭제합니다. -### `ipcMain.removeAllListeners(channel)` +### `ipcRenderer.removeAllListeners(channel)` * `channel` String (optional) diff --git a/docs-translations/ko-KR/api/web-contents.md b/docs-translations/ko-KR/api/web-contents.md index 41592011613ce..467c019a7ef7d 100644 --- a/docs-translations/ko-KR/api/web-contents.md +++ b/docs-translations/ko-KR/api/web-contents.md @@ -284,6 +284,15 @@ Returns: ``` +### Event: 'update-target-url' + +Returns: + +* `event` Event +* `url` URL + +마우스나 키보드를 사용해 링크에 포커스를 할 때 발생하는 이벤트입니다. + ### Event: 'cursor-changed' Returns: @@ -591,6 +600,12 @@ CSS 코드를 현재 웹 페이지에 삽입합니다. 웹 페이지에서 `replaceMisspelling` 편집 커맨드를 실행합니다. +### `webContents.insertText(text)` + +* `text` String + +포커스된 요소에 `text`를 삽입합니다. + ### `webContents.findInPage(text[, options])` * `text` String - 찾을 콘텐츠, 반드시 공백이 아니여야 합니다. diff --git a/docs-translations/ko-KR/tutorial/application-distribution.md b/docs-translations/ko-KR/tutorial/application-distribution.md index fedd613c0f117..66f729a18e0f8 100644 --- a/docs-translations/ko-KR/tutorial/application-distribution.md +++ b/docs-translations/ko-KR/tutorial/application-distribution.md @@ -117,25 +117,7 @@ MyApp.app/Contents 또한 Electron 소스 코드를 다시 빌드할 때 어플리케이션 이름을 변경할 수 있습니다. -`GYP_DEFINES` 환경변수를 사용하여 다음과 같이 다시 빌드할 수 있습니다: - -__Windows__ - -```bash -> set "GYP_DEFINES=project_name=myapp product_name=MyApp" -> python script\clean.py -> python script\bootstrap.py -> python script\build.py -c R -t myapp -``` - -__Bash__ - -```bash -$ export GYP_DEFINES="project_name=myapp product_name=MyApp" -$ script/clean.py -$ script/bootstrap.py -$ script/build.py -c Release -t myapp -``` +`atom.gyp` 파일을 수정하여 다음과 같이 다시 빌드할 수 있습니다: ### grunt-build-atom-shell @@ -175,16 +157,16 @@ Electron의 개발자로써, Electron을 매우 많은 시나리오에서도 작 3. 다음의 환경 변수들을 설정합니다: -* `ELECTRON_GITHUB_TOKEN` - GitHub에 릴리즈를 만들 수 있는 토큰. -* `ELECTRON_S3_ACCESS_KEY`, `ELECTRON_S3_BUCKET`, `ELECTRON_S3_SECRET_KEY` - + * `ELECTRON_GITHUB_TOKEN` - GitHub에 릴리즈를 만들 수 있는 토큰. + * `ELECTRON_S3_ACCESS_KEY`, `ELECTRON_S3_BUCKET`, `ELECTRON_S3_SECRET_KEY` - node.js 헤더 뿐만 아니라 심볼을 업로드할 장소. -* `ELECTRON_RELEASE` - `true`로 지정하고 업로드 부분이 실행되면, 설정되지 않은 + * `ELECTRON_RELEASE` - `true`로 지정하고 업로드 부분이 실행되면, 설정되지 않은 부분을 남기고 `surf-build`가 CI-type 확인을 실행합니다. 모든 pull request를 실행할 때 적합합니다. -* `CI` - `true` 또는 다른 것을 지정하면 실패합니다. -* `GITHUB_TOKEN` - `ELECTRON_GITHUB_TOKEN`와 같게 설정 -* `SURF_TEMP` - Windows에선 `C:\Temp`로 설정하면 긴 경로 문제를 해결할 수 있습니다. -* `TARGET_ARCH` - `ia32` 또는 `x64`를 지정. + * `CI` - `true` 또는 다른 것을 지정하면 실패합니다. + * `GITHUB_TOKEN` - `ELECTRON_GITHUB_TOKEN`와 같게 설정 + * `SURF_TEMP` - Windows에선 `C:\Temp`로 설정하면 긴 경로 문제를 해결할 수 있습니다. + * `TARGET_ARCH` - `ia32` 또는 `x64`를 지정. 4. Electron에 기여를 하는 기여자라면, _반드시_ `script/upload.py`에서 포크를 위해 `ELECTRON_REPO`를 설정해야 합니다. (`MYORG/electron`) diff --git a/docs-translations/ko-KR/tutorial/quick-start.md b/docs-translations/ko-KR/tutorial/quick-start.md index 48e76d5cd54f1..d96a430ecc93a 100644 --- a/docs-translations/ko-KR/tutorial/quick-start.md +++ b/docs-translations/ko-KR/tutorial/quick-start.md @@ -41,7 +41,7 @@ API를 사용하여 low-level 수준으로 운영체제와 상호작용할 수 프로세스에서 그 작업을 처리할 수 있도록 메인 프로세스와 통신을 해야 합니다. Electron에는 메인 프로세스와 렌더러 프로세스 사이에 통신을 할 수 있도록 -[ipc](../api/ipc-renderer.md) 모듈을 제공하고 있습니다. +[ipcRenderer](../api/ipc-renderer.md)와 [ipcMain](../api/ipc-main.md) 모듈을 제공하고 있습니다. 또는 [remote](../api/remote.md) 모듈을 사용하여 RPC 스타일로 통신할 수도 있습니다. 또한 FAQ에서 [다양한 객체를 공유하는 방법](share-data)도 소개하고 있습니다. From cae25cab3ec3c5e5d9aa61202ed613cb5e8fbc40 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Tue, 7 Jun 2016 19:38:41 +0900 Subject: [PATCH 020/126] Implement SetIgnoreMouseEvents for Windows --- atom/browser/native_window.cc | 3 --- atom/browser/native_window.h | 2 +- atom/browser/native_window_views.cc | 11 +++++++++++ atom/browser/native_window_views.h | 1 + 4 files changed, 13 insertions(+), 4 deletions(-) diff --git a/atom/browser/native_window.cc b/atom/browser/native_window.cc index c22159fc25db7..46c3250a94a65 100644 --- a/atom/browser/native_window.cc +++ b/atom/browser/native_window.cc @@ -281,9 +281,6 @@ bool NativeWindow::IsDocumentEdited() { return false; } -void NativeWindow::SetIgnoreMouseEvents(bool ignore) { -} - void NativeWindow::SetMenu(ui::MenuModel* menu) { } diff --git a/atom/browser/native_window.h b/atom/browser/native_window.h index 0846fbde4a9ce..a12663a1aa5a0 100644 --- a/atom/browser/native_window.h +++ b/atom/browser/native_window.h @@ -154,7 +154,7 @@ class NativeWindow : public base::SupportsUserData, virtual std::string GetRepresentedFilename(); virtual void SetDocumentEdited(bool edited); virtual bool IsDocumentEdited(); - virtual void SetIgnoreMouseEvents(bool ignore); + virtual void SetIgnoreMouseEvents(bool ignore) = 0; virtual void SetMenu(ui::MenuModel* menu); virtual bool HasModalDialog(); virtual gfx::NativeWindow GetNativeWindow() = 0; diff --git a/atom/browser/native_window_views.cc b/atom/browser/native_window_views.cc index 6a0919635f3e1..6b16072f6adb4 100644 --- a/atom/browser/native_window_views.cc +++ b/atom/browser/native_window_views.cc @@ -672,6 +672,17 @@ bool NativeWindowViews::HasShadow() { return wm::GetShadowType(GetNativeWindow()) != wm::SHADOW_TYPE_NONE; } +void NativeWindowViews::SetIgnoreMouseEvents(bool ignore) { +#if defined(OS_WIN) + LONG ex_style = ::GetWindowLong(GetAcceleratedWidget(), GWL_EXSTYLE); + if (ignore) + ex_style |= (WS_EX_TRANSPARENT | WS_EX_LAYERED); + else + ex_style &= ~(WS_EX_TRANSPARENT | WS_EX_LAYERED); + ::SetWindowLong(GetAcceleratedWidget(), GWL_EXSTYLE, ex_style); +#endif +} + void NativeWindowViews::SetMenu(ui::MenuModel* menu_model) { if (menu_model == nullptr) { // Remove accelerators diff --git a/atom/browser/native_window_views.h b/atom/browser/native_window_views.h index 909c5b6fd4bab..6a26c14e00846 100644 --- a/atom/browser/native_window_views.h +++ b/atom/browser/native_window_views.h @@ -91,6 +91,7 @@ class NativeWindowViews : public NativeWindow, void SetBackgroundColor(const std::string& color_name) override; void SetHasShadow(bool has_shadow) override; bool HasShadow() override; + void SetIgnoreMouseEvents(bool ignore) override; void SetMenu(ui::MenuModel* menu_model) override; gfx::NativeWindow GetNativeWindow() override; void SetOverlayIcon(const gfx::Image& overlay, From f8b69c1fac54fd85e444f77320de91fb81b6e280 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Tue, 7 Jun 2016 20:23:29 +0900 Subject: [PATCH 021/126] Implement SetIgnoreMouseEvents for Linux --- atom/browser/native_window_views.cc | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/atom/browser/native_window_views.cc b/atom/browser/native_window_views.cc index 6b16072f6adb4..29c4187a124c9 100644 --- a/atom/browser/native_window_views.cc +++ b/atom/browser/native_window_views.cc @@ -680,6 +680,15 @@ void NativeWindowViews::SetIgnoreMouseEvents(bool ignore) { else ex_style &= ~(WS_EX_TRANSPARENT | WS_EX_LAYERED); ::SetWindowLong(GetAcceleratedWidget(), GWL_EXSTYLE, ex_style); +#elif defined(USE_X11) + if (ignore) { + XRectangle r = {0, 0, 1, 1}; + XShapeCombineRectangles(gfx::GetXDisplay(), GetAcceleratedWidget(), + ShapeInput, 0, 0, &r, 1, ShapeSet, YXBanded); + } else { + XShapeCombineMask(gfx::GetXDisplay(), GetAcceleratedWidget(), + ShapeInput, 0, 0, None, ShapeSet); + } #endif } From 6192eef1b6b9a5adbdfaa4a206adbdc8eb2f2c09 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Tue, 7 Jun 2016 20:32:52 +0900 Subject: [PATCH 022/126] Update docs on win.setIgnoreMouseEvents --- docs/api/browser-window.md | 8 ++++++-- docs/api/frameless-window.md | 20 ++++++++++++++++---- 2 files changed, 22 insertions(+), 6 deletions(-) diff --git a/docs/api/browser-window.md b/docs/api/browser-window.md index fc558515fdc40..e6ff43ca234da 100644 --- a/docs/api/browser-window.md +++ b/docs/api/browser-window.md @@ -928,10 +928,14 @@ Returns whether the window is visible on all workspaces. **Note:** This API always returns false on Windows. -### `win.setIgnoreMouseEvents(ignore)` _OS X_ +### `win.setIgnoreMouseEvents(ignore)` * `ignore` Boolean -Ignore all moused events that happened in the window. +Makes the window ignore all mouse events. + +All mouse events happened in this window will be passed to the window bellow +this window, but if this window has focus, it will still receive keyboard +events. [blink-feature-string]: https://code.google.com/p/chromium/codesearch#chromium/src/out/Debug/gen/blink/platform/RuntimeEnabledFeatures.cpp&sq=package:chromium&type=cs&l=576 diff --git a/docs/api/frameless-window.md b/docs/api/frameless-window.md index f3017037210d5..66c42588b2b5c 100644 --- a/docs/api/frameless-window.md +++ b/docs/api/frameless-window.md @@ -14,8 +14,8 @@ To create a frameless window, you need to set `frame` to `false` in ```javascript -const {BrowserWindow} = require('electron'); -let win = new BrowserWindow({width: 800, height: 600, frame: false}); +const {BrowserWindow} = require('electron') +let win = new BrowserWindow({width: 800, height: 600, frame: false}) ``` ### Alternatives on OS X @@ -28,7 +28,7 @@ the window controls ("traffic lights") for standard window actions. You can do so by specifying the new `titleBarStyle` option: ```javascript -let win = new BrowserWindow({titleBarStyle: 'hidden'}); +let win = new BrowserWindow({titleBarStyle: 'hidden'}) ``` ## Transparent window @@ -37,7 +37,7 @@ By setting the `transparent` option to `true`, you can also make the frameless window transparent: ```javascript -let win = new BrowserWindow({transparent: true, frame: false}); +let win = new BrowserWindow({transparent: true, frame: false}) ``` ### Limitations @@ -59,6 +59,16 @@ let win = new BrowserWindow({transparent: true, frame: false}); Linux. * On Mac the native window shadow will not be shown on a transparent window. +## Click-through window + +To create a click-through window, i.e. making the window ignore all mouse +events, you can call the [win.setIgnoreMouseEvents(ignore)][ignore-mouse-events] +API: + +```javascript +win.setIgnoreMouseEvents(true) +``` + ## Draggable region By default, the frameless window is non-draggable. Apps need to specify @@ -108,3 +118,5 @@ On some platforms, the draggable area will be treated as a non-client frame, so when you right click on it a system menu will pop up. To make the context menu behave correctly on all platforms you should never use a custom context menu on draggable areas. + +[ignore-mouse-events]: browser-window.md#winsetignoremouseeventsignore From 3bcb411e28ccc223b019505d1bb697dc8e132db3 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Tue, 7 Jun 2016 10:24:33 -0700 Subject: [PATCH 023/126] Don't collect unused results array --- lib/browser/guest-view-manager.js | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/lib/browser/guest-view-manager.js b/lib/browser/guest-view-manager.js index c5c075b28bb77..0bdbb1d1f68db 100644 --- a/lib/browser/guest-view-manager.js +++ b/lib/browser/guest-view-manager.js @@ -92,13 +92,9 @@ var createGuest = function (embedder, params) { } } guest.once('destroyed', function () { - var j, len1, results - results = [] - for (j = 0, len1 = destroyEvents.length; j < len1; j++) { - event = destroyEvents[j] - results.push(embedder.removeListener(event, destroy)) + for (const event of destroyEvents) { + embedder.removeListener(event, destroy) } - return results }) // Init guest web view after attached. From ce1a9740f6201b6ac5c51034cabfc02038923fa0 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Tue, 7 Jun 2016 10:24:48 -0700 Subject: [PATCH 024/126] :art: Use const and for/of loops --- lib/browser/guest-view-manager.js | 25 ++++++++++++------------- 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/lib/browser/guest-view-manager.js b/lib/browser/guest-view-manager.js index 0bdbb1d1f68db..3d4596d725d2e 100644 --- a/lib/browser/guest-view-manager.js +++ b/lib/browser/guest-view-manager.js @@ -57,12 +57,12 @@ var getNextInstanceId = function () { // Create a new guest instance. var createGuest = function (embedder, params) { - var destroy, destroyEvents, event, fn, guest, i, id, j, len, len1, listeners if (webViewManager == null) { webViewManager = process.atomBinding('web_view_manager') } - id = getNextInstanceId(embedder) - guest = webContents.create({ + + const id = getNextInstanceId(embedder) + const guest = webContents.create({ isGuest: true, partition: params.partition, embedder: embedder @@ -73,20 +73,19 @@ var createGuest = function (embedder, params) { } // Destroy guest when the embedder is gone or navigated. - destroyEvents = ['will-destroy', 'crashed', 'did-navigate'] - destroy = function () { + const destroyEvents = ['will-destroy', 'crashed', 'did-navigate'] + const destroy = function () { if (guestInstances[id] != null) { - return destroyGuest(embedder, id) + destroyGuest(embedder, id) } } - for (i = 0, len = destroyEvents.length; i < len; i++) { - event = destroyEvents[i] + for (const event of destroyEvents) { embedder.once(event, destroy) // Users might also listen to the crashed event, so We must ensure the guest // is destroyed before users' listener gets called. It is done by moving our // listener to the first one in queue. - listeners = embedder._events[event] + const listeners = embedder._events[event] if (Array.isArray(listeners)) { moveLastToFirst(listeners) } @@ -132,13 +131,12 @@ var createGuest = function (embedder, params) { }) // Dispatch events to embedder. - fn = function (event) { - return guest.on(event, function (_, ...args) { + const fn = function (event) { + guest.on(event, function (_, ...args) { embedder.send.apply(embedder, ['ELECTRON_GUEST_VIEW_INTERNAL_DISPATCH_EVENT-' + guest.viewInstanceId, event].concat(args)) }) } - for (j = 0, len1 = supportedWebViewEvents.length; j < len1; j++) { - event = supportedWebViewEvents[j] + for (const event of supportedWebViewEvents) { fn(event) } @@ -151,6 +149,7 @@ var createGuest = function (embedder, params) { guest.on('size-changed', function (_, ...args) { embedder.send.apply(embedder, ['ELECTRON_GUEST_VIEW_INTERNAL_SIZE_CHANGED-' + guest.viewInstanceId].concat(args)) }) + return id } From 5c880b7c99350ffcfe98750302bb616daa33deb5 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Tue, 7 Jun 2016 10:25:21 -0700 Subject: [PATCH 025/126] We -> we --- lib/browser/guest-view-manager.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/browser/guest-view-manager.js b/lib/browser/guest-view-manager.js index 3d4596d725d2e..9fffb745ac296 100644 --- a/lib/browser/guest-view-manager.js +++ b/lib/browser/guest-view-manager.js @@ -82,7 +82,7 @@ var createGuest = function (embedder, params) { for (const event of destroyEvents) { embedder.once(event, destroy) - // Users might also listen to the crashed event, so We must ensure the guest + // Users might also listen to the crashed event, so we must ensure the guest // is destroyed before users' listener gets called. It is done by moving our // listener to the first one in queue. const listeners = embedder._events[event] From ba762464d223a4ceea7251a07840a6e34a60f617 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Tue, 7 Jun 2016 10:29:24 -0700 Subject: [PATCH 026/126] More let/const-ing --- lib/browser/guest-view-manager.js | 42 +++++++++++++++---------------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/lib/browser/guest-view-manager.js b/lib/browser/guest-view-manager.js index 9fffb745ac296..a0bc751813bf3 100644 --- a/lib/browser/guest-view-manager.js +++ b/lib/browser/guest-view-manager.js @@ -4,9 +4,9 @@ const ipcMain = require('electron').ipcMain const webContents = require('electron').webContents // Doesn't exist in early initialization. -var webViewManager = null +let webViewManager = null -var supportedWebViewEvents = [ +const supportedWebViewEvents = [ 'load-commit', 'did-finish-load', 'did-fail-load', @@ -40,23 +40,23 @@ var supportedWebViewEvents = [ 'update-target-url' ] -var nextInstanceId = 0 -var guestInstances = {} -var embedderElementsMap = {} -var reverseEmbedderElementsMap = {} +let nextInstanceId = 0 +const guestInstances = {} +const embedderElementsMap = {} +const reverseEmbedderElementsMap = {} // Moves the last element of array to the first one. -var moveLastToFirst = function (list) { +const moveLastToFirst = function (list) { return list.unshift(list.pop()) } // Generate guestInstanceId. -var getNextInstanceId = function () { +const getNextInstanceId = function () { return ++nextInstanceId } // Create a new guest instance. -var createGuest = function (embedder, params) { +const createGuest = function (embedder, params) { if (webViewManager == null) { webViewManager = process.atomBinding('web_view_manager') } @@ -98,7 +98,7 @@ var createGuest = function (embedder, params) { // Init guest web view after attached. guest.once('did-attach', function () { - var opts + let opts params = this.attachParams delete this.attachParams this.viewInstanceId = params.instanceId @@ -154,8 +154,8 @@ var createGuest = function (embedder, params) { } // Attach the guest to an element of embedder. -var attachGuest = function (embedder, elementInstanceId, guestInstanceId, params) { - var guest, key, oldGuestInstanceId, ref1, webPreferences +const attachGuest = function (embedder, elementInstanceId, guestInstanceId, params) { + let guest, key, oldGuestInstanceId, ref1, webPreferences guest = guestInstances[guestInstanceId].guest // Destroy the old guest when attaching. @@ -190,12 +190,12 @@ var attachGuest = function (embedder, elementInstanceId, guestInstanceId, params } // Destroy an existing guest instance. -var destroyGuest = function (embedder, id) { - var key +const destroyGuest = function (embedder, id) { webViewManager.removeGuest(embedder, id) guestInstances[id].guest.destroy() delete guestInstances[id] - key = reverseEmbedderElementsMap[id] + + const key = reverseEmbedderElementsMap[id] if (key != null) { delete reverseEmbedderElementsMap[id] return delete embedderElementsMap[key] @@ -215,18 +215,18 @@ ipcMain.on('ELECTRON_GUEST_VIEW_MANAGER_DESTROY_GUEST', function (event, id) { }) ipcMain.on('ELECTRON_GUEST_VIEW_MANAGER_SET_SIZE', function (event, id, params) { - var ref1 - return (ref1 = guestInstances[id]) != null ? ref1.guest.setSize(params) : void 0 + const guestInstance = guestInstances[id] + return guestInstance != null ? guestInstance.guest.setSize(params) : void 0 }) // Returns WebContents from its guest id. exports.getGuest = function (id) { - var ref1 - return (ref1 = guestInstances[id]) != null ? ref1.guest : void 0 + const guestInstance = guestInstances[id] + return guestInstance != null ? guestInstance.guest : void 0 } // Returns the embedder of the guest. exports.getEmbedder = function (id) { - var ref1 - return (ref1 = guestInstances[id]) != null ? ref1.embedder : void 0 + const guestInstance = guestInstances[id] + return guestInstance != null ? guestInstance.embedder : void 0 } From ae71cf3df139bd1373b60effc23e5715094a922a Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Tue, 7 Jun 2016 13:42:42 -0700 Subject: [PATCH 027/126] Add disableBlinkFeatures option --- atom/browser/web_contents_preferences.cc | 7 +++++++ atom/common/options_switches.cc | 3 +++ atom/common/options_switches.h | 1 + 3 files changed, 11 insertions(+) diff --git a/atom/browser/web_contents_preferences.cc b/atom/browser/web_contents_preferences.cc index a32e23de68f56..8a7eee09201f9 100644 --- a/atom/browser/web_contents_preferences.cc +++ b/atom/browser/web_contents_preferences.cc @@ -166,6 +166,13 @@ void WebContentsPreferences::AppendExtraCommandLineSwitches( command_line->AppendSwitchASCII(::switches::kEnableBlinkFeatures, blink_features); + // Disable blink features. + std::string disable_blink_features; + if (web_preferences.GetString(options::kDisableBlinkFeatures, + &disable_blink_features)) + command_line->AppendSwitchASCII(::switches::kDisableBlinkFeatures, + disable_blink_features); + // The initial visibility state. NativeWindow* window = NativeWindow::FromWebContents(web_contents); diff --git a/atom/common/options_switches.cc b/atom/common/options_switches.cc index de130eee13ebc..2447d7324b997 100644 --- a/atom/common/options_switches.cc +++ b/atom/common/options_switches.cc @@ -109,6 +109,9 @@ const char kScrollBounce[] = "scrollBounce"; // Enable blink features. const char kBlinkFeatures[] = "blinkFeatures"; +// Disable blink features. +const char kDisableBlinkFeatures[] = "disableBlinkFeatures"; + } // namespace options namespace switches { diff --git a/atom/common/options_switches.h b/atom/common/options_switches.h index fadde79f18c81..0f75e56dcb303 100644 --- a/atom/common/options_switches.h +++ b/atom/common/options_switches.h @@ -58,6 +58,7 @@ extern const char kExperimentalCanvasFeatures[]; extern const char kOpenerID[]; extern const char kScrollBounce[]; extern const char kBlinkFeatures[]; +extern const char kDisableBlinkFeatures[]; } // namespace options From ca6e3ed1efd7c480644070f257a9c7a2e158b871 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Tue, 7 Jun 2016 13:49:31 -0700 Subject: [PATCH 028/126] Add webview support for disabled blink features --- lib/browser/guest-view-manager.js | 3 ++- lib/renderer/web-view/web-view-attributes.js | 8 ++++++++ lib/renderer/web-view/web-view-constants.js | 1 + 3 files changed, 11 insertions(+), 1 deletion(-) diff --git a/lib/browser/guest-view-manager.js b/lib/browser/guest-view-manager.js index c5c075b28bb77..604e1785fe924 100644 --- a/lib/browser/guest-view-manager.js +++ b/lib/browser/guest-view-manager.js @@ -182,7 +182,8 @@ var attachGuest = function (embedder, elementInstanceId, guestInstanceId, params plugins: params.plugins, zoomFactor: params.zoomFactor, webSecurity: !params.disablewebsecurity, - blinkFeatures: params.blinkfeatures + blinkFeatures: params.blinkfeatures, + disableBlinkFeatures: params.disableBlinkFeatures, } if (params.preload) { diff --git a/lib/renderer/web-view/web-view-attributes.js b/lib/renderer/web-view/web-view-attributes.js index c76e0d26f953b..d62c496f4228f 100644 --- a/lib/renderer/web-view/web-view-attributes.js +++ b/lib/renderer/web-view/web-view-attributes.js @@ -264,6 +264,13 @@ class BlinkFeaturesAttribute extends WebViewAttribute { } } +// Attribute that specifies the blink features to be disabled. +class DisableBlinkFeaturesAttribute extends WebViewAttribute { + constructor (webViewImpl) { + super(webViewConstants.ATTRIBUTE_DISBLEBLINKFEATURES, webViewImpl) + } +} + // Sets up all of the webview attributes. WebViewImpl.prototype.setupWebViewAttributes = function () { this.attributes = {} @@ -278,6 +285,7 @@ WebViewImpl.prototype.setupWebViewAttributes = function () { this.attributes[webViewConstants.ATTRIBUTE_ALLOWPOPUPS] = new BooleanAttribute(webViewConstants.ATTRIBUTE_ALLOWPOPUPS, this) this.attributes[webViewConstants.ATTRIBUTE_PRELOAD] = new PreloadAttribute(this) this.attributes[webViewConstants.ATTRIBUTE_BLINKFEATURES] = new BlinkFeaturesAttribute(this) + this.attributes[webViewConstants.ATTRIBUTE_DISBLEBLINKFEATURES] = new DisableBlinkFeaturesAttribute(this) const autosizeAttributes = [webViewConstants.ATTRIBUTE_MAXHEIGHT, webViewConstants.ATTRIBUTE_MAXWIDTH, webViewConstants.ATTRIBUTE_MINHEIGHT, webViewConstants.ATTRIBUTE_MINWIDTH] autosizeAttributes.forEach((attribute) => { diff --git a/lib/renderer/web-view/web-view-constants.js b/lib/renderer/web-view/web-view-constants.js index 5501f4f3599b4..7cce4708ef328 100644 --- a/lib/renderer/web-view/web-view-constants.js +++ b/lib/renderer/web-view/web-view-constants.js @@ -16,6 +16,7 @@ module.exports = { ATTRIBUTE_PRELOAD: 'preload', ATTRIBUTE_USERAGENT: 'useragent', ATTRIBUTE_BLINKFEATURES: 'blinkfeatures', + ATTRIBUTE_DISBLEBLINKFEATURES: 'disableblinkfeatures', // Internal attribute. ATTRIBUTE_INTERNALINSTANCEID: 'internalinstanceid', From b941e25bf569dc02d1ba8f04161995d11a618e43 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Tue, 7 Jun 2016 13:55:44 -0700 Subject: [PATCH 029/126] Link to RuntimeEnabledFeatures.in --- docs/api/browser-window.md | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/docs/api/browser-window.md b/docs/api/browser-window.md index e6ff43ca234da..2351c0d404f0d 100644 --- a/docs/api/browser-window.md +++ b/docs/api/browser-window.md @@ -176,8 +176,7 @@ The `webPreferences` option is an object that can have following properties: OS X. Default is `false`. * `blinkFeatures` String - A list of feature strings separated by `,`, like `CSSVariables,KeyboardEventKey`. The full list of supported feature strings - can be found in the [setFeatureEnabledFromString][blink-feature-string] - function. + can be found in the [RuntimeEnabledFeatures.in][blink-feature-string] file. * `defaultFontFamily` Object - Sets the default font for the font-family. * `standard` String - Defaults to `Times New Roman`. * `serif` String - Defaults to `Times New Roman`. @@ -938,4 +937,4 @@ All mouse events happened in this window will be passed to the window bellow this window, but if this window has focus, it will still receive keyboard events. -[blink-feature-string]: https://code.google.com/p/chromium/codesearch#chromium/src/out/Debug/gen/blink/platform/RuntimeEnabledFeatures.cpp&sq=package:chromium&type=cs&l=576 +[blink-feature-string]: https://cs.chromium.org/chromium/src/third_party/WebKit/Source/platform/RuntimeEnabledFeatures.in From 636e356977fb580bba6204b546d1a4c95f172133 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Tue, 7 Jun 2016 13:56:33 -0700 Subject: [PATCH 030/126] Document disableBlinkFeatures option --- docs/api/browser-window.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docs/api/browser-window.md b/docs/api/browser-window.md index 2351c0d404f0d..b89daa877f645 100644 --- a/docs/api/browser-window.md +++ b/docs/api/browser-window.md @@ -177,6 +177,10 @@ The `webPreferences` option is an object that can have following properties: * `blinkFeatures` String - A list of feature strings separated by `,`, like `CSSVariables,KeyboardEventKey`. The full list of supported feature strings can be found in the [RuntimeEnabledFeatures.in][blink-feature-string] file. +* `disableBlinkFeatures` String - A list of feature strings separated by `,`, + like `CSSVariables,KeyboardEventKey`. The full list of supported feature + strings can be found in the [RuntimeEnabledFeatures.in][blink-feature-string] + file. * `defaultFontFamily` Object - Sets the default font for the font-family. * `standard` String - Defaults to `Times New Roman`. * `serif` String - Defaults to `Times New Roman`. From 1b6a95adcb2f767534ba25729fbade274cf44d64 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Tue, 7 Jun 2016 13:57:54 -0700 Subject: [PATCH 031/126] Document disableblinkfeatures attribute --- docs/api/web-view-tag.md | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/docs/api/web-view-tag.md b/docs/api/web-view-tag.md index d00f64d4eb53e..1c9edcecaa754 100644 --- a/docs/api/web-view-tag.md +++ b/docs/api/web-view-tag.md @@ -205,7 +205,17 @@ If "on", the guest page will be allowed to open new windows. A list of strings which specifies the blink features to be enabled separated by `,`. The full list of supported feature strings can be found in the -[setFeatureEnabledFromString][blink-feature-string] function. +[RuntimeEnabledFeatures.in][blink-feature-string] file. + +### `disableblinkfeatures` + +```html + +``` + +A list of strings which specifies the blink features to be disabled separated by `,`. +The full list of supported feature strings can be found in the +[RuntimeEnabledFeatures.in][blink-feature-string] file. ## Methods @@ -802,4 +812,4 @@ Emitted when DevTools is closed. Emitted when DevTools is focused / opened. -[blink-feature-string]: https://code.google.com/p/chromium/codesearch#chromium/src/out/Debug/gen/blink/platform/RuntimeEnabledFeatures.cpp&sq=package:chromium&type=cs&l=527 +[blink-feature-string]: https://cs.chromium.org/chromium/src/third_party/WebKit/Source/platform/RuntimeEnabledFeatures.in From c7f2c25bc90f081b79aca9ec478f0b663d7203a8 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Tue, 7 Jun 2016 13:59:30 -0700 Subject: [PATCH 032/126] Mention enabling/disabling --- docs/api/browser-window.md | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/docs/api/browser-window.md b/docs/api/browser-window.md index b89daa877f645..e20d17b8e772c 100644 --- a/docs/api/browser-window.md +++ b/docs/api/browser-window.md @@ -175,12 +175,13 @@ The `webPreferences` option is an object that can have following properties: * `scrollBounce` Boolean - Enables scroll bounce (rubber banding) effect on OS X. Default is `false`. * `blinkFeatures` String - A list of feature strings separated by `,`, like - `CSSVariables,KeyboardEventKey`. The full list of supported feature strings - can be found in the [RuntimeEnabledFeatures.in][blink-feature-string] file. -* `disableBlinkFeatures` String - A list of feature strings separated by `,`, - like `CSSVariables,KeyboardEventKey`. The full list of supported feature + `CSSVariables,KeyboardEventKey` to enable. The full list of supported feature strings can be found in the [RuntimeEnabledFeatures.in][blink-feature-string] file. +* `disableBlinkFeatures` String - A list of feature strings separated by `,`, + like `CSSVariables,KeyboardEventKey` to disable. The full list of supported + feature strings can be found in the + [RuntimeEnabledFeatures.in][blink-feature-string] file. * `defaultFontFamily` Object - Sets the default font for the font-family. * `standard` String - Defaults to `Times New Roman`. * `serif` String - Defaults to `Times New Roman`. From 9b979f3b49e8ad8e9e69bb786c06f8909a2f9623 Mon Sep 17 00:00:00 2001 From: Emmanouil Konstantinidis Date: Tue, 7 Jun 2016 23:40:07 +0100 Subject: [PATCH 033/126] Move example to the correct place --- docs/api/tray.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/api/tray.md b/docs/api/tray.md index 4c4891ef8960a..421d4fcf63dca 100644 --- a/docs/api/tray.md +++ b/docs/api/tray.md @@ -29,12 +29,12 @@ __Platform limitations:__ * When app indicator is used on Linux, the `click` event is ignored. * On Linux in order for changes made to individual `MenuItem`s to take effect, you have to call `setContextMenu` again. For example: -* On Windows it is recommended to use `ICO` icons to get best visual effects. ```javascript contextMenu.items[2].checked = false; appIcon.setContextMenu(contextMenu); ``` +* On Windows it is recommended to use `ICO` icons to get best visual effects. If you want to keep exact same behaviors on all platforms, you should not rely on the `click` event and always attach a context menu to the tray icon. From f7b0bb2bf3b15df34543b963979945c7528c8263 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Tue, 7 Jun 2016 16:23:09 -0700 Subject: [PATCH 034/126] Add TODO about blinkFeatures -> enableBlinkFeatures --- atom/common/options_switches.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/atom/common/options_switches.cc b/atom/common/options_switches.cc index 2447d7324b997..22cdc3c63aefb 100644 --- a/atom/common/options_switches.cc +++ b/atom/common/options_switches.cc @@ -107,6 +107,7 @@ const char kOpenerID[] = "openerId"; const char kScrollBounce[] = "scrollBounce"; // Enable blink features. +// TODO(kevinsawicki) Rename to enableBlinkFeatures in 2.0 const char kBlinkFeatures[] = "blinkFeatures"; // Disable blink features. From 96012d6523c6ffd187608ec7b264c77ea87d1253 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Tue, 7 Jun 2016 16:24:05 -0700 Subject: [PATCH 035/126] Remove trailing comma --- lib/browser/guest-view-manager.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/browser/guest-view-manager.js b/lib/browser/guest-view-manager.js index 604e1785fe924..4e7721c40aa3a 100644 --- a/lib/browser/guest-view-manager.js +++ b/lib/browser/guest-view-manager.js @@ -183,7 +183,7 @@ var attachGuest = function (embedder, elementInstanceId, guestInstanceId, params zoomFactor: params.zoomFactor, webSecurity: !params.disablewebsecurity, blinkFeatures: params.blinkfeatures, - disableBlinkFeatures: params.disableBlinkFeatures, + disableBlinkFeatures: params.disableBlinkFeatures } if (params.preload) { From cd2041375b7fc17d417979c20d525d3e1b9276a2 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Tue, 7 Jun 2016 16:26:53 -0700 Subject: [PATCH 036/126] Add missing A in constant name --- lib/renderer/web-view/web-view-attributes.js | 4 ++-- lib/renderer/web-view/web-view-constants.js | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/renderer/web-view/web-view-attributes.js b/lib/renderer/web-view/web-view-attributes.js index d62c496f4228f..e918578900cd2 100644 --- a/lib/renderer/web-view/web-view-attributes.js +++ b/lib/renderer/web-view/web-view-attributes.js @@ -267,7 +267,7 @@ class BlinkFeaturesAttribute extends WebViewAttribute { // Attribute that specifies the blink features to be disabled. class DisableBlinkFeaturesAttribute extends WebViewAttribute { constructor (webViewImpl) { - super(webViewConstants.ATTRIBUTE_DISBLEBLINKFEATURES, webViewImpl) + super(webViewConstants.ATTRIBUTE_DISABLEBLINKFEATURES, webViewImpl) } } @@ -285,7 +285,7 @@ WebViewImpl.prototype.setupWebViewAttributes = function () { this.attributes[webViewConstants.ATTRIBUTE_ALLOWPOPUPS] = new BooleanAttribute(webViewConstants.ATTRIBUTE_ALLOWPOPUPS, this) this.attributes[webViewConstants.ATTRIBUTE_PRELOAD] = new PreloadAttribute(this) this.attributes[webViewConstants.ATTRIBUTE_BLINKFEATURES] = new BlinkFeaturesAttribute(this) - this.attributes[webViewConstants.ATTRIBUTE_DISBLEBLINKFEATURES] = new DisableBlinkFeaturesAttribute(this) + this.attributes[webViewConstants.ATTRIBUTE_DISABLEBLINKFEATURES] = new DisableBlinkFeaturesAttribute(this) const autosizeAttributes = [webViewConstants.ATTRIBUTE_MAXHEIGHT, webViewConstants.ATTRIBUTE_MAXWIDTH, webViewConstants.ATTRIBUTE_MINHEIGHT, webViewConstants.ATTRIBUTE_MINWIDTH] autosizeAttributes.forEach((attribute) => { diff --git a/lib/renderer/web-view/web-view-constants.js b/lib/renderer/web-view/web-view-constants.js index 7cce4708ef328..96ee289831e9f 100644 --- a/lib/renderer/web-view/web-view-constants.js +++ b/lib/renderer/web-view/web-view-constants.js @@ -16,7 +16,7 @@ module.exports = { ATTRIBUTE_PRELOAD: 'preload', ATTRIBUTE_USERAGENT: 'useragent', ATTRIBUTE_BLINKFEATURES: 'blinkfeatures', - ATTRIBUTE_DISBLEBLINKFEATURES: 'disableblinkfeatures', + ATTRIBUTE_DISABLEBLINKFEATURES: 'disableblinkfeatures', // Internal attribute. ATTRIBUTE_INTERNALINSTANCEID: 'internalinstanceid', From 02e0ca60efac035adfd00e6884cccbd4e61f2b30 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Tue, 7 Jun 2016 16:35:23 -0700 Subject: [PATCH 037/126] Use lowercase param key --- lib/browser/guest-view-manager.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/browser/guest-view-manager.js b/lib/browser/guest-view-manager.js index 4e7721c40aa3a..b7a93b068a58d 100644 --- a/lib/browser/guest-view-manager.js +++ b/lib/browser/guest-view-manager.js @@ -183,7 +183,7 @@ var attachGuest = function (embedder, elementInstanceId, guestInstanceId, params zoomFactor: params.zoomFactor, webSecurity: !params.disablewebsecurity, blinkFeatures: params.blinkfeatures, - disableBlinkFeatures: params.disableBlinkFeatures + disableBlinkFeatures: params.disableblinkfeatures } if (params.preload) { From 3ec4fcb3ec8e4be6500bf1182e7f5ffe004241c9 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Wed, 8 Jun 2016 11:03:01 +0900 Subject: [PATCH 038/126] bellow => below --- docs/api/browser-window.md | 2 +- docs/api/session.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/api/browser-window.md b/docs/api/browser-window.md index e20d17b8e772c..c133a49beda0b 100644 --- a/docs/api/browser-window.md +++ b/docs/api/browser-window.md @@ -938,7 +938,7 @@ Returns whether the window is visible on all workspaces. Makes the window ignore all mouse events. -All mouse events happened in this window will be passed to the window bellow +All mouse events happened in this window will be passed to the window below this window, but if this window has focus, it will still receive keyboard events. diff --git a/docs/api/session.md b/docs/api/session.md index 43107e98e9208..e7affddde9323 100644 --- a/docs/api/session.md +++ b/docs/api/session.md @@ -206,7 +206,7 @@ Sets the proxy settings. When `pacScript` and `proxyRules` are provided together, the `proxyRules` option is ignored and `pacScript` configuration is applied. -The `proxyRules` has to follow the rules bellow: +The `proxyRules` has to follow the rules below: ``` proxyRules = schemeProxies[";"] From 77dc08f2f9024d22e7d3a5ca82f9aee6fba2f86c Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Wed, 8 Jun 2016 11:08:24 +0900 Subject: [PATCH 039/126] Update to Chrome 51.0.2704.84 --- atom/common/chrome_version.h | 2 +- script/lib/config.py | 2 +- vendor/brightray | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/atom/common/chrome_version.h b/atom/common/chrome_version.h index 4f4a46bc8b676..2cd932bd55ad5 100644 --- a/atom/common/chrome_version.h +++ b/atom/common/chrome_version.h @@ -8,7 +8,7 @@ #ifndef ATOM_COMMON_CHROME_VERSION_H_ #define ATOM_COMMON_CHROME_VERSION_H_ -#define CHROME_VERSION_STRING "51.0.2704.79" +#define CHROME_VERSION_STRING "51.0.2704.84" #define CHROME_VERSION "v" CHROME_VERSION_STRING #endif // ATOM_COMMON_CHROME_VERSION_H_ diff --git a/script/lib/config.py b/script/lib/config.py index 63dec7211e146..dcdb7e2cfe230 100644 --- a/script/lib/config.py +++ b/script/lib/config.py @@ -8,7 +8,7 @@ BASE_URL = os.getenv('LIBCHROMIUMCONTENT_MIRROR') or \ 'https://s3.amazonaws.com/github-janky-artifacts/libchromiumcontent' -LIBCHROMIUMCONTENT_COMMIT = 'c86ebfb5278e0ec1a8cff1f8eb4da3c6a8cfa8f7' +LIBCHROMIUMCONTENT_COMMIT = '7ae12b2856b81f5bfa1290108f72c3e4b5c13c52' PLATFORM = { 'cygwin': 'win32', diff --git a/vendor/brightray b/vendor/brightray index 1b57d5860be32..097d14b39f83a 160000 --- a/vendor/brightray +++ b/vendor/brightray @@ -1 +1 @@ -Subproject commit 1b57d5860be3271d5e2a14b3a3b8027b04b30bcb +Subproject commit 097d14b39f83a945373c111dec46ad078c6f5f39 From 1146b2d5c1d0e1f74e8b383725e530713f506ac8 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Wed, 8 Jun 2016 14:44:30 +0900 Subject: [PATCH 040/126] spec: Custom protocol can have "fetch" working in it --- spec/api-protocol-spec.js | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/spec/api-protocol-spec.js b/spec/api-protocol-spec.js index 803511917104d..57e8638ee6d30 100644 --- a/spec/api-protocol-spec.js +++ b/spec/api-protocol-spec.js @@ -919,6 +919,23 @@ describe('protocol module', function () { }) w.loadURL(origin) }) + }), + + it('can have fetch working in it', function (done) { + const content = '' + const handler = function (request, callback) { + callback({data: content, mimeType: 'text/html'}) + } + protocol.registerStringProtocol(standardScheme, handler, function (error) { + if (error) return done(error) + w.webContents.on('crashed', function () { + done('WebContents crashed') + }) + w.webContents.on('did-finish-load', function () { + done() + }) + w.loadURL(origin) + }) }) }) }) From 920ebee333f27824fa84c90864281bda955f9ef8 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Wed, 8 Jun 2016 15:46:50 +0900 Subject: [PATCH 041/126] Make sure standard schemes are also set in child process --- atom/app/atom_content_client.cc | 14 ++++++++++++++ atom/browser/api/atom_api_protocol.cc | 7 +++++++ atom/browser/atom_browser_client.cc | 8 ++++++++ atom/common/options_switches.cc | 3 +++ atom/common/options_switches.h | 1 + 5 files changed, 33 insertions(+) diff --git a/atom/app/atom_content_client.cc b/atom/app/atom_content_client.cc index 40a6e1f5268dd..c9c41404d4a25 100644 --- a/atom/app/atom_content_client.cc +++ b/atom/app/atom_content_client.cc @@ -181,6 +181,20 @@ void AtomContentClient::AddAdditionalSchemes( std::vector* standard_schemes, std::vector* referrer_schemes, std::vector* savable_schemes) { + // Parse --standard-schemes=scheme1,scheme2 + auto command_line = base::CommandLine::ForCurrentProcess(); + std::string custom_schemes = command_line->GetSwitchValueASCII( + switches::kStandardSchemes); + if (!custom_schemes.empty()) { + // Note that url::SchemeWithType requires passing const char*, so we have + // to ensure the string still lives after this function exits. + static std::vector schemes_list; + schemes_list = base::SplitString( + custom_schemes, ",", base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY); + for (const std::string& scheme : schemes_list) + standard_schemes->push_back({scheme.c_str(), url::SCHEME_WITHOUT_PORT}); + } + standard_schemes->push_back({"chrome-extension", url::SCHEME_WITHOUT_PORT}); } diff --git a/atom/browser/api/atom_api_protocol.cc b/atom/browser/api/atom_api_protocol.cc index 226f689d32de9..f420e52b3e9d9 100644 --- a/atom/browser/api/atom_api_protocol.cc +++ b/atom/browser/api/atom_api_protocol.cc @@ -14,6 +14,9 @@ #include "atom/common/native_mate_converters/callback.h" #include "atom/common/native_mate_converters/net_converter.h" #include "atom/common/node_includes.h" +#include "atom/common/options_switches.h" +#include "base/command_line.h" +#include "base/strings/string_util.h" #include "native_mate/dictionary.h" #include "url/url_util.h" @@ -160,6 +163,10 @@ void RegisterStandardSchemes( const std::vector& schemes) { for (const auto& scheme : schemes) url::AddStandardScheme(scheme.c_str(), url::SCHEME_WITHOUT_PORT); + + auto command_line = base::CommandLine::ForCurrentProcess(); + command_line->AppendSwitchASCII(atom::switches::kStandardSchemes, + base::JoinString(schemes, ",")); } mate::Handle CreateProtocol(v8::Isolate* isolate) { diff --git a/atom/browser/atom_browser_client.cc b/atom/browser/atom_browser_client.cc index e3cb9c5c8c892..c1b50459c6808 100644 --- a/atom/browser/atom_browser_client.cc +++ b/atom/browser/atom_browser_client.cc @@ -169,6 +169,14 @@ void AtomBrowserClient::AppendExtraCommandLineSwitches( if (process_type != "renderer") return; + // Copy following switches to child process. + static const char* const kCommonSwitchNames[] = { + switches::kStandardSchemes, + }; + command_line->CopySwitchesFrom( + *base::CommandLine::ForCurrentProcess(), + kCommonSwitchNames, arraysize(kCommonSwitchNames)); + // The registered service worker schemes. if (!g_custom_service_worker_schemes.empty()) command_line->AppendSwitchASCII(switches::kRegisterServiceWorkerSchemes, diff --git a/atom/common/options_switches.cc b/atom/common/options_switches.cc index 22cdc3c63aefb..d370f0ef859fb 100644 --- a/atom/common/options_switches.cc +++ b/atom/common/options_switches.cc @@ -129,6 +129,9 @@ const char kPpapiFlashVersion[] = "ppapi-flash-version"; // Disable HTTP cache. const char kDisableHttpCache[] = "disable-http-cache"; +// The list of standard schemes. +const char kStandardSchemes[] = "standard-schemes"; + // Register schemes to handle service worker. const char kRegisterServiceWorkerSchemes[] = "register-service-worker-schemes"; diff --git a/atom/common/options_switches.h b/atom/common/options_switches.h index 0f75e56dcb303..5924c05491192 100644 --- a/atom/common/options_switches.h +++ b/atom/common/options_switches.h @@ -71,6 +71,7 @@ extern const char kEnablePlugins[]; extern const char kPpapiFlashPath[]; extern const char kPpapiFlashVersion[]; extern const char kDisableHttpCache[]; +extern const char kStandardSchemes[]; extern const char kRegisterServiceWorkerSchemes[]; extern const char kSSLVersionFallbackMin[]; extern const char kCipherSuiteBlacklist[]; From 7108cc5f2b1408299e711d76d7a555b09518b8de Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Wed, 8 Jun 2016 15:49:26 +0900 Subject: [PATCH 042/126] Mark standard scheme as safe scheme --- atom/browser/api/atom_api_protocol.cc | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/atom/browser/api/atom_api_protocol.cc b/atom/browser/api/atom_api_protocol.cc index f420e52b3e9d9..de4de9de59d95 100644 --- a/atom/browser/api/atom_api_protocol.cc +++ b/atom/browser/api/atom_api_protocol.cc @@ -17,6 +17,7 @@ #include "atom/common/options_switches.h" #include "base/command_line.h" #include "base/strings/string_util.h" +#include "content/public/browser/child_process_security_policy.h" #include "native_mate/dictionary.h" #include "url/url_util.h" @@ -161,8 +162,11 @@ namespace { void RegisterStandardSchemes( const std::vector& schemes) { - for (const auto& scheme : schemes) + auto policy = content::ChildProcessSecurityPolicy::GetInstance(); + for (const auto& scheme : schemes) { url::AddStandardScheme(scheme.c_str(), url::SCHEME_WITHOUT_PORT); + policy->RegisterWebSafeScheme(scheme); + } auto command_line = base::CommandLine::ForCurrentProcess(); command_line->AppendSwitchASCII(atom::switches::kStandardSchemes, From 1bfbd215eaac99dd8984192259f5fed54c9c3025 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Wed, 8 Jun 2016 16:27:16 +0900 Subject: [PATCH 043/126] Don't rely on AddAdditionalSchemes for setting standard schemes On Linux because of the existence of zygote process, it becomes very tricky to correctly set standard schemes, basically we have to: 1. Pass --standard-schemes to both zygote and render processes 2. Init standard schemes for both zygote and render processes The )1 is very hard to achieve, so instead of using AddAdditionalSchemes, we just call url::AddStandardScheme directly. --- atom/app/atom_content_client.cc | 14 -------------- atom/renderer/atom_renderer_client.cc | 10 ++++++++++ 2 files changed, 10 insertions(+), 14 deletions(-) diff --git a/atom/app/atom_content_client.cc b/atom/app/atom_content_client.cc index c9c41404d4a25..40a6e1f5268dd 100644 --- a/atom/app/atom_content_client.cc +++ b/atom/app/atom_content_client.cc @@ -181,20 +181,6 @@ void AtomContentClient::AddAdditionalSchemes( std::vector* standard_schemes, std::vector* referrer_schemes, std::vector* savable_schemes) { - // Parse --standard-schemes=scheme1,scheme2 - auto command_line = base::CommandLine::ForCurrentProcess(); - std::string custom_schemes = command_line->GetSwitchValueASCII( - switches::kStandardSchemes); - if (!custom_schemes.empty()) { - // Note that url::SchemeWithType requires passing const char*, so we have - // to ensure the string still lives after this function exits. - static std::vector schemes_list; - schemes_list = base::SplitString( - custom_schemes, ",", base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY); - for (const std::string& scheme : schemes_list) - standard_schemes->push_back({scheme.c_str(), url::SCHEME_WITHOUT_PORT}); - } - standard_schemes->push_back({"chrome-extension", url::SCHEME_WITHOUT_PORT}); } diff --git a/atom/renderer/atom_renderer_client.cc b/atom/renderer/atom_renderer_client.cc index ee2dd7d54e04d..99b00227c3b13 100644 --- a/atom/renderer/atom_renderer_client.cc +++ b/atom/renderer/atom_renderer_client.cc @@ -122,6 +122,16 @@ bool IsDevToolsExtension(content::RenderFrame* render_frame) { AtomRendererClient::AtomRendererClient() : node_bindings_(NodeBindings::Create(false)), atom_bindings_(new AtomBindings) { + // Parse --standard-schemes=scheme1,scheme2 + base::CommandLine* command_line = base::CommandLine::ForCurrentProcess(); + std::string custom_schemes = command_line->GetSwitchValueASCII( + switches::kStandardSchemes); + if (!custom_schemes.empty()) { + std::vector schemes_list = base::SplitString( + custom_schemes, ",", base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY); + for (const std::string& scheme : schemes_list) + url::AddStandardScheme(scheme.c_str(), url::SCHEME_WITHOUT_PORT); + } } AtomRendererClient::~AtomRendererClient() { From b2bea57eff03efe7b7fd267fd814058aa48abbf8 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Wed, 8 Jun 2016 16:47:41 +0900 Subject: [PATCH 044/126] Bump v1.2.2 --- atom/browser/resources/mac/Info.plist | 4 ++-- atom/browser/resources/win/atom.rc | 8 ++++---- atom/common/atom_version.h | 2 +- electron.gyp | 2 +- package.json | 2 +- 5 files changed, 9 insertions(+), 9 deletions(-) diff --git a/atom/browser/resources/mac/Info.plist b/atom/browser/resources/mac/Info.plist index 28eddfa612355..7fda39ce35e87 100644 --- a/atom/browser/resources/mac/Info.plist +++ b/atom/browser/resources/mac/Info.plist @@ -17,9 +17,9 @@ CFBundleIconFile electron.icns CFBundleVersion - 1.2.1 + 1.2.2 CFBundleShortVersionString - 1.2.1 + 1.2.2 LSApplicationCategoryType public.app-category.developer-tools LSMinimumSystemVersion diff --git a/atom/browser/resources/win/atom.rc b/atom/browser/resources/win/atom.rc index 7e386d319d9df..b82f28a478998 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,2,1,0 - PRODUCTVERSION 1,2,1,0 + FILEVERSION 1,2,2,0 + PRODUCTVERSION 1,2,2,0 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -74,12 +74,12 @@ BEGIN BEGIN VALUE "CompanyName", "GitHub, Inc." VALUE "FileDescription", "Electron" - VALUE "FileVersion", "1.2.1" + VALUE "FileVersion", "1.2.2" VALUE "InternalName", "electron.exe" VALUE "LegalCopyright", "Copyright (C) 2015 GitHub, Inc. All rights reserved." VALUE "OriginalFilename", "electron.exe" VALUE "ProductName", "Electron" - VALUE "ProductVersion", "1.2.1" + VALUE "ProductVersion", "1.2.2" VALUE "SquirrelAwareVersion", "1" END END diff --git a/atom/common/atom_version.h b/atom/common/atom_version.h index 455bfacbfc11e..fc11a68b2915a 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 2 -#define ATOM_PATCH_VERSION 1 +#define ATOM_PATCH_VERSION 2 #define ATOM_VERSION_IS_RELEASE 1 diff --git a/electron.gyp b/electron.gyp index 055cb0c209acd..994cdcea899bb 100644 --- a/electron.gyp +++ b/electron.gyp @@ -4,7 +4,7 @@ 'product_name%': 'Electron', 'company_name%': 'GitHub, Inc', 'company_abbr%': 'github', - 'version%': '1.2.1', + 'version%': '1.2.2', }, 'includes': [ 'filenames.gypi', diff --git a/package.json b/package.json index 6f873786e3f0f..824cae71107bb 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "electron", - "version": "1.2.1", + "version": "1.2.2", "devDependencies": { "asar": "^0.11.0", "request": "*", From 8e2ae9b9e73953ded7ae9233fe2adb6a194f9053 Mon Sep 17 00:00:00 2001 From: Vadim Macagon Date: Wed, 8 Jun 2016 23:34:45 +0700 Subject: [PATCH 045/126] Fix location of code snippet in nativeImage docs The code snippet for `nativeImage.createFromPath` somehow ended up in the wrong section of the document, this PR moves it back where it belongs. --- docs/api/native-image.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/docs/api/native-image.md b/docs/api/native-image.md index 5244b71dfb168..d61f57ee4b9a8 100644 --- a/docs/api/native-image.md +++ b/docs/api/native-image.md @@ -103,6 +103,12 @@ Creates an empty `nativeImage` instance. Creates a new `nativeImage` instance from a file located at `path`. +```javascript +const nativeImage = require('electron').nativeImage; + +let image = nativeImage.createFromPath('/Users/somebody/images/icon.png'); +``` + ### `nativeImage.createFromBuffer(buffer[, scaleFactor])` * `buffer` [Buffer][buffer] @@ -121,12 +127,6 @@ Creates a new `nativeImage` instance from `dataURL`. The following methods are available on instances of `nativeImage`: -```javascript -const nativeImage = require('electron').nativeImage; - -let image = nativeImage.createFromPath('/Users/somebody/images/icon.png'); -``` - ### `image.toPng()` Returns a [Buffer][buffer] that contains the image's `PNG` encoded data. From 4f0a52628e33c5e65d42d5d31d82e54810c73ffa Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Thu, 2 Jun 2016 10:12:38 -0700 Subject: [PATCH 046/126] Add showDefinitionForSelection to webContents/webview --- atom/browser/api/atom_api_web_contents.cc | 11 +++++++++++ atom/browser/api/atom_api_web_contents.h | 1 + lib/renderer/web-view/web-view.js | 3 ++- 3 files changed, 14 insertions(+), 1 deletion(-) diff --git a/atom/browser/api/atom_api_web_contents.cc b/atom/browser/api/atom_api_web_contents.cc index c33b9f1d9bd96..59cdf746ab15f 100644 --- a/atom/browser/api/atom_api_web_contents.cc +++ b/atom/browser/api/atom_api_web_contents.cc @@ -1094,6 +1094,16 @@ void WebContents::StopFindInPage(content::StopFindAction action) { web_contents()->StopFinding(action); } +void WebContents::ShowDefinitionForSelection() { +#if defined(OS_WIN) + const auto view = web_contents()->GetRenderWidgetHostView(); + if (view) + view->ShowDefinitionForSelection(); +#else + NOTIMPLEMENTED(); +#endif +} + void WebContents::Focus() { web_contents()->Focus(); } @@ -1289,6 +1299,7 @@ void WebContents::BuildPrototype(v8::Isolate* isolate, .SetMethod("_printToPDF", &WebContents::PrintToPDF) .SetMethod("addWorkSpace", &WebContents::AddWorkSpace) .SetMethod("removeWorkSpace", &WebContents::RemoveWorkSpace) + .SetMethod("showDefinitionForSelection", &WebContents::ShowDefinitionForSelection) .SetProperty("id", &WebContents::ID) .SetProperty("session", &WebContents::Session) .SetProperty("hostWebContents", &WebContents::HostWebContents) diff --git a/atom/browser/api/atom_api_web_contents.h b/atom/browser/api/atom_api_web_contents.h index dfaac8791fb4c..f8e6710a5c586 100644 --- a/atom/browser/api/atom_api_web_contents.h +++ b/atom/browser/api/atom_api_web_contents.h @@ -116,6 +116,7 @@ class WebContents : public mate::TrackableObject, void ReplaceMisspelling(const base::string16& word); uint32_t FindInPage(mate::Arguments* args); void StopFindInPage(content::StopFindAction action); + void ShowDefinitionForSelection(); // Focus. void Focus(); diff --git a/lib/renderer/web-view/web-view.js b/lib/renderer/web-view/web-view.js index e9d300aabbcb3..82ed62dd3a5dd 100644 --- a/lib/renderer/web-view/web-view.js +++ b/lib/renderer/web-view/web-view.js @@ -379,7 +379,8 @@ var registerWebViewElement = function () { 'downloadURL', 'inspectServiceWorker', 'print', - 'printToPDF' + 'printToPDF', + 'showDefinitionForSelection' ] nonblockMethods = [ 'insertCSS', From ce19c2c0adf305516fd40136ed0f5165bbd2e91f Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Tue, 7 Jun 2016 13:09:54 -0700 Subject: [PATCH 047/126] Document webContents.showDefinitionForSelection --- docs/api/browser-window.md | 2 +- docs/api/web-contents.md | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/docs/api/browser-window.md b/docs/api/browser-window.md index c133a49beda0b..8b850b5c43882 100644 --- a/docs/api/browser-window.md +++ b/docs/api/browser-window.md @@ -885,7 +885,7 @@ The `flags` is an array that can include following `String`s: ### `win.showDefinitionForSelection()` _OS X_ -Shows pop-up dictionary that searches the selected word on the page. +Same as `webContents.showDefinitionForSelection()`. ### `win.setIcon(icon)` _Windows_ _Linux_ diff --git a/docs/api/web-contents.md b/docs/api/web-contents.md index b9ff9d7c48638..60c736e0041c7 100644 --- a/docs/api/web-contents.md +++ b/docs/api/web-contents.md @@ -957,6 +957,10 @@ win.webContents.on('did-finish-load', () => { }); ``` +### `webContents.showDefinitionForSelection()` _OS X_ + +Shows pop-up dictionary that searches the selected word on the page. + ## Instance Properties `WebContents` objects also have the following properties: From 6360a5cae43257d587c1c77bf37a96a9ed282cfa Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Tue, 7 Jun 2016 13:12:24 -0700 Subject: [PATCH 048/126] Add deprecation TODO for BrowserWindow.showDefinitionForSelection --- atom/browser/native_window_mac.mm | 2 ++ 1 file changed, 2 insertions(+) diff --git a/atom/browser/native_window_mac.mm b/atom/browser/native_window_mac.mm index 2b88b180694dd..995031a6f5368 100644 --- a/atom/browser/native_window_mac.mm +++ b/atom/browser/native_window_mac.mm @@ -934,6 +934,8 @@ - (void)drawRect:(NSRect)dirtyRect { } void NativeWindowMac::ShowDefinitionForSelection() { + // TODO(kevinsawicki): Deprecate and remove this method in 2.0 in favor of + // calling it directly on webContents. if (!web_contents()) return; auto rwhv = web_contents()->GetRenderWidgetHostView(); From 8c520cf158baacb9740dd4606f5367116e0bbb1f Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Tue, 7 Jun 2016 13:13:49 -0700 Subject: [PATCH 049/126] :art: --- atom/browser/api/atom_api_web_contents.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/atom/browser/api/atom_api_web_contents.cc b/atom/browser/api/atom_api_web_contents.cc index 59cdf746ab15f..f05b70c50f49b 100644 --- a/atom/browser/api/atom_api_web_contents.cc +++ b/atom/browser/api/atom_api_web_contents.cc @@ -1299,7 +1299,8 @@ void WebContents::BuildPrototype(v8::Isolate* isolate, .SetMethod("_printToPDF", &WebContents::PrintToPDF) .SetMethod("addWorkSpace", &WebContents::AddWorkSpace) .SetMethod("removeWorkSpace", &WebContents::RemoveWorkSpace) - .SetMethod("showDefinitionForSelection", &WebContents::ShowDefinitionForSelection) + .SetMethod("showDefinitionForSelection", + &WebContents::ShowDefinitionForSelection) .SetProperty("id", &WebContents::ID) .SetProperty("session", &WebContents::Session) .SetProperty("hostWebContents", &WebContents::HostWebContents) From c66299bf6603b89a8b44af0e06437e43c284c41c Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Tue, 7 Jun 2016 13:17:41 -0700 Subject: [PATCH 050/126] Document webview.showDefinitionForSelection --- docs/api/web-view-tag.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docs/api/web-view-tag.md b/docs/api/web-view-tag.md index 1c9edcecaa754..c210bd8b9cb0f 100644 --- a/docs/api/web-view-tag.md +++ b/docs/api/web-view-tag.md @@ -490,6 +490,10 @@ Sends an input `event` to the page. See [webContents.sendInputEvent](web-contents.md##webcontentssendinputeventevent) for detailed description of `event` object. +### `.showDefinitionForSelection()` _OS X_ + +Shows pop-up dictionary that searches the selected word on the page. + ### `.getWebContents()` Returns the [WebContents](web-contents.md) associated with this `webview`. From 6337e93e6dc1b9d511839cd8526c6a34c36f9b16 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Tue, 7 Jun 2016 13:20:06 -0700 Subject: [PATCH 051/126] Check for Mac in if block --- atom/browser/api/atom_api_web_contents.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/atom/browser/api/atom_api_web_contents.cc b/atom/browser/api/atom_api_web_contents.cc index f05b70c50f49b..b0927ee57298e 100644 --- a/atom/browser/api/atom_api_web_contents.cc +++ b/atom/browser/api/atom_api_web_contents.cc @@ -1095,7 +1095,7 @@ void WebContents::StopFindInPage(content::StopFindAction action) { } void WebContents::ShowDefinitionForSelection() { -#if defined(OS_WIN) +#if defined(OS_MACOSX) const auto view = web_contents()->GetRenderWidgetHostView(); if (view) view->ShowDefinitionForSelection(); From 70996c79ba82529cfcf8ef625964737538b42973 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Wed, 8 Jun 2016 10:19:28 -0700 Subject: [PATCH 052/126] Add showDefinitionForSelection webContents proxy method --- atom/browser/api/atom_api_window.cc | 10 ---------- atom/browser/api/atom_api_window.h | 4 ---- atom/browser/native_window.cc | 4 ---- atom/browser/native_window.h | 3 --- atom/browser/native_window_mac.h | 1 - atom/browser/native_window_mac.mm | 11 ----------- lib/browser/api/browser-window.js | 3 +++ 7 files changed, 3 insertions(+), 33 deletions(-) diff --git a/atom/browser/api/atom_api_window.cc b/atom/browser/api/atom_api_window.cc index ac3c510193ed3..c95a43340418a 100644 --- a/atom/browser/api/atom_api_window.cc +++ b/atom/browser/api/atom_api_window.cc @@ -623,12 +623,6 @@ void Window::UnhookAllWindowMessages() { } #endif -#if defined(OS_MACOSX) -void Window::ShowDefinitionForSelection() { - window_->ShowDefinitionForSelection(); -} -#endif - #if defined(TOOLKIT_VIEWS) void Window::SetIcon(mate::Handle icon) { #if defined(OS_WIN) @@ -760,10 +754,6 @@ void Window::BuildPrototype(v8::Isolate* isolate, .SetMethod("unhookWindowMessage", &Window::UnhookWindowMessage) .SetMethod("unhookAllWindowMessages", &Window::UnhookAllWindowMessages) #endif -#if defined(OS_MACOSX) - .SetMethod("showDefinitionForSelection", - &Window::ShowDefinitionForSelection) -#endif #if defined(TOOLKIT_VIEWS) .SetMethod("setIcon", &Window::SetIcon) #endif diff --git a/atom/browser/api/atom_api_window.h b/atom/browser/api/atom_api_window.h index e698eaaf78cc2..23ab162261ff1 100644 --- a/atom/browser/api/atom_api_window.h +++ b/atom/browser/api/atom_api_window.h @@ -169,10 +169,6 @@ class Window : public mate::TrackableObject, void UnhookAllWindowMessages(); #endif -#if defined(OS_MACOSX) - void ShowDefinitionForSelection(); -#endif - #if defined(TOOLKIT_VIEWS) void SetIcon(mate::Handle icon); #endif diff --git a/atom/browser/native_window.cc b/atom/browser/native_window.cc index 46c3250a94a65..b50de48dc54b1 100644 --- a/atom/browser/native_window.cc +++ b/atom/browser/native_window.cc @@ -334,10 +334,6 @@ void NativeWindow::CapturePage(const gfx::Rect& rect, kBGRA_8888_SkColorType); } -void NativeWindow::ShowDefinitionForSelection() { - NOTIMPLEMENTED(); -} - void NativeWindow::SetAutoHideMenuBar(bool auto_hide) { } diff --git a/atom/browser/native_window.h b/atom/browser/native_window.h index a12663a1aa5a0..c7d099fcadf21 100644 --- a/atom/browser/native_window.h +++ b/atom/browser/native_window.h @@ -179,9 +179,6 @@ class NativeWindow : public base::SupportsUserData, virtual void CapturePage(const gfx::Rect& rect, const CapturePageCallback& callback); - // Show popup dictionary. - virtual void ShowDefinitionForSelection(); - // Toggle the menu bar. virtual void SetAutoHideMenuBar(bool auto_hide); virtual bool IsMenuBarAutoHide(); diff --git a/atom/browser/native_window_mac.h b/atom/browser/native_window_mac.h index 52ebcbcb9c51f..27857239e8c87 100644 --- a/atom/browser/native_window_mac.h +++ b/atom/browser/native_window_mac.h @@ -83,7 +83,6 @@ class NativeWindowMac : public NativeWindow { void SetProgressBar(double progress) override; void SetOverlayIcon(const gfx::Image& overlay, const std::string& description) override; - void ShowDefinitionForSelection() override; void SetVisibleOnAllWorkspaces(bool visible) override; bool IsVisibleOnAllWorkspaces() override; diff --git a/atom/browser/native_window_mac.mm b/atom/browser/native_window_mac.mm index 995031a6f5368..73aa3017eb3fe 100644 --- a/atom/browser/native_window_mac.mm +++ b/atom/browser/native_window_mac.mm @@ -933,17 +933,6 @@ - (void)drawRect:(NSRect)dirtyRect { const std::string& description) { } -void NativeWindowMac::ShowDefinitionForSelection() { - // TODO(kevinsawicki): Deprecate and remove this method in 2.0 in favor of - // calling it directly on webContents. - if (!web_contents()) - return; - auto rwhv = web_contents()->GetRenderWidgetHostView(); - if (!rwhv) - return; - rwhv->ShowDefinitionForSelection(); -} - void NativeWindowMac::SetVisibleOnAllWorkspaces(bool visible) { SetCollectionBehavior(visible, NSWindowCollectionBehaviorCanJoinAllSpaces); } diff --git a/lib/browser/api/browser-window.js b/lib/browser/api/browser-window.js index ec61229368d1e..6ac31e737b8c6 100644 --- a/lib/browser/api/browser-window.js +++ b/lib/browser/api/browser-window.js @@ -151,6 +151,9 @@ Object.assign(BrowserWindow.prototype, { }, inspectServiceWorker () { return this.webContents.inspectServiceWorker() + }, + showDefinitionForSelection () { + return this.webContents.showDefinitionForSelection() } }) From 7250c461bef33feb5dfa56bc06dd3ff62c889af2 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Wed, 8 Jun 2016 10:21:28 -0700 Subject: [PATCH 053/126] Remove NOTIMPLEMENTED() call --- atom/browser/api/atom_api_web_contents.cc | 2 -- 1 file changed, 2 deletions(-) diff --git a/atom/browser/api/atom_api_web_contents.cc b/atom/browser/api/atom_api_web_contents.cc index b0927ee57298e..6a18f0967b53c 100644 --- a/atom/browser/api/atom_api_web_contents.cc +++ b/atom/browser/api/atom_api_web_contents.cc @@ -1099,8 +1099,6 @@ void WebContents::ShowDefinitionForSelection() { const auto view = web_contents()->GetRenderWidgetHostView(); if (view) view->ShowDefinitionForSelection(); -#else - NOTIMPLEMENTED(); #endif } From 7dcb939338bda806eff187131462d4c7245c8e30 Mon Sep 17 00:00:00 2001 From: Mathias Buus Date: Tue, 7 Jun 2016 14:45:38 +0200 Subject: [PATCH 054/126] support --abi --- default_app/main.js | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/default_app/main.js b/default_app/main.js index e26c70590b1a2..e172941ca1c01 100644 --- a/default_app/main.js +++ b/default_app/main.js @@ -8,11 +8,14 @@ const url = require('url') // Parse command line options. const argv = process.argv.slice(1) -const option = { file: null, help: null, version: null, webdriver: null, modules: [] } +const option = { file: null, help: null, version: null, abi: null, webdriver: null, modules: [] } for (let i = 0; i < argv.length; i++) { if (argv[i] === '--version' || argv[i] === '-v') { option.version = true break + } else if (argv[i] === '--abi') { + option.abi = true + break } else if (argv[i].match(/^--app=/)) { option.file = argv[i].split('=')[1] break @@ -304,6 +307,9 @@ if (option.file && !option.webdriver) { } else if (option.version) { console.log('v' + process.versions.electron) process.exit(0) +} else if (option.abi) { + console.log(process.versions.modules) + process.exit(0) } else if (option.help) { const helpMessage = `Electron ${process.versions.electron} - Build cross platform desktop apps with JavaScript, HTML, and CSS @@ -321,7 +327,8 @@ if (option.file && !option.webdriver) { -h, --help Print this usage message. -i, --interactive Open a REPL to the main process. -r, --require Module to preload (option can be repeated) - -v, --version Print the version.` + -v, --version Print the version. + --abi Print the application binary interface.` console.log(helpMessage) process.exit(0) } else if (option.interactive) { From 19787544b5f6b5323ade07ac3c155d508b45a24f Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Tue, 7 Jun 2016 09:50:06 -0700 Subject: [PATCH 055/126] Add failing spec for webview devtools extension --- spec/fixtures/pages/webview-devtools.html | 30 +++++++++++++++++++++++ spec/webview-spec.js | 20 +++++++++++++++ 2 files changed, 50 insertions(+) create mode 100644 spec/fixtures/pages/webview-devtools.html diff --git a/spec/fixtures/pages/webview-devtools.html b/spec/fixtures/pages/webview-devtools.html new file mode 100644 index 0000000000000..c16dbb2f8f141 --- /dev/null +++ b/spec/fixtures/pages/webview-devtools.html @@ -0,0 +1,30 @@ + + + + + + + + + + + diff --git a/spec/webview-spec.js b/spec/webview-spec.js index b1fa4405ada8b..a588f389bea9d 100644 --- a/spec/webview-spec.js +++ b/spec/webview-spec.js @@ -912,4 +912,24 @@ describe(' tag', function () { w.loadURL('file://' + fixtures + '/pages/webview-visibilitychange.html') }) + + it('loads devtools extension registered on the parent window', function (done) { + this.timeout(10000) + + w = new BrowserWindow({ + show: false + }) + + BrowserWindow.removeDevToolsExtension('foo') + + var extensionPath = path.join(__dirname, 'fixtures', 'devtools-extensions', 'foo') + BrowserWindow.addDevToolsExtension(extensionPath) + + w.loadURL('file://' + fixtures + '/pages/webview-devtools.html') + + ipcMain.once('answer', function (event, message) { + assert.equal(message.runtimeId, 'foo') + done() + }) + }) }) From 4f46f75d8f804fcc001417c710b02ade7541da2c Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Tue, 7 Jun 2016 09:50:36 -0700 Subject: [PATCH 056/126] Load dev tools extensions in webviews --- lib/browser/chrome-extension.js | 15 ++++++++++----- lib/browser/guest-view-manager.js | 5 +++++ 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/lib/browser/chrome-extension.js b/lib/browser/chrome-extension.js index d3c76ce797be6..fac80d9177e6e 100644 --- a/lib/browser/chrome-extension.js +++ b/lib/browser/chrome-extension.js @@ -81,8 +81,8 @@ const removeBackgroundPages = function (manifest) { } // Dispatch tabs events. -const hookWindowForTabEvents = function (win) { - const tabId = win.webContents.id +const hookWindowForTabEvents = function (win, webContents) { + const tabId = webContents.id for (const page of objectValues(backgroundPages)) { page.webContents.sendToAll('CHROME_TABS_ONCREATED', tabId) } @@ -301,6 +301,7 @@ app.once('ready', function () { return manifest.name } } + BrowserWindow.removeDevToolsExtension = function (name) { const manifest = manifestNameMap[name] if (!manifest) return @@ -315,9 +316,13 @@ app.once('ready', function () { const init = BrowserWindow.prototype._init BrowserWindow.prototype._init = function () { init.call(this) - hookWindowForTabEvents(this) - this.webContents.on('devtools-opened', () => { - loadDevToolsExtensions(this, objectValues(manifestMap)) + this._loadDevToolsExtensions(this.webContents) + } + + BrowserWindow.prototype._loadDevToolsExtensions = function (webContents) { + hookWindowForTabEvents(this, webContents) + webContents.on('devtools-opened', function () { + loadDevToolsExtensions(webContents, objectValues(manifestMap)) }) } }) diff --git a/lib/browser/guest-view-manager.js b/lib/browser/guest-view-manager.js index fdd426c229f67..8bccaad84b0e5 100644 --- a/lib/browser/guest-view-manager.js +++ b/lib/browser/guest-view-manager.js @@ -1,5 +1,6 @@ 'use strict' +const BrowserWindow = require('electron').BrowserWindow const ipcMain = require('electron').ipcMain const webContents = require('electron').webContents @@ -150,6 +151,10 @@ const createGuest = function (embedder, params) { embedder.send.apply(embedder, ['ELECTRON_GUEST_VIEW_INTERNAL_SIZE_CHANGED-' + guest.viewInstanceId].concat(args)) }) + // Enable DevTools extensions in guest view + const window = BrowserWindow.fromWebContents(embedder) + if (window) window._loadDevToolsExtensions(guest) + return id } From 4c1ede32cfa1358acfe0c6f60b7b3b0b38f2c8a5 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Tue, 7 Jun 2016 10:10:56 -0700 Subject: [PATCH 057/126] Use destroyed event instead of closed event --- lib/browser/chrome-extension.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/browser/chrome-extension.js b/lib/browser/chrome-extension.js index fac80d9177e6e..c323819a7877b 100644 --- a/lib/browser/chrome-extension.js +++ b/lib/browser/chrome-extension.js @@ -81,13 +81,13 @@ const removeBackgroundPages = function (manifest) { } // Dispatch tabs events. -const hookWindowForTabEvents = function (win, webContents) { +const hookWindowForTabEvents = function (webContents) { const tabId = webContents.id for (const page of objectValues(backgroundPages)) { page.webContents.sendToAll('CHROME_TABS_ONCREATED', tabId) } - win.once('closed', () => { + webContents.once('destroyed', () => { for (const page of objectValues(backgroundPages)) { page.webContents.sendToAll('CHROME_TABS_ONREMOVED', tabId) } @@ -320,7 +320,7 @@ app.once('ready', function () { } BrowserWindow.prototype._loadDevToolsExtensions = function (webContents) { - hookWindowForTabEvents(this, webContents) + hookWindowForTabEvents(webContents) webContents.on('devtools-opened', function () { loadDevToolsExtensions(webContents, objectValues(manifestMap)) }) From 78e3bb066038c76b25a7ba1ff9e2be2e7bf60b27 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Tue, 7 Jun 2016 10:11:47 -0700 Subject: [PATCH 058/126] :art: --- lib/browser/guest-view-manager.js | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/lib/browser/guest-view-manager.js b/lib/browser/guest-view-manager.js index 8bccaad84b0e5..61ab7673fb1c9 100644 --- a/lib/browser/guest-view-manager.js +++ b/lib/browser/guest-view-manager.js @@ -1,8 +1,6 @@ 'use strict' -const BrowserWindow = require('electron').BrowserWindow -const ipcMain = require('electron').ipcMain -const webContents = require('electron').webContents +const {BrowserWindow, ipcMain, webContents} = require('electron') // Doesn't exist in early initialization. let webViewManager = null From bf47056561ee613105072f10be2f7079cc9fcc49 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Tue, 7 Jun 2016 10:34:17 -0700 Subject: [PATCH 059/126] Pluralize extension --- spec/webview-spec.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/webview-spec.js b/spec/webview-spec.js index a588f389bea9d..3e22a79a9cf7b 100644 --- a/spec/webview-spec.js +++ b/spec/webview-spec.js @@ -913,7 +913,7 @@ describe(' tag', function () { w.loadURL('file://' + fixtures + '/pages/webview-visibilitychange.html') }) - it('loads devtools extension registered on the parent window', function (done) { + it('loads devtools extensions registered on the parent window', function (done) { this.timeout(10000) w = new BrowserWindow({ From 4f7bde38a973cd0e95722bfd270dbddb3f4c592c Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Tue, 7 Jun 2016 10:38:01 -0700 Subject: [PATCH 060/126] Assert on tab id as well --- spec/api-browser-window-spec.js | 2 ++ spec/fixtures/devtools-extensions/foo/index.html | 3 ++- spec/webview-spec.js | 1 + 3 files changed, 5 insertions(+), 1 deletion(-) diff --git a/spec/api-browser-window-spec.js b/spec/api-browser-window-spec.js index 11b954d2d07a8..6a76ba5ddb6cc 100644 --- a/spec/api-browser-window-spec.js +++ b/spec/api-browser-window-spec.js @@ -864,6 +864,7 @@ describe('browser-window module', function () { ipcMain.once('answer', function (event, message) { assert.equal(message.runtimeId, 'foo') + assert.equal(message.tabId, w.webContents.id) done() }) }) @@ -875,6 +876,7 @@ describe('browser-window module', function () { ipcMain.once('answer', function (event, message, extensionId) { assert.equal(message.runtimeId, 'foo') + assert.equal(message.tabId, w.webContents.id) done() }) }) diff --git a/spec/fixtures/devtools-extensions/foo/index.html b/spec/fixtures/devtools-extensions/foo/index.html index 1b9d1b8cb9b4a..2e0a29aff3d09 100644 --- a/spec/fixtures/devtools-extensions/foo/index.html +++ b/spec/fixtures/devtools-extensions/foo/index.html @@ -5,7 +5,8 @@ + + + + From c8180ab301882f7459bcc7d01d792e1b79733cf5 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Thu, 9 Jun 2016 12:06:49 -0700 Subject: [PATCH 096/126] Update spec description --- spec/chromium-spec.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/chromium-spec.js b/spec/chromium-spec.js index 83e8bdf3fc638..be40f127ca293 100644 --- a/spec/chromium-spec.js +++ b/spec/chromium-spec.js @@ -328,7 +328,7 @@ describe('chromium feature', function () { b = window.open('file://' + fixtures + '/pages/window-opener-postMessage.html', '', 'show=no') }) - it('works for windows opened from a ', function (done) { + it('supports windows opened from a ', function (done) { const webview = new WebView() webview.addEventListener('console-message', function (e) { webview.remove() From 2f93735909af3f451c42d35fe7dde09bc1d30ccb Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Thu, 9 Jun 2016 13:41:42 -0700 Subject: [PATCH 097/126] Make BrowserWindowProxy guestId non-writeable --- lib/renderer/override.js | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/lib/renderer/override.js b/lib/renderer/override.js index 5667e5e16f55f..ced2318e71888 100644 --- a/lib/renderer/override.js +++ b/lib/renderer/override.js @@ -25,7 +25,13 @@ var BrowserWindowProxy = (function () { } function BrowserWindowProxy (guestId1) { - this.guestId = guestId1 + Object.defineProperty(this, 'guestId', { + configurable: false, + enumerable: true, + writeable: false, + value: guestId1 + }) + this.closed = false ipcRenderer.once('ELECTRON_GUEST_WINDOW_MANAGER_WINDOW_CLOSED_' + this.guestId, () => { BrowserWindowProxy.remove(this.guestId) From 2f88bec17742c47c6e0522ab775d7bf2c0cf0c8f Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Thu, 9 Jun 2016 13:45:05 -0700 Subject: [PATCH 098/126] Add guestId non-writeable assertions --- spec/chromium-spec.js | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/spec/chromium-spec.js b/spec/chromium-spec.js index cd046ab29abf4..7a8c25b7b3765 100644 --- a/spec/chromium-spec.js +++ b/spec/chromium-spec.js @@ -165,6 +165,12 @@ describe('chromium feature', function () { var b = window.open('about:blank', '', 'show=no') assert.equal(b.closed, false) assert.equal(b.constructor.name, 'BrowserWindowProxy') + + // Check that guestId is not writeable + assert(b.guestId) + b.guestId = 'anotherValue' + assert.notEqual(b.guestId, 'anoterValue') + b.close() }) From 39180e65397f9861699352477b8bdd66b9c8779f Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Thu, 9 Jun 2016 13:37:50 -0700 Subject: [PATCH 099/126] Get webContents from guestId --- spec/chromium-spec.js | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/spec/chromium-spec.js b/spec/chromium-spec.js index be40f127ca293..939570d6abce4 100644 --- a/spec/chromium-spec.js +++ b/spec/chromium-spec.js @@ -5,8 +5,7 @@ const ws = require('ws') const url = require('url') const remote = require('electron').remote -const BrowserWindow = remote.require('electron').BrowserWindow -const session = remote.require('electron').session +const {BrowserWindow, session, webContents} = remote const isCI = remote.getGlobal('isCi') @@ -235,7 +234,7 @@ describe('chromium feature', function () { else targetURL = 'file://' + fixtures + '/pages/base-page.html' b = window.open(targetURL) - BrowserWindow.fromId(b.guestId).webContents.once('did-finish-load', function () { + webContents.fromId(b.guestId).once('did-finish-load', function () { assert.equal(b.location, targetURL) b.close() done() @@ -246,10 +245,10 @@ describe('chromium feature', function () { // Load a page that definitely won't redirect var b b = window.open('about:blank') - BrowserWindow.fromId(b.guestId).webContents.once('did-finish-load', function () { + webContents.fromId(b.guestId).once('did-finish-load', function () { // When it loads, redirect b.location = 'file://' + fixtures + '/pages/base-page.html' - BrowserWindow.fromId(b.guestId).webContents.once('did-finish-load', function () { + webContents.fromId(b.guestId).once('did-finish-load', function () { // After our second redirect, cleanup and callback b.close() done() @@ -308,7 +307,7 @@ describe('chromium feature', function () { } window.addEventListener('message', listener) b = window.open('file://' + fixtures + '/pages/window-open-postMessage.html', '', 'show=no') - BrowserWindow.fromId(b.guestId).webContents.once('did-finish-load', function () { + webContents.fromId(b.guestId).once('did-finish-load', function () { b.postMessage('testing', '*') }) }) From 939ae567acb1cc7a35b0e614dfa6d1f813f74df3 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Thu, 9 Jun 2016 13:53:36 -0700 Subject: [PATCH 100/126] :art: --- lib/browser/guest-window-manager.js | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/lib/browser/guest-window-manager.js b/lib/browser/guest-window-manager.js index 78c9158f8eccd..776ab91fec966 100644 --- a/lib/browser/guest-window-manager.js +++ b/lib/browser/guest-window-manager.js @@ -91,8 +91,11 @@ const getGuestWindow = function (guestId) { if (guestContents == null) return let guestWindow = BrowserWindow.fromWebContents(guestContents) - if (guestWindow == null && guestContents.hostWebContents != null) { - guestWindow = BrowserWindow.fromWebContents(guestContents.hostWebContents) + if (guestWindow == null) { + const hostContents = guestContents.hostWebContents + if (hostContents != null) { + guestWindow = BrowserWindow.fromWebContents(hostContents) + } } return guestWindow } From 84960af793d0a43166400f5024c469ba762cfc1e Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Tue, 7 Jun 2016 15:34:17 -0700 Subject: [PATCH 101/126] Add initial chrome.i18n.getMessage API --- filenames.gypi | 1 + lib/browser/chrome-extension.js | 4 ++++ lib/renderer/chrome-api.js | 2 ++ lib/renderer/extensions/i18n.js | 34 +++++++++++++++++++++++++++++++++ 4 files changed, 41 insertions(+) create mode 100644 lib/renderer/extensions/i18n.js diff --git a/filenames.gypi b/filenames.gypi index 5f1fdc3b141f5..af1942fc36977 100644 --- a/filenames.gypi +++ b/filenames.gypi @@ -63,6 +63,7 @@ 'lib/renderer/api/remote.js', 'lib/renderer/api/screen.js', 'lib/renderer/api/web-frame.js', + 'lib/renderer/extensions/i18n.js', ], 'js2c_sources': [ 'lib/common/asar.js', diff --git a/lib/browser/chrome-extension.js b/lib/browser/chrome-extension.js index fc49f5e06be52..97bf292f9e237 100644 --- a/lib/browser/chrome-extension.js +++ b/lib/browser/chrome-extension.js @@ -115,6 +115,10 @@ ipcMain.on('CHROME_RUNTIME_CONNECT', function (event, extensionId, connectInfo) page.webContents.sendToAll(`CHROME_RUNTIME_ONCONNECT_${extensionId}`, event.sender.id, portId, connectInfo) }) +ipcMain.on('CHROME_I18N_MANIFEST', function (event, extensionId) { + event.returnValue = manifestMap[extensionId] +}) + ipcMain.on('CHROME_RUNTIME_SENDMESSAGE', function (event, extensionId, message) { const page = backgroundPages[extensionId] if (!page) { diff --git a/lib/renderer/chrome-api.js b/lib/renderer/chrome-api.js index 17c3f5bfbd1ae..b22fe743fd2d6 100644 --- a/lib/renderer/chrome-api.js +++ b/lib/renderer/chrome-api.js @@ -199,4 +199,6 @@ exports.injectTo = function (extensionId, isBackgroundPage, context) { setPopup () {}, getPopup () {} } + + chrome.i18n = require('./extensions/i18n.js') } diff --git a/lib/renderer/extensions/i18n.js b/lib/renderer/extensions/i18n.js new file mode 100644 index 0000000000000..34a559bedb39a --- /dev/null +++ b/lib/renderer/extensions/i18n.js @@ -0,0 +1,34 @@ +const {ipcRenderer} = require('electron') +const fs = require('fs') +const path = require('path') + +const getMessagesPath = (language) => { + const manifest = ipcRenderer.sendSync('CHROME_I18N_MANIFEST', chrome.runtime.id) + let messagesPath = path.join(manifest.srcDirectory, '_locales', language, 'messages.json') + if (!fs.statSyncNoException(messagesPath)) { + messagesPath = path.join(manifest.srcDirectory, '_locales', manifest.default_locale, 'messages.json') + } + return messagesPath +} + +const getMessages = (language) => { + try { + return JSON.parse(fs.readFileSync(getMessagesPath(language))) || {} + } catch (error) { + return {} + } +} + +const getLanguage = () => { + return navigator.language.replace(/-.*$/, '').toLowerCase() +} + +module.exports = { + getMessage (messageName, substitutions) { + const language = getLanguage() + const messages = getMessages(language) + if (messages.hasOwnProperty(messageName)) { + return messages[messageName].message + } + } +} From d54de73e0322d8148d5c303ace4899caded8baf6 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Tue, 7 Jun 2016 15:36:08 -0700 Subject: [PATCH 102/126] :art: --- lib/renderer/extensions/i18n.js | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/lib/renderer/extensions/i18n.js b/lib/renderer/extensions/i18n.js index 34a559bedb39a..168a29ef577f8 100644 --- a/lib/renderer/extensions/i18n.js +++ b/lib/renderer/extensions/i18n.js @@ -2,11 +2,16 @@ const {ipcRenderer} = require('electron') const fs = require('fs') const path = require('path') +const getExtensionMetadata = () => { + return ipcRenderer.sendSync('CHROME_I18N_MANIFEST', chrome.runtime.id) +} + const getMessagesPath = (language) => { - const manifest = ipcRenderer.sendSync('CHROME_I18N_MANIFEST', chrome.runtime.id) - let messagesPath = path.join(manifest.srcDirectory, '_locales', language, 'messages.json') + const {srcDirectory, default_locale} = getExtensionMetadata() + const localesDirectory = path.join(srcDirectory, '_locales') + let messagesPath = path.join(localesDirectory, language, 'messages.json') if (!fs.statSyncNoException(messagesPath)) { - messagesPath = path.join(manifest.srcDirectory, '_locales', manifest.default_locale, 'messages.json') + messagesPath = path.join(localesDirectory, default_locale, 'messages.json') } return messagesPath } From d4925e6226771f727f48da1c5bf46a75e08128e3 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Tue, 7 Jun 2016 16:03:43 -0700 Subject: [PATCH 103/126] Add initial support for placeholders and substitutions --- lib/renderer/extensions/i18n.js | 35 ++++++++++++++++++++++++++++++++- 1 file changed, 34 insertions(+), 1 deletion(-) diff --git a/lib/renderer/extensions/i18n.js b/lib/renderer/extensions/i18n.js index 168a29ef577f8..b14499e2b2080 100644 --- a/lib/renderer/extensions/i18n.js +++ b/lib/renderer/extensions/i18n.js @@ -1,3 +1,9 @@ +// Implementation of chrome.i18n.getMessage +// https://developer.chrome.com/extensions/i18n#method-getMessage +// +// Does not implement predefined messages: +// https://developer.chrome.com/extensions/i18n#overview-predefined + const {ipcRenderer} = require('electron') const fs = require('fs') const path = require('path') @@ -28,12 +34,39 @@ const getLanguage = () => { return navigator.language.replace(/-.*$/, '').toLowerCase() } +const replaceNumberedSubstitutions = (message, substitutions) => { + return message.replace(/\$(\d+)/, (_, number) => { + const index = parseInt(number, 10) - 1 + return substitutions[index] || '' + }) +} + +const replacePlaceholders = (message, placeholders, substitutions) => { + if (typeof substitutions === 'string') { + substitutions = [substitutions] + } + if (!Array.isArray(substitutions)) { + substitutions = [] + } + + if (placeholders) { + Object.keys(placeholders).forEach((name) => { + let {content} = placeholders[name] + content = replaceNumberedSubstitutions(content, substitutions) + message = message.replace(new RegExp(`\\$${name}\\$`, 'gi'), content) + }) + } + + return replaceNumberedSubstitutions(message, substitutions) +} + module.exports = { getMessage (messageName, substitutions) { const language = getLanguage() const messages = getMessages(language) if (messages.hasOwnProperty(messageName)) { - return messages[messageName].message + const {message, placeholders} = messages[messageName] + return replacePlaceholders(message, placeholders, substitutions) } } } From ea9d2dadf8a9a223e26839855eda536e3da237b5 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Tue, 7 Jun 2016 16:04:17 -0700 Subject: [PATCH 104/126] Add fixme for sync ipc --- lib/renderer/extensions/i18n.js | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/renderer/extensions/i18n.js b/lib/renderer/extensions/i18n.js index b14499e2b2080..5085365c7beb4 100644 --- a/lib/renderer/extensions/i18n.js +++ b/lib/renderer/extensions/i18n.js @@ -9,6 +9,7 @@ const fs = require('fs') const path = require('path') const getExtensionMetadata = () => { + // FIXME(kevinsawicki) Either cache this or don't use sync IPC to obtain it return ipcRenderer.sendSync('CHROME_I18N_MANIFEST', chrome.runtime.id) } From 2367cd574e11dbedf4bbc16f589d16f358881343 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Tue, 7 Jun 2016 16:10:27 -0700 Subject: [PATCH 105/126] Cache extension metadata --- lib/renderer/extensions/i18n.js | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/lib/renderer/extensions/i18n.js b/lib/renderer/extensions/i18n.js index 5085365c7beb4..d6362e3954f24 100644 --- a/lib/renderer/extensions/i18n.js +++ b/lib/renderer/extensions/i18n.js @@ -8,9 +8,13 @@ const {ipcRenderer} = require('electron') const fs = require('fs') const path = require('path') +let metadata + const getExtensionMetadata = () => { - // FIXME(kevinsawicki) Either cache this or don't use sync IPC to obtain it - return ipcRenderer.sendSync('CHROME_I18N_MANIFEST', chrome.runtime.id) + if (!metadata) { + metadata = ipcRenderer.sendSync('CHROME_I18N_MANIFEST', chrome.runtime.id) + } + return metadata } const getMessagesPath = (language) => { From 9f64c39f8c6a30f1bea4cae331ea14cfc9612ba8 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Tue, 7 Jun 2016 17:00:53 -0700 Subject: [PATCH 106/126] Remove lint warnings --- lib/renderer/chrome-api.js | 2 +- lib/renderer/extensions/i18n.js | 32 +++++++++++++++++++------------- 2 files changed, 20 insertions(+), 14 deletions(-) diff --git a/lib/renderer/chrome-api.js b/lib/renderer/chrome-api.js index b22fe743fd2d6..4a3556c37e674 100644 --- a/lib/renderer/chrome-api.js +++ b/lib/renderer/chrome-api.js @@ -200,5 +200,5 @@ exports.injectTo = function (extensionId, isBackgroundPage, context) { getPopup () {} } - chrome.i18n = require('./extensions/i18n.js') + chrome.i18n = require('./extensions/i18n.js').setup(extensionId) } diff --git a/lib/renderer/extensions/i18n.js b/lib/renderer/extensions/i18n.js index d6362e3954f24..cee0fb17aa802 100644 --- a/lib/renderer/extensions/i18n.js +++ b/lib/renderer/extensions/i18n.js @@ -10,15 +10,15 @@ const path = require('path') let metadata -const getExtensionMetadata = () => { +const getExtensionMetadata = (extensionId) => { if (!metadata) { - metadata = ipcRenderer.sendSync('CHROME_I18N_MANIFEST', chrome.runtime.id) + metadata = ipcRenderer.sendSync('CHROME_I18N_MANIFEST', extensionId) } return metadata } -const getMessagesPath = (language) => { - const {srcDirectory, default_locale} = getExtensionMetadata() +const getMessagesPath = (extensionId, language) => { + const {srcDirectory, default_locale} = getExtensionMetadata(extensionId) const localesDirectory = path.join(srcDirectory, '_locales') let messagesPath = path.join(localesDirectory, language, 'messages.json') if (!fs.statSyncNoException(messagesPath)) { @@ -27,9 +27,10 @@ const getMessagesPath = (language) => { return messagesPath } -const getMessages = (language) => { +const getMessages = (extensionId, language) => { try { - return JSON.parse(fs.readFileSync(getMessagesPath(language))) || {} + const messagesPath = getMessagesPath(extensionId, language) + return JSON.parse(fs.readFileSync(messagesPath)) || {} } catch (error) { return {} } @@ -65,13 +66,18 @@ const replacePlaceholders = (message, placeholders, substitutions) => { return replaceNumberedSubstitutions(message, substitutions) } -module.exports = { - getMessage (messageName, substitutions) { - const language = getLanguage() - const messages = getMessages(language) - if (messages.hasOwnProperty(messageName)) { - const {message, placeholders} = messages[messageName] - return replacePlaceholders(message, placeholders, substitutions) +const getMessage = (extensionId, messageName, substitutions) => { + const messages = getMessages(extensionId, getLanguage()) + if (messages.hasOwnProperty(messageName)) { + const {message, placeholders} = messages[messageName] + return replacePlaceholders(message, placeholders, substitutions) + } +} + +exports.setup = (extensionId) => { + return { + getMessage (messageName, substitutions) { + return getMessage(extensionId, messageName, substitutions) } } } From 0ed10658a3971170e6bd6b65cea63b67c4f21e4e Mon Sep 17 00:00:00 2001 From: Jessica Lord Date: Wed, 8 Jun 2016 14:57:20 -0700 Subject: [PATCH 107/126] Add spec --- spec/api-browser-window-spec.js | 1 + .../devtools-extensions/foo/_locales/en/messages.json | 10 ++++++++++ spec/fixtures/devtools-extensions/foo/index.html | 3 ++- spec/fixtures/devtools-extensions/foo/manifest.json | 3 ++- 4 files changed, 15 insertions(+), 2 deletions(-) create mode 100644 spec/fixtures/devtools-extensions/foo/_locales/en/messages.json diff --git a/spec/api-browser-window-spec.js b/spec/api-browser-window-spec.js index bad3b80a9b5c6..cf3442d59ce4e 100644 --- a/spec/api-browser-window-spec.js +++ b/spec/api-browser-window-spec.js @@ -865,6 +865,7 @@ describe('browser-window module', function () { ipcMain.once('answer', function (event, message) { assert.equal(message.runtimeId, 'foo') assert.equal(message.tabId, w.webContents.id) + assert.equal(message.i18nString, 'foo - bar (baz)') done() }) }) diff --git a/spec/fixtures/devtools-extensions/foo/_locales/en/messages.json b/spec/fixtures/devtools-extensions/foo/_locales/en/messages.json new file mode 100644 index 0000000000000..fe5653c2b4115 --- /dev/null +++ b/spec/fixtures/devtools-extensions/foo/_locales/en/messages.json @@ -0,0 +1,10 @@ +{ + "foo": { + "message": "foo - $BAZ$ ($2)", + "placeholders": { + "baz": { + "content": "$1" + } + } + } +} diff --git a/spec/fixtures/devtools-extensions/foo/index.html b/spec/fixtures/devtools-extensions/foo/index.html index 2e0a29aff3d09..414370ae2c06d 100644 --- a/spec/fixtures/devtools-extensions/foo/index.html +++ b/spec/fixtures/devtools-extensions/foo/index.html @@ -6,7 +6,8 @@ From 2efc913222464c74d4802a1480e96639eb060f0f Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Thu, 9 Jun 2016 14:17:54 -0700 Subject: [PATCH 111/126] Remove standard lint warnings --- lib/renderer/extensions/i18n.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/renderer/extensions/i18n.js b/lib/renderer/extensions/i18n.js index 913bcb26c8646..d0279601f43d8 100644 --- a/lib/renderer/extensions/i18n.js +++ b/lib/renderer/extensions/i18n.js @@ -18,9 +18,9 @@ const getExtensionMetadata = (extensionId) => { } const getMessagesPath = (extensionId, language) => { - const {srcDirectory, default_locale} = getExtensionMetadata(extensionId) - const defaultLocale = default_locale != null ? default_locale : 'en' - const localesDirectory = path.join(srcDirectory, '_locales') + const metadata = getExtensionMetadata(extensionId) + const defaultLocale = metadata.default_locale || 'en' + const localesDirectory = path.join(metadata.srcDirectory, '_locales') let messagesPath = path.join(localesDirectory, language, 'messages.json') if (!fs.statSyncNoException(messagesPath)) { messagesPath = path.join(localesDirectory, defaultLocale, 'messages.json') From d6d4d511735c1a8100d67f7cbc28ecd7ebf26ea1 Mon Sep 17 00:00:00 2001 From: Jessica Lord Date: Thu, 9 Jun 2016 16:26:25 -0700 Subject: [PATCH 112/126] Fix spec case --- spec/fixtures/devtools-extensions/foo/index.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/fixtures/devtools-extensions/foo/index.html b/spec/fixtures/devtools-extensions/foo/index.html index fffd93adf6d56..0a6b74f8eda54 100644 --- a/spec/fixtures/devtools-extensions/foo/index.html +++ b/spec/fixtures/devtools-extensions/foo/index.html @@ -6,7 +6,7 @@