mirror of
https://github.com/electron/electron.git
synced 2026-02-19 03:14:51 -05:00
Compare commits
287 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1e34cdda96 | ||
|
|
880aee0aa7 | ||
|
|
c00489396b | ||
|
|
30587d9700 | ||
|
|
ede0ebcc73 | ||
|
|
5966b42ac5 | ||
|
|
33e61a19ef | ||
|
|
a90c5b1b08 | ||
|
|
06e01e5b76 | ||
|
|
96d053677d | ||
|
|
8fe14665a0 | ||
|
|
c9384a609e | ||
|
|
fd2620bda4 | ||
|
|
dc04802296 | ||
|
|
90ca4e5f80 | ||
|
|
5013150cfd | ||
|
|
2d9c5a62c6 | ||
|
|
23f690ffd0 | ||
|
|
8f4e94694e | ||
|
|
af47434dc8 | ||
|
|
8ab99e2d8e | ||
|
|
ffcccdcf37 | ||
|
|
ce2ac1c0c2 | ||
|
|
1c3feddef8 | ||
|
|
c779f19ee5 | ||
|
|
09fbee9998 | ||
|
|
69d371fc41 | ||
|
|
b6db80c1c4 | ||
|
|
b87cf56b09 | ||
|
|
bc40a1aa0c | ||
|
|
d8606efe94 | ||
|
|
523e0d4574 | ||
|
|
3b23911121 | ||
|
|
516cbfa29a | ||
|
|
5c71377f40 | ||
|
|
85db55516b | ||
|
|
e071faa31b | ||
|
|
53e1c63d69 | ||
|
|
b8917a03d6 | ||
|
|
b33bc21159 | ||
|
|
9bb821a818 | ||
|
|
432b89445f | ||
|
|
00a3c3c883 | ||
|
|
288ec2ed93 | ||
|
|
90ca228cdc | ||
|
|
aa4ea630f8 | ||
|
|
d6fedc20bc | ||
|
|
42a72df1e7 | ||
|
|
16764199a7 | ||
|
|
4113f9d6a6 | ||
|
|
7aff4bc1dd | ||
|
|
d5b0df6775 | ||
|
|
b4f66e5f79 | ||
|
|
fbab31a699 | ||
|
|
7bccdbcbdb | ||
|
|
d715090a36 | ||
|
|
31054d6d46 | ||
|
|
76859affbd | ||
|
|
f3224365cf | ||
|
|
4a24337b14 | ||
|
|
2312420deb | ||
|
|
a05c9bcfb9 | ||
|
|
25f52d5d32 | ||
|
|
1fefe25ed5 | ||
|
|
d92ffceafb | ||
|
|
6e1dc452f9 | ||
|
|
9daf416097 | ||
|
|
738e0b9664 | ||
|
|
370a2c702b | ||
|
|
3f85bd57a2 | ||
|
|
5c8b5ff811 | ||
|
|
7d7f390c93 | ||
|
|
0fc5e42018 | ||
|
|
1ff780d3dd | ||
|
|
dd142b0327 | ||
|
|
0df4312ded | ||
|
|
95e3df589f | ||
|
|
7441b812e4 | ||
|
|
12f4204824 | ||
|
|
b84beed666 | ||
|
|
ebeb8adaf4 | ||
|
|
d5433ec0cc | ||
|
|
8d49957c93 | ||
|
|
471c44c709 | ||
|
|
8f4e7bde5e | ||
|
|
94fdb02987 | ||
|
|
2377746413 | ||
|
|
2bb2ef92da | ||
|
|
c994eb8e13 | ||
|
|
a9d358e730 | ||
|
|
69e30e8d67 | ||
|
|
02dfdce54a | ||
|
|
bd304f7c9d | ||
|
|
c2524d762b | ||
|
|
0b1e1b1612 | ||
|
|
0d0340ec69 | ||
|
|
f0d42aed88 | ||
|
|
ddb1c784d0 | ||
|
|
33ae7cc786 | ||
|
|
cbd1b4486c | ||
|
|
40a13b649f | ||
|
|
5728d3b709 | ||
|
|
0778cc70bb | ||
|
|
f0c02568da | ||
|
|
3c01b58114 | ||
|
|
c257cc25a2 | ||
|
|
e1ec17d641 | ||
|
|
ce7e0afd0a | ||
|
|
f589b73dee | ||
|
|
44f29fc675 | ||
|
|
daf00de2ed | ||
|
|
877a3b9fe2 | ||
|
|
0bcaaca6bd | ||
|
|
8619bd5027 | ||
|
|
4875c9b645 | ||
|
|
f4979e3cd2 | ||
|
|
d6a80bad05 | ||
|
|
cb0da6ff34 | ||
|
|
9aa73abe78 | ||
|
|
85bc005cd6 | ||
|
|
ee8d97d7fe | ||
|
|
3a510a26d0 | ||
|
|
9afeaa3a4c | ||
|
|
10a165a9ff | ||
|
|
66b4b21646 | ||
|
|
6f14dba7a0 | ||
|
|
3609fc7402 | ||
|
|
344b7f0d06 | ||
|
|
96f5f89f1b | ||
|
|
9c94fd7afb | ||
|
|
39ee94089a | ||
|
|
b2fcc15ec7 | ||
|
|
763bc62c7f | ||
|
|
abb71f5307 | ||
|
|
c12ab7c941 | ||
|
|
5c7579ab1c | ||
|
|
f0f027c06d | ||
|
|
58a21a3cd9 | ||
|
|
79e714a825 | ||
|
|
44e055a788 | ||
|
|
e78ce82641 | ||
|
|
1574cbf137 | ||
|
|
3340bc1bf9 | ||
|
|
2029224a84 | ||
|
|
f3676ff975 | ||
|
|
0b5fceb50e | ||
|
|
dbe170c665 | ||
|
|
3d2a754531 | ||
|
|
d6bb9b40b0 | ||
|
|
2c03b8fd6b | ||
|
|
67894f1493 | ||
|
|
471449d9f6 | ||
|
|
dec96acf14 | ||
|
|
d2b07a484d | ||
|
|
371bca69b6 | ||
|
|
088affd4a4 | ||
|
|
0e4e9dc98c | ||
|
|
b639fa4626 | ||
|
|
7981d955b8 | ||
|
|
cf5f0419f1 | ||
|
|
262723e394 | ||
|
|
6697042c0a | ||
|
|
2677f36db1 | ||
|
|
d504d150ef | ||
|
|
0f68d845f9 | ||
|
|
1ba535296e | ||
|
|
e8d9294d9d | ||
|
|
b55d7f4a16 | ||
|
|
7999ea39e2 | ||
|
|
ee108903a0 | ||
|
|
5b18d90597 | ||
|
|
f501dabc80 | ||
|
|
719e52928e | ||
|
|
089eb34e8d | ||
|
|
5200abe744 | ||
|
|
83f0d2645e | ||
|
|
878c6e3062 | ||
|
|
b163187235 | ||
|
|
425efb5e47 | ||
|
|
bc1ba1fe9d | ||
|
|
83892ab995 | ||
|
|
39d36e4462 | ||
|
|
f526206095 | ||
|
|
29d7be1565 | ||
|
|
e1c413c845 | ||
|
|
fcdd5cba71 | ||
|
|
4b1c31e4db | ||
|
|
8210d0f90e | ||
|
|
dd68581d30 | ||
|
|
652f995128 | ||
|
|
30fbcfca7b | ||
|
|
3f92a98315 | ||
|
|
621b3ba897 | ||
|
|
f66d4c7ee0 | ||
|
|
514a9319b9 | ||
|
|
be44a2c5b7 | ||
|
|
54ff706b71 | ||
|
|
a867503af6 | ||
|
|
beb0cbc6d0 | ||
|
|
025af3500c | ||
|
|
32a721fa2b | ||
|
|
e254593616 | ||
|
|
fd2861117e | ||
|
|
5b105f911f | ||
|
|
29270f3df5 | ||
|
|
657e88b173 | ||
|
|
09bab60a9e | ||
|
|
666907d50d | ||
|
|
73a42d0b7b | ||
|
|
f65d1f3d55 | ||
|
|
ba4d6d08a7 | ||
|
|
b6ec19a582 | ||
|
|
f7b1c75c72 | ||
|
|
6d0d350e13 | ||
|
|
f362e089b1 | ||
|
|
c9f6f15df6 | ||
|
|
bbd2236bdd | ||
|
|
5d6023ae0d | ||
|
|
dc4476d480 | ||
|
|
ce4ae584e3 | ||
|
|
344f8fd384 | ||
|
|
592a30aa0b | ||
|
|
3c31246343 | ||
|
|
7ab2a82166 | ||
|
|
5c821d3379 | ||
|
|
3e70692e4b | ||
|
|
c892c61b90 | ||
|
|
2c88626b51 | ||
|
|
7e312c81ca | ||
|
|
86df4db6f1 | ||
|
|
563c370d51 | ||
|
|
47beca1d2a | ||
|
|
925e4f7d74 | ||
|
|
a31deea1ba | ||
|
|
24bc0ee5c7 | ||
|
|
f5c177698e | ||
|
|
737e3de3fa | ||
|
|
8b8fbd0408 | ||
|
|
6a99c7b840 | ||
|
|
cff50ac65a | ||
|
|
a55c163db0 | ||
|
|
fdf8b02e14 | ||
|
|
73553032ea | ||
|
|
8f7a48879e | ||
|
|
83a928f6e3 | ||
|
|
3392d9a2e7 | ||
|
|
5ad69df52e | ||
|
|
b3a1c6d13c | ||
|
|
b0590b6ee8 | ||
|
|
713d8c4167 | ||
|
|
04b2ba84cd | ||
|
|
9d0e6d09f0 | ||
|
|
503ae86ab2 | ||
|
|
37c79ea844 | ||
|
|
93bcb30c3e | ||
|
|
d301616f60 | ||
|
|
5643e86956 | ||
|
|
371e83a8d2 | ||
|
|
d6c8ff2e70 | ||
|
|
d002f16157 | ||
|
|
dd7395ebed | ||
|
|
e3e793d25b | ||
|
|
da92c9aa27 | ||
|
|
02b58333dc | ||
|
|
23cf9fa4e9 | ||
|
|
4cf6884dd4 | ||
|
|
94585f5889 | ||
|
|
43a646ed85 | ||
|
|
f628ce67dd | ||
|
|
c8156c3c57 | ||
|
|
689d1b76de | ||
|
|
480f48b2fc | ||
|
|
a0ae691a9c | ||
|
|
f943b8c940 | ||
|
|
b7c9c895b5 | ||
|
|
1ba321b733 | ||
|
|
ad57867594 | ||
|
|
e613595982 | ||
|
|
624ae024e2 | ||
|
|
2190793fe6 | ||
|
|
fa215f1009 | ||
|
|
943bfa89ce | ||
|
|
d75a852743 | ||
|
|
18f517d8a6 | ||
|
|
fdf1ecec47 | ||
|
|
beb52ce61c | ||
|
|
2085aae915 |
@@ -68,8 +68,8 @@ executors:
|
||||
version:
|
||||
description: "xcode version"
|
||||
type: enum
|
||||
enum: ["14.3.0", "14.0.0"]
|
||||
default: 14.3.0
|
||||
enum: ["15.0.0", "14.0.0"]
|
||||
default: 15.0.0
|
||||
macos:
|
||||
xcode: << parameters.version >>
|
||||
resource_class: << parameters.size >>
|
||||
@@ -80,12 +80,14 @@ executors:
|
||||
machine: true
|
||||
|
||||
linux-arm:
|
||||
resource_class: electronjs/linux-arm
|
||||
machine: true
|
||||
resource_class: electronjs/aks-linux-arm-test
|
||||
docker:
|
||||
- image: ghcr.io/electron/test:arm32v7-8e0f85b708fa58e28e4824954d6fd55adfda5e9e
|
||||
|
||||
linux-arm64:
|
||||
resource_class: electronjs/linux-arm64
|
||||
machine: true
|
||||
resource_class: electronjs/aks-linux-arm-test
|
||||
docker:
|
||||
- image: ghcr.io/electron/test:arm64v8-76d5d29e247972da3855a01c2d8cf72c5998233a
|
||||
|
||||
# The config expects the following environment variables to be set:
|
||||
# - "SLACK_WEBHOOK" Slack hook URL to send notifications.
|
||||
@@ -335,46 +337,27 @@ step-setup-env-for-build: &step-setup-env-for-build
|
||||
# To find `gn` executable.
|
||||
echo 'export CHROMIUM_BUILDTOOLS_PATH="'"$PWD"'/src/buildtools"' >> $BASH_ENV
|
||||
|
||||
step-setup-goma-for-build: &step-setup-goma-for-build
|
||||
step-setup-rbe-for-build: &step-setup-rbe-for-build
|
||||
run:
|
||||
name: Setup Goma
|
||||
name: Setup RBE
|
||||
command: |
|
||||
echo 'export NUMBER_OF_NINJA_PROCESSES=300' >> $BASH_ENV
|
||||
if [ "`uname`" == "Darwin" ]; then
|
||||
echo 'export NUMBER_OF_NINJA_PROCESSES=200' >> $BASH_ENV
|
||||
echo 'ulimit -n 10000' >> $BASH_ENV
|
||||
echo 'sudo launchctl limit maxfiles 65536 200000' >> $BASH_ENV
|
||||
fi
|
||||
if [ ! -z "$RAW_GOMA_AUTH" ]; then
|
||||
echo $RAW_GOMA_AUTH > ~/.goma_oauth2_config
|
||||
fi
|
||||
git clone https://github.com/electron/build-tools.git
|
||||
cd build-tools
|
||||
npm install
|
||||
npx yarn --ignore-engines
|
||||
mkdir third_party
|
||||
node -e "require('./src/utils/goma.js').downloadAndPrepare({ gomaOneForAll: true })"
|
||||
export GOMA_FALLBACK_ON_AUTH_FAILURE=true
|
||||
third_party/goma/goma_ctl.py ensure_start
|
||||
if [ ! -z "$RAW_GOMA_AUTH" ] && [ "`third_party/goma/goma_auth.py info`" != "Login as Fermi Planck" ]; then
|
||||
echo "WARNING!!!!!! Goma authentication is incorrect; please update Goma auth token."
|
||||
exit 1
|
||||
fi
|
||||
echo 'export GN_GOMA_FILE='`node -e "console.log(require('./src/utils/goma.js').gnFilePath)"` >> $BASH_ENV
|
||||
echo 'export GOMA_DIR='`node -e "console.log(require('./src/utils/goma.js').dir)"` >> $BASH_ENV
|
||||
echo 'export GOMA_FALLBACK_ON_AUTH_FAILURE=true' >> $BASH_ENV
|
||||
cd ..
|
||||
touch "${TMPDIR:=/tmp}"/.goma-ready
|
||||
background: true
|
||||
|
||||
step-wait-for-goma: &step-wait-for-goma
|
||||
run:
|
||||
name: Wait for Goma
|
||||
command: |
|
||||
until [ -f "${TMPDIR:=/tmp}"/.goma-ready ]
|
||||
do
|
||||
sleep 5
|
||||
done
|
||||
echo "Goma ready"
|
||||
no_output_timeout: 5m
|
||||
# Pull down credential helper and print status
|
||||
node -e "require('./src/utils/reclient.js').downloadAndPrepare({})"
|
||||
HELPER=$(node -p "require('./src/utils/reclient.js').helperPath({})")
|
||||
$HELPER login
|
||||
echo 'export RBE_service='`node -e "console.log(require('./src/utils/reclient.js').serviceAddress)"` >> $BASH_ENV
|
||||
echo 'export RBE_experimental_credentials_helper='`node -e "console.log(require('./src/utils/reclient.js').helperPath({}))"` >> $BASH_ENV
|
||||
echo 'export RBE_experimental_credentials_helper_args="print"' >> $BASH_ENV
|
||||
|
||||
step-restore-brew-cache: &step-restore-brew-cache
|
||||
restore_cache:
|
||||
@@ -548,6 +531,13 @@ step-fix-sync: &step-fix-sync
|
||||
sed -i '' "s/Updating depot_tools... //g" gn_ensure_file
|
||||
cipd ensure --root src/buildtools/mac -ensure-file gn_ensure_file
|
||||
|
||||
# Fix reclient (wrong binary)
|
||||
echo 'infra/rbe/client/${platform}' `gclient getdep --deps-file=src/DEPS -r 'src/buildtools/reclient:infra/rbe/client/${platform}'` > gn_ensure_file
|
||||
# Remove extra output from calling gclient getdep which always calls update_depot_tools
|
||||
sed -i '' "s/Updating depot_tools... //g" gn_ensure_file
|
||||
cipd ensure --root src/buildtools/reclient -ensure-file gn_ensure_file
|
||||
python3 src/buildtools/reclient_cfgs/configure_reclient_cfgs.py --rbe_instance "projects/rbe-chrome-untrusted/instances/default_instance" --reproxy_cfg_template reproxy.cfg.template --rewrapper_cfg_project "" --skip_remoteexec_cfg_fetch
|
||||
|
||||
# Fix dsymutil (wrong binary)
|
||||
if [ "$TARGET_ARCH" == "arm64" ]; then
|
||||
export DSYM_SHA_FILE=src/tools/clang/dsymutil/bin/dsymutil.arm64.sha1
|
||||
@@ -600,7 +590,7 @@ step-gn-gen-default: &step-gn-gen-default
|
||||
name: Default GN gen
|
||||
command: |
|
||||
cd src
|
||||
gn gen out/Default --args="import(\"$GN_CONFIG\") import(\"$GN_GOMA_FILE\") $GN_EXTRA_ARGS $GN_BUILDFLAG_ARGS"
|
||||
gn gen out/Default --args="import(\"$GN_CONFIG\") use_remoteexec=true $GN_EXTRA_ARGS $GN_BUILDFLAG_ARGS"
|
||||
|
||||
step-gn-check: &step-gn-check
|
||||
run:
|
||||
@@ -636,16 +626,16 @@ step-electron-chromedriver-build: &step-electron-chromedriver-build
|
||||
command: |
|
||||
cd src
|
||||
if [ "`uname`" != "Darwin" ] && ([ "$TARGET_ARCH" == "arm" ] || [ "$TARGET_ARCH" == "arm64" ]); then
|
||||
gn gen out/chromedriver --args="import(\"$GN_CONFIG\") import(\"$GN_GOMA_FILE\") is_component_ffmpeg=false proprietary_codecs=false $GN_EXTRA_ARGS $GN_BUILDFLAG_ARGS"
|
||||
gn gen out/chromedriver --args="import(\"$GN_CONFIG\") use_remoteexec=true is_component_ffmpeg=false proprietary_codecs=false $GN_EXTRA_ARGS $GN_BUILDFLAG_ARGS"
|
||||
export CHROMEDRIVER_DIR="out/chromedriver"
|
||||
else
|
||||
export CHROMEDRIVER_DIR="out/Default"
|
||||
fi
|
||||
ninja -C $CHROMEDRIVER_DIR electron:electron_chromedriver -j $NUMBER_OF_NINJA_PROCESSES
|
||||
autoninja -C $CHROMEDRIVER_DIR electron:electron_chromedriver -j $NUMBER_OF_NINJA_PROCESSES
|
||||
if [ "`uname`" == "Linux" ]; then
|
||||
electron/script/strip-binaries.py --target-cpu="$TARGET_ARCH" --file $PWD/$CHROMEDRIVER_DIR/chromedriver
|
||||
fi
|
||||
ninja -C $CHROMEDRIVER_DIR electron:electron_chromedriver_zip
|
||||
autoninja -C $CHROMEDRIVER_DIR electron:electron_chromedriver_zip
|
||||
if [ "`uname`" != "Darwin" ] && ([ "$TARGET_ARCH" == "arm" ] || [ "$TARGET_ARCH" == "arm64" ]); then
|
||||
cp out/chromedriver/chromedriver.zip out/Default
|
||||
fi
|
||||
@@ -655,11 +645,12 @@ step-nodejs-headers-build: &step-nodejs-headers-build
|
||||
name: Build Node.js headers
|
||||
command: |
|
||||
cd src
|
||||
ninja -C out/Default electron:node_headers
|
||||
autoninja -C out/Default electron:node_headers
|
||||
|
||||
step-electron-publish: &step-electron-publish
|
||||
run:
|
||||
name: Publish Electron Dist
|
||||
no_output_timeout: 30m
|
||||
command: |
|
||||
if [ "`uname`" == "Darwin" ]; then
|
||||
rm -rf src/out/Default/obj
|
||||
@@ -708,14 +699,14 @@ step-ffmpeg-gn-gen: &step-ffmpeg-gn-gen
|
||||
name: ffmpeg GN gen
|
||||
command: |
|
||||
cd src
|
||||
gn gen out/ffmpeg --args="import(\"//electron/build/args/ffmpeg.gn\") import(\"$GN_GOMA_FILE\") $GN_EXTRA_ARGS"
|
||||
gn gen out/ffmpeg --args="import(\"//electron/build/args/ffmpeg.gn\") use_remoteexec=true $GN_EXTRA_ARGS"
|
||||
|
||||
step-ffmpeg-build: &step-ffmpeg-build
|
||||
run:
|
||||
name: Non proprietary ffmpeg build
|
||||
command: |
|
||||
cd src
|
||||
ninja -C out/ffmpeg electron:electron_ffmpeg_zip -j $NUMBER_OF_NINJA_PROCESSES
|
||||
autoninja -C out/ffmpeg electron:electron_ffmpeg_zip -j $NUMBER_OF_NINJA_PROCESSES
|
||||
|
||||
step-verify-mksnapshot: &step-verify-mksnapshot
|
||||
run:
|
||||
@@ -747,26 +738,13 @@ step-setup-linux-for-headless-testing: &step-setup-linux-for-headless-testing
|
||||
sh -e /etc/init.d/xvfb start
|
||||
fi
|
||||
|
||||
step-show-goma-stats: &step-show-goma-stats
|
||||
run:
|
||||
shell: /bin/bash
|
||||
name: Check goma stats after build
|
||||
command: |
|
||||
set +e
|
||||
set +o pipefail
|
||||
$GOMA_DIR/goma_ctl.py stat
|
||||
$GOMA_DIR/diagnose_goma_log.py
|
||||
true
|
||||
when: always
|
||||
background: true
|
||||
|
||||
step-mksnapshot-build: &step-mksnapshot-build
|
||||
run:
|
||||
name: mksnapshot build
|
||||
no_output_timeout: 30m
|
||||
command: |
|
||||
cd src
|
||||
ninja -C out/Default electron:electron_mksnapshot -j $NUMBER_OF_NINJA_PROCESSES
|
||||
autoninja -C out/Default electron:electron_mksnapshot -j $NUMBER_OF_NINJA_PROCESSES
|
||||
gn desc out/Default v8:run_mksnapshot_default args > out/Default/mksnapshot_args
|
||||
# Remove unused args from mksnapshot_args
|
||||
SEDOPTION="-i"
|
||||
@@ -775,6 +753,7 @@ step-mksnapshot-build: &step-mksnapshot-build
|
||||
fi
|
||||
sed $SEDOPTION '/.*builtins-pgo/d' out/Default/mksnapshot_args
|
||||
sed $SEDOPTION '/--turbo-profiling-input/d' out/Default/mksnapshot_args
|
||||
sed $SEDOPTION '/The gn arg use_goma=true .*/d' out/Default/mksnapshot_args
|
||||
if [ "`uname`" != "Darwin" ]; then
|
||||
if [ "$TARGET_ARCH" == "arm" ]; then
|
||||
electron/script/strip-binaries.py --file $PWD/out/Default/clang_x86_v8_arm/mksnapshot
|
||||
@@ -788,7 +767,7 @@ step-mksnapshot-build: &step-mksnapshot-build
|
||||
fi
|
||||
fi
|
||||
if [ "$SKIP_DIST_ZIP" != "1" ]; then
|
||||
ninja -C out/Default electron:electron_mksnapshot_zip -j $NUMBER_OF_NINJA_PROCESSES
|
||||
autoninja -C out/Default electron:electron_mksnapshot_zip -j $NUMBER_OF_NINJA_PROCESSES
|
||||
(cd out/Default; zip mksnapshot.zip mksnapshot_args gen/v8/embedded.S)
|
||||
fi
|
||||
|
||||
@@ -798,7 +777,7 @@ step-hunspell-build: &step-hunspell-build
|
||||
command: |
|
||||
cd src
|
||||
if [ "$SKIP_DIST_ZIP" != "1" ]; then
|
||||
ninja -C out/Default electron:hunspell_dictionaries_zip -j $NUMBER_OF_NINJA_PROCESSES
|
||||
autoninja -C out/Default electron:hunspell_dictionaries_zip -j $NUMBER_OF_NINJA_PROCESSES
|
||||
fi
|
||||
|
||||
step-maybe-generate-libcxx: &step-maybe-generate-libcxx
|
||||
@@ -807,9 +786,9 @@ step-maybe-generate-libcxx: &step-maybe-generate-libcxx
|
||||
command: |
|
||||
cd src
|
||||
if [ "`uname`" == "Linux" ]; then
|
||||
ninja -C out/Default electron:libcxx_headers_zip -j $NUMBER_OF_NINJA_PROCESSES
|
||||
ninja -C out/Default electron:libcxxabi_headers_zip -j $NUMBER_OF_NINJA_PROCESSES
|
||||
ninja -C out/Default electron:libcxx_objects_zip -j $NUMBER_OF_NINJA_PROCESSES
|
||||
autoninja -C out/Default electron:libcxx_headers_zip -j $NUMBER_OF_NINJA_PROCESSES
|
||||
autoninja -C out/Default electron:libcxxabi_headers_zip -j $NUMBER_OF_NINJA_PROCESSES
|
||||
autoninja -C out/Default electron:libcxx_objects_zip -j $NUMBER_OF_NINJA_PROCESSES
|
||||
fi
|
||||
|
||||
step-maybe-generate-breakpad-symbols: &step-maybe-generate-breakpad-symbols
|
||||
@@ -819,7 +798,7 @@ step-maybe-generate-breakpad-symbols: &step-maybe-generate-breakpad-symbols
|
||||
command: |
|
||||
if [ "$GENERATE_SYMBOLS" == "true" ]; then
|
||||
cd src
|
||||
ninja -C out/Default electron:electron_symbols
|
||||
autoninja -C out/Default electron:electron_symbols
|
||||
fi
|
||||
|
||||
step-maybe-zip-symbols: &step-maybe-zip-symbols
|
||||
@@ -828,8 +807,8 @@ step-maybe-zip-symbols: &step-maybe-zip-symbols
|
||||
command: |
|
||||
cd src
|
||||
export BUILD_PATH="$PWD/out/Default"
|
||||
ninja -C out/Default electron:licenses
|
||||
ninja -C out/Default electron:electron_version_file
|
||||
autoninja -C out/Default electron:licenses
|
||||
autoninja -C out/Default electron:electron_version_file
|
||||
electron/script/zip-symbols.py -b $BUILD_PATH
|
||||
|
||||
step-maybe-zip-symbols-and-clean: &step-maybe-zip-symbols-and-clean
|
||||
@@ -838,8 +817,8 @@ step-maybe-zip-symbols-and-clean: &step-maybe-zip-symbols-and-clean
|
||||
command: |
|
||||
cd src
|
||||
export BUILD_PATH="$PWD/out/Default"
|
||||
ninja -C out/Default electron:licenses
|
||||
ninja -C out/Default electron:electron_version_file
|
||||
autoninja -C out/Default electron:licenses
|
||||
autoninja -C out/Default electron:electron_version_file
|
||||
DELETE_DSYMS_AFTER_ZIP=1 electron/script/zip-symbols.py -b $BUILD_PATH
|
||||
|
||||
step-maybe-cross-arch-snapshot: &step-maybe-cross-arch-snapshot
|
||||
@@ -1186,11 +1165,10 @@ commands:
|
||||
could-be-aks:
|
||||
type: boolean
|
||||
steps:
|
||||
- *step-setup-goma-for-build
|
||||
- *step-setup-rbe-for-build
|
||||
- checkout-from-cache:
|
||||
could-be-aks: << parameters.could-be-aks >>
|
||||
- *step-setup-env-for-build
|
||||
- *step-wait-for-goma
|
||||
- *step-gn-gen-default
|
||||
- *step-gn-check
|
||||
build_and_save_artifacts:
|
||||
@@ -1209,9 +1187,7 @@ commands:
|
||||
build-type: << parameters.build-type >>
|
||||
- *step-maybe-electron-dist-strip
|
||||
- step-electron-dist-build:
|
||||
additional-targets: shell_browser_ui_unittests electron:node_headers third_party/electron_node:overlapped-checker electron:hunspell_dictionaries_zip
|
||||
|
||||
- *step-show-goma-stats
|
||||
additional-targets: electron:node_headers third_party/electron_node:overlapped-checker electron:hunspell_dictionaries_zip
|
||||
|
||||
# mksnapshot
|
||||
- *step-mksnapshot-build
|
||||
@@ -1341,7 +1317,7 @@ commands:
|
||||
command: |
|
||||
cd src
|
||||
if [ "$SKIP_DIST_ZIP" != "1" ]; then
|
||||
ninja -C out/Default electron:electron_dist_zip << parameters.additional-targets >> -j $NUMBER_OF_NINJA_PROCESSES
|
||||
autoninja -C out/Default electron:electron_dist_zip << parameters.additional-targets >> -j $NUMBER_OF_NINJA_PROCESSES
|
||||
if [ "$CHECK_DIST_MANIFEST" == "1" ]; then
|
||||
if [ "`uname`" == "Darwin" ]; then
|
||||
target_os=mac
|
||||
@@ -1442,7 +1418,7 @@ commands:
|
||||
- when:
|
||||
condition: << parameters.build >>
|
||||
steps:
|
||||
- *step-setup-goma-for-build
|
||||
- *step-setup-rbe-for-build
|
||||
- when:
|
||||
condition: << parameters.checkout-and-assume-cache >>
|
||||
steps:
|
||||
@@ -1561,7 +1537,6 @@ commands:
|
||||
steps:
|
||||
- *step-depot-tools-add-to-path
|
||||
- *step-setup-env-for-build
|
||||
- *step-wait-for-goma
|
||||
- *step-get-more-space-on-mac
|
||||
- *step-fix-sync
|
||||
- *step-delete-git-directories
|
||||
@@ -1655,17 +1630,15 @@ commands:
|
||||
export LLVM_SYMBOLIZER_PATH=$PWD/third_party/llvm-build/Release+Asserts/bin/llvm-symbolizer
|
||||
export MOCHA_TIMEOUT=180000
|
||||
echo "Piping output to ASAN_SYMBOLIZE ($ASAN_SYMBOLIZE)"
|
||||
(cd electron && (circleci tests glob "spec/*-spec.ts" | circleci tests run --command="xargs node script/yarn test --runners=main --trace-uncaught --enable-logging --files" --split-by=timings 2>&1)) | $ASAN_SYMBOLIZE
|
||||
(cd electron && (circleci tests glob "spec/*-spec.ts" | xargs -I@ -P4 bash -c "echo $(pwd)/@" | circleci tests run --command="xargs node script/yarn test --runners=main --trace-uncaught --enable-logging --files" --split-by=timings 2>&1)) | $ASAN_SYMBOLIZE
|
||||
else
|
||||
if [ "$TARGET_ARCH" == "arm" ] || [ "$TARGET_ARCH" == "arm64" ]; then
|
||||
export ELECTRON_SKIP_NATIVE_MODULE_TESTS=true
|
||||
(cd electron && node script/yarn test --runners=main --trace-uncaught --enable-logging)
|
||||
else
|
||||
if [ "$TARGET_ARCH" == "ia32" ]; then
|
||||
npm_config_arch=x64 node electron/node_modules/dugite/script/download-git.js
|
||||
fi
|
||||
(cd electron && (circleci tests glob "spec/*-spec.ts" | circleci tests run --command="xargs node script/yarn test --runners=main --trace-uncaught --enable-logging --files" --split-by=timings))
|
||||
fi
|
||||
if [ "$TARGET_ARCH" == "ia32" ]; then
|
||||
npm_config_arch=x64 node electron/node_modules/dugite/script/download-git.js
|
||||
fi
|
||||
(cd electron && (circleci tests glob "spec/*-spec.ts" | xargs -I@ -P4 bash -c "echo $(pwd)/@" | circleci tests run --command="xargs node script/yarn test --runners=main --trace-uncaught --enable-logging --files" --split-by=timings))
|
||||
fi
|
||||
- store_test_results:
|
||||
path: src/junit
|
||||
@@ -1749,14 +1722,12 @@ commands:
|
||||
- *step-fix-sync
|
||||
- *step-setup-env-for-build
|
||||
- *step-fix-known-hosts-linux
|
||||
- *step-setup-goma-for-build
|
||||
- *step-wait-for-goma
|
||||
- *step-setup-rbe-for-build
|
||||
- *step-gn-gen-default
|
||||
|
||||
# Electron app
|
||||
- ninja_build_electron:
|
||||
build-type: << parameters.build-type >>
|
||||
- *step-show-goma-stats
|
||||
- *step-maybe-generate-breakpad-symbols
|
||||
- *step-maybe-electron-dist-strip
|
||||
- step-electron-dist-build
|
||||
@@ -2163,7 +2134,7 @@ jobs:
|
||||
<<: *env-ninja-status
|
||||
<<: *env-macos-build
|
||||
<<: *env-apple-silicon
|
||||
GCLIENT_EXTRA_ARGS: '--custom-var=checkout_mac=True --custom-var=host_os=mac'
|
||||
GCLIENT_EXTRA_ARGS: '--custom-var=checkout_mac=True --custom-var=host_os=mac --custom-var=host_cpu=arm64'
|
||||
steps:
|
||||
- electron-build:
|
||||
persist: true
|
||||
@@ -2295,6 +2266,7 @@ jobs:
|
||||
<<: *env-global
|
||||
<<: *env-headless-testing
|
||||
<<: *env-stack-dumping
|
||||
parallelism: 3
|
||||
steps:
|
||||
- electron-tests:
|
||||
artifact-key: linux-arm
|
||||
@@ -2306,6 +2278,7 @@ jobs:
|
||||
<<: *env-global
|
||||
<<: *env-headless-testing
|
||||
<<: *env-stack-dumping
|
||||
parallelism: 3
|
||||
steps:
|
||||
- electron-tests:
|
||||
artifact-key: linux-arm64
|
||||
|
||||
1
.github/ISSUE_TEMPLATE/bug_report.yml
vendored
1
.github/ISSUE_TEMPLATE/bug_report.yml
vendored
@@ -2,7 +2,6 @@ name: Bug Report
|
||||
description: Report an Electron bug
|
||||
title: "[Bug]: "
|
||||
labels: "bug :beetle:"
|
||||
projects: ["electron/90"]
|
||||
body:
|
||||
- type: checkboxes
|
||||
attributes:
|
||||
|
||||
142
.github/workflows/branch-created.yml
vendored
142
.github/workflows/branch-created.yml
vendored
@@ -8,7 +8,7 @@ permissions: {}
|
||||
jobs:
|
||||
release-branch-created:
|
||||
name: Release Branch Created
|
||||
if: ${{ github.event.ref_type == 'branch' && endsWith(github.event.ref, '-x-y') }}
|
||||
if: ${{ github.event.ref_type == 'branch' && endsWith(github.event.ref, '-x-y') && !startsWith(github.event.ref, 'roller') }}
|
||||
permissions:
|
||||
contents: read
|
||||
pull-requests: write
|
||||
@@ -60,106 +60,56 @@ jobs:
|
||||
done
|
||||
- name: Generate GitHub App token
|
||||
if: ${{ steps.check-major-version.outputs.MAJOR }}
|
||||
uses: electron/github-app-auth-action@cc6751b3b5e4edc5b9a4ad0a021ac455653b6dc8 # v1.0.0
|
||||
uses: electron/github-app-auth-action@384fd19694fe7b6dcc9a684746c6976ad78228ae # v1.1.1
|
||||
id: generate-token
|
||||
with:
|
||||
creds: ${{ secrets.RELEASE_BOARD_GH_APP_CREDS }}
|
||||
org: electron
|
||||
- name: Generate Release Project Board Metadata
|
||||
if: ${{ steps.check-major-version.outputs.MAJOR }}
|
||||
uses: actions/github-script@d7906e4ad0b1822421a7e6a35d5ca353c962f410 # v6.4.1
|
||||
id: generate-project-metadata
|
||||
with:
|
||||
script: |
|
||||
const major = ${{ steps.check-major-version.outputs.MAJOR }}
|
||||
const nextMajor = major + 1
|
||||
const prevMajor = major - 1
|
||||
|
||||
core.setOutput("major", major)
|
||||
core.setOutput("next-major", nextMajor)
|
||||
core.setOutput("prev-major", prevMajor)
|
||||
core.setOutput("prev-prev-major", prevMajor - 1)
|
||||
core.setOutput("template-view", JSON.stringify({
|
||||
major,
|
||||
"next-major": nextMajor,
|
||||
"prev-major": prevMajor,
|
||||
}))
|
||||
- name: Create Release Project Board
|
||||
if: ${{ steps.check-major-version.outputs.MAJOR }}
|
||||
uses: dsanders11/project-actions/copy-project@3a81985616963f32fae17d1d1b406c631f3201a1 # v1.1.0
|
||||
id: create-release-board
|
||||
with:
|
||||
drafts: true
|
||||
project-number: 64
|
||||
# TODO - Set to public once GitHub fixes their GraphQL bug
|
||||
# public: true
|
||||
link-to-repository: electron/electron
|
||||
template-view: ${{ steps.generate-project-metadata.outputs.template-view }}
|
||||
title: ${{ steps.generate-project-metadata.outputs.major }}-x-y
|
||||
token: ${{ steps.generate-token.outputs.token }}
|
||||
- name: Dump Release Project Board Contents
|
||||
if: ${{ steps.check-major-version.outputs.MAJOR }}
|
||||
run: gh project item-list ${{ steps.create-release-board.outputs.number }} --owner electron --format json | jq
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ steps.generate-token.outputs.token }}
|
||||
MAJOR: ${{ steps.check-major-version.outputs.MAJOR }}
|
||||
ELECTRON_ORG_ID: "O_kgDOAMybxg"
|
||||
ELECTRON_REPO_ID: "R_kgDOAI8xSw"
|
||||
TEMPLATE_PROJECT_ID: "PVT_kwDOAMybxs4AQvib"
|
||||
run: |
|
||||
# Copy template to create new project board
|
||||
PROJECT_ID=$(gh api graphql -f query='mutation ($ownerId: ID!, $projectId: ID!, $title: String!) {
|
||||
copyProjectV2(input: {
|
||||
includeDraftIssues: true,
|
||||
ownerId: $ownerId,
|
||||
projectId: $projectId,
|
||||
title: $title
|
||||
}) {
|
||||
projectV2 {
|
||||
id
|
||||
}
|
||||
}
|
||||
}' -f ownerId=$ELECTRON_ORG_ID -f projectId=$TEMPLATE_PROJECT_ID -f title="${MAJOR}-x-y" | jq -r '.data.copyProjectV2.projectV2.id')
|
||||
|
||||
# Make the new project public
|
||||
gh api graphql -f query='mutation ($projectId: ID!) {
|
||||
updateProjectV2(input: {
|
||||
projectId: $projectId,
|
||||
public: true,
|
||||
}) {
|
||||
projectV2 {
|
||||
id
|
||||
}
|
||||
}
|
||||
}' -f projectId=$PROJECT_ID
|
||||
|
||||
# Link the new project to the Electron repository
|
||||
gh api graphql -f query='mutation ($projectId: ID!, $repositoryId: ID!) {
|
||||
linkProjectV2ToRepository(input: {
|
||||
projectId: $projectId,
|
||||
repositoryId: $repositoryId
|
||||
}) {
|
||||
clientMutationId
|
||||
}
|
||||
}' -f projectId=$PROJECT_ID -f repositoryId=$ELECTRON_REPO_ID
|
||||
|
||||
# Get all draft issues on the new project board
|
||||
gh api graphql -f query='query ($id: ID!) {
|
||||
node(id: $id) {
|
||||
... on ProjectV2 {
|
||||
items(first: 100) {
|
||||
nodes {
|
||||
... on ProjectV2Item {
|
||||
id
|
||||
content {
|
||||
... on DraftIssue { id title
|
||||
body
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}' -f id=$PROJECT_ID > issues.json
|
||||
PROJECT_ITEMS=$(jq '.data.node.items.nodes[] | select(.content.id != null) | .id' issues.json)
|
||||
|
||||
#
|
||||
# Do template replacement for draft issues
|
||||
#
|
||||
echo "{\"major\": $MAJOR, \"next-major\": $((MAJOR + 1)), \"prev-major\": $((MAJOR - 1))}" > variables.json
|
||||
|
||||
# npx mustache is annoyingly slow, so install mustache directly
|
||||
yarn add -D mustache
|
||||
|
||||
for PROJECT_ITEM_ID in $PROJECT_ITEMS; do
|
||||
# These are done with the raw output flag and sent to file to better retain formatting
|
||||
jq -r ".data.node.items.nodes[] | select(.id == $PROJECT_ITEM_ID) | .content.title" issues.json > title.txt
|
||||
jq -r ".data.node.items.nodes[] | select(.id == $PROJECT_ITEM_ID) | .content.body" issues.json > body.txt
|
||||
|
||||
./node_modules/.bin/mustache variables.json title.txt new_title.txt
|
||||
./node_modules/.bin/mustache variables.json body.txt new_body.txt
|
||||
|
||||
# Only update draft issues which had content change when interpolated
|
||||
if ! cmp --silent -- new_title.txt title.txt || ! cmp --silent -- new_body.txt body.txt; then
|
||||
DRAFT_ISSUE_ID=$(jq ".data.node.items.nodes[] | select(.id == $PROJECT_ITEM_ID) | .content.id" issues.json)
|
||||
gh api graphql -f query='mutation ($draftIssueId: ID!, $title: String!, $body: String!) {
|
||||
updateProjectV2DraftIssue(input: {
|
||||
draftIssueId: $draftIssueId,
|
||||
title: $title,
|
||||
body: $body
|
||||
}) {
|
||||
draftIssue {
|
||||
id
|
||||
}
|
||||
}
|
||||
}' -f draftIssueId=$DRAFT_ISSUE_ID -f title="$(cat new_title.txt)" -f body="$(cat new_body.txt)"
|
||||
fi
|
||||
done
|
||||
- name: Find Previous Release Project Board
|
||||
if: ${{ steps.check-major-version.outputs.MAJOR }}
|
||||
uses: dsanders11/project-actions/find-project@3a81985616963f32fae17d1d1b406c631f3201a1 # v1.1.0
|
||||
id: find-prev-release-board
|
||||
with:
|
||||
title: ${{ steps.generate-project-metadata.outputs.prev-prev-major }}-x-y
|
||||
- name: Close Previous Release Project Board
|
||||
if: ${{ steps.check-major-version.outputs.MAJOR }}
|
||||
uses: dsanders11/project-actions/close-project@3a81985616963f32fae17d1d1b406c631f3201a1 # v1.1.0
|
||||
with:
|
||||
project-number: ${{ steps.find-prev-release-board.outputs.number }}
|
||||
|
||||
10
.github/workflows/issue-labeled.yml
vendored
10
.github/workflows/issue-labeled.yml
vendored
@@ -20,14 +20,12 @@ jobs:
|
||||
creds: ${{ secrets.ISSUE_TRIAGE_GH_APP_CREDS }}
|
||||
org: electron
|
||||
- name: Set status
|
||||
uses: github/update-project-action@2d475e08804f11f4022df7e21f5816531e97cb64 # v2
|
||||
uses: dsanders11/project-actions/edit-item@a24415515fa60a22f71f9d9d00e36ca82660cde9 # v1.0.1
|
||||
with:
|
||||
github_token: ${{ steps.generate-token.outputs.token }}
|
||||
organization: electron
|
||||
project_number: 90
|
||||
content_id: ${{ github.event.issue.node_id }}
|
||||
token: ${{ steps.generate-token.outputs.token }}
|
||||
project-number: 90
|
||||
field: Status
|
||||
value: 🛑 Blocked
|
||||
field-value: 🛑 Blocked
|
||||
issue-labeled-blocked-need-repro:
|
||||
name: blocked/need-repro label added
|
||||
if: github.event.label.name == 'blocked/need-repro'
|
||||
|
||||
27
.github/workflows/issue-opened.yml
vendored
Normal file
27
.github/workflows/issue-opened.yml
vendored
Normal file
@@ -0,0 +1,27 @@
|
||||
name: Issue Opened
|
||||
|
||||
on:
|
||||
issues:
|
||||
types:
|
||||
- opened
|
||||
|
||||
permissions: {}
|
||||
|
||||
jobs:
|
||||
add-to-issue-triage:
|
||||
if: ${{ contains(github.event.issue.labels.*.name, 'bug :beetle:') }}
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Generate GitHub App token
|
||||
uses: electron/github-app-auth-action@384fd19694fe7b6dcc9a684746c6976ad78228ae # v1.1.1
|
||||
id: generate-token
|
||||
with:
|
||||
creds: ${{ secrets.ISSUE_TRIAGE_GH_APP_CREDS }}
|
||||
org: electron
|
||||
- name: Add to Issue Triage
|
||||
uses: dsanders11/project-actions/add-item@a24415515fa60a22f71f9d9d00e36ca82660cde9 # v1.0.1
|
||||
with:
|
||||
field: Reporter
|
||||
field-value: ${{ github.event.issue.user.login }}
|
||||
project-number: 90
|
||||
token: ${{ steps.generate-token.outputs.token }}
|
||||
10
.github/workflows/issue-unlabeled.yml
vendored
10
.github/workflows/issue-unlabeled.yml
vendored
@@ -30,11 +30,9 @@ jobs:
|
||||
org: electron
|
||||
- name: Set status
|
||||
if: ${{ steps.check-for-blocked-labels.outputs.NOT_BLOCKED }}
|
||||
uses: github/update-project-action@2d475e08804f11f4022df7e21f5816531e97cb64 # v2
|
||||
uses: dsanders11/project-actions/edit-item@a24415515fa60a22f71f9d9d00e36ca82660cde9 # v1.0.1
|
||||
with:
|
||||
github_token: ${{ steps.generate-token.outputs.token }}
|
||||
organization: electron
|
||||
project_number: 90
|
||||
content_id: ${{ github.event.issue.node_id }}
|
||||
token: ${{ steps.generate-token.outputs.token }}
|
||||
project-number: 90
|
||||
field: Status
|
||||
value: 📥 Was Blocked
|
||||
field-value: 📥 Was Blocked
|
||||
|
||||
29
.github/workflows/pull-request-labeled.yml
vendored
29
.github/workflows/pull-request-labeled.yml
vendored
@@ -1,13 +1,26 @@
|
||||
name: Pull Request Labeled
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
pull_request_target:
|
||||
types: [labeled]
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
permissions: {}
|
||||
|
||||
jobs:
|
||||
pull-request-labeled-backport-requested:
|
||||
name: backport/requested label added
|
||||
if: github.event.label.name == 'backport/requested 🗳'
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Trigger Slack workflow
|
||||
uses: slackapi/slack-github-action@e28cf165c92ffef168d23c5c9000cffc8a25e117 # v1.24.0
|
||||
with:
|
||||
payload: |
|
||||
{
|
||||
"url": "${{ github.event.pull_request.html_url }}"
|
||||
}
|
||||
env:
|
||||
SLACK_WEBHOOK_URL: ${{ secrets.BACKPORT_REQUESTED_SLACK_WEBHOOK_URL }}
|
||||
pull-request-labeled-deprecation-review-complete:
|
||||
name: deprecation-review/complete label added
|
||||
if: github.event.label.name == 'deprecation-review/complete ✅'
|
||||
@@ -20,11 +33,9 @@ jobs:
|
||||
creds: ${{ secrets.RELEASE_BOARD_GH_APP_CREDS }}
|
||||
org: electron
|
||||
- name: Set status
|
||||
uses: dsanders11/update-project-action@7ade91760df70df76770a238abee7a4869e01cf8
|
||||
uses: dsanders11/project-actions/edit-item@a24415515fa60a22f71f9d9d00e36ca82660cde9 # v1.0.1
|
||||
with:
|
||||
github_token: ${{ steps.generate-token.outputs.token }}
|
||||
organization: electron
|
||||
project_number: 94
|
||||
content_id: ${{ github.event.pull_request.node_id }}
|
||||
token: ${{ steps.generate-token.outputs.token }}
|
||||
project-number: 94
|
||||
field: Status
|
||||
value: ✅ Reviewed
|
||||
field-value: ✅ Reviewed
|
||||
|
||||
35
.github/workflows/stable-prep-items.yml
vendored
Normal file
35
.github/workflows/stable-prep-items.yml
vendored
Normal file
@@ -0,0 +1,35 @@
|
||||
name: Check Stable Prep Items
|
||||
|
||||
on:
|
||||
schedule:
|
||||
- cron: '0 */12 * * *'
|
||||
workflow_dispatch:
|
||||
|
||||
permissions: {}
|
||||
|
||||
jobs:
|
||||
check-stable-prep-items:
|
||||
name: Check Stable Prep Items
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Generate GitHub App token
|
||||
uses: electron/github-app-auth-action@384fd19694fe7b6dcc9a684746c6976ad78228ae # v1.1.1
|
||||
id: generate-token
|
||||
with:
|
||||
creds: ${{ secrets.RELEASE_BOARD_GH_APP_CREDS }}
|
||||
org: electron
|
||||
- name: Find Newest Release Project Board
|
||||
id: find-project-number
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ steps.generate-token.outputs.token }}
|
||||
run: |
|
||||
set -eo pipefail
|
||||
PROJECT_NUMBER=$(gh project list --owner electron --format json | jq -r '.projects | map(select(.title | test("^[0-9]+-x-y$"))) | max_by(.number) | .number')
|
||||
echo "PROJECT_NUMBER=$PROJECT_NUMBER" >> "$GITHUB_OUTPUT"
|
||||
- name: Update Completed Stable Prep Items
|
||||
uses: dsanders11/project-actions/completed-by@a24415515fa60a22f71f9d9d00e36ca82660cde9 # v1.0.1
|
||||
with:
|
||||
field: Prep Status
|
||||
field-value: ✅ Complete
|
||||
project-number: ${{ steps.find-project-number.outputs.PROJECT_NUMBER }}
|
||||
token: ${{ steps.generate-token.outputs.token }}
|
||||
94
BUILD.gn
94
BUILD.gn
@@ -29,6 +29,7 @@ import("filenames.gni")
|
||||
import("filenames.hunspell.gni")
|
||||
import("filenames.libcxx.gni")
|
||||
import("filenames.libcxxabi.gni")
|
||||
import("js2c_toolchain.gni")
|
||||
|
||||
if (is_mac) {
|
||||
import("//build/config/mac/rules.gni")
|
||||
@@ -104,14 +105,26 @@ branding = read_file("shell/app/BRANDING.json", "json")
|
||||
electron_project_name = branding.project_name
|
||||
electron_product_name = branding.product_name
|
||||
electron_mac_bundle_id = branding.mac_bundle_id
|
||||
electron_version = exec_script("script/print-version.py",
|
||||
[],
|
||||
"trim string",
|
||||
[
|
||||
".git/packed-refs",
|
||||
".git/HEAD",
|
||||
"script/lib/get-version.js",
|
||||
])
|
||||
|
||||
if (override_electron_version != "") {
|
||||
electron_version = override_electron_version
|
||||
} else {
|
||||
# When building from source code tarball there is no git tag available and
|
||||
# builders must explicitly pass override_electron_version in gn args.
|
||||
# This read_file call will assert if there is no git information, without it
|
||||
# gn will generate a malformed build configuration and ninja will get into
|
||||
# infinite loop.
|
||||
read_file(".git/packed-refs", "string")
|
||||
|
||||
# Set electron version from git tag.
|
||||
electron_version = exec_script("script/get-git-version.py",
|
||||
[],
|
||||
"trim string",
|
||||
[
|
||||
".git/packed-refs",
|
||||
".git/HEAD",
|
||||
])
|
||||
}
|
||||
|
||||
if (is_mas_build) {
|
||||
assert(is_mac,
|
||||
@@ -153,15 +166,6 @@ npm_action("build_electron_definitions") {
|
||||
outputs = [ "$target_gen_dir/tsc/typings/electron.d.ts" ]
|
||||
}
|
||||
|
||||
webpack_build("electron_asar_bundle") {
|
||||
deps = [ ":build_electron_definitions" ]
|
||||
|
||||
inputs = auto_filenames.asar_bundle_deps
|
||||
|
||||
config_file = "//electron/build/webpack/webpack.config.asar.js"
|
||||
out_file = "$target_gen_dir/js2c/asar_bundle.js"
|
||||
}
|
||||
|
||||
webpack_build("electron_browser_bundle") {
|
||||
deps = [ ":build_electron_definitions" ]
|
||||
|
||||
@@ -207,6 +211,15 @@ webpack_build("electron_isolated_renderer_bundle") {
|
||||
out_file = "$target_gen_dir/js2c/isolated_bundle.js"
|
||||
}
|
||||
|
||||
webpack_build("electron_node_bundle") {
|
||||
deps = [ ":build_electron_definitions" ]
|
||||
|
||||
inputs = auto_filenames.node_bundle_deps
|
||||
|
||||
config_file = "//electron/build/webpack/webpack.config.node.js"
|
||||
out_file = "$target_gen_dir/js2c/node_init.js"
|
||||
}
|
||||
|
||||
webpack_build("electron_utility_bundle") {
|
||||
deps = [ ":build_electron_definitions" ]
|
||||
|
||||
@@ -218,32 +231,37 @@ webpack_build("electron_utility_bundle") {
|
||||
|
||||
action("electron_js2c") {
|
||||
deps = [
|
||||
":electron_asar_bundle",
|
||||
":electron_browser_bundle",
|
||||
":electron_isolated_renderer_bundle",
|
||||
":electron_node_bundle",
|
||||
":electron_renderer_bundle",
|
||||
":electron_sandboxed_renderer_bundle",
|
||||
":electron_utility_bundle",
|
||||
":electron_worker_bundle",
|
||||
"//third_party/electron_node:node_js2c($electron_js2c_toolchain)",
|
||||
]
|
||||
|
||||
sources = [
|
||||
"$target_gen_dir/js2c/asar_bundle.js",
|
||||
"$target_gen_dir/js2c/browser_init.js",
|
||||
"$target_gen_dir/js2c/isolated_bundle.js",
|
||||
"$target_gen_dir/js2c/node_init.js",
|
||||
"$target_gen_dir/js2c/renderer_init.js",
|
||||
"$target_gen_dir/js2c/sandbox_bundle.js",
|
||||
"$target_gen_dir/js2c/utility_init.js",
|
||||
"$target_gen_dir/js2c/worker_init.js",
|
||||
]
|
||||
|
||||
inputs = sources + [ "//third_party/electron_node/tools/js2c.py" ]
|
||||
inputs = sources
|
||||
outputs = [ "$root_gen_dir/electron_natives.cc" ]
|
||||
|
||||
script = "build/js2c.py"
|
||||
args = [ rebase_path("//third_party/electron_node") ] +
|
||||
rebase_path(outputs, root_build_dir) +
|
||||
rebase_path(sources, root_build_dir)
|
||||
out_dir =
|
||||
get_label_info(":anything($electron_js2c_toolchain)", "root_out_dir")
|
||||
args = [
|
||||
rebase_path("$out_dir/node_js2c"),
|
||||
rebase_path("$root_gen_dir"),
|
||||
] + rebase_path(outputs, root_gen_dir) +
|
||||
rebase_path(sources, root_gen_dir)
|
||||
}
|
||||
|
||||
action("generate_config_gypi") {
|
||||
@@ -422,6 +440,7 @@ source_set("electron_lib") {
|
||||
"//chrome/app/resources:platform_locale_settings",
|
||||
"//components/autofill/core/common:features",
|
||||
"//components/certificate_transparency",
|
||||
"//components/compose:buildflags",
|
||||
"//components/embedder_support:browser_util",
|
||||
"//components/language/core/browser",
|
||||
"//components/net_log",
|
||||
@@ -430,6 +449,8 @@ source_set("electron_lib") {
|
||||
"//components/network_hints/renderer",
|
||||
"//components/network_session_configurator/common",
|
||||
"//components/omnibox/browser:buildflags",
|
||||
"//components/os_crypt/async/browser",
|
||||
"//components/os_crypt/async/browser:key_provider_interface",
|
||||
"//components/os_crypt/sync",
|
||||
"//components/pref_registry",
|
||||
"//components/prefs",
|
||||
@@ -471,6 +492,7 @@ source_set("electron_lib") {
|
||||
"//third_party/webrtc_overrides:webrtc_component",
|
||||
"//third_party/widevine/cdm:headers",
|
||||
"//third_party/zlib/google:zip",
|
||||
"//ui/base:ozone_buildflags",
|
||||
"//ui/base/idle",
|
||||
"//ui/compositor",
|
||||
"//ui/events:dom_keycode_converter",
|
||||
@@ -701,6 +723,7 @@ source_set("electron_lib") {
|
||||
"shell/common/extensions/api",
|
||||
"shell/common/extensions/api:extensions_features",
|
||||
"//chrome/browser/resources:component_extension_resources",
|
||||
"//components/guest_view/common:mojom",
|
||||
"//components/update_client:update_client",
|
||||
"//components/zoom",
|
||||
"//extensions/browser",
|
||||
@@ -904,10 +927,7 @@ if (is_mac) {
|
||||
assert(defined(invoker.helper_name_suffix))
|
||||
|
||||
output_name = electron_helper_name + invoker.helper_name_suffix
|
||||
deps = [
|
||||
":electron_framework+link",
|
||||
"//base/allocator:early_zone_registration_apple",
|
||||
]
|
||||
deps = [ ":electron_framework+link" ]
|
||||
if (!is_mas_build) {
|
||||
deps += [ "//sandbox/mac:seatbelt" ]
|
||||
}
|
||||
@@ -1068,7 +1088,6 @@ if (is_mac) {
|
||||
":electron_app_plist",
|
||||
":electron_app_resources",
|
||||
":electron_fuses",
|
||||
"//base/allocator:early_zone_registration_apple",
|
||||
"//electron/buildflags",
|
||||
]
|
||||
if (is_mas_build) {
|
||||
@@ -1320,25 +1339,6 @@ if (is_mac) {
|
||||
}
|
||||
}
|
||||
|
||||
test("shell_browser_ui_unittests") {
|
||||
sources = [
|
||||
"//electron/shell/browser/ui/accelerator_util_unittests.cc",
|
||||
"//electron/shell/browser/ui/run_all_unittests.cc",
|
||||
]
|
||||
|
||||
configs += [ ":electron_lib_config" ]
|
||||
|
||||
deps = [
|
||||
":electron_lib",
|
||||
"//base",
|
||||
"//base/test:test_support",
|
||||
"//testing/gmock",
|
||||
"//testing/gtest",
|
||||
"//ui/base",
|
||||
"//ui/strings",
|
||||
]
|
||||
}
|
||||
|
||||
template("dist_zip") {
|
||||
_runtime_deps_target = "${target_name}__deps"
|
||||
_runtime_deps_file =
|
||||
|
||||
11
DEPS
11
DEPS
@@ -2,9 +2,9 @@ gclient_gn_args_from = 'src'
|
||||
|
||||
vars = {
|
||||
'chromium_version':
|
||||
'119.0.6019.2',
|
||||
'122.0.6261.112',
|
||||
'node_version':
|
||||
'v18.18.0',
|
||||
'v20.9.0',
|
||||
'nan_version':
|
||||
'e14bdcd1f72d62bca1d541b66da43130384ec213',
|
||||
'squirrel.mac_version':
|
||||
@@ -13,6 +13,8 @@ vars = {
|
||||
'74ab5baccc6f7202c8ac69a8d1e152c29dc1ea76',
|
||||
'mantle_version':
|
||||
'78d3966b3c331292ea29ec38661b25df0a245948',
|
||||
'engflow_reclient_configs_version':
|
||||
'955335c30a752e9ef7bff375baab5e0819b6c00d',
|
||||
|
||||
'pyyaml_version': '3.12',
|
||||
|
||||
@@ -23,6 +25,7 @@ vars = {
|
||||
'squirrel_git': 'https://github.com/Squirrel',
|
||||
'reactiveobjc_git': 'https://github.com/ReactiveCocoa',
|
||||
'mantle_git': 'https://github.com/Mantle',
|
||||
'engflow_git': 'https://github.com/EngFlow',
|
||||
|
||||
# The path of the sysroots.json file.
|
||||
'sysroots_json_path': 'electron/script/sysroots.json',
|
||||
@@ -102,6 +105,10 @@ deps = {
|
||||
'src/third_party/squirrel.mac/vendor/Mantle': {
|
||||
'url': Var("mantle_git") + '/Mantle.git@' + Var("mantle_version"),
|
||||
'condition': 'process_deps',
|
||||
},
|
||||
'src/third_party/engflow-reclient-configs': {
|
||||
'url': Var("engflow_git") + '/reclient-configs.git@' + Var("engflow_reclient_configs_version"),
|
||||
'condition': 'process_deps'
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
10
README.md
10
README.md
@@ -9,8 +9,8 @@ View these docs in other languages on our [Crowdin](https://crowdin.com/project/
|
||||
|
||||
The Electron framework lets you write cross-platform desktop applications
|
||||
using JavaScript, HTML and CSS. It is based on [Node.js](https://nodejs.org/) and
|
||||
[Chromium](https://www.chromium.org) and is used by the [Atom
|
||||
editor](https://github.com/atom/atom) and many other [apps](https://electronjs.org/apps).
|
||||
[Chromium](https://www.chromium.org) and is used by the [Visual Studio
|
||||
Code](https://github.com/Microsoft/vscode/) and many other [apps](https://electronjs.org/apps).
|
||||
|
||||
Follow [@electronjs](https://twitter.com/electronjs) on Twitter for important
|
||||
announcements.
|
||||
@@ -41,9 +41,9 @@ Each Electron release provides binaries for macOS, Windows, and Linux.
|
||||
* macOS (Catalina and up): Electron provides 64-bit Intel and ARM binaries for macOS. Apple Silicon support was added in Electron 11.
|
||||
* Windows (Windows 10 and up): Electron provides `ia32` (`x86`), `x64` (`amd64`), and `arm64` binaries for Windows. Windows on ARM support was added in Electron 5.0.8. Support for Windows 7, 8 and 8.1 was [removed in Electron 23, in line with Chromium's Windows deprecation policy](https://www.electronjs.org/blog/windows-7-to-8-1-deprecation-notice).
|
||||
* Linux: The prebuilt binaries of Electron are built on Ubuntu 20.04. They have also been verified to work on:
|
||||
* Ubuntu 14.04 and newer
|
||||
* Fedora 24 and newer
|
||||
* Debian 8 and newer
|
||||
* Ubuntu 18.04 and newer
|
||||
* Fedora 32 and newer
|
||||
* Debian 10 and newer
|
||||
|
||||
## Quick start & Electron Fiddle
|
||||
|
||||
|
||||
@@ -6,14 +6,13 @@
|
||||
|
||||
version: 1.0.{build}
|
||||
build_cloud: electronhq-16-core
|
||||
image: e-112.0.5607.0-vs2022
|
||||
image: base-bake-image
|
||||
environment:
|
||||
GIT_CACHE_PATH: C:\Users\appveyor\libcc_cache
|
||||
ELECTRON_OUT_DIR: Default
|
||||
ELECTRON_ENABLE_STACK_DUMPING: 1
|
||||
MOCHA_REPORTER: mocha-multi-reporters
|
||||
MOCHA_MULTI_REPORTERS: mocha-appveyor-reporter, tap
|
||||
GOMA_FALLBACK_ON_AUTH_FAILURE: true
|
||||
DEPOT_TOOLS_WIN_TOOLCHAIN: 0
|
||||
PYTHONIOENCODING: UTF-8
|
||||
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
|
||||
version: 1.0.{build}
|
||||
build_cloud: electronhq-16-core
|
||||
image: e-119.0.6019.2
|
||||
image: e-121.0.6116.0
|
||||
environment:
|
||||
GIT_CACHE_PATH: C:\Users\appveyor\libcc_cache
|
||||
ELECTRON_OUT_DIR: Default
|
||||
@@ -37,7 +37,6 @@ environment:
|
||||
ELECTRON_ALSO_LOG_TO_STDERR: 1
|
||||
MOCHA_REPORTER: mocha-multi-reporters
|
||||
MOCHA_MULTI_REPORTERS: "@marshallofsound/mocha-appveyor-reporter, tap"
|
||||
GOMA_FALLBACK_ON_AUTH_FAILURE: true
|
||||
DEPOT_TOOLS_WIN_TOOLCHAIN: 1
|
||||
DEPOT_TOOLS_WIN_TOOLCHAIN_BASE_URL: "https://dev-cdn.electronjs.org/windows-toolchains/_"
|
||||
GYP_MSVS_HASH_27370823e7: 28622d16b1
|
||||
@@ -101,31 +100,22 @@ for:
|
||||
if (Test-Path -Path "$pwd\src\electron") {
|
||||
Remove-Item -Recurse -Force $pwd\src\electron
|
||||
}
|
||||
- ps: >-
|
||||
if (Test-Path 'env:RAW_GOMA_AUTH') {
|
||||
$env:GOMA_OAUTH2_CONFIG_FILE = "$pwd\.goma_oauth2_config"
|
||||
$env:RAW_GOMA_AUTH | Set-Content $env:GOMA_OAUTH2_CONFIG_FILE
|
||||
}
|
||||
- git clone https://github.com/electron/build-tools.git
|
||||
- cd build-tools
|
||||
- npm install
|
||||
- npx yarn --ignore-engines
|
||||
- mkdir third_party
|
||||
- ps: >-
|
||||
node -e "require('./src/utils/goma.js').downloadAndPrepare({ gomaOneForAll: true })"
|
||||
- ps: $env:GN_GOMA_FILE = node -e "console.log(require('./src/utils/goma.js').gnFilePath)"
|
||||
- ps: $env:LOCAL_GOMA_DIR = node -e "console.log(require('./src/utils/goma.js').dir)"
|
||||
- cd ..\..
|
||||
- ps: .\src\electron\script\start-goma.ps1 -gomaDir $env:LOCAL_GOMA_DIR
|
||||
node -e "require('./src/utils/reclient.js').downloadAndPrepare({})"
|
||||
- ps: $env:RECLIENT_HELPER = node -p "require('./src/utils/reclient.js').helperPath({})"
|
||||
- ps: >-
|
||||
if (Test-Path 'env:RAW_GOMA_AUTH') {
|
||||
$goma_login = python3 $env:LOCAL_GOMA_DIR\goma_auth.py info
|
||||
if ($goma_login -eq 'Login as Fermi Planck') {
|
||||
Write-warning "Goma authentication is correct";
|
||||
} else {
|
||||
Write-warning "WARNING!!!!!! Goma authentication is incorrect; please update Goma auth token.";
|
||||
$host.SetShouldExit(1)
|
||||
}
|
||||
}
|
||||
& $env:RECLIENT_HELPER login
|
||||
- ps: >-
|
||||
$env:RBE_service = node -e "console.log(require('./src/utils/reclient.js').serviceAddress)"
|
||||
- ps: >-
|
||||
$env:RBE_experimental_credentials_helper = $env:RECLIENT_HELPER
|
||||
- ps: >-
|
||||
$env:RBE_experimental_credentials_helper_args = "print"
|
||||
- cd ..\..
|
||||
- ps: $env:CHROMIUM_BUILDTOOLS_PATH="$pwd\src\buildtools"
|
||||
- ps: >-
|
||||
if ($env:GN_CONFIG -ne 'release') {
|
||||
@@ -147,37 +137,36 @@ for:
|
||||
- cd src
|
||||
- ps: $env:PATH="$pwd\third_party\ninja;$env:PATH"
|
||||
- set BUILD_CONFIG_PATH=//electron/build/args/%GN_CONFIG%.gn
|
||||
- gn gen out/Default "--args=import(\"%BUILD_CONFIG_PATH%\") import(\"%GN_GOMA_FILE%\") %GN_EXTRA_ARGS% "
|
||||
- gn gen out/Default "--args=import(\"%BUILD_CONFIG_PATH%\") use_remoteexec=true %GN_EXTRA_ARGS% "
|
||||
- gn check out/Default //electron:electron_lib
|
||||
- gn check out/Default //electron:electron_app
|
||||
- gn check out/Default //electron/shell/common/api:mojo
|
||||
- if DEFINED GN_GOMA_FILE (ninja -j 300 -C out/Default electron:electron_app) else (ninja -C out/Default electron:electron_app)
|
||||
- if DEFINED ELECTRON_RBE_JWT (autoninja -j 300 -C out/Default electron:electron_app) else (autoninja -C out/Default electron:electron_app)
|
||||
- if "%GN_CONFIG%"=="testing" ( python C:\depot_tools\post_build_ninja_summary.py -C out\Default )
|
||||
- gn gen out/ffmpeg "--args=import(\"//electron/build/args/ffmpeg.gn\") %GN_EXTRA_ARGS%"
|
||||
- ninja -C out/ffmpeg electron:electron_ffmpeg_zip
|
||||
- ninja -C out/Default electron:electron_dist_zip
|
||||
- ninja -C out/Default shell_browser_ui_unittests
|
||||
- gn gen out/ffmpeg "--args=import(\"//electron/build/args/ffmpeg.gn\") use_remoteexec=true %GN_EXTRA_ARGS%"
|
||||
- autoninja -C out/ffmpeg electron:electron_ffmpeg_zip
|
||||
- autoninja -C out/Default electron:electron_dist_zip
|
||||
- gn desc out/Default v8:run_mksnapshot_default args > out/Default/default_mksnapshot_args
|
||||
# Remove unused args from mksnapshot_args
|
||||
- ps: >-
|
||||
Get-Content out/Default/default_mksnapshot_args | Where-Object { -not $_.Contains('--turbo-profiling-input') -And -not $_.Contains('builtins-pgo') } | Set-Content out/Default/mksnapshot_args
|
||||
- ninja -C out/Default electron:electron_mksnapshot_zip
|
||||
Get-Content out/Default/default_mksnapshot_args | Where-Object { -not $_.Contains('--turbo-profiling-input') -And -not $_.Contains('builtins-pgo') -And -not $_.Contains('The gn arg use_goma=true') } | Set-Content out/Default/mksnapshot_args
|
||||
- autoninja -C out/Default electron:electron_mksnapshot_zip
|
||||
- cd out\Default
|
||||
- 7z a mksnapshot.zip mksnapshot_args gen\v8\embedded.S
|
||||
- cd ..\..
|
||||
- ninja -C out/Default electron:hunspell_dictionaries_zip
|
||||
- ninja -C out/Default electron:electron_chromedriver_zip
|
||||
- ninja -C out/Default electron:node_headers
|
||||
- python3 %LOCAL_GOMA_DIR%\goma_ctl.py stat
|
||||
- autoninja -C out/Default electron:hunspell_dictionaries_zip
|
||||
- autoninja -C out/Default electron:electron_chromedriver_zip
|
||||
- autoninja -C out/Default electron:node_headers
|
||||
- ps: >-
|
||||
Get-CimInstance -Namespace root\cimv2 -Class Win32_product | Select vendor, description, @{l='install_location';e='InstallLocation'}, @{l='install_date';e='InstallDate'}, @{l='install_date_2';e='InstallDate2'}, caption, version, name, @{l='sku_number';e='SKUNumber'} | ConvertTo-Json | Out-File -Encoding utf8 -FilePath .\installed_software.json
|
||||
- python3 electron/build/profile_toolchain.py --output-json=out/Default/windows_toolchain_profile.json
|
||||
- 7z a node_headers.zip out\Default\gen\node_headers
|
||||
- 7z a nan.zip third_party\nan
|
||||
- ps: >-
|
||||
if ($env:GN_CONFIG -eq 'release') {
|
||||
# Needed for msdia140.dll on 64-bit windows
|
||||
$env:Path += ";$pwd\third_party\llvm-build\Release+Asserts\bin"
|
||||
ninja -C out/Default electron:electron_symbols
|
||||
autoninja -C out/Default electron:electron_symbols
|
||||
}
|
||||
- ps: >-
|
||||
if ($env:GN_CONFIG -eq 'release') {
|
||||
@@ -188,20 +177,28 @@ for:
|
||||
# built on CI.
|
||||
7z a pdb.zip out\Default\*.pdb
|
||||
}
|
||||
- python3 electron/script/zip_manifests/check-zip-manifest.py out/Default/dist.zip electron/script/zip_manifests/dist_zip.win.%TARGET_ARCH%.manifest
|
||||
- ps: |
|
||||
$manifest_file = "electron/script/zip_manifests/dist_zip.win.$env:TARGET_ARCH.manifest"
|
||||
python3 electron/script/zip_manifests/check-zip-manifest.py out/Default/dist.zip $manifest_file
|
||||
if ($LASTEXITCODE -ne 0) {
|
||||
throw "Zip contains files not listed in the manifest $manifest_file"
|
||||
}
|
||||
- ps: |
|
||||
cd C:\projects\src
|
||||
$missing_artifacts = $false
|
||||
if ($env:SHOULD_SKIP_ARTIFACT_VALIDATION -eq 'true') {
|
||||
Write-warning "Skipping artifact validation for doc-only $env:APPVEYOR_PROJECT_NAME"
|
||||
} else {
|
||||
$artifacts_to_validate = 'dist.zip','windows_toolchain_profile.json','shell_browser_ui_unittests.exe','chromedriver.zip','ffmpeg.zip','node_headers.zip','mksnapshot.zip','electron.lib','hunspell_dictionaries.zip'
|
||||
$artifacts_to_validate = 'dist.zip','windows_toolchain_profile.json','chromedriver.zip','ffmpeg.zip','node_headers.zip','mksnapshot.zip','electron.lib','hunspell_dictionaries.zip','nan.zip'
|
||||
foreach($artifact_name in $artifacts_to_validate) {
|
||||
if ($artifact_name -eq 'ffmpeg.zip') {
|
||||
$artifact_file = "out\ffmpeg\ffmpeg.zip"
|
||||
} elseif (
|
||||
$artifact_name -eq 'node_headers.zip') {
|
||||
$artifact_file = $artifact_name
|
||||
} elseif (
|
||||
$artifact_name -eq 'nan.zip') {
|
||||
$artifact_file = $artifact_name
|
||||
} else {
|
||||
$artifact_file = "out\Default\$artifact_name"
|
||||
}
|
||||
@@ -233,10 +230,10 @@ for:
|
||||
- cd C:\projects\src
|
||||
- if exist out\Default\windows_toolchain_profile.json ( appveyor-retry appveyor PushArtifact out\Default\windows_toolchain_profile.json )
|
||||
- if exist out\Default\dist.zip (appveyor-retry appveyor PushArtifact out\Default\dist.zip)
|
||||
- if exist out\Default\shell_browser_ui_unittests.exe (appveyor-retry appveyor PushArtifact out\Default\shell_browser_ui_unittests.exe)
|
||||
- if exist out\Default\chromedriver.zip (appveyor-retry appveyor PushArtifact out\Default\chromedriver.zip)
|
||||
- if exist out\ffmpeg\ffmpeg.zip (appveyor-retry appveyor PushArtifact out\ffmpeg\ffmpeg.zip)
|
||||
- if exist node_headers.zip (appveyor-retry appveyor PushArtifact node_headers.zip)
|
||||
- if exist nan.zip (appveyor-retry appveyor PushArtifact nan.zip)
|
||||
- if exist out\Default\mksnapshot.zip (appveyor-retry appveyor PushArtifact out\Default\mksnapshot.zip)
|
||||
- if exist out\Default\hunspell_dictionaries.zip (appveyor-retry appveyor PushArtifact out\Default\hunspell_dictionaries.zip)
|
||||
- if exist out\Default\electron.lib (appveyor-retry appveyor PushArtifact out\Default\electron.lib)
|
||||
@@ -272,12 +269,12 @@ for:
|
||||
# Download build artifacts
|
||||
$apiUrl = 'https://ci.appveyor.com/api'
|
||||
$build_info = Invoke-RestMethod -Method Get -Uri "$apiUrl/projects/$env:APPVEYOR_ACCOUNT_NAME/$env:APPVEYOR_PROJECT_SLUG/builds/$env:APPVEYOR_BUILD_ID"
|
||||
$artifacts_to_download = @('dist.zip','ffmpeg.zip','node_headers.zip','electron.lib')
|
||||
$artifacts_to_download = @('dist.zip','ffmpeg.zip','node_headers.zip','electron.lib', 'nan.zip')
|
||||
foreach ($job in $build_info.build.jobs) {
|
||||
if ($job.name -eq "Build Arm on X64 Windows") {
|
||||
$jobId = $job.jobId
|
||||
foreach($artifact_name in $artifacts_to_download) {
|
||||
if ($artifact_name -eq 'shell_browser_ui_unittests.exe' -Or $artifact_name -eq 'electron.lib') {
|
||||
if ($artifact_name -eq 'electron.lib') {
|
||||
$outfile = "src\out\Default\$artifact_name"
|
||||
} else {
|
||||
$outfile = $artifact_name
|
||||
@@ -296,6 +293,7 @@ for:
|
||||
}
|
||||
- ps: 7z x -y -osrc\out\ffmpeg ffmpeg.zip
|
||||
- ps: 7z x -y -osrc node_headers.zip
|
||||
- ps: 7z x -y -osrc nan.zip
|
||||
|
||||
test_script:
|
||||
# Workaround for https://github.com/appveyor/ci/issues/2420
|
||||
|
||||
73
appveyor.yml
73
appveyor.yml
@@ -29,7 +29,7 @@
|
||||
|
||||
version: 1.0.{build}
|
||||
build_cloud: electronhq-16-core
|
||||
image: e-119.0.6019.2
|
||||
image: e-121.0.6116.0
|
||||
environment:
|
||||
GIT_CACHE_PATH: C:\Users\appveyor\libcc_cache
|
||||
ELECTRON_OUT_DIR: Default
|
||||
@@ -37,7 +37,6 @@ environment:
|
||||
ELECTRON_ALSO_LOG_TO_STDERR: 1
|
||||
MOCHA_REPORTER: mocha-multi-reporters
|
||||
MOCHA_MULTI_REPORTERS: "@marshallofsound/mocha-appveyor-reporter, tap"
|
||||
GOMA_FALLBACK_ON_AUTH_FAILURE: true
|
||||
DEPOT_TOOLS_WIN_TOOLCHAIN: 1
|
||||
DEPOT_TOOLS_WIN_TOOLCHAIN_BASE_URL: "https://dev-cdn.electronjs.org/windows-toolchains/_"
|
||||
GYP_MSVS_HASH_27370823e7: 28622d16b1
|
||||
@@ -99,31 +98,22 @@ for:
|
||||
if (Test-Path -Path "$pwd\src\electron") {
|
||||
Remove-Item -Recurse -Force $pwd\src\electron
|
||||
}
|
||||
- ps: >-
|
||||
if (Test-Path 'env:RAW_GOMA_AUTH') {
|
||||
$env:GOMA_OAUTH2_CONFIG_FILE = "$pwd\.goma_oauth2_config"
|
||||
$env:RAW_GOMA_AUTH | Set-Content $env:GOMA_OAUTH2_CONFIG_FILE
|
||||
}
|
||||
- git clone https://github.com/electron/build-tools.git
|
||||
- cd build-tools
|
||||
- npm install
|
||||
- npx yarn --ignore-engines
|
||||
- mkdir third_party
|
||||
- ps: >-
|
||||
node -e "require('./src/utils/goma.js').downloadAndPrepare({ gomaOneForAll: true })"
|
||||
- ps: $env:GN_GOMA_FILE = node -e "console.log(require('./src/utils/goma.js').gnFilePath)"
|
||||
- ps: $env:LOCAL_GOMA_DIR = node -e "console.log(require('./src/utils/goma.js').dir)"
|
||||
- cd ..\..
|
||||
- ps: .\src\electron\script\start-goma.ps1 -gomaDir $env:LOCAL_GOMA_DIR
|
||||
node -e "require('./src/utils/reclient.js').downloadAndPrepare({})"
|
||||
- ps: $env:RECLIENT_HELPER = node -p "require('./src/utils/reclient.js').helperPath({})"
|
||||
- ps: >-
|
||||
if (Test-Path 'env:RAW_GOMA_AUTH') {
|
||||
$goma_login = python3 $env:LOCAL_GOMA_DIR\goma_auth.py info
|
||||
if ($goma_login -eq 'Login as Fermi Planck') {
|
||||
Write-warning "Goma authentication is correct";
|
||||
} else {
|
||||
Write-warning "WARNING!!!!!! Goma authentication is incorrect; please update Goma auth token.";
|
||||
$host.SetShouldExit(1)
|
||||
}
|
||||
}
|
||||
& $env:RECLIENT_HELPER login
|
||||
- ps: >-
|
||||
$env:RBE_service = node -e "console.log(require('./src/utils/reclient.js').serviceAddress)"
|
||||
- ps: >-
|
||||
$env:RBE_experimental_credentials_helper = $env:RECLIENT_HELPER
|
||||
- ps: >-
|
||||
$env:RBE_experimental_credentials_helper_args = "print"
|
||||
- cd ..\..
|
||||
- ps: $env:CHROMIUM_BUILDTOOLS_PATH="$pwd\src\buildtools"
|
||||
- ps: >-
|
||||
if ($env:GN_CONFIG -ne 'release') {
|
||||
@@ -145,28 +135,26 @@ for:
|
||||
- cd src
|
||||
- ps: $env:PATH="$pwd\third_party\ninja;$env:PATH"
|
||||
- set BUILD_CONFIG_PATH=//electron/build/args/%GN_CONFIG%.gn
|
||||
- gn gen out/Default "--args=import(\"%BUILD_CONFIG_PATH%\") import(\"%GN_GOMA_FILE%\") %GN_EXTRA_ARGS% "
|
||||
- gn gen out/Default "--args=import(\"%BUILD_CONFIG_PATH%\") use_remoteexec=true %GN_EXTRA_ARGS% "
|
||||
- gn check out/Default //electron:electron_lib
|
||||
- gn check out/Default //electron:electron_app
|
||||
- gn check out/Default //electron/shell/common/api:mojo
|
||||
- if DEFINED GN_GOMA_FILE (ninja -j 300 -C out/Default electron:electron_app) else (ninja -C out/Default electron:electron_app)
|
||||
- if DEFINED ELECTRON_RBE_JWT (autoninja -j 300 -C out/Default electron:electron_app) else (autoninja -C out/Default electron:electron_app)
|
||||
- if "%GN_CONFIG%"=="testing" ( python C:\depot_tools\post_build_ninja_summary.py -C out\Default )
|
||||
- gn gen out/ffmpeg "--args=import(\"//electron/build/args/ffmpeg.gn\") %GN_EXTRA_ARGS%"
|
||||
- ninja -C out/ffmpeg electron:electron_ffmpeg_zip
|
||||
- ninja -C out/Default electron:electron_dist_zip
|
||||
- ninja -C out/Default shell_browser_ui_unittests
|
||||
- gn gen out/ffmpeg "--args=import(\"//electron/build/args/ffmpeg.gn\") use_remoteexec=true %GN_EXTRA_ARGS%"
|
||||
- autoninja -C out/ffmpeg electron:electron_ffmpeg_zip
|
||||
- autoninja -C out/Default electron:electron_dist_zip
|
||||
- gn desc out/Default v8:run_mksnapshot_default args > out/Default/default_mksnapshot_args
|
||||
# Remove unused args from mksnapshot_args
|
||||
- ps: >-
|
||||
Get-Content out/Default/default_mksnapshot_args | Where-Object { -not $_.Contains('--turbo-profiling-input') -And -not $_.Contains('builtins-pgo') } | Set-Content out/Default/mksnapshot_args
|
||||
- ninja -C out/Default electron:electron_mksnapshot_zip
|
||||
Get-Content out/Default/default_mksnapshot_args | Where-Object { -not $_.Contains('--turbo-profiling-input') -And -not $_.Contains('builtins-pgo') -And -not $_.Contains('The gn arg use_goma=true') } | Set-Content out/Default/mksnapshot_args
|
||||
- autoninja -C out/Default electron:electron_mksnapshot_zip
|
||||
- cd out\Default
|
||||
- 7z a mksnapshot.zip mksnapshot_args gen\v8\embedded.S
|
||||
- cd ..\..
|
||||
- ninja -C out/Default electron:hunspell_dictionaries_zip
|
||||
- ninja -C out/Default electron:electron_chromedriver_zip
|
||||
- ninja -C out/Default electron:node_headers
|
||||
- python3 %LOCAL_GOMA_DIR%\goma_ctl.py stat
|
||||
- autoninja -C out/Default electron:hunspell_dictionaries_zip
|
||||
- autoninja -C out/Default electron:electron_chromedriver_zip
|
||||
- autoninja -C out/Default electron:node_headers
|
||||
- ps: >-
|
||||
Get-CimInstance -Namespace root\cimv2 -Class Win32_product | Select vendor, description, @{l='install_location';e='InstallLocation'}, @{l='install_date';e='InstallDate'}, @{l='install_date_2';e='InstallDate2'}, caption, version, name, @{l='sku_number';e='SKUNumber'} | ConvertTo-Json | Out-File -Encoding utf8 -FilePath .\installed_software.json
|
||||
- python3 electron/build/profile_toolchain.py --output-json=out/Default/windows_toolchain_profile.json
|
||||
@@ -175,7 +163,7 @@ for:
|
||||
if ($env:GN_CONFIG -eq 'release') {
|
||||
# Needed for msdia140.dll on 64-bit windows
|
||||
$env:Path += ";$pwd\third_party\llvm-build\Release+Asserts\bin"
|
||||
ninja -C out/Default electron:electron_symbols
|
||||
autoninja -C out/Default electron:electron_symbols
|
||||
}
|
||||
- ps: >-
|
||||
if ($env:GN_CONFIG -eq 'release') {
|
||||
@@ -186,14 +174,19 @@ for:
|
||||
# built on CI.
|
||||
7z a pdb.zip out\Default\*.pdb
|
||||
}
|
||||
- python3 electron/script/zip_manifests/check-zip-manifest.py out/Default/dist.zip electron/script/zip_manifests/dist_zip.win.%TARGET_ARCH%.manifest
|
||||
- ps: |
|
||||
$manifest_file = "electron/script/zip_manifests/dist_zip.win.$env:TARGET_ARCH.manifest"
|
||||
python3 electron/script/zip_manifests/check-zip-manifest.py out/Default/dist.zip $manifest_file
|
||||
if ($LASTEXITCODE -ne 0) {
|
||||
throw "Zip contains files not listed in the manifest $manifest_file"
|
||||
}
|
||||
- ps: |
|
||||
cd C:\projects\src
|
||||
$missing_artifacts = $false
|
||||
if ($env:SHOULD_SKIP_ARTIFACT_VALIDATION -eq 'true') {
|
||||
Write-warning "Skipping artifact validation for doc-only $env:APPVEYOR_PROJECT_NAME"
|
||||
} else {
|
||||
$artifacts_to_validate = 'dist.zip','windows_toolchain_profile.json','shell_browser_ui_unittests.exe','chromedriver.zip','ffmpeg.zip','node_headers.zip','mksnapshot.zip','electron.lib','hunspell_dictionaries.zip'
|
||||
$artifacts_to_validate = 'dist.zip','windows_toolchain_profile.json','chromedriver.zip','ffmpeg.zip','node_headers.zip','mksnapshot.zip','electron.lib','hunspell_dictionaries.zip'
|
||||
foreach($artifact_name in $artifacts_to_validate) {
|
||||
if ($artifact_name -eq 'ffmpeg.zip') {
|
||||
$artifact_file = "out\ffmpeg\ffmpeg.zip"
|
||||
@@ -231,7 +224,6 @@ for:
|
||||
- cd C:\projects\src
|
||||
- if exist out\Default\windows_toolchain_profile.json ( appveyor-retry appveyor PushArtifact out\Default\windows_toolchain_profile.json )
|
||||
- if exist out\Default\dist.zip (appveyor-retry appveyor PushArtifact out\Default\dist.zip)
|
||||
- if exist out\Default\shell_browser_ui_unittests.exe (appveyor-retry appveyor PushArtifact out\Default\shell_browser_ui_unittests.exe)
|
||||
- if exist out\Default\chromedriver.zip (appveyor-retry appveyor PushArtifact out\Default\chromedriver.zip)
|
||||
- if exist out\ffmpeg\ffmpeg.zip (appveyor-retry appveyor PushArtifact out\ffmpeg\ffmpeg.zip)
|
||||
- if exist node_headers.zip (appveyor-retry appveyor PushArtifact node_headers.zip)
|
||||
@@ -268,12 +260,12 @@ for:
|
||||
# Download build artifacts
|
||||
$apiUrl = 'https://ci.appveyor.com/api'
|
||||
$build_info = Invoke-RestMethod -Method Get -Uri "$apiUrl/projects/$env:APPVEYOR_ACCOUNT_NAME/$env:APPVEYOR_PROJECT_SLUG/builds/$env:APPVEYOR_BUILD_ID"
|
||||
$artifacts_to_download = @('dist.zip','shell_browser_ui_unittests.exe','chromedriver.zip','ffmpeg.zip','node_headers.zip','mksnapshot.zip','electron.lib')
|
||||
$artifacts_to_download = @('dist.zip','chromedriver.zip','ffmpeg.zip','node_headers.zip','mksnapshot.zip','electron.lib')
|
||||
foreach ($job in $build_info.build.jobs) {
|
||||
if ($job.name -eq "Build") {
|
||||
$jobId = $job.jobId
|
||||
foreach($artifact_name in $artifacts_to_download) {
|
||||
if ($artifact_name -eq 'shell_browser_ui_unittests.exe' -Or $artifact_name -eq 'electron.lib') {
|
||||
if ($artifact_name -eq 'electron.lib') {
|
||||
$outfile = "src\out\Default\$artifact_name"
|
||||
} else {
|
||||
$outfile = $artifact_name
|
||||
@@ -307,7 +299,6 @@ for:
|
||||
$env:npm_config_arch = "ia32"
|
||||
}
|
||||
- echo Running main test suite & node script/yarn test -- --trace-uncaught --runners=main --enable-logging=file --log-file=%cd%\electron.log
|
||||
- echo Running native test suite & node script/yarn test -- --trace-uncaught --runners=native --enable-logging=file --log-file=%cd%\electron.log
|
||||
- cd ..
|
||||
- echo Verifying non proprietary ffmpeg & python electron\script\verify-ffmpeg.py --build-dir out\Default --source-root %cd% --ffmpeg-path out\ffmpeg
|
||||
- echo "About to verify mksnapshot"
|
||||
|
||||
@@ -2,7 +2,7 @@ is_electron_build = true
|
||||
root_extra_deps = [ "//electron" ]
|
||||
|
||||
# Registry of NMVs --> https://github.com/nodejs/node/blob/main/doc/abi_version_registry.json
|
||||
node_module_version = 118
|
||||
node_module_version = 121
|
||||
|
||||
v8_promise_internal_field_count = 1
|
||||
v8_embedder_string = "-electron.0"
|
||||
@@ -24,6 +24,10 @@ enable_printing = true
|
||||
angle_enable_vulkan_validation_layers = false
|
||||
dawn_enable_vulkan_validation_layers = false
|
||||
|
||||
# Removes dxc dll's that are only used experimentally.
|
||||
# See https://bugs.chromium.org/p/chromium/issues/detail?id=1474897
|
||||
dawn_use_built_dxc = false
|
||||
|
||||
# These are disabled because they cause the zip manifest to differ between
|
||||
# testing and release builds.
|
||||
# See https://chromium-review.googlesource.com/c/chromium/src/+/2774898.
|
||||
@@ -60,3 +64,6 @@ enable_dangling_raw_ptr_checks = false
|
||||
# This flag speeds up the performance of fork/execve on linux systems.
|
||||
# Ref: https://chromium-review.googlesource.com/c/v8/v8/+/4602858
|
||||
v8_enable_private_mapping_fork_optimization = true
|
||||
|
||||
# Expose public V8 symbols for native modules.
|
||||
v8_expose_public_symbols = true
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
from __future__ import print_function
|
||||
#!/usr/bin/env python3
|
||||
|
||||
import collections
|
||||
import os
|
||||
|
||||
@@ -32,6 +32,13 @@ extern const volatile char kFuseWire[];
|
||||
|
||||
TEMPLATE_CC = """
|
||||
#include "electron/fuses.h"
|
||||
#include "base/dcheck_is_on.h"
|
||||
|
||||
#if DCHECK_IS_ON()
|
||||
#include "base/command_line.h"
|
||||
#include "base/strings/string_util.h"
|
||||
#include <string>
|
||||
#endif
|
||||
|
||||
namespace electron::fuses {
|
||||
|
||||
@@ -66,9 +73,20 @@ for fuse in fuses:
|
||||
getters_h += "FUSE_EXPORT bool Is{name}Enabled();\n".replace("{name}", name)
|
||||
getters_cc += """
|
||||
bool Is{name}Enabled() {
|
||||
#if DCHECK_IS_ON()
|
||||
// RunAsNode is checked so early that base::CommandLine isn't yet
|
||||
// initialized, so guard here to avoid a CHECK.
|
||||
if (base::CommandLine::InitializedForCurrentProcess()) {
|
||||
base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
|
||||
if (command_line->HasSwitch("{switch_name}")) {
|
||||
std::string switch_value = command_line->GetSwitchValueASCII("{switch_name}");
|
||||
return switch_value == "1";
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return kFuseWire[{index}] == '1';
|
||||
}
|
||||
""".replace("{name}", name).replace("{index}", str(index))
|
||||
""".replace("{name}", name).replace("{switch_name}", f"set-fuse-{fuse.lower()}").replace("{index}", str(index))
|
||||
|
||||
def c_hex(n):
|
||||
s = hex(n)[2:]
|
||||
|
||||
@@ -8,5 +8,6 @@
|
||||
"node_cli_inspect": "1",
|
||||
"embedded_asar_integrity_validation": "0",
|
||||
"only_load_app_from_asar": "0",
|
||||
"load_browser_process_specific_v8_snapshot": "0"
|
||||
"load_browser_process_specific_v8_snapshot": "0",
|
||||
"grant_file_protocol_extra_privileges": "1"
|
||||
}
|
||||
|
||||
30
build/js2c.py
Executable file → Normal file
30
build/js2c.py
Executable file → Normal file
@@ -4,32 +4,14 @@ import os
|
||||
import subprocess
|
||||
import sys
|
||||
|
||||
TEMPLATE = """
|
||||
#include "node_native_module.h"
|
||||
#include "node_internals.h"
|
||||
|
||||
namespace node::native_module {{
|
||||
|
||||
{definitions}
|
||||
|
||||
void NativeModuleLoader::LoadEmbedderJavaScriptSource() {{
|
||||
{initializers}
|
||||
}}
|
||||
|
||||
}} // namespace node::native_module
|
||||
"""
|
||||
|
||||
def main():
|
||||
node_path = os.path.abspath(sys.argv[1])
|
||||
natives = os.path.abspath(sys.argv[2])
|
||||
js_source_files = sys.argv[3:]
|
||||
js2c = sys.argv[1]
|
||||
root = sys.argv[2]
|
||||
natives = sys.argv[3]
|
||||
js_source_files = sys.argv[4:]
|
||||
|
||||
js2c = os.path.join(node_path, 'tools', 'js2c.py')
|
||||
subprocess.check_call(
|
||||
[sys.executable, js2c] +
|
||||
js_source_files +
|
||||
['--only-js', '--target', natives])
|
||||
|
||||
[js2c, natives] + js_source_files + ['--only-js', "--root", root])
|
||||
|
||||
if __name__ == '__main__':
|
||||
sys.exit(main())
|
||||
sys.exit(main())
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env python3
|
||||
from __future__ import print_function
|
||||
|
||||
import os
|
||||
import subprocess
|
||||
import sys
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
from __future__ import unicode_literals
|
||||
#!/usr/bin/env python3
|
||||
|
||||
import contextlib
|
||||
import sys
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
import sys
|
||||
import os
|
||||
import subprocess
|
||||
|
||||
def main(argv):
|
||||
cwd = argv[1]
|
||||
os.chdir(cwd)
|
||||
os.execv(sys.executable, [sys.executable] + argv[2:])
|
||||
os.chdir(argv[1])
|
||||
p = subprocess.Popen(argv[2:])
|
||||
return p.wait()
|
||||
|
||||
if __name__ == '__main__':
|
||||
main(sys.argv)
|
||||
sys.exit(main(sys.argv))
|
||||
|
||||
@@ -1,5 +0,0 @@
|
||||
module.exports = require('./webpack.config.base')({
|
||||
target: 'asar',
|
||||
alwaysHasNode: true,
|
||||
targetDeletesNodeGlobals: true
|
||||
});
|
||||
4
build/webpack/webpack.config.node.js
Normal file
4
build/webpack/webpack.config.node.js
Normal file
@@ -0,0 +1,4 @@
|
||||
module.exports = require('./webpack.config.base')({
|
||||
target: 'node',
|
||||
alwaysHasNode: true
|
||||
});
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env python3
|
||||
from __future__ import print_function
|
||||
|
||||
import os
|
||||
import subprocess
|
||||
import sys
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env python3
|
||||
from __future__ import print_function
|
||||
|
||||
import os
|
||||
import subprocess
|
||||
import sys
|
||||
|
||||
@@ -15,4 +15,15 @@ buildflag_header("buildflags") {
|
||||
"ENABLE_BUILTIN_SPELLCHECKER=$enable_builtin_spellchecker",
|
||||
"OVERRIDE_LOCATION_PROVIDER=$enable_fake_location_provider",
|
||||
]
|
||||
|
||||
if (electron_vendor_version != "") {
|
||||
result = string_split(electron_vendor_version, ":")
|
||||
flags += [
|
||||
"HAS_VENDOR_VERSION=true",
|
||||
"VENDOR_VERSION_NAME=\"${result[0]}\"",
|
||||
"VENDOR_VERSION_VALUE=\"${result[1]}\"",
|
||||
]
|
||||
} else {
|
||||
flags += [ "HAS_VENDOR_VERSION=false" ]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,4 +18,15 @@ declare_args() {
|
||||
|
||||
# Enable Spellchecker support
|
||||
enable_builtin_spellchecker = true
|
||||
|
||||
# The version of Electron.
|
||||
# Packagers and vendor builders should set this in gn args to avoid running
|
||||
# the script that reads git tag.
|
||||
override_electron_version = ""
|
||||
|
||||
# Define an extra item that will show in process.versions, the value must
|
||||
# be in the format of "key:value".
|
||||
# Packagers and vendor builders can set this in gn args to attach extra info
|
||||
# about the build in the binary.
|
||||
electron_vendor_version = ""
|
||||
}
|
||||
|
||||
@@ -31,6 +31,8 @@ static_library("chrome") {
|
||||
"//chrome/browser/devtools/devtools_file_system_indexer.cc",
|
||||
"//chrome/browser/devtools/devtools_file_system_indexer.h",
|
||||
"//chrome/browser/devtools/devtools_settings.h",
|
||||
"//chrome/browser/devtools/visual_logging.cc",
|
||||
"//chrome/browser/devtools/visual_logging.h",
|
||||
"//chrome/browser/extensions/global_shortcut_listener.cc",
|
||||
"//chrome/browser/extensions/global_shortcut_listener.h",
|
||||
"//chrome/browser/icon_loader.cc",
|
||||
@@ -57,8 +59,14 @@ static_library("chrome") {
|
||||
"//chrome/browser/net/proxy_service_factory.h",
|
||||
"//chrome/browser/picture_in_picture/picture_in_picture_bounds_cache.cc",
|
||||
"//chrome/browser/picture_in_picture/picture_in_picture_bounds_cache.h",
|
||||
"//chrome/browser/picture_in_picture/picture_in_picture_occlusion_tracker.cc",
|
||||
"//chrome/browser/picture_in_picture/picture_in_picture_occlusion_tracker.h",
|
||||
"//chrome/browser/picture_in_picture/picture_in_picture_occlusion_tracker_observer.cc",
|
||||
"//chrome/browser/picture_in_picture/picture_in_picture_occlusion_tracker_observer.h",
|
||||
"//chrome/browser/picture_in_picture/picture_in_picture_window_manager.cc",
|
||||
"//chrome/browser/picture_in_picture/picture_in_picture_window_manager.h",
|
||||
"//chrome/browser/picture_in_picture/scoped_picture_in_picture_occlusion_observation.cc",
|
||||
"//chrome/browser/picture_in_picture/scoped_picture_in_picture_occlusion_observation.h",
|
||||
"//chrome/browser/platform_util.cc",
|
||||
"//chrome/browser/platform_util.h",
|
||||
"//chrome/browser/predictors/preconnect_manager.cc",
|
||||
@@ -100,8 +108,6 @@ static_library("chrome") {
|
||||
"//chrome/browser/ui/ui_features.h",
|
||||
"//chrome/browser/ui/views/eye_dropper/eye_dropper.cc",
|
||||
"//chrome/browser/ui/views/eye_dropper/eye_dropper.h",
|
||||
"//chrome/browser/ui/views/eye_dropper/eye_dropper_view.cc",
|
||||
"//chrome/browser/ui/views/eye_dropper/eye_dropper_view.h",
|
||||
"//chrome/browser/ui/views/overlay/back_to_tab_label_button.cc",
|
||||
"//chrome/browser/ui/views/overlay/close_image_button.cc",
|
||||
"//chrome/browser/ui/views/overlay/close_image_button.h",
|
||||
@@ -156,15 +162,6 @@ static_library("chrome") {
|
||||
sources += [ "//chrome/browser/media/webrtc/window_icon_util_ozone.cc" ]
|
||||
}
|
||||
|
||||
if (use_aura) {
|
||||
sources += [
|
||||
"//chrome/browser/platform_util_aura.cc",
|
||||
"//chrome/browser/ui/views/eye_dropper/eye_dropper_view_aura.cc",
|
||||
"//ui/views/native_window_tracker_aura.cc",
|
||||
"//ui/views/native_window_tracker_aura.h",
|
||||
]
|
||||
}
|
||||
|
||||
public_deps = [
|
||||
"//chrome/browser:dev_ui_browser_resources",
|
||||
"//chrome/browser/resources/accessibility:resources",
|
||||
@@ -189,6 +186,16 @@ static_library("chrome") {
|
||||
"//ui/views/controls/webview",
|
||||
]
|
||||
|
||||
if (use_aura) {
|
||||
sources += [
|
||||
"//chrome/browser/platform_util_aura.cc",
|
||||
"//chrome/browser/ui/views/eye_dropper/eye_dropper_aura.cc",
|
||||
"//ui/views/native_window_tracker_aura.cc",
|
||||
"//ui/views/native_window_tracker_aura.h",
|
||||
]
|
||||
deps += [ "//components/eye_dropper" ]
|
||||
}
|
||||
|
||||
if (is_linux) {
|
||||
sources += [ "//chrome/browser/icon_loader_auralinux.cc" ]
|
||||
if (use_ozone) {
|
||||
@@ -204,6 +211,10 @@ static_library("chrome") {
|
||||
"//chrome/browser/ui/views/status_icons/status_icon_linux_dbus.cc",
|
||||
"//chrome/browser/ui/views/status_icons/status_icon_linux_dbus.h",
|
||||
]
|
||||
sources += [
|
||||
"//chrome/browser/ui/views/dark_mode_manager_linux.cc",
|
||||
"//chrome/browser/ui/views/dark_mode_manager_linux.h",
|
||||
]
|
||||
public_deps += [
|
||||
"//components/dbus/menu",
|
||||
"//components/dbus/thread_linux",
|
||||
@@ -215,7 +226,11 @@ static_library("chrome") {
|
||||
"//chrome/browser/win/icon_reader_service.cc",
|
||||
"//chrome/browser/win/icon_reader_service.h",
|
||||
]
|
||||
public_deps += [ "//chrome/services/util_win:lib" ]
|
||||
public_deps += [
|
||||
"//chrome/browser/web_applications/proto",
|
||||
"//chrome/services/util_win:lib",
|
||||
"//components/webapps/common:mojo_bindings",
|
||||
]
|
||||
}
|
||||
|
||||
if (is_mac) {
|
||||
@@ -227,6 +242,8 @@ static_library("chrome") {
|
||||
"//chrome/browser/media/webrtc/system_media_capture_permissions_mac.mm",
|
||||
"//chrome/browser/media/webrtc/system_media_capture_permissions_stats_mac.h",
|
||||
"//chrome/browser/media/webrtc/system_media_capture_permissions_stats_mac.mm",
|
||||
"//chrome/browser/media/webrtc/thumbnail_capturer_mac.h",
|
||||
"//chrome/browser/media/webrtc/thumbnail_capturer_mac.mm",
|
||||
"//chrome/browser/media/webrtc/window_icon_util_mac.mm",
|
||||
"//chrome/browser/platform_util_mac.mm",
|
||||
"//chrome/browser/process_singleton_mac.mm",
|
||||
@@ -249,6 +266,8 @@ static_library("chrome") {
|
||||
sources += [
|
||||
"//chrome/browser/bad_message.cc",
|
||||
"//chrome/browser/bad_message.h",
|
||||
"//chrome/browser/printing/prefs_util.cc",
|
||||
"//chrome/browser/printing/prefs_util.h",
|
||||
"//chrome/browser/printing/print_job.cc",
|
||||
"//chrome/browser/printing/print_job.h",
|
||||
"//chrome/browser/printing/print_job_manager.cc",
|
||||
@@ -326,6 +345,8 @@ static_library("chrome") {
|
||||
"//chrome/browser/pdf/pdf_extension_util.h",
|
||||
"//chrome/browser/pdf/pdf_frame_util.cc",
|
||||
"//chrome/browser/pdf/pdf_frame_util.h",
|
||||
"//chrome/browser/pdf/pdf_viewer_stream_manager.cc",
|
||||
"//chrome/browser/pdf/pdf_viewer_stream_manager.h",
|
||||
"//chrome/browser/plugins/pdf_iframe_navigation_throttle.cc",
|
||||
"//chrome/browser/plugins/pdf_iframe_navigation_throttle.h",
|
||||
]
|
||||
@@ -334,6 +355,34 @@ static_library("chrome") {
|
||||
"//components/pdf/renderer",
|
||||
]
|
||||
}
|
||||
} else {
|
||||
# These are required by the webRequest module.
|
||||
sources += [
|
||||
"//extensions/browser/api/declarative_net_request/request_action.cc",
|
||||
"//extensions/browser/api/declarative_net_request/request_action.h",
|
||||
"//extensions/browser/api/web_request/form_data_parser.cc",
|
||||
"//extensions/browser/api/web_request/form_data_parser.h",
|
||||
"//extensions/browser/api/web_request/upload_data_presenter.cc",
|
||||
"//extensions/browser/api/web_request/upload_data_presenter.h",
|
||||
"//extensions/browser/api/web_request/web_request_api_constants.cc",
|
||||
"//extensions/browser/api/web_request/web_request_api_constants.h",
|
||||
"//extensions/browser/api/web_request/web_request_info.cc",
|
||||
"//extensions/browser/api/web_request/web_request_info.h",
|
||||
"//extensions/browser/api/web_request/web_request_resource_type.cc",
|
||||
"//extensions/browser/api/web_request/web_request_resource_type.h",
|
||||
"//extensions/browser/extension_api_frame_id_map.cc",
|
||||
"//extensions/browser/extension_api_frame_id_map.h",
|
||||
"//extensions/browser/extension_navigation_ui_data.cc",
|
||||
"//extensions/browser/extension_navigation_ui_data.h",
|
||||
"//extensions/browser/extensions_browser_client.cc",
|
||||
"//extensions/browser/extensions_browser_client.h",
|
||||
"//extensions/browser/guest_view/web_view/web_view_renderer_state.cc",
|
||||
"//extensions/browser/guest_view/web_view/web_view_renderer_state.h",
|
||||
]
|
||||
|
||||
public_deps += [
|
||||
"//extensions/browser/api/declarative_net_request/flat:extension_ruleset",
|
||||
]
|
||||
}
|
||||
|
||||
if (!is_mas_build) {
|
||||
@@ -405,6 +454,8 @@ source_set("chrome_spellchecker") {
|
||||
"//chrome/browser/profiles/profile_selections.h",
|
||||
"//chrome/browser/spellchecker/spell_check_host_chrome_impl.cc",
|
||||
"//chrome/browser/spellchecker/spell_check_host_chrome_impl.h",
|
||||
"//chrome/browser/spellchecker/spell_check_initialization_host_impl.cc",
|
||||
"//chrome/browser/spellchecker/spell_check_initialization_host_impl.h",
|
||||
"//chrome/browser/spellchecker/spellcheck_custom_dictionary.cc",
|
||||
"//chrome/browser/spellchecker/spellcheck_custom_dictionary.h",
|
||||
"//chrome/browser/spellchecker/spellcheck_factory.cc",
|
||||
|
||||
@@ -15,7 +15,7 @@ Shortcuts are registered with the [`globalShortcut`](global-shortcut.md) module
|
||||
using the [`register`](global-shortcut.md#globalshortcutregisteraccelerator-callback)
|
||||
method, i.e.
|
||||
|
||||
```javascript
|
||||
```js
|
||||
const { app, globalShortcut } = require('electron')
|
||||
|
||||
app.whenReady().then(() => {
|
||||
|
||||
109
docs/api/app.md
109
docs/api/app.md
@@ -377,35 +377,6 @@ page.
|
||||
|
||||
Emitted whenever there is a GPU info update.
|
||||
|
||||
### Event: 'gpu-process-crashed' _Deprecated_
|
||||
|
||||
Returns:
|
||||
|
||||
* `event` Event
|
||||
* `killed` boolean
|
||||
|
||||
Emitted when the GPU process crashes or is killed.
|
||||
|
||||
**Deprecated:** This event is superceded by the `child-process-gone` event
|
||||
which contains more information about why the child process disappeared. It
|
||||
isn't always because it crashed. The `killed` boolean can be replaced by
|
||||
checking `reason === 'killed'` when you switch to that event.
|
||||
|
||||
### Event: 'renderer-process-crashed' _Deprecated_
|
||||
|
||||
Returns:
|
||||
|
||||
* `event` Event
|
||||
* `webContents` [WebContents](web-contents.md)
|
||||
* `killed` boolean
|
||||
|
||||
Emitted when the renderer process of `webContents` crashes or is killed.
|
||||
|
||||
**Deprecated:** This event is superceded by the `render-process-gone` event
|
||||
which contains more information about why the render process disappeared. It
|
||||
isn't always because it crashed. The `killed` boolean can be replaced by
|
||||
checking `reason === 'killed'` when you switch to that event.
|
||||
|
||||
### Event: 'render-process-gone'
|
||||
|
||||
Returns:
|
||||
@@ -1134,11 +1105,11 @@ indicates success while any other value indicates failure according to Chromium
|
||||
resolver will attempt to use the system's DNS settings to do DNS lookups
|
||||
itself. Enabled by default on macOS, disabled by default on Windows and
|
||||
Linux.
|
||||
* `secureDnsMode` string (optional) - Can be "off", "automatic" or "secure".
|
||||
Configures the DNS-over-HTTP mode. When "off", no DoH lookups will be
|
||||
performed. When "automatic", DoH lookups will be performed first if DoH is
|
||||
* `secureDnsMode` string (optional) - Can be 'off', 'automatic' or 'secure'.
|
||||
Configures the DNS-over-HTTP mode. When 'off', no DoH lookups will be
|
||||
performed. When 'automatic', DoH lookups will be performed first if DoH is
|
||||
available, and insecure DNS lookups will be performed as a fallback. When
|
||||
"secure", only DoH lookups will be performed. Defaults to "automatic".
|
||||
'secure', only DoH lookups will be performed. Defaults to 'automatic'.
|
||||
* `secureDnsServers` string[] (optional) - A list of DNS-over-HTTP
|
||||
server templates. See [RFC8484 § 3][] for details on the template format.
|
||||
Most servers support the POST method; the template for such servers is
|
||||
@@ -1278,10 +1249,10 @@ Returns `boolean` - Whether the current desktop environment is Unity launcher.
|
||||
### `app.getLoginItemSettings([options])` _macOS_ _Windows_
|
||||
|
||||
* `options` Object (optional)
|
||||
* `path` string (optional) _Windows_ - The executable path to compare against.
|
||||
Defaults to `process.execPath`.
|
||||
* `args` string[] (optional) _Windows_ - The command-line arguments to compare
|
||||
against. Defaults to an empty array.
|
||||
* `type` string (optional) _macOS_ - Can be one of `mainAppService`, `agentService`, `daemonService`, or `loginItemService`. Defaults to `mainAppService`. Only available on macOS 13 and up. See [app.setLoginItemSettings](app.md#appsetloginitemsettingssettings-macos-windows) for more information about each type.
|
||||
* `serviceName` string (optional) _macOS_ - The name of the service. Required if `type` is non-default. Only available on macOS 13 and up.
|
||||
* `path` string (optional) _Windows_ - The executable path to compare against. Defaults to `process.execPath`.
|
||||
* `args` string[] (optional) _Windows_ - The command-line arguments to compare against. Defaults to an empty array.
|
||||
|
||||
If you provided `path` and `args` options to `app.setLoginItemSettings`, then you
|
||||
need to pass the same arguments here for `openAtLogin` to be set correctly.
|
||||
@@ -1289,17 +1260,11 @@ need to pass the same arguments here for `openAtLogin` to be set correctly.
|
||||
Returns `Object`:
|
||||
|
||||
* `openAtLogin` boolean - `true` if the app is set to open at login.
|
||||
* `openAsHidden` boolean _macOS_ - `true` if the app is set to open as hidden at login.
|
||||
This setting is not available on [MAS builds][mas-builds].
|
||||
* `wasOpenedAtLogin` boolean _macOS_ - `true` if the app was opened at login
|
||||
automatically. This setting is not available on [MAS builds][mas-builds].
|
||||
* `wasOpenedAsHidden` boolean _macOS_ - `true` if the app was opened as a hidden login
|
||||
item. This indicates that the app should not open any windows at startup.
|
||||
This setting is not available on [MAS builds][mas-builds].
|
||||
* `restoreState` boolean _macOS_ - `true` if the app was opened as a login item that
|
||||
should restore the state from the previous session. This indicates that the
|
||||
app should restore the windows that were open the last time the app was
|
||||
closed. This setting is not available on [MAS builds][mas-builds].
|
||||
* `openAsHidden` boolean _macOS_ _Deprecated_ - `true` if the app is set to open as hidden at login. This does not work on macOS 13 and up.
|
||||
* `wasOpenedAtLogin` boolean _macOS_ _Deprecated_ - `true` if the app was opened at login automatically. This setting is not available on [MAS builds][mas-builds] or on macOS 13 and up.
|
||||
* `wasOpenedAsHidden` boolean _macOS_ _Deprecated_ - `true` if the app was opened as a hidden login item. This indicates that the app should not open any windows at startup. This setting is not available on [MAS builds][mas-builds] or on macOS 13 and up.
|
||||
* `restoreState` boolean _macOS_ _Deprecated_ - `true` if the app was opened as a login item that should restore the state from the previous session. This indicates that the app should restore the windows that were open the last time the app was closed. This setting is not available on [MAS builds][mas-builds] or on macOS 13 and up.
|
||||
* `status` string _macOS_ - can be one of `not-registered`, `enabled`, `requires-approval`, or `not-found`.
|
||||
* `executableWillLaunchAtLogin` boolean _Windows_ - `true` if app is set to open at login and its run key is not deactivated. This differs from `openAtLogin` as it ignores the `args` option, this property will be true if the given executable would be launched at login with **any** arguments.
|
||||
* `launchItems` Object[] _Windows_
|
||||
* `name` string _Windows_ - name value of a registry entry.
|
||||
@@ -1313,10 +1278,14 @@ Returns `Object`:
|
||||
* `settings` Object
|
||||
* `openAtLogin` boolean (optional) - `true` to open the app at login, `false` to remove
|
||||
the app as a login item. Defaults to `false`.
|
||||
* `openAsHidden` boolean (optional) _macOS_ - `true` to open the app as hidden. Defaults to
|
||||
`false`. The user can edit this setting from the System Preferences so
|
||||
`app.getLoginItemSettings().wasOpenedAsHidden` should be checked when the app
|
||||
is opened to know the current value. This setting is not available on [MAS builds][mas-builds].
|
||||
* `openAsHidden` boolean (optional) _macOS_ _Deprecated_ - `true` to open the app as hidden. Defaults to `false`. The user can edit this setting from the System Preferences so `app.getLoginItemSettings().wasOpenedAsHidden` should be checked when the app is opened to know the current value. This setting is not available on [MAS build
|
||||
s][mas-builds] or on macOS 13 and up.
|
||||
* `type` string (optional) _macOS_ - The type of service to add as a login item. Defaults to `mainAppService`. Only available on macOS 13 and up.
|
||||
* `mainAppService` - The primary application.
|
||||
* `agentService` - The property list name for a launch agent. The property list name must correspond to a property list in the app’s `Contents/Library/LaunchAgents` directory.
|
||||
* `daemonService` string (optional) _macOS_ - The property list name for a launch agent. The property list name must correspond to a property list in the app’s `Contents/Library/LaunchDaemons` directory.
|
||||
* `loginItemService` string (optional) _macOS_ - The property list name for a login item service. The property list name must correspond to a property list in the app’s `Contents/Library/LoginItems` directory.
|
||||
* `serviceName` string (optional) _macOS_ - The name of the service. Required if `type` is non-default. Only available on macOS 13 and up.
|
||||
* `path` string (optional) _Windows_ - The executable to launch at login.
|
||||
Defaults to `process.execPath`.
|
||||
* `args` string[] (optional) _Windows_ - The command-line arguments to pass to
|
||||
@@ -1325,6 +1294,7 @@ Returns `Object`:
|
||||
* `enabled` boolean (optional) _Windows_ - `true` will change the startup approved registry key and `enable / disable` the App in Task Manager and Windows Settings.
|
||||
Defaults to `true`.
|
||||
* `name` string (optional) _Windows_ - value name to write into registry. Defaults to the app's AppUserModelId().
|
||||
|
||||
Set the app's login item settings.
|
||||
|
||||
To work with Electron's `autoUpdater` on Windows, which uses [Squirrel][Squirrel-Windows],
|
||||
@@ -1349,6 +1319,8 @@ app.setLoginItemSettings({
|
||||
})
|
||||
```
|
||||
|
||||
For more information about setting different services as login items on macOS 13 and up, see [`SMAppService`](https://developer.apple.com/documentation/servicemanagement/smappservice?language=objc).
|
||||
|
||||
### `app.isAccessibilitySupportEnabled()` _macOS_ _Windows_
|
||||
|
||||
Returns `boolean` - `true` if Chrome's accessibility support is enabled,
|
||||
@@ -1496,6 +1468,24 @@ details.
|
||||
|
||||
**Note:** Enable `Secure Keyboard Entry` only when it is needed and disable it when it is no longer needed.
|
||||
|
||||
### `app.setProxy(config)`
|
||||
|
||||
* `config` [ProxyConfig](structures/proxy-config.md)
|
||||
|
||||
Returns `Promise<void>` - Resolves when the proxy setting process is complete.
|
||||
|
||||
Sets the proxy settings for networks requests made without an associated [Session](session.md).
|
||||
Currently this will affect requests made with [Net](net.md) in the [utility process](../glossary.md#utility-process)
|
||||
and internal requests made by the runtime (ex: geolocation queries).
|
||||
|
||||
This method can only be called after app is ready.
|
||||
|
||||
#### `app.resolveProxy(url)`
|
||||
|
||||
* `url` URL
|
||||
|
||||
Returns `Promise<string>` - Resolves with the proxy information for `url` that will be used when attempting to make requests using [Net](net.md) in the [utility process](../glossary.md#utility-process).
|
||||
|
||||
## Properties
|
||||
|
||||
### `app.accessibilitySupportEnabled` _macOS_ _Windows_
|
||||
@@ -1542,7 +1532,7 @@ A `boolean` property that returns `true` if the app is packaged, `false` otherw
|
||||
[tasks]:https://learn.microsoft.com/en-us/windows/win32/shell/taskbar-extensions#tasks
|
||||
[app-user-model-id]: https://learn.microsoft.com/en-us/windows/win32/shell/appids
|
||||
[electron-forge]: https://www.electronforge.io/
|
||||
[electron-packager]: https://github.com/electron/electron-packager
|
||||
[electron-packager]: https://github.com/electron/packager
|
||||
[CFBundleURLTypes]: https://developer.apple.com/library/ios/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html#//apple_ref/doc/uid/TP40009249-102207-TPXREF115
|
||||
[LSCopyDefaultHandlerForURLScheme]: https://developer.apple.com/documentation/coreservices/1441725-lscopydefaulthandlerforurlscheme?language=objc
|
||||
[handoff]: https://developer.apple.com/library/ios/documentation/UserExperience/Conceptual/Handoff/HandoffFundamentals/HandoffFundamentals.html
|
||||
@@ -1571,19 +1561,6 @@ This is the user agent that will be used when no user agent is set at the
|
||||
app has the same user agent. Set to a custom value as early as possible
|
||||
in your app's initialization to ensure that your overridden value is used.
|
||||
|
||||
### `app.runningUnderRosettaTranslation` _macOS_ _Readonly_ _Deprecated_
|
||||
|
||||
A `boolean` which when `true` indicates that the app is currently running
|
||||
under the [Rosetta Translator Environment](https://en.wikipedia.org/wiki/Rosetta_(software)).
|
||||
|
||||
You can use this property to prompt users to download the arm64 version of
|
||||
your application when they are running the x64 version under Rosetta
|
||||
incorrectly.
|
||||
|
||||
**Deprecated:** This property is superceded by the `runningUnderARM64Translation`
|
||||
property which detects when the app is being translated to ARM64 in both macOS
|
||||
and Windows.
|
||||
|
||||
### `app.runningUnderARM64Translation` _Readonly_ _macOS_ _Windows_
|
||||
|
||||
A `boolean` which when `true` indicates that the app is currently running under
|
||||
|
||||
@@ -16,7 +16,7 @@ module is emitted.
|
||||
|
||||
### Example
|
||||
|
||||
```javascript
|
||||
```js
|
||||
// In the main process.
|
||||
const { app, BrowserView, BrowserWindow } = require('electron')
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@ Process: [Main](../glossary.md#main-process)
|
||||
This module cannot be used until the `ready` event of the `app`
|
||||
module is emitted.
|
||||
|
||||
```javascript
|
||||
```js
|
||||
// In the main process.
|
||||
const { BrowserWindow } = require('electron')
|
||||
|
||||
@@ -38,7 +38,7 @@ While loading the page, the `ready-to-show` event will be emitted when the rende
|
||||
process has rendered the page for the first time if the window has not been shown yet. Showing
|
||||
the window after this event will have no visual flash:
|
||||
|
||||
```javascript
|
||||
```js
|
||||
const { BrowserWindow } = require('electron')
|
||||
const win = new BrowserWindow({ show: false })
|
||||
win.once('ready-to-show', () => {
|
||||
@@ -59,7 +59,7 @@ For a complex app, the `ready-to-show` event could be emitted too late, making
|
||||
the app feel slow. In this case, it is recommended to show the window
|
||||
immediately, and use a `backgroundColor` close to your app's background:
|
||||
|
||||
```javascript
|
||||
```js
|
||||
const { BrowserWindow } = require('electron')
|
||||
|
||||
const win = new BrowserWindow({ backgroundColor: '#2e2c29' })
|
||||
@@ -85,7 +85,7 @@ For more information about these color types see valid options in [win.setBackgr
|
||||
|
||||
By using `parent` option, you can create child windows:
|
||||
|
||||
```javascript
|
||||
```js
|
||||
const { BrowserWindow } = require('electron')
|
||||
|
||||
const top = new BrowserWindow()
|
||||
@@ -101,7 +101,7 @@ The `child` window will always show on top of the `top` window.
|
||||
A modal window is a child window that disables parent window, to create a modal
|
||||
window, you have to set both `parent` and `modal` options:
|
||||
|
||||
```javascript
|
||||
```js
|
||||
const { BrowserWindow } = require('electron')
|
||||
|
||||
const top = new BrowserWindow()
|
||||
@@ -188,7 +188,7 @@ window should be closed, which will also be called when the window is
|
||||
reloaded. In Electron, returning any value other than `undefined` would cancel the
|
||||
close. For example:
|
||||
|
||||
```javascript
|
||||
```js
|
||||
window.onbeforeunload = (e) => {
|
||||
console.log('I do not want to be closed')
|
||||
|
||||
@@ -351,7 +351,7 @@ Commands are lowercased, underscores are replaced with hyphens, and the
|
||||
`APPCOMMAND_` prefix is stripped off.
|
||||
e.g. `APPCOMMAND_BROWSER_BACKWARD` is emitted as `browser-backward`.
|
||||
|
||||
```javascript
|
||||
```js
|
||||
const { BrowserWindow } = require('electron')
|
||||
const win = new BrowserWindow()
|
||||
win.on('app-command', (e, cmd) => {
|
||||
@@ -456,7 +456,7 @@ Returns `BrowserWindow | null` - The window with the given `id`.
|
||||
|
||||
Objects created with `new BrowserWindow` have the following properties:
|
||||
|
||||
```javascript
|
||||
```js
|
||||
const { BrowserWindow } = require('electron')
|
||||
// In this example `win` is our instance
|
||||
const win = new BrowserWindow({ width: 800, height: 600 })
|
||||
@@ -475,6 +475,10 @@ events.
|
||||
|
||||
A `Integer` property representing the unique ID of the window. Each ID is unique among all `BrowserWindow` instances of the entire Electron application.
|
||||
|
||||
#### `win.tabbingIdentifier` _macOS_ _Readonly_
|
||||
|
||||
A `string` (optional) property that is equal to the `tabbingIdentifier` passed to the `BrowserWindow` constructor or `undefined` if none was set.
|
||||
|
||||
#### `win.autoHideMenuBar`
|
||||
|
||||
A `boolean` property that determines whether the window menu bar should hide itself automatically. Once set, the menu bar will only show when users press the single `Alt` key.
|
||||
@@ -776,7 +780,7 @@ Closes the currently open [Quick Look][quick-look] panel.
|
||||
|
||||
Resizes and moves the window to the supplied bounds. Any properties that are not supplied will default to their current values.
|
||||
|
||||
```javascript
|
||||
```js
|
||||
const { BrowserWindow } = require('electron')
|
||||
const win = new BrowserWindow()
|
||||
|
||||
@@ -1031,7 +1035,7 @@ Changes the attachment point for sheets on macOS. By default, sheets are
|
||||
attached just below the window frame, but you may want to display them beneath
|
||||
a HTML-rendered toolbar. For example:
|
||||
|
||||
```javascript
|
||||
```js
|
||||
const { BrowserWindow } = require('electron')
|
||||
const win = new BrowserWindow()
|
||||
|
||||
@@ -1174,7 +1178,7 @@ To ensure that file URLs are properly formatted, it is recommended to use
|
||||
Node's [`url.format`](https://nodejs.org/api/url.html#url_url_format_urlobject)
|
||||
method:
|
||||
|
||||
```javascript
|
||||
```js
|
||||
const { BrowserWindow } = require('electron')
|
||||
const win = new BrowserWindow()
|
||||
|
||||
@@ -1190,7 +1194,7 @@ win.loadURL(url)
|
||||
You can load a URL using a `POST` request with URL-encoded data by doing
|
||||
the following:
|
||||
|
||||
```javascript
|
||||
```js
|
||||
const { BrowserWindow } = require('electron')
|
||||
const win = new BrowserWindow()
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
> Make HTTP/HTTPS requests.
|
||||
|
||||
Process: [Main](../glossary.md#main-process)<br />
|
||||
Process: [Main](../glossary.md#main-process), [Utility](../glossary.md#utility-process)<br />
|
||||
_This class is not exported from the `'electron'` module. It is only available as a return value of other methods in the Electron API._
|
||||
|
||||
`ClientRequest` implements the [Writable Stream](https://nodejs.org/api/stream.html#stream_writable_streams)
|
||||
@@ -65,7 +65,7 @@ strictly follow the Node.js model as described in the
|
||||
|
||||
For instance, we could have created the same request to 'github.com' as follows:
|
||||
|
||||
```javascript
|
||||
```js
|
||||
const request = net.request({
|
||||
method: 'GET',
|
||||
protocol: 'https:',
|
||||
@@ -104,7 +104,7 @@ The `callback` function is expected to be called back with user credentials:
|
||||
* `username` string
|
||||
* `password` string
|
||||
|
||||
```javascript @ts-type={request:Electron.ClientRequest}
|
||||
```js @ts-type={request:Electron.ClientRequest}
|
||||
request.on('login', (authInfo, callback) => {
|
||||
callback('username', 'password')
|
||||
})
|
||||
@@ -113,7 +113,7 @@ request.on('login', (authInfo, callback) => {
|
||||
Providing empty credentials will cancel the request and report an authentication
|
||||
error on the response object:
|
||||
|
||||
```javascript @ts-type={request:Electron.ClientRequest}
|
||||
```js @ts-type={request:Electron.ClientRequest}
|
||||
request.on('response', (response) => {
|
||||
console.log(`STATUS: ${response.statusCode}`)
|
||||
response.on('error', (error) => {
|
||||
|
||||
@@ -7,7 +7,7 @@ Process: [Main](../glossary.md#main-process), [Renderer](../glossary.md#renderer
|
||||
On Linux, there is also a `selection` clipboard. To manipulate it
|
||||
you need to pass `selection` to each method:
|
||||
|
||||
```javascript
|
||||
```js
|
||||
const { clipboard } = require('electron')
|
||||
|
||||
clipboard.writeText('Example string', 'selection')
|
||||
|
||||
@@ -6,7 +6,7 @@ You can use [app.commandLine.appendSwitch][append-switch] to append them in
|
||||
your app's main script before the [ready][ready] event of the [app][app] module
|
||||
is emitted:
|
||||
|
||||
```javascript
|
||||
```js
|
||||
const { app } = require('electron')
|
||||
app.commandLine.appendSwitch('remote-debugging-port', '8315')
|
||||
app.commandLine.appendSwitch('host-rules', 'MAP * 127.0.0.1')
|
||||
@@ -185,7 +185,7 @@ list of hosts. This flag has an effect only if used in tandem with
|
||||
|
||||
For example:
|
||||
|
||||
```javascript
|
||||
```js
|
||||
const { app } = require('electron')
|
||||
app.commandLine.appendSwitch('proxy-bypass-list', '<local>;*.google.com;*foo.com;1.2.3.4:5678')
|
||||
```
|
||||
|
||||
@@ -7,7 +7,7 @@ _This class is not exported from the `'electron'` module. It is only available a
|
||||
|
||||
The following example shows how to check if the `--disable-gpu` flag is set.
|
||||
|
||||
```javascript
|
||||
```js
|
||||
const { app } = require('electron')
|
||||
app.commandLine.hasSwitch('disable-gpu')
|
||||
```
|
||||
|
||||
@@ -10,7 +10,7 @@ This module does not include a web interface. To view recorded traces, use
|
||||
**Note:** You should not use this module until the `ready` event of the app
|
||||
module is emitted.
|
||||
|
||||
```javascript
|
||||
```js
|
||||
const { app, contentTracing } = require('electron')
|
||||
|
||||
app.whenReady().then(() => {
|
||||
|
||||
@@ -6,7 +6,7 @@ Process: [Renderer](../glossary.md#renderer-process)
|
||||
|
||||
An example of exposing an API to a renderer from an isolated preload script is given below:
|
||||
|
||||
```javascript
|
||||
```js
|
||||
// Preload (Isolated World)
|
||||
const { contextBridge, ipcRenderer } = require('electron')
|
||||
|
||||
@@ -18,7 +18,7 @@ contextBridge.exposeInMainWorld(
|
||||
)
|
||||
```
|
||||
|
||||
```javascript @ts-nocheck
|
||||
```js @ts-nocheck
|
||||
// Renderer (Main World)
|
||||
|
||||
window.electron.doThing()
|
||||
@@ -64,7 +64,7 @@ the API become immutable and updates on either side of the bridge do not result
|
||||
|
||||
An example of a complex API is shown below:
|
||||
|
||||
```javascript
|
||||
```js
|
||||
const { contextBridge, ipcRenderer } = require('electron')
|
||||
|
||||
contextBridge.exposeInMainWorld(
|
||||
@@ -92,7 +92,7 @@ contextBridge.exposeInMainWorld(
|
||||
|
||||
An example of `exposeInIsolatedWorld` is shown below:
|
||||
|
||||
```javascript
|
||||
```js
|
||||
const { contextBridge, ipcRenderer } = require('electron')
|
||||
|
||||
contextBridge.exposeInIsolatedWorld(
|
||||
@@ -104,7 +104,7 @@ contextBridge.exposeInIsolatedWorld(
|
||||
)
|
||||
```
|
||||
|
||||
```javascript @ts-nocheck
|
||||
```js @ts-nocheck
|
||||
// Renderer (In isolated world id1004)
|
||||
|
||||
window.electron.doThing()
|
||||
@@ -145,7 +145,7 @@ The table of supported types described above also applies to Node APIs that you
|
||||
Please note that many Node APIs grant access to local system resources.
|
||||
Be very cautious about which globals and APIs you expose to untrusted remote content.
|
||||
|
||||
```javascript
|
||||
```js
|
||||
const { contextBridge } = require('electron')
|
||||
const crypto = require('node:crypto')
|
||||
contextBridge.exposeInMainWorld('nodeCrypto', {
|
||||
|
||||
@@ -10,7 +10,7 @@ a `Session`.
|
||||
|
||||
For example:
|
||||
|
||||
```javascript
|
||||
```js
|
||||
const { session } = require('electron')
|
||||
|
||||
// Query all cookies.
|
||||
|
||||
@@ -7,7 +7,7 @@ Process: [Main](../glossary.md#main-process), [Renderer](../glossary.md#renderer
|
||||
The following is an example of setting up Electron to automatically submit
|
||||
crash reports to a remote server:
|
||||
|
||||
```javascript
|
||||
```js
|
||||
const { crashReporter } = require('electron')
|
||||
|
||||
crashReporter.start({ submitURL: 'https://your-domain.com/url-to-submit' })
|
||||
@@ -100,7 +100,7 @@ longer than the maximum length will be truncated.
|
||||
|
||||
### `crashReporter.getLastCrashReport()`
|
||||
|
||||
Returns [`CrashReport`](structures/crash-report.md) - The date and ID of the
|
||||
Returns [`CrashReport | null`](structures/crash-report.md) - The date and ID of the
|
||||
last crash report. Only crash reports that have been uploaded will be returned;
|
||||
even if a crash report is present on disk it will not be returned until it is
|
||||
uploaded. In the case that there are no uploaded reports, `null` is returned.
|
||||
|
||||
@@ -8,7 +8,7 @@ _This class is not exported from the `'electron'` module. It is only available a
|
||||
Chrome Developer Tools has a [special binding][rdp] available at JavaScript
|
||||
runtime that allows interacting with pages and instrumenting them.
|
||||
|
||||
```javascript
|
||||
```js
|
||||
const { BrowserWindow } = require('electron')
|
||||
const win = new BrowserWindow()
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@ Process: [Main](../glossary.md#main-process)
|
||||
The following example shows how to capture video from a desktop window whose
|
||||
title is `Electron`:
|
||||
|
||||
```javascript
|
||||
```js
|
||||
// In the main process.
|
||||
const { BrowserWindow, desktopCapturer } = require('electron')
|
||||
|
||||
@@ -24,7 +24,7 @@ desktopCapturer.getSources({ types: ['window', 'screen'] }).then(async sources =
|
||||
})
|
||||
```
|
||||
|
||||
```javascript @ts-nocheck
|
||||
```js @ts-nocheck
|
||||
// In the preload script.
|
||||
const { ipcRenderer } = require('electron')
|
||||
|
||||
@@ -68,7 +68,7 @@ To capture both audio and video from the entire desktop the constraints passed
|
||||
to [`navigator.mediaDevices.getUserMedia`][] must include `chromeMediaSource: 'desktop'`,
|
||||
for both `audio` and `video`, but should not include a `chromeMediaSourceId` constraint.
|
||||
|
||||
```javascript
|
||||
```js
|
||||
const constraints = {
|
||||
audio: {
|
||||
mandatory: {
|
||||
|
||||
@@ -6,7 +6,7 @@ Process: [Main](../glossary.md#main-process)
|
||||
|
||||
An example of showing a dialog to select multiple files:
|
||||
|
||||
```javascript
|
||||
```js
|
||||
const { dialog } = require('electron')
|
||||
console.log(dialog.showOpenDialog({ properties: ['openFile', 'multiSelections'] }))
|
||||
```
|
||||
@@ -52,7 +52,7 @@ The `browserWindow` argument allows the dialog to attach itself to a parent wind
|
||||
The `filters` specifies an array of file types that can be displayed or
|
||||
selected when you want to limit the user to a specific type. For example:
|
||||
|
||||
```javascript
|
||||
```js
|
||||
{
|
||||
filters: [
|
||||
{ name: 'Images', extensions: ['jpg', 'png', 'gif'] },
|
||||
@@ -119,7 +119,7 @@ The `browserWindow` argument allows the dialog to attach itself to a parent wind
|
||||
The `filters` specifies an array of file types that can be displayed or
|
||||
selected when you want to limit the user to a specific type. For example:
|
||||
|
||||
```javascript
|
||||
```js
|
||||
{
|
||||
filters: [
|
||||
{ name: 'Images', extensions: ['jpg', 'png', 'gif'] },
|
||||
|
||||
@@ -7,7 +7,7 @@ _This class is not exported from the `'electron'` module. It is only available a
|
||||
|
||||
The following example shows how to bounce your icon on the dock.
|
||||
|
||||
```javascript
|
||||
```js
|
||||
const { app } = require('electron')
|
||||
app.dock.bounce()
|
||||
```
|
||||
|
||||
@@ -9,7 +9,7 @@ _This class is not exported from the `'electron'` module. It is only available a
|
||||
It is used in `will-download` event of `Session` class, and allows users to
|
||||
control the download item.
|
||||
|
||||
```javascript
|
||||
```js
|
||||
// In the main process.
|
||||
const { BrowserWindow } = require('electron')
|
||||
const win = new BrowserWindow()
|
||||
|
||||
@@ -59,7 +59,7 @@ geolocation webservice. To enable this feature, acquire a
|
||||
and place the following code in your main process file, before opening any
|
||||
browser windows that will make geolocation requests:
|
||||
|
||||
```javascript
|
||||
```js
|
||||
process.env.GOOGLE_API_KEY = 'YOUR_KEY_HERE'
|
||||
```
|
||||
|
||||
|
||||
@@ -2,6 +2,11 @@
|
||||
|
||||
> Use the HTML5 `File` API to work natively with files on the filesystem.
|
||||
|
||||
> **Warning**
|
||||
> The `path` property that Electron adds to the `File` interface is deprecated
|
||||
> and **will** be removed in a future Electron release. We recommend you
|
||||
> use `webUtils.getPathForFile` instead.
|
||||
|
||||
The DOM's File interface provides abstraction around native files in order to
|
||||
let users work on native files directly with the HTML5 file API. Electron has
|
||||
added a `path` attribute to the `File` interface which exposes the file's real
|
||||
|
||||
@@ -12,7 +12,7 @@ shortcuts.
|
||||
not have the keyboard focus. This module cannot be used before the `ready`
|
||||
event of the app module is emitted.
|
||||
|
||||
```javascript
|
||||
```js
|
||||
const { app, globalShortcut } = require('electron')
|
||||
|
||||
app.whenReady().then(() => {
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
> Handle responses to HTTP/HTTPS requests.
|
||||
|
||||
Process: [Main](../glossary.md#main-process)<br />
|
||||
Process: [Main](../glossary.md#main-process), [Utility](../glossary.md#utility-process)<br />
|
||||
_This class is not exported from the `'electron'` module. It is only available as a return value of other methods in the Electron API._
|
||||
|
||||
`IncomingMessage` implements the [Readable Stream](https://nodejs.org/api/stream.html#stream_readable_streams)
|
||||
@@ -89,7 +89,7 @@ tuples. So, the even-numbered offsets are key values, and the odd-numbered
|
||||
offsets are the associated values. Header names are not lowercased, and
|
||||
duplicates are not merged.
|
||||
|
||||
```javascript @ts-type={response:Electron.IncomingMessage}
|
||||
```js @ts-type={response:Electron.IncomingMessage}
|
||||
// Prints something like:
|
||||
//
|
||||
// [ 'user-agent',
|
||||
|
||||
@@ -120,7 +120,7 @@ The main process should listen for `channel` with
|
||||
|
||||
For example:
|
||||
|
||||
```javascript @ts-type={someArgument:unknown} @ts-type={doSomeWork:(arg:unknown)=>Promise<unknown>}
|
||||
```js @ts-type={someArgument:unknown} @ts-type={doSomeWork:(arg:unknown)=>Promise<unknown>}
|
||||
// Renderer process
|
||||
ipcRenderer.invoke('some-name', someArgument).then((result) => {
|
||||
// ...
|
||||
|
||||
@@ -151,7 +151,7 @@ can have a submenu.
|
||||
|
||||
An example of creating the application menu with the simple template API:
|
||||
|
||||
```javascript @ts-expect-error=[107]
|
||||
```js @ts-expect-error=[107]
|
||||
const { app, Menu } = require('electron')
|
||||
|
||||
const isMac = process.platform === 'darwin'
|
||||
@@ -353,7 +353,7 @@ By default, items will be inserted in the order they exist in the template unles
|
||||
|
||||
Template:
|
||||
|
||||
```javascript
|
||||
```js
|
||||
[
|
||||
{ id: '1', label: 'one' },
|
||||
{ id: '2', label: 'two' },
|
||||
@@ -373,7 +373,7 @@ Menu:
|
||||
|
||||
Template:
|
||||
|
||||
```javascript
|
||||
```js
|
||||
[
|
||||
{ id: '1', label: 'one' },
|
||||
{ type: 'separator' },
|
||||
@@ -397,7 +397,7 @@ Menu:
|
||||
|
||||
Template:
|
||||
|
||||
```javascript
|
||||
```js
|
||||
[
|
||||
{ id: '1', label: 'one', after: ['3'] },
|
||||
{ id: '2', label: 'two', before: ['1'] },
|
||||
|
||||
@@ -4,36 +4,41 @@
|
||||
|
||||
Process: [Main](../glossary.md#main-process), [Renderer](../glossary.md#renderer-process)
|
||||
|
||||
In Electron, for the APIs that take images, you can pass either file paths or
|
||||
`NativeImage` instances. An empty image will be used when `null` is passed.
|
||||
The `nativeImage` module provides a unified interface for manipulating
|
||||
system images. These can be handy if you want to provide multiple scaled
|
||||
versions of the same icon or take advantage of macOS [template images][template-image].
|
||||
|
||||
For example, when creating a tray or setting a window's icon, you can pass an
|
||||
image file path as a `string`:
|
||||
Electron APIs that take image files accept either file paths or
|
||||
`NativeImage` instances. An empty and transparent image will be used when `null` is passed.
|
||||
|
||||
```javascript
|
||||
For example, when creating a [Tray](../api/tray.md) or setting a [BrowserWindow](../api/browser-window.md)'s
|
||||
icon, you can either pass an image file path as a string:
|
||||
|
||||
```js title='Main Process'
|
||||
const { BrowserWindow, Tray } = require('electron')
|
||||
|
||||
const appIcon = new Tray('/Users/somebody/images/icon.png')
|
||||
const tray = new Tray('/Users/somebody/images/icon.png')
|
||||
const win = new BrowserWindow({ icon: '/Users/somebody/images/window.png' })
|
||||
console.log(appIcon, win)
|
||||
```
|
||||
|
||||
Or read the image from the clipboard, which returns a `NativeImage`:
|
||||
or generate a `NativeImage` instance from the same file:
|
||||
|
||||
```javascript
|
||||
const { clipboard, Tray } = require('electron')
|
||||
const image = clipboard.readImage()
|
||||
const appIcon = new Tray(image)
|
||||
console.log(appIcon)
|
||||
```js title='Main Process'
|
||||
const { BrowserWindow, nativeImage, Tray } = require('electron')
|
||||
|
||||
const trayIcon = nativeImage.createFromPath('/Users/somebody/images/icon.png')
|
||||
const appIcon = nativeImage.createFromPath('/Users/somebody/images/window.png')
|
||||
const tray = new Tray(trayIcon)
|
||||
const win = new BrowserWindow({ icon: appIcon })
|
||||
```
|
||||
|
||||
## Supported Formats
|
||||
|
||||
Currently `PNG` and `JPEG` image formats are supported. `PNG` is recommended
|
||||
because of its support for transparency and lossless compression.
|
||||
Currently, `PNG` and `JPEG` image formats are supported across all platforms.
|
||||
`PNG` is recommended because of its support for transparency and lossless compression.
|
||||
|
||||
On Windows, you can also load `ICO` icons from file paths. For best visual
|
||||
quality, it is recommended to include at least the following sizes in the:
|
||||
quality, we recommend including at least the following sizes:
|
||||
|
||||
* Small icon
|
||||
* 16x16 (100% DPI scale)
|
||||
@@ -47,22 +52,30 @@ quality, it is recommended to include at least the following sizes in the:
|
||||
* 64x64 (200% DPI scale)
|
||||
* 256x256
|
||||
|
||||
Check the _Size requirements_ section in [this article][icons].
|
||||
Check the _Icon Scaling_ section in the Windows [App Icon Construction][icons] reference.
|
||||
|
||||
[icons]: https://learn.microsoft.com/en-us/windows/win32/uxguide/vis-icons
|
||||
[icons]: https://learn.microsoft.com/en-us/windows/apps/design/style/iconography/app-icon-construction#icon-scaling
|
||||
|
||||
:::note
|
||||
|
||||
EXIF metadata is currently not supported and will not be taken into account during
|
||||
image encoding and decoding.
|
||||
|
||||
:::
|
||||
|
||||
## High Resolution Image
|
||||
|
||||
On platforms that have high-DPI support such as Apple Retina displays, you can
|
||||
append `@2x` after image's base filename to mark it as a high resolution image.
|
||||
On platforms that support high pixel density displays (such as Apple Retina),
|
||||
you can append `@2x` after image's base filename to mark it as a 2x scale
|
||||
high resolution image.
|
||||
|
||||
For example, if `icon.png` is a normal image that has standard resolution, then
|
||||
`icon@2x.png` will be treated as a high resolution image that has double DPI
|
||||
density.
|
||||
`icon@2x.png` will be treated as a high resolution image that has double
|
||||
Dots per Inch (DPI) density.
|
||||
|
||||
If you want to support displays with different DPI densities at the same time,
|
||||
you can put images with different sizes in the same folder and use the filename
|
||||
without DPI suffixes. For example:
|
||||
without DPI suffixes within Electron. For example:
|
||||
|
||||
```plaintext
|
||||
images/
|
||||
@@ -71,10 +84,9 @@ images/
|
||||
└── icon@3x.png
|
||||
```
|
||||
|
||||
```javascript
|
||||
```js title='Main Process'
|
||||
const { Tray } = require('electron')
|
||||
const appIcon = new Tray('/Users/somebody/images/icon.png')
|
||||
console.log(appIcon)
|
||||
const appTray = new Tray('/Users/somebody/images/icon.png')
|
||||
```
|
||||
|
||||
The following suffixes for DPI are also supported:
|
||||
@@ -91,27 +103,23 @@ The following suffixes for DPI are also supported:
|
||||
* `@4x`
|
||||
* `@5x`
|
||||
|
||||
## Template Image
|
||||
## Template Image _macOS_
|
||||
|
||||
Template images consist of black and an alpha channel.
|
||||
On macOS, [template images][template-image] consist of black and an alpha channel.
|
||||
Template images are not intended to be used as standalone images and are usually
|
||||
mixed with other content to create the desired final appearance.
|
||||
|
||||
The most common case is to use template images for a menu bar icon, so it can
|
||||
The most common case is to use template images for a menu bar (Tray) icon, so it can
|
||||
adapt to both light and dark menu bars.
|
||||
|
||||
**Note:** Template image is only supported on macOS.
|
||||
|
||||
To mark an image as a template image, its filename should end with the word
|
||||
`Template`. For example:
|
||||
|
||||
* `xxxTemplate.png`
|
||||
* `xxxTemplate@2x.png`
|
||||
To mark an image as a template image, its base filename should end with the word
|
||||
`Template` (e.g. `xxxTemplate.png`). You can also specify template images at
|
||||
different DPI densities (e.g. `xxxTemplate@2x.png`).
|
||||
|
||||
## Methods
|
||||
|
||||
The `nativeImage` module has the following methods, all of which return
|
||||
an instance of the `NativeImage` class:
|
||||
an instance of the [`NativeImage`](#class-nativeimage) class:
|
||||
|
||||
### `nativeImage.createEmpty()`
|
||||
|
||||
@@ -130,7 +138,7 @@ Note: The Windows implementation will ignore `size.height` and scale the height
|
||||
|
||||
### `nativeImage.createFromPath(path)`
|
||||
|
||||
* `path` string
|
||||
* `path` string - path to a file that we intend to construct an image out of.
|
||||
|
||||
Returns `NativeImage`
|
||||
|
||||
@@ -138,8 +146,8 @@ Creates a new `NativeImage` instance from a file located at `path`. This method
|
||||
returns an empty image if the `path` does not exist, cannot be read, or is not
|
||||
a valid image.
|
||||
|
||||
```javascript
|
||||
const nativeImage = require('electron').nativeImage
|
||||
```js
|
||||
const { nativeImage } = require('electron')
|
||||
|
||||
const image = nativeImage.createFromPath('/Users/somebody/images/icon.png')
|
||||
console.log(image)
|
||||
@@ -176,7 +184,7 @@ Creates a new `NativeImage` instance from `buffer`. Tries to decode as PNG or JP
|
||||
|
||||
Returns `NativeImage`
|
||||
|
||||
Creates a new `NativeImage` instance from `dataURL`.
|
||||
Creates a new `NativeImage` instance from `dataUrl`, a base 64 encoded [Data URL][data-url] string.
|
||||
|
||||
### `nativeImage.createFromNamedImage(imageName[, hslShift])` _macOS_
|
||||
|
||||
@@ -185,14 +193,14 @@ Creates a new `NativeImage` instance from `dataURL`.
|
||||
|
||||
Returns `NativeImage`
|
||||
|
||||
Creates a new `NativeImage` instance from the NSImage that maps to the
|
||||
given image name. See [`System Icons`](https://developer.apple.com/design/human-interface-guidelines/macos/icons-and-images/system-icons/)
|
||||
for a list of possible values.
|
||||
Creates a new `NativeImage` instance from the `NSImage` that maps to the
|
||||
given image name. See Apple's [`NSImageName`](https://developer.apple.com/documentation/appkit/nsimagename#2901388)
|
||||
documentation for a list of possible values.
|
||||
|
||||
The `hslShift` is applied to the image with the following rules:
|
||||
|
||||
* `hsl_shift[0]` (hue): The absolute hue value for the image - 0 and 1 map
|
||||
to 0 and 360 on the hue color wheel (red).
|
||||
to 0 and 360 on the hue color wheel (red).
|
||||
* `hsl_shift[1]` (saturation): A saturation shift for the image, with the
|
||||
following key values:
|
||||
0 = remove all color.
|
||||
@@ -209,7 +217,9 @@ This means that `[-1, 0, 1]` will make the image completely white and
|
||||
|
||||
In some cases, the `NSImageName` doesn't match its string representation; one example of this is `NSFolderImageName`, whose string representation would actually be `NSFolder`. Therefore, you'll need to determine the correct string representation for your image before passing it in. This can be done with the following:
|
||||
|
||||
`echo -e '#import <Cocoa/Cocoa.h>\nint main() { NSLog(@"%@", SYSTEM_IMAGE_NAME); }' | clang -otest -x objective-c -framework Cocoa - && ./test`
|
||||
```sh
|
||||
echo -e '#import <Cocoa/Cocoa.h>\nint main() { NSLog(@"%@", SYSTEM_IMAGE_NAME); }' | clang -otest -x objective-c -framework Cocoa - && ./test
|
||||
```
|
||||
|
||||
where `SYSTEM_IMAGE_NAME` should be replaced with any value from [this list](https://developer.apple.com/documentation/appkit/nsimagename?language=objc).
|
||||
|
||||
@@ -250,7 +260,7 @@ data.
|
||||
* `options` Object (optional)
|
||||
* `scaleFactor` Number (optional) - Defaults to 1.0.
|
||||
|
||||
Returns `string` - The data URL of the image.
|
||||
Returns `string` - The [Data URL][data-url] of the image.
|
||||
|
||||
#### `image.getBitmap([options])`
|
||||
|
||||
@@ -266,7 +276,7 @@ current event loop tick; otherwise the data might be changed or destroyed.
|
||||
#### `image.getNativeHandle()` _macOS_
|
||||
|
||||
Returns `Buffer` - A [Buffer][buffer] that stores C pointer to underlying native handle of
|
||||
the image. On macOS, a pointer to `NSImage` instance would be returned.
|
||||
the image. On macOS, a pointer to `NSImage` instance is returned.
|
||||
|
||||
Notice that the returned pointer is a weak pointer to the underlying native
|
||||
image instead of a copy, so you _must_ ensure that the associated
|
||||
@@ -288,11 +298,11 @@ If `scaleFactor` is passed, this will return the size corresponding to the image
|
||||
|
||||
* `option` boolean
|
||||
|
||||
Marks the image as a template image.
|
||||
Marks the image as a macOS [template image][template-image].
|
||||
|
||||
#### `image.isTemplateImage()`
|
||||
|
||||
Returns `boolean` - Whether the image is a template image.
|
||||
Returns `boolean` - Whether the image is a macOS [template image][template-image].
|
||||
|
||||
#### `image.crop(rect)`
|
||||
|
||||
@@ -321,13 +331,13 @@ will be preserved in the resized image.
|
||||
|
||||
* `scaleFactor` Number (optional) - Defaults to 1.0.
|
||||
|
||||
Returns `Number` - The image's aspect ratio.
|
||||
Returns `Number` - The image's aspect ratio (width divided by height).
|
||||
|
||||
If `scaleFactor` is passed, this will return the aspect ratio corresponding to the image representation most closely matching the passed value.
|
||||
|
||||
#### `image.getScaleFactors()`
|
||||
|
||||
Returns `Number[]` - An array of all scale factors corresponding to representations for a given nativeImage.
|
||||
Returns `Number[]` - An array of all scale factors corresponding to representations for a given `NativeImage`.
|
||||
|
||||
#### `image.addRepresentation(options)`
|
||||
|
||||
@@ -342,15 +352,17 @@ Returns `Number[]` - An array of all scale factors corresponding to representati
|
||||
encoded PNG or JPEG image.
|
||||
|
||||
Add an image representation for a specific scale factor. This can be used
|
||||
to explicitly add different scale factor representations to an image. This
|
||||
to programmatically add different scale factor representations to an image. This
|
||||
can be called on empty images.
|
||||
|
||||
[buffer]: https://nodejs.org/api/buffer.html#buffer_class_buffer
|
||||
|
||||
### Instance Properties
|
||||
|
||||
#### `nativeImage.isMacTemplateImage` _macOS_
|
||||
|
||||
A `boolean` property that determines whether the image is considered a [template image](https://developer.apple.com/documentation/appkit/nsimage/1520017-template).
|
||||
A `boolean` property that determines whether the image is considered a [template image][template-image].
|
||||
|
||||
Please note that this property only has an effect on macOS.
|
||||
|
||||
[buffer]: https://nodejs.org/api/buffer.html#buffer_class_buffer
|
||||
[data-url]: https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/Data_URLs
|
||||
[template-image]: https://developer.apple.com/documentation/appkit/nsimage/1520017-template
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
Process: [Main](../glossary.md#main-process)
|
||||
|
||||
```javascript
|
||||
```js
|
||||
const { app, netLog } = require('electron')
|
||||
|
||||
app.whenReady().then(async () => {
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
> Issue HTTP/HTTPS requests using Chromium's native networking library
|
||||
|
||||
Process: [Main](../glossary.md#main-process)
|
||||
Process: [Main](../glossary.md#main-process), [Utility](../glossary.md#utility-process)
|
||||
|
||||
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
|
||||
@@ -26,7 +26,7 @@ Node.js.
|
||||
|
||||
Example usage:
|
||||
|
||||
```javascript
|
||||
```js
|
||||
const { app } = require('electron')
|
||||
app.whenReady().then(() => {
|
||||
const { net } = require('electron')
|
||||
@@ -119,6 +119,9 @@ protocol.handle('https', (req) => {
|
||||
})
|
||||
```
|
||||
|
||||
Note: in the [utility process](../glossary.md#utility-process) custom protocols
|
||||
are not supported.
|
||||
|
||||
### `net.isOnline()`
|
||||
|
||||
Returns `boolean` - Whether there is currently internet connection.
|
||||
|
||||
@@ -85,6 +85,8 @@ Emitted when the notification is closed by manual intervention from the user.
|
||||
This event is not guaranteed to be emitted in all cases where the notification
|
||||
is closed.
|
||||
|
||||
On Windows, the `close` event can be emitted in one of three ways: programmatic dismissal with `notification.close()`, by the user closing the notification, or via system timeout. If a notification is in the Action Center after the initial `close` event is emitted, a call to `notification.close()` will remove the notification from the action center but the `close` event will not be emitted again.
|
||||
|
||||
#### Event: 'reply' _macOS_
|
||||
|
||||
Returns:
|
||||
@@ -127,6 +129,8 @@ shown notification and create a new one with identical properties.
|
||||
|
||||
Dismisses the notification.
|
||||
|
||||
On Windows, calling `notification.close()` while the notification is visible on screen will dismiss the notification and remove it from the Action Center. If `notification.close()` is called after the notification is no longer visible on screen, calling `notification.close()` will try remove it from the Action Center.
|
||||
|
||||
### Instance Properties
|
||||
|
||||
#### `notification.title`
|
||||
|
||||
@@ -6,7 +6,7 @@ Process: [Main](../glossary.md#main-process)
|
||||
|
||||
For example:
|
||||
|
||||
```javascript
|
||||
```js
|
||||
const { powerSaveBlocker } = require('electron')
|
||||
|
||||
const id = powerSaveBlocker.start('prevent-display-sleep')
|
||||
|
||||
@@ -7,7 +7,7 @@ Process: [Main](../glossary.md#main-process)
|
||||
An example of implementing a protocol that has the same effect as the
|
||||
`file://` protocol:
|
||||
|
||||
```javascript
|
||||
```js
|
||||
const { app, protocol, net } = require('electron')
|
||||
|
||||
app.whenReady().then(() => {
|
||||
@@ -31,7 +31,7 @@ a different session and your custom protocol will not work if you just use
|
||||
To have your custom protocol work in combination with a custom session, you need
|
||||
to register it to that session explicitly.
|
||||
|
||||
```javascript
|
||||
```js
|
||||
const { app, BrowserWindow, net, protocol, session } = require('electron')
|
||||
const path = require('node:path')
|
||||
const url = require('url')
|
||||
@@ -61,13 +61,14 @@ The `protocol` module has the following methods:
|
||||
module gets emitted and can be called only once.
|
||||
|
||||
Registers the `scheme` as standard, secure, bypasses content security policy for
|
||||
resources, allows registering ServiceWorker, supports fetch API, and streaming
|
||||
video/audio. Specify a privilege with the value of `true` to enable the capability.
|
||||
resources, allows registering ServiceWorker, supports fetch API, streaming
|
||||
video/audio, and V8 code cache. Specify a privilege with the value of `true` to
|
||||
enable the capability.
|
||||
|
||||
An example of registering a privileged scheme, that bypasses Content Security
|
||||
Policy:
|
||||
|
||||
```javascript
|
||||
```js
|
||||
const { protocol } = require('electron')
|
||||
protocol.registerSchemesAsPrivileged([
|
||||
{ scheme: 'foo', privileges: { bypassCSP: true } }
|
||||
@@ -122,7 +123,7 @@ Example:
|
||||
|
||||
```js
|
||||
const { app, net, protocol } = require('electron')
|
||||
const { join } = require('node:path')
|
||||
const path = require('node:path')
|
||||
const { pathToFileURL } = require('url')
|
||||
|
||||
protocol.registerSchemesAsPrivileged([
|
||||
@@ -145,9 +146,19 @@ app.whenReady().then(() => {
|
||||
headers: { 'content-type': 'text/html' }
|
||||
})
|
||||
}
|
||||
// NB, this does not check for paths that escape the bundle, e.g.
|
||||
// NB, this checks for paths that escape the bundle, e.g.
|
||||
// app://bundle/../../secret_file.txt
|
||||
return net.fetch(pathToFileURL(join(__dirname, pathname)).toString())
|
||||
const pathToServe = path.resolve(__dirname, pathname)
|
||||
const relativePath = path.relative(__dirname, pathToServe)
|
||||
const isSafe = relativePath && !relativePath.startsWith('..') && !path.isAbsolute(relativePath)
|
||||
if (!isSafe) {
|
||||
return new Response('bad', {
|
||||
status: 400,
|
||||
headers: { 'content-type': 'text/html' }
|
||||
})
|
||||
}
|
||||
|
||||
return net.fetch(pathToFileURL(pathToServe).toString())
|
||||
} else if (host === 'api') {
|
||||
return net.fetch('https://api.my-server.com/' + pathname, {
|
||||
method: req.method,
|
||||
@@ -212,7 +223,7 @@ property.
|
||||
|
||||
Example:
|
||||
|
||||
```javascript
|
||||
```js
|
||||
protocol.registerBufferProtocol('atom', (request, callback) => {
|
||||
callback({ mimeType: 'text/html', data: Buffer.from('<h5>Response</h5>') })
|
||||
})
|
||||
@@ -267,7 +278,7 @@ has the `data` property.
|
||||
|
||||
Example:
|
||||
|
||||
```javascript
|
||||
```js
|
||||
const { protocol } = require('electron')
|
||||
const { PassThrough } = require('stream')
|
||||
|
||||
@@ -292,7 +303,7 @@ protocol.registerStreamProtocol('atom', (request, callback) => {
|
||||
It is possible to pass any object that implements the readable stream API (emits
|
||||
`data`/`end`/`error` events). For example, here's how a file could be returned:
|
||||
|
||||
```javascript
|
||||
```js
|
||||
protocol.registerStreamProtocol('atom', (request, callback) => {
|
||||
callback(fs.createReadStream('index.html'))
|
||||
})
|
||||
|
||||
@@ -6,7 +6,7 @@ Process: [Main](../glossary.md#main-process)
|
||||
|
||||
For example, when registering for push notifications via Apple push notification services (APNS):
|
||||
|
||||
```javascript
|
||||
```js
|
||||
const { pushNotifications, Notification } = require('electron')
|
||||
|
||||
pushNotifications.registerForAPNSNotifications().then((token) => {
|
||||
|
||||
@@ -14,20 +14,29 @@ property, so writing `let { screen } = require('electron')` will not work.
|
||||
|
||||
An example of creating a window that fills the whole screen:
|
||||
|
||||
```javascript fiddle='docs/fiddles/screen/fit-screen'
|
||||
const { app, BrowserWindow, screen } = require('electron')
|
||||
```fiddle docs/fiddles/screen/fit-screen
|
||||
// Retrieve information about screen size, displays, cursor position, etc.
|
||||
//
|
||||
// For more info, see:
|
||||
// https://www.electronjs.org/docs/latest/api/screen
|
||||
|
||||
const { app, BrowserWindow, screen } = require('electron/main')
|
||||
|
||||
let mainWindow = null
|
||||
|
||||
let win
|
||||
app.whenReady().then(() => {
|
||||
const { width, height } = screen.getPrimaryDisplay().workAreaSize
|
||||
win = new BrowserWindow({ width, height })
|
||||
win.loadURL('https://github.com')
|
||||
// Create a window that fills the screen's available work area.
|
||||
const primaryDisplay = screen.getPrimaryDisplay()
|
||||
const { width, height } = primaryDisplay.workAreaSize
|
||||
|
||||
mainWindow = new BrowserWindow({ width, height })
|
||||
mainWindow.loadURL('https://electronjs.org')
|
||||
})
|
||||
```
|
||||
|
||||
Another example of creating a window in the external display:
|
||||
|
||||
```javascript
|
||||
```js
|
||||
const { app, BrowserWindow, screen } = require('electron')
|
||||
|
||||
let win
|
||||
|
||||
@@ -10,7 +10,7 @@ a `Session`.
|
||||
|
||||
For example:
|
||||
|
||||
```javascript
|
||||
```js
|
||||
const { session } = require('electron')
|
||||
|
||||
// Get all service workers.
|
||||
|
||||
@@ -9,7 +9,7 @@ The `session` module can be used to create new `Session` objects.
|
||||
You can also access the `session` of existing pages by using the `session`
|
||||
property of [`WebContents`](web-contents.md), or from the `session` module.
|
||||
|
||||
```javascript
|
||||
```js
|
||||
const { BrowserWindow } = require('electron')
|
||||
|
||||
const win = new BrowserWindow({ width: 800, height: 600 })
|
||||
@@ -75,7 +75,7 @@ _This class is not exported from the `'electron'` module. It is only available a
|
||||
|
||||
You can create a `Session` object in the `session` module:
|
||||
|
||||
```javascript
|
||||
```js
|
||||
const { session } = require('electron')
|
||||
const ses = session.fromPartition('persist:name')
|
||||
console.log(ses.getUserAgent())
|
||||
@@ -98,7 +98,7 @@ Emitted when Electron is about to download `item` in `webContents`.
|
||||
Calling `event.preventDefault()` will cancel the download and `item` will not be
|
||||
available from next tick of the process.
|
||||
|
||||
```javascript @ts-expect-error=[4]
|
||||
```js @ts-expect-error=[4]
|
||||
const { session } = require('electron')
|
||||
session.defaultSession.on('will-download', (event, item, webContents) => {
|
||||
event.preventDefault()
|
||||
@@ -214,7 +214,7 @@ cancel the request. Additionally, permissioning on `navigator.hid` can
|
||||
be further managed by using [`ses.setPermissionCheckHandler(handler)`](#sessetpermissioncheckhandlerhandler)
|
||||
and [`ses.setDevicePermissionHandler(handler)`](#sessetdevicepermissionhandlerhandler).
|
||||
|
||||
```javascript @ts-type={fetchGrantedDevices:()=>(Array<Electron.DevicePermissionHandlerHandlerDetails['device']>)}
|
||||
```js @ts-type={fetchGrantedDevices:()=>(Array<Electron.DevicePermissionHandlerHandlerDetails['device']>)}
|
||||
const { app, BrowserWindow } = require('electron')
|
||||
|
||||
let win = null
|
||||
@@ -266,7 +266,7 @@ Returns:
|
||||
|
||||
* `event` Event
|
||||
* `details` Object
|
||||
* `device` [HIDDevice[]](structures/hid-device.md)
|
||||
* `device` [HIDDevice](structures/hid-device.md)
|
||||
* `frame` [WebFrameMain](web-frame-main.md)
|
||||
|
||||
Emitted after `navigator.hid.requestDevice` has been called and
|
||||
@@ -281,7 +281,7 @@ Returns:
|
||||
|
||||
* `event` Event
|
||||
* `details` Object
|
||||
* `device` [HIDDevice[]](structures/hid-device.md)
|
||||
* `device` [HIDDevice](structures/hid-device.md)
|
||||
* `frame` [WebFrameMain](web-frame-main.md)
|
||||
|
||||
Emitted after `navigator.hid.requestDevice` has been called and
|
||||
@@ -296,7 +296,7 @@ Returns:
|
||||
|
||||
* `event` Event
|
||||
* `details` Object
|
||||
* `device` [HIDDevice[]](structures/hid-device.md)
|
||||
* `device` [HIDDevice](structures/hid-device.md)
|
||||
* `origin` string (optional) - The origin that the device has been revoked from.
|
||||
|
||||
Emitted after `HIDDevice.forget()` has been called. This event can be used
|
||||
@@ -320,7 +320,7 @@ cancel the request. Additionally, permissioning on `navigator.serial` can
|
||||
be managed by using [ses.setPermissionCheckHandler(handler)](#sessetpermissioncheckhandlerhandler)
|
||||
with the `serial` permission.
|
||||
|
||||
```javascript @ts-type={fetchGrantedDevices:()=>(Array<Electron.DevicePermissionHandlerHandlerDetails['device']>)}
|
||||
```js @ts-type={fetchGrantedDevices:()=>(Array<Electron.DevicePermissionHandlerHandlerDetails['device']>)}
|
||||
const { app, BrowserWindow } = require('electron')
|
||||
|
||||
let win = null
|
||||
@@ -463,7 +463,7 @@ cancel the request. Additionally, permissioning on `navigator.usb` can
|
||||
be further managed by using [`ses.setPermissionCheckHandler(handler)`](#sessetpermissioncheckhandlerhandler)
|
||||
and [`ses.setDevicePermissionHandler(handler)`](#sessetdevicepermissionhandlerhandler).
|
||||
|
||||
```javascript @ts-type={fetchGrantedDevices:()=>(Array<Electron.DevicePermissionHandlerHandlerDetails['device']>)} @ts-type={updateGrantedDevices:(devices:Array<Electron.DevicePermissionHandlerHandlerDetails['device']>)=>void}
|
||||
```js @ts-type={fetchGrantedDevices:()=>(Array<Electron.DevicePermissionHandlerHandlerDetails['device']>)} @ts-type={updateGrantedDevices:(devices:Array<Electron.DevicePermissionHandlerHandlerDetails['device']>)=>void}
|
||||
const { app, BrowserWindow } = require('electron')
|
||||
|
||||
let win = null
|
||||
@@ -589,105 +589,15 @@ Writes any unwritten DOMStorage data to disk.
|
||||
|
||||
#### `ses.setProxy(config)`
|
||||
|
||||
* `config` Object
|
||||
* `mode` string (optional) - The proxy mode. Should be one of `direct`,
|
||||
`auto_detect`, `pac_script`, `fixed_servers` or `system`. If it's
|
||||
unspecified, it will be automatically determined based on other specified
|
||||
options.
|
||||
* `direct`
|
||||
In direct mode all connections are created directly, without any proxy involved.
|
||||
* `auto_detect`
|
||||
In auto_detect mode the proxy configuration is determined by a PAC script that can
|
||||
be downloaded at http://wpad/wpad.dat.
|
||||
* `pac_script`
|
||||
In pac_script mode the proxy configuration is determined by a PAC script that is
|
||||
retrieved from the URL specified in the `pacScript`. This is the default mode
|
||||
if `pacScript` is specified.
|
||||
* `fixed_servers`
|
||||
In fixed_servers mode the proxy configuration is specified in `proxyRules`.
|
||||
This is the default mode if `proxyRules` is specified.
|
||||
* `system`
|
||||
In system mode the proxy configuration is taken from the operating system.
|
||||
Note that the system mode is different from setting no proxy configuration.
|
||||
In the latter case, Electron falls back to the system settings
|
||||
only if no command-line options influence the proxy configuration.
|
||||
* `pacScript` string (optional) - The URL associated with the PAC file.
|
||||
* `proxyRules` string (optional) - Rules indicating which proxies to use.
|
||||
* `proxyBypassRules` string (optional) - Rules indicating which URLs should
|
||||
bypass the proxy settings.
|
||||
* `config` [ProxyConfig](structures/proxy-config.md)
|
||||
|
||||
Returns `Promise<void>` - Resolves when the proxy setting process is complete.
|
||||
|
||||
Sets the proxy settings.
|
||||
|
||||
When `mode` is unspecified, `pacScript` and `proxyRules` are provided together, the `proxyRules`
|
||||
option is ignored and `pacScript` configuration is applied.
|
||||
|
||||
You may need `ses.closeAllConnections` to close currently in flight connections to prevent
|
||||
pooled sockets using previous proxy from being reused by future requests.
|
||||
|
||||
The `proxyRules` has to follow the rules below:
|
||||
|
||||
```sh
|
||||
proxyRules = schemeProxies[";"<schemeProxies>]
|
||||
schemeProxies = [<urlScheme>"="]<proxyURIList>
|
||||
urlScheme = "http" | "https" | "ftp" | "socks"
|
||||
proxyURIList = <proxyURL>[","<proxyURIList>]
|
||||
proxyURL = [<proxyScheme>"://"]<proxyHost>[":"<proxyPort>]
|
||||
```
|
||||
|
||||
For example:
|
||||
|
||||
* `http=foopy:80;ftp=foopy2` - Use HTTP proxy `foopy:80` for `http://` URLs, and
|
||||
HTTP proxy `foopy2:80` for `ftp://` URLs.
|
||||
* `foopy:80` - Use HTTP proxy `foopy:80` for all URLs.
|
||||
* `foopy:80,bar,direct://` - Use HTTP proxy `foopy:80` for all URLs, failing
|
||||
over to `bar` if `foopy:80` is unavailable, and after that using no proxy.
|
||||
* `socks4://foopy` - Use SOCKS v4 proxy `foopy:1080` for all URLs.
|
||||
* `http=foopy,socks5://bar.com` - Use HTTP proxy `foopy` for http URLs, and fail
|
||||
over to the SOCKS5 proxy `bar.com` if `foopy` is unavailable.
|
||||
* `http=foopy,direct://` - Use HTTP proxy `foopy` for http URLs, and use no
|
||||
proxy if `foopy` is unavailable.
|
||||
* `http=foopy;socks=foopy2` - Use HTTP proxy `foopy` for http URLs, and use
|
||||
`socks4://foopy2` for all other URLs.
|
||||
|
||||
The `proxyBypassRules` is a comma separated list of rules described below:
|
||||
|
||||
* `[ URL_SCHEME "://" ] HOSTNAME_PATTERN [ ":" <port> ]`
|
||||
|
||||
Match all hostnames that match the pattern HOSTNAME_PATTERN.
|
||||
|
||||
Examples:
|
||||
"foobar.com", "\*foobar.com", "\*.foobar.com", "\*foobar.com:99",
|
||||
"https://x.\*.y.com:99"
|
||||
|
||||
* `"." HOSTNAME_SUFFIX_PATTERN [ ":" PORT ]`
|
||||
|
||||
Match a particular domain suffix.
|
||||
|
||||
Examples:
|
||||
".google.com", ".com", "http://.google.com"
|
||||
|
||||
* `[ SCHEME "://" ] IP_LITERAL [ ":" PORT ]`
|
||||
|
||||
Match URLs which are IP address literals.
|
||||
|
||||
Examples:
|
||||
"127.0.1", "\[0:0::1]", "\[::1]", "http://\[::1]:99"
|
||||
|
||||
* `IP_LITERAL "/" PREFIX_LENGTH_IN_BITS`
|
||||
|
||||
Match any URL that is to an IP literal that falls between the
|
||||
given range. IP range is specified using CIDR notation.
|
||||
|
||||
Examples:
|
||||
"192.168.1.1/16", "fefe:13::abc/33".
|
||||
|
||||
* `<local>`
|
||||
|
||||
Match local addresses. The meaning of `<local>` is whether the
|
||||
host matches one of: "127.0.0.1", "::1", "localhost".
|
||||
|
||||
#### `ses.resolveHost(host, [options])`
|
||||
|
||||
* `host` string - Hostname to resolve.
|
||||
@@ -754,7 +664,7 @@ Sets download saving directory. By default, the download directory will be the
|
||||
|
||||
Emulates network with the given configuration for the `session`.
|
||||
|
||||
```javascript
|
||||
```js
|
||||
const win = new BrowserWindow()
|
||||
|
||||
// To emulate a GPRS connection with 50kbps throughput and 500 ms latency.
|
||||
@@ -785,7 +695,7 @@ Returns `Promise<void>` - Resolves when all connections are closed.
|
||||
#### `ses.fetch(input[, init])`
|
||||
|
||||
* `input` string | [GlobalRequest](https://nodejs.org/api/globals.html#request)
|
||||
* `init` [RequestInit](https://developer.mozilla.org/en-US/docs/Web/API/fetch#options) (optional)
|
||||
* `init` [RequestInit](https://developer.mozilla.org/en-US/docs/Web/API/fetch#options) & { bypassCustomProtocolHandlers?: boolean } (optional)
|
||||
|
||||
Returns `Promise<GlobalResponse>` - see [Response](https://developer.mozilla.org/en-US/docs/Web/API/Response).
|
||||
|
||||
@@ -868,7 +778,7 @@ calling `callback(-2)` rejects it.
|
||||
Calling `setCertificateVerifyProc(null)` will revert back to default certificate
|
||||
verify proc.
|
||||
|
||||
```javascript
|
||||
```js
|
||||
const { BrowserWindow } = require('electron')
|
||||
const win = new BrowserWindow()
|
||||
|
||||
@@ -901,6 +811,7 @@ win.webContents.session.setCertificateVerifyProc((request, callback) => {
|
||||
* `midiSysex` - Request the use of system exclusive messages in the [Web MIDI API](https://developer.mozilla.org/en-US/docs/Web/API/Web_MIDI_API).
|
||||
* `notifications` - Request notification creation and the ability to display them in the user's system tray using the [Notifications API](https://developer.mozilla.org/en-US/docs/Web/API/notification)
|
||||
* `pointerLock` - Request to directly interpret mouse movements as an input method via the [Pointer Lock API](https://developer.mozilla.org/en-US/docs/Web/API/Pointer_Lock_API). These requests always appear to originate from the main frame.
|
||||
* `keyboardLock` - Request capture of keypresses for any or all of the keys on the physical keyboard via the [Keyboard Lock API](https://developer.mozilla.org/en-US/docs/Web/API/Keyboard/lock). These requests always appear to originate from the main frame.
|
||||
* `openExternal` - Request to open links in external applications.
|
||||
* `window-management` - Request access to enumerate screens using the [`getScreenDetails`](https://developer.chrome.com/en/articles/multi-screen-window-placement/) API.
|
||||
* `unknown` - An unrecognized permission request.
|
||||
@@ -920,7 +831,7 @@ To clear the handler, call `setPermissionRequestHandler(null)`. Please note tha
|
||||
you must also implement `setPermissionCheckHandler` to get complete permission handling.
|
||||
Most web APIs do a permission check and then make a permission request if the check is denied.
|
||||
|
||||
```javascript
|
||||
```js
|
||||
const { session } = require('electron')
|
||||
session.fromPartition('some-partition').setPermissionRequestHandler((webContents, permission, callback) => {
|
||||
if (webContents.getURL() === 'some-host' && permission === 'notifications') {
|
||||
@@ -966,7 +877,7 @@ you must also implement `setPermissionRequestHandler` to get complete permission
|
||||
Most web APIs do a permission check and then make a permission request if the check is denied.
|
||||
To clear the handler, call `setPermissionCheckHandler(null)`.
|
||||
|
||||
```javascript
|
||||
```js
|
||||
const { session } = require('electron')
|
||||
const url = require('url')
|
||||
session.fromPartition('some-partition').setPermissionCheckHandler((webContents, permission, requestingOrigin) => {
|
||||
@@ -1011,7 +922,7 @@ via the `navigator.mediaDevices.getDisplayMedia` API. Use the
|
||||
[desktopCapturer](desktop-capturer.md) API to choose which stream(s) to grant
|
||||
access to.
|
||||
|
||||
```javascript
|
||||
```js
|
||||
const { session, desktopCapturer } = require('electron')
|
||||
|
||||
session.defaultSession.setDisplayMediaRequestHandler((request, callback) => {
|
||||
@@ -1025,7 +936,7 @@ session.defaultSession.setDisplayMediaRequestHandler((request, callback) => {
|
||||
Passing a [WebFrameMain](web-frame-main.md) object as a video or audio stream
|
||||
will capture the video or audio stream from that frame.
|
||||
|
||||
```javascript
|
||||
```js
|
||||
const { session } = require('electron')
|
||||
|
||||
session.defaultSession.setDisplayMediaRequestHandler((request, callback) => {
|
||||
@@ -1050,11 +961,11 @@ To clear the handler, call `setDevicePermissionHandler(null)`.
|
||||
This handler can be used to provide default permissioning to devices without first calling for permission
|
||||
to devices (eg via `navigator.hid.requestDevice`). If this handler is not defined, the default device
|
||||
permissions as granted through device selection (eg via `navigator.hid.requestDevice`) will be used.
|
||||
Additionally, the default behavior of Electron is to store granted device permision in memory.
|
||||
Additionally, the default behavior of Electron is to store granted device permission in memory.
|
||||
If longer term storage is needed, a developer can store granted device
|
||||
permissions (eg when handling the `select-hid-device` event) and then read from that storage with `setDevicePermissionHandler`.
|
||||
|
||||
```javascript @ts-type={fetchGrantedDevices:()=>(Array<Electron.DevicePermissionHandlerHandlerDetails['device']>)}
|
||||
```js @ts-type={fetchGrantedDevices:()=>(Array<Electron.DevicePermissionHandlerHandlerDetails['device']>)}
|
||||
const { app, BrowserWindow } = require('electron')
|
||||
|
||||
let win = null
|
||||
@@ -1136,7 +1047,7 @@ The return value for the handler is a string array of USB classes which should b
|
||||
Returning an empty string array from the handler will allow all USB classes; returning the passed in array will maintain the default list of protected USB classes (this is also the default behavior if a handler is not defined).
|
||||
To clear the handler, call `setUSBProtectedClassesHandler(null)`.
|
||||
|
||||
```javascript
|
||||
```js
|
||||
const { app, BrowserWindow } = require('electron')
|
||||
|
||||
let win = null
|
||||
@@ -1191,7 +1102,7 @@ that requires additional validation will be automatically cancelled.
|
||||
macOS does not require a handler because macOS handles the pairing
|
||||
automatically. To clear the handler, call `setBluetoothPairingHandler(null)`.
|
||||
|
||||
```javascript
|
||||
```js
|
||||
const { app, BrowserWindow, session } = require('electron')
|
||||
const path = require('node:path')
|
||||
|
||||
@@ -1237,7 +1148,7 @@ Clears the host resolver cache.
|
||||
Dynamically sets whether to always send credentials for HTTP NTLM or Negotiate
|
||||
authentication.
|
||||
|
||||
```javascript
|
||||
```js
|
||||
const { session } = require('electron')
|
||||
// consider any url ending with `example.com`, `foobar.com`, `baz`
|
||||
// for integrated authentication.
|
||||
@@ -1355,6 +1266,10 @@ registered.
|
||||
Sets the directory to store the generated JS [code cache](https://v8.dev/blog/code-caching-for-devs) for this session. The directory is not required to be created by the user before this call, the runtime will create if it does not exist otherwise will use the existing directory. If directory cannot be created, then code cache will not be used and all operations related to code cache will fail silently inside the runtime. By default, the directory will be `Code Cache` under the
|
||||
respective user data folder.
|
||||
|
||||
Note that by default code cache is only enabled for http(s) URLs, to enable code
|
||||
cache for custom protocols, `codeCache: true` and `standard: true` must be
|
||||
specified when registering the protocol.
|
||||
|
||||
#### `ses.clearCodeCaches(options)`
|
||||
|
||||
* `options` Object
|
||||
@@ -1542,7 +1457,7 @@ A [`WebRequest`](web-request.md) object for this session.
|
||||
|
||||
A [`Protocol`](protocol.md) object for this session.
|
||||
|
||||
```javascript
|
||||
```js
|
||||
const { app, session } = require('electron')
|
||||
const path = require('node:path')
|
||||
|
||||
@@ -1561,7 +1476,7 @@ app.whenReady().then(() => {
|
||||
|
||||
A [`NetLog`](net-log.md) object for this session.
|
||||
|
||||
```javascript
|
||||
```js
|
||||
const { app, session } = require('electron')
|
||||
|
||||
app.whenReady().then(async () => {
|
||||
|
||||
@@ -8,7 +8,7 @@ The `shell` module provides functions related to desktop integration.
|
||||
|
||||
An example of opening a URL in the user's default browser:
|
||||
|
||||
```javascript
|
||||
```js
|
||||
const { shell } = require('electron')
|
||||
|
||||
shell.openExternal('https://github.com')
|
||||
|
||||
@@ -9,3 +9,5 @@
|
||||
* `supportFetchAPI` boolean (optional) - Default false.
|
||||
* `corsEnabled` boolean (optional) - Default false.
|
||||
* `stream` boolean (optional) - Default false.
|
||||
* `codeCache` boolean (optional) - Enable V8 code cache for the scheme, only
|
||||
works when `standard` is also set to true. Default false.
|
||||
|
||||
@@ -1,22 +1,25 @@
|
||||
# Display Object
|
||||
|
||||
* `id` number - Unique identifier associated with the display.
|
||||
* `accelerometerSupport` string - Can be `available`, `unavailable`, `unknown`.
|
||||
* `bounds` [Rectangle](rectangle.md) - the bounds of the display in DIP points.
|
||||
* `colorDepth` number - The number of bits per pixel.
|
||||
* `colorSpace` string - represent a color space (three-dimensional object which contains all realizable color combinations) for the purpose of color conversions.
|
||||
* `depthPerComponent` number - The number of bits per color component.
|
||||
* `detected` boolean - `true`` if the display is detected by the system.
|
||||
* `displayFrequency` number - The display refresh rate.
|
||||
* `id` number - Unique identifier associated with the display. A value of of -1 means the display is invalid or the correct `id` is not yet known, and a value of -10 means the display is a virtual display assigned to a unified desktop.
|
||||
* `internal` boolean - `true` for an internal display and `false` for an external display.
|
||||
* `label` string - User-friendly label, determined by the platform.
|
||||
* `maximumCursorSize` [Size](size.md) - Maximum cursor size in native pixels.
|
||||
* `nativeOrigin` [Point](point.md) - Returns the display's origin in pixel coordinates. Only available on windowing systems like X11 that position displays in pixel coordinates.
|
||||
* `rotation` number - Can be 0, 90, 180, 270, represents screen rotation in
|
||||
clock-wise degrees.
|
||||
* `scaleFactor` number - Output device's pixel scale factor.
|
||||
* `touchSupport` string - Can be `available`, `unavailable`, `unknown`.
|
||||
* `monochrome` boolean - Whether or not the display is a monochrome display.
|
||||
* `accelerometerSupport` string - Can be `available`, `unavailable`, `unknown`.
|
||||
* `colorSpace` string - represent a color space (three-dimensional object which contains all realizable color combinations) for the purpose of color conversions
|
||||
* `colorDepth` number - The number of bits per pixel.
|
||||
* `depthPerComponent` number - The number of bits per color component.
|
||||
* `displayFrequency` number - The display refresh rate.
|
||||
* `bounds` [Rectangle](rectangle.md) - the bounds of the display in DIP points.
|
||||
* `size` [Size](size.md)
|
||||
* `workArea` [Rectangle](rectangle.md) - the work area of the display in DIP points.
|
||||
* `workAreaSize` [Size](size.md)
|
||||
* `internal` boolean - `true` for an internal display and `false` for an external display
|
||||
* `workAreaSize` [Size](size.md) - The size of the work area.
|
||||
|
||||
The `Display` object represents a physical display connected to the system. A
|
||||
fake `Display` may exist on a headless system, or a `Display` may correspond to
|
||||
|
||||
@@ -14,7 +14,7 @@ The number represented by `status` means different things on different platforms
|
||||
Below is an example of some of the additional options that may be set which
|
||||
may be different on each platform.
|
||||
|
||||
```javascript
|
||||
```js
|
||||
{
|
||||
name: 'Austin_4th_Floor_Printer___C02XK13BJHD4',
|
||||
displayName: 'Austin 4th Floor Printer @ C02XK13BJHD4',
|
||||
|
||||
86
docs/api/structures/proxy-config.md
Normal file
86
docs/api/structures/proxy-config.md
Normal file
@@ -0,0 +1,86 @@
|
||||
# ProxyConfig Object
|
||||
|
||||
* `mode` string (optional) - The proxy mode. Should be one of `direct`,
|
||||
`auto_detect`, `pac_script`, `fixed_servers` or `system`.
|
||||
Defaults to `pac_script` proxy mode if `pacScript` option is specified
|
||||
otherwise defaults to `fixed_servers`.
|
||||
* `direct` - In direct mode all connections are created directly, without any proxy involved.
|
||||
* `auto_detect` - In auto_detect mode the proxy configuration is determined by a PAC script that can
|
||||
be downloaded at http://wpad/wpad.dat.
|
||||
* `pac_script` - In pac_script mode the proxy configuration is determined by a PAC script that is
|
||||
retrieved from the URL specified in the `pacScript`. This is the default mode if `pacScript` is specified.
|
||||
* `fixed_servers` - In fixed_servers mode the proxy configuration is specified in `proxyRules`.
|
||||
This is the default mode if `proxyRules` is specified.
|
||||
* `system` - In system mode the proxy configuration is taken from the operating system.
|
||||
Note that the system mode is different from setting no proxy configuration.
|
||||
In the latter case, Electron falls back to the system settings only if no
|
||||
command-line options influence the proxy configuration.
|
||||
* `pacScript` string (optional) - The URL associated with the PAC file.
|
||||
* `proxyRules` string (optional) - Rules indicating which proxies to use.
|
||||
* `proxyBypassRules` string (optional) - Rules indicating which URLs should
|
||||
bypass the proxy settings.
|
||||
|
||||
When `mode` is unspecified, `pacScript` and `proxyRules` are provided together, the `proxyRules`
|
||||
option is ignored and `pacScript` configuration is applied.
|
||||
|
||||
The `proxyRules` has to follow the rules below:
|
||||
|
||||
```sh
|
||||
proxyRules = schemeProxies[";"<schemeProxies>]
|
||||
schemeProxies = [<urlScheme>"="]<proxyURIList>
|
||||
urlScheme = "http" | "https" | "ftp" | "socks"
|
||||
proxyURIList = <proxyURL>[","<proxyURIList>]
|
||||
proxyURL = [<proxyScheme>"://"]<proxyHost>[":"<proxyPort>]
|
||||
```
|
||||
|
||||
For example:
|
||||
|
||||
* `http=foopy:80;ftp=foopy2` - Use HTTP proxy `foopy:80` for `http://` URLs, and
|
||||
HTTP proxy `foopy2:80` for `ftp://` URLs.
|
||||
* `foopy:80` - Use HTTP proxy `foopy:80` for all URLs.
|
||||
* `foopy:80,bar,direct://` - Use HTTP proxy `foopy:80` for all URLs, failing
|
||||
over to `bar` if `foopy:80` is unavailable, and after that using no proxy.
|
||||
* `socks4://foopy` - Use SOCKS v4 proxy `foopy:1080` for all URLs.
|
||||
* `http=foopy,socks5://bar.com` - Use HTTP proxy `foopy` for http URLs, and fail
|
||||
over to the SOCKS5 proxy `bar.com` if `foopy` is unavailable.
|
||||
* `http=foopy,direct://` - Use HTTP proxy `foopy` for http URLs, and use no
|
||||
proxy if `foopy` is unavailable.
|
||||
* `http=foopy;socks=foopy2` - Use HTTP proxy `foopy` for http URLs, and use
|
||||
`socks4://foopy2` for all other URLs.
|
||||
|
||||
The `proxyBypassRules` is a comma separated list of rules described below:
|
||||
|
||||
* `[ URL_SCHEME "://" ] HOSTNAME_PATTERN [ ":" <port> ]`
|
||||
|
||||
Match all hostnames that match the pattern HOSTNAME_PATTERN.
|
||||
|
||||
Examples:
|
||||
"foobar.com", "\*foobar.com", "\*.foobar.com", "\*foobar.com:99",
|
||||
"https://x.\*.y.com:99"
|
||||
|
||||
* `"." HOSTNAME_SUFFIX_PATTERN [ ":" PORT ]`
|
||||
|
||||
Match a particular domain suffix.
|
||||
|
||||
Examples:
|
||||
".google.com", ".com", "http://.google.com"
|
||||
|
||||
* `[ SCHEME "://" ] IP_LITERAL [ ":" PORT ]`
|
||||
|
||||
Match URLs which are IP address literals.
|
||||
|
||||
Examples:
|
||||
"127.0.1", "\[0:0::1]", "\[::1]", "http://\[::1]:99"
|
||||
|
||||
* `IP_LITERAL "/" PREFIX_LENGTH_IN_BITS`
|
||||
|
||||
Match any URL that is to an IP literal that falls between the
|
||||
given range. IP range is specified using CIDR notation.
|
||||
|
||||
Examples:
|
||||
"192.168.1.1/16", "fefe:13::abc/33".
|
||||
|
||||
* `<local>`
|
||||
|
||||
Match local addresses. The meaning of `<local>` is whether the
|
||||
host matches one of: "127.0.0.1", "::1", "localhost".
|
||||
@@ -9,4 +9,4 @@
|
||||
* `array` Array\<unknown>
|
||||
* `dictionary` Record\<string, unknown>
|
||||
|
||||
This type is a helper alias, no object will never exist of this type.
|
||||
This type is a helper alias, no object will ever exist of this type.
|
||||
|
||||
@@ -74,7 +74,11 @@
|
||||
* `defaultEncoding` string (optional) - Defaults to `ISO-8859-1`.
|
||||
* `backgroundThrottling` boolean (optional) - Whether to throttle animations and timers
|
||||
when the page becomes background. This also affects the
|
||||
[Page Visibility API](../browser-window.md#page-visibility). Defaults to `true`.
|
||||
[Page Visibility API](../browser-window.md#page-visibility). When at least one
|
||||
[webContents](../web-contents.md) displayed in a single
|
||||
[browserWindow](../browser-window.md) has disabled `backgroundThrottling` then
|
||||
frames will be drawn and swapped for the whole window and other
|
||||
[webContents](../web-contents.md) displayed by it. Defaults to `true`.
|
||||
* `offscreen` boolean (optional) - Whether to enable offscreen rendering for the browser
|
||||
window. Defaults to `false`. See the
|
||||
[offscreen rendering tutorial](../../tutorial/offscreen-rendering.md) for
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
Process: [Main](../glossary.md#main-process)
|
||||
|
||||
```javascript
|
||||
```js
|
||||
const { systemPreferences } = require('electron')
|
||||
console.log(systemPreferences.isAeroGlassEnabled())
|
||||
```
|
||||
@@ -189,7 +189,7 @@ enabled, and `false` otherwise.
|
||||
An example of using it to determine if you should create a transparent window or
|
||||
not (transparent windows won't work correctly when DWM composition is disabled):
|
||||
|
||||
```javascript
|
||||
```js
|
||||
const { BrowserWindow, systemPreferences } = require('electron')
|
||||
const browserOptions = { width: 1000, height: 800 }
|
||||
|
||||
@@ -306,7 +306,7 @@ This API is only available on macOS 10.14 Mojave or newer.
|
||||
* `window-background` - The background of a window.
|
||||
* `window-frame-text` - The text in the window's titlebar area.
|
||||
|
||||
Returns `string` - The system color setting in RGB hexadecimal form (`#ABCDEF`).
|
||||
Returns `string` - The system color setting in RGBA hexadecimal form (`#RRGGBBAA`).
|
||||
See the [Windows docs][windows-colors] and the [macOS docs][macos-colors] for more details.
|
||||
|
||||
The following colors are only available on macOS 10.14: `find-highlight`, `selected-content-background`, `separator`, `unemphasized-selected-content-background`, `unemphasized-selected-text-background`, and `unemphasized-selected-text`.
|
||||
@@ -348,7 +348,7 @@ Returns `boolean` - whether or not this device has the ability to use Touch ID.
|
||||
|
||||
Returns `Promise<void>` - resolves if the user has successfully authenticated with Touch ID.
|
||||
|
||||
```javascript
|
||||
```js
|
||||
const { systemPreferences } = require('electron')
|
||||
|
||||
systemPreferences.promptTouchID('To get consent for a Security-Gated Thing').then(success => {
|
||||
|
||||
@@ -79,7 +79,7 @@ immediately updates the escape item in the touch bar.
|
||||
Below is an example of a simple slot machine touch bar game with a button
|
||||
and some labels.
|
||||
|
||||
```javascript
|
||||
```js
|
||||
const { app, BrowserWindow, TouchBar } = require('electron')
|
||||
|
||||
const { TouchBarLabel, TouchBarButton, TouchBarSpacer } = TouchBar
|
||||
|
||||
@@ -8,7 +8,7 @@ Process: [Main](../glossary.md#main-process)
|
||||
|
||||
`Tray` is an [EventEmitter][event-emitter].
|
||||
|
||||
```javascript
|
||||
```js
|
||||
const { app, Menu, Tray } = require('electron')
|
||||
|
||||
let tray = null
|
||||
@@ -39,7 +39,7 @@ app.whenReady().then(() => {
|
||||
* In order for changes made to individual `MenuItem`s to take effect,
|
||||
you have to call `setContextMenu` again. For example:
|
||||
|
||||
```javascript
|
||||
```js
|
||||
const { app, Menu, Tray } = require('electron')
|
||||
|
||||
let appIcon = null
|
||||
@@ -60,7 +60,7 @@ app.whenReady().then(() => {
|
||||
|
||||
**MacOS**
|
||||
|
||||
* Icons passed to the Tray constructor should be [Template Images](native-image.md#template-image).
|
||||
* Icons passed to the Tray constructor should be [Template Images](native-image.md#template-image-macos).
|
||||
* To make sure your icon isn't grainy on retina monitors, be sure your `@2x` image is 144dpi.
|
||||
* If you are bundling your application (e.g., with webpack for development), be sure that the file names are not being mangled or hashed. The filename needs to end in Template, and the `@2x` image needs to have the same filename as the standard image, or MacOS will not magically invert your image's colors or use the high density image.
|
||||
* 16x16 (72dpi) and 32x32@2x (144dpi) work well for most icons.
|
||||
@@ -111,6 +111,15 @@ Returns:
|
||||
|
||||
Emitted when the tray icon is double clicked.
|
||||
|
||||
#### Event: 'middle-click' _Windows_
|
||||
|
||||
Returns:
|
||||
|
||||
* `event` [KeyboardEvent](structures/keyboard-event.md)
|
||||
* `bounds` [Rectangle](structures/rectangle.md) - The bounds of tray icon.
|
||||
|
||||
Emitted when the tray icon is middle clicked.
|
||||
|
||||
#### Event: 'balloon-show' _Windows_
|
||||
|
||||
Emitted when the tray balloon shows.
|
||||
@@ -178,7 +187,7 @@ Returns:
|
||||
|
||||
Emitted when the mouse clicks the tray icon.
|
||||
|
||||
#### Event: 'mouse-enter' _macOS_
|
||||
#### Event: 'mouse-enter' _macOS_ _Windows_
|
||||
|
||||
Returns:
|
||||
|
||||
@@ -187,7 +196,7 @@ Returns:
|
||||
|
||||
Emitted when the mouse enters the tray icon.
|
||||
|
||||
#### Event: 'mouse-leave' _macOS_
|
||||
#### Event: 'mouse-leave' _macOS_ _Windows_
|
||||
|
||||
Returns:
|
||||
|
||||
|
||||
@@ -21,15 +21,15 @@ Process: [Main](../glossary.md#main-process)<br />
|
||||
of the child process. Default is `inherit`.
|
||||
String value can be one of `pipe`, `ignore`, `inherit`, for more details on these values you can refer to
|
||||
[stdio][] documentation from Node.js. Currently this option only supports configuring `stdout` and
|
||||
`stderr` to either `pipe`, `inherit` or `ignore`. Configuring `stdin` is not supported; `stdin` will
|
||||
always be ignored.
|
||||
`stderr` to either `pipe`, `inherit` or `ignore`. Configuring `stdin` to any property other than `ignore` is not supported and will result in an error.
|
||||
For example, the supported values will be processed as following:
|
||||
* `pipe`: equivalent to \['ignore', 'pipe', 'pipe'] (the default)
|
||||
* `pipe`: equivalent to \['ignore', 'pipe', 'pipe']
|
||||
* `ignore`: equivalent to \['ignore', 'ignore', 'ignore']
|
||||
* `inherit`: equivalent to \['ignore', 'inherit', 'inherit']
|
||||
* `inherit`: equivalent to \['ignore', 'inherit', 'inherit'] (the default)
|
||||
* `serviceName` string (optional) - Name of the process that will appear in `name` property of
|
||||
[`child-process-gone` event of `app`](app.md#event-child-process-gone).
|
||||
Default is `node.mojom.NodeService`.
|
||||
[`ProcessMetric`](structures/process-metric.md) returned by [`app.getAppMetrics`](app.md#appgetappmetrics)
|
||||
and [`child-process-gone` event of `app`](app.md#event-child-process-gone).
|
||||
Default is `Node Utility Process`.
|
||||
* `allowLoadingUnsignedLibraries` boolean (optional) _macOS_ - With this flag, the utility process will be
|
||||
launched via the `Electron Helper (Plugin).app` helper executable on macOS, which can be
|
||||
codesigned with `com.apple.security.cs.disable-library-validation` and
|
||||
|
||||
@@ -9,7 +9,7 @@ It is responsible for rendering and controlling a web page and is a property of
|
||||
the [`BrowserWindow`](browser-window.md) object. An example of accessing the
|
||||
`webContents` object:
|
||||
|
||||
```javascript
|
||||
```js
|
||||
const { BrowserWindow } = require('electron')
|
||||
|
||||
const win = new BrowserWindow({ width: 800, height: 1500 })
|
||||
@@ -53,7 +53,7 @@ If you want to also observe navigations in `<iframe>`s, use [`will-frame-navigat
|
||||
|
||||
These methods can be accessed from the `webContents` module:
|
||||
|
||||
```javascript
|
||||
```js
|
||||
const { webContents } = require('electron')
|
||||
console.log(webContents)
|
||||
```
|
||||
@@ -439,7 +439,7 @@ Emitted when a `beforeunload` event handler is attempting to cancel a page unloa
|
||||
Calling `event.preventDefault()` will ignore the `beforeunload` event handler
|
||||
and allow the page to be unloaded.
|
||||
|
||||
```javascript
|
||||
```js
|
||||
const { BrowserWindow, dialog } = require('electron')
|
||||
const win = new BrowserWindow({ width: 800, height: 600 })
|
||||
win.webContents.on('will-prevent-unload', (event) => {
|
||||
@@ -460,20 +460,6 @@ win.webContents.on('will-prevent-unload', (event) => {
|
||||
|
||||
**Note:** This will be emitted for `BrowserViews` but will _not_ be respected - this is because we have chosen not to tie the `BrowserView` lifecycle to its owning BrowserWindow should one exist per the [specification](https://developer.mozilla.org/en-US/docs/Web/API/Window/beforeunload_event).
|
||||
|
||||
#### Event: 'crashed' _Deprecated_
|
||||
|
||||
Returns:
|
||||
|
||||
* `event` Event
|
||||
* `killed` boolean
|
||||
|
||||
Emitted when the renderer process crashes or is killed.
|
||||
|
||||
**Deprecated:** This event is superceded by the `render-process-gone` event
|
||||
which contains more information about why the render process disappeared. It
|
||||
isn't always because it crashed. The `killed` boolean can be replaced by
|
||||
checking `reason === 'killed'` when you switch to that event.
|
||||
|
||||
#### Event: 'render-process-gone'
|
||||
|
||||
Returns:
|
||||
@@ -541,7 +527,7 @@ and the menu shortcuts.
|
||||
To only prevent the menu shortcuts, use
|
||||
[`setIgnoreMenuShortcuts`](#contentssetignoremenushortcutsignore):
|
||||
|
||||
```javascript
|
||||
```js
|
||||
const { BrowserWindow } = require('electron')
|
||||
|
||||
const win = new BrowserWindow({ width: 800, height: 600 })
|
||||
@@ -783,9 +769,18 @@ Returns:
|
||||
word and spellchecker is enabled.
|
||||
* `frameCharset` string - The character encoding of the frame on which the
|
||||
menu was invoked.
|
||||
* `inputFieldType` string - If the context menu was invoked on an input
|
||||
field, the type of that field. Possible values include `none`, `plainText`,
|
||||
`password`, `other`.
|
||||
* `formControlType` string - The source that the context menu was invoked on.
|
||||
Possible values include `none`, `button-button`, `field-set`,
|
||||
`input-button`, `input-checkbox`, `input-color`, `input-date`,
|
||||
`input-datetime-local`, `input-email`, `input-file`, `input-hidden`,
|
||||
`input-image`, `input-month`, `input-number`, `input-password`, `input-radio`,
|
||||
`input-range`, `input-reset`, `input-search`, `input-submit`, `input-telephone`,
|
||||
`input-text`, `input-time`, `input-url`, `input-week`, `output`, `reset-button`,
|
||||
`select-list`, `select-list`, `select-multiple`, `select-one`, `submit-button`,
|
||||
and `text-area`,
|
||||
* `inputFieldType` string _Deprecated_ - If the context menu was invoked on an
|
||||
input field, the type of that field. Possible values include `none`,
|
||||
`plainText`, `password`, `other`.
|
||||
* `spellcheckEnabled` boolean - If the context is editable, whether or not spellchecking is enabled.
|
||||
* `menuSourceType` string - Input source that invoked the context menu.
|
||||
Can be `none`, `mouse`, `keyboard`, `touch`, `touchMenu`, `longPress`, `longTap`, `touchHandle`, `stylus`, `adjustSelection`, or `adjustSelectionReset`.
|
||||
@@ -842,7 +837,7 @@ Due to the nature of bluetooth, scanning for devices when
|
||||
`select-bluetooth-device` to fire multiple times until `callback` is called
|
||||
with either a device id or an empty string to cancel the request.
|
||||
|
||||
```javascript title='main.js'
|
||||
```js title='main.js'
|
||||
const { app, BrowserWindow } = require('electron')
|
||||
|
||||
let win = null
|
||||
@@ -877,7 +872,7 @@ Returns:
|
||||
Emitted when a new frame is generated. Only the dirty area is passed in the
|
||||
buffer.
|
||||
|
||||
```javascript
|
||||
```js
|
||||
const { BrowserWindow } = require('electron')
|
||||
|
||||
const win = new BrowserWindow({ webPreferences: { offscreen: true } })
|
||||
@@ -1009,7 +1004,7 @@ Loads the `url` in the window. The `url` must contain the protocol prefix,
|
||||
e.g. the `http://` or `file://`. If the load should bypass http cache then
|
||||
use the `pragma` header to achieve it.
|
||||
|
||||
```javascript
|
||||
```js
|
||||
const win = new BrowserWindow()
|
||||
const options = { extraHeaders: 'pragma: no-cache\n' }
|
||||
win.webContents.loadURL('https://github.com', options)
|
||||
@@ -1059,7 +1054,7 @@ Initiates a download of the resource at `url` without navigating. The
|
||||
|
||||
Returns `string` - The URL of the current web page.
|
||||
|
||||
```javascript
|
||||
```js
|
||||
const { BrowserWindow } = require('electron')
|
||||
const win = new BrowserWindow({ width: 800, height: 600 })
|
||||
win.loadURL('https://github.com').then(() => {
|
||||
@@ -1211,7 +1206,7 @@ Returns `string` - The user agent for this web page.
|
||||
|
||||
* `css` string
|
||||
* `options` Object (optional)
|
||||
* `cssOrigin` string (optional) - Can be either 'user' or 'author'. Sets the [cascade origin](https://www.w3.org/TR/css3-cascade/#cascade-origin) of the inserted stylesheet. Default is 'author'.
|
||||
* `cssOrigin` string (optional) - Can be 'user' or 'author'. Sets the [cascade origin](https://www.w3.org/TR/css3-cascade/#cascade-origin) of the inserted stylesheet. Default is 'author'.
|
||||
|
||||
Returns `Promise<string>` - A promise that resolves with a key for the inserted CSS that can later be used to remove the CSS via `contents.removeInsertedCSS(key)`.
|
||||
|
||||
@@ -1508,7 +1503,7 @@ can be obtained by subscribing to [`found-in-page`](web-contents.md#event-found-
|
||||
|
||||
Stops any `findInPage` request for the `webContents` with the provided `action`.
|
||||
|
||||
```javascript
|
||||
```js
|
||||
const win = new BrowserWindow()
|
||||
win.webContents.on('found-in-page', (event, result) => {
|
||||
if (result.finalUpdate) win.webContents.stopFindInPage('clearSelection')
|
||||
@@ -1619,6 +1614,7 @@ win.webContents.print(options, (success, errorType) => {
|
||||
* `footerTemplate` string (optional) - HTML template for the print footer. Should use the same format as the `headerTemplate`.
|
||||
* `preferCSSPageSize` boolean (optional) - Whether or not to prefer page size as defined by css. Defaults to false, in which case the content will be scaled to fit the paper size.
|
||||
* `generateTaggedPDF` boolean (optional) _Experimental_ - Whether or not to generate a tagged (accessible) PDF. Defaults to false. As this property is experimental, the generated PDF may not adhere fully to PDF/UA and WCAG standards.
|
||||
* `generateDocumentOutline` boolean (optional) _Experimental_ - Whether or not to generate a PDF document outline from content headers. Defaults to false.
|
||||
|
||||
Returns `Promise<Buffer>` - Resolves with the generated PDF data.
|
||||
|
||||
@@ -1628,25 +1624,27 @@ The `landscape` will be ignored if `@page` CSS at-rule is used in the web page.
|
||||
|
||||
An example of `webContents.printToPDF`:
|
||||
|
||||
```javascript
|
||||
const { BrowserWindow } = require('electron')
|
||||
```js
|
||||
const { app, BrowserWindow } = require('electron')
|
||||
const fs = require('node:fs')
|
||||
const path = require('node:path')
|
||||
const os = require('node:os')
|
||||
|
||||
const win = new BrowserWindow()
|
||||
win.loadURL('https://github.com')
|
||||
app.whenReady().then(() => {
|
||||
const win = new BrowserWindow()
|
||||
win.loadURL('https://github.com')
|
||||
|
||||
win.webContents.on('did-finish-load', () => {
|
||||
// Use default printing options
|
||||
const pdfPath = path.join(os.homedir(), 'Desktop', 'temp.pdf')
|
||||
win.webContents.printToPDF({}).then(data => {
|
||||
fs.writeFile(pdfPath, data, (error) => {
|
||||
if (error) throw error
|
||||
console.log(`Wrote PDF successfully to ${pdfPath}`)
|
||||
win.webContents.on('did-finish-load', () => {
|
||||
// Use default printing options
|
||||
const pdfPath = path.join(os.homedir(), 'Desktop', 'temp.pdf')
|
||||
win.webContents.printToPDF({}).then(data => {
|
||||
fs.writeFile(pdfPath, data, (error) => {
|
||||
if (error) throw error
|
||||
console.log(`Wrote PDF successfully to ${pdfPath}`)
|
||||
})
|
||||
}).catch(error => {
|
||||
console.log(`Failed to write PDF to ${pdfPath}: `, error)
|
||||
})
|
||||
}).catch(error => {
|
||||
console.log(`Failed to write PDF to ${pdfPath}: `, error)
|
||||
})
|
||||
})
|
||||
```
|
||||
@@ -1660,7 +1658,7 @@ See [Page.printToPdf](https://chromedevtools.github.io/devtools-protocol/tot/Pag
|
||||
Adds the specified path to DevTools workspace. Must be used after DevTools
|
||||
creation:
|
||||
|
||||
```javascript
|
||||
```js
|
||||
const { BrowserWindow } = require('electron')
|
||||
const win = new BrowserWindow()
|
||||
win.webContents.on('devtools-opened', () => {
|
||||
@@ -1983,7 +1981,7 @@ the cursor when dragging.
|
||||
|
||||
Returns `Promise<void>` - resolves if the page is saved.
|
||||
|
||||
```javascript
|
||||
```js
|
||||
const { BrowserWindow } = require('electron')
|
||||
const win = new BrowserWindow()
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@ The `webFrameMain` module can be used to lookup frames across existing
|
||||
[`WebContents`](web-contents.md) instances. Navigation events are the common
|
||||
use case.
|
||||
|
||||
```javascript
|
||||
```js
|
||||
const { BrowserWindow, webFrameMain } = require('electron')
|
||||
|
||||
const win = new BrowserWindow({ width: 800, height: 1500 })
|
||||
@@ -29,7 +29,7 @@ win.webContents.on(
|
||||
You can also access frames of existing pages by using the `mainFrame` property
|
||||
of [`WebContents`](web-contents.md).
|
||||
|
||||
```javascript
|
||||
```js
|
||||
const { BrowserWindow } = require('electron')
|
||||
|
||||
async function main () {
|
||||
|
||||
@@ -10,7 +10,7 @@ certain properties and methods (e.g. `webFrame.firstChild`).
|
||||
|
||||
An example of zooming current page to 200%.
|
||||
|
||||
```javascript
|
||||
```js
|
||||
const { webFrame } = require('electron')
|
||||
|
||||
webFrame.setZoomFactor(2)
|
||||
@@ -96,7 +96,7 @@ with an array of misspelt words when complete.
|
||||
|
||||
An example of using [node-spellchecker][spellchecker] as provider:
|
||||
|
||||
```javascript @ts-expect-error=[2,6]
|
||||
```js @ts-expect-error=[2,6]
|
||||
const { webFrame } = require('electron')
|
||||
const spellChecker = require('spellchecker')
|
||||
webFrame.setSpellCheckProvider('en-US', {
|
||||
@@ -113,7 +113,7 @@ webFrame.setSpellCheckProvider('en-US', {
|
||||
|
||||
* `css` string
|
||||
* `options` Object (optional)
|
||||
* `cssOrigin` string (optional) - Can be either 'user' or 'author'. Sets the [cascade origin](https://www.w3.org/TR/css3-cascade/#cascade-origin) of the inserted stylesheet. Default is 'author'.
|
||||
* `cssOrigin` string (optional) - Can be 'user' or 'author'. Sets the [cascade origin](https://www.w3.org/TR/css3-cascade/#cascade-origin) of the inserted stylesheet. Default is 'author'.
|
||||
|
||||
Returns `string` - A key for the inserted CSS that can later be used to remove
|
||||
the CSS via `webFrame.removeInsertedCSS(key)`.
|
||||
@@ -205,14 +205,14 @@ Returns `Object`:
|
||||
Returns an object describing usage information of Blink's internal memory
|
||||
caches.
|
||||
|
||||
```javascript
|
||||
```js
|
||||
const { webFrame } = require('electron')
|
||||
console.log(webFrame.getResourceUsage())
|
||||
```
|
||||
|
||||
This will generate:
|
||||
|
||||
```javascript
|
||||
```js
|
||||
{
|
||||
images: {
|
||||
count: 22,
|
||||
|
||||
@@ -23,7 +23,7 @@ called with a `response` object when `listener` has done its work.
|
||||
|
||||
An example of adding `User-Agent` header for requests:
|
||||
|
||||
```javascript
|
||||
```js
|
||||
const { session } = require('electron')
|
||||
|
||||
// Modify the user agent for all requests to the following urls.
|
||||
|
||||
26
docs/api/web-utils.md
Normal file
26
docs/api/web-utils.md
Normal file
@@ -0,0 +1,26 @@
|
||||
# webUtils
|
||||
|
||||
> A utility layer to interact with Web API objects (Files, Blobs, etc.)
|
||||
|
||||
Process: [Renderer](../glossary.md#renderer-process)
|
||||
|
||||
## Methods
|
||||
|
||||
The `webUtils` module has the following methods:
|
||||
|
||||
### `webUtils.getPathForFile(file)`
|
||||
|
||||
* `file` File - A web [File](https://developer.mozilla.org/en-US/docs/Web/API/File) object.
|
||||
|
||||
Returns `string` - The file system path that this `File` object points to. In the case where the object passed in is not a `File` object an exception is thrown. In the case where the File object passed in was constructed in JS and is not backed by a file on disk an empty string is returned.
|
||||
|
||||
This method superceded the previous augmentation to the `File` object with the `path` property. An example is included below.
|
||||
|
||||
```js
|
||||
// Before
|
||||
const oldPath = document.querySelector('input').files[0].path
|
||||
|
||||
// After
|
||||
const { webUtils } = require('electron')
|
||||
const newPath = webUtils.getPathForFile(document.querySelector('input').files[0])
|
||||
```
|
||||
@@ -255,7 +255,7 @@ The `webview` tag has the following methods:
|
||||
|
||||
**Example**
|
||||
|
||||
```javascript @ts-expect-error=[3]
|
||||
```js @ts-expect-error=[3]
|
||||
const webview = document.querySelector('webview')
|
||||
webview.addEventListener('dom-ready', () => {
|
||||
webview.openDevTools()
|
||||
@@ -608,6 +608,7 @@ Prints `webview`'s web page. Same as `webContents.print([options])`.
|
||||
* `footerTemplate` string (optional) - HTML template for the print footer. Should use the same format as the `headerTemplate`.
|
||||
* `preferCSSPageSize` boolean (optional) - Whether or not to prefer page size as defined by css. Defaults to false, in which case the content will be scaled to fit the paper size.
|
||||
* `generateTaggedPDF` boolean (optional) _Experimental_ - Whether or not to generate a tagged (accessible) PDF. Defaults to false. As this property is experimental, the generated PDF may not adhere fully to PDF/UA and WCAG standards.
|
||||
* `generateDocumentOutline` boolean (optional) _Experimental_ - Whether or not to generate a PDF document outline from content headers. Defaults to false.
|
||||
|
||||
Returns `Promise<Uint8Array>` - Resolves with the generated PDF data.
|
||||
|
||||
@@ -802,7 +803,7 @@ Fired when the guest window logs a console message.
|
||||
The following example code forwards all log messages to the embedder's console
|
||||
without regard for log level or other properties.
|
||||
|
||||
```javascript @ts-expect-error=[3]
|
||||
```js @ts-expect-error=[3]
|
||||
const webview = document.querySelector('webview')
|
||||
webview.addEventListener('console-message', (e) => {
|
||||
console.log('Guest page logged a message:', e.message)
|
||||
@@ -823,7 +824,7 @@ Returns:
|
||||
Fired when a result is available for
|
||||
[`webview.findInPage`](#webviewfindinpagetext-options) request.
|
||||
|
||||
```javascript @ts-expect-error=[3,6]
|
||||
```js @ts-expect-error=[3,6]
|
||||
const webview = document.querySelector('webview')
|
||||
webview.addEventListener('found-in-page', (e) => {
|
||||
webview.stopFindInPage('keepSelection')
|
||||
@@ -948,7 +949,7 @@ Fired when the guest page attempts to close itself.
|
||||
The following example code navigates the `webview` to `about:blank` when the
|
||||
guest attempts to close itself.
|
||||
|
||||
```javascript @ts-expect-error=[3]
|
||||
```js @ts-expect-error=[3]
|
||||
const webview = document.querySelector('webview')
|
||||
webview.addEventListener('close', () => {
|
||||
webview.src = 'about:blank'
|
||||
@@ -968,7 +969,7 @@ Fired when the guest page has sent an asynchronous message to embedder page.
|
||||
With `sendToHost` method and `ipc-message` event you can communicate
|
||||
between guest page and embedder page:
|
||||
|
||||
```javascript @ts-expect-error=[4,7]
|
||||
```js @ts-expect-error=[4,7]
|
||||
// In embedder page.
|
||||
const webview = document.querySelector('webview')
|
||||
webview.addEventListener('ipc-message', (event) => {
|
||||
@@ -978,7 +979,7 @@ webview.addEventListener('ipc-message', (event) => {
|
||||
webview.send('ping')
|
||||
```
|
||||
|
||||
```javascript
|
||||
```js
|
||||
// In guest page.
|
||||
const { ipcRenderer } = require('electron')
|
||||
ipcRenderer.on('ping', () => {
|
||||
@@ -986,14 +987,6 @@ ipcRenderer.on('ping', () => {
|
||||
})
|
||||
```
|
||||
|
||||
### Event: 'crashed' _Deprecated_
|
||||
|
||||
Fired when the renderer process crashes or is killed.
|
||||
|
||||
**Deprecated:** This event is superceded by the `render-process-gone` event
|
||||
which contains more information about why the render process disappeared. It
|
||||
isn't always because it crashed.
|
||||
|
||||
### Event: 'render-process-gone'
|
||||
|
||||
Returns:
|
||||
@@ -1106,9 +1099,18 @@ Returns:
|
||||
word and spellchecker is enabled.
|
||||
* `frameCharset` string - The character encoding of the frame on which the
|
||||
menu was invoked.
|
||||
* `inputFieldType` string - If the context menu was invoked on an input
|
||||
field, the type of that field. Possible values include `none`, `plainText`,
|
||||
`password`, `other`.
|
||||
* `formControlType` string - The source that the context menu was invoked on.
|
||||
Possible values include `none`, `button-button`, `field-set`,
|
||||
`input-button`, `input-checkbox`, `input-color`, `input-date`,
|
||||
`input-datetime-local`, `input-email`, `input-file`, `input-hidden`,
|
||||
`input-image`, `input-month`, `input-number`, `input-password`, `input-radio`,
|
||||
`input-range`, `input-reset`, `input-search`, `input-submit`, `input-telephone`,
|
||||
`input-text`, `input-time`, `input-url`, `input-week`, `output`, `reset-button`,
|
||||
`select-list`, `select-list`, `select-multiple`, `select-one`, `submit-button`,
|
||||
and `text-area`,
|
||||
* `inputFieldType` string _Deprecated_ - If the context menu was invoked on an
|
||||
input field, the type of that field. Possible values include `none`,
|
||||
`plainText`, `password`, `other`.
|
||||
* `spellcheckEnabled` boolean - If the context is editable, whether or not spellchecking is enabled.
|
||||
* `menuSourceType` string - Input source that invoked the context menu.
|
||||
Can be `none`, `mouse`, `keyboard`, `touch`, `touchMenu`, `longPress`, `longTap`, `touchHandle`, `stylus`, `adjustSelection`, or `adjustSelectionReset`.
|
||||
|
||||
@@ -80,7 +80,7 @@ window will not close when the opener window closes. The default value is `false
|
||||
|
||||
### Native `Window` example
|
||||
|
||||
```javascript
|
||||
```js
|
||||
// main.js
|
||||
const mainWindow = new BrowserWindow()
|
||||
|
||||
@@ -104,7 +104,7 @@ mainWindow.webContents.setWindowOpenHandler(({ url }) => {
|
||||
})
|
||||
```
|
||||
|
||||
```javascript
|
||||
```js
|
||||
// renderer process (mainWindow)
|
||||
const childWindow = window.open('', 'modal')
|
||||
childWindow.document.write('<h1>Hello</h1>')
|
||||
|
||||
@@ -12,8 +12,83 @@ This document uses the following convention to categorize breaking changes:
|
||||
* **Deprecated:** An API was marked as deprecated. The API will continue to function, but will emit a deprecation warning, and will be removed in a future release.
|
||||
* **Removed:** An API or feature was removed, and is no longer supported by Electron.
|
||||
|
||||
## Planned Breaking API Changes (30.0)
|
||||
|
||||
### Behavior Changed: cross-origin iframes now use Permission Policy to access features
|
||||
|
||||
Cross-origin iframes must now specify features available to a given `iframe` via the `allow`
|
||||
attribute in order to access them.
|
||||
|
||||
See [documentation](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/iframe#allow) for
|
||||
more information.
|
||||
|
||||
### Removed: The `--disable-color-correct-rendering` switch
|
||||
|
||||
This switch was never formally documented but it's removal is being noted here regardless. Chromium itself now has better support for color spaces so this flag should not be needed.
|
||||
|
||||
## Planned Breaking API Changes (29.0)
|
||||
|
||||
### Behavior Changed: `ipcRenderer` can no longer be sent over the `contextBridge`
|
||||
|
||||
Attempting to send the entire `ipcRenderer` module as an object over the `contextBridge` will now result in
|
||||
an empty object on the receiving side of the bridge. This change was made to remove / mitigate
|
||||
a security footgun. You should not directly expose ipcRenderer or its methods over the bridge.
|
||||
Instead, provide a safe wrapper like below:
|
||||
|
||||
```js
|
||||
contextBridge.exposeInMainWorld('app', {
|
||||
onEvent: (cb) => ipcRenderer.on('foo', (e, ...args) => cb(args))
|
||||
})
|
||||
```
|
||||
|
||||
### Removed: `renderer-process-crashed` event on `app`
|
||||
|
||||
The `renderer-process-crashed` event on `app` has been removed.
|
||||
Use the new `render-process-gone` event instead.
|
||||
|
||||
```js
|
||||
// Removed
|
||||
app.on('renderer-process-crashed', (event, webContents, killed) => { /* ... */ })
|
||||
|
||||
// Replace with
|
||||
app.on('render-process-gone', (event, webContents, details) => { /* ... */ })
|
||||
```
|
||||
|
||||
### Removed: `crashed` event on `WebContents` and `<webview>`
|
||||
|
||||
The `crashed` events on `WebContents` and `<webview>` have been removed.
|
||||
Use the new `render-process-gone` event instead.
|
||||
|
||||
```js
|
||||
// Removed
|
||||
win.webContents.on('crashed', (event, killed) => { /* ... */ })
|
||||
webview.addEventListener('crashed', (event) => { /* ... */ })
|
||||
|
||||
// Replace with
|
||||
win.webContents.on('render-process-gone', (event, details) => { /* ... */ })
|
||||
webview.addEventListener('render-process-gone', (event) => { /* ... */ })
|
||||
```
|
||||
|
||||
### Removed: `gpu-process-crashed` event on `app`
|
||||
|
||||
The `gpu-process-crashed` event on `app` has been removed.
|
||||
Use the new `child-process-gone` event instead.
|
||||
|
||||
```js
|
||||
// Removed
|
||||
app.on('gpu-process-crashed', (event, killed) => { /* ... */ })
|
||||
|
||||
// Replace with
|
||||
app.on('child-process-gone', (event, details) => { /* ... */ })
|
||||
```
|
||||
|
||||
## Planned Breaking API Changes (28.0)
|
||||
|
||||
### Behavior Changed: `WebContents.backgroundThrottling` set to false affects all `WebContents` in the host `BrowserWindow`
|
||||
|
||||
`WebContents.backgroundThrottling` set to false will disable frames throttling
|
||||
in the `BrowserWindow` for all `WebContents` displayed by it.
|
||||
|
||||
### Removed: `BrowserWindow.setTrafficLightPosition(position)`
|
||||
|
||||
`BrowserWindow.setTrafficLightPosition(position)` has been removed, the
|
||||
@@ -58,6 +133,65 @@ The `ipcRenderer.sendTo()` API has been removed. It should be replaced by settin
|
||||
|
||||
The `senderId` and `senderIsMainFrame` properties of `IpcRendererEvent` have been removed as well.
|
||||
|
||||
### Removed: `app.runningUnderRosettaTranslation`
|
||||
|
||||
The `app.runningUnderRosettaTranslation` property has been removed.
|
||||
Use `app.runningUnderARM64Translation` instead.
|
||||
|
||||
```js
|
||||
// Removed
|
||||
console.log(app.runningUnderRosettaTranslation)
|
||||
// Replace with
|
||||
console.log(app.runningUnderARM64Translation)
|
||||
```
|
||||
|
||||
### Deprecated: `renderer-process-crashed` event on `app`
|
||||
|
||||
The `renderer-process-crashed` event on `app` has been deprecated.
|
||||
Use the new `render-process-gone` event instead.
|
||||
|
||||
```js
|
||||
// Deprecated
|
||||
app.on('renderer-process-crashed', (event, webContents, killed) => { /* ... */ })
|
||||
|
||||
// Replace with
|
||||
app.on('render-process-gone', (event, webContents, details) => { /* ... */ })
|
||||
```
|
||||
|
||||
### Deprecated: `params.inputFormType` property on `context-menu` on `WebContents`
|
||||
|
||||
The `inputFormType` property of the params object in the `context-menu`
|
||||
event from `WebContents` has been deprecated. Use the new `formControlType`
|
||||
property instead.
|
||||
|
||||
### Deprecated: `crashed` event on `WebContents` and `<webview>`
|
||||
|
||||
The `crashed` events on `WebContents` and `<webview>` have been deprecated.
|
||||
Use the new `render-process-gone` event instead.
|
||||
|
||||
```js
|
||||
// Deprecated
|
||||
win.webContents.on('crashed', (event, killed) => { /* ... */ })
|
||||
webview.addEventListener('crashed', (event) => { /* ... */ })
|
||||
|
||||
// Replace with
|
||||
win.webContents.on('render-process-gone', (event, details) => { /* ... */ })
|
||||
webview.addEventListener('render-process-gone', (event) => { /* ... */ })
|
||||
```
|
||||
|
||||
### Deprecated: `gpu-process-crashed` event on `app`
|
||||
|
||||
The `gpu-process-crashed` event on `app` has been deprecated.
|
||||
Use the new `child-process-gone` event instead.
|
||||
|
||||
```js
|
||||
// Deprecated
|
||||
app.on('gpu-process-crashed', (event, killed) => { /* ... */ })
|
||||
|
||||
// Replace with
|
||||
app.on('child-process-gone', (event, details) => { /* ... */ })
|
||||
```
|
||||
|
||||
## Planned Breaking API Changes (27.0)
|
||||
|
||||
### Removed: macOS 10.13 / 10.14 support
|
||||
@@ -91,6 +225,18 @@ systemPreferences.on('high-contrast-color-scheme-changed', () => { /* ... */ })
|
||||
nativeTheme.on('updated', () => { /* ... */ })
|
||||
```
|
||||
|
||||
### Removed: Some `window.setVibrancy` options on macOS
|
||||
|
||||
The following vibrancy options have been removed:
|
||||
|
||||
* 'light'
|
||||
* 'medium-light'
|
||||
* 'dark'
|
||||
* 'ultra-dark'
|
||||
* 'appearance-based'
|
||||
|
||||
These were previously deprecated and have been removed by Apple in 10.15.
|
||||
|
||||
### Removed: `webContents.getPrinters`
|
||||
|
||||
The `webContents.getPrinters` method has been removed. Use
|
||||
@@ -470,7 +616,7 @@ The `new-window` event of `<webview>` has been removed. There is no direct repla
|
||||
webview.addEventListener('new-window', (event) => {})
|
||||
```
|
||||
|
||||
```javascript fiddle='docs/fiddles/ipc/webview-new-window'
|
||||
```js
|
||||
// Replace with
|
||||
|
||||
// main.js
|
||||
@@ -716,6 +862,18 @@ to open synchronously scriptable child windows, among other incompatibilities.
|
||||
See the documentation for [window.open in Electron](api/window-open.md)
|
||||
for more details.
|
||||
|
||||
### Deprecated: `app.runningUnderRosettaTranslation`
|
||||
|
||||
The `app.runningUnderRosettaTranslation` property has been deprecated.
|
||||
Use `app.runningUnderARM64Translation` instead.
|
||||
|
||||
```js
|
||||
// Deprecated
|
||||
console.log(app.runningUnderRosettaTranslation)
|
||||
// Replace with
|
||||
console.log(app.runningUnderARM64Translation)
|
||||
```
|
||||
|
||||
## Planned Breaking API Changes (14.0)
|
||||
|
||||
### Removed: `remote` module
|
||||
@@ -1123,7 +1281,7 @@ module](https://medium.com/@nornagon/electrons-remote-module-considered-harmful-
|
||||
|
||||
The APIs are now synchronous and the optional callback is no longer needed.
|
||||
|
||||
```javascript
|
||||
```js
|
||||
// Deprecated
|
||||
protocol.unregisterProtocol(scheme, () => { /* ... */ })
|
||||
// Replace with
|
||||
@@ -1152,7 +1310,7 @@ protocol.unregisterProtocol(scheme)
|
||||
|
||||
The APIs are now synchronous and the optional callback is no longer needed.
|
||||
|
||||
```javascript
|
||||
```js
|
||||
// Deprecated
|
||||
protocol.registerFileProtocol(scheme, handler, () => { /* ... */ })
|
||||
// Replace with
|
||||
@@ -1167,7 +1325,7 @@ until navigation happens.
|
||||
This API is deprecated and users should use `protocol.isProtocolRegistered`
|
||||
and `protocol.isProtocolIntercepted` instead.
|
||||
|
||||
```javascript
|
||||
```js
|
||||
// Deprecated
|
||||
protocol.isProtocolHandled(scheme).then(() => { /* ... */ })
|
||||
// Replace with
|
||||
|
||||
@@ -164,7 +164,7 @@ An example of the contents of this file can be found [here](https://github.com/e
|
||||
|
||||
Add your module to the module list found at `"lib/browser/api/module-list.ts"` like so:
|
||||
|
||||
```typescript title='lib/browser/api/module-list.ts' @ts-nocheck
|
||||
```ts title='lib/browser/api/module-list.ts' @ts-nocheck
|
||||
export const browserModuleList: ElectronInternal.ModuleEntry[] = [
|
||||
{ name: 'apiName', loader: () => require('./api-name') },
|
||||
];
|
||||
|
||||
@@ -65,7 +65,7 @@ If you encounter this problem, the following articles may prove helpful:
|
||||
If you want a quick fix, you can make the variables global by changing your
|
||||
code from this:
|
||||
|
||||
```javascript
|
||||
```js
|
||||
const { app, Tray } = require('electron')
|
||||
app.whenReady().then(() => {
|
||||
const tray = new Tray('/path/to/icon.png')
|
||||
@@ -75,7 +75,7 @@ app.whenReady().then(() => {
|
||||
|
||||
to this:
|
||||
|
||||
```javascript
|
||||
```js
|
||||
const { app, Tray } = require('electron')
|
||||
let tray = null
|
||||
app.whenReady().then(() => {
|
||||
@@ -92,7 +92,7 @@ for some libraries since they want to insert the symbols with the same names.
|
||||
|
||||
To solve this, you can turn off node integration in Electron:
|
||||
|
||||
```javascript
|
||||
```js
|
||||
// In the main process.
|
||||
const { BrowserWindow } = require('electron')
|
||||
const win = new BrowserWindow({
|
||||
@@ -141,7 +141,7 @@ Sub-pixel anti-aliasing needs a non-transparent background of the layer containi
|
||||
|
||||
To achieve this goal, set the background in the constructor for [BrowserWindow][browser-window]:
|
||||
|
||||
```javascript
|
||||
```js
|
||||
const { BrowserWindow } = require('electron')
|
||||
const win = new BrowserWindow({
|
||||
backgroundColor: '#fff'
|
||||
|
||||
@@ -7,14 +7,20 @@ function createWindow () {
|
||||
height: 600
|
||||
})
|
||||
|
||||
win.setRepresentedFilename(os.homedir())
|
||||
win.setDocumentEdited(true)
|
||||
|
||||
win.loadFile('index.html')
|
||||
}
|
||||
|
||||
app.whenReady().then(() => {
|
||||
const win = new BrowserWindow()
|
||||
createWindow()
|
||||
|
||||
win.setRepresentedFilename(os.homedir())
|
||||
win.setDocumentEdited(true)
|
||||
app.on('activate', () => {
|
||||
if (BrowserWindow.getAllWindows().length === 0) {
|
||||
createWindow()
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
app.on('window-all-closed', () => {
|
||||
@@ -22,9 +28,3 @@ app.on('window-all-closed', () => {
|
||||
app.quit()
|
||||
}
|
||||
})
|
||||
|
||||
app.on('activate', () => {
|
||||
if (BrowserWindow.getAllWindows().length === 0) {
|
||||
createWindow()
|
||||
}
|
||||
})
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
const { contextBridge, ipcRenderer } = require('electron/renderer')
|
||||
|
||||
contextBridge.exposeInMainWorld('electronAPI', {
|
||||
handleCounter: (callback) => ipcRenderer.on('update-counter', () => callback())
|
||||
onUpdateCounter: (callback) => ipcRenderer.on('update-counter', (_event, value) => callback(value)),
|
||||
counterValue: (value) => ipcRenderer.send('counter-value', value)
|
||||
})
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
const counter = document.getElementById('counter')
|
||||
|
||||
window.electronAPI.handleCounter((event, value) => {
|
||||
window.electronAPI.onUpdateCounter((value) => {
|
||||
const oldValue = Number(counter.innerText)
|
||||
const newValue = oldValue + value
|
||||
counter.innerText = newValue
|
||||
event.sender.send('counter-value', newValue)
|
||||
counter.innerText = newValue.toString()
|
||||
window.electronAPI.counterValue(newValue)
|
||||
})
|
||||
|
||||
@@ -44,7 +44,7 @@
|
||||
<h3>Packaging</h3>
|
||||
<p>This feature will only work on macOS when your app is packaged. It will not work when you're launching it in
|
||||
development from the command-line. When you package your app you'll need to make sure the macOS <code>plist</code>
|
||||
for the app is updated to include the new protocol handler. If you're using <code>electron-packager</code> then you
|
||||
for the app is updated to include the new protocol handler. If you're using <code>@electron/packager</code> then you
|
||||
can add the flag <code>--extend-info</code> with a path to the <code>plist</code> you've created. The one for this
|
||||
app is below:</p>
|
||||
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 59 KiB After Width: | Height: | Size: 4.2 MiB |
@@ -12,7 +12,7 @@ including instances of `BrowserWindow`, `BrowserView`, and `WebView`. You
|
||||
can open them programmatically by calling the `openDevTools()` API on the
|
||||
`webContents` of the instance:
|
||||
|
||||
```javascript
|
||||
```js
|
||||
const { BrowserWindow } = require('electron')
|
||||
|
||||
const win = new BrowserWindow()
|
||||
|
||||
@@ -41,27 +41,27 @@ $ asar list /path/to/example.asar
|
||||
|
||||
Read a file in the ASAR archive:
|
||||
|
||||
```javascript
|
||||
```js
|
||||
const fs = require('node:fs')
|
||||
fs.readFileSync('/path/to/example.asar/file.txt')
|
||||
```
|
||||
|
||||
List all files under the root of the archive:
|
||||
|
||||
```javascript
|
||||
```js
|
||||
const fs = require('node:fs')
|
||||
fs.readdirSync('/path/to/example.asar')
|
||||
```
|
||||
|
||||
Use a module from the archive:
|
||||
|
||||
```javascript @ts-nocheck
|
||||
```js @ts-nocheck
|
||||
require('./path/to/example.asar/dir/module.js')
|
||||
```
|
||||
|
||||
You can also display a web page in an ASAR archive with `BrowserWindow`:
|
||||
|
||||
```javascript
|
||||
```js
|
||||
const { BrowserWindow } = require('electron')
|
||||
const win = new BrowserWindow()
|
||||
|
||||
@@ -90,7 +90,7 @@ For some cases like verifying the ASAR archive's checksum, we need to read the
|
||||
content of an ASAR archive as a file. For this purpose you can use the built-in
|
||||
`original-fs` module which provides original `fs` APIs without `asar` support:
|
||||
|
||||
```javascript
|
||||
```js
|
||||
const originalFs = require('original-fs')
|
||||
originalFs.readFileSync('/path/to/example.asar')
|
||||
```
|
||||
@@ -98,7 +98,7 @@ originalFs.readFileSync('/path/to/example.asar')
|
||||
You can also set `process.noAsar` to `true` to disable the support for `asar` in
|
||||
the `fs` module:
|
||||
|
||||
```javascript
|
||||
```js
|
||||
const fs = require('node:fs')
|
||||
process.noAsar = true
|
||||
fs.readFileSync('/path/to/example.asar')
|
||||
|
||||
@@ -13,7 +13,7 @@ Currently ASAR integrity checking is only supported on macOS.
|
||||
|
||||
### Electron Forge / Electron Packager
|
||||
|
||||
If you are using `>= electron-packager@15.4.0` or `>= @electron-forge/core@6.0.0-beta.61` then all these requirements are met for you automatically and you can skip to [Toggling the Fuse](#toggling-the-fuse).
|
||||
If you are using `>= @electron/packager`, `>= electron-packager@15.4.0` or `>= @electron-forge/core@6.0.0-beta.61` then all these requirements are met for you automatically and you can skip to [Toggling the Fuse](#toggling-the-fuse).
|
||||
|
||||
### Other build systems
|
||||
|
||||
|
||||
@@ -22,34 +22,101 @@ There are a few ways that you can set up testing using WebDriver.
|
||||
Node.js package for testing with WebDriver. Its ecosystem also includes various plugins
|
||||
(e.g. reporter and services) that can help you put together your test setup.
|
||||
|
||||
If you already have an existing WebdriverIO setup, it is recommended to update your dependencies and validate your existing configuration with how it is [outlined in the docs](https://webdriver.io/docs/desktop-testing/electron#configuration).
|
||||
|
||||
#### Install the test runner
|
||||
|
||||
First you need to run the WebdriverIO starter toolkit in your project root directory:
|
||||
If you don't use WebdriverIO in your project yet, you can add it by running the starter toolkit in your project root directory:
|
||||
|
||||
```sh npm2yarn
|
||||
npx wdio . --yes
|
||||
npm init wdio@latest ./
|
||||
```
|
||||
|
||||
This installs all necessary packages for you and generates a `wdio.conf.js` configuration file.
|
||||
This starts a configuration wizard that helps you put together the right setup, installs all necessary packages, and generates a `wdio.conf.js` configuration file. Make sure to select _"Desktop Testing - of Electron Applications"_ on one of the first questions asking _"What type of testing would you like to do?"_.
|
||||
|
||||
#### Connect WDIO to your Electron app
|
||||
|
||||
Update the capabilities in your configuration file to point to your Electron app binary:
|
||||
After running the configuration wizard, your `wdio.conf.js` should include roughly the following content:
|
||||
|
||||
```javascript title='wdio.conf.js'
|
||||
exports.config = {
|
||||
```js title='wdio.conf.js' @ts-nocheck
|
||||
export const config = {
|
||||
// ...
|
||||
services: ['electron'],
|
||||
capabilities: [{
|
||||
browserName: 'chrome',
|
||||
'goog:chromeOptions': {
|
||||
binary: '/path/to/your/electron/binary', // Path to your Electron binary.
|
||||
args: [/* cli arguments */] // Optional, perhaps 'app=' + /path/to/your/app/
|
||||
browserName: 'electron',
|
||||
'wdio:electronServiceOptions': {
|
||||
// WebdriverIO can automatically find your bundled application
|
||||
// if you use Electron Forge or electron-builder, otherwise you
|
||||
// can define it here, e.g.:
|
||||
// appBinaryPath: './path/to/bundled/application.exe',
|
||||
appArgs: ['foo', 'bar=baz']
|
||||
}
|
||||
}]
|
||||
// ...
|
||||
}
|
||||
```
|
||||
|
||||
#### Write your tests
|
||||
|
||||
Use the [WebdriverIO API](https://webdriver.io/docs/api) to interact with elements on the screen. The framework provides custom "matchers" that make asserting the state of your application easy, e.g.:
|
||||
|
||||
```js @ts-nocheck
|
||||
import { browser, $, expect } from '@wdio/globals'
|
||||
|
||||
describe('keyboard input', () => {
|
||||
it('should detect keyboard input', async () => {
|
||||
await browser.keys(['y', 'o'])
|
||||
await expect($('keypress-count')).toHaveText('YO')
|
||||
})
|
||||
})
|
||||
```
|
||||
|
||||
Furthermore, WebdriverIO allows you to access Electron APIs to get static information about your application:
|
||||
|
||||
```js @ts-nocheck
|
||||
import { browser, $, expect } from '@wdio/globals'
|
||||
|
||||
describe('when the make smaller button is clicked', () => {
|
||||
it('should decrease the window height and width by 10 pixels', async () => {
|
||||
const boundsBefore = await browser.electron.browserWindow('getBounds')
|
||||
expect(boundsBefore.width).toEqual(210)
|
||||
expect(boundsBefore.height).toEqual(310)
|
||||
|
||||
await $('.make-smaller').click()
|
||||
const boundsAfter = await browser.electron.browserWindow('getBounds')
|
||||
expect(boundsAfter.width).toEqual(200)
|
||||
expect(boundsAfter.height).toEqual(300)
|
||||
})
|
||||
})
|
||||
```
|
||||
|
||||
or to retrieve other Electron process information:
|
||||
|
||||
```js @ts-nocheck
|
||||
import fs from 'node:fs'
|
||||
import path from 'node:path'
|
||||
import { browser, expect } from '@wdio/globals'
|
||||
|
||||
const packageJson = JSON.parse(fs.readFileSync(path.join(__dirname, '..', 'package.json'), { encoding: 'utf-8' }))
|
||||
const { name, version } = packageJson
|
||||
|
||||
describe('electron APIs', () => {
|
||||
it('should retrieve app metadata through the electron API', async () => {
|
||||
const appName = await browser.electron.app('getName')
|
||||
expect(appName).toEqual(name)
|
||||
const appVersion = await browser.electron.app('getVersion')
|
||||
expect(appVersion).toEqual(version)
|
||||
})
|
||||
|
||||
it('should pass args through to the launched application', async () => {
|
||||
// custom args are set in the wdio.conf.js file as they need to be set before WDIO starts
|
||||
const argv = await browser.electron.mainProcess('argv')
|
||||
expect(argv).toContain('--foo')
|
||||
expect(argv).toContain('--bar=baz')
|
||||
})
|
||||
})
|
||||
```
|
||||
|
||||
#### Run your tests
|
||||
|
||||
To run your tests:
|
||||
@@ -58,6 +125,12 @@ To run your tests:
|
||||
$ npx wdio run wdio.conf.js
|
||||
```
|
||||
|
||||
WebdriverIO helps launch and shut down the application for you.
|
||||
|
||||
#### More documentation
|
||||
|
||||
Find more documentation on Mocking Electron APIs and other useful resources in the [official WebdriverIO documentation](https://webdriver.io/docs/desktop-testing/electron).
|
||||
|
||||
### With Selenium
|
||||
|
||||
[Selenium](https://www.selenium.dev/) is a web automation framework that
|
||||
@@ -123,32 +196,19 @@ support via Electron's support for the [Chrome DevTools Protocol][] (CDP).
|
||||
|
||||
### Install dependencies
|
||||
|
||||
You can install Playwright through your preferred Node.js package manager. The Playwright team
|
||||
recommends using the `PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD` environment variable to avoid
|
||||
unnecessary browser downloads when testing an Electron app.
|
||||
|
||||
```sh npm2yarn
|
||||
PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD=1 npm install --save-dev playwright
|
||||
```
|
||||
|
||||
Playwright also comes with its own test runner, Playwright Test, which is built for end-to-end
|
||||
testing. You can also install it as a dev dependency in your project:
|
||||
You can install Playwright through your preferred Node.js package manager. It comes with its
|
||||
own [test runner][playwright-intro], which is built for end-to-end testing:
|
||||
|
||||
```sh npm2yarn
|
||||
npm install --save-dev @playwright/test
|
||||
```
|
||||
|
||||
:::caution Dependencies
|
||||
This tutorial was written `playwright@1.16.3` and `@playwright/test@1.16.3`. Check out
|
||||
This tutorial was written with `@playwright/test@1.41.1`. Check out
|
||||
[Playwright's releases][playwright-releases] page to learn about
|
||||
changes that might affect the code below.
|
||||
:::
|
||||
|
||||
:::info Using third-party test runners
|
||||
If you're interested in using an alternative test runner (e.g. Jest or Mocha), check out
|
||||
Playwright's [Third-Party Test Runner][playwright-test-runners] guide.
|
||||
:::
|
||||
|
||||
### Write your tests
|
||||
|
||||
Playwright launches your app in development mode through the `_electron.launch` API.
|
||||
@@ -156,8 +216,7 @@ To point this API to your Electron app, you can pass the path to your main proce
|
||||
entry point (here, it is `main.js`).
|
||||
|
||||
```js {5} @ts-nocheck
|
||||
const { _electron: electron } = require('playwright')
|
||||
const { test } = require('@playwright/test')
|
||||
const { test, _electron: electron } = require('@playwright/test')
|
||||
|
||||
test('launch app', async () => {
|
||||
const electronApp = await electron.launch({ args: ['main.js'] })
|
||||
@@ -169,9 +228,8 @@ test('launch app', async () => {
|
||||
After that, you will access to an instance of Playwright's `ElectronApp` class. This
|
||||
is a powerful class that has access to main process modules for example:
|
||||
|
||||
```js {6-11} @ts-nocheck
|
||||
const { _electron: electron } = require('playwright')
|
||||
const { test } = require('@playwright/test')
|
||||
```js {5-10} @ts-nocheck
|
||||
const { test, _electron: electron } = require('@playwright/test')
|
||||
|
||||
test('get isPackaged', async () => {
|
||||
const electronApp = await electron.launch({ args: ['main.js'] })
|
||||
@@ -190,8 +248,7 @@ It can also create individual [Page][playwright-page] objects from Electron Brow
|
||||
For example, to grab the first BrowserWindow and save a screenshot:
|
||||
|
||||
```js {6-7} @ts-nocheck
|
||||
const { _electron: electron } = require('playwright')
|
||||
const { test } = require('@playwright/test')
|
||||
const { test, _electron: electron } = require('@playwright/test')
|
||||
|
||||
test('save screenshot', async () => {
|
||||
const electronApp = await electron.launch({ args: ['main.js'] })
|
||||
@@ -202,12 +259,11 @@ test('save screenshot', async () => {
|
||||
})
|
||||
```
|
||||
|
||||
Putting all this together using the PlayWright Test runner, let's create a `example.spec.js`
|
||||
Putting all this together using the Playwright test-runner, let's create a `example.spec.js`
|
||||
test file with a single test and assertion:
|
||||
|
||||
```js title='example.spec.js' @ts-nocheck
|
||||
const { _electron: electron } = require('playwright')
|
||||
const { test, expect } = require('@playwright/test')
|
||||
const { test, expect, _electron: electron } = require('@playwright/test')
|
||||
|
||||
test('example test', async () => {
|
||||
const electronApp = await electron.launch({ args: ['.'] })
|
||||
@@ -243,6 +299,7 @@ Running 1 test using 1 worker
|
||||
:::info
|
||||
Playwright Test will automatically run any files matching the `.*(test|spec)\.(js|ts|mjs)` regex.
|
||||
You can customize this match in the [Playwright Test configuration options][playwright-test-config].
|
||||
It also works with TypeScript out of the box.
|
||||
:::
|
||||
|
||||
:::tip Further reading
|
||||
@@ -400,10 +457,10 @@ test.after.always('cleanup', async t => {
|
||||
|
||||
[chrome-driver]: https://sites.google.com/chromium.org/driver/
|
||||
[Puppeteer]: https://github.com/puppeteer/puppeteer
|
||||
[playwright-intro]: https://playwright.dev/docs/intro
|
||||
[playwright-electron]: https://playwright.dev/docs/api/class-electron/
|
||||
[playwright-electronapplication]: https://playwright.dev/docs/api/class-electronapplication
|
||||
[playwright-page]: https://playwright.dev/docs/api/class-page
|
||||
[playwright-releases]: https://github.com/microsoft/playwright/releases
|
||||
[playwright-releases]: https://playwright.dev/docs/release-notes
|
||||
[playwright-test-config]: https://playwright.dev/docs/api/class-testconfig#test-config-test-match
|
||||
[playwright-test-runners]: https://playwright.dev/docs/test-runners/
|
||||
[Chrome DevTools Protocol]: https://chromedevtools.github.io/devtools-protocol/
|
||||
|
||||
@@ -30,7 +30,7 @@ Electron Forge is a tool for packaging and publishing Electron applications. It
|
||||
into a single extensible interface so that anyone can jump right into making Electron apps.
|
||||
|
||||
Forge comes with [a ready-to-use template](https://electronforge.io/templates) using Webpack as a bundler. It includes an example typescript configuration and provides two configuration files to enable easy customization. It uses the same core modules used by the
|
||||
greater Electron community (like [`electron-packager`](https://github.com/electron/electron-packager)) –
|
||||
greater Electron community (like [`@electron/packager`](https://github.com/electron/packager)) –
|
||||
changes made by Electron maintainers (like Slack) benefit Forge's users, too.
|
||||
|
||||
You can find more information and documentation on [electronforge.io](https://electronforge.io/).
|
||||
|
||||
@@ -5,34 +5,25 @@ slug: code-signing
|
||||
hide_title: false
|
||||
---
|
||||
|
||||
Code signing is a security technology that you use to certify that an app was
|
||||
created by you. You should sign your application so it does not trigger any
|
||||
operating system security checks.
|
||||
Code signing is a security technology to certify that an app was created by you.
|
||||
You should sign your application so it does not trigger any operating system
|
||||
security warnings.
|
||||
|
||||
On macOS, the system can detect any change to the app, whether the change is
|
||||
introduced accidentally or by malicious code.
|
||||

|
||||
|
||||
On Windows, the system assigns a trust level to your code signing certificate
|
||||
which if you don't have, or if your trust level is low, will cause security
|
||||
dialogs to appear when users start using your application. Trust level builds
|
||||
over time so it's better to start code signing as early as possible.
|
||||
|
||||
While it is possible to distribute unsigned apps, it is not recommended. Both
|
||||
Windows and macOS will, by default, prevent either the download or the execution
|
||||
of unsigned applications. Starting with macOS Catalina (version 10.15), users
|
||||
have to go through multiple manual steps to open unsigned applications.
|
||||
|
||||

|
||||
|
||||
As you can see, users get two options: Move the app straight to the trash or
|
||||
cancel running it. You don't want your users to see that dialog.
|
||||
Both Windows and macOS prevent users from running unsigned applications. It is
|
||||
possible to distribute applications without codesigning them - but in order to
|
||||
run them, users need to go through multiple advanced and manual steps to run
|
||||
them.
|
||||
|
||||
If you are building an Electron app that you intend to package and distribute,
|
||||
it should be code signed.
|
||||
it should be code signed. The Electron ecosystem tooling makes codesigning your
|
||||
apps straightforward - this documentation explains how sign your apps on both
|
||||
Windows and macOS.
|
||||
|
||||
## Signing & notarizing macOS builds
|
||||
|
||||
Properly preparing macOS applications for release requires two steps. First, the
|
||||
Preparing macOS applications for release requires two steps: First, the
|
||||
app needs to be code signed. Then, the app needs to be uploaded to Apple for a
|
||||
process called **notarization**, where automated systems will further verify that
|
||||
your app isn't doing anything to endanger its users.
|
||||
@@ -51,7 +42,7 @@ ways to get your application signed and notarized.
|
||||
|
||||
If you're using Electron's favorite build tool, getting your application signed
|
||||
and notarized requires a few additions to your configuration. [Forge](https://electronforge.io) is a
|
||||
collection of the official Electron tools, using [`electron-packager`][],
|
||||
collection of the official Electron tools, using [`@electron/packager`][],
|
||||
[`@electron/osx-sign`][], and [`@electron/notarize`][] under the hood.
|
||||
|
||||
Detailed instructions on how to configure your application can be found in the
|
||||
@@ -61,14 +52,16 @@ the Electron Forge docs.
|
||||
### Using Electron Packager
|
||||
|
||||
If you're not using an integrated build pipeline like Forge, you
|
||||
are likely using [`electron-packager`][], which includes [`@electron/osx-sign`][] and
|
||||
are likely using [`@electron/packager`][], which includes [`@electron/osx-sign`][] and
|
||||
[`@electron/notarize`][].
|
||||
|
||||
If you're using Packager's API, you can pass [in configuration that both signs
|
||||
and notarizes your application](https://electron.github.io/electron-packager/main/interfaces/electronpackager.options.html).
|
||||
and notarizes your application](https://electron.github.io/packager/main/modules.html).
|
||||
If the example below does not meet your needs, please see [`@electron/osx-sign`][] and
|
||||
[`@electron/notarize`][] for the many possible configuration options.
|
||||
|
||||
```js @ts-nocheck
|
||||
const packager = require('electron-packager')
|
||||
const packager = require('@electron/packager')
|
||||
|
||||
packager({
|
||||
dir: '/path/to/my/app',
|
||||
@@ -86,35 +79,81 @@ See the [Mac App Store Guide][].
|
||||
|
||||
## Signing Windows builds
|
||||
|
||||
Before signing Windows builds, you must do the following:
|
||||
Before you can code sign your application, you need to acquire a code signing
|
||||
certificate. Unlike Apple, Microsoft allows developers to purchase those
|
||||
certificates on the open market. They are usually sold by the same companies
|
||||
also offering HTTPS certificates. Prices vary, so it may be worth your time to
|
||||
shop around. Popular resellers include:
|
||||
|
||||
1. Get a Windows Authenticode code signing certificate (requires an annual fee)
|
||||
2. Install Visual Studio to get the signing utility (the free [Community
|
||||
Edition](https://visualstudio.microsoft.com/vs/community/) is enough)
|
||||
- [Certum EV code signing certificate](https://shop.certum.eu/data-safety/code-signing-certificates/certum-ev-code-sigining.html)
|
||||
- [DigiCert EV code signing certificate](https://www.digicert.com/signing/code-signing-certificates)
|
||||
- [Entrust EV code signing certificate](https://www.entrustdatacard.com/products/digital-signing-certificates/code-signing-certificates)
|
||||
- [GlobalSign EV code signing certificate](https://www.globalsign.com/en/code-signing-certificate/ev-code-signing-certificates)
|
||||
- [IdenTrust EV code signing certificate](https://www.identrust.com/digital-certificates/trustid-ev-code-signing)
|
||||
- [Sectigo (formerly Comodo) EV code signing certificate](https://sectigo.com/ssl-certificates-tls/code-signing)
|
||||
- [SSL.com EV code signing certificate](https://www.ssl.com/certificates/ev-code-signing/)
|
||||
|
||||
You can get a code signing certificate from a lot of resellers. Prices vary, so
|
||||
it may be worth your time to shop around. Popular resellers include:
|
||||
It is important to call out that since June 2023, Microsoft requires software to
|
||||
be signed with an "extended validation" certificate, also called an "EV code signing
|
||||
certificate". In the past, developers could sign software with a simpler and cheaper
|
||||
certificate called "authenticode code signing certificate" or "software-based OV certificate".
|
||||
These simpler certificates no longer provide benefits: Windows will treat your app as
|
||||
completely unsigned and display the equivalent warning dialogs.
|
||||
|
||||
- [digicert](https://www.digicert.com/dc/code-signing/microsoft-authenticode.htm)
|
||||
- [Sectigo](https://sectigo.com/ssl-certificates-tls/code-signing)
|
||||
- Amongst others, please shop around to find one that suits your needs! 😄
|
||||
The new EV certificates are required to be stored on a hardware storage module
|
||||
compliant with FIPS 140 Level 2, Common Criteria EAL 4+ or equivalent. In other words,
|
||||
the certificate cannot be simply downloaded onto a CI infrastructure. In practice,
|
||||
those storage modules look like fancy USB thumb drives.
|
||||
|
||||
:::caution Keep your certificate password private
|
||||
Your certificate password should be a **secret**. Do not share it publicly or
|
||||
commit it to your source code.
|
||||
:::
|
||||
Many certificate providers now offer "cloud-based signing" - the entire signing hardware
|
||||
is in their data center and you can use it to remotely sign code. This approach is
|
||||
popular with Electron maintainers since it makes signing your applications in CI (like
|
||||
GitHub Actions, CircleCI, etc) relatively easy.
|
||||
|
||||
At the time of writing, Electron's own apps use [DigiCert KeyLocker](https://docs.digicert.com/en/digicert-keylocker.html), but any provider that provides a command line tool for
|
||||
signing files will be compatible with Electron's tooling.
|
||||
|
||||
All tools in the Electron ecosystem use [`@electron/windows-sign`][] and typically
|
||||
expose configuration options through a `windowsSign` property. You can either use it
|
||||
to sign files directly - or use the same `windowsSign` configuration across Electron
|
||||
Forge, [`@electron/packager`][], [`electron-winstaller`][], and [`electron-wix-msi`][].
|
||||
|
||||
### Using Electron Forge
|
||||
|
||||
Electron Forge is the recommended way to sign your `Squirrel.Windows` and `WiX MSI` installers. Detailed instructions on how to configure your application can be found in the [Electron Forge Code Signing Tutorial](https://www.electronforge.io/guides/code-signing/code-signing-macos).
|
||||
Electron Forge is the recommended way to sign your app as well as your `Squirrel.Windows`
|
||||
and `WiX MSI` installers. Detailed instructions on how to configure your application can
|
||||
be found in the [Electron Forge Code Signing Tutorial](https://www.electronforge.io/guides/code-signing/code-signing-windows).
|
||||
|
||||
### Using Electron Packager
|
||||
|
||||
If you're not using an integrated build pipeline like Forge, you
|
||||
are likely using [`@electron/packager`][], which includes [`@electron/windows-sign`][].
|
||||
|
||||
If you're using Packager's API, you can pass [in configuration that signs
|
||||
your application](https://electron.github.io/packager/main/modules.html). If the
|
||||
example below does not meet your needs, please see [`@electron/windows-sign`][]
|
||||
for the many possible configuration options.
|
||||
|
||||
```js @ts-nocheck
|
||||
const packager = require('@electron/packager')
|
||||
|
||||
packager({
|
||||
dir: '/path/to/my/app',
|
||||
windowsSign: {
|
||||
signWithParams: '--my=custom --parameters',
|
||||
// If signtool.exe does not work for you, customize!
|
||||
signToolPath: 'C:\\Path\\To\\my-custom-tool.exe'
|
||||
}
|
||||
})
|
||||
```
|
||||
|
||||
### Using electron-winstaller (Squirrel.Windows)
|
||||
|
||||
[`electron-winstaller`][] is a package that can generate Squirrel.Windows installers for your
|
||||
Electron app. This is the tool used under the hood by Electron Forge's
|
||||
[Squirrel.Windows Maker][maker-squirrel]. If you're not using Electron Forge and want to use
|
||||
`electron-winstaller` directly, use the `certificateFile` and `certificatePassword` configuration
|
||||
options when creating your installer.
|
||||
[Squirrel.Windows Maker][maker-squirrel]. Just like `@electron/packager`, it uses
|
||||
[`@electron/windows-sign`][] under the hood and supports the same `windowsSign`
|
||||
options.
|
||||
|
||||
```js {10-11} @ts-nocheck
|
||||
const electronInstaller = require('electron-winstaller')
|
||||
@@ -126,8 +165,11 @@ try {
|
||||
outputDirectory: '/tmp/build/installer64',
|
||||
authors: 'My App Inc.',
|
||||
exe: 'myapp.exe',
|
||||
certificateFile: './cert.pfx',
|
||||
certificatePassword: 'this-is-a-secret'
|
||||
windowsSign: {
|
||||
signWithParams: '--my=custom --parameters',
|
||||
// If signtool.exe does not work for you, customize!
|
||||
signToolPath: 'C:\\Path\\To\\my-custom-tool.exe'
|
||||
}
|
||||
})
|
||||
console.log('It worked!')
|
||||
} catch (e) {
|
||||
@@ -141,10 +183,8 @@ For full configuration options, check out the [`electron-winstaller`][] reposito
|
||||
|
||||
[`electron-wix-msi`][] is a package that can generate MSI installers for your
|
||||
Electron app. This is the tool used under the hood by Electron Forge's [MSI Maker][maker-msi].
|
||||
|
||||
If you're not using Electron Forge and want to use `electron-wix-msi` directly, use the
|
||||
`certificateFile` and `certificatePassword` configuration options
|
||||
or pass in parameters directly to [SignTool.exe][] with the `signWithParams` option.
|
||||
Just like `@electron/packager`, it uses [`@electron/windows-sign`][] under the hood
|
||||
and supports the same `windowsSign` options.
|
||||
|
||||
```js {12-13} @ts-nocheck
|
||||
import { MSICreator } from 'electron-wix-msi'
|
||||
@@ -158,8 +198,11 @@ const msiCreator = new MSICreator({
|
||||
manufacturer: 'Kitten Technologies',
|
||||
version: '1.1.2',
|
||||
outputDirectory: '/path/to/output/folder',
|
||||
certificateFile: './cert.pfx',
|
||||
certificatePassword: 'this-is-a-secret'
|
||||
windowsSign: {
|
||||
signWithParams: '--my=custom --parameters',
|
||||
// If signtool.exe does not work for you, customize!
|
||||
signToolPath: 'C:\\Path\\To\\my-custom-tool.exe'
|
||||
}
|
||||
})
|
||||
|
||||
// Step 2: Create a .wxs template file
|
||||
@@ -190,8 +233,9 @@ See the [Windows Store Guide][].
|
||||
|
||||
[apple developer program]: https://developer.apple.com/programs/
|
||||
[`@electron/osx-sign`]: https://github.com/electron/osx-sign
|
||||
[`electron-packager`]: https://github.com/electron/electron-packager
|
||||
[`@electron/packager`]: https://github.com/electron/packager
|
||||
[`@electron/notarize`]: https://github.com/electron/notarize
|
||||
[`@electron/windows-sign`]: https://github.com/electron/windows-sign
|
||||
[`electron-winstaller`]: https://github.com/electron/windows-installer
|
||||
[`electron-wix-msi`]: https://github.com/electron-userland/electron-wix-msi
|
||||
[xcode]: https://developer.apple.com/xcode
|
||||
@@ -200,4 +244,3 @@ See the [Windows Store Guide][].
|
||||
[windows store guide]: ./windows-store-guide.md
|
||||
[maker-squirrel]: https://www.electronforge.io/config/makers/squirrel.windows
|
||||
[maker-msi]: https://www.electronforge.io/config/makers/wix-msi
|
||||
[signtool.exe]: https://learn.microsoft.com/en-us/dotnet/framework/tools/signtool-exe
|
||||
|
||||
@@ -16,7 +16,7 @@ Context isolation has been enabled by default since Electron 12, and it is a rec
|
||||
|
||||
Exposing APIs from your preload script to a loaded website in the renderer process is a common use-case. With context isolation disabled, your preload script would share a common global `window` object with the renderer. You could then attach arbitrary properties to a preload script:
|
||||
|
||||
```javascript title='preload.js' @ts-nocheck
|
||||
```js title='preload.js' @ts-nocheck
|
||||
// preload with contextIsolation disabled
|
||||
window.myAPI = {
|
||||
doAThing: () => {}
|
||||
@@ -25,7 +25,7 @@ window.myAPI = {
|
||||
|
||||
The `doAThing()` function could then be used directly in the renderer process:
|
||||
|
||||
```javascript title='renderer.js' @ts-nocheck
|
||||
```js title='renderer.js' @ts-nocheck
|
||||
// use the exposed API in the renderer
|
||||
window.myAPI.doAThing()
|
||||
```
|
||||
@@ -34,7 +34,7 @@ window.myAPI.doAThing()
|
||||
|
||||
There is a dedicated module in Electron to help you do this in a painless way. The [`contextBridge`](../api/context-bridge.md) module can be used to **safely** expose APIs from your preload script's isolated context to the context the website is running in. The API will also be accessible from the website on `window.myAPI` just like it was before.
|
||||
|
||||
```javascript title='preload.js'
|
||||
```js title='preload.js'
|
||||
// preload with contextIsolation enabled
|
||||
const { contextBridge } = require('electron')
|
||||
|
||||
@@ -43,7 +43,7 @@ contextBridge.exposeInMainWorld('myAPI', {
|
||||
})
|
||||
```
|
||||
|
||||
```javascript title='renderer.js' @ts-nocheck
|
||||
```js title='renderer.js' @ts-nocheck
|
||||
// use the exposed API in the renderer
|
||||
window.myAPI.doAThing()
|
||||
```
|
||||
@@ -54,7 +54,7 @@ Please read the `contextBridge` documentation linked above to fully understand i
|
||||
|
||||
Just enabling `contextIsolation` and using `contextBridge` does not automatically mean that everything you do is safe. For instance, this code is **unsafe**.
|
||||
|
||||
```javascript title='preload.js'
|
||||
```js title='preload.js'
|
||||
// ❌ Bad code
|
||||
contextBridge.exposeInMainWorld('myAPI', {
|
||||
send: ipcRenderer.send
|
||||
@@ -63,7 +63,7 @@ contextBridge.exposeInMainWorld('myAPI', {
|
||||
|
||||
It directly exposes a powerful API without any kind of argument filtering. This would allow any website to send arbitrary IPC messages, which you do not want to be possible. The correct way to expose IPC-based APIs would instead be to provide one method per IPC message.
|
||||
|
||||
```javascript title='preload.js'
|
||||
```js title='preload.js'
|
||||
// ✅ Good code
|
||||
contextBridge.exposeInMainWorld('myAPI', {
|
||||
loadPreferences: () => ipcRenderer.invoke('load-prefs')
|
||||
@@ -76,15 +76,15 @@ If you're building your Electron app with TypeScript, you'll want to add types t
|
||||
|
||||
For example, given this `preload.ts` script:
|
||||
|
||||
```typescript title='preload.ts'
|
||||
```ts title='preload.ts'
|
||||
contextBridge.exposeInMainWorld('electronAPI', {
|
||||
loadPreferences: () => ipcRenderer.invoke('load-prefs')
|
||||
})
|
||||
```
|
||||
|
||||
You can create a `renderer.d.ts` declaration file and globally augment the `Window` interface:
|
||||
You can create a `interface.d.ts` declaration file and globally augment the `Window` interface:
|
||||
|
||||
```typescript title='renderer.d.ts' @ts-noisolate
|
||||
```ts title='interface.d.ts' @ts-noisolate
|
||||
export interface IElectronAPI {
|
||||
loadPreferences: () => Promise<void>,
|
||||
}
|
||||
@@ -98,7 +98,7 @@ declare global {
|
||||
|
||||
Doing so will ensure that the TypeScript compiler will know about the `electronAPI` property on your global `window` object when writing scripts in your renderer process:
|
||||
|
||||
```typescript title='renderer.ts'
|
||||
```ts title='renderer.ts'
|
||||
window.electronAPI.loadPreferences()
|
||||
```
|
||||
|
||||
|
||||
@@ -50,7 +50,7 @@ of this theming, due to the use of the macOS 10.14 SDK.
|
||||
This example demonstrates an Electron application that derives its theme colors from the
|
||||
`nativeTheme`. Additionally, it provides theme toggle and reset controls using IPC channels.
|
||||
|
||||
```javascript fiddle='docs/fiddles/features/dark-mode'
|
||||
```fiddle docs/fiddles/features/dark-mode
|
||||
|
||||
```
|
||||
|
||||
@@ -199,7 +199,7 @@ Run the example using Electron Fiddle and then click the "Toggle Dark Mode" butt
|
||||
|
||||
[system-wide-dark-mode]: https://developer.apple.com/design/human-interface-guidelines/macos/visual-design/dark-mode/
|
||||
[electron-forge]: https://www.electronforge.io/
|
||||
[electron-packager]: https://github.com/electron/electron-packager
|
||||
[packager-darwindarkmode-api]: https://electron.github.io/electron-packager/main/interfaces/electronpackager.options.html#darwindarkmodesupport
|
||||
[electron-packager]: https://github.com/electron/packager
|
||||
[packager-darwindarkmode-api]: https://electron.github.io/packager/main/interfaces/electronpackager.options.html#darwindarkmodesupport
|
||||
[prefers-color-scheme]: https://developer.mozilla.org/en-US/docs/Web/CSS/@media/prefers-color-scheme
|
||||
[event-listeners]: https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener
|
||||
|
||||
@@ -26,14 +26,14 @@ This example demonstrates an Electron application that automatically selects
|
||||
the first available bluetooth device when the `Test Bluetooth` button is
|
||||
clicked.
|
||||
|
||||
```javascript fiddle='docs/fiddles/features/web-bluetooth'
|
||||
```fiddle docs/fiddles/features/web-bluetooth
|
||||
|
||||
```
|
||||
|
||||
## WebHID API
|
||||
|
||||
The [WebHID API](https://web.dev/hid/) can be used to access HID devices such
|
||||
as keyboards and gamepads. Electron provides several APIs for working with
|
||||
as keyboards and gamepads. Electron provides several APIs for working with
|
||||
the WebHID API:
|
||||
|
||||
* The [`select-hid-device` event on the Session](../api/session.md#event-select-hid-device)
|
||||
@@ -61,7 +61,7 @@ By default Electron employs the same [blocklist](https://github.com/WICG/webhid/
|
||||
used by Chromium. If you wish to override this behavior, you can do so by
|
||||
setting the `disable-hid-blocklist` flag:
|
||||
|
||||
```javascript
|
||||
```js
|
||||
app.commandLine.appendSwitch('disable-hid-blocklist')
|
||||
```
|
||||
|
||||
@@ -72,7 +72,7 @@ HID devices through [`ses.setDevicePermissionHandler(handler)`](../api/session.m
|
||||
and through [`select-hid-device` event on the Session](../api/session.md#event-select-hid-device)
|
||||
when the `Test WebHID` button is clicked.
|
||||
|
||||
```javascript fiddle='docs/fiddles/features/web-hid'
|
||||
```fiddle docs/fiddles/features/web-hid
|
||||
|
||||
```
|
||||
|
||||
@@ -112,7 +112,7 @@ as well as demonstrating selecting the first available Arduino Uno serial device
|
||||
[`select-serial-port` event on the Session](../api/session.md#event-select-serial-port)
|
||||
when the `Test Web Serial` button is clicked.
|
||||
|
||||
```javascript fiddle='docs/fiddles/features/web-serial'
|
||||
```fiddle docs/fiddles/features/web-serial
|
||||
|
||||
```
|
||||
|
||||
@@ -152,6 +152,6 @@ USB devices (if they are attached) through [`ses.setDevicePermissionHandler(hand
|
||||
and through [`select-usb-device` event on the Session](../api/session.md#event-select-usb-device)
|
||||
when the `Test WebUSB` button is clicked.
|
||||
|
||||
```javascript fiddle='docs/fiddles/features/web-usb'
|
||||
```fiddle docs/fiddles/features/web-usb
|
||||
|
||||
```
|
||||
|
||||
@@ -33,7 +33,7 @@ Using the [React Developer Tools][react-devtools] as an example:
|
||||
1. Pass the location of the extension to the [`ses.loadExtension`][load-extension]
|
||||
API. For React Developer Tools `v4.9.0`, it looks something like:
|
||||
|
||||
```javascript
|
||||
```js
|
||||
const { app, session } = require('electron')
|
||||
const path = require('node:path')
|
||||
const os = require('node:os')
|
||||
|
||||
@@ -9,12 +9,14 @@ check out our [Electron Versioning](./electron-versioning.md) doc.
|
||||
|
||||
| Electron | Alpha | Beta | Stable | EOL | Chrome | Node | Supported |
|
||||
| ------- | ----- | ------- | ------ | ------ | ---- | ---- | ---- |
|
||||
| 27.0.0 | 2023-Aug-17 | 2023-Sep-13 | 2023-Oct-10 | TBD | M118 | TBD | ✅ |
|
||||
| 26.0.0 | 2023-Jun-01 | 2023-Jun-27 | 2023-Aug-15 | 2024-Feb-27 | M116 | v18.16 | ✅ |
|
||||
| 25.0.0 | 2023-Apr-10 | 2023-May-02 | 2023-May-30 | 2024-Jan-02 | M114 | v18.15 | ✅ |
|
||||
| 24.0.0 | 2022-Feb-09 | 2023-Mar-07 | 2023-Apr-04 | 2023-Oct-10 | M112 | v18.14 | ✅ |
|
||||
| 29.0.0 | 2023-Dec-07 | 2024-Jan-24 | 2024-Feb-20 | 2024-Aug-20 | M122 | v18.19 | ✅ |
|
||||
| 28.0.0 | 2023-Oct-11 | 2023-Nov-06 | 2023-Dec-05 | 2024-Jun-11 | M120 | v18.18 | ✅ |
|
||||
| 27.0.0 | 2023-Aug-17 | 2023-Sep-13 | 2023-Oct-10 | 2024-Apr-16 | M118 | v18.17 | ✅ |
|
||||
| 26.0.0 | 2023-Jun-01 | 2023-Jun-27 | 2023-Aug-15 | 2024-Feb-20 | M116 | v18.16 | 🚫 |
|
||||
| 25.0.0 | 2023-Apr-10 | 2023-May-02 | 2023-May-30 | 2023-Dec-05 | M114 | v18.15 | 🚫 |
|
||||
| 24.0.0 | 2023-Feb-09 | 2023-Mar-07 | 2023-Apr-04 | 2023-Oct-10 | M112 | v18.14 | 🚫 |
|
||||
| 23.0.0 | 2022-Dec-01 | 2023-Jan-10 | 2023-Feb-07 | 2023-Aug-15 | M110 | v18.12 | 🚫 |
|
||||
| 22.0.0 | 2022-Sep-29 | 2022-Oct-25 | 2022-Nov-29 | 2023-Oct-10 | M108 | v16.17 | ✅ |
|
||||
| 22.0.0 | 2022-Sep-29 | 2022-Oct-25 | 2022-Nov-29 | 2023-Oct-10 | M108 | v16.17 | 🚫 |
|
||||
| 21.0.0 | 2022-Aug-04 | 2022-Aug-30 | 2022-Sep-27 | 2023-Apr-04 | M106 | v16.16 | 🚫 |
|
||||
| 20.0.0 | 2022-May-26 | 2022-Jun-21 | 2022-Aug-02 | 2023-Feb-07 | M104 | v16.15 | 🚫 |
|
||||
| 19.0.0 | 2022-Mar-31 | 2022-Apr-26 | 2022-May-24 | 2022-Nov-29 | M102 | v16.14 | 🚫 |
|
||||
@@ -36,6 +38,19 @@ check out our [Electron Versioning](./electron-versioning.md) doc.
|
||||
| 3.0.0 | -- | 2018-Jun-21 | 2018-Sep-18 | 2019-Jul-30 | M66 | v10.2 | 🚫 |
|
||||
| 2.0.0 | -- | 2018-Feb-21 | 2018-May-01 | 2019-Apr-23 | M61 | v8.9 | 🚫 |
|
||||
|
||||
:::info Official support dates may change
|
||||
|
||||
Electron's official support policy is the latest 3 stable releases. Our stable
|
||||
release and end-of-life dates are determined by Chromium, and may be subject to
|
||||
change. While we try to keep our planned release and end-of-life dates frequently
|
||||
updated here, future dates may change if affected by upstream scheduling changes,
|
||||
and may not always be accurately reflected.
|
||||
|
||||
See [Chromium's public release schedule](https://chromiumdash.appspot.com/schedule) for
|
||||
definitive information about Chromium's scheduled release dates.
|
||||
|
||||
:::
|
||||
|
||||
**Notes:**
|
||||
|
||||
* The `-alpha.1`, `-beta.1`, and `stable` dates are our solid release dates.
|
||||
@@ -47,26 +62,10 @@ check out our [Electron Versioning](./electron-versioning.md) doc.
|
||||
* Since Electron 5, Electron has been publicizing its release dates ([see blog post](https://www.electronjs.org/blog/electron-5-0-timeline)).
|
||||
* Since Electron 6, Electron major versions have been targeting every other Chromium major version. Each Electron stable should happen on the same day as Chrome stable ([see blog post](https://www.electronjs.org/blog/12-week-cadence)).
|
||||
* Since Electron 16, Electron has been releasing major versions on an 8-week cadence in accordance to Chrome's change to a 4-week release cadence ([see blog post](https://www.electronjs.org/blog/8-week-cadence)).
|
||||
|
||||
:::info Chrome release dates
|
||||
|
||||
Chromium has the own public release schedule [here](https://chromiumdash.appspot.com/schedule).
|
||||
|
||||
:::
|
||||
* Electron temporarily extended support for Electron 22 until October 10, 2023, to support an extended end-of-life for Windows 7/8/8.1
|
||||
|
||||
## Version support policy
|
||||
|
||||
:::info
|
||||
|
||||
The Electron team will temporarily support Electron 22 until October 10, 2023.
|
||||
This extended support is intended to help Electron developers who still need
|
||||
support for Windows 7/8/8.1, which ended support in Electron 23. The October
|
||||
support date follows the extended support dates from both Chromium and Microsoft.
|
||||
On October 11, the Electron team will drop support back to the latest three
|
||||
stable major versions.
|
||||
|
||||
:::
|
||||
|
||||
The latest three _stable_ major versions are supported by the Electron team.
|
||||
For example, if the latest release is 6.1.x, then the 5.0.x as well
|
||||
as the 4.2.x series are supported. We only support the latest minor release
|
||||
@@ -78,6 +77,38 @@ and the version prior to that receives the vast majority of those fixes
|
||||
as time and bandwidth warrants. The oldest supported release line will receive
|
||||
only security fixes directly.
|
||||
|
||||
### Chromium version support
|
||||
|
||||
:::info Chromium release schedule
|
||||
|
||||
Chromium's public release schedule is [here](https://chromiumdash.appspot.com/schedule).
|
||||
|
||||
:::
|
||||
|
||||
Electron targets Chromium even-number versions, releasing every 8 weeks in concert
|
||||
with Chromium's 4-week release schedule. For example, Electron 26 uses Chromium 116, while Electron 27 uses Chromium 118.
|
||||
|
||||
### Node.js version support
|
||||
|
||||
Electron upgrades its `main` branch to even-number versions of Node.js when they enter Active LTS. The schedule
|
||||
is as follows:
|
||||
|
||||
<img src="https://raw.githubusercontent.com/nodejs/Release/main/schedule.svg?sanitize=true" alt="Releases">
|
||||
|
||||
As a rule, stable branches of Electron do not receive Node.js upgrades after they have been cut.
|
||||
If Electron has recently updated its `main` branch to a new major version of Node.js, the next stable
|
||||
branch to be cut will be released with the new version.
|
||||
|
||||
Patch upgrades of Node that contain significant security or bug fixes, and are submitted
|
||||
more than 2 weeks prior to a stable release date, will be accepted into an Electron alpha
|
||||
or beta release branch.
|
||||
|
||||
Minor upgrades of Node that contain significant security or bug fixes, and are submitted
|
||||
more than 2 weeks prior to a stable release date may be accepted into an Electron alpha or
|
||||
beta release branch on a case-by-case basis. These requests will be reviewed and voted on
|
||||
by the [Releases Working Group](https://github.com/electron/governance/tree/main/wg-releases),
|
||||
to ensure minimal disruption for developers who may be consuming alpha or beta releases.
|
||||
|
||||
### Breaking API changes
|
||||
|
||||
When an API is changed or removed in a way that breaks existing functionality, the
|
||||
|
||||
@@ -1,38 +0,0 @@
|
||||
# ESM Limitations
|
||||
|
||||
This document serves to outline the limitations / differences between ESM in Electron and ESM in Node.js and Chromium.
|
||||
|
||||
## ESM Support Matrix
|
||||
|
||||
This table gives a general overview of where ESM is supported and most importantly which ESM loader is used.
|
||||
|
||||
| | Supported | Loader | Supported in Preload | Loader in Preload | Applicable Requirements |
|
||||
|-|-|-|-|-|-|
|
||||
| Main Process | Yes | Node.js | N/A | N/A | <ul><li> [You must `await` generously in the main process to avoid race conditions](#you-must-use-await-generously-in-the-main-process-to-avoid-race-conditions) </li></ul> |
|
||||
| Sandboxed Renderer | Yes | Chromium | No | | <ul><li> [Sandboxed preload scripts can't use ESM imports](#sandboxed-preload-scripts-cant-use-esm-imports) </li></ul> |
|
||||
| Node.js Renderer + Context Isolation | Yes | Chromium | Yes | Node.js | <ul><li> [Node.js ESM Preload Scripts will run after page load on pages with no content](#nodejs-esm-preload-scripts-will-run-after-page-load-on-pages-with-no-content) </li> <li>[ESM Preload Scripts must have the `.mjs` extension](#esm-preload-scripts-must-have-the-mjs-extension)</li></ul> |
|
||||
| Node.js Renderer + No Context Isolation | Yes | Chromium | Yes | Node.js | <ul><li> [Non-context-isolated renderers can't use dynamic Node.js ESM imports](#non-context-isolated-renderers-cant-use-dynamic-nodejs-esm-imports) </li> <li>[ESM Preload Scripts must have the `.mjs` extension](#esm-preload-scripts-must-have-the-mjs-extension)</li></ul> |
|
||||
|
||||
## Requirements
|
||||
|
||||
### You must use `await` generously in the main process to avoid race conditions
|
||||
|
||||
Certain APIs in Electron (`app.setPath` for instance) are documented as needing to be called **before** the `app.on('ready')` event is emitted. When using ESM in the main process it is only guaranteed that the `ready` event hasn't been emitted while executing the side-effects of the primary import. i.e. if `index.mjs` calls `import('./set-up-paths.mjs')` at the top level the app will likely already be "ready" by the time that dynamic import resolves. To avoid this you should `await import('./set-up-paths.mjs')` at the top level of `index.mjs`. It's not just import calls you should await, if you are reading files asynchronously or performing other asynchronous actions you must await those at the top-level as well to ensure the app does not resume initialization and become ready too early.
|
||||
|
||||
### Sandboxed preload scripts can't use ESM imports
|
||||
|
||||
Sandboxed preload scripts are run as plain javascript without an ESM context. It is recommended that preload scripts are bundled via something like `webpack` or `vite` for performance reasons regardless, so your preload script should just be a single file that doesn't need to use ESM imports. Loading the `electron` API is still done via `require('electron')`.
|
||||
|
||||
### Node.js ESM Preload Scripts will run after page load on pages with no content
|
||||
|
||||
If the response body for the page is **completely** empty, i.e. `Content-Length: 0`, the preload script will not block the page load, which may result in race conditions. If this impacts you, change your response body to have _something_ in it, for example an empty `html` tag (`<html></html>`) or swap back to using a CommonJS preload script (`.js` or `.cjs`) which will block the page load.
|
||||
|
||||
### ESM Preload Scripts must have the `.mjs` extension
|
||||
|
||||
In order to load an ESM preload script it must have a `.mjs` file extension. Using `type: module` in a nearby package.json is not sufficient. Please also note the limitation above around not blocking page load if the page is empty.
|
||||
|
||||
### Non-context-isolated renderers can't use dynamic Node.js ESM imports
|
||||
|
||||
If your renderer process does not have `contextIsolation` enabled you can not `import()` ESM files via the Node.js module loader. This means that you can't `import('fs')` or `import('./foo')`. If you want to be able to do so you must enable context isolation. This is because in the renderer Chromium's `import()` function takes precedence and without context isolation there is no way for Electron to know which loader to route the request to.
|
||||
|
||||
If you enable context isolation `import()` from the isolated preload context will use the Node.js loader and `import()` from the main context will continue using Chromium's loader.
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user