Compare commits

...

57 Commits

Author SHA1 Message Date
Electron Bot
93e786d1b5 Bump v12.0.0-nightly.20201026 2020-10-26 07:31:57 -07:00
Chris Patterson
6a0c5a8a65 docs: add snapcraft + electron-packager example (#25750)
* docs: add snapcraft + electron-packager example

Add example to snap electron app (electron-quick-start)
using snapcraft & electron-packager.

Include notes on how to apply this to an existing project.

Signed-off-by: Chris Patterson <chris.patterson@canonical.com>

* Update snapcraft.md

* Update snapcraft.md

* Update snapcraft.md

* Update docs/tutorial/snapcraft.md

Co-authored-by: John Kleinschmidt <jkleinsc@github.com>

Co-authored-by: Cheng Zhao <github@zcbenz.com>
Co-authored-by: John Kleinschmidt <jkleinsc@github.com>
2020-10-26 16:47:01 +09:00
Antonio
ecb758dae5 docs: revised the represented file feature page (#26018)
* docs: revised the represented file feature page

* docs: fixed mentions, updated screenshot to be more consistent
2020-10-26 16:45:45 +09:00
Fabio Spampinato
d4191c4a26 fix: optimized asar paths checks (#26024)
* fix: optimized asar paths checks

* fix: ensuring the linter is happy
2020-10-26 12:19:35 +09:00
Milan Burda
aa157c3f05 feat: add osProcessId / name properties to webFrameMain (#26093)
* feat: add osProcessId / name properties to webFrameMain

* Update docs/api/web-frame-main.md

Co-authored-by: Jeremy Rose <jeremya@chromium.org>

Co-authored-by: Jeremy Rose <jeremya@chromium.org>
2020-10-26 06:03:34 +03:00
David Sanders
30b5e15ddc chore: bump @typescript-eslint version (#25986)
* chore: bump @typescript-eslint version

* chore: update config for newer @typescript-eslint

* chore: disable eslint no-undef rule for typescript
2020-10-26 11:59:35 +09:00
David Sanders
4379a14335 chore: bump @electron/docs-parser version (#26088) 2020-10-25 12:29:47 -05:00
Shelley Vohr
e89abed924 fix: disable use of the vm module in the renderer (#26087) 2020-10-23 11:49:52 -07:00
Electron Bot
c89ce5eecf Bump v12.0.0-nightly.20201023 2020-10-23 07:32:10 -07:00
Samuel Attard
9d18f9d54f fix: re-enable the spellchecker when new language list set (#26119)
* fix: re-enable the spellchecker when new language list set

Chromium recently added prefs logic to disable the spellchecker if the list of languages is empty, but the logic to re-enable if the languages are provided again lives in another part of Chromium.  This change makes it so our API re-enables the spellchecker correctly when required.

* chore: fix lint
2020-10-23 00:34:19 -07:00
Shelley Vohr
6181c03df0 fix: setSimpleFullScreen shows traffic light in frameless window (#26096) 2020-10-23 15:04:53 +09:00
Jeremy Rose
2d49d82072 chore: synchronously destroy WebContents on event prevented (#26090) 2020-10-23 15:04:07 +09:00
Antonio
722903f068 docs: revised the application progress bar feature page (#26003)
* docs: revised the application progress bar feature page

* docs: fixed mentions, added screenshots to make the guide more consistent

* docs: added an extra phrase about indeterminate mode

* docs: revised paragraph about indeterminate mode

* docs: fixed lint errors, broken links
2020-10-23 15:03:04 +09:00
David Sanders
554ad93d45 chore: prefer empty() check for readability (#26109) 2020-10-22 13:24:59 -07:00
David Sanders
d9db9873fd fix: return early on promise rejection (#26095) 2020-10-22 10:53:42 -07:00
Charles Kerr
c934d1386b docs: add discord link to docs community page (#26048) 2020-10-22 10:24:30 -05:00
Electron Bot
7f0c6ea47a Bump v12.0.0-nightly.20201022 2020-10-22 07:33:26 -07:00
Cheng Zhao
e3c4bbd21f fix: release NSAlert properly (#26078) 2020-10-22 15:46:58 +09:00
Antonio
f93e33528e docs: revised the web embeds feature page (#26008)
* docs: revised the web embeds feature page

* docs: minor styling updates to the web embeds feature page

* docs: fixed text and grammar mentions

* docs: changed placement of the webviews warning

* docs: added a few missing commas
2020-10-22 11:08:26 +09:00
David Sanders
35455c725d build: fix running eslint on Windows (#26014) 2020-10-21 15:44:38 -07:00
Samuel Maddock
10a209ecba feat: add webPreferences.enablePreferredSizeMode (#25874)
* feat: add preferredSizeMode preference

* docs: webPreferences.preferredSizeMode and event

* docs: better explain preferred size

* docs: small improvement

* refactor: preferredSizeMode -> enablePreferredSizeMode
2020-10-21 15:44:19 -07:00
David Sanders
2aa5a1f494 build: lint the npm folder (#26085) 2020-10-21 15:43:52 -07:00
Jeremy Rose
22cb3cd18b feat: add disabledCipherSuites option to setSSLConfig (#25818) 2020-10-21 11:03:59 -07:00
Milan Burda
f6a27973d1 chore: sort filenames (#26049) 2020-10-21 17:38:20 +03:00
Electron Bot
939be5eb8a Bump v12.0.0-nightly.20201021 2020-10-21 07:31:34 -07:00
Cheng Zhao
a631a8a8b0 docs: put required field frontmost in the dialog options (#26059) 2020-10-21 20:07:44 +09:00
Antonio
5c6fa7e420 docs: revised the online-offline event detection feature page (#26017)
* docs: revised the online-offline event detection feature page

* docs: fixed text and grammar mentions
2020-10-21 15:46:56 +09:00
Milan Burda
df1432a315 feat: add net.online / net.isOnline() (#21004) 2020-10-20 19:55:06 -07:00
Milan Burda
1ef803d2ea chore: make RenderProcessHostPrivilege enum class (#26050) 2020-10-20 19:47:04 -05:00
Julie Koubová
56d1fafe66 build: Wrap bundles using webpack (#25557) 2020-10-20 12:10:15 -07:00
David Sanders
f7945ade07 build: mtime cache for patches to speed up build (#25881) 2020-10-20 11:49:57 -07:00
Valentin Hăloiu
c4525b4ea6 fix: add Wayland support (#26022) 2020-10-20 11:24:52 -07:00
Electron Bot
d38c47e748 Bump v12.0.0-nightly.20201020 2020-10-20 07:33:02 -07:00
Antonio
aebb56cb33 docs: revised Notifications feature page (#25901)
* docs: revised Notifications feature page

* docs: fixed mentions and updated content according to style guide in the notifications feature page

* docs: fixed lint errors in the notifications feature page

* docs: slightly improved consistency of steps in the notifications feature page

* docs: fixed mentions in the notifications feature page
2020-10-20 11:24:27 +09:00
David Sanders
e6f570d191 docs: improve relative link linting and fix broken (#26020) 2020-10-20 10:46:27 +09:00
David Sanders
042ebdd5b0 build: lint patches for trailing whitespace (#26007) 2020-10-20 10:40:58 +09:00
Cheng Zhao
6b6ffbdd10 feat: add support for share menu on macOS (#25629) 2020-10-19 18:33:06 -07:00
Antonio
89c04b3c6c docs: revised the macos dock menu feature page (#25985)
* docs: revised the macos dock menu feature page

* docs: added a cross-link to api, fixed mentions in the macos feature page
2020-10-20 10:32:40 +09:00
Charles Kerr
ae5de3d9c5 perf: remove GC timer that fired once per minute. (#25958) 2020-10-20 10:31:02 +09:00
Antonio
12e3c85081 docs: revised the recent documents feature page (#25941)
* docs: revised the recent documents feature page

* docs: fixed lint errors in the recent documents feature page

* docs: slightly improved consistency of steps in the recent documents feature page
2020-10-20 10:26:24 +09:00
John Kleinschmidt
4ce7ca6cfb test: disable flaky arm tests (#26046)
* tests: disable flaking test on all arm platforms

* tests: disable flaky did-change-theme-color tests on WOA
2020-10-19 20:11:30 -04:00
Shelley Vohr
c6a6f53c8d fix: crash when printing (#25989) 2020-10-19 14:31:25 -07:00
The Gem Dev
3219812c02 docs: update native file drag and drop (#26044)
fixed a typo.
2020-10-19 14:18:43 -07:00
Electron Bot
e895353f7a chore: bump node to v14.14.0 (master) (#25994)
* chore: bump node in DEPS to v14.14.0

* Remove upstreamed certs patch

https://github.com/nodejs/node/pull/35546

* Remove V8 Isolate callbacks patch

https://github.com/nodejs/node/pull/35512

* Update patch indices

* Update Node.js filenames

Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2020-10-19 13:28:28 -07:00
Shelley Vohr
88508d5166 fix: support new PDF viewer update (#26010) 2020-10-19 13:07:02 -07:00
David Sanders
64504536fa build: fix invocation of cpplint on Windows (#26011) 2020-10-19 12:08:13 -07:00
Charles Kerr
16caa54248 chore: tweak branch detection in release notes. (#25973) 2020-10-19 11:36:37 -07:00
Michaela Laurencin
11ce55628e fix: correct null pointer checks in autoresizing browser views (#25951)
* Correction null pointer checks

* fix: correct null pointer checks in autoresizing browser views

Co-authored-by: mlaurencin <mlaurencin@microsoft.com>
2020-10-19 09:26:38 -07:00
John Kleinschmidt
87d3f3584c fix: segfault in SerialChooserController (#25969)
* fix: segfault in SerialChooserController

* Remove temporary testing
2020-10-19 10:51:25 -04:00
Electron Bot
6a0221297e Bump v12.0.0-nightly.20201019 2020-10-19 07:31:58 -07:00
Milan Burda
decb1eb87b feat: add serviceName to 'child-process-gone' / app.getAppMetrics() (#25975) 2020-10-19 14:55:47 +03:00
David Sanders
c27e5fdbb6 chore: fix linter errors (#25996) 2020-10-19 20:55:27 +09:00
Lishid
05b5c197ae feat: Expose renderer spellcheck API (#25060) 2020-10-19 20:48:16 +09:00
Milan Burda
321395d96e refactor: use Map instead of Object for better semantics (#25982) 2020-10-19 03:24:51 +03:00
Shelley Vohr
eca53aaaf1 fix: Save As PDF from PDF Preview (#25959) 2020-10-16 18:30:46 -07:00
Robo
708cf44d19 ci: disable CalculateNativeWinOcclusion for woa (#26001) 2020-10-16 13:45:38 -07:00
Cheng Zhao
44221d7452 chore: update chore_expose_v8_initialization_isolate_callbacks.patch (#25992)
* chore: update chore_expose_v8_initialization_isolate_callbacks.patch

* update patches

* update patches

Co-authored-by: Electron Bot <anonymous@electronjs.org>
2020-10-16 13:31:13 -07:00
165 changed files with 2279 additions and 3389 deletions

View File

@@ -26,15 +26,6 @@
"ecmaVersion": 6,
"sourceType": "module"
},
"globals": {
"standardScheme": "readonly",
"globalThis": "readonly",
"BUILDFLAG": "readonly",
"ENABLE_DESKTOP_CAPTURER": "readonly",
"ENABLE_REMOTE_MODULE": "readonly",
"ENABLE_VIEWS_API": "readonly",
"BigInt": "readonly"
},
"overrides": [
{
"files": "*.js",
@@ -42,6 +33,15 @@
"@typescript-eslint/no-unused-vars": "off"
}
},
{
"files": "*.ts",
"rules": {
"no-undef": "off",
"no-redeclare": "off",
"@typescript-eslint/no-redeclare": ["error"],
"no-use-before-define": "off"
}
},
{
"files": "*.d.ts",
"rules": {

5
.gitignore vendored
View File

@@ -65,4 +65,7 @@ ts-gen
# Used to accelerate CI builds
.depshash
.depshash-target
.depshash-target
# Used to accelerate builds after sync
patches/mtime-cache.json

34
DEPS
View File

@@ -16,7 +16,7 @@ vars = {
'chromium_version':
'9269f9eb1d98d29564c2b2ab97f30c6e148c4e11',
'node_version':
'v14.13.1',
'v14.14.0',
'nan_version':
'2c4ee8a32a299eada3cd6e468bbd0a473bfea96d',
'squirrel.mac_version':
@@ -38,6 +38,9 @@ vars = {
# To be able to build clean Chromium from sources.
'apply_patches': True,
# To use an mtime cache for patched files to speed up builds.
'use_mtime_cache': True,
# To allow in-house builds to checkout those manually.
'checkout_chromium': True,
'checkout_node': True,
@@ -112,6 +115,23 @@ deps = {
}
}
pre_deps_hooks = [
{
'name': 'generate_mtime_cache',
'condition': '(checkout_chromium and apply_patches and use_mtime_cache) and process_deps',
'pattern': 'src/electron',
'action': [
'python3',
'src/electron/script/patches-mtime-cache.py',
'generate',
'--cache-file',
'src/electron/patches/mtime-cache.json',
'--patches-config',
'src/electron/patches/config.json',
],
},
]
hooks = [
{
'name': 'patch_chromium',
@@ -123,6 +143,18 @@ hooks = [
'src/electron/patches/config.json',
],
},
{
'name': 'apply_mtime_cache',
'condition': '(checkout_chromium and apply_patches and use_mtime_cache) and process_deps',
'pattern': 'src/electron',
'action': [
'python3',
'src/electron/script/patches-mtime-cache.py',
'apply',
'--cache-file',
'src/electron/patches/mtime-cache.json',
],
},
{
'name': 'electron_external_binaries',
'pattern': 'src/electron/script/update-external-binaries.py',

View File

@@ -1 +1 @@
12.0.0-nightly.20201016
12.0.0-nightly.20201026

View File

@@ -63,7 +63,8 @@ steps:
set npm_config_nodedir=%cd%\out\Default\gen\node_headers
set npm_config_arch=arm64
cd electron
node script/yarn test -- --enable-logging --verbose
# CalculateNativeWinOcclusion is disabled due to https://bugs.chromium.org/p/chromium/issues/detail?id=1139022
node script/yarn test -- --enable-logging --verbose --disable-features=CalculateNativeWinOcclusion
displayName: 'Run Electron tests'
env:
ELECTRON_OUT_DIR: Default

View File

@@ -1,2 +0,0 @@
process.env.PRINT_WEBPACK_GRAPH = true;
require('./run-compiler');

View File

@@ -1,45 +0,0 @@
const fs = require('fs');
const path = require('path');
const webpack = require('webpack');
const configPath = process.argv[2];
const outPath = path.resolve(process.argv[3]);
const config = require(configPath);
config.output = {
path: path.dirname(outPath),
filename: path.basename(outPath)
};
const { wrapInitWithProfilingTimeout, wrapInitWithTryCatch, ...webpackConfig } = config;
webpack(webpackConfig, (err, stats) => {
if (err) {
console.error(err);
process.exit(1);
} else if (stats.hasErrors()) {
console.error(stats.toString('normal'));
process.exit(1);
} else {
let contents = fs.readFileSync(outPath, 'utf8');
if (wrapInitWithTryCatch) {
contents = `try {
${contents}
} catch (err) {
console.error('Electron ${webpackConfig.output.filename} script failed to run');
console.error(err);
}`;
}
if (wrapInitWithProfilingTimeout) {
contents = `function ___electron_webpack_init__() {
${contents}
};
if ((globalThis.process || binding.process).argv.includes("--profile-electron-init")) {
setTimeout(___electron_webpack_init__, 0);
} else {
___electron_webpack_init__();
}`;
}
fs.writeFileSync(outPath, contents);
process.exit(0);
}
});

View File

@@ -2,16 +2,12 @@ const fs = require('fs');
const path = require('path');
const webpack = require('webpack');
const TerserPlugin = require('terser-webpack-plugin');
const WrapperPlugin = require('wrapper-webpack-plugin');
const electronRoot = path.resolve(__dirname, '../..');
const onlyPrintingGraph = !!process.env.PRINT_WEBPACK_GRAPH;
class AccessDependenciesPlugin {
apply (compiler) {
// Only hook into webpack when we are printing the dependency graph
if (!onlyPrintingGraph) return;
compiler.hooks.compilation.tap('AccessDependenciesPlugin', compilation => {
compilation.hooks.finishModules.tap('AccessDependenciesPlugin', modules => {
const filePaths = modules.map(m => m.resource).filter(p => p).map(p => path.relative(electronRoot, p));
@@ -21,49 +17,6 @@ class AccessDependenciesPlugin {
}
}
const defines = {
BUILDFLAG: onlyPrintingGraph ? '(a => a)' : ''
};
const buildFlagsPrefix = '--buildflags=';
const buildFlagArg = process.argv.find(arg => arg.startsWith(buildFlagsPrefix));
if (buildFlagArg) {
const buildFlagPath = buildFlagArg.substr(buildFlagsPrefix.length);
const flagFile = fs.readFileSync(buildFlagPath, 'utf8');
for (const line of flagFile.split(/(\r\n|\r|\n)/g)) {
const flagMatch = line.match(/#define BUILDFLAG_INTERNAL_(.+?)\(\) \(([01])\)/);
if (flagMatch) {
const [, flagName, flagValue] = flagMatch;
defines[flagName] = JSON.stringify(Boolean(parseInt(flagValue, 10)));
}
}
}
const ignoredModules = [];
if (defines.ENABLE_DESKTOP_CAPTURER === 'false') {
ignoredModules.push(
'@electron/internal/browser/desktop-capturer',
'@electron/internal/browser/api/desktop-capturer',
'@electron/internal/renderer/api/desktop-capturer'
);
}
if (defines.ENABLE_REMOTE_MODULE === 'false') {
ignoredModules.push(
'@electron/internal/browser/remote/server',
'@electron/internal/renderer/api/remote'
);
}
if (defines.ENABLE_VIEWS_API === 'false') {
ignoredModules.push(
'@electron/internal/browser/api/views/image-view.js'
);
}
module.exports = ({
alwaysHasNode,
loadElectronFromAlternateTarget,
@@ -79,76 +32,148 @@ module.exports = ({
const electronAPIFile = path.resolve(electronRoot, 'lib', loadElectronFromAlternateTarget || target, 'api', 'exports', 'electron.ts');
return ({
mode: 'development',
devtool: false,
entry,
target: alwaysHasNode ? 'node' : 'web',
output: {
filename: `${target}.bundle.js`
},
wrapInitWithProfilingTimeout,
wrapInitWithTryCatch,
resolve: {
alias: {
'@electron/internal': path.resolve(electronRoot, 'lib'),
electron$: electronAPIFile,
'electron/main$': electronAPIFile,
'electron/renderer$': electronAPIFile,
'electron/common$': electronAPIFile,
// Force timers to resolve to our dependency that doesn't use window.postMessage
timers: path.resolve(electronRoot, 'node_modules', 'timers-browserify', 'main.js')
},
extensions: ['.ts', '.js']
},
module: {
rules: [{
test: (moduleName) => !onlyPrintingGraph && ignoredModules.includes(moduleName),
loader: 'null-loader'
}, {
test: /\.ts$/,
loader: 'ts-loader',
options: {
configFile: path.resolve(electronRoot, 'tsconfig.electron.json'),
transpileOnly: onlyPrintingGraph,
ignoreDiagnostics: [
// File '{0}' is not under 'rootDir' '{1}'.
6059
]
return (env = {}, argv = {}) => {
const onlyPrintingGraph = !!env.PRINT_WEBPACK_GRAPH;
const outputFilename = argv['output-filename'] || `${target}.bundle.js`;
const defines = {
BUILDFLAG: onlyPrintingGraph ? '(a => a)' : ''
};
if (env.buildflags) {
const flagFile = fs.readFileSync(env.buildflags, 'utf8');
for (const line of flagFile.split(/(\r\n|\r|\n)/g)) {
const flagMatch = line.match(/#define BUILDFLAG_INTERNAL_(.+?)\(\) \(([01])\)/);
if (flagMatch) {
const [, flagName, flagValue] = flagMatch;
defines[flagName] = JSON.stringify(Boolean(parseInt(flagValue, 10)));
}
}]
},
node: {
__dirname: false,
__filename: false,
// We provide our own "timers" import above, any usage of setImmediate inside
// one of our renderer bundles should import it from the 'timers' package
setImmediate: false
},
optimization: {
minimize: true,
minimizer: [
new TerserPlugin({
terserOptions: {
keep_classnames: true,
keep_fnames: true
}
})
]
},
plugins: [
new AccessDependenciesPlugin(),
...(targetDeletesNodeGlobals ? [
new webpack.ProvidePlugin({
process: ['@electron/internal/common/webpack-provider', 'process'],
global: ['@electron/internal/common/webpack-provider', '_global'],
Buffer: ['@electron/internal/common/webpack-provider', 'Buffer']
})
] : []),
new webpack.ProvidePlugin({
Promise: ['@electron/internal/common/webpack-globals-provider', 'Promise']
}),
new webpack.DefinePlugin(defines)
]
});
}
}
const ignoredModules = [];
if (defines.ENABLE_DESKTOP_CAPTURER === 'false') {
ignoredModules.push(
'@electron/internal/browser/desktop-capturer',
'@electron/internal/browser/api/desktop-capturer',
'@electron/internal/renderer/api/desktop-capturer'
);
}
if (defines.ENABLE_REMOTE_MODULE === 'false') {
ignoredModules.push(
'@electron/internal/browser/remote/server',
'@electron/internal/renderer/api/remote'
);
}
if (defines.ENABLE_VIEWS_API === 'false') {
ignoredModules.push(
'@electron/internal/browser/api/views/image-view.js'
);
}
const plugins = [];
if (onlyPrintingGraph) {
plugins.push(new AccessDependenciesPlugin());
}
if (targetDeletesNodeGlobals) {
plugins.push(new webpack.ProvidePlugin({
process: ['@electron/internal/common/webpack-provider', 'process'],
global: ['@electron/internal/common/webpack-provider', '_global'],
Buffer: ['@electron/internal/common/webpack-provider', 'Buffer']
}));
}
plugins.push(new webpack.ProvidePlugin({
Promise: ['@electron/internal/common/webpack-globals-provider', 'Promise']
}));
plugins.push(new webpack.DefinePlugin(defines));
if (wrapInitWithProfilingTimeout) {
plugins.push(new WrapperPlugin({
header: 'function ___electron_webpack_init__() {',
footer: `
};
if ((globalThis.process || binding.process).argv.includes("--profile-electron-init")) {
setTimeout(___electron_webpack_init__, 0);
} else {
___electron_webpack_init__();
}`
}));
}
if (wrapInitWithTryCatch) {
plugins.push(new WrapperPlugin({
header: 'try {',
footer: `
} catch (err) {
console.error('Electron ${outputFilename} script failed to run');
console.error(err);
}`
}));
}
return {
mode: 'development',
devtool: false,
entry,
target: alwaysHasNode ? 'node' : 'web',
output: {
filename: outputFilename
},
resolve: {
alias: {
'@electron/internal': path.resolve(electronRoot, 'lib'),
electron$: electronAPIFile,
'electron/main$': electronAPIFile,
'electron/renderer$': electronAPIFile,
'electron/common$': electronAPIFile,
// Force timers to resolve to our dependency that doesn't use window.postMessage
timers: path.resolve(electronRoot, 'node_modules', 'timers-browserify', 'main.js')
},
extensions: ['.ts', '.js']
},
module: {
rules: [{
test: (moduleName) => !onlyPrintingGraph && ignoredModules.includes(moduleName),
loader: 'null-loader'
}, {
test: /\.ts$/,
loader: 'ts-loader',
options: {
configFile: path.resolve(electronRoot, 'tsconfig.electron.json'),
transpileOnly: onlyPrintingGraph,
ignoreDiagnostics: [
// File '{0}' is not under 'rootDir' '{1}'.
6059
]
}
}]
},
node: {
__dirname: false,
__filename: false,
// We provide our own "timers" import above, any usage of setImmediate inside
// one of our renderer bundles should import it from the 'timers' package
setImmediate: false
},
optimization: {
minimize: true,
minimizer: [
new TerserPlugin({
terserOptions: {
keep_classnames: true,
keep_fnames: true
}
})
]
},
plugins
};
};
};

View File

@@ -16,7 +16,6 @@ template("webpack_build") {
inputs = [
invoker.config_file,
"//electron/build/webpack/webpack.config.base.js",
"//electron/build/webpack/run-compiler.js",
"//electron/tsconfig.json",
"//electron/yarn.lock",
"//electron/typings/internal-ambient.d.ts",
@@ -24,9 +23,12 @@ template("webpack_build") {
] + invoker.inputs
args = [
"--config",
rebase_path(invoker.config_file),
rebase_path(invoker.out_file),
"--buildflags=" + rebase_path("$target_gen_dir/buildflags/buildflags.h"),
"--output-filename=" + get_path_info(invoker.out_file, "file"),
"--output-path=" + rebase_path(get_path_info(invoker.out_file, "dir")),
"--env.buildflags=" +
rebase_path("$target_gen_dir/buildflags/buildflags.h"),
]
deps += [ "buildflags" ]

View File

@@ -93,9 +93,18 @@ static_library("chrome") {
if (is_linux) {
sources += [ "//chrome/browser/icon_loader_auralinux.cc" ]
if (use_x11) {
sources += [
"//chrome/browser/extensions/global_shortcut_listener_x11.cc",
"//chrome/browser/extensions/global_shortcut_listener_x11.h",
]
} else if (use_ozone) {
sources += [
"//chrome/browser/extensions/global_shortcut_listener_ozone.cc",
"//chrome/browser/extensions/global_shortcut_listener_ozone.h",
]
}
sources += [
"//chrome/browser/extensions/global_shortcut_listener_x11.cc",
"//chrome/browser/extensions/global_shortcut_listener_x11.h",
"//chrome/browser/ui/views/status_icons/concat_menu_model.cc",
"//chrome/browser/ui/views/status_icons/concat_menu_model.h",
"//chrome/browser/ui/views/status_icons/status_icon_linux_dbus.cc",

View File

@@ -432,6 +432,7 @@ Returns:
* `integrity-failure` - Windows code integrity checks failed
* `exitCode` Number - The exit code for the process
(e.g. status from waitpid if on posix, from GetExitCodeProcess on Windows).
* `serviceName` String (optional) - The non-localized name of the process.
* `name` String (optional) - The name of the process.
Examples for utility: `Audio Service`, `Content Decryption Module Service`, `Network Service`, `Video Capture`, etc.

View File

@@ -398,6 +398,11 @@ It creates a new `BrowserWindow` with native properties as set by the `options`.
* `bypassHeatCheck` - Bypass code caching heuristics but with lazy compilation
* `bypassHeatCheckAndEagerCompile` - Same as above except compilation is eager.
Default policy is `code`.
* `enablePreferredSizeMode` Boolean (optional) - Whether to enable
preferred size mode. The preferred size is the minimum size needed to
contain the layout of the document—without requiring scrolling. Enabling
this will cause the `preferred-size-changed` event to be emitted on the
`WebContents` when the preferred size changes. Default is `false`.
When setting minimum or maximum window size with `minWidth`/`maxWidth`/
`minHeight`/`maxHeight`, it only constrains the users. It won't prevent you from

View File

@@ -232,7 +232,7 @@ Specify ways of the inspector web socket url exposure.
By default inspector websocket url is available in stderr and under /json/list endpoint on http://host:port/json/list.
[app]: app.md
[append-switch]: app.md#appcommandlineappendswitchswitch-value
[append-switch]: command-line.md#commandlineappendswitchswitch-value
[ready]: app.md#event-ready
[play-silent-audio]: https://github.com/atom/atom/pull/9485/files
[debugging-main-process]: ../tutorial/debugging-main-process.md

View File

@@ -95,7 +95,7 @@ Returns `Promise<DesktopCapturerSource[]>` - Resolves with an array of [`Desktop
which can detected by [`systemPreferences.getMediaAccessStatus`].
[`navigator.mediaDevices.getUserMedia`]: https://developer.mozilla.org/en/docs/Web/API/MediaDevices/getUserMedia
[`systemPreferences.getMediaAccessStatus`]: system-preferences.md#systempreferencesgetmediaaccessstatusmediatype-macos
[`systemPreferences.getMediaAccessStatus`]: system-preferences.md#systempreferencesgetmediaaccessstatusmediatype-windows-macos
## Caveats

View File

@@ -221,6 +221,7 @@ expanding and collapsing the dialog.
* `browserWindow` [BrowserWindow](browser-window.md) (optional)
* `options` Object
* `message` String - Content of the message box.
* `type` String (optional) - Can be `"none"`, `"info"`, `"error"`, `"question"` or
`"warning"`. On Windows, `"question"` displays the same icon as `"info"`, unless
you set an icon using the `"icon"` option. On macOS, both `"warning"` and
@@ -230,7 +231,6 @@ expanding and collapsing the dialog.
* `defaultId` Integer (optional) - Index of the button in the buttons array which will
be selected by default when the message box opens.
* `title` String (optional) - Title of the message box, some platforms will not show it.
* `message` String - Content of the message box.
* `detail` String (optional) - Extra information of the message.
* `checkboxLabel` String (optional) - If provided, the message box will
include a checkbox with the given label.
@@ -267,6 +267,7 @@ If `browserWindow` is not shown dialog will not be attached to it. In such case
* `browserWindow` [BrowserWindow](browser-window.md) (optional)
* `options` Object
* `message` String - Content of the message box.
* `type` String (optional) - Can be `"none"`, `"info"`, `"error"`, `"question"` or
`"warning"`. On Windows, `"question"` displays the same icon as `"info"`, unless
you set an icon using the `"icon"` option. On macOS, both `"warning"` and
@@ -276,7 +277,6 @@ If `browserWindow` is not shown dialog will not be attached to it. In such case
* `defaultId` Integer (optional) - Index of the button in the buttons array which will
be selected by default when the message box opens.
* `title` String (optional) - Title of the message box, some platforms will not show it.
* `message` String - Content of the message box.
* `detail` String (optional) - Extra information of the message.
* `checkboxLabel` String (optional) - If provided, the message box will
include a checkbox with the given label.

View File

@@ -14,7 +14,7 @@ See [`Menu`](menu.md) for examples.
* `menuItem` MenuItem
* `browserWindow` [BrowserWindow](browser-window.md) | undefined - This will not be defined if no window is open.
* `event` [KeyboardEvent](structures/keyboard-event.md)
* `role` String (optional) - Can be `undo`, `redo`, `cut`, `copy`, `paste`, `pasteAndMatchStyle`, `delete`, `selectAll`, `reload`, `forceReload`, `toggleDevTools`, `resetZoom`, `zoomIn`, `zoomOut`, `togglefullscreen`, `window`, `minimize`, `close`, `help`, `about`, `services`, `hide`, `hideOthers`, `unhide`, `quit`, `startSpeaking`, `stopSpeaking`, `zoom`, `front`, `appMenu`, `fileMenu`, `editMenu`, `viewMenu`, `recentDocuments`, `toggleTabBar`, `selectNextTab`, `selectPreviousTab`, `mergeAllWindows`, `clearRecentDocuments`, `moveTabToNewWindow` or `windowMenu` - Define the action of the menu item, when specified the
* `role` String (optional) - Can be `undo`, `redo`, `cut`, `copy`, `paste`, `pasteAndMatchStyle`, `delete`, `selectAll`, `reload`, `forceReload`, `toggleDevTools`, `resetZoom`, `zoomIn`, `zoomOut`, `togglefullscreen`, `window`, `minimize`, `close`, `help`, `about`, `services`, `hide`, `hideOthers`, `unhide`, `quit`, `startSpeaking`, `stopSpeaking`, `zoom`, `front`, `appMenu`, `fileMenu`, `editMenu`, `viewMenu`, `shareMenu`, `recentDocuments`, `toggleTabBar`, `selectNextTab`, `selectPreviousTab`, `mergeAllWindows`, `clearRecentDocuments`, `moveTabToNewWindow` or `windowMenu` - Define the action of the menu item, when specified the
`click` property will be ignored. See [roles](#roles).
* `type` String (optional) - Can be `normal`, `separator`, `submenu`, `checkbox` or
`radio`.
@@ -31,6 +31,7 @@ See [`Menu`](menu.md) for examples.
menu items.
* `registerAccelerator` Boolean (optional) _Linux_ _Windows_ - If false, the accelerator won't be registered
with the system, but it will still be displayed. Defaults to true.
* `sharingItem` SharingItem (optional) _macOS_ - The item to share when the `role` is `shareMenu`.
* `submenu` (MenuItemConstructorOptions[] | [Menu](menu.md)) (optional) - Should be specified
for `submenu` type menu items. If `submenu` is specified, the `type: 'submenu'` can be omitted.
If the value is not a [`Menu`](menu.md) then it will be automatically converted to one using
@@ -112,6 +113,7 @@ The following additional roles are available on _macOS_:
* `services` - The submenu is a ["Services"](https://developer.apple.com/documentation/appkit/nsapplication/1428608-servicesmenu?language=objc) menu. This is only intended for use in the Application Menu and is *not* the same as the "Services" submenu used in context menus in macOS apps, which is not implemented in Electron.
* `recentDocuments` - The submenu is an "Open Recent" menu.
* `clearRecentDocuments` - Map to the `clearRecentDocuments` action.
* `shareMenu` - The submenu is [share menu][ShareMenu]. The `sharingItem` property must also be set to indicate the item to share.
When specifying a `role` on macOS, `label` and `accelerator` are the only
options that will affect the menu item. All other options will be ignored.
@@ -200,6 +202,12 @@ system or just displayed.
This property can be dynamically changed.
#### `menuItem.sharingItem` _macOS_
A `SharingItem` indicating the item to share when the `role` is `shareMenu`.
This property can be dynamically changed.
#### `menuItem.commandId`
A `Number` indicating an item's sequential unique id.
@@ -207,3 +215,5 @@ A `Number` indicating an item's sequential unique id.
#### `menuItem.menu`
A `Menu` that the item is a part of.
[ShareMenu]: https://developer.apple.com/design/human-interface-guidelines/macos/extensions/share-extensions/

View File

@@ -8,7 +8,7 @@ The `net` module is a client-side API for issuing HTTP(S) requests. It is
similar to the [HTTP](https://nodejs.org/api/http.html) and
[HTTPS](https://nodejs.org/api/https.html) modules of Node.js but uses
Chromium's native networking library instead of the Node.js implementation,
offering better support for web proxies.
offering better support for web proxies. It also supports checking network status.
The following is a non-exhaustive list of why you may consider using the `net`
module instead of the native Node.js modules:
@@ -62,3 +62,25 @@ Creates a [`ClientRequest`](./client-request.md) instance using the provided
`options` which are directly forwarded to the `ClientRequest` constructor.
The `net.request` method would be used to issue both secure and insecure HTTP
requests according to the specified protocol scheme in the `options` object.
### `net.isOnline()`
Returns `Boolean` - Whether there is currently internet connection.
A return value of `false` is a pretty strong indicator that the user
won't be able to connect to remote sites. However, a return value of
`true` is inconclusive; even if some link is up, it is uncertain
whether a particular connection attempt to a particular remote site
will be successful.
## Properties
### `net.online` _Readonly_
A `Boolean` property. Whether there is currently internet connection.
A return value of `false` is a pretty strong indicator that the user
won't be able to connect to remote sites. However, a return value of
`true` is inconclusive; even if some link is up, it is uncertain
whether a particular connection attempt to a particular remote site
will be successful.

View File

@@ -574,11 +574,20 @@ Returns `String` - The user agent for this session.
#### `ses.setSSLConfig(config)`
* `config` Object
* `minVersion` String - Can be `tls1`, `tls1.1`, `tls1.2` or `tls1.3`. The
* `minVersion` String (optional) - Can be `tls1`, `tls1.1`, `tls1.2` or `tls1.3`. The
minimum SSL version to allow when connecting to remote servers. Defaults to
`tls1`.
* `maxVersion` String - Can be `tls1.2` or `tls1.3`. The maximum SSL version
* `maxVersion` String (optional) - Can be `tls1.2` or `tls1.3`. The maximum SSL version
to allow when connecting to remote servers. Defaults to `tls1.3`.
* `disabledCipherSuites` Integer[] (optional) - List of cipher suites which
should be explicitly prevented from being used in addition to those
disabled by the net built-in policy.
Supported literal forms: 0xAABB, where AA is `cipher_suite[0]` and BB is
`cipher_suite[1]`, as defined in RFC 2246, Section 7.4.1.2. Unrecognized but
parsable cipher suites in this form will not return an error.
Ex: To disable TLS_RSA_WITH_RC4_128_MD5, specify 0x0004, while to
disable TLS_ECDH_ECDSA_WITH_RC4_128_SHA, specify 0xC002.
Note that TLSv1.3 ciphers cannot be disabled using this mechanism.
Sets the SSL configuration for the session. All subsequent network requests
will use the new configuration. Existing network connections (such as WebSocket

45
docs/api/share-menu.md Normal file
View File

@@ -0,0 +1,45 @@
## Class: ShareMenu
> Create share menu on macOS.
Process: [Main](../glossary.md#main-process)
The `ShareMenu` class creates [Share Menu][share-menu] on macOS, which can be
used to share information from the current context to apps, social media
accounts, and other services.
For including the share menu as a submenu of other menus, please use the
`shareMenu` role of [`MenuItem`](menu-item.md).
### `new ShareMenu(sharingItem)`
* `sharingItem` SharingItem - The item to share.
Creates a new share menu.
### Instance Methods
The `shareMenu` object has the following instance methods:
#### `shareMenu.popup([options])`
* `options` PopupOptions (optional)
* `browserWindow` [BrowserWindow](browser-window.md) (optional) - Default is the focused window.
* `x` Number (optional) - Default is the current mouse cursor position.
Must be declared if `y` is declared.
* `y` Number (optional) - Default is the current mouse cursor position.
Must be declared if `x` is declared.
* `positioningItem` Number (optional) _macOS_ - The index of the menu item to
be positioned under the mouse cursor at the specified coordinates. Default
is -1.
* `callback` Function (optional) - Called when menu is closed.
Pops up this menu as a context menu in the [`BrowserWindow`](browser-window.md).
#### `shareMenu.closePopup([browserWindow])`
* `browserWindow` [BrowserWindow](browser-window.md) (optional) - Default is the focused window.
Closes the context menu in the `browserWindow`.
[share-menu]: https://developer.apple.com/design/human-interface-guidelines/macos/extensions/share-extensions/

View File

@@ -4,4 +4,4 @@
* `senderId` Integer - The `webContents.id` that sent the message, you can call `event.sender.sendTo(event.senderId, ...)` to reply to the message, see [ipcRenderer.sendTo][ipc-renderer-sendto] for more information. This only applies to messages sent from a different renderer. Messages sent directly from the main process set `event.senderId` to `0`.
* `ports` MessagePort[] - A list of MessagePorts that were transferred with this message
[ipc-renderer-sendto]: #ipcrenderersendtowindowid-channel--arg1-arg2-
[ipc-renderer-sendto]: ../ipc-renderer.md#ipcrenderersendtowebcontentsid-channel-args

View File

@@ -11,7 +11,8 @@
* `Pepper Plugin`
* `Pepper Plugin Broker`
* `Unknown`
* `name` String (optional) - The name of the process. i.e. for plugins it might be Flash.
* `serviceName` String (optional) - The non-localized name of the process.
* `name` String (optional) - The name of the process.
Examples for utility: `Audio Service`, `Content Decryption Module Service`, `Network Service`, `Video Capture`, etc.
* `cpu` [CPUUsage](cpu-usage.md) - CPU usage of the process.
* `creationTime` Number - Creation time for this process.

View File

@@ -0,0 +1,5 @@
# SharingItem Object
* `texts` String[] (optional) - An array of text to share.
* `filePaths` String[] (optional) - An array of files to share.
* `urls` String[] (optional) - An array of URLs to share.

View File

@@ -837,6 +837,19 @@ Emitted when `remote.getCurrentWebContents()` is called in the renderer process.
Calling `event.preventDefault()` will prevent the object from being returned.
Custom value can be returned by setting `event.returnValue`.
#### Event: 'preferred-size-changed'
Returns:
* `event` Event
* `preferredSize` [Size](structures/size.md) - The minimum size needed to
contain the layout of the document—without requiring scrolling.
Emitted when the `WebContents` preferred size has changed.
This event will only be emitted when `enablePreferredSizeMode` is set to `true`
in `webPreferences`.
### Instance Methods
#### `contents.loadURL(url[, options])`

View File

@@ -122,9 +122,18 @@ content. The identifier is fixed at the creation of the frame and stays
constant for the lifetime of the frame. When the frame is removed, the id is
not used again.
#### `frame.name` _Readonly_
A `String` representing the frame name.
#### `frame.osProcessId` _Readonly_
An `Integer` representing the operating system `pid` of the process which owns this frame.
#### `frame.processId` _Readonly_
An `Integer` representing the id of the process which owns this frame.
An `Integer` representing the Chromium internal `pid` of the process which owns this frame.
This is not the same as the OS process ID; to read that use `frame.osProcessId`.
#### `frame.routingId` _Readonly_

View File

@@ -257,6 +257,20 @@ renderer process.
Returns `WebFrame` - that has the supplied `routingId`, `null` if not found.
### `webFrame.isWordMisspelled(word)`
* `word` String - The word to be spellchecked.
Returns `Boolean` - True if the word is misspelled according to the built in
spellchecker, false otherwise. If no dictionary is loaded, always return false.
### `webFrame.getWordSuggestions(word)`
* `word` String - The misspelled word.
Returns `String[]` - A list of suggested words for a given word. If the word
is spelled correctly, the result will be empty.
## Properties
### `webFrame.top` _Readonly_

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 100 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 54 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 44 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 46 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

View File

@@ -1,10 +1,11 @@
# macOS Dock
## Overview
Electron has APIs to configure the app's icon in the macOS Dock. A macOS-only
API exists to create a custom dock menu, but
Electron also uses the app's dock icon to implement cross-platform features
like [recent documents][recent-documents] and
[application progress][progress-bar].
API exists to create a custom dock menu, but Electron also uses the app dock
icon as the entry point for cross-platform features like
[recent documents][recent-documents] and [application progress][progress-bar].
The custom dock is commonly used to add shortcuts to tasks the user wouldn't
want to open the whole app window for.
@@ -13,8 +14,15 @@ __Dock menu of Terminal.app:__
![Dock Menu][dock-menu-image]
To set your custom dock menu, you can use the `app.dock.setMenu` API, which is
only available on macOS:
To set your custom dock menu, you need to use the
[`app.dock.setMenu`](../api/dock.md#docksetmenumenu-macos) API,
which is only available on macOS.
## Example
Starting with a working application from the
[Quick Start Guide](quick-start.md), update the `main.js` file with the
following lines:
```javascript
const { app, Menu } = require('electron')
@@ -33,9 +41,16 @@ const dockMenu = Menu.buildFromTemplate([
{ label: 'New Command...' }
])
app.dock.setMenu(dockMenu)
app.whenReady().then(() => {
app.dock.setMenu(dockMenu)
})
```
After launching the Electron application, right click the application icon.
You should see the custom menu you just defined:
![macOS dock menu](../images/macos-dock-menu.png)
[dock-menu-image]: https://cloud.githubusercontent.com/assets/639601/5069962/6032658a-6e9c-11e4-9953-aa84006bdfff.png
[recent-documents]: ./recent-documents.md
[progress-bar]: ./progress-bar.md

View File

@@ -51,7 +51,7 @@ ipcMain.on('ondragstart', (event, filePath) => {
})
```
After launching the Electron application, try to dragging and dropping
After launching the Electron application, try dragging and dropping
the item from the BroswerWindow onto your desktop. In this guide,
the item is a Markdown file located in the root of the project:

View File

@@ -1,17 +1,36 @@
# Notifications (Windows, Linux, macOS)
All three operating systems provide means for applications to send notifications
to the user. Electron conveniently allows developers to send notifications with
the [HTML5 Notification API](https://notifications.spec.whatwg.org/), using
the currently running operating system's native notification APIs to display it.
## Overview
**Note:** Since this is an HTML5 API it is only available in the renderer process. If
you want to show Notifications in the main process please check out the
All three operating systems provide means for applications to send
notifications to the user. The technique of showing notifications is different
for the Main and Renderer processes.
For the Renderer process, Electron conveniently allows developers to send
notifications with the [HTML5 Notification API](https://notifications.spec.whatwg.org/),
using the currently running operating system's native notification APIs
to display it.
To show notifications in the Main process, you need to use the
[Notification](../api/notification.md) module.
```javascript
## Example
### Show notifications in the Renderer process
Assuming you have a working Electron application from the
[Quick Start Guide](quick-start.md), add the following line to the
`index.html` file before the closing `</body>` tag:
```html
<script src="renderer.js"></script>
```
and add the `renderer.js` file:
```js
const myNotification = new Notification('Title', {
body: 'Lorem Ipsum Dolor Sit Amet'
body: 'Notification from the Renderer process'
})
myNotification.onclick = () => {
@@ -19,12 +38,52 @@ myNotification.onclick = () => {
}
```
After launching the Electron application, you should see the notification:
![Notification in the Renderer process](../images/notification-renderer.png)
If you open the Console and then click the notification, you will see the
message that was generated after triggering the `onclick` event:
![Onclick message for the notification](../images/message-notification-renderer.png)
### Show notifications in the Main process
Starting with a working application from the
[Quick Start Guide](quick-start.md), update the `main.js` file with the following lines:
```js
const { Notification } = require('electron')
function showNotification () {
const notification = {
title: 'Basic Notification',
body: 'Notification from the Main process'
}
new Notification(notification).show()
}
app.whenReady().then(createWindow).then(showNotification)
```
After launching the Electron application, you should see the notification:
![Notification in the Main process](../images/notification-main.png)
## Additional information
While code and user experience across operating systems are similar, there
are subtle differences.
## Windows
* On Windows 10, a shortcut to your app with an [Application User
Model ID][app-user-model-id] must be installed to the Start Menu. This can be overkill during development, so adding `node_modules\electron\dist\electron.exe` to your Start Menu also does the trick. Navigate to the file in Explorer, right-click and 'Pin to Start Menu'. You will then need to add the line `app.setAppUserModelId(process.execPath)` to your main process to see notifications.
### Windows
* On Windows 10, a shortcut to your app with an
[Application User Model ID][app-user-model-id] must be installed to the
Start Menu. This can be overkill during development, so adding
`node_modules\electron\dist\electron.exe` to your Start Menu also does the
trick. Navigate to the file in Explorer, right-click and 'Pin to Start Menu'.
You will then need to add the line `app.setAppUserModelId(process.execPath)` to
your main process to see notifications.
* On Windows 8.1 and Windows 8, a shortcut to your app with an [Application User
Model ID][app-user-model-id] must be installed to the Start screen. Note,
however, that it does not need to be pinned to the Start screen.
@@ -44,7 +103,7 @@ to 200 characters. That said, that limitation has been removed in Windows 10, wi
the Windows team asking developers to be reasonable. Attempting to send gigantic
amounts of text to the API (thousands of characters) might result in instability.
### Advanced Notifications
#### Advanced Notifications
Later versions of Windows allow for advanced notifications, with custom templates,
images, and other flexible elements. To send those notifications (from either the
@@ -53,40 +112,47 @@ main process or the renderer process), use the userland module
which uses native Node addons to send `ToastNotification` and `TileNotification` objects.
While notifications including buttons work with `electron-windows-notifications`,
handling replies requires the use of [`electron-windows-interactive-notifications`](https://github.com/felixrieseberg/electron-windows-interactive-notifications), which
helps with registering the required COM components and calling your Electron app with
the entered user data.
handling replies requires the use of
[`electron-windows-interactive-notifications`](https://github.com/felixrieseberg/electron-windows-interactive-notifications),
which helps with registering the required COM components and calling your
Electron app with the entered user data.
### Quiet Hours / Presentation Mode
#### Quiet Hours / Presentation Mode
To detect whether or not you're allowed to send a notification, use the userland module
[electron-notification-state](https://github.com/felixrieseberg/electron-notification-state).
To detect whether or not you're allowed to send a notification, use the
userland module [electron-notification-state](https://github.com/felixrieseberg/electron-notification-state).
This allows you to determine ahead of time whether or not Windows will silently throw
the notification away.
This allows you to determine ahead of time whether or not Windows will
silently throw the notification away.
## macOS
### macOS
Notifications are straight-forward on macOS, but you should be aware of
[Apple's Human Interface guidelines regarding notifications](https://developer.apple.com/macos/human-interface-guidelines/system-capabilities/notifications/).
[Apple's Human Interface guidelines regarding notifications][apple-notification-guidelines].
Note that notifications are limited to 256 bytes in size and will be truncated
if you exceed that limit.
### Advanced Notifications
[apple-notification-guidelines]: https://developer.apple.com/macos/human-interface-guidelines/system-capabilities/notifications/
#### Advanced Notifications
Later versions of macOS allow for notifications with an input field, allowing the user
to quickly reply to a notification. In order to send notifications with an input field,
use the userland module [node-mac-notifier](https://github.com/CharlieHess/node-mac-notifier).
use the userland module [node-mac-notifier][node-mac-notifier].
### Do not disturb / Session State
[node-mac-notifier]: https://github.com/CharlieHess/node-mac-notifier
#### Do not disturb / Session State
To detect whether or not you're allowed to send a notification, use the userland module
[electron-notification-state](https://github.com/felixrieseberg/electron-notification-state).
[electron-notification-state][electron-notification-state].
This will allow you to detect ahead of time whether or not the notification will be displayed.
## Linux
[electron-notification-state]: https://github.com/felixrieseberg/electron-notification-state
### Linux
Notifications are sent using `libnotify` which can show notifications on any
desktop environment that follows [Desktop Notifications

View File

@@ -1,14 +1,30 @@
# Online/Offline Event Detection
[Online and offline event](https://developer.mozilla.org/en-US/docs/Online_and_offline_events) detection can be implemented in the renderer process using the [`navigator.onLine`](http://html5index.org/Offline%20-%20NavigatorOnLine.html) attribute, part of standard HTML5 API.
The `navigator.onLine` attribute returns `false` if any network requests are guaranteed to fail i.e. definitely offline (disconnected from the network). It returns `true` in all other cases.
Since all other conditions return `true`, one has to be mindful of getting false positives, as we cannot assume `true` value necessarily means that Electron can access the internet. Such as in cases where the computer is running a virtualization software that has virtual ethernet adapters that are always “connected.”
Therefore, if you really want to determine the internet access status of Electron,
you should develop additional means for checking.
## Overview
Example:
[Online and offline event](https://developer.mozilla.org/en-US/docs/Online_and_offline_events)
detection can be implemented in the Renderer process using the
[`navigator.onLine`](http://html5index.org/Offline%20-%20NavigatorOnLine.html)
attribute, part of standard HTML5 API.
_main.js_
The `navigator.onLine` attribute returns:
* `false` if all network requests are guaranteed to fail (e.g. when disconnected from the network).
* `true` in all other cases.
Since many cases return `true`, you should treat with care situations of
getting false positives, as we cannot always assume that `true` value means
that Electron can access the Internet. For example, in cases when the computer
is running a virtualization software that has virtual Ethernet adapters in "always
connected" state. Therefore, if you want to determine the Internet access
status of Electron, you should develop additional means for this check.
## Example
### Event detection in the Renderer process
Starting with a working application from the
[Quick Start Guide](quick-start.md), update the `main.js` file
with the following lines:
```javascript
const { app, BrowserWindow } = require('electron')
@@ -21,33 +37,39 @@ app.whenReady().then(() => {
})
```
_online-status.html_
create the `online-status.html` file and add the following line before the
closing `</body>` tag:
```html
<!DOCTYPE html>
<html>
<body>
<script>
const alertOnlineStatus = () => {
window.alert(navigator.onLine ? 'online' : 'offline')
}
window.addEventListener('online', alertOnlineStatus)
window.addEventListener('offline', alertOnlineStatus)
alertOnlineStatus()
</script>
</body>
</html>
<script src="renderer.js"></script>
```
There may be instances where you want to respond to these events in the
main process as well. The main process however does not have a
`navigator` object and thus cannot detect these events directly. Using
Electron's inter-process communication utilities, the events can be forwarded
to the main process and handled as needed, as shown in the following example.
and add the `renderer.js` file:
_main.js_
```javascript
const alertOnlineStatus = () => { window.alert(navigator.onLine ? 'online' : 'offline') }
window.addEventListener('online', alertOnlineStatus)
window.addEventListener('offline', alertOnlineStatus)
alertOnlineStatus()
```
After launching the Electron application, you should see the notification:
![Online-offline-event detection](../images/online-event-detection.png)
### Event detection in the Main process
There may be situations when you want to respond to online/offline events in
the Main process as well. The Main process, however, does not have a
`navigator` object and cannot detect these events directly. In this case, you
need to forward the events to the Main process using Electron's inter-process
communication (IPC) utilities.
Starting with a working application from the
[Quick Start Guide](quick-start.md), update the `main.js` file
with the following lines:
```javascript
const { app, BrowserWindow, ipcMain } = require('electron')
@@ -63,23 +85,33 @@ ipcMain.on('online-status-changed', (event, status) => {
})
```
_online-status.html_
create the `online-status.html` file and add the following line before the
closing `</body>` tag:
```html
<!DOCTYPE html>
<html>
<body>
<script>
const { ipcRenderer } = require('electron')
const updateOnlineStatus = () => {
ipcRenderer.send('online-status-changed', navigator.onLine ? 'online' : 'offline')
}
window.addEventListener('online', updateOnlineStatus)
window.addEventListener('offline', updateOnlineStatus)
updateOnlineStatus()
</script>
</body>
</html>
<script src="renderer.js"></script>
```
and add the `renderer.js` file:
```javascript
const { ipcRenderer } = require('electron')
const updateOnlineStatus = () => { ipcRenderer.send('online-status-changed', navigator.onLine ? 'online' : 'offline') }
window.addEventListener('online', updateOnlineStatus)
window.addEventListener('offline', updateOnlineStatus)
updateOnlineStatus()
```
After launching the Electron application, you should see the notification in the
Console:
```sh
npm start
> electron@1.0.0 start /electron
> electron .
online
```

View File

@@ -1,29 +1,50 @@
# Progress Bar in Taskbar (Windows, macOS, Unity)
On Windows a taskbar button can be used to display a progress bar. This enables
a window to provide progress information to the user without the user having to
switch to the window itself.
## Overview
On macOS the progress bar will be displayed as a part of the dock icon.
A progress bar enables a window to provide progress information to the user
without the need of switching to the window itself.
The Unity DE also has a similar feature that allows you to specify the progress
bar in the launcher.
On Windows, you can use a taskbar button to display a progress bar.
__Progress bar in taskbar button:__
![Windows Progress Bar][windows-progress-bar]
![Taskbar Progress Bar][taskbar-progress-image]
On macOS, the progress bar will be displayed as a part of the dock icon.
All three cases are covered by the same API - the `setProgressBar()` method
available on instances of `BrowserWindows`. Call it with a number between `0`
and `1` to indicate your progress. If you have a long-running task that's
currently at 63% towards completion, you'd call it with `setProgressBar(0.63)`.
![macOS Progress Bar][macos-progress-bar]
Generally speaking, setting the parameter to a value below zero (like `-1`)
will remove the progress bar while setting it to a value higher than one
(like `2`) will switch the progress bar to intermediate mode.
On Linux, the Unity graphical interface also has a similar feature that allows
you to specify the progress bar in the launcher.
![Linux Progress Bar][linux-progress-bar]
> NOTE: on Windows, each window can have its own progress bar, whereas on macOS
and Linux (Unity) there can be only one progress bar for the application.
----
All three cases are covered by the same API - the
[`setProgressBar()`][setprogressbar] method available on an instance of
`BrowserWindow`. To indicate your progress, call this method with a number
between `0` and `1`. For example, if you have a long-running task that is
currently at 63% towards completion, you would call it as
`setProgressBar(0.63)`.
Setting the parameter to negative values (e.g. `-1`) will remove the progress
bar, whereas setting it to values greater than `1` (e.g. `2`) will switch the
progress bar to indeterminate mode (Windows-only -- it will clamp to 100%
otherwise). In this mode, a progress bar remains active but does not show an
actual percentage. Use this mode for situations when you do not know how long
an operation will take to complete.
See the [API documentation for more options and modes][setprogressbar].
## Example
Starting with a working application from the
[Quick Start Guide](quick-start.md), add the following lines to the
`main.js` file:
```javascript
const { BrowserWindow } = require('electron')
const win = new BrowserWindow()
@@ -31,5 +52,18 @@ const win = new BrowserWindow()
win.setProgressBar(0.5)
```
[taskbar-progress-image]: https://cloud.githubusercontent.com/assets/639601/5081682/16691fda-6f0e-11e4-9676-49b6418f1264.png
[setprogressbar]: ../api/browser-window.md#winsetprogressbarprogress
After launching the Electron application, you should see the bar in
the dock (macOS) or taskbar (Windows, Unity), indicating the progress
percentage you just defined.
![macOS dock progress bar](../images/dock-progress-bar.png)
For macOS, the progress bar will also be indicated for your application
when using [Mission Control](https://support.apple.com/en-us/HT204100):
![Mission Control Progress Bar](../images/mission-control-progress-bar.png)
[windows-progress-bar]: https://cloud.githubusercontent.com/assets/639601/5081682/16691fda-6f0e-11e4-9676-49b6418f1264.png
[macos-progress-bar]: ../images/macos-progress-bar.png
[linux-progress-bar]: ../images/linux-progress-bar.png
[setprogressbar]: ../api/browser-window.md#winsetprogressbarprogress-options

View File

@@ -1,5 +1,7 @@
# Recent Documents (Windows & macOS)
## Overview
Windows and macOS provide access to a list of recent documents opened by
the application via JumpList or dock menu, respectively.
@@ -11,39 +13,58 @@ __Application dock menu:__
![macOS Dock Menu][dock-menu-image]
To add a file to recent documents, you can use the
[app.addRecentDocument][addrecentdocument] API:
To add a file to recent documents, you need to use the
[app.addRecentDocument][addrecentdocument] API.
## Example
### Add an item to recent documents
Starting with a working application from the
[Quick Start Guide](quick-start.md), add the following lines to the
`main.js` file:
```javascript
const { app } = require('electron')
app.addRecentDocument('/Users/USERNAME/Desktop/work.type')
```
And you can use [app.clearRecentDocuments][clearrecentdocuments] API to empty
the recent documents list:
After launching the Electron application, right click the application icon.
You should see the item you just added. In this guide, the item is a Markdown
file located in the root of the project:
![Recent document](../images/recent-documents.png)
### Clear the list of recent documents
To clear the list of recent documents, you need to use
[app.clearRecentDocuments][clearrecentdocuments] API in the `main.js` file:
```javascript
const { app } = require('electron')
app.clearRecentDocuments()
```
## Windows Notes
## Additional information
In order to be able to use this feature on Windows, your application has to be
registered as a handler of the file type of the document, otherwise the file
won't appear in JumpList even after you have added it. You can find everything
### Windows Notes
To use this feature on Windows, your application has to be registered as
a handler of the file type of the document, otherwise the file won't appear
in JumpList even after you have added it. You can find everything
on registering your application in [Application Registration][app-registration].
When a user clicks a file from the JumpList, a new instance of your application
will be started with the path of the file added as a command line argument.
## macOS Notes
### macOS Notes
### Adding the Recent Documents list to the application menu:
#### Add the Recent Documents list to the application menu
![macOS Recent Documents menu item][menu-item-image]
You can add menu items to access and clear recent documents by adding the following code snippet to your menu's template.
You can add menu items to access and clear recent documents by adding the
following code snippet to your menu template:
```json
{
@@ -62,6 +83,8 @@ You can add menu items to access and clear recent documents by adding the follow
}
```
![macOS Recent Documents menu item][menu-item-image]
When a file is requested from the recent documents menu, the `open-file` event
of `app` module will be emitted for it.

View File

@@ -1,28 +1,45 @@
# Represented File for macOS BrowserWindows
On macOS a window can set its represented file, so the file's icon can show in
the title bar and when users Command-Click or Control-Click on the title a path
popup will show.
## Overview
You can also set the edited state of a window so that the file icon can indicate
whether the document in this window has been modified.
__Represented file popup menu:__
On macOS, you can set a represented file for any window in your application.
The represented file's icon will be shown in the title bar, and when users
`Command-Click` or `Control-Click`, a popup with a path to the file will be
shown.
![Represented File][represented-image]
> NOTE: The screenshot above is an example where this feature is used to indicate the currently opened file in the Atom text editor.
You can also set the edited state for a window so that the file icon can
indicate whether the document in this window has been modified.
To set the represented file of window, you can use the
[BrowserWindow.setRepresentedFilename][setrepresentedfilename] and
[BrowserWindow.setDocumentEdited][setdocumentedited] APIs:
[BrowserWindow.setDocumentEdited][setdocumentedited] APIs.
## Example
Starting with a working application from the
[Quick Start Guide](quick-start.md), add the following lines to the
`main.js` file:
```javascript
const { BrowserWindow } = require('electron')
const { app, BrowserWindow } = require('electron')
const win = new BrowserWindow()
win.setRepresentedFilename('/etc/passwd')
win.setDocumentEdited(true)
app.whenReady().then(() => {
const win = new BrowserWindow()
win.setRepresentedFilename('/etc/passwd')
win.setDocumentEdited(true)
})
```
After launching the Electron application, click on the title with `Command` or
`Control` key pressed. You should see a popup with the file you just defined:
![Represented file](../images/represented-file.png)
[represented-image]: https://cloud.githubusercontent.com/assets/639601/5082061/670a949a-6f14-11e4-987a-9aaa04b23c1d.png
[setrepresentedfilename]: ../api/browser-window.md#winsetrepresentedfilenamefilename-macos
[setdocumentedited]: ../api/browser-window.md#winsetdocumenteditededited-macos

View File

@@ -814,6 +814,6 @@ which potential security issues are not as widely known.
[web-contents]: ../api/web-contents.md
[new-window]: ../api/web-contents.md#event-new-window
[will-navigate]: ../api/web-contents.md#event-will-navigate
[open-external]: ../api/shell.md#shellopenexternalurl-options-callback
[open-external]: ../api/shell.md#shellopenexternalurl-options
[sandbox]: ../api/sandbox-option.md
[responsible-disclosure]: https://en.wikipedia.org/wiki/Responsible_disclosure

View File

@@ -79,6 +79,78 @@ snap(options)
.then(snapPath => console.log(`Created snap at ${snapPath}!`))
```
## Using `snapcraft` with `electron-packager`
### Step 1: Create Sample Snapcraft Project
Create your project directory and add add the following to `snap/snapcraft.yaml`:
```yaml
name: electron-packager-hello-world
version: '0.1'
summary: Hello World Electron app
description: |
Simple Hello World Electron app as an example
base: core18
confinement: strict
grade: stable
apps:
electron-packager-hello-world:
command: electron-quick-start/electron-quick-start --no-sandbox
extensions: [gnome-3-34]
plugs:
- browser-support
- network
- network-bind
environment:
# Correct the TMPDIR path for Chromium Framework/Electron to ensure
# libappindicator has readable resources.
TMPDIR: $XDG_RUNTIME_DIR
parts:
electron-quick-start:
plugin: nil
source: https://github.com/electron/electron-quick-start.git
override-build: |
npm install electron electron-packager
npx electron-packager . --overwrite --platform=linux --output=release-build --prune=true
cp -rv ./electron-quick-start-linux-* $SNAPCRAFT_PART_INSTALL/electron-quick-start
build-snaps:
- node/14/stable
build-packages:
- unzip
stage-packages:
- libnss3
- libnspr4
```
If you want to apply this example to an existing project:
- Replace `source: https://github.com/electron/electron-quick-start.git` with `source: .`.
- Replace all instances of `electron-quick-start` with your project's name.
### Step 2: Build the snap
```sh
$ snapcraft
<output snipped>
Snapped electron-packager-hello-world_0.1_amd64.snap
```
### Step 3: Install the snap
```sh
sudo snap install electron-packager-hello-world_0.1_amd64.snap --dangerous
```
### Step 4: Run the snap
```sh
electron-packager-hello-world
```
## Using an Existing Debian Package
Snapcraft is capable of taking an existing `.deb` file and turning it into

View File

@@ -9,8 +9,12 @@ If you're looking for programming help,
for answers to questions,
or to join in discussion with other developers who use Electron,
you can interact with the community in these locations:
- [`electron`](https://discuss.atom.io/c/electron) category on the Atom
forums
- [`Electron's Discord`](https://discord.com/invite/electron) has channels for:
- Getting help
- Ecosystem apps like [Electron Forge](https://github.com/electron-userland/electron-forge) and [Electron Fiddle](https://github.com/electron/fiddle)
- Sharing ideas with other Electron app developers
- And more!
- [`electron`](https://discuss.atom.io/c/electron) category on the Atom forums
- `#atom-shell` channel on Freenode
- `#electron` channel on [Atom's Slack](https://discuss.atom.io/t/join-us-on-slack/16638?source_topic_id=25406)
- [`electron-ru`](https://telegram.me/electron_ru) *(Russian)*

View File

@@ -1,22 +1,57 @@
# Web embeds in Electron
# Web embeds
If you want to embed (third party) web content in an Electron `BrowserWindow`, there are three options available to you: `<iframe>` tags, `<webview>` tags, and `BrowserViews`. Each one offers slightly different functionality and is useful in different situations. To help you choose between these, this guide will explain the differences and capabilities of each.
## Overview
## Iframes
If you want to embed (third-party) web content in an Electron `BrowserWindow`,
there are three options available to you: `<iframe>` tags, `<webview>` tags,
and `BrowserViews`. Each one offers slightly different functionality and is
useful in different situations. To help you choose between these, this guide
explains the differences and capabilities of each option.
Iframes in Electron behave like iframes in regular browsers. An `<iframe>` element in your page can show external web pages, provided that their [Content Security Policy](https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP) allows it. To limit the amount of capabilities a site in an `<iframe>` tag, it's recommended to use the [`sandbox` attribute](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/iframe#attr-sandbox) and only allow the capabilities you want to support.
### Iframes
## WebViews
Iframes in Electron behave like iframes in regular browsers. An `<iframe>`
element in your page can show external web pages, provided that their
[Content Security Policy](https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP)
allows it. To limit the number of capabilities of a site in an `<iframe>` tag,
it is recommended to use the [`sandbox` attribute](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/iframe#attr-sandbox)
and only allow the capabilities you want to support.
[WebViews](../api/webview-tag.md) are based on Chromium's WebViews and are not explicitly supported by Electron. We do not guarantee that the WebView API will remain available in future versions of Electron. This is why, if you want to use `<webview>` tags, you will need to set `webviewTag` to `true` in the `webPreferences` of your `BrowserWindow`.
### WebViews
WebViews are a custom element (`<webview>`) that will only work inside Electron.
They are implemented as an "out-of-process iframe". This means that all communication with the `<webview>` is done asynchronously using IPC. The `<webview>` element has many custom methods and events, similar to `webContents`, that allow you much greater control over the contents.
> Important Note:
[we do not recommend you to use use WebViews](https://www.electronjs.org/docs/api/webview-tag#warning),
as this tag undergoes dramatic architectural changes that may affect stability
of your application. Consider switching to alternatives, like `iframe` and
Electron's `BrowserView`, or an architecture that avoids embedded content
by design.
Compared to an `<iframe>`, `<webview>` tends to be slightly slower but offers much greater control in loading and communicating with the third party content and handling various events.
[WebViews](../api/webview-tag.md) are based on Chromium's WebViews and are not
explicitly supported by Electron. We do not guarantee that the WebView API will
remain available in future versions of Electron. To use `<webview>` tags, you
will need to set `webviewTag` to `true` in the `webPreferences` of your
`BrowserWindow`.
## BrowserViews
WebView is a custom element (`<webview>`) that will only work inside Electron.
They are implemented as an "out-of-process iframe". This means that all
communication with the `<webview>` is done asynchronously using IPC. The
`<webview>` element has many custom methods and events, similar to
`webContents`, that provide you with greater control over the content.
[BrowserViews](../api/browser-view.md) are not part of the DOM - instead, they are created in and controlled by your main process. They are simply another layer of web content on top of your existing window. This means that they are completely separate from your own `BrowserWindow` content and that their position is not controlled by the DOM or CSS but by setting the bounds in the main process.
Compared to an `<iframe>`, `<webview>` tends to be slightly slower but offers
much greater control in loading and communicating with the third-party content
and handling various events.
BrowserViews offer the greatest control over their contents, since they implement the `webContents` similarly to how a `BrowserWindow` implements it. However, they are not part of your DOM but are overlaid on top of them, which means you will have to manage their position manually.
### BrowserViews
[BrowserViews](../api/browser-view.md) are not a part of the DOM - instead,
they are created in and controlled by your Main process. They are simply
another layer of web content on top of your existing window. This means
that they are completely separate from your own `BrowserWindow` content and
their position is not controlled by the DOM or CSS. Instead, it is controlled
by setting the bounds in the Main process.
`BrowserViews` offer the greatest control over their contents, since they
implement the `webContents` similarly to how the `BrowserWindow` does it.
However, as `BrowserViews` are not a part of your DOM, but are rather overlaid
on top of them, you will have to manage their position manually.

View File

@@ -49,6 +49,7 @@ auto_filenames = {
"docs/api/screen.md",
"docs/api/service-workers.md",
"docs/api/session.md",
"docs/api/share-menu.md",
"docs/api/shell.md",
"docs/api/structures",
"docs/api/synopsis.md",
@@ -119,6 +120,7 @@ auto_filenames = {
"docs/api/structures/serial-port.md",
"docs/api/structures/service-worker-info.md",
"docs/api/structures/shared-worker-info.md",
"docs/api/structures/sharing-item.md",
"docs/api/structures/shortcut-details.md",
"docs/api/structures/size.md",
"docs/api/structures/task.md",
@@ -219,6 +221,7 @@ auto_filenames = {
"lib/browser/api/protocol.ts",
"lib/browser/api/screen.ts",
"lib/browser/api/session.ts",
"lib/browser/api/share-menu.ts",
"lib/browser/api/system-preferences.ts",
"lib/browser/api/touch-bar.ts",
"lib/browser/api/tray.ts",

View File

@@ -1,3 +1,5 @@
import("//build/config/ui.gni")
filenames = {
default_app_ts_sources = [
"default_app/default_app.ts",
@@ -22,35 +24,25 @@ filenames = {
]
lib_sources_linux = [
"chromium_src/chrome/browser/ui/views/frame/global_menu_bar_registrar_x11.cc",
"chromium_src/chrome/browser/ui/views/frame/global_menu_bar_registrar_x11.h",
"shell/browser/browser_linux.cc",
"shell/browser/lib/power_observer_linux.cc",
"shell/browser/lib/power_observer_linux.h",
"shell/browser/linux/unity_service.cc",
"shell/browser/linux/unity_service.h",
"shell/browser/notifications/linux/libnotify_notification.cc",
"shell/browser/notifications/linux/libnotify_notification.h",
"shell/browser/notifications/linux/notification_presenter_linux.cc",
"shell/browser/notifications/linux/notification_presenter_linux.h",
"shell/browser/relauncher_linux.cc",
"shell/browser/ui/file_dialog_gtk.cc",
"shell/browser/ui/message_box_gtk.cc",
"shell/browser/ui/tray_icon_gtk.cc",
"shell/browser/ui/tray_icon_gtk.h",
"shell/browser/ui/views/global_menu_bar_x11.cc",
"shell/browser/ui/views/global_menu_bar_x11.h",
"shell/browser/ui/x/event_disabler.cc",
"shell/browser/ui/x/event_disabler.h",
"shell/browser/ui/x/window_state_watcher.cc",
"shell/browser/ui/x/window_state_watcher.h",
"shell/browser/ui/x/x_window_utils.cc",
"shell/browser/ui/x/x_window_utils.h",
"shell/browser/browser_linux.cc",
"shell/browser/lib/power_observer_linux.cc",
"shell/browser/lib/power_observer_linux.h",
"shell/browser/notifications/linux/notification_presenter_linux.cc",
"shell/browser/notifications/linux/notification_presenter_linux.h",
"shell/browser/relauncher_linux.cc",
"shell/common/application_info_linux.cc",
"shell/common/language_util_linux.cc",
"shell/common/node_bindings_linux.cc",
"shell/common/node_bindings_linux.h",
"shell/common/platform_util_linux.cc",
"shell/browser/linux/unity_service.h",
"shell/browser/notifications/linux/libnotify_notification.cc",
"shell/browser/notifications/linux/libnotify_notification.h",
"shell/browser/linux/unity_service.cc",
]
lib_sources_posix = [
@@ -68,6 +60,17 @@ filenames = {
"shell/browser/notifications/win/notification_presenter_win.h",
"shell/browser/notifications/win/notification_presenter_win7.cc",
"shell/browser/notifications/win/notification_presenter_win7.h",
"shell/browser/notifications/win/win32_desktop_notifications/common.h",
"shell/browser/notifications/win/win32_desktop_notifications/desktop_notification_controller.cc",
"shell/browser/notifications/win/win32_desktop_notifications/desktop_notification_controller.h",
"shell/browser/notifications/win/win32_desktop_notifications/toast_uia.cc",
"shell/browser/notifications/win/win32_desktop_notifications/toast_uia.h",
"shell/browser/notifications/win/win32_desktop_notifications/toast.cc",
"shell/browser/notifications/win/win32_desktop_notifications/toast.h",
"shell/browser/notifications/win/win32_notification.cc",
"shell/browser/notifications/win/win32_notification.h",
"shell/browser/notifications/win/windows_toast_notification.cc",
"shell/browser/notifications/win/windows_toast_notification.h",
"shell/browser/relauncher_win.cc",
"shell/browser/ui/certificate_trust_win.cc",
"shell/browser/ui/file_dialog_win.cc",
@@ -76,39 +79,28 @@ filenames = {
"shell/browser/ui/views/electron_views_delegate_win.cc",
"shell/browser/ui/views/win_frame_view.cc",
"shell/browser/ui/views/win_frame_view.h",
"shell/browser/ui/win/dialog_thread.cc",
"shell/browser/ui/win/dialog_thread.h",
"shell/browser/ui/win/electron_desktop_native_widget_aura.cc",
"shell/browser/ui/win/electron_desktop_native_widget_aura.h",
"shell/browser/ui/win/electron_desktop_window_tree_host_win.cc",
"shell/browser/ui/win/electron_desktop_window_tree_host_win.h",
"shell/browser/ui/win/jump_list.cc",
"shell/browser/ui/win/jump_list.h",
"shell/browser/ui/win/notify_icon_host.cc",
"shell/browser/ui/win/notify_icon_host.h",
"shell/browser/ui/win/notify_icon.cc",
"shell/browser/ui/win/notify_icon.h",
"shell/browser/ui/win/taskbar_host.cc",
"shell/browser/ui/win/taskbar_host.h",
"shell/browser/win/scoped_hstring.cc",
"shell/browser/win/scoped_hstring.h",
"shell/common/api/electron_api_native_image_win.cc",
"shell/common/application_info_win.cc",
"shell/common/language_util_win.cc",
"shell/common/node_bindings_win.cc",
"shell/common/node_bindings_win.h",
"shell/common/platform_util_win.cc",
"shell/browser/notifications/win/win32_desktop_notifications/common.h",
"shell/browser/notifications/win/win32_desktop_notifications/desktop_notification_controller.cc",
"shell/browser/notifications/win/win32_desktop_notifications/desktop_notification_controller.h",
"shell/browser/notifications/win/win32_desktop_notifications/toast.cc",
"shell/browser/notifications/win/win32_desktop_notifications/toast.h",
"shell/browser/notifications/win/win32_desktop_notifications/toast_uia.cc",
"shell/browser/notifications/win/win32_desktop_notifications/toast_uia.h",
"shell/browser/notifications/win/win32_notification.cc",
"shell/browser/notifications/win/win32_notification.h",
"shell/browser/notifications/win/windows_toast_notification.cc",
"shell/browser/notifications/win/windows_toast_notification.h",
"shell/browser/ui/win/dialog_thread.cc",
"shell/browser/ui/win/dialog_thread.h",
"shell/browser/ui/win/electron_desktop_native_widget_aura.cc",
"shell/browser/ui/win/electron_desktop_native_widget_aura.h",
"shell/browser/ui/win/jump_list.cc",
"shell/browser/ui/win/jump_list.h",
"shell/browser/ui/win/notify_icon.cc",
"shell/browser/ui/win/notify_icon.h",
"shell/browser/ui/win/notify_icon_host.cc",
"shell/browser/ui/win/notify_icon_host.h",
"shell/browser/ui/win/taskbar_host.cc",
"shell/browser/ui/win/taskbar_host.h",
"shell/browser/win/scoped_hstring.cc",
"shell/browser/win/scoped_hstring.h",
]
lib_sources_mac = [
@@ -124,22 +116,56 @@ filenames = {
"shell/browser/api/electron_api_web_contents_mac.mm",
"shell/browser/auto_updater_mac.mm",
"shell/browser/browser_mac.mm",
"shell/browser/notifications/mac/notification_center_delegate.h",
"shell/browser/notifications/mac/notification_center_delegate.mm",
"shell/common/mac/main_application_bundle.h",
"shell/common/mac/main_application_bundle.mm",
"shell/browser/common_web_contents_delegate_mac.mm",
"shell/browser/electron_browser_main_parts_mac.mm",
"shell/browser/mac/dict_util.h",
"shell/browser/mac/dict_util.mm",
"shell/browser/mac/electron_application_delegate.h",
"shell/browser/mac/electron_application_delegate.mm",
"shell/browser/mac/electron_application.h",
"shell/browser/mac/electron_application.mm",
"shell/browser/mac/in_app_purchase_observer.h",
"shell/browser/mac/in_app_purchase_observer.mm",
"shell/browser/mac/in_app_purchase_product.h",
"shell/browser/mac/in_app_purchase_product.mm",
"shell/browser/mac/in_app_purchase.h",
"shell/browser/mac/in_app_purchase.mm",
"shell/browser/native_browser_view_mac.h",
"shell/browser/native_browser_view_mac.mm",
"shell/browser/native_window_mac.h",
"shell/browser/native_window_mac.mm",
"shell/browser/notifications/mac/cocoa_notification.h",
"shell/browser/notifications/mac/cocoa_notification.mm",
"shell/browser/notifications/mac/notification_center_delegate.h",
"shell/browser/notifications/mac/notification_center_delegate.mm",
"shell/browser/notifications/mac/notification_presenter_mac.h",
"shell/browser/notifications/mac/notification_presenter_mac.mm",
"shell/browser/relauncher_mac.cc",
"shell/browser/ui/certificate_trust_mac.mm",
"shell/browser/ui/cocoa/delayed_native_view_host.cc",
"shell/browser/ui/cocoa/delayed_native_view_host.h",
"shell/browser/ui/cocoa/electron_bundle_mover.h",
"shell/browser/ui/cocoa/electron_bundle_mover.mm",
"shell/browser/ui/cocoa/electron_inspectable_web_contents_view.h",
"shell/browser/ui/cocoa/electron_inspectable_web_contents_view.mm",
"shell/browser/ui/cocoa/electron_menu_controller.h",
"shell/browser/ui/cocoa/electron_menu_controller.mm",
"shell/browser/ui/cocoa/electron_native_widget_mac.h",
"shell/browser/ui/cocoa/electron_native_widget_mac.mm",
"shell/browser/ui/cocoa/electron_ns_window_delegate.h",
"shell/browser/ui/cocoa/electron_ns_window_delegate.mm",
"shell/browser/ui/cocoa/electron_ns_window.h",
"shell/browser/ui/cocoa/electron_ns_window.mm",
"shell/browser/ui/cocoa/electron_preview_item.h",
"shell/browser/ui/cocoa/electron_preview_item.mm",
"shell/browser/ui/cocoa/electron_touch_bar.h",
"shell/browser/ui/cocoa/electron_touch_bar.mm",
"shell/browser/ui/cocoa/event_dispatching_window.h",
"shell/browser/ui/cocoa/event_dispatching_window.mm",
"shell/browser/ui/cocoa/NSColor+Hex.h",
"shell/browser/ui/cocoa/NSColor+Hex.mm",
"shell/browser/ui/cocoa/NSString+ANSI.h",
"shell/browser/ui/cocoa/NSString+ANSI.mm",
"shell/browser/ui/cocoa/root_view_mac.h",
"shell/browser/ui/cocoa/root_view_mac.mm",
"shell/browser/ui/cocoa/views_delegate_mac.h",
@@ -149,51 +175,17 @@ filenames = {
"shell/browser/ui/inspectable_web_contents_view_mac.h",
"shell/browser/ui/inspectable_web_contents_view_mac.mm",
"shell/browser/ui/message_box_mac.mm",
"shell/browser/ui/tray_icon_cocoa.h",
"shell/browser/ui/tray_icon_cocoa.mm",
"shell/common/api/electron_api_clipboard_mac.mm",
"shell/common/api/electron_api_native_image_mac.mm",
"shell/common/application_info_mac.mm",
"shell/common/language_util_mac.mm",
"shell/common/mac/main_application_bundle.h",
"shell/common/mac/main_application_bundle.mm",
"shell/common/node_bindings_mac.cc",
"shell/common/node_bindings_mac.h",
"shell/common/platform_util_mac.mm",
"shell/browser/notifications/mac/cocoa_notification.h",
"shell/browser/notifications/mac/cocoa_notification.mm",
"shell/browser/ui/cocoa/NSColor+Hex.h",
"shell/browser/ui/cocoa/NSColor+Hex.mm",
"shell/browser/ui/cocoa/NSString+ANSI.h",
"shell/browser/ui/cocoa/NSString+ANSI.mm",
"shell/browser/ui/cocoa/delayed_native_view_host.cc",
"shell/browser/ui/cocoa/delayed_native_view_host.h",
"shell/browser/ui/cocoa/electron_bundle_mover.h",
"shell/browser/ui/cocoa/electron_bundle_mover.mm",
"shell/browser/ui/cocoa/electron_inspectable_web_contents_view.h",
"shell/browser/ui/cocoa/electron_inspectable_web_contents_view.mm",
"shell/browser/ui/cocoa/electron_menu_controller.h",
"shell/browser/ui/cocoa/electron_menu_controller.mm",
"shell/browser/ui/cocoa/electron_ns_window.h",
"shell/browser/ui/cocoa/electron_ns_window.mm",
"shell/browser/ui/cocoa/electron_ns_window_delegate.h",
"shell/browser/ui/cocoa/electron_ns_window_delegate.mm",
"shell/browser/ui/cocoa/electron_preview_item.h",
"shell/browser/ui/cocoa/electron_preview_item.mm",
"shell/browser/ui/cocoa/electron_touch_bar.h",
"shell/browser/ui/cocoa/electron_touch_bar.mm",
"shell/browser/ui/cocoa/event_dispatching_window.h",
"shell/browser/ui/cocoa/event_dispatching_window.mm",
"shell/browser/ui/tray_icon_cocoa.h",
"shell/browser/ui/tray_icon_cocoa.mm",
"shell/browser/mac/dict_util.h",
"shell/browser/mac/dict_util.mm",
"shell/browser/mac/electron_application.h",
"shell/browser/mac/electron_application.mm",
"shell/browser/mac/electron_application_delegate.h",
"shell/browser/mac/electron_application_delegate.mm",
"shell/browser/mac/in_app_purchase.h",
"shell/browser/mac/in_app_purchase.mm",
"shell/browser/mac/in_app_purchase_observer.h",
"shell/browser/mac/in_app_purchase_observer.mm",
"shell/browser/mac/in_app_purchase_product.h",
"shell/browser/mac/in_app_purchase_product.mm",
]
lib_sources_views = [
@@ -206,14 +198,14 @@ filenames = {
"shell/browser/native_window_views.cc",
"shell/browser/native_window_views.h",
"shell/browser/ui/drag_util_views.cc",
"shell/browser/ui/views/inspectable_web_contents_view_views.cc",
"shell/browser/ui/views/inspectable_web_contents_view_views.h",
"shell/browser/ui/views/autofill_popup_view.cc",
"shell/browser/ui/views/autofill_popup_view.h",
"shell/browser/ui/views/electron_views_delegate.cc",
"shell/browser/ui/views/electron_views_delegate.h",
"shell/browser/ui/views/frameless_view.cc",
"shell/browser/ui/views/frameless_view.h",
"shell/browser/ui/views/inspectable_web_contents_view_views.cc",
"shell/browser/ui/views/inspectable_web_contents_view_views.h",
"shell/browser/ui/views/menu_bar.cc",
"shell/browser/ui/views/menu_bar.h",
"shell/browser/ui/views/menu_delegate.cc",
@@ -642,6 +634,21 @@ filenames = {
"shell/utility/electron_content_utility_client.h",
]
if (use_x11) {
lib_sources_linux += [
"chromium_src/chrome/browser/ui/views/frame/global_menu_bar_registrar_x11.cc",
"chromium_src/chrome/browser/ui/views/frame/global_menu_bar_registrar_x11.h",
"shell/browser/ui/views/global_menu_bar_x11.cc",
"shell/browser/ui/views/global_menu_bar_x11.h",
"shell/browser/ui/x/event_disabler.cc",
"shell/browser/ui/x/event_disabler.h",
"shell/browser/ui/x/window_state_watcher.cc",
"shell/browser/ui/x/window_state_watcher.h",
"shell/browser/ui/x/x_window_utils.cc",
"shell/browser/ui/x/x_window_utils.h",
]
}
lib_sources_nss = [
"chromium_src/chrome/browser/certificate_manager_model.cc",
"chromium_src/chrome/browser/certificate_manager_model.h",
@@ -650,16 +657,16 @@ filenames = {
lib_sources_extensions = [
"shell/browser/extensions/api/i18n/i18n_api.cc",
"shell/browser/extensions/api/i18n/i18n_api.h",
"shell/browser/extensions/api/management/electron_management_api_delegate.cc",
"shell/browser/extensions/api/management/electron_management_api_delegate.h",
"shell/browser/extensions/api/resources_private/resources_private_api.cc",
"shell/browser/extensions/api/resources_private/resources_private_api.h",
"shell/browser/extensions/api/runtime/electron_runtime_api_delegate.cc",
"shell/browser/extensions/api/runtime/electron_runtime_api_delegate.h",
"shell/browser/extensions/api/management/electron_management_api_delegate.cc",
"shell/browser/extensions/api/management/electron_management_api_delegate.h",
"shell/browser/extensions/api/tabs/tabs_api.cc",
"shell/browser/extensions/api/tabs/tabs_api.h",
"shell/browser/extensions/api/streams_private/streams_private_api.cc",
"shell/browser/extensions/api/streams_private/streams_private_api.h",
"shell/browser/extensions/api/tabs/tabs_api.cc",
"shell/browser/extensions/api/tabs/tabs_api.h",
"shell/browser/extensions/electron_browser_context_keyed_service_factories.cc",
"shell/browser/extensions/electron_browser_context_keyed_service_factories.h",
"shell/browser/extensions/electron_component_extension_resource_manager.cc",
@@ -672,10 +679,10 @@ filenames = {
"shell/browser/extensions/electron_extension_loader.h",
"shell/browser/extensions/electron_extension_message_filter.cc",
"shell/browser/extensions/electron_extension_message_filter.h",
"shell/browser/extensions/electron_extension_system.cc",
"shell/browser/extensions/electron_extension_system.h",
"shell/browser/extensions/electron_extension_system_factory.cc",
"shell/browser/extensions/electron_extension_system_factory.h",
"shell/browser/extensions/electron_extension_system.cc",
"shell/browser/extensions/electron_extension_system.h",
"shell/browser/extensions/electron_extension_web_contents_observer.cc",
"shell/browser/extensions/electron_extension_web_contents_observer.h",
"shell/browser/extensions/electron_extensions_api_client.cc",

View File

@@ -37,6 +37,8 @@ const getOrCreateArchive = (archivePath: string) => {
return newArchive;
};
const asarRe = /\.asar/i;
// Separate asar package's path from full path.
const splitPath = (archivePathOrBuffer: string | Buffer) => {
// Shortcut for disabled asar.
@@ -48,6 +50,7 @@ const splitPath = (archivePathOrBuffer: string | Buffer) => {
archivePath = archivePathOrBuffer.toString();
}
if (typeof archivePath !== 'string') return { isAsar: <const>false };
if (!asarRe.test(archivePath)) return { isAsar: <const>false };
return asar.splitPath(path.normalize(archivePath));
};
@@ -216,16 +219,16 @@ const makePromiseFunction = function (orig: Function, pathArgumentIndex: number)
// Override fs APIs.
export const wrapFsWithAsar = (fs: Record<string, any>) => {
const logFDs: Record<string, number> = {};
const logFDs = new Map<string, number>();
const logASARAccess = (asarPath: string, filePath: string, offset: number) => {
if (!process.env.ELECTRON_LOG_ASAR_READS) return;
if (!logFDs[asarPath]) {
if (!logFDs.has(asarPath)) {
const path = require('path');
const logFilename = `${path.basename(asarPath, '.asar')}-access-log.txt`;
const logPath = path.join(require('os').tmpdir(), logFilename);
logFDs[asarPath] = fs.openSync(logPath, 'a');
logFDs.set(asarPath, fs.openSync(logPath, 'a'));
}
fs.writeSync(logFDs[asarPath], `${offset}: ${filePath}\n`);
fs.writeSync(logFDs.get(asarPath), `${offset}: ${filePath}\n`);
};
const { lstatSync } = fs;

View File

@@ -6,7 +6,7 @@ const isLinux = process.platform === 'linux';
type RoleId = 'about' | 'close' | 'copy' | 'cut' | 'delete' | 'forcereload' | 'front' | 'help' | 'hide' | 'hideothers' | 'minimize' |
'paste' | 'pasteandmatchstyle' | 'quit' | 'redo' | 'reload' | 'resetzoom' | 'selectall' | 'services' | 'recentdocuments' | 'clearrecentdocuments' | 'startspeaking' | 'stopspeaking' |
'toggledevtools' | 'togglefullscreen' | 'undo' | 'unhide' | 'window' | 'zoom' | 'zoomin' | 'zoomout' | 'appmenu' | 'filemenu' | 'editmenu' | 'viewmenu' | 'windowmenu'
'toggledevtools' | 'togglefullscreen' | 'undo' | 'unhide' | 'window' | 'zoom' | 'zoomin' | 'zoomout' | 'appmenu' | 'filemenu' | 'editmenu' | 'viewmenu' | 'windowmenu' | 'sharemenu'
interface Role {
label: string;
accelerator?: string;
@@ -261,6 +261,11 @@ export const roleList: Record<RoleId, Role> = {
{ role: 'close' }
] as MenuItemConstructorOptions[])
]
},
// Share submenu
sharemenu: {
label: 'Share',
submenu: []
}
};

View File

@@ -41,6 +41,12 @@ Menu.prototype._shouldRegisterAcceleratorForCommandId = function (id) {
return this.commandsMap[id] ? this.commandsMap[id].registerAccelerator : false;
};
if (process.platform === 'darwin') {
Menu.prototype._getSharingItemForCommandId = function (id) {
return this.commandsMap[id] ? this.commandsMap[id].sharingItem : null;
};
}
Menu.prototype._executeCommand = function (event, id) {
const command = this.commandsMap[id];
if (!command) return;

View File

@@ -26,6 +26,7 @@ export const browserModuleList: ElectronInternal.ModuleEntry[] = [
{ name: 'protocol', loader: () => require('./protocol') },
{ name: 'screen', loader: () => require('./screen') },
{ name: 'session', loader: () => require('./session') },
{ name: 'ShareMenu', loader: () => require('./share-menu') },
{ name: 'systemPreferences', loader: () => require('./system-preferences') },
{ name: 'TouchBar', loader: () => require('./touch-bar') },
{ name: 'Tray', loader: () => require('./tray') },

View File

@@ -29,6 +29,7 @@ export const browserModuleNames = [
'protocol',
'screen',
'session',
'ShareMenu',
'systemPreferences',
'TouchBar',
'Tray',

View File

@@ -4,6 +4,7 @@ import { app } from 'electron/main';
import type { ClientRequestConstructorOptions, UploadProgress } from 'electron/main';
const {
isOnline,
isValidHeaderName,
isValidHeaderValue,
createURLLoader
@@ -516,3 +517,9 @@ export class ClientRequest extends Writable implements Electron.ClientRequest {
export function request (options: ClientRequestConstructorOptions | string, callback?: (message: IncomingMessage) => void) {
return new ClientRequest(options, callback);
}
exports.isOnline = isOnline;
Object.defineProperty(exports, 'online', {
get: () => isOnline()
});

View File

@@ -0,0 +1,19 @@
import { BrowserWindow, Menu, SharingItem, PopupOptions } from 'electron/main';
class ShareMenu {
private menu: Menu;
constructor (sharingItem: SharingItem) {
this.menu = new (Menu as any)({ sharingItem });
}
popup (options?: PopupOptions) {
this.menu.popup(options);
}
closePopup (browserWindow?: BrowserWindow) {
this.menu.closePopup(browserWindow);
}
}
export default ShareMenu;

View File

@@ -300,8 +300,8 @@ class TouchBar extends EventEmitter implements Electron.TouchBar {
touchBar._addToWindow(window);
}
private windowListeners: Record<number, Function> = {};
private items: Record<string, TouchBarItem<any>> = {};
private windowListeners = new Map<number, Function>();
private items = new Map<string, TouchBarItem<any>>();
orderedItems: TouchBarItem<any>[] = [];
constructor (options: Electron.TouchBarConstructorOptions) {
@@ -317,12 +317,10 @@ class TouchBar extends EventEmitter implements Electron.TouchBar {
items = [];
}
this.windowListeners = {};
this.items = {};
this.escapeItem = (escapeItem as any) || null;
const registerItem = (item: TouchBarItem<any>) => {
this.items[item.id] = item;
this.items.set(item.id, item);
item.on('change', this.changeListener);
if (item.child instanceof TouchBar) {
item.child.orderedItems.forEach(registerItem);
@@ -387,7 +385,7 @@ class TouchBar extends EventEmitter implements Electron.TouchBar {
const { id } = window;
// Already added to window
if (Object.prototype.hasOwnProperty.call(this.windowListeners, id)) return;
if (this.windowListeners.has(id)) return;
window._touchBar = this;
@@ -402,7 +400,7 @@ class TouchBar extends EventEmitter implements Electron.TouchBar {
this.on('escape-item-change', escapeItemListener);
const interactionListener = (_: any, itemID: string, details: any) => {
let item = this.items[itemID];
let item = this.items.get(itemID);
if (item == null && this.escapeItem != null && this.escapeItem.id === itemID) {
item = this.escapeItem;
}
@@ -418,7 +416,7 @@ class TouchBar extends EventEmitter implements Electron.TouchBar {
window.removeListener('-touch-bar-interaction', interactionListener);
window.removeListener('closed', removeListeners);
window._touchBar = null;
delete this.windowListeners[id];
this.windowListeners.delete(id);
const unregisterItems = (items: TouchBarItem<any>[]) => {
for (const item of items) {
item.removeListener('change', this.changeListener);
@@ -433,14 +431,14 @@ class TouchBar extends EventEmitter implements Electron.TouchBar {
}
};
window.once('closed', removeListeners);
this.windowListeners[id] = removeListeners;
this.windowListeners.set(id, removeListeners);
window._setTouchBarItems(this.orderedItems);
escapeItemListener(this.escapeItem);
}
_removeFromWindow (window: Electron.BrowserWindow) {
const removeListeners = this.windowListeners[window.id];
const removeListeners = this.windowListeners.get(window.id);
if (removeListeners != null) removeListeners();
}

View File

@@ -18,8 +18,8 @@ const webViewManager = process._linkedBinding('electron_browser_web_view_manager
const supportedWebViewEvents = Object.keys(webViewEvents);
const guestInstances: Record<string, GuestInstance> = {};
const embedderElementsMap: Record<string, number> = {};
const guestInstances = new Map<number, GuestInstance>();
const embedderElementsMap = new Map<string, number>();
function sanitizeOptionsForGuest (options: Record<string, any>) {
const ret = { ...options };
@@ -37,14 +37,14 @@ const createGuest = function (embedder: Electron.WebContents, params: Record<str
embedder: embedder
});
const guestInstanceId = guest.id;
guestInstances[guestInstanceId] = {
guestInstances.set(guestInstanceId, {
guest: guest,
embedder: embedder
};
});
// Clear the guest from map when it is destroyed.
guest.once('destroyed', () => {
if (Object.prototype.hasOwnProperty.call(guestInstances, guestInstanceId)) {
if (guestInstances.has(guestInstanceId)) {
detachGuest(embedder, guestInstanceId);
}
});
@@ -107,7 +107,7 @@ const createGuest = function (embedder: Electron.WebContents, params: Record<str
// Notify guest of embedder window visibility when it is ready
// FIXME Remove once https://github.com/electron/electron/issues/6828 is fixed
guest.on('dom-ready', function () {
const guestInstance = guestInstances[guestInstanceId];
const guestInstance = guestInstances.get(guestInstanceId);
if (guestInstance != null && guestInstance.visibilityState != null) {
guest._sendInternal(IPC_MESSAGES.GUEST_INSTANCE_VISIBILITY_CHANGE, guestInstance.visibilityState);
}
@@ -122,20 +122,20 @@ const attachGuest = function (event: Electron.IpcMainInvokeEvent,
const embedder = event.sender;
// Destroy the old guest when attaching.
const key = `${embedder.id}-${elementInstanceId}`;
const oldGuestInstanceId = embedderElementsMap[key];
const oldGuestInstanceId = embedderElementsMap.get(key);
if (oldGuestInstanceId != null) {
// Reattachment to the same guest is just a no-op.
if (oldGuestInstanceId === guestInstanceId) {
return;
}
const oldGuestInstance = guestInstances[oldGuestInstanceId];
const oldGuestInstance = guestInstances.get(oldGuestInstanceId);
if (oldGuestInstance) {
oldGuestInstance.guest.detachFromOuterFrame();
}
}
const guestInstance = guestInstances[guestInstanceId];
const guestInstance = guestInstances.get(guestInstanceId);
// If this isn't a valid guest instance then do nothing.
if (!guestInstance) {
throw new Error(`Invalid guestInstanceId: ${guestInstanceId}`);
@@ -148,7 +148,7 @@ const attachGuest = function (event: Electron.IpcMainInvokeEvent,
// If this guest is already attached to an element then remove it
if (guestInstance.elementInstanceId) {
const oldKey = `${guestInstance.embedder.id}-${guestInstance.elementInstanceId}`;
delete embedderElementsMap[oldKey];
embedderElementsMap.delete(oldKey);
// Remove guest from embedder if moving across web views
if (guest.viewInstanceId !== params.instanceId) {
@@ -210,7 +210,7 @@ const attachGuest = function (event: Electron.IpcMainInvokeEvent,
}
guest.attachParams = params;
embedderElementsMap[key] = guestInstanceId;
embedderElementsMap.set(key, guestInstanceId);
guest.setEmbedder(embedder);
guestInstance.embedder = embedder;
@@ -224,7 +224,7 @@ const attachGuest = function (event: Electron.IpcMainInvokeEvent,
// Remove an guest-embedder relationship.
const detachGuest = function (embedder: Electron.WebContents, guestInstanceId: number) {
const guestInstance = guestInstances[guestInstanceId];
const guestInstance = guestInstances.get(guestInstanceId);
if (!guestInstance) return;
@@ -233,10 +233,10 @@ const detachGuest = function (embedder: Electron.WebContents, guestInstanceId: n
}
webViewManager.removeGuest(embedder, guestInstanceId);
delete guestInstances[guestInstanceId];
guestInstances.delete(guestInstanceId);
const key = `${embedder.id}-${guestInstance.elementInstanceId}`;
delete embedderElementsMap[key];
embedderElementsMap.delete(key);
};
// Once an embedder has had a guest attached we watch it for destruction to
@@ -250,8 +250,7 @@ const watchEmbedder = function (embedder: Electron.WebContents) {
// Forward embedder window visibility change events to guest
const onVisibilityChange = function (visibilityState: VisibilityState) {
for (const guestInstanceId of Object.keys(guestInstances)) {
const guestInstance = guestInstances[guestInstanceId];
for (const guestInstance of guestInstances.values()) {
guestInstance.visibilityState = visibilityState;
if (guestInstance.embedder === embedder) {
guestInstance.guest._sendInternal(IPC_MESSAGES.GUEST_INSTANCE_VISIBILITY_CHANGE, visibilityState);
@@ -264,10 +263,9 @@ const watchEmbedder = function (embedder: Electron.WebContents) {
// Usually the guestInstances is cleared when guest is destroyed, but it
// may happen that the embedder gets manually destroyed earlier than guest,
// and the embedder will be invalid in the usual code path.
for (const guestInstanceId of Object.keys(guestInstances)) {
const guestInstance = guestInstances[guestInstanceId];
for (const [guestInstanceId, guestInstance] of guestInstances) {
if (guestInstance.embedder === embedder) {
detachGuest(embedder, parseInt(guestInstanceId));
detachGuest(embedder, guestInstanceId);
}
}
// Clear the listeners.
@@ -388,6 +386,6 @@ const getGuestForWebContents = function (guestInstanceId: number, contents: Elec
// Returns WebContents from its guest id.
const getGuest = function (guestInstanceId: number) {
const guestInstance = guestInstances[guestInstanceId];
const guestInstance = guestInstances.get(guestInstanceId);
if (guestInstance != null) return guestInstance.guest;
};

View File

@@ -5,6 +5,18 @@ const Module = require('module');
// Clear Node's global search paths.
Module.globalPaths.length = 0;
// We do not want to allow use of the VM module in the renderer process as
// it conflicts with Blink's V8::Context internal logic.
if (process.type === 'renderer') {
const _load = Module._load;
Module._load = function (request: string) {
if (request === 'vm') {
console.warn('The vm module of Node.js is deprecated in the renderer process and will be removed.');
}
return _load.apply(this, arguments);
};
}
// Prevent Node from adding paths outside this app to search paths.
const resourcesPathWithTrailingSlash = process.resourcesPath + path.sep;
const originalNodeModulePaths = Module._nodeModulePaths;

View File

@@ -1,25 +1,25 @@
#!/usr/bin/env node
var electron = require('./')
const electron = require('./');
var proc = require('child_process')
const proc = require('child_process');
var child = proc.spawn(electron, process.argv.slice(2), { stdio: 'inherit', windowsHide: false })
const child = proc.spawn(electron, process.argv.slice(2), { stdio: 'inherit', windowsHide: false });
child.on('close', function (code, signal) {
if (code === null) {
console.error(electron, 'exited with signal', signal)
process.exit(1)
console.error(electron, 'exited with signal', signal);
process.exit(1);
}
process.exit(code)
})
process.exit(code);
});
const handleTerminationSignal = function (signal) {
process.on(signal, function signalHandler () {
if (!child.killed) {
child.kill(signal)
child.kill(signal);
}
})
}
});
};
handleTerminationSignal('SIGINT')
handleTerminationSignal('SIGTERM')
handleTerminationSignal('SIGINT');
handleTerminationSignal('SIGTERM');

View File

@@ -1,18 +1,18 @@
var fs = require('fs')
var path = require('path')
const fs = require('fs');
const path = require('path');
var pathFile = path.join(__dirname, 'path.txt')
const pathFile = path.join(__dirname, 'path.txt');
function getElectronPath () {
if (fs.existsSync(pathFile)) {
var executablePath = fs.readFileSync(pathFile, 'utf-8')
const executablePath = fs.readFileSync(pathFile, 'utf-8');
if (process.env.ELECTRON_OVERRIDE_DIST_PATH) {
return path.join(process.env.ELECTRON_OVERRIDE_DIST_PATH, executablePath)
return path.join(process.env.ELECTRON_OVERRIDE_DIST_PATH, executablePath);
}
return path.join(__dirname, 'dist', executablePath)
return path.join(__dirname, 'dist', executablePath);
} else {
throw new Error('Electron failed to install correctly, please delete node_modules/electron and try installing again')
throw new Error('Electron failed to install correctly, please delete node_modules/electron and try installing again');
}
}
module.exports = getElectronPath()
module.exports = getElectronPath();

View File

@@ -1,21 +1,21 @@
#!/usr/bin/env node
const {version} = require('./package')
const { version } = require('./package');
const fs = require('fs')
const os = require('os')
const path = require('path')
const extract = require('extract-zip')
const { downloadArtifact } = require('@electron/get')
const fs = require('fs');
const os = require('os');
const path = require('path');
const extract = require('extract-zip');
const { downloadArtifact } = require('@electron/get');
if (process.env.ELECTRON_SKIP_BINARY_DOWNLOAD) {
process.exit(0)
process.exit(0);
}
const platformPath = getPlatformPath()
const platformPath = getPlatformPath();
if (isInstalled()) {
process.exit(0)
process.exit(0);
}
// downloads if not cached
@@ -27,57 +27,57 @@ downloadArtifact({
platform: process.env.npm_config_platform || process.platform,
arch: process.env.npm_config_arch || process.arch
}).then(extractFile).catch(err => {
console.error(err.stack)
process.exit(1)
})
console.error(err.stack);
process.exit(1);
});
function isInstalled () {
try {
if (fs.readFileSync(path.join(__dirname, 'dist', 'version'), 'utf-8').replace(/^v/, '') !== version) {
return false
return false;
}
if (fs.readFileSync(path.join(__dirname, 'path.txt'), 'utf-8') !== platformPath) {
return false
return false;
}
} catch (ignored) {
return false
return false;
}
const electronPath = process.env.ELECTRON_OVERRIDE_DIST_PATH || path.join(__dirname, 'dist', platformPath)
return fs.existsSync(electronPath)
const electronPath = process.env.ELECTRON_OVERRIDE_DIST_PATH || path.join(__dirname, 'dist', platformPath);
return fs.existsSync(electronPath);
}
// unzips and makes path.txt point at the correct executable
function extractFile (zipPath) {
return new Promise((resolve, reject) => {
extract(zipPath, { dir: path.join(__dirname, 'dist') }, err => {
if (err) return reject(err)
if (err) return reject(err);
fs.writeFile(path.join(__dirname, 'path.txt'), platformPath, err => {
if (err) return reject(err)
if (err) return reject(err);
resolve()
})
})
})
resolve();
});
});
});
}
function getPlatformPath () {
const platform = process.env.npm_config_platform || os.platform()
const platform = process.env.npm_config_platform || os.platform();
switch (platform) {
case 'mas':
case 'darwin':
return 'Electron.app/Contents/MacOS/Electron'
return 'Electron.app/Contents/MacOS/Electron';
case 'freebsd':
case 'openbsd':
case 'linux':
return 'electron'
return 'electron';
case 'win32':
return 'electron.exe'
return 'electron.exe';
default:
throw new Error('Electron builds are not available on platform: ' + platform)
throw new Error('Electron builds are not available on platform: ' + platform);
}
}

View File

@@ -1,10 +1,10 @@
{
"name": "electron",
"version": "12.0.0-nightly.20201016",
"version": "12.0.0-nightly.20201026",
"repository": "https://github.com/electron/electron",
"description": "Build cross platform desktop apps with JavaScript, HTML, and CSS",
"devDependencies": {
"@electron/docs-parser": "^0.9.1",
"@electron/docs-parser": "^0.10.0",
"@electron/typescript-definitions": "^8.8.0",
"@octokit/rest": "^18.0.3",
"@primer/octicons": "^10.0.0",
@@ -23,8 +23,8 @@
"@types/uuid": "^3.4.6",
"@types/webpack": "^4.41.21",
"@types/webpack-env": "^1.15.2",
"@typescript-eslint/eslint-plugin": "^3.9.1",
"@typescript-eslint/parser": "^3.9.1",
"@typescript-eslint/eslint-plugin": "^4.4.1",
"@typescript-eslint/parser": "^4.4.1",
"asar": "^3.0.3",
"check-for-leaks": "^1.2.1",
"colors": "^1.4.0",
@@ -63,7 +63,8 @@
"ts-node": "6.2.0",
"typescript": "^4.0.2",
"webpack": "^4.43.0",
"webpack-cli": "^3.3.12"
"webpack-cli": "^3.3.12",
"wrapper-webpack-plugin": "^2.1.0"
},
"private": true,
"scripts": {
@@ -91,7 +92,7 @@
"start": "node ./script/start.js",
"test": "node ./script/spec-runner.js",
"tsc": "tsc",
"webpack": "node build/webpack/run-compiler"
"webpack": "webpack"
},
"license": "MIT",
"author": "Electron Community",

View File

@@ -9,10 +9,10 @@ we're running with contextIsolation enabled, we should be falling back
to Blink's logic. This will be upstreamed in some form.
diff --git a/third_party/blink/renderer/bindings/core/v8/v8_initializer.cc b/third_party/blink/renderer/bindings/core/v8/v8_initializer.cc
index 7c2ae147254dad017214d2535203a18719294768..3313d6aff572307777f02801b09fc3d29318050e 100644
index 85ac9d5d95856470707d320d382743673cd1451a..398095d8890cee3f8838170a86ccb48010ff74a0 100644
--- a/third_party/blink/renderer/bindings/core/v8/v8_initializer.cc
+++ b/third_party/blink/renderer/bindings/core/v8/v8_initializer.cc
@@ -442,7 +442,7 @@ CodeGenerationCheckCallbackInMainThread(v8::Local<v8::Context> context,
@@ -438,7 +438,7 @@ CodeGenerationCheckCallbackInMainThread(v8::Local<v8::Context> context,
return {true, std::move(stringified_source)};
}

View File

@@ -81,7 +81,7 @@ index 5575c90cf05ec43bc787711f1d44b8dd58ead99c..a544d836159522751c1262370d8c1562
!command_line->HasSwitch(switches::kUIDisablePartialSwap);
#if defined(OS_APPLE)
diff --git a/components/viz/service/display/gl_renderer.cc b/components/viz/service/display/gl_renderer.cc
index 31fa3d22a28cb673a1eac983acafb7bcd484e6ca..58d52c207f12dd329a0cb8593af5f76ab5ba70f1 100644
index 31fa3d22a28cb673a1eac983acafb7bcd484e6ca..e1bfab6b716fa5d2f552b7af149748b3b0dc0a23 100644
--- a/components/viz/service/display/gl_renderer.cc
+++ b/components/viz/service/display/gl_renderer.cc
@@ -88,6 +88,9 @@
@@ -121,7 +121,7 @@ index 31fa3d22a28cb673a1eac983acafb7bcd484e6ca..58d52c207f12dd329a0cb8593af5f76a
tint_gl_composited_content_,
ShouldApplyRoundedCorner(quad)),
- CurrentRenderPassColorSpace(), CurrentRenderPassColorSpace());
+ PATCH_CS(CurrentRenderPassColorSpace()),
+ PATCH_CS(CurrentRenderPassColorSpace()),
+ PATCH_CS(CurrentRenderPassColorSpace()));
gfx::ColorSpace quad_color_space = gfx::ColorSpace::CreateSRGB();

View File

@@ -7,7 +7,7 @@ This tweaks Chrome's Accessibility support at chrome://accessibility
to make it usable from Electron by removing Profile references.
diff --git a/chrome/browser/accessibility/accessibility_ui.cc b/chrome/browser/accessibility/accessibility_ui.cc
index 42d79b5651e204dc8014489f8feb6b6ad7994d8c..77ca7e88b9e5c2f1dd80d28452588f85a1120169 100644
index 42d79b5651e204dc8014489f8feb6b6ad7994d8c..bed9a4f98f566d368a891a8247f3e528f9db910d 100644
--- a/chrome/browser/accessibility/accessibility_ui.cc
+++ b/chrome/browser/accessibility/accessibility_ui.cc
@@ -19,7 +19,10 @@
@@ -101,7 +101,7 @@ index 42d79b5651e204dc8014489f8feb6b6ad7994d8c..77ca7e88b9e5c2f1dd80d28452588f85
+#if 0
PrefService* pref = Profile::FromWebUI(web_ui())->GetPrefs();
bool internal = pref->GetBoolean(prefs::kShowInternalAccessibilityTree);
+#endif
+#endif
std::string accessibility_contents =
- web_contents->DumpAccessibilityTree(internal, property_filters);
+ web_contents->DumpAccessibilityTree(true, property_filters);

View File

@@ -25,7 +25,7 @@ index f63f7f2674d9562f57dea4f9c9f473aa595a0c5f..78a46dbea7ff31209748ef47d5417253
// Returns true if duplex mode is set.
bool SetDuplexModeInPrintSettings(mojom::DuplexMode mode);
diff --git a/printing/printing_context_mac.mm b/printing/printing_context_mac.mm
index aa950b59390fdae9a5152affb7a7438cb78eb6f4..3ec9ee0ee464960a48d23f5000137cc44027e9b1 100644
index aa950b59390fdae9a5152affb7a7438cb78eb6f4..9b5307bda7b73cb502fe185be2a7c02e23a7722c 100644
--- a/printing/printing_context_mac.mm
+++ b/printing/printing_context_mac.mm
@@ -189,7 +189,8 @@ PMPaper MatchPaper(CFArrayRef paper_list,
@@ -45,7 +45,7 @@ index aa950b59390fdae9a5152affb7a7438cb78eb6f4..3ec9ee0ee464960a48d23f5000137cc4
+bool PrintingContextMac::SetPrintRangeInPrintSettings(const PageRanges& ranges) {
+ // Default is already NSPrintAllPages - we can safely bail.
+ if (ranges.empty())
+ return true;
+ return true;
+
+ auto* print_settings =
+ static_cast<PMPrintSettings>([print_info_.get() PMPrintSettings]);
@@ -100,14 +100,14 @@ index d3c8677f30d72efc49b28f293260c74c7b8d8b4e..f6e66aaa58ab1881d64dcbb320ae8b5a
} else {
// No need to bother, we don't know how many pages are available.
diff --git a/ui/gtk/printing/print_dialog_gtk.cc b/ui/gtk/printing/print_dialog_gtk.cc
index f2ed36e1258f4f3ef1bfce972e215e3d5d7335b6..405839e9f944f70106c1c203652044c3abfade3d 100644
index f2ed36e1258f4f3ef1bfce972e215e3d5d7335b6..5b38bf1369a68546f0aeea8948abba995c65e7f7 100644
--- a/ui/gtk/printing/print_dialog_gtk.cc
+++ b/ui/gtk/printing/print_dialog_gtk.cc
@@ -239,6 +239,24 @@ void PrintDialogGtk::UpdateSettings(
gtk_print_settings_set_n_copies(gtk_settings_, settings->copies());
gtk_print_settings_set_collate(gtk_settings_, settings->collate());
+
+
+ auto print_ranges = settings->ranges();
+ if (!print_ranges.empty()) {
+ // Tell the system that we only intend to print a subset of pages.

View File

@@ -12,14 +12,14 @@ rendering and there is no signal from browser process on this event
to identify it.
diff --git a/content/browser/gpu/gpu_data_manager_impl.cc b/content/browser/gpu/gpu_data_manager_impl.cc
index 694f63ecd2de241fd1a8b7b529bbd4d1bea78337..cc9679eb86f85239f5612d8db8200db5392f5bc5 100644
index 694f63ecd2de241fd1a8b7b529bbd4d1bea78337..705d24cb09a2a8b07ac7acd21b18e2e3483856bf 100644
--- a/content/browser/gpu/gpu_data_manager_impl.cc
+++ b/content/browser/gpu/gpu_data_manager_impl.cc
@@ -229,6 +229,11 @@ void GpuDataManagerImpl::TerminateInfoCollectionGpuProcess() {
base::AutoLock auto_lock(lock_);
private_->TerminateInfoCollectionGpuProcess();
}
+
+
+bool GpuDataManagerImpl::DxdiagDx12VulkanRequested() const {
+ base::AutoLock auto_lock(lock_);
+ return private_->DxdiagDx12VulkanRequested();

View File

@@ -419,7 +419,7 @@ index 894ac47e596c1c96a7e0659be80ed8a5629d0304..eca797a24df79b8502b9698e6ed8830a
} // namespace
diff --git a/content/renderer/theme_helper_mac.mm b/content/renderer/theme_helper_mac.mm
index 1db129740992672a4e8be8100da18b6813f1a4f8..5b1e456020ac859c826dbef2826cacf3bb60108b 100644
index 1db129740992672a4e8be8100da18b6813f1a4f8..dc18d623869e815d4d1ef64ad8bceb6948f5cc9e 100644
--- a/content/renderer/theme_helper_mac.mm
+++ b/content/renderer/theme_helper_mac.mm
@@ -7,11 +7,11 @@
@@ -445,7 +445,7 @@ index 1db129740992672a4e8be8100da18b6813f1a4f8..5b1e456020ac859c826dbef2826cacf3
+#else
+ NSUserDefaults* defaults = [NSUserDefaults standardUserDefaults];
+ NSString *default_key = @"CGFontRenderingGetFontSmoothingDisabled";
+ // Check that key exists since boolForKey defaults to NO when the
+ // Check that key exists since boolForKey defaults to NO when the
+ // key is missing and this key in fact defaults to YES;
+ if ([defaults objectForKey:default_key] == nil)
+ return false;

View File

@@ -102,7 +102,7 @@ index 89c7798d8ddf21eb74e726c142377afa05b59c26..dd75b8e82552a54868ce86caf90ba175
}
diff --git a/chrome/browser/printing/print_view_manager_base.cc b/chrome/browser/printing/print_view_manager_base.cc
index ad70dada204132ce44d6613378072a080771148a..02ecf3e77bee365eef4dc8a985cfe092785b8b8e 100644
index ad70dada204132ce44d6613378072a080771148a..75908fc9978db020d752e7fc7211d1a075c11ffb 100644
--- a/chrome/browser/printing/print_view_manager_base.cc
+++ b/chrome/browser/printing/print_view_manager_base.cc
@@ -28,10 +28,7 @@
@@ -145,7 +145,7 @@ index ad70dada204132ce44d6613378072a080771148a..02ecf3e77bee365eef4dc8a985cfe092
: PrintManager(web_contents),
queue_(g_browser_process->print_job_manager()->queue()) {
DCHECK(queue_);
+#if 0
+#if 0 // Printing is always enabled.
Profile* profile =
Profile::FromBrowserContext(web_contents->GetBrowserContext());
printing_enabled_.Init(
@@ -197,7 +197,22 @@ index ad70dada204132ce44d6613378072a080771148a..02ecf3e77bee365eef4dc8a985cfe092
}
void PrintViewManagerBase::NavigationStopped() {
@@ -441,7 +454,7 @@ void PrintViewManagerBase::PrintingFailed(int32_t cookie) {
@@ -421,12 +434,13 @@ void PrintViewManagerBase::OnDidPrintDocument(
void PrintViewManagerBase::GetDefaultPrintSettings(
GetDefaultPrintSettingsCallback callback) {
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
+#if 0 // Printing is always enabled.
if (!printing_enabled_.GetValue()) {
auto params = mojom::PrintParams::New();
GetDefaultPrintSettingsReply(std::move(callback), std::move(params));
return;
}
-
+#endif
content::RenderFrameHost* render_frame_host =
print_manager_host_receivers_.GetCurrentTargetFrame();
@@ -441,7 +455,7 @@ void PrintViewManagerBase::PrintingFailed(int32_t cookie) {
PrintManager::PrintingFailed(cookie);
#if BUILDFLAG(ENABLE_PRINT_PREVIEW)
@@ -206,7 +221,7 @@ index ad70dada204132ce44d6613378072a080771148a..02ecf3e77bee365eef4dc8a985cfe092
#endif
ReleasePrinterQuery();
@@ -460,6 +473,11 @@ void PrintViewManagerBase::OnScriptedPrint(
@@ -460,6 +474,11 @@ void PrintViewManagerBase::OnScriptedPrint(
}
void PrintViewManagerBase::ShowInvalidPrinterSettingsError() {
@@ -218,7 +233,7 @@ index ad70dada204132ce44d6613378072a080771148a..02ecf3e77bee365eef4dc8a985cfe092
base::ThreadTaskRunnerHandle::Get()->PostTask(
FROM_HERE, base::BindOnce(&ShowWarningMessageBox,
l10n_util::GetStringUTF16(
@@ -529,9 +547,13 @@ void PrintViewManagerBase::OnNotifyPrintJobEvent(
@@ -529,9 +548,13 @@ void PrintViewManagerBase::OnNotifyPrintJobEvent(
content::NotificationService::NoDetails());
break;
}
@@ -234,7 +249,7 @@ index ad70dada204132ce44d6613378072a080771148a..02ecf3e77bee365eef4dc8a985cfe092
NOTREACHED();
break;
}
@@ -627,8 +649,10 @@ bool PrintViewManagerBase::CreateNewPrintJob(
@@ -627,8 +650,10 @@ bool PrintViewManagerBase::CreateNewPrintJob(
DCHECK(!quit_inner_loop_);
DCHECK(query);
@@ -247,7 +262,7 @@ index ad70dada204132ce44d6613378072a080771148a..02ecf3e77bee365eef4dc8a985cfe092
// We can't print if there is no renderer.
if (!web_contents()->GetRenderViewHost() ||
@@ -649,8 +673,6 @@ bool PrintViewManagerBase::CreateNewPrintJob(
@@ -649,8 +674,6 @@ bool PrintViewManagerBase::CreateNewPrintJob(
print_job_->SetSource(source, /*source_id=*/"");
#endif
@@ -256,7 +271,7 @@ index ad70dada204132ce44d6613378072a080771148a..02ecf3e77bee365eef4dc8a985cfe092
printing_succeeded_ = false;
return true;
}
@@ -699,14 +721,22 @@ void PrintViewManagerBase::ReleasePrintJob() {
@@ -699,14 +722,22 @@ void PrintViewManagerBase::ReleasePrintJob() {
content::RenderFrameHost* rfh = printing_rfh_;
printing_rfh_ = nullptr;
@@ -281,7 +296,7 @@ index ad70dada204132ce44d6613378072a080771148a..02ecf3e77bee365eef4dc8a985cfe092
// Don't close the worker thread.
print_job_ = nullptr;
}
@@ -742,7 +772,7 @@ bool PrintViewManagerBase::RunInnerMessageLoop() {
@@ -742,7 +773,7 @@ bool PrintViewManagerBase::RunInnerMessageLoop() {
}
bool PrintViewManagerBase::OpportunisticallyCreatePrintJob(int cookie) {

View File

@@ -25,8 +25,6 @@ fix_use_crypto_impls_for_compat.patch
fix_comment_out_incompatible_crypto_modules.patch
update_tests_after_increasing_typed_array_size.patch
feat_add_implementation_of_v8_platform_postjob.patch
crypto_update_certdata_to_nss_3_56.patch
fix_-wincompatible-pointer-types-discards-qualifiers_error.patch
fix_add_v8_enable_reverse_jsargs_defines_in_common_gypi.patch
fix_allow_preventing_initializeinspector_in_env.patch
chore_expose_v8_initialization_isolate_callbacks.patch

View File

@@ -846,10 +846,10 @@ index 0000000000000000000000000000000000000000..2c9d2826c85bdd033f1df1d6188df636
+}
diff --git a/filenames.json b/filenames.json
new file mode 100644
index 0000000000000000000000000000000000000000..fbf2c13688d52b5ba320eadac42d472f09441e79
index 0000000000000000000000000000000000000000..9480edd9b00591e7aad7f764a409b86094e4cd5d
--- /dev/null
+++ b/filenames.json
@@ -0,0 +1,527 @@
@@ -0,0 +1,530 @@
+// This file is automatically generated by generate_gn_filenames_json.py
+// DO NOT EDIT
+{
@@ -871,6 +871,7 @@ index 0000000000000000000000000000000000000000..fbf2c13688d52b5ba320eadac42d472f
+ "files": [
+ "//v8/include/cppgc/allocation.h",
+ "//v8/include/cppgc/common.h",
+ "//v8/include/cppgc/cross-thread-persistent.h",
+ "//v8/include/cppgc/custom-space.h",
+ "//v8/include/cppgc/default-platform.h",
+ "//v8/include/cppgc/garbage-collected.h",
@@ -878,6 +879,7 @@ index 0000000000000000000000000000000000000000..fbf2c13688d52b5ba320eadac42d472f
+ "//v8/include/cppgc/liveness-broker.h",
+ "//v8/include/cppgc/macros.h",
+ "//v8/include/cppgc/member.h",
+ "//v8/include/cppgc/name-provider.h",
+ "//v8/include/cppgc/persistent.h",
+ "//v8/include/cppgc/platform.h",
+ "//v8/include/cppgc/prefinalizer.h",
@@ -897,6 +899,7 @@ index 0000000000000000000000000000000000000000..fbf2c13688d52b5ba320eadac42d472f
+ "//v8/include/cppgc/internal/finalizer-trait.h",
+ "//v8/include/cppgc/internal/gc-info.h",
+ "//v8/include/cppgc/internal/logging.h",
+ "//v8/include/cppgc/internal/name-trait.h",
+ "//v8/include/cppgc/internal/persistent-node.h",
+ "//v8/include/cppgc/internal/pointer-policies.h",
+ "//v8/include/cppgc/internal/prefinalizer-handler.h",
@@ -1153,7 +1156,6 @@ index 0000000000000000000000000000000000000000..fbf2c13688d52b5ba320eadac42d472f
+ "lib/internal/worker/js_transferable.js",
+ "lib/internal/watchdog.js",
+ "lib/internal/streams/lazy_transform.js",
+ "lib/internal/streams/async_iterator.js",
+ "lib/internal/streams/buffer_list.js",
+ "lib/internal/streams/duplexpair.js",
+ "lib/internal/streams/from.js",
@@ -1183,7 +1185,8 @@ index 0000000000000000000000000000000000000000..fbf2c13688d52b5ba320eadac42d472f
+ "deps/acorn-plugins/acorn-private-class-elements/index.js",
+ "deps/acorn-plugins/acorn-private-methods/index.js",
+ "deps/acorn-plugins/acorn-static-class-features/index.js",
+ "deps/cjs-module-lexer/lexer.js"
+ "deps/cjs-module-lexer/lexer.js",
+ "deps/cjs-module-lexer/dist/lexer.js"
+ ],
+ "node_sources": [
+ "src/api/async_resource.cc",
@@ -1583,7 +1586,7 @@ index 0000000000000000000000000000000000000000..f3c5c798c0aefcb8cf9b1570a7b4817c
+ args = rebase_path(inputs + outputs, root_build_dir)
+}
diff --git a/src/node_version.h b/src/node_version.h
index 19fa04ebe755ecd120ef0842a02688e121c4c963..fdbde0397dd4bfaa117ca8e9223510b885511ce6 100644
index 7f2f31389637d07fcf0f721daf18b409ade039b4..ffc4ed7085f2b97ce2017245947085e26e7633ac 100644
--- a/src/node_version.h
+++ b/src/node_version.h
@@ -89,7 +89,10 @@

View File

@@ -10,7 +10,7 @@ THe fix for this should land in node-gyp as discussed in above issue,
landing this as temporary patch.
diff --git a/common.gypi b/common.gypi
index 6f309e5cdbf336d27ec88ee5be431a8aebf85d7f..c8618597d8d71b58a46d4aa405536357055edcd3 100644
index 81568d5afabd6d80b4df445124ccd7108801769d..463adbfdd8fb3af5d19ed30461eae46fd647de1a 100644
--- a/common.gypi
+++ b/common.gypi
@@ -19,7 +19,7 @@

View File

@@ -1,89 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Shelley Vohr <shelley.vohr@gmail.com>
Date: Mon, 5 Oct 2020 16:05:45 -0700
Subject: chore: expose v8 initialization isolate callbacks
Exposes v8 initializer callbacks to Electron so that we can call them
directly. We expand upon and adapt their behavior, so allows us to
ensure that we stay in sync with Node.js default behavior.
This will be upstreamed.
diff --git a/src/api/environment.cc b/src/api/environment.cc
index 274d0481529ace763c997910ce40e2c730a20146..194094e1d5bdda4589c7cc4d99270af3cb3ef5a3 100644
--- a/src/api/environment.cc
+++ b/src/api/environment.cc
@@ -30,14 +30,16 @@ using v8::PropertyDescriptor;
using v8::String;
using v8::Value;
-static bool AllowWasmCodeGenerationCallback(Local<Context> context,
+// static
+bool Environment::AllowWasmCodeGenerationCallback(Local<Context> context,
Local<String>) {
Local<Value> wasm_code_gen =
context->GetEmbedderData(ContextEmbedderIndex::kAllowWasmCodeGeneration);
return wasm_code_gen->IsUndefined() || wasm_code_gen->IsTrue();
}
-static bool ShouldAbortOnUncaughtException(Isolate* isolate) {
+// static
+bool Environment::ShouldAbortOnUncaughtException(Isolate* isolate) {
DebugSealHandleScope scope(isolate);
Environment* env = Environment::GetCurrent(isolate);
return env != nullptr &&
@@ -47,7 +49,8 @@ static bool ShouldAbortOnUncaughtException(Isolate* isolate) {
!env->inside_should_not_abort_on_uncaught_scope();
}
-static MaybeLocal<Value> PrepareStackTraceCallback(Local<Context> context,
+// static
+MaybeLocal<Value> Environment::PrepareStackTraceCallback(Local<Context> context,
Local<Value> exception,
Local<Array> trace) {
Environment* env = Environment::GetCurrent(context);
@@ -221,7 +224,7 @@ void SetIsolateErrorHandlers(v8::Isolate* isolate, const IsolateSettings& s) {
auto* abort_callback = s.should_abort_on_uncaught_exception_callback ?
s.should_abort_on_uncaught_exception_callback :
- ShouldAbortOnUncaughtException;
+ Environment::ShouldAbortOnUncaughtException;
isolate->SetAbortOnUncaughtExceptionCallback(abort_callback);
auto* fatal_error_cb = s.fatal_error_callback ?
@@ -229,7 +232,7 @@ void SetIsolateErrorHandlers(v8::Isolate* isolate, const IsolateSettings& s) {
isolate->SetFatalErrorHandler(fatal_error_cb);
auto* prepare_stack_trace_cb = s.prepare_stack_trace_callback ?
- s.prepare_stack_trace_callback : PrepareStackTraceCallback;
+ s.prepare_stack_trace_callback : Environment::PrepareStackTraceCallback;
isolate->SetPrepareStackTraceCallback(prepare_stack_trace_cb);
}
@@ -237,7 +240,7 @@ void SetIsolateMiscHandlers(v8::Isolate* isolate, const IsolateSettings& s) {
isolate->SetMicrotasksPolicy(s.policy);
auto* allow_wasm_codegen_cb = s.allow_wasm_code_generation_callback ?
- s.allow_wasm_code_generation_callback : AllowWasmCodeGenerationCallback;
+ s.allow_wasm_code_generation_callback : Environment::AllowWasmCodeGenerationCallback;
isolate->SetAllowWasmCodeGenerationCallback(allow_wasm_codegen_cb);
if ((s.flags & SHOULD_NOT_SET_PROMISE_REJECTION_CALLBACK) == 0) {
diff --git a/src/env.h b/src/env.h
index 4fe2eb3b7699efcab87c377743a955effbbfd9de..2bb196d199bd9b6c27d9de8ca7e5a9bffad0c788 100644
--- a/src/env.h
+++ b/src/env.h
@@ -904,6 +904,13 @@ class Environment : public MemoryRetainer {
void Exit(int code);
void ExitEnv();
+ static bool AllowWasmCodeGenerationCallback(v8::Local<v8::Context> context,
+ v8::Local<v8::String>);
+ static bool ShouldAbortOnUncaughtException(v8::Isolate* isolate);
+ static v8::MaybeLocal<v8::Value> PrepareStackTraceCallback(v8::Local<v8::Context> context,
+ v8::Local<v8::Value> exception,
+ v8::Local<v8::Array> trace);
+
// Register clean-up cb to be called on environment destruction.
inline void RegisterHandleCleanup(uv_handle_t* handle,
HandleCleanupCb cb,

View File

@@ -8,10 +8,10 @@ once we stop warning and begin to unilaterally prevent non-context aware modules
from being loaded.
diff --git a/lib/internal/bootstrap/pre_execution.js b/lib/internal/bootstrap/pre_execution.js
index f947c6bf27e80c534a8f72265d0139a8b5b3f13a..d7e56d9c3fe5a56897989915984cb823d27b9c52 100644
index 1b781fb8193002e111d8904e44ca66dbec9daaac..3f80a6e4c03a51d40c25717baab5c690c53abccd 100644
--- a/lib/internal/bootstrap/pre_execution.js
+++ b/lib/internal/bootstrap/pre_execution.js
@@ -92,10 +92,12 @@ function patchProcessObject(expandArgv1) {
@@ -93,10 +93,12 @@ function patchProcessObject(expandArgv1) {
if (expandArgv1 && process.argv[1] && !process.argv[1].startsWith('-')) {
// Expand process.argv[1] into a full path.

File diff suppressed because it is too large Load Diff

View File

@@ -8,7 +8,7 @@ node modules will have different (wrong) ideas about how v8 structs are laid
out in memory on 64-bit machines, and will summarily fail to work.
diff --git a/common.gypi b/common.gypi
index c8618597d8d71b58a46d4aa405536357055edcd3..5e209300b5ce85c2a6e15480465623f911053960 100644
index 463adbfdd8fb3af5d19ed30461eae46fd647de1a..4d63ac7981edca3f99c05ce08af8ea41628b0387 100644
--- a/common.gypi
+++ b/common.gypi
@@ -64,7 +64,7 @@

View File

@@ -65,7 +65,7 @@ index 905afd8c235b7b1a7b45823db486384935a2a52b..102847cd32d03addeb40c9539eafc92b
NativeModuleEnv::InitializeCodeCache();
diff --git a/src/node.h b/src/node.h
index 33e11327e487bca9d0d7b5cd5a1c036c7009a359..7340d1a6f0cf2f912aaee15d66ed137fe2870bab 100644
index 38e0ef50f9b283b1d7ca8f54412d99b8cd38e524..34a16feaed229a59181e1b2e48b0e111d5b0b2a6 100644
--- a/src/node.h
+++ b/src/node.h
@@ -220,6 +220,8 @@ namespace node {

View File

@@ -6,10 +6,10 @@ Subject: feat: initialize asar support
This patch initializes asar support in Node.js.
diff --git a/lib/internal/bootstrap/pre_execution.js b/lib/internal/bootstrap/pre_execution.js
index dfbefa955cab8adcafc5f46151ac83ed893645e0..f947c6bf27e80c534a8f72265d0139a8b5b3f13a 100644
index 9689e2a9edf69530546d5238155f6ea28dd70daf..1b781fb8193002e111d8904e44ca66dbec9daaac 100644
--- a/lib/internal/bootstrap/pre_execution.js
+++ b/lib/internal/bootstrap/pre_execution.js
@@ -73,6 +73,7 @@ function prepareMainThreadExecution(expandArgv1 = false) {
@@ -74,6 +74,7 @@ function prepareMainThreadExecution(expandArgv1 = false) {
assert(!CJSLoader.hasLoadedAnyUserCJSModule);
loadPreloadModules();
initializeFrozenIntrinsics();
@@ -17,7 +17,7 @@ index dfbefa955cab8adcafc5f46151ac83ed893645e0..f947c6bf27e80c534a8f72265d0139a8
}
function patchProcessObject(expandArgv1) {
@@ -447,6 +448,10 @@ function loadPreloadModules() {
@@ -448,6 +449,10 @@ function loadPreloadModules() {
}
}

View File

@@ -8,7 +8,7 @@ common.gypi is a file that's included in the node header bundle, despite
the fact that we do not build node with gyp.
diff --git a/common.gypi b/common.gypi
index 33b1325eb513eadfb4b5aba77e52bd63aa1c9980..6f309e5cdbf336d27ec88ee5be431a8aebf85d7f 100644
index 4745bb5ac77639a97b30a9730d0ab990fdcca05e..81568d5afabd6d80b4df445124ccd7108801769d 100644
--- a/common.gypi
+++ b/common.gypi
@@ -81,6 +81,22 @@

View File

@@ -6,7 +6,7 @@ Subject: fix: add v8_enable_reverse_jsargs defines in common.gypi
This can be removed once node upgrades V8 and inevitably has to do this exact same thing. Also hi node people if you are looking at this.
diff --git a/common.gypi b/common.gypi
index 5e209300b5ce85c2a6e15480465623f911053960..27892535631a3e6431bdb3bdea15d0c4ee6e2b59 100644
index 4d63ac7981edca3f99c05ce08af8ea41628b0387..42d353c7495ff29a58a942ad72227ada8be662a9 100644
--- a/common.gypi
+++ b/common.gypi
@@ -65,6 +65,7 @@

View File

@@ -11,7 +11,7 @@ initialize it in the browser process. This adds a new
EnvironmentFlags option which allows preventing that invocation.
diff --git a/src/api/environment.cc b/src/api/environment.cc
index 5110c9f754f7653261f7de6d5f0c35e541880a4d..274d0481529ace763c997910ce40e2c730a20146 100644
index 53b07052e43a09f29f863ee1b2287bdebe7b7a7f..c08fe4b32d4155badb572f15529f903c0ec63146 100644
--- a/src/api/environment.cc
+++ b/src/api/environment.cc
@@ -358,12 +358,14 @@ Environment* CreateEnvironment(
@@ -63,7 +63,7 @@ index 38d17f4e18aa38fde2c2f59a9816c8fb0f65fd51..4fe2eb3b7699efcab87c377743a955ef
inline worker::Worker* worker_context() const;
Environment* worker_parent_env() const;
diff --git a/src/node.h b/src/node.h
index b9493d1f3d5b4f192609f1e7529715ec30ab46e2..019620ad0c6a0ca80e6cbcfc5a8322f4e1220bb1 100644
index a649f52403659fd18898e1e813f97e32f33784e7..b646fdda58ebcbf2dd92ee4fc9cb0d9c039174d1 100644
--- a/src/node.h
+++ b/src/node.h
@@ -426,7 +426,11 @@ enum Flags : uint64_t {

View File

@@ -6,10 +6,10 @@ Subject: fix: expose InternalCallbackScope
This commit exposes InternalCallbackScope in order to allow us access to its internal flags.
diff --git a/src/node_internals.h b/src/node_internals.h
index c8952e59a2b071c94eaba41393df5b2aa238318e..ab664208076ea776fcb2223dbc228cacd3eb7e58 100644
index aa7180e18544cab4004a0ef87ba230bd2e732d28..9a5b2165d5648045ea18d66b0c15d29b4ea1cced 100644
--- a/src/node_internals.h
+++ b/src/node_internals.h
@@ -204,7 +204,7 @@ v8::MaybeLocal<v8::Value> InternalMakeCallback(
@@ -200,7 +200,7 @@ v8::MaybeLocal<v8::Value> InternalMakeCallback(
v8::Local<v8::Value> argv[],
async_context asyncContext);

View File

@@ -5,7 +5,7 @@ Subject: fix: expose tracing::Agent and use tracing::TracingController instead
of v8::TracingController
diff --git a/src/api/environment.cc b/src/api/environment.cc
index 9a2661ce8b6146a73b910444a49e01e20c8d96e5..5110c9f754f7653261f7de6d5f0c35e541880a4d 100644
index 2c4acbc4fa0eca3b7c6d03b997445633646446e7..53b07052e43a09f29f863ee1b2287bdebe7b7a7f 100644
--- a/src/api/environment.cc
+++ b/src/api/environment.cc
@@ -472,6 +472,10 @@ MultiIsolatePlatform* GetMultiIsolatePlatform(IsolateData* env) {
@@ -20,7 +20,7 @@ index 9a2661ce8b6146a73b910444a49e01e20c8d96e5..5110c9f754f7653261f7de6d5f0c35e5
int thread_pool_size,
node::tracing::TracingController* tracing_controller) {
diff --git a/src/node.h b/src/node.h
index 7340d1a6f0cf2f912aaee15d66ed137fe2870bab..b9493d1f3d5b4f192609f1e7529715ec30ab46e2 100644
index 34a16feaed229a59181e1b2e48b0e111d5b0b2a6..a649f52403659fd18898e1e813f97e32f33784e7 100644
--- a/src/node.h
+++ b/src/node.h
@@ -125,6 +125,7 @@ namespace node {
@@ -31,7 +31,7 @@ index 7340d1a6f0cf2f912aaee15d66ed137fe2870bab..b9493d1f3d5b4f192609f1e7529715ec
class TracingController;
}
@@ -512,6 +513,8 @@ NODE_DEPRECATED("Use GetMultiIsolatePlatform(env) instead",
@@ -522,6 +523,8 @@ NODE_DEPRECATED("Use GetMultiIsolatePlatform(env) instead",
NODE_EXTERN MultiIsolatePlatform* GetMultiIsolatePlatform(Environment* env);
NODE_EXTERN MultiIsolatePlatform* GetMultiIsolatePlatform(IsolateData* env);

View File

@@ -7,10 +7,10 @@ This broke the build at some point. Does it still? We should probably remove
this patch and find out!
diff --git a/src/node_internals.h b/src/node_internals.h
index ab664208076ea776fcb2223dbc228cacd3eb7e58..4a1c3392cf53490bcb883e826bf731a4a674ef61 100644
index 9a5b2165d5648045ea18d66b0c15d29b4ea1cced..6aff1a4ee7f708437dbf581b9eacc21e5bdd1c43 100644
--- a/src/node_internals.h
+++ b/src/node_internals.h
@@ -372,10 +372,11 @@ class TraceEventScope {
@@ -368,10 +368,11 @@ class TraceEventScope {
TraceEventScope(const char* category,
const char* name,
void* id) : category_(category), name_(name), id_(id) {

View File

@@ -48,14 +48,20 @@ def getBrokenLinks(filepath):
finally:
f.close()
regexLink = re.compile('\[(.*?)\]\((?P<links>(.*?))\)')
linkRegexLink = re.compile('\[(.*?)\]\((?P<link>(.*?))\)')
referenceLinkRegex = re.compile('^\s{0,3}\[.*?\]:\s*(?P<link>[^<\s]+|<[^<>\r\n]+>)')
links = []
for line in lines:
matchLinks = regexLink.search(line)
matchLinks = linkRegexLink.search(line)
matchReferenceLinks = referenceLinkRegex.search(line)
if matchLinks:
relativeLink = matchLinks.group('links')
relativeLink = matchLinks.group('link')
if not str(relativeLink).startswith('http'):
links.append(relativeLink)
if matchReferenceLinks:
referenceLink = matchReferenceLinks.group('link').strip('<>')
if not str(referenceLink).startswith('http'):
links.append(referenceLink)
for link in links:
sections = link.split('#')

View File

@@ -46,9 +46,12 @@ const main = async () => {
const webpackTargetsWithDeps = await Promise.all(webpackTargets.map(async webpackTarget => {
const tmpDir = await fs.mkdtemp(path.resolve(os.tmpdir(), 'electron-filenames-'));
const child = cp.spawn('node', [
'build/webpack/get-outputs.js',
`./${webpackTarget.config}`,
path.resolve(tmpDir, `${webpackTarget.name}.measure.js`)
'./node_modules/webpack-cli/bin/cli.js',
'--config', `./build/webpack/${webpackTarget.config}`,
'--display', 'errors-only',
`--output-path=${tmpDir}`,
`--output-filename=${webpackTarget.name}.measure.js`,
'--env.PRINT_WEBPACK_GRAPH'
], {
cwd: path.resolve(__dirname, '..')
});

View File

@@ -12,7 +12,8 @@ def read_patch(patch_dir, patch_filename):
patch_path = os.path.join(patch_dir, patch_filename)
with codecs.open(patch_path, encoding='utf-8') as f:
for l in f.readlines():
if not added_filename_line and (l.startswith('diff -') or l.startswith('---')):
line_has_correct_start = l.startswith('diff -') or l.startswith('---')
if not added_filename_line and line_has_correct_start:
ret.append('Patch-Filename: {}\n'.format(patch_filename))
added_filename_line = True
ret.append(l)

View File

@@ -23,6 +23,8 @@ const IGNORELIST = new Set([
['spec', 'ts-smoke', 'runner.js']
].map(tokens => path.join(SOURCE_ROOT, ...tokens)));
const IS_WINDOWS = process.platform === 'win32';
function spawnAndCheckExitCode (cmd, args, opts) {
opts = Object.assign({ stdio: 'inherit' }, opts);
const status = childProcess.spawnSync(cmd, args, opts).status;
@@ -30,7 +32,7 @@ function spawnAndCheckExitCode (cmd, args, opts) {
}
function cpplint (args) {
const result = childProcess.spawnSync('cpplint.py', args, { encoding: 'utf8' });
const result = childProcess.spawnSync(IS_WINDOWS ? 'cpplint.bat' : 'cpplint.py', args, { encoding: 'utf8', shell: true });
// cpplint.py writes EVERYTHING to stderr, including status messages
if (result.stderr) {
for (const line of result.stderr.split(/[\r\n]+/)) {
@@ -39,8 +41,9 @@ function cpplint (args) {
}
}
}
if (result.status) {
process.exit(result.status);
if (result.status !== 0) {
if (result.error) console.error(result.error);
process.exit(result.status || 1);
}
}
@@ -90,14 +93,44 @@ const LINTERS = [{
}
}, {
key: 'javascript',
roots: ['lib', 'spec', 'spec-main', 'script', 'default_app', 'build'],
roots: ['build', 'default_app', 'lib', 'npm', 'script', 'spec', 'spec-main'],
ignoreRoots: ['spec/node_modules', 'spec-main/node_modules'],
test: filename => filename.endsWith('.js') || filename.endsWith('.ts'),
run: (opts, filenames) => {
const cmd = path.join(SOURCE_ROOT, 'node_modules', '.bin', 'eslint');
const args = ['--cache', '--ext', '.js,.ts', ...filenames];
const args = ['--cache', '--ext', '.js,.ts'];
if (opts.fix) args.unshift('--fix');
spawnAndCheckExitCode(cmd, args, { cwd: SOURCE_ROOT });
// Windows has a max command line length of 2047 characters, so we can't provide
// all of the filenames without going over that. To work around it, run eslint
// multiple times and chunk the filenames so that each run is under that limit.
// Use a much higher limit on other platforms which will effectively be a no-op.
const MAX_FILENAME_ARGS_LENGTH = IS_WINDOWS ? 1900 : 100 * 1024;
const cmdOpts = { stdio: 'inherit', shell: IS_WINDOWS, cwd: SOURCE_ROOT };
if (IS_WINDOWS) {
// When running with shell spaces in filenames are problematic
filenames = filenames.map(filename => `"${filename}"`);
}
const chunkedFilenames = filenames.reduce((chunkedFilenames, filename) => {
const currentChunk = chunkedFilenames[chunkedFilenames.length - 1];
const currentChunkLength = currentChunk.reduce((totalLength, _filename) => totalLength + _filename.length, 0);
if (currentChunkLength + filename.length > MAX_FILENAME_ARGS_LENGTH) {
chunkedFilenames.push([filename]);
} else {
currentChunk.push(filename);
}
return chunkedFilenames;
}, [[]]);
const allOk = chunkedFilenames.map(filenames => {
const result = childProcess.spawnSync(cmd, [...args, ...filenames], cmdOpts);
if (result.error) {
console.error(result.error);
process.exit(result.status || 1);
}
return result.status === 0;
}).every(x => x);
if (!allOk) {
process.exit(1);
}
}
}, {
key: 'gn',
@@ -183,6 +216,11 @@ const LINTERS = [{
console.warn(`Patch file '${f}' has no description. Every patch must contain a justification for why the patch exists and the plan for its removal.`);
ok = false;
}
const trailingWhitespace = patchText.split('\n').filter(line => line.startsWith('+')).some(line => /\s+$/.test(line));
if (trailingWhitespace) {
console.warn(`Patch file '${f}' has trailing whitespace on some lines.`);
ok = false;
}
});
if (!ok) {
process.exit(1);

View File

@@ -0,0 +1,185 @@
#!/usr/bin/env python
from __future__ import print_function
import argparse
import hashlib
import json
import os
import posixpath
import sys
import traceback
from lib.patches import patch_from_dir
def patched_file_paths(patches_config):
for patch_dir, repo in patches_config.items():
for line in patch_from_dir(patch_dir).split("\n"):
if line.startswith("+++"):
yield posixpath.join(repo, line[6:])
def generate_cache(patches_config):
mtime_cache = {}
for file_path in patched_file_paths(patches_config):
if file_path in mtime_cache:
# File may be patched multiple times, we don't need to
# rehash it since we are looking at the final result
continue
if not os.path.exists(file_path):
print("Skipping non-existent file:", file_path)
continue
with open(file_path, "rb") as f:
mtime_cache[file_path] = {
"sha256": hashlib.sha256(f.read()).hexdigest(),
"atime": os.path.getatime(file_path),
"mtime": os.path.getmtime(file_path),
}
return mtime_cache
def apply_mtimes(mtime_cache):
updates = []
for file_path, metadata in mtime_cache.items():
if not os.path.exists(file_path):
print("Skipping non-existent file:", file_path)
continue
with open(file_path, "rb") as f:
if hashlib.sha256(f.read()).hexdigest() == metadata["sha256"]:
updates.append(
[file_path, metadata["atime"], metadata["mtime"]]
)
# We can't atomically set the times for all files at once, but by waiting
# to update until we've checked all the files we at least have less chance
# of only updating some files due to an error on one of the files
for [file_path, atime, mtime] in updates:
os.utime(file_path, (atime, mtime))
def set_mtimes(patches_config, mtime):
mtime_cache = {}
for file_path in patched_file_paths(patches_config):
if file_path in mtime_cache:
continue
if not os.path.exists(file_path):
print("Skipping non-existent file:", file_path)
continue
mtime_cache[file_path] = mtime
for file_path in mtime_cache:
os.utime(file_path, (mtime_cache[file_path], mtime_cache[file_path]))
def main():
parser = argparse.ArgumentParser(
description="Make mtime cache for patched files"
)
subparsers = parser.add_subparsers(
dest="operation", help="sub-command help"
)
apply_subparser = subparsers.add_parser(
"apply", help="apply the mtimes from the cache"
)
apply_subparser.add_argument(
"--cache-file", required=True, help="mtime cache file"
)
apply_subparser.add_argument(
"--preserve-cache",
action="store_true",
help="don't delete cache after applying",
)
generate_subparser = subparsers.add_parser(
"generate", help="generate the mtime cache"
)
generate_subparser.add_argument(
"--cache-file",
type=argparse.FileType("w"),
required=True,
help="mtime cache file",
)
set_subparser = subparsers.add_parser(
"set", help="set all mtimes to a specific date"
)
set_subparser.add_argument(
"--mtime",
type=int,
required=True,
help="mtime to use for all patched files",
)
for subparser in [generate_subparser, set_subparser]:
subparser.add_argument(
"--patches-config",
type=argparse.FileType("r"),
required=True,
help="patches' config in the JSON format",
)
args = parser.parse_args()
if args.operation == "generate":
try:
mtime_cache = generate_cache(json.load(args.patches_config))
json.dump(mtime_cache, args.cache_file, indent=2)
except Exception:
print(
"ERROR: failed to generate mtime cache for patches",
file=sys.stderr,
)
traceback.print_exc(file=sys.stderr)
return 0
elif args.operation == "apply":
if not os.path.exists(args.cache_file):
print("ERROR: --cache-file does not exist", file=sys.stderr)
return 0 # Cache file may not exist, fail more gracefully
try:
with open(args.cache_file, mode="r") as f:
apply_mtimes(json.load(f))
if not args.preserve_cache:
os.remove(args.cache_file)
except Exception:
print(
"ERROR: failed to apply mtime cache for patches",
file=sys.stderr,
)
traceback.print_exc(file=sys.stderr)
return 0
elif args.operation == "set":
# Python 2/3 compatibility
try:
user_input = raw_input
except NameError:
user_input = input
answer = user_input(
"WARNING: Manually setting mtimes could mess up your build. "
"If you're sure, type yes: "
)
if answer.lower() != "yes":
print("Aborting")
return 0
set_mtimes(json.load(args.patches_config), args.mtime)
return 0
if __name__ == "__main__":
sys.exit(main())

View File

@@ -381,6 +381,7 @@ async function getBranchNameOfRef (ref, dir) {
return (await runGit(dir, ['branch', '--all', '--contains', ref, '--sort', 'version:refname']))
.split(/\r?\n/) // split into lines
.shift() // we sorted by refname and want the first result
.match(/(?:\s?\*\s){0,1}(.*)/)[1] // if present, remove leading '* ' in case we're currently in that branch
.match(/(?:.*\/)?(.*)/)[1] // 'remote/origins/10-x-y' -> '10-x-y'
.trim();
}
@@ -398,7 +399,7 @@ const getNotes = async (fromRef, toRef, newVersion) => {
const pool = new Pool();
const toBranch = await getBranchNameOfRef(toRef, ELECTRON_DIR);
console.log(`Generating release notes between ${fromRef} and ${toRef} for version ${newVersion} in branch ${toBranch}`);
console.log(`Generating release notes between '${fromRef}' and '${toRef}' for version '${newVersion}' in branch '${toBranch}'`);
// get the electron/electron commits
const electron = { owner: 'electron', repo: 'electron', dir: ELECTRON_DIR };

View File

@@ -46,7 +46,9 @@ def main():
for symbol_file in files:
print("Generating Sentry src bundle for: " + symbol_file)
subprocess.check_output([NPX_CMD, '@sentry/cli@1.51.1', 'difutil', 'bundle-sources', symbol_file])
subprocess.check_output([
NPX_CMD, '@sentry/cli@1.51.1', 'difutil', 'bundle-sources',
symbol_file])
files += glob.glob(SYMBOLS_DIR + '/*/*/*.src.zip')

View File

@@ -36,7 +36,8 @@ SYMBOLS_NAME = get_zip_name(PROJECT_NAME, ELECTRON_VERSION, 'symbols')
DSYM_NAME = get_zip_name(PROJECT_NAME, ELECTRON_VERSION, 'dsym')
PDB_NAME = get_zip_name(PROJECT_NAME, ELECTRON_VERSION, 'pdb')
DEBUG_NAME = get_zip_name(PROJECT_NAME, ELECTRON_VERSION, 'debug')
TOOLCHAIN_PROFILE_NAME = get_zip_name(PROJECT_NAME, ELECTRON_VERSION, 'toolchain-profile')
TOOLCHAIN_PROFILE_NAME = get_zip_name(PROJECT_NAME, ELECTRON_VERSION,
'toolchain-profile')
def main():
@@ -59,7 +60,8 @@ def main():
tag_exists = True
if not args.upload_to_s3:
assert release['exists'], 'Release does not exist; cannot upload to GitHub!'
assert release['exists'], \
'Release does not exist; cannot upload to GitHub!'
assert tag_exists == args.overwrite, \
'You have to pass --overwrite to overwrite a published release'
@@ -114,7 +116,8 @@ def main():
if PLATFORM == 'linux' and get_target_arch() == 'x64':
# Upload the hunspell dictionaries only from the linux x64 build
hunspell_dictionaries_zip = os.path.join(OUT_DIR, 'hunspell_dictionaries.zip')
hunspell_dictionaries_zip = os.path.join(
OUT_DIR, 'hunspell_dictionaries.zip')
upload_electron(release, hunspell_dictionaries_zip, args)
if not tag_exists and not args.upload_to_s3:
@@ -126,7 +129,9 @@ def main():
if PLATFORM == 'win32':
toolchain_profile_zip = os.path.join(OUT_DIR, TOOLCHAIN_PROFILE_NAME)
with ZipFile(toolchain_profile_zip, 'w') as myzip:
myzip.write(os.path.join(OUT_DIR, 'windows_toolchain_profile.json'), 'toolchain_profile.json')
myzip.write(
os.path.join(OUT_DIR, 'windows_toolchain_profile.json'),
'toolchain_profile.json')
upload_electron(release, toolchain_profile_zip, args)
@@ -170,12 +175,10 @@ class NonZipFileError(ValueError):
def zero_zip_date_time(fname):
""" Wrap strip-zip zero_zip_date_time within a file opening operation """
try:
zip = open(fname, 'r+b')
_zero_zip_date_time(zip)
with open(fname, 'r+b') as f:
_zero_zip_date_time(f)
except:
raise NonZipFileError(fname)
finally:
zip.close()
def _zero_zip_date_time(zip_):
@@ -208,7 +211,7 @@ def _zero_zip_date_time(zip_):
_, header_length = values
extra_struct = Struct("<HH" + "B" * header_length)
values = list(extra_struct.unpack_from(mm, offset))
header_id, header_length, rest = values[0], values[1], values[2:]
header_id, header_length = values[:2]
if header_id in (EXTENDED_TIME_DATA, UNIX_EXTRA_DATA):
values[0] = STRIPZIP_OPTION_HEADER
@@ -218,7 +221,7 @@ def _zero_zip_date_time(zip_):
if header_id == ZIP64_EXTRA_HEADER:
assert header_length == 16
values = list(zip64_extra_struct.unpack_from(mm, offset))
header_id, header_length, uncompressed_size, compressed_size = values
header_id, header_length, _, compressed_size = values
offset += extra_header_struct.size + header_length
@@ -266,7 +269,7 @@ def _zero_zip_date_time(zip_):
if signature_struct.unpack_from(mm, offset) != (FILE_HEADER_SIGNATURE,):
break
values = list(local_file_header_struct.unpack_from(mm, offset))
_, _, _, _, _, _, _, compressed_size, _, name_length, extra_field_length = values
compressed_size, _, name_length, extra_field_length = values[7:11]
# reset last_mod_time
values[4] = 0
# reset last_mod_date
@@ -274,20 +277,22 @@ def _zero_zip_date_time(zip_):
local_file_header_struct.pack_into(mm, offset, *values)
offset += local_file_header_struct.size + name_length
if extra_field_length != 0:
compressed_size = purify_extra_data(mm, offset, extra_field_length, compressed_size)
compressed_size = purify_extra_data(mm, offset, extra_field_length,
compressed_size)
offset += compressed_size + extra_field_length
while offset < archive_size:
if signature_struct.unpack_from(mm, offset) != (CENDIR_HEADER_SIGNATURE,):
break
values = list(central_directory_header_struct.unpack_from(mm, offset))
_, _, _, _, _, _, _, _, _, _, file_name_length, extra_field_length, file_comment_length, _, _, _, _ = values
file_name_length, extra_field_length, file_comment_length = values[10:13]
# reset last_mod_time
values[5] = 0
# reset last_mod_date
values[6] = 0x21
central_directory_header_struct.pack_into(mm, offset, *values)
offset += central_directory_header_struct.size + file_name_length + extra_field_length + file_comment_length
offset += central_directory_header_struct.size
offset += file_name_length + extra_field_length + file_comment_length
if extra_field_length != 0:
purify_extra_data(mm, offset - extra_field_length, extra_field_length)

View File

@@ -22,7 +22,9 @@ def strip_binary(binary_path, target_cpu):
strip = 'mips64el-redhat-linux-strip'
else:
strip = 'strip'
execute([strip, '--discard-all', '--strip-debug', '--preserve-dates', binary_path])
execute([
strip, '--discard-all', '--strip-debug', '--preserve-dates',
binary_path])
def main():
args = parse_args()

View File

@@ -20,7 +20,10 @@ def parse_args():
parser.add_argument('--base-url', required=False,
help="Base URL for all downloads")
parser.add_argument('--force', action='store_true', default=False, required=False)
parser.add_argument('--force',
action='store_true',
default=False,
required=False)
return parser.parse_args()
@@ -111,7 +114,9 @@ def download_binary(base_url, sha, binary_name, attempt=3):
def validate_sha(file_path, sha):
downloaded_sha = sha256(file_path)
if downloaded_sha != sha:
raise Exception("SHA for external binary file {} does not match expected '{}' != '{}'".format(file_path, downloaded_sha, sha))
raise Exception("SHA for external binary file {} does not match "
"expected '{}' != '{}'".format(
file_path, downloaded_sha, sha))
def download_to_temp_dir(url, filename, sha):

View File

@@ -33,7 +33,9 @@ def main():
returncode = 0
match = re.search(
'^Starting ChromeDriver [0-9]+.[0-9]+.[0-9]+.[0-9]+ .* on port [0-9]+$', output)
'^Starting ChromeDriver [0-9]+.[0-9]+.[0-9]+.[0-9]+ .* on port [0-9]+$',
output
)
if match is None:
returncode = 1

View File

@@ -837,7 +837,7 @@ void App::OnGpuProcessCrashed(base::TerminationStatus status) {
void App::BrowserChildProcessLaunchedAndConnected(
const content::ChildProcessData& data) {
ChildProcessLaunched(data.process_type, data.GetProcess().Handle(),
base::UTF16ToUTF8(data.name));
data.metrics_name, base::UTF16ToUTF8(data.name));
}
void App::BrowserChildProcessHostDisconnected(
@@ -868,6 +868,7 @@ void App::BrowserChildProcessCrashedOrKilled(
details.Set("type", content::GetProcessTypeNameInEnglish(data.process_type));
details.Set("reason", info.status);
details.Set("exitCode", info.exit_code);
details.Set("serviceName", data.metrics_name);
if (!data.name.empty()) {
details.Set("name", data.name);
}
@@ -896,6 +897,7 @@ void App::RenderProcessDisconnected(base::ProcessId host_pid) {
void App::ChildProcessLaunched(int process_type,
base::ProcessHandle handle,
const std::string& service_name,
const std::string& name) {
auto pid = base::GetProcId(handle);
@@ -906,7 +908,7 @@ void App::ChildProcessLaunched(int process_type,
auto metrics = base::ProcessMetrics::CreateProcessMetrics(handle);
#endif
app_metrics_[pid] = std::make_unique<electron::ProcessMetric>(
process_type, handle, std::move(metrics), name);
process_type, handle, std::move(metrics), service_name, name);
}
void App::ChildProcessDisconnected(base::ProcessId pid) {
@@ -1349,6 +1351,10 @@ std::vector<gin_helper::Dictionary> App::GetAppMetrics(v8::Isolate* isolate) {
pid_dict.Set("creationTime",
process_metric.second->process.CreationTime().ToJsTime());
if (!process_metric.second->service_name.empty()) {
pid_dict.Set("serviceName", process_metric.second->service_name);
}
if (!process_metric.second->name.empty()) {
pid_dict.Set("name", process_metric.second->name);
}

View File

@@ -168,6 +168,7 @@ class App : public ElectronBrowserClient::Delegate,
void SetAppPath(const base::FilePath& app_path);
void ChildProcessLaunched(int process_type,
base::ProcessHandle handle,
const std::string& service_name = std::string(),
const std::string& name = std::string());
void ChildProcessDisconnected(base::ProcessId pid);

View File

@@ -951,7 +951,7 @@ std::vector<v8::Local<v8::Object>> BaseWindow::GetChildWindows() const {
v8::Local<v8::Value> BaseWindow::GetBrowserView(
gin_helper::Arguments* args) const {
if (browser_views_.size() == 0) {
if (browser_views_.empty()) {
return v8::Null(isolate());
} else if (browser_views_.size() == 1) {
auto first_view = browser_views_.begin();
@@ -999,7 +999,7 @@ void BaseWindow::SetIcon(gin::Handle<NativeImage> icon) {
static_cast<NativeWindowViews*>(window_.get())
->SetIcon(icon->GetHICON(GetSystemMetrics(SM_CXSMICON)),
icon->GetHICON(GetSystemMetrics(SM_CXICON)));
#elif defined(USE_X11)
#elif defined(OS_LINUX)
static_cast<NativeWindowViews*>(window_.get())
->SetIcon(icon->image().AsImageSkia());
#endif

View File

@@ -12,12 +12,39 @@
#include "shell/browser/native_window.h"
#include "shell/common/gin_converters/accelerator_converter.h"
#include "shell/common/gin_converters/callback_converter.h"
#include "shell/common/gin_converters/file_path_converter.h"
#include "shell/common/gin_converters/gurl_converter.h"
#include "shell/common/gin_converters/image_converter.h"
#include "shell/common/gin_helper/dictionary.h"
#include "shell/common/gin_helper/object_template_builder.h"
#include "shell/common/node_includes.h"
#include "ui/base/models/image_model.h"
#if defined(OS_MAC)
namespace gin {
using SharingItem = electron::ElectronMenuModel::SharingItem;
template <>
struct Converter<SharingItem> {
static bool FromV8(v8::Isolate* isolate,
v8::Local<v8::Value> val,
SharingItem* out) {
gin_helper::Dictionary dict;
if (!ConvertFromV8(isolate, val, &dict))
return false;
dict.GetOptional("texts", &(out->texts));
dict.GetOptional("filePaths", &(out->file_paths));
dict.GetOptional("urls", &(out->urls));
return true;
}
};
} // namespace gin
#endif
namespace electron {
namespace api {
@@ -26,6 +53,15 @@ gin::WrapperInfo Menu::kWrapperInfo = {gin::kEmbedderNativeGin};
Menu::Menu(gin::Arguments* args) : model_(new ElectronMenuModel(this)) {
model_->AddObserver(this);
#if defined(OS_MAC)
gin_helper::Dictionary options;
if (args->GetNext(&options)) {
ElectronMenuModel::SharingItem item;
if (options.Get("sharingItem", &item))
model_->SetSharingItem(std::move(item));
}
#endif
}
Menu::~Menu() {
@@ -81,6 +117,19 @@ bool Menu::ShouldRegisterAcceleratorForCommandId(int command_id) const {
command_id);
}
#if defined(OS_MAC)
bool Menu::GetSharingItemForCommandId(
int command_id,
ElectronMenuModel::SharingItem* item) const {
v8::Isolate* isolate = JavascriptEnvironment::GetIsolate();
v8::HandleScope handle_scope(isolate);
v8::Local<v8::Value> val =
gin_helper::CallMethod(isolate, const_cast<Menu*>(this),
"_getSharingItemForCommandId", command_id);
return gin::ConvertFromV8(isolate, val, item);
}
#endif
void Menu::ExecuteCommand(int command_id, int flags) {
v8::Isolate* isolate = JavascriptEnvironment::GetIsolate();
v8::HandleScope scope(isolate);

Some files were not shown because too many files have changed in this diff Show More