From 8184cbfb06190dec4a334d04c4e80a9e2ac60f99 Mon Sep 17 00:00:00 2001 From: Ted Kim Date: Tue, 17 Oct 2017 16:28:29 +0900 Subject: [PATCH 01/18] Implement login helper to manage login item in Mac App Store build --- atom/app/atom_login_helper.mm | 11 +++++ atom/app/resources/mac/loginhelper-Info.plist | 16 ++++++++ atom/browser/browser_mac.mm | 9 +++++ atom/common/platform_util.h | 5 +++ atom/common/platform_util_mac.mm | 27 +++++++++++++ docs/api/app.md | 25 +++++------- .../mac-app-store-submission-guide.md | 4 +- electron.gyp | 40 +++++++++++++++++++ filenames.gypi | 3 ++ 9 files changed, 123 insertions(+), 17 deletions(-) create mode 100644 atom/app/atom_login_helper.mm create mode 100644 atom/app/resources/mac/loginhelper-Info.plist diff --git a/atom/app/atom_login_helper.mm b/atom/app/atom_login_helper.mm new file mode 100644 index 000000000000..327480adac20 --- /dev/null +++ b/atom/app/atom_login_helper.mm @@ -0,0 +1,11 @@ +#import + +int main(int argc, char* argv[]) { + NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; + NSArray* pathComponents = [[[NSBundle mainBundle] bundlePath] pathComponents]; + pathComponents = [pathComponents subarrayWithRange:NSMakeRange(0, [pathComponents count] - 4)]; + NSString* path = [NSString pathWithComponents:pathComponents]; + [[NSWorkspace sharedWorkspace] launchApplication:path]; + [pool drain]; + return 0; +} diff --git a/atom/app/resources/mac/loginhelper-Info.plist b/atom/app/resources/mac/loginhelper-Info.plist new file mode 100644 index 000000000000..68348d27a1eb --- /dev/null +++ b/atom/app/resources/mac/loginhelper-Info.plist @@ -0,0 +1,16 @@ + + + + + CFBundleIdentifier + ${ATOM_BUNDLE_ID} + CFBundleName + ${PRODUCT_NAME} + CFBundleExecutable + ${PRODUCT_NAME} + CFBundlePackageType + APPL + LSBackgroundOnly + + + diff --git a/atom/browser/browser_mac.mm b/atom/browser/browser_mac.mm index d187fa6cf905..d12de2c14c9d 100644 --- a/atom/browser/browser_mac.mm +++ b/atom/browser/browser_mac.mm @@ -4,6 +4,7 @@ #include "atom/browser/browser.h" +#include "atom/common/platform_util.h" #include "atom/browser/mac/atom_application.h" #include "atom/browser/mac/atom_application_delegate.h" #include "atom/browser/mac/dict_util.h" @@ -193,19 +194,27 @@ bool Browser::UpdateUserActivityState(const std::string& type, Browser::LoginItemSettings Browser::GetLoginItemSettings( const LoginItemSettings& options) { LoginItemSettings settings; +#if defined(MAS_BUILD) + settings.open_at_login = platform_util::GetLoginItemEnabled(); +#else settings.open_at_login = base::mac::CheckLoginItemStatus( &settings.open_as_hidden); settings.restore_state = base::mac::WasLaunchedAsLoginItemRestoreState(); settings.opened_at_login = base::mac::WasLaunchedAsLoginOrResumeItem(); settings.opened_as_hidden = base::mac::WasLaunchedAsHiddenLoginItem(); +#endif return settings; } void Browser::SetLoginItemSettings(LoginItemSettings settings) { +#if defined(MAS_BUILD) + platform_util::SetLoginItemEnabled(settings.open_at_login); +#else if (settings.open_at_login) base::mac::AddToLoginItems(settings.open_as_hidden); else base::mac::RemoveFromLoginItems(); +#endif } std::string Browser::GetExecutableFileVersion() const { diff --git a/atom/common/platform_util.h b/atom/common/platform_util.h index dc4b4723589b..6fd84056a06a 100644 --- a/atom/common/platform_util.h +++ b/atom/common/platform_util.h @@ -57,6 +57,11 @@ bool MoveItemToTrash(const base::FilePath& full_path); void Beep(); +#if defined(OS_MACOSX) +bool GetLoginItemEnabled(); +void SetLoginItemEnabled(bool enabled); +#endif + } // namespace platform_util #endif // ATOM_COMMON_PLATFORM_UTIL_H_ diff --git a/atom/common/platform_util_mac.mm b/atom/common/platform_util_mac.mm index b48ec51c10fe..c69d05ebbf44 100644 --- a/atom/common/platform_util_mac.mm +++ b/atom/common/platform_util_mac.mm @@ -6,6 +6,7 @@ #import #import +#import #include "base/callback.h" #include "base/files/file_path.h" @@ -98,6 +99,10 @@ std::string OpenURL(NSURL* ns_url, bool activate) { return ""; } +NSString* GetLoginHelperBundleIdentifier() { + return [[[NSBundle mainBundle] bundleIdentifier] stringByAppendingString:@".loginhelper"]; +} + } // namespace namespace platform_util { @@ -177,4 +182,26 @@ void Beep() { NSBeep(); } +bool GetLoginItemEnabled() { + BOOL enabled = NO; + // SMJobCopyDictionary does not work in sandbox (see rdar://13626319) + CFArrayRef jobs = SMCopyAllJobDictionaries(kSMDomainUserLaunchd); + NSArray* jobs_ = CFBridgingRelease(jobs); + NSString* identifier = GetLoginHelperBundleIdentifier(); + if (jobs_ && [jobs_ count] > 0) { + for (NSDictionary* job in jobs_) { + if ([identifier isEqualToString:[job objectForKey:@"Label"]]) { + enabled = [[job objectForKey:@"OnDemand"] boolValue]; + break; + } + } + } + return enabled; +} + +void SetLoginItemEnabled(bool enabled) { + NSString* identifier = GetLoginHelperBundleIdentifier(); + SMLoginItemSetEnabled((__bridge CFStringRef) identifier, enabled); +} + } // namespace platform_util diff --git a/docs/api/app.md b/docs/api/app.md index f7ff23e3a755..ff37e9898609 100644 --- a/docs/api/app.md +++ b/docs/api/app.md @@ -893,30 +893,27 @@ need to pass the same arguments here for `openAtLogin` to be set correctly. Returns `Object`: * `openAtLogin` Boolean - `true` if the app is set to open at login. -* `openAsHidden` Boolean - `true` if the app is set to open as hidden at login. - This setting is only supported on macOS. -* `wasOpenedAtLogin` Boolean - `true` if the app was opened at login - automatically. This setting is only supported on macOS. -* `wasOpenedAsHidden` Boolean - `true` if the app was opened as a hidden login +* `openAsHidden` Boolean _macOS_ - `true` if the app is set to open as hidden at login. + This setting is not available on [MAS builds][mas-builds]. +* `wasOpenedAtLogin` Boolean _macOS_ - `true` if the app was opened at login + automatically. This setting is not available on [MAS builds][mas-builds]. +* `wasOpenedAsHidden` Boolean _macOS_ - `true` if the app was opened as a hidden login item. This indicates that the app should not open any windows at startup. - This setting is only supported on macOS. -* `restoreState` Boolean - `true` if the app was opened as a login item that + This setting is not available on [MAS builds][mas-builds]. +* `restoreState` Boolean _macOS_ - `true` if the app was opened as a login item that should restore the state from the previous session. This indicates that the app should restore the windows that were open the last time the app was - closed. This setting is only supported on macOS. - -**Note:** This API has no effect on [MAS builds][mas-builds]. + closed. This setting is not available on [MAS builds][mas-builds]. ### `app.setLoginItemSettings(settings)` _macOS_ _Windows_ * `settings` Object * `openAtLogin` Boolean (optional) - `true` to open the app at login, `false` to remove the app as a login item. Defaults to `false`. - * `openAsHidden` Boolean (optional) - `true` to open the app as hidden. Defaults to + * `openAsHidden` Boolean (optional) _macOS_ - `true` to open the app as hidden. Defaults to `false`. The user can edit this setting from the System Preferences so `app.getLoginItemStatus().wasOpenedAsHidden` should be checked when the app - is opened to know the current value. This setting is only supported on - macOS. + is opened to know the current value. This setting is not available on [MAS builds][mas-builds]. * `path` String (optional) _Windows_ - The executable to launch at login. Defaults to `process.execPath`. * `args` String[] (optional) _Windows_ - The command-line arguments to pass to @@ -944,8 +941,6 @@ app.setLoginItemSettings({ }) ``` -**Note:** This API has no effect on [MAS builds][mas-builds]. - ### `app.isAccessibilitySupportEnabled()` _macOS_ _Windows_ Returns `Boolean` - `true` if Chrome's accessibility support is enabled, diff --git a/docs/tutorial/mac-app-store-submission-guide.md b/docs/tutorial/mac-app-store-submission-guide.md index 10c59906a2b8..4f85e347fcdc 100644 --- a/docs/tutorial/mac-app-store-submission-guide.md +++ b/docs/tutorial/mac-app-store-submission-guide.md @@ -110,6 +110,8 @@ codesign -s "$APP_KEY" -f --entitlements "$CHILD_PLIST" "$FRAMEWORKS_PATH/$APP H 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 "$PARENT_PLIST" "$APP_PATH/Contents/Library/LoginItems/$APP Login Helper.app/Contents/MacOS/$APP Login Helper" +codesign -s "$APP_KEY" -f --entitlements "$PARENT_PLIST" "$APP_PATH/Contents/Library/LoginItems/$APP Login Helper.app/" codesign -s "$APP_KEY" -f --entitlements "$CHILD_PLIST" "$APP_PATH/Contents/MacOS/$APP" codesign -s "$APP_KEY" -f --entitlements "$PARENT_PLIST" "$APP_PATH" @@ -162,8 +164,6 @@ and the following behaviors have been changed: * Video capture may not work for some machines. * Certain accessibility features may not work. * Apps will not be aware of DNS changes. -* APIs for launching apps at login are disabled. See -https://github.com/electron/electron/issues/7312#issuecomment-249479237 Also, due to the usage of app sandboxing, the resources which can be accessed by the app are strictly limited; you can read [App Sandboxing][app-sandboxing] for diff --git a/electron.gyp b/electron.gyp index aa81d930683d..dbb38630ccfa 100644 --- a/electron.gyp +++ b/electron.gyp @@ -122,6 +122,19 @@ }, ], }], + ['mas_build==1', { + 'dependencies': [ + '<(project_name)_login_helper', + ], + 'copies': [ + { + 'destination': '<(PRODUCT_DIR)/<(product_name).app/Contents/Library/LoginItems', + 'files': [ + '<(PRODUCT_DIR)/<(product_name) Login Helper.app', + ], + }, + ], + }], ], }], # OS!="mac" ['OS=="win"', { @@ -566,6 +579,7 @@ '$(SDKROOT)/System/Library/Frameworks/Quartz.framework', '$(SDKROOT)/System/Library/Frameworks/Security.framework', '$(SDKROOT)/System/Library/Frameworks/SecurityInterface.framework', + '$(SDKROOT)/System/Library/Frameworks/ServiceManagement.framework', ], }, 'mac_bundle': 1, @@ -684,6 +698,32 @@ ], }, }, # target helper + { + 'target_name': '<(project_name)_login_helper', + 'product_name': '<(product_name) Login Helper', + 'type': 'executable', + 'sources': [ + '<@(login_helper_sources)', + ], + 'include_dirs': [ + '.', + 'vendor', + '<(libchromiumcontent_src_dir)', + ], + 'link_settings': { + 'libraries': [ + '$(SDKROOT)/System/Library/Frameworks/AppKit.framework', + ], + }, + 'mac_bundle': 1, + 'xcode_settings': { + 'ATOM_BUNDLE_ID': 'com.<(company_abbr).<(project_name).loginhelper', + 'INFOPLIST_FILE': 'atom/app/resources/mac/loginhelper-Info.plist', + 'OTHER_LDFLAGS': [ + '-ObjC', + ], + }, + }, # target login_helper ], }], # OS!="mac" ], diff --git a/filenames.gypi b/filenames.gypi index efe5c5f854d8..f7a3ac145bd6 100644 --- a/filenames.gypi +++ b/filenames.gypi @@ -665,6 +665,9 @@ 'atom/app/atom_library_main.h', 'atom/app/atom_library_main.mm', ], + 'login_helper_sources': [ + 'atom/app/atom_login_helper.mm', + ], 'locales': [ 'am', 'ar', 'bg', 'bn', 'ca', 'cs', 'da', 'de', 'el', 'en-GB', 'en-US', 'es-419', 'es', 'et', 'fa', 'fi', 'fil', 'fr', 'gu', 'he', From ada71eea39eaa5df6a0dfd63e7d8843c4e32c195 Mon Sep 17 00:00:00 2001 From: Taeho Kim Date: Sat, 21 Oct 2017 20:52:20 +0900 Subject: [PATCH 02/18] =?UTF-8?q?=F0=9F=93=9D=20Use=20separate=20entitleme?= =?UTF-8?q?nts=20for=20login=20helper?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../mac-app-store-submission-guide.md | 20 ++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/docs/tutorial/mac-app-store-submission-guide.md b/docs/tutorial/mac-app-store-submission-guide.md index 4f85e347fcdc..e0b3cd083c0a 100644 --- a/docs/tutorial/mac-app-store-submission-guide.md +++ b/docs/tutorial/mac-app-store-submission-guide.md @@ -45,7 +45,7 @@ has your Team ID as value: ``` -Then, you need to prepare two entitlements files. +Then, you need to prepare three entitlements files. `child.plist`: @@ -77,6 +77,19 @@ Then, you need to prepare two entitlements files. ``` +`loginhelper.plist`: + +```xml + + + + + com.apple.security.app-sandbox + + + +``` + You have to replace `TEAM_ID` with your Team ID, and replace `your.bundle.id` with the Bundle ID of your app. @@ -97,6 +110,7 @@ INSTALLER_KEY="3rd Party Mac Developer Installer: Company Name (APPIDENTITY)" # The path of your plist files. CHILD_PLIST="/path/to/child.plist" PARENT_PLIST="/path/to/parent.plist" +LOGINHELPER_PLIST="/path/to/loginhelper.plist" FRAMEWORKS_PATH="$APP_PATH/Contents/Frameworks" @@ -110,8 +124,8 @@ codesign -s "$APP_KEY" -f --entitlements "$CHILD_PLIST" "$FRAMEWORKS_PATH/$APP H 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 "$PARENT_PLIST" "$APP_PATH/Contents/Library/LoginItems/$APP Login Helper.app/Contents/MacOS/$APP Login Helper" -codesign -s "$APP_KEY" -f --entitlements "$PARENT_PLIST" "$APP_PATH/Contents/Library/LoginItems/$APP Login Helper.app/" +codesign -s "$APP_KEY" -f --entitlements "$LOGINHELPER_PLIST" "$APP_PATH/Contents/Library/LoginItems/$APP Login Helper.app/Contents/MacOS/$APP Login Helper" +codesign -s "$APP_KEY" -f --entitlements "$LOGINHELPER_PLIST" "$APP_PATH/Contents/Library/LoginItems/$APP Login Helper.app/" codesign -s "$APP_KEY" -f --entitlements "$CHILD_PLIST" "$APP_PATH/Contents/MacOS/$APP" codesign -s "$APP_KEY" -f --entitlements "$PARENT_PLIST" "$APP_PATH" From d9481430dfa07c1028285d5aee56f55ed6f8dabf Mon Sep 17 00:00:00 2001 From: Ted Kim Date: Fri, 17 Nov 2017 10:49:23 +0900 Subject: [PATCH 03/18] Fix test failure --- spec/api-app-spec.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/api-app-spec.js b/spec/api-app-spec.js index 5624c319bf37..2997966f5575 100644 --- a/spec/api-app-spec.js +++ b/spec/api-app-spec.js @@ -360,7 +360,7 @@ describe('app module', () => { app.setLoginItemSettings({openAtLogin: true, openAsHidden: true}) assert.deepEqual(app.getLoginItemSettings(), { openAtLogin: true, - openAsHidden: process.platform === 'darwin', // Only available on macOS + openAsHidden: process.platform === 'darwin' && !process.mas, // Only available on macOS wasOpenedAtLogin: false, wasOpenedAsHidden: false, restoreState: false From 1660fc8d139813cfa85944fe3851dfcfcf827845 Mon Sep 17 00:00:00 2001 From: Ted Kim Date: Mon, 20 Nov 2017 10:15:45 +0900 Subject: [PATCH 04/18] Fix getLoginItemSettings timing issue --- spec/api-app-spec.js | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/spec/api-app-spec.js b/spec/api-app-spec.js index 2997966f5575..6f028b09e9c0 100644 --- a/spec/api-app-spec.js +++ b/spec/api-app-spec.js @@ -347,7 +347,7 @@ describe('app module', () => { app.setLoginItemSettings({openAtLogin: false, path: updateExe, args: processStartArgs}) }) - it('returns the login item status of the app', () => { + it('returns the login item status of the app', (done) => { app.setLoginItemSettings({openAtLogin: true}) assert.deepEqual(app.getLoginItemSettings(), { openAtLogin: true, @@ -367,13 +367,18 @@ describe('app module', () => { }) app.setLoginItemSettings({}) - assert.deepEqual(app.getLoginItemSettings(), { - openAtLogin: false, - openAsHidden: false, - wasOpenedAtLogin: false, - wasOpenedAsHidden: false, - restoreState: false - }) + // Wait because login item settings are not applied immediately in MAS build + const delay = process.mas ? 100 : 0; + setTimeout(() => { + assert.deepEqual(app.getLoginItemSettings(), { + openAtLogin: false, + openAsHidden: false, + wasOpenedAtLogin: false, + wasOpenedAsHidden: false, + restoreState: false + }) + done() + }, delay); }) it('allows you to pass a custom executable and arguments', () => { From 71c16ad76f0390e7bc2e507375c599ff0a460fdf Mon Sep 17 00:00:00 2001 From: Ted Kim Date: Mon, 20 Nov 2017 10:17:34 +0900 Subject: [PATCH 05/18] lint --- spec/api-app-spec.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/spec/api-app-spec.js b/spec/api-app-spec.js index 6f028b09e9c0..73971d9b50bf 100644 --- a/spec/api-app-spec.js +++ b/spec/api-app-spec.js @@ -368,7 +368,7 @@ describe('app module', () => { app.setLoginItemSettings({}) // Wait because login item settings are not applied immediately in MAS build - const delay = process.mas ? 100 : 0; + const delay = process.mas ? 100 : 0 setTimeout(() => { assert.deepEqual(app.getLoginItemSettings(), { openAtLogin: false, @@ -378,7 +378,7 @@ describe('app module', () => { restoreState: false }) done() - }, delay); + }, delay) }) it('allows you to pass a custom executable and arguments', () => { From 19df1cf07084572f2300677f9159bf54401de218 Mon Sep 17 00:00:00 2001 From: Felix Rieseberg Date: Thu, 23 Nov 2017 13:41:14 -0800 Subject: [PATCH 06/18] :package: Upgrade to StandardJS 10 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 14c3ba9421db..acf290904f64 100644 --- a/package.json +++ b/package.json @@ -20,7 +20,7 @@ "remark-cli": "^4.0.0", "remark-preset-lint-markdown-style-guide": "^2.1.1", "request": "^2.68.0", - "standard": "^8.4.0", + "standard": "^10.0.0", "standard-markdown": "^4.0.0", "sumchecker": "^2.0.2", "temp": "^0.8.3" From 451a44c4b5c9156063e1dac60d01722f0e7136b7 Mon Sep 17 00:00:00 2001 From: Felix Rieseberg Date: Thu, 23 Nov 2017 13:41:47 -0800 Subject: [PATCH 07/18] =?UTF-8?q?:wrench:=20Don=E2=80=99t=20use=20deprecat?= =?UTF-8?q?ed=20`new=20Buffer()`?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/common/asar.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/lib/common/asar.js b/lib/common/asar.js index e35efc279958..6eaddebf2618 100644 --- a/lib/common/asar.js +++ b/lib/common/asar.js @@ -482,7 +482,7 @@ } if (info.size === 0) { return process.nextTick(function () { - callback(null, encoding ? '' : new Buffer(0)) + callback(null, encoding ? '' : Buffer.alloc(0)) }) } if (info.unpacked) { @@ -490,7 +490,7 @@ return fs.readFile(realPath, options, callback) } - const buffer = new Buffer(info.size) + const buffer = Buffer.alloc(info.size) const fd = archive.getFd() if (!(fd >= 0)) { return notFoundError(asarPath, filePath, callback) @@ -519,7 +519,7 @@ if (options) { return '' } else { - return new Buffer(0) + return Buffer.alloc(0) } } if (info.unpacked) { @@ -538,7 +538,7 @@ throw new TypeError('Bad arguments') } const {encoding} = options - const buffer = new Buffer(info.size) + const buffer = Buffer.alloc(info.size) const fd = archive.getFd() if (!(fd >= 0)) { notFoundError(asarPath, filePath) @@ -611,7 +611,7 @@ encoding: 'utf8' }) } - const buffer = new Buffer(info.size) + const buffer = Buffer.alloc(info.size) const fd = archive.getFd() if (!(fd >= 0)) { return From d0ef834b4fd87e7613ff7669e45b1c4d19b7e3ce Mon Sep 17 00:00:00 2001 From: Felix Rieseberg Date: Thu, 23 Nov 2017 13:42:09 -0800 Subject: [PATCH 08/18] :wrench: Remove redundant `await` statements --- script/merge-release.js | 10 +++++----- script/release.js | 6 +++--- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/script/merge-release.js b/script/merge-release.js index 60ac3acb244c..8917da4f2f23 100755 --- a/script/merge-release.js +++ b/script/merge-release.js @@ -31,7 +31,7 @@ async function checkoutBranch (branchName) { console.log(`Checking out ${branchName}.`) let errorMessage = `Error checking out branch ${branchName}:` let successMessage = `Successfully checked out branch ${branchName}.` - return await callGit(['checkout', branchName], errorMessage, successMessage) + return callGit(['checkout', branchName], errorMessage, successMessage) } async function commitMerge () { @@ -39,7 +39,7 @@ async function commitMerge () { let errorMessage = `Error committing merge:` let successMessage = `Successfully committed the merge for v${pkg.version}` let gitArgs = ['commit', '-m', `v${pkg.version}`] - return await callGit(gitArgs, errorMessage, successMessage) + return callGit(gitArgs, errorMessage, successMessage) } async function mergeReleaseIntoBranch (branchName) { @@ -67,14 +67,14 @@ async function pushBranch (branchName) { let pushArgs = ['push', 'origin', branchName] let errorMessage = `Could not push branch ${branchName} due to an error:` let successMessage = `Successfully pushed branch ${branchName}.` - return await callGit(pushArgs, errorMessage, successMessage) + return callGit(pushArgs, errorMessage, successMessage) } async function pull () { console.log(`Performing a git pull`) let errorMessage = `Could not pull due to an error:` let successMessage = `Successfully performed a git pull` - return await callGit(['pull'], errorMessage, successMessage) + return callGit(['pull'], errorMessage, successMessage) } async function rebase (targetBranch) { @@ -82,7 +82,7 @@ async function rebase (targetBranch) { let errorMessage = `Could not rebase due to an error:` let successMessage = `Successfully rebased release branch from ` + `${targetBranch}` - return await callGit(['rebase', targetBranch], errorMessage, successMessage) + return callGit(['rebase', targetBranch], errorMessage, successMessage) } async function mergeRelease () { diff --git a/script/release.js b/script/release.js index 42c55b5cee3b..5b62d529bd09 100755 --- a/script/release.js +++ b/script/release.js @@ -213,7 +213,7 @@ async function uploadShasumFile (filePath, fileName, release) { filePath, name: fileName } - return await github.repos.uploadAsset(githubOpts) + return github.repos.uploadAsset(githubOpts) .catch(err => { console.log(`${fail} Error uploading ${filePath} to GitHub:`, err) process.exit(1) @@ -248,7 +248,7 @@ async function publishRelease (release) { tag_name: release.tag_name, draft: false } - return await github.repos.editRelease(githubOpts) + return github.repos.editRelease(githubOpts) .catch(err => { console.log(`${fail} Error publishing release:`, err) process.exit(1) @@ -445,7 +445,7 @@ async function cleanupReleaseBranch () { await callGit(['branch', '-D', 'release'], errorMessage, successMessage) errorMessage = `Could not delete remote release branch.` successMessage = `Successfully deleted remote release branch.` - return await callGit(['push', 'origin', ':release'], errorMessage, successMessage) + return callGit(['push', 'origin', ':release'], errorMessage, successMessage) } async function callGit (args, errorMessage, successMessage) { From 97a084a591e2589f3599bd0a58a8e33e2c4e57d6 Mon Sep 17 00:00:00 2001 From: Felix Rieseberg Date: Thu, 23 Nov 2017 13:42:31 -0800 Subject: [PATCH 09/18] :wrench: Script: Reject with error --- script/ci-release-build.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/script/ci-release-build.js b/script/ci-release-build.js index 27461f95a47d..275ef98e9e38 100644 --- a/script/ci-release-build.js +++ b/script/ci-release-build.js @@ -31,7 +31,7 @@ async function makeRequest (requestOptions, parseResponse) { } else { console.log('Error: ', `(status ${res.statusCode})`, err || res.body, requestOptions) } - reject() + reject(err) } }) }) From f81bfb7b86589d7f199a44013c0279077adc2d49 Mon Sep 17 00:00:00 2001 From: Felix Rieseberg Date: Thu, 23 Nov 2017 13:42:48 -0800 Subject: [PATCH 10/18] :wrench: Fix style issues --- default_app/main.js | 1 - lib/browser/api/auto-updater/squirrel-update-win.js | 6 +++--- lib/browser/api/net.js | 3 --- lib/browser/api/web-contents.js | 1 + 4 files changed, 4 insertions(+), 7 deletions(-) diff --git a/default_app/main.js b/default_app/main.js index ce77a15362d3..7fdfc7c3fa36 100644 --- a/default_app/main.js +++ b/default_app/main.js @@ -306,7 +306,6 @@ function startRepl () { if (process.platform === 'win32') { console.error('Electron REPL not currently supported on Windows') process.exit(1) - return } const repl = require('repl') diff --git a/lib/browser/api/auto-updater/squirrel-update-win.js b/lib/browser/api/auto-updater/squirrel-update-win.js index 60345f1a1abe..d82577bcf483 100644 --- a/lib/browser/api/auto-updater/squirrel-update-win.js +++ b/lib/browser/api/auto-updater/squirrel-update-win.js @@ -28,7 +28,7 @@ var spawnUpdate = function (args, detached, callback) { // Process spawned, different args: Return with error // No process spawned: Spawn new process if (spawnedProcess && !isSameArgs(args)) { - return callback('AutoUpdater process with arguments ' + args + ' is already running') + return callback(`AutoUpdater process with arguments ${args} is already running`) } else if (!spawnedProcess) { spawnedProcess = spawn(updateExe, args, { detached: detached @@ -68,7 +68,7 @@ var spawnUpdate = function (args, detached, callback) { // Process terminated with error. if (code !== 0) { - return callback('Command failed: ' + (signal != null ? signal : code) + '\n' + stderr) + return callback(`Command failed: ${signal != null ? signal : code}\n${stderr}`) } // Success. @@ -93,7 +93,7 @@ exports.checkForUpdate = function (updateURL, callback) { json = stdout.trim().split('\n').pop() update = (ref = JSON.parse(json)) != null ? (ref1 = ref.releasesToApply) != null ? typeof ref1.pop === 'function' ? ref1.pop() : void 0 : void 0 : void 0 } catch (jsonError) { - return callback('Invalid result:\n' + stdout) + return callback(`Invalid result:\n${stdout}`) } return callback(null, update) }) diff --git a/lib/browser/api/net.js b/lib/browser/api/net.js index d588e238d43a..54ef99d407ff 100644 --- a/lib/browser/api/net.js +++ b/lib/browser/api/net.js @@ -79,7 +79,6 @@ class IncomingMessage extends Readable { this.shouldPush = true this._pushInternalData() } - } URLRequest.prototype._emitRequestEvent = function (isAsync, ...rest) { @@ -103,7 +102,6 @@ URLRequest.prototype._emitResponseEvent = function (isAsync, ...rest) { } class ClientRequest extends EventEmitter { - constructor (options, callback) { super() @@ -354,7 +352,6 @@ class ClientRequest extends EventEmitter { abort () { this.urlRequest.cancel() } - } function writeAfterEndNT (self, error, callback) { diff --git a/lib/browser/api/web-contents.js b/lib/browser/api/web-contents.js index 61b37f773317..f770dbb31b3c 100644 --- a/lib/browser/api/web-contents.js +++ b/lib/browser/api/web-contents.js @@ -6,6 +6,7 @@ const {app, ipcMain, session, NavigationController} = electron // session is not used here, the purpose is to make sure session is initalized // before the webContents module. +// eslint-disable-next-line session let nextId = 0 From f7d6e3fa7bb703e00410ce729661a91f02e97b0b Mon Sep 17 00:00:00 2001 From: Felix Rieseberg Date: Thu, 23 Nov 2017 13:53:03 -0800 Subject: [PATCH 11/18] :wrench: Disable standard/no-callback-literal where necessary --- lib/browser/api/auto-updater/squirrel-update-win.js | 6 ++++++ lib/browser/api/session.js | 2 ++ lib/browser/chrome-extension.js | 4 ++++ lib/common/asar.js | 2 ++ lib/renderer/chrome-api.js | 2 ++ lib/renderer/extensions/storage.js | 5 +++++ 6 files changed, 21 insertions(+) diff --git a/lib/browser/api/auto-updater/squirrel-update-win.js b/lib/browser/api/auto-updater/squirrel-update-win.js index d82577bcf483..b0813d1fcdda 100644 --- a/lib/browser/api/auto-updater/squirrel-update-win.js +++ b/lib/browser/api/auto-updater/squirrel-update-win.js @@ -28,6 +28,8 @@ var spawnUpdate = function (args, detached, callback) { // Process spawned, different args: Return with error // No process spawned: Spawn new process if (spawnedProcess && !isSameArgs(args)) { + // Disabled for backwards compatibility: + // eslint-disable-next-line standard/no-callback-literal return callback(`AutoUpdater process with arguments ${args} is already running`) } else if (!spawnedProcess) { spawnedProcess = spawn(updateExe, args, { @@ -68,6 +70,8 @@ var spawnUpdate = function (args, detached, callback) { // Process terminated with error. if (code !== 0) { + // Disabled for backwards compatibility: + // eslint-disable-next-line standard/no-callback-literal return callback(`Command failed: ${signal != null ? signal : code}\n${stderr}`) } @@ -93,6 +97,8 @@ exports.checkForUpdate = function (updateURL, callback) { json = stdout.trim().split('\n').pop() update = (ref = JSON.parse(json)) != null ? (ref1 = ref.releasesToApply) != null ? typeof ref1.pop === 'function' ? ref1.pop() : void 0 : void 0 : void 0 } catch (jsonError) { + // Disabled for backwards compatibility: + // eslint-disable-next-line standard/no-callback-literal return callback(`Invalid result:\n${stdout}`) } return callback(null, update) diff --git a/lib/browser/api/session.js b/lib/browser/api/session.js index 33f3b47dee0e..6c103d25d623 100644 --- a/lib/browser/api/session.js +++ b/lib/browser/api/session.js @@ -26,6 +26,8 @@ Session.prototype.setCertificateVerifyProc = function (verifyProc) { // TODO(kevinsawicki): Remove in 2.0, deprecate before then with warnings this._setCertificateVerifyProc(({hostname, certificate, verificationResult}, cb) => { verifyProc(hostname, certificate, (result) => { + // Disabled due to false positive in StandardJS + // eslint-disable-next-line standard/no-callback-literal cb(result ? 0 : -2) }) }) diff --git a/lib/browser/chrome-extension.js b/lib/browser/chrome-extension.js index 868e07e96096..af88438d33dd 100644 --- a/lib/browser/chrome-extension.js +++ b/lib/browser/chrome-extension.js @@ -311,6 +311,8 @@ const chromeExtensionHandler = function (request, callback) { const page = backgroundPages[parsed.hostname] if (page && parsed.path === `/${page.name}`) { + // Disabled due to false positive in StandardJS + // eslint-disable-next-line standard/no-callback-literal return callback({ mimeType: 'text/html', data: page.html @@ -319,6 +321,8 @@ const chromeExtensionHandler = function (request, callback) { fs.readFile(path.join(manifest.srcDirectory, parsed.path), function (err, content) { if (err) { + // Disabled due to false positive in StandardJS + // eslint-disable-next-line standard/no-callback-literal return callback(-6) // FILE_NOT_FOUND } else { return callback(content) diff --git a/lib/common/asar.js b/lib/common/asar.js index 6eaddebf2618..1b9a993a2e67 100644 --- a/lib/common/asar.js +++ b/lib/common/asar.js @@ -367,6 +367,8 @@ return invalidArchiveError(asarPath, callback) } process.nextTick(function () { + // Disabled due to false positive in StandardJS + // eslint-disable-next-line standard/no-callback-literal callback(archive.stat(filePath) !== false) }) } diff --git a/lib/renderer/chrome-api.js b/lib/renderer/chrome-api.js index 1b509178f49e..07b940675b30 100644 --- a/lib/renderer/chrome-api.js +++ b/lib/renderer/chrome-api.js @@ -147,6 +147,8 @@ exports.injectTo = function (extensionId, isBackgroundPage, context) { executeScript (tabId, details, callback) { const requestId = ++nextId ipcRenderer.once(`CHROME_TABS_EXECUTESCRIPT_RESULT_${requestId}`, (event, result) => { + // Disabled due to false positive in StandardJS + // eslint-disable-next-line standard/no-callback-literal callback([event.result]) }) ipcRenderer.send('CHROME_TABS_EXECUTESCRIPT', requestId, tabId, extensionId, details) diff --git a/lib/renderer/extensions/storage.js b/lib/renderer/extensions/storage.js index 2920a2860e03..f2a560f81c2c 100644 --- a/lib/renderer/extensions/storage.js +++ b/lib/renderer/extensions/storage.js @@ -51,6 +51,8 @@ const getStorage = (storageType, extensionId, cb) => { if (data !== null) { cb(JSON.parse(data)) } else { + // Disabled due to false positive in StandardJS + // eslint-disable-next-line standard/no-callback-literal cb({}) } }) @@ -82,6 +84,9 @@ const getStorageManager = (storageType, extensionId) => { } break } + + // Disabled due to false positive in StandardJS + // eslint-disable-next-line standard/no-callback-literal if (keys.length === 0) return callback({}) let items = {} From 0278e380de36977ec853ec610c192a08dd2a0101 Mon Sep 17 00:00:00 2001 From: Felix Rieseberg Date: Thu, 23 Nov 2017 14:22:31 -0800 Subject: [PATCH 12/18] =?UTF-8?q?:wrench:=20Spec:=20Don=E2=80=99t=20use=20?= =?UTF-8?q?deprecated=20`new=20Buffer()`?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- spec/api-browser-window-spec.js | 4 ++-- spec/api-ipc-spec.js | 4 ++-- spec/api-protocol-spec.js | 6 +++--- spec/api-session-spec.js | 4 ++-- spec/asar-spec.js | 6 +++--- spec/node-spec.js | 8 ++++---- 6 files changed, 16 insertions(+), 16 deletions(-) diff --git a/spec/api-browser-window-spec.js b/spec/api-browser-window-spec.js index 2adc82df05d0..066d47d9b708 100644 --- a/spec/api-browser-window-spec.js +++ b/spec/api-browser-window-spec.js @@ -27,7 +27,7 @@ describe('BrowserWindow module', () => { postData = [ { type: 'rawData', - bytes: new Buffer('username=test&file=') + bytes: Buffer.from('username=test&file=') }, { type: 'file', @@ -270,7 +270,7 @@ describe('BrowserWindow module', () => { assert.equal(isMainFrame, true) done() }) - const data = new Buffer(2 * 1024 * 1024).toString('base64') + const data = Buffer.alloc(2 * 1024 * 1024).toString('base64') w.loadURL(`data:image/png;base64,${data}`) }) diff --git a/spec/api-ipc-spec.js b/spec/api-ipc-spec.js index 79f7c0927037..4bb563184ad2 100644 --- a/spec/api-ipc-spec.js +++ b/spec/api-ipc-spec.js @@ -145,7 +145,7 @@ describe('ipc module', () => { describe('remote.createFunctionWithReturnValue', () => { it('should be called in browser synchronously', () => { - const buf = new Buffer('test') + const buf = Buffer.from('test') const call = remote.require(path.join(fixtures, 'module', 'call.js')) const result = call.call(remote.createFunctionWithReturnValue(buf)) assert.equal(result.constructor.name, 'Buffer') @@ -239,7 +239,7 @@ describe('ipc module', () => { const printName = remote.require(print) it('keeps its constructor name for objects', () => { - const buf = new Buffer('test') + const buf = Buffer.from('test') assert.equal(printName.print(buf), 'Buffer') }) diff --git a/spec/api-protocol-spec.js b/spec/api-protocol-spec.js index 2d76d49c6a53..a9d69867157b 100644 --- a/spec/api-protocol-spec.js +++ b/spec/api-protocol-spec.js @@ -28,7 +28,7 @@ describe('protocol module', () => { const body = stream.PassThrough() async function sendChunks () { - let buf = new Buffer(data) + let buf = Buffer.from(data) for (;;) { body.push(buf.slice(0, chunkSize)) buf = buf.slice(chunkSize) @@ -204,7 +204,7 @@ describe('protocol module', () => { }) describe('protocol.registerBufferProtocol', () => { - const buffer = new Buffer(text) + const buffer = Buffer.from(text) it('sends Buffer as response', (done) => { const handler = (request, callback) => callback(buffer) protocol.registerBufferProtocol(protocolName, handler, (error) => { @@ -767,7 +767,7 @@ describe('protocol module', () => { describe('protocol.interceptBufferProtocol', () => { it('can intercept http protocol', (done) => { - const handler = (request, callback) => callback(new Buffer(text)) + const handler = (request, callback) => callback(Buffer.from(text)) protocol.interceptBufferProtocol('http', handler, (error) => { if (error) return done(error) $.ajax({ diff --git a/spec/api-session-spec.js b/spec/api-session-spec.js index 54235a334a54..50504ccadae1 100644 --- a/spec/api-session-spec.js +++ b/spec/api-session-spec.js @@ -242,7 +242,7 @@ describe('session module', () => { }) it('can cancel default download behavior', (done) => { - const mockFile = new Buffer(1024) + const mockFile = Buffer.alloc(1024) const contentDisposition = 'inline; filename="mockFile.txt"' const downloadServer = http.createServer((req, res) => { res.writeHead(200, { @@ -271,7 +271,7 @@ describe('session module', () => { }) describe('DownloadItem', () => { - const mockPDF = new Buffer(1024 * 1024 * 5) + const mockPDF = Buffer.alloc(1024 * 1024 * 5) let contentDisposition = 'inline; filename="mock.pdf"' const downloadFilePath = path.join(fixtures, 'mock.pdf') const downloadServer = http.createServer((req, res) => { diff --git a/spec/asar-spec.js b/spec/asar-spec.js index 31f15ef77284..f87554f32e26 100644 --- a/spec/asar-spec.js +++ b/spec/asar-spec.js @@ -15,7 +15,7 @@ describe('asar package', function () { describe('node api', function () { it('supports paths specified as a Buffer', function () { - var file = new Buffer(path.join(fixtures, 'asar', 'a.asar', 'file1')) + var file = Buffer.from(path.join(fixtures, 'asar', 'a.asar', 'file1')) assert.equal(fs.existsSync(file), true) }) @@ -491,7 +491,7 @@ describe('asar package', function () { file = ref2[j] p = path.join(fixtures, 'asar', 'a.asar', file) fd = fs.openSync(p, 'r') - buffer = new Buffer(6) + buffer = Buffer.alloc(6) fs.readSync(fd, buffer, 0, 6, 0) assert.equal(String(buffer).trim(), 'file1') fs.closeSync(fd) @@ -512,7 +512,7 @@ describe('asar package', function () { var p = path.join(fixtures, 'asar', 'a.asar', 'file1') fs.open(p, 'r', function (err, fd) { assert.equal(err, null) - var buffer = new Buffer(6) + var buffer = Buffer.alloc(6) fs.read(fd, buffer, 0, 6, 0, function (err) { assert.equal(err, null) assert.equal(String(buffer).trim(), 'file1') diff --git a/spec/node-spec.js b/spec/node-spec.js index 57cb31e2b528..ae639167ff07 100644 --- a/spec/node-spec.js +++ b/spec/node-spec.js @@ -274,7 +274,7 @@ describe('node feature', () => { it('can be created from WebKit external string', () => { const p = document.createElement('p') p.innerText = '闲云潭影日悠悠,物换星移几度秋' - const b = new Buffer(p.innerText) + const b = Buffer.from(p.innerText) assert.equal(b.toString(), '闲云潭影日悠悠,物换星移几度秋') assert.equal(Buffer.byteLength(p.innerText), 45) }) @@ -282,15 +282,15 @@ describe('node feature', () => { it('correctly parses external one-byte UTF8 string', () => { const p = document.createElement('p') p.innerText = 'Jøhänñéß' - const b = new Buffer(p.innerText) + const b = Buffer.from(p.innerText) assert.equal(b.toString(), 'Jøhänñéß') assert.equal(Buffer.byteLength(p.innerText), 13) }) it('does not crash when creating large Buffers', () => { - let buffer = new Buffer(new Array(4096).join(' ')) + let buffer = Buffer.from(new Array(4096).join(' ')) assert.equal(buffer.length, 4095) - buffer = new Buffer(new Array(4097).join(' ')) + buffer = Buffer.from(new Array(4097).join(' ')) assert.equal(buffer.length, 4096) }) }) From 9f0df695ca4899ae2e351677dc5a875b80cec585 Mon Sep 17 00:00:00 2001 From: Felix Rieseberg Date: Thu, 23 Nov 2017 14:22:43 -0800 Subject: [PATCH 13/18] :wrench: Spec: Fix style issues --- spec/api-browser-window-spec.js | 6 +++++- spec/api-ipc-spec.js | 1 + spec/api-native-image-spec.js | 2 ++ spec/api-net-spec.js | 11 +++++++++++ spec/api-protocol-spec.js | 3 +++ spec/api-session-spec.js | 3 +++ spec/api-web-contents-spec.js | 5 ++++- spec/api-web-frame-spec.js | 3 +++ spec/api-web-request-spec.js | 3 +++ spec/chromium-spec.js | 3 +++ spec/node-spec.js | 3 ++- spec/static/main.js | 4 ++++ spec/webview-spec.js | 7 +++++-- 13 files changed, 49 insertions(+), 5 deletions(-) diff --git a/spec/api-browser-window-spec.js b/spec/api-browser-window-spec.js index 066d47d9b708..fb7e6bf2755c 100644 --- a/spec/api-browser-window-spec.js +++ b/spec/api-browser-window-spec.js @@ -153,7 +153,7 @@ describe('BrowserWindow module', () => { ] const responseEvent = 'window-webContents-destroyed' - function* genNavigationEvent () { + function * genNavigationEvent () { let eventOptions = null while ((eventOptions = events.shift()) && events.length) { let w = new BrowserWindow({show: false}) @@ -1056,6 +1056,8 @@ describe('BrowserWindow module', () => { // http protocol to simulate accessing another domain. This is required // because the code paths for cross domain popups is different. function crossDomainHandler (request, callback) { + // Disabled due to false positive in StandardJS + // eslint-disable-next-line standard/no-callback-literal callback({ mimeType: 'text/html', data: `

${request.url}

` @@ -3025,6 +3027,8 @@ const isScaleFactorRounding = () => { function serveFileFromProtocol (protocolName, filePath) { return new Promise((resolve, reject) => { protocol.registerBufferProtocol(protocolName, (request, callback) => { + // Disabled due to false positive in StandardJS + // eslint-disable-next-line standard/no-callback-literal callback({ mimeType: 'text/html', data: fs.readFileSync(filePath) diff --git a/spec/api-ipc-spec.js b/spec/api-ipc-spec.js index 4bb563184ad2..b7b233adc3db 100644 --- a/spec/api-ipc-spec.js +++ b/spec/api-ipc-spec.js @@ -195,6 +195,7 @@ describe('ipc module', () => { const foo = remote.require(path.join(fixtures, 'module', 'error-properties.js')) assert.throws(() => { + // eslint-disable-next-line foo.bar }, /getting error/) diff --git a/spec/api-native-image-spec.js b/spec/api-native-image-spec.js index a86bda75af94..c604d3917023 100644 --- a/spec/api-native-image-spec.js +++ b/spec/api-native-image-spec.js @@ -1,5 +1,7 @@ 'use strict' +/* eslint-disable no-unused-expressions */ + const {expect} = require('chai') const {nativeImage} = require('electron') const path = require('path') diff --git a/spec/api-net-spec.js b/spec/api-net-spec.js index 69aa1154ee8e..4f9abfe1a5ff 100644 --- a/spec/api-net-spec.js +++ b/spec/api-net-spec.js @@ -6,6 +6,9 @@ const url = require('url') const {net} = remote const {session} = remote +/* The whole net API doesn't use standard callbacks */ +/* eslint-disable standard/no-callback-literal */ + function randomBuffer (size, start, end) { start = start || 0 end = end || 255 @@ -855,6 +858,8 @@ describe('net module', () => { (details, callback) => { if (details.url === `${server.url}${requestUrl}`) { requestIsIntercepted = true + // Disabled due to false positive in StandardJS + // eslint-disable-next-line standard/no-callback-literal callback({ redirectURL: `${server.url}${redirectUrl}` }) @@ -907,6 +912,8 @@ describe('net module', () => { customSession.webRequest.onBeforeRequest((details, callback) => { if (details.url === `${server.url}${requestUrl}`) { requestIsIntercepted = true + // Disabled due to false positive in StandardJS + // eslint-disable-next-line standard/no-callback-literal callback({ redirectURL: `${server.url}${redirectUrl}` }) @@ -1154,6 +1161,8 @@ describe('net module', () => { url: `${server.url}${requestUrl}`, session: 1 }) + + // eslint-disable-next-line urlRequest } catch (exception) { done() @@ -1223,6 +1232,8 @@ describe('net module', () => { url: `${server.url}${requestUrl}`, partition: 1 }) + + // eslint-disable-next-line urlRequest } catch (exception) { done() diff --git a/spec/api-protocol-spec.js b/spec/api-protocol-spec.js index a9d69867157b..f214bfc6d27f 100644 --- a/spec/api-protocol-spec.js +++ b/spec/api-protocol-spec.js @@ -10,6 +10,9 @@ const {BrowserWindow, ipcMain, protocol, session, webContents} = remote // and use Stream instances created in the browser process. const stream = remote.require('stream') +/* The whole protocol API doesn't use standard callbacks */ +/* eslint-disable standard/no-callback-literal */ + describe('protocol module', () => { const protocolName = 'sp' const text = 'valar morghulis' diff --git a/spec/api-session-spec.js b/spec/api-session-spec.js index 50504ccadae1..cf6296cd448f 100644 --- a/spec/api-session-spec.js +++ b/spec/api-session-spec.js @@ -10,6 +10,9 @@ const {closeWindow} = require('./window-helpers') const {ipcRenderer, remote} = require('electron') const {ipcMain, session, BrowserWindow, net} = remote +/* The whole session API doesn't use standard callbacks */ +/* eslint-disable standard/no-callback-literal */ + describe('session module', () => { let fixtures = path.resolve(__dirname, 'fixtures') let w = null diff --git a/spec/api-web-contents-spec.js b/spec/api-web-contents-spec.js index 39e466d56bce..4e5cc022df7c 100644 --- a/spec/api-web-contents-spec.js +++ b/spec/api-web-contents-spec.js @@ -10,6 +10,9 @@ const {BrowserWindow, webContents, ipcMain, session} = remote const isCi = remote.getGlobal('isCi') +/* The whole webContents API doesn't use standard callbacks */ +/* eslint-disable standard/no-callback-literal */ + describe('webContents module', () => { const fixtures = path.resolve(__dirname, 'fixtures') let w @@ -634,7 +637,7 @@ describe('webContents module', () => { ] const responseEvent = 'webcontents-destroyed' - function* genNavigationEvent () { + function * genNavigationEvent () { let eventOptions = null while ((eventOptions = events.shift()) && events.length) { eventOptions.responseEvent = responseEvent diff --git a/spec/api-web-frame-spec.js b/spec/api-web-frame-spec.js index ce0d0436ec58..a62c075d8e86 100644 --- a/spec/api-web-frame-spec.js +++ b/spec/api-web-frame-spec.js @@ -4,6 +4,9 @@ const {closeWindow} = require('./window-helpers') const {remote, webFrame} = require('electron') const {BrowserWindow, protocol, ipcMain} = remote +/* Most of the APIs here don't use standard callbacks */ +/* eslint-disable standard/no-callback-literal */ + describe('webFrame module', function () { var fixtures = path.resolve(__dirname, 'fixtures') var w = null diff --git a/spec/api-web-request-spec.js b/spec/api-web-request-spec.js index 6ad0550eb7d4..7dc1f370ce86 100644 --- a/spec/api-web-request-spec.js +++ b/spec/api-web-request-spec.js @@ -4,6 +4,9 @@ const qs = require('querystring') const remote = require('electron').remote const session = remote.session +/* The whole webRequest API doesn't use standard callbacks */ +/* eslint-disable standard/no-callback-literal */ + describe('webRequest module', () => { const ses = session.defaultSession const server = http.createServer((req, res) => { diff --git a/spec/chromium-spec.js b/spec/chromium-spec.js index 1420fed7c6a7..f068ef75f12d 100644 --- a/spec/chromium-spec.js +++ b/spec/chromium-spec.js @@ -11,6 +11,9 @@ const {app, BrowserWindow, ipcMain, protocol, session, webContents} = remote const isCI = remote.getGlobal('isCi') +/* Most of the APIs here don't use standard callbacks */ +/* eslint-disable standard/no-callback-literal */ + describe('chromium feature', () => { const fixtures = path.resolve(__dirname, 'fixtures') let listener = null diff --git a/spec/node-spec.js b/spec/node-spec.js index ae639167ff07..6f2390e93eab 100644 --- a/spec/node-spec.js +++ b/spec/node-spec.js @@ -298,6 +298,7 @@ describe('node feature', () => { describe('process.stdout', () => { it('does not throw an exception when accessed', () => { assert.doesNotThrow(() => { + // eslint-disable-next-line process.stdout }) }) @@ -332,7 +333,7 @@ describe('node feature', () => { describe('process.stdin', () => { it('does not throw an exception when accessed', () => { assert.doesNotThrow(() => { - process.stdin + process.stdin // eslint-disable-line }) }) diff --git a/spec/static/main.js b/spec/static/main.js index 4a4dfd109df3..80c8e716c678 100644 --- a/spec/static/main.js +++ b/spec/static/main.js @@ -32,9 +32,11 @@ app.commandLine.appendSwitch('disable-renderer-backgrounding') // Accessing stdout in the main process will result in the process.stdout // throwing UnknownSystemError in renderer process sometimes. This line makes // sure we can reproduce it in renderer process. +// eslint-disable-next-line process.stdout // Access console to reproduce #3482. +// eslint-disable-next-line console ipcMain.on('message', function (event, ...args) { @@ -378,6 +380,8 @@ const suspendListeners = (emitter, eventName, callback) => { listeners.forEach((listener) => { emitter.on(eventName, listener) }) + + // eslint-disable-next-line standard/no-callback-literal callback(...args) }) } diff --git a/spec/webview-spec.js b/spec/webview-spec.js index 0ce043069f24..4ac8136b81fc 100644 --- a/spec/webview-spec.js +++ b/spec/webview-spec.js @@ -9,6 +9,9 @@ const {closeWindow} = require('./window-helpers') const isCI = remote.getGlobal('isCi') const nativeModulesEnabled = remote.getGlobal('nativeModulesEnabled') +/* Most of the APIs here don't use standard callbacks */ +/* eslint-disable standard/no-callback-literal */ + describe(' tag', function () { this.timeout(3 * 60 * 1000) @@ -1423,7 +1426,7 @@ describe(' tag', function () { }) webview.style.display = 'none' - webview.offsetHeight + webview.offsetHeight // eslint-disable-line webview.style.display = 'block' }) webview.src = `file://${fixtures}/pages/a.html` @@ -1442,7 +1445,7 @@ describe(' tag', function () { }) webview.style.display = 'none' - webview.offsetHeight + webview.offsetHeight // eslint-disable-line webview.style.display = 'block' }) webview.src = `file://${fixtures}/pages/a.html` From d9c7b95141b6dba7d1a70048d19b2c10ee0b1fe6 Mon Sep 17 00:00:00 2001 From: Shelley Vohr Date: Fri, 24 Nov 2017 21:40:19 +0100 Subject: [PATCH 14/18] fix remark code flag error --- docs/development/upgrading-node.md | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/docs/development/upgrading-node.md b/docs/development/upgrading-node.md index 0424cedfc5dc..b6518d40be21 100644 --- a/docs/development/upgrading-node.md +++ b/docs/development/upgrading-node.md @@ -114,11 +114,10 @@ We need to generate a patch file from each patch applied to V8. electron/vendor/libchromiumcontent$ git checkout upgrade-to-chromium-X electron/vendor/libchromiumcontent$ cd ../.. electron$ git add vendor - electron$ git commit -m "update submodule referefences for node and libc" + electron$ git commit -m "update submodule references for node and libc" electron$ git pso upgrade-to-chromium-62 electron$ script/bootstrap.py -d - electron$ script/build.py -c -D - ``` + electron$ script/build.py -c -D``` From d9d2a8176ee7b1a2e7f45d0f18a085e330e1ebeb Mon Sep 17 00:00:00 2001 From: Aleksei Kuzmin Date: Fri, 24 Nov 2017 10:31:06 +0100 Subject: [PATCH 15/18] Use latest libcc with Chromium 61 --- vendor/libchromiumcontent | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vendor/libchromiumcontent b/vendor/libchromiumcontent index 5d55b4ebd1f1..fe78f44d3e1d 160000 --- a/vendor/libchromiumcontent +++ b/vendor/libchromiumcontent @@ -1 +1 @@ -Subproject commit 5d55b4ebd1f1597394360c16eb4fcec7889148b9 +Subproject commit fe78f44d3e1d6cc38454fd6fbae324124830b1ef From ce6af85f9851d09d80ca153a1ea6cc1795d842d0 Mon Sep 17 00:00:00 2001 From: Aleksei Kuzmin Date: Sat, 25 Nov 2017 00:56:07 +0100 Subject: [PATCH 16/18] Fix a codeblock markup --- docs/development/upgrading-node.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/development/upgrading-node.md b/docs/development/upgrading-node.md index 0424cedfc5dc..e8ad46c4eb26 100644 --- a/docs/development/upgrading-node.md +++ b/docs/development/upgrading-node.md @@ -105,7 +105,7 @@ We need to generate a patch file from each patch applied to V8. - `git commit patches/v8/` 8. Update `patches/v8/README.md` with references to all new patches that have been added so that the next person will know which need to be removed. 9. Update Electron's submodule references: - - ```sh + ```sh cd electron/vendor/node electron/vendor/node$ git fetch electron/vendor/node$ git checkout electron-node-vA.B.C From 9c5acf623397331009876f163d22ad3abe02687d Mon Sep 17 00:00:00 2001 From: Aleksei Kuzmin Date: Sat, 25 Nov 2017 13:29:14 +0100 Subject: [PATCH 17/18] Remove "async" flag from the `menu.popup()` options All menus have become async after the Chromium 61 upgrade. Fixes #11242. --- docs/api/menu.md | 3 --- 1 file changed, 3 deletions(-) diff --git a/docs/api/menu.md b/docs/api/menu.md index 3ccd118091a4..7f694d037892 100644 --- a/docs/api/menu.md +++ b/docs/api/menu.md @@ -67,9 +67,6 @@ The `menu` object has the following instance methods: Must be declared if `y` is declared. * `y` Number (optional) - Default is the current mouse cursor position. Must be declared if `x` is declared. - * `async` Boolean (optional) - Set to `true` to have this method return - immediately called, `false` to return after the menu has been selected - or closed. Defaults to `false`. * `positioningItem` Number (optional) _macOS_ - The index of the menu item to be positioned under the mouse cursor at the specified coordinates. Default is -1. From f8b683ca3d1095c3a9c187bc2ced9ffd24de0d4f Mon Sep 17 00:00:00 2001 From: Ales Pergl Date: Mon, 27 Nov 2017 17:55:21 +0100 Subject: [PATCH 18/18] Don't access unique pointer after it was moved from --- .../browser/inspectable_web_contents_impl.cc | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/brightray/browser/inspectable_web_contents_impl.cc b/brightray/browser/inspectable_web_contents_impl.cc index 874215f7d917..4d0826990c8c 100644 --- a/brightray/browser/inspectable_web_contents_impl.cc +++ b/brightray/browser/inspectable_web_contents_impl.cc @@ -800,16 +800,21 @@ void InspectableWebContentsImpl::OnURLFetchComplete( DCHECK(it != pending_requests_.end()); base::DictionaryValue response; - auto headers = base::MakeUnique(); + net::HttpResponseHeaders* rh = source->GetResponseHeaders(); response.SetInteger("statusCode", rh ? rh->response_code() : 200); - response.Set("headers", std::move(headers)); - size_t iterator = 0; - std::string name; - std::string value; - while (rh && rh->EnumerateHeaderLines(&iterator, &name, &value)) - headers->SetString(name, value); + { + auto headers = base::MakeUnique(); + + size_t iterator = 0; + std::string name; + std::string value; + while (rh && rh->EnumerateHeaderLines(&iterator, &name, &value)) + headers->SetString(name, value); + + response.Set("headers", std::move(headers)); + } it->second.Run(&response); pending_requests_.erase(it);