mirror of
https://github.com/electron/electron.git
synced 2026-02-19 03:14:51 -05:00
Compare commits
212 Commits
v28.2.3
...
same-party
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e3bd73cbd7 | ||
|
|
4f3391d92a | ||
|
|
5cbaf97e31 | ||
|
|
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 |
@@ -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
|
||||
python3 $GOMA_DIR/goma_ctl.py stat
|
||||
python3 $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"
|
||||
@@ -789,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
|
||||
|
||||
@@ -799,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
|
||||
@@ -808,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
|
||||
@@ -820,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
|
||||
@@ -829,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
|
||||
@@ -839,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
|
||||
@@ -1187,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:
|
||||
@@ -1210,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
|
||||
@@ -1342,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
|
||||
@@ -1443,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:
|
||||
@@ -1562,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
|
||||
@@ -1656,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
|
||||
@@ -1750,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
|
||||
@@ -2164,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
|
||||
@@ -2296,6 +2266,7 @@ jobs:
|
||||
<<: *env-global
|
||||
<<: *env-headless-testing
|
||||
<<: *env-stack-dumping
|
||||
parallelism: 3
|
||||
steps:
|
||||
- electron-tests:
|
||||
artifact-key: linux-arm
|
||||
@@ -2307,6 +2278,7 @@ jobs:
|
||||
<<: *env-global
|
||||
<<: *env-headless-testing
|
||||
<<: *env-stack-dumping
|
||||
parallelism: 3
|
||||
steps:
|
||||
- electron-tests:
|
||||
artifact-key: linux-arm64
|
||||
|
||||
35
.github/workflows/branch-created.yml
vendored
35
.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
|
||||
@@ -72,21 +72,44 @@ jobs:
|
||||
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": major + 1,
|
||||
"prev-major": major - 1,
|
||||
"next-major": nextMajor,
|
||||
"prev-major": prevMajor,
|
||||
}))
|
||||
core.setOutput("title", `${major}-x-y`)
|
||||
- name: Create Release Project Board
|
||||
if: ${{ steps.check-major-version.outputs.MAJOR }}
|
||||
uses: dsanders11/project-actions/copy-project@a24415515fa60a22f71f9d9d00e36ca82660cde9 # v1.0.1
|
||||
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.title}}
|
||||
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 }}
|
||||
- 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 }}
|
||||
|
||||
19
.github/workflows/pull-request-labeled.yml
vendored
19
.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 ✅'
|
||||
|
||||
60
BUILD.gn
60
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")
|
||||
@@ -165,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" ]
|
||||
|
||||
@@ -219,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" ]
|
||||
|
||||
@@ -230,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") {
|
||||
@@ -434,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",
|
||||
@@ -442,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",
|
||||
@@ -483,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",
|
||||
@@ -713,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",
|
||||
@@ -1328,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.6045.0',
|
||||
'122.0.6261.70',
|
||||
'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.6045.0
|
||||
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') -And -not $_.Contains('The gn arg use_goma=true') } | Set-Content out/Default/mksnapshot_args
|
||||
- ninja -C out/Default electron:electron_mksnapshot_zip
|
||||
- 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
|
||||
|
||||
71
appveyor.yml
71
appveyor.yml
@@ -29,7 +29,7 @@
|
||||
|
||||
version: 1.0.{build}
|
||||
build_cloud: electronhq-16-core
|
||||
image: e-119.0.6045.0
|
||||
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') -And -not $_.Contains('The gn arg use_goma=true') } | Set-Content out/Default/mksnapshot_args
|
||||
- ninja -C out/Default electron:electron_mksnapshot_zip
|
||||
- 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 = 119
|
||||
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" ]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,4 +23,10 @@ declare_args() {
|
||||
# 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) {
|
||||
@@ -235,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",
|
||||
@@ -257,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",
|
||||
@@ -334,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",
|
||||
]
|
||||
@@ -441,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(() => {
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 })
|
||||
@@ -780,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()
|
||||
|
||||
@@ -1035,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()
|
||||
|
||||
@@ -1178,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()
|
||||
|
||||
@@ -1194,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'] },
|
||||
|
||||
@@ -10,7 +10,7 @@ In Electron, for the APIs that take images, you can pass either file paths or
|
||||
For example, when creating a tray or setting a window's icon, you can pass an
|
||||
image file path as a `string`:
|
||||
|
||||
```javascript
|
||||
```js
|
||||
const { BrowserWindow, Tray } = require('electron')
|
||||
|
||||
const appIcon = new Tray('/Users/somebody/images/icon.png')
|
||||
@@ -20,7 +20,7 @@ console.log(appIcon, win)
|
||||
|
||||
Or read the image from the clipboard, which returns a `NativeImage`:
|
||||
|
||||
```javascript
|
||||
```js
|
||||
const { clipboard, Tray } = require('electron')
|
||||
const image = clipboard.readImage()
|
||||
const appIcon = new Tray(image)
|
||||
@@ -51,6 +51,13 @@ Check the _Size requirements_ section in [this article][icons].
|
||||
|
||||
[icons]: https://learn.microsoft.com/en-us/windows/win32/uxguide/vis-icons
|
||||
|
||||
:::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
|
||||
@@ -71,7 +78,7 @@ images/
|
||||
└── icon@3x.png
|
||||
```
|
||||
|
||||
```javascript
|
||||
```js
|
||||
const { Tray } = require('electron')
|
||||
const appIcon = new Tray('/Users/somebody/images/icon.png')
|
||||
console.log(appIcon)
|
||||
@@ -138,7 +145,7 @@ 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
|
||||
```js
|
||||
const nativeImage = require('electron').nativeImage
|
||||
|
||||
const image = nativeImage.createFromPath('/Users/somebody/images/icon.png')
|
||||
|
||||
@@ -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) => {
|
||||
@@ -1054,7 +965,7 @@ Additionally, the default behavior of Electron is to store granted device permis
|
||||
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.
|
||||
|
||||
@@ -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 }
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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,6 +12,76 @@ 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`
|
||||
@@ -88,6 +158,12 @@ app.on('renderer-process-crashed', (event, webContents, killed) => { /* ... */ }
|
||||
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.
|
||||
@@ -103,6 +179,19 @@ 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
|
||||
@@ -136,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
|
||||
@@ -515,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
|
||||
@@ -1180,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
|
||||
@@ -1209,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
|
||||
@@ -1224,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>
|
||||
|
||||
|
||||
@@ -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/).
|
||||
|
||||
@@ -51,7 +51,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 +61,14 @@ 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/interfaces/electronpackager.options.html).
|
||||
|
||||
```js @ts-nocheck
|
||||
const packager = require('electron-packager')
|
||||
const packager = require('@electron/packager')
|
||||
|
||||
packager({
|
||||
dir: '/path/to/my/app',
|
||||
@@ -190,7 +190,7 @@ 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-winstaller`]: https://github.com/electron/windows-installer
|
||||
[`electron-wix-msi`]: https://github.com/electron-userland/electron-wix-msi
|
||||
|
||||
@@ -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,10 +9,11 @@ check out our [Electron Versioning](./electron-versioning.md) doc.
|
||||
|
||||
| Electron | Alpha | Beta | Stable | EOL | Chrome | Node | Supported |
|
||||
| ------- | ----- | ------- | ------ | ------ | ---- | ---- | ---- |
|
||||
| 28.0.0 | 2023-Oct-11 | 2023-Nov-6 | 2023-Dec-5 | TBD | M120 | TBD | ✅ |
|
||||
| 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-27 | M116 | v18.16 | ✅ |
|
||||
| 25.0.0 | 2023-Apr-10 | 2023-May-02 | 2023-May-30 | 2024-Jan-02 | M114 | v18.15 | ✅ |
|
||||
| 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 | 🚫 |
|
||||
@@ -37,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.
|
||||
@@ -48,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
|
||||
@@ -79,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
|
||||
|
||||
@@ -16,16 +16,7 @@ Once Fiddle is installed, you can press on the "Open in Fiddle" button that you
|
||||
will find below code samples like the following one:
|
||||
|
||||
```fiddle docs/fiddles/quick-start
|
||||
window.addEventListener('DOMContentLoaded', () => {
|
||||
const replaceText = (selector, text) => {
|
||||
const element = document.getElementById(selector)
|
||||
if (element) element.innerText = text
|
||||
}
|
||||
|
||||
for (const type of ['chrome', 'node', 'electron']) {
|
||||
replaceText(`${type}-version`, process.versions[type])
|
||||
}
|
||||
})
|
||||
```
|
||||
|
||||
If there is still something that you do not know how to do, please take a look at the [API][app]
|
||||
|
||||
@@ -15,7 +15,7 @@ Fuses are the solution to this problem, at a high level they are "magic bits" in
|
||||
**Default:** Enabled
|
||||
**@electron/fuses:** `FuseV1Options.RunAsNode`
|
||||
|
||||
The runAsNode fuse toggles whether the `ELECTRON_RUN_AS_NODE` environment variable is respected or not. Please note that if this fuse is disabled then `process.fork` in the main process will not function as expected as it depends on this environment variable to function.
|
||||
The runAsNode fuse toggles whether the `ELECTRON_RUN_AS_NODE` environment variable is respected or not. Please note that if this fuse is disabled then `process.fork` in the main process will not function as expected as it depends on this environment variable to function. Instead, we recommend that you use [Utility Processes](../api/utility-process.md), which work for many use cases where you need a standalone Node.js process (like a Sqlite server process or similar scenarios).
|
||||
|
||||
### `cookieEncryption`
|
||||
|
||||
@@ -61,6 +61,19 @@ The onlyLoadAppFromAsar fuse changes the search system that Electron uses to loc
|
||||
|
||||
The loadBrowserProcessSpecificV8Snapshot fuse changes which V8 snapshot file is used for the browser process. By default Electron's processes will all use the same V8 snapshot file. When this fuse is enabled the browser process uses the file called `browser_v8_context_snapshot.bin` for its V8 snapshot. The other processes will use the V8 snapshot file that they normally do.
|
||||
|
||||
### `grantFileProtocolExtraPrivileges`
|
||||
|
||||
**Default:** Enabled
|
||||
**@electron/fuses:** `FuseV1Options.GrantFileProtocolExtraPrivileges`
|
||||
|
||||
The grantFileProtocolExtraPrivileges fuse changes whether pages loaded from the `file://` protocol are given privileges beyond what they would receive in a traditional web browser. This behavior was core to Electron apps in original versions of Electron but is no longer required as apps should be [serving local files from custom protocols](./security.md#18-avoid-usage-of-the-file-protocol-and-prefer-usage-of-custom-protocols) now instead. If you aren't serving pages from `file://` you should disable this fuse.
|
||||
|
||||
The extra privileges granted to the `file://` protocol by this fuse are incompletely documented below:
|
||||
|
||||
* `file://` protocol pages can use `fetch` to load other assets over `file://`
|
||||
* `file://` protocol pages can use service workers
|
||||
* `file://` protocol pages have universal access granted to child frames also running on `file://` protocols regardless of sandbox settings
|
||||
|
||||
## How do I flip the fuses?
|
||||
|
||||
### The easy way
|
||||
|
||||
@@ -34,7 +34,7 @@ To test In-App Purchase in development with Electron you'll have to change the `
|
||||
|
||||
Here is an example that shows how to use In-App Purchases in Electron. You'll have to replace the product ids by the identifiers of the products created with iTunes Connect (the identifier of `com.example.app.product1` is `product1`). Note that you have to listen to the `transactions-updated` event as soon as possible in your app.
|
||||
|
||||
```javascript
|
||||
```js
|
||||
// Main process
|
||||
const { inAppPurchase } = require('electron')
|
||||
const PRODUCT_IDS = ['id1', 'id2']
|
||||
@@ -107,7 +107,7 @@ if (!inAppPurchase.canMakePayments()) {
|
||||
inAppPurchase.getProducts(PRODUCT_IDS).then(products => {
|
||||
// Check the parameters.
|
||||
if (!Array.isArray(products) || products.length <= 0) {
|
||||
console.log('Unable to retrieve the product informations.')
|
||||
console.log('Unable to retrieve the product information.')
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
@@ -66,7 +66,7 @@ You can use environment variables to override the base URL, the path at which to
|
||||
look for Electron binaries, and the binary filename. The URL used by `@electron/get`
|
||||
is composed as follows:
|
||||
|
||||
```javascript @ts-nocheck
|
||||
```js @ts-nocheck
|
||||
url = ELECTRON_MIRROR + ELECTRON_CUSTOM_DIR + '/' + ELECTRON_CUSTOM_FILENAME
|
||||
```
|
||||
|
||||
@@ -91,9 +91,9 @@ The above configuration will download from URLs such as
|
||||
`https://npmmirror.com/mirrors/electron/8.0.0/electron-v8.0.0-linux-x64.zip`.
|
||||
|
||||
If your mirror serves artifacts with different checksums to the official
|
||||
Electron release you may have to set `electron_use_remote_checksums=1` to
|
||||
force Electron to use the remote `SHASUMS256.txt` file to verify the checksum
|
||||
instead of the embedded checksums.
|
||||
Electron release you may have to set `electron_use_remote_checksums=1` directly,
|
||||
or configure it in a `.npmrc` file, to force Electron to use the remote `SHASUMS256.txt`
|
||||
file to verify the checksum instead of the embedded checksums.
|
||||
|
||||
#### Cache
|
||||
|
||||
|
||||
@@ -50,7 +50,7 @@ sections.
|
||||
|
||||
In the main process, set an IPC listener on the `set-title` channel with the `ipcMain.on` API:
|
||||
|
||||
```javascript {6-10,22} title='main.js (Main Process)'
|
||||
```js {6-10,22} title='main.js (Main Process)'
|
||||
const { app, BrowserWindow, ipcMain } = require('electron')
|
||||
const path = require('node:path')
|
||||
|
||||
@@ -96,7 +96,7 @@ you need to choose which APIs to expose from your preload script using the `cont
|
||||
In your preload script, add the following code, which will expose a global `window.electronAPI`
|
||||
variable to your renderer process.
|
||||
|
||||
```javascript title='preload.js (Preload Script)'
|
||||
```js title='preload.js (Preload Script)'
|
||||
const { contextBridge, ipcRenderer } = require('electron')
|
||||
|
||||
contextBridge.exposeInMainWorld('electronAPI', {
|
||||
@@ -138,7 +138,7 @@ To make these elements interactive, we'll be adding a few lines of code in the i
|
||||
`renderer.js` file that leverages the `window.electronAPI` functionality exposed from the preload
|
||||
script:
|
||||
|
||||
```javascript title='renderer.js (Renderer Process)' @ts-expect-error=[4,5]
|
||||
```js title='renderer.js (Renderer Process)' @ts-expect-error=[4,5]
|
||||
const setButton = document.getElementById('btn')
|
||||
const titleInput = document.getElementById('title')
|
||||
setButton.addEventListener('click', () => {
|
||||
@@ -181,7 +181,7 @@ provided to the renderer process. Please refer to
|
||||
[#24427](https://github.com/electron/electron/issues/24427) for details.
|
||||
:::
|
||||
|
||||
```javascript {6-13,25} title='main.js (Main Process)'
|
||||
```js {6-13,25} title='main.js (Main Process)'
|
||||
const { app, BrowserWindow, dialog, ipcMain } = require('electron')
|
||||
const path = require('node:path')
|
||||
|
||||
@@ -225,7 +225,7 @@ In the preload script, we expose a one-line `openFile` function that calls and r
|
||||
`ipcRenderer.invoke('dialog:openFile')`. We'll be using this API in the next step to call the
|
||||
native dialog from our renderer's user interface.
|
||||
|
||||
```javascript title='preload.js (Preload Script)'
|
||||
```js title='preload.js (Preload Script)'
|
||||
const { contextBridge, ipcRenderer } = require('electron')
|
||||
|
||||
contextBridge.exposeInMainWorld('electronAPI', {
|
||||
@@ -263,7 +263,7 @@ The UI consists of a single `#btn` button element that will be used to trigger o
|
||||
a `#filePath` element that will be used to display the path of the selected file. Making these
|
||||
pieces work will take a few lines of code in the renderer process script:
|
||||
|
||||
```javascript title='renderer.js (Renderer Process)' @ts-expect-error=[5]
|
||||
```js title='renderer.js (Renderer Process)' @ts-expect-error=[5]
|
||||
const btn = document.getElementById('btn')
|
||||
const filePathElement = document.getElementById('filePath')
|
||||
|
||||
@@ -280,8 +280,8 @@ selected file path in the `#filePath` element.
|
||||
### Note: legacy approaches
|
||||
|
||||
The `ipcRenderer.invoke` API was added in Electron 7 as a developer-friendly way to tackle two-way
|
||||
IPC from the renderer process. However, there exist a couple alternative approaches to this IPC
|
||||
pattern.
|
||||
IPC from the renderer process. However, a couple of alternative approaches to this IPC pattern
|
||||
exist.
|
||||
|
||||
:::warning Avoid legacy approaches if possible
|
||||
We recommend using `ipcRenderer.invoke` whenever possible. The following two-way renderer-to-main
|
||||
@@ -299,7 +299,7 @@ The `ipcRenderer.send` API that we used for single-way communication can also be
|
||||
perform two-way communication. This was the recommended way for asynchronous two-way communication
|
||||
via IPC prior to Electron 7.
|
||||
|
||||
```javascript title='preload.js (Preload Script)'
|
||||
```js title='preload.js (Preload Script)'
|
||||
// You can also put expose this code to the renderer
|
||||
// process with the `contextBridge` API
|
||||
const { ipcRenderer } = require('electron')
|
||||
@@ -310,7 +310,7 @@ ipcRenderer.on('asynchronous-reply', (_event, arg) => {
|
||||
ipcRenderer.send('asynchronous-message', 'ping')
|
||||
```
|
||||
|
||||
```javascript title='main.js (Main Process)'
|
||||
```js title='main.js (Main Process)'
|
||||
ipcMain.on('asynchronous-message', (event, arg) => {
|
||||
console.log(arg) // prints "ping" in the Node console
|
||||
// works like `send`, but returning a message back
|
||||
@@ -332,7 +332,7 @@ channels, you would need to add additional app code to track each call and respo
|
||||
The `ipcRenderer.sendSync` API sends a message to the main process and waits _synchronously_ for a
|
||||
response.
|
||||
|
||||
```javascript title='main.js (Main Process)'
|
||||
```js title='main.js (Main Process)'
|
||||
const { ipcMain } = require('electron')
|
||||
ipcMain.on('synchronous-message', (event, arg) => {
|
||||
console.log(arg) // prints "ping" in the Node console
|
||||
@@ -340,7 +340,7 @@ ipcMain.on('synchronous-message', (event, arg) => {
|
||||
})
|
||||
```
|
||||
|
||||
```javascript title='preload.js (Preload Script)'
|
||||
```js title='preload.js (Preload Script)'
|
||||
// You can also put expose this code to the renderer
|
||||
// process with the `contextBridge` API
|
||||
const { ipcRenderer } = require('electron')
|
||||
@@ -376,7 +376,7 @@ For this demo, we'll need to first build a custom menu in the main process using
|
||||
module that uses the `webContents.send` API to send an IPC message from the main process to the
|
||||
target renderer.
|
||||
|
||||
```javascript {11-26} title='main.js (Main Process)'
|
||||
```js {11-26} title='main.js (Main Process)'
|
||||
const { app, BrowserWindow, Menu, ipcMain } = require('electron')
|
||||
const path = require('node:path')
|
||||
|
||||
@@ -412,7 +412,7 @@ function createWindow () {
|
||||
For the purposes of the tutorial, it's important to note that the `click` handler
|
||||
sends a message (either `1` or `-1`) to the renderer process through the `update-counter` channel.
|
||||
|
||||
```javascript @ts-type={mainWindow:Electron.BrowserWindow}
|
||||
```js @ts-type={mainWindow:Electron.BrowserWindow}
|
||||
click: () => mainWindow.webContents.send('update-counter', -1)
|
||||
```
|
||||
|
||||
@@ -425,11 +425,11 @@ Make sure you're loading the `index.html` and `preload.js` entry points for the
|
||||
Like in the previous renderer-to-main example, we use the `contextBridge` and `ipcRenderer`
|
||||
modules in the preload script to expose IPC functionality to the renderer process:
|
||||
|
||||
```javascript title='preload.js (Preload Script)'
|
||||
```js title='preload.js (Preload Script)'
|
||||
const { contextBridge, ipcRenderer } = require('electron')
|
||||
|
||||
contextBridge.exposeInMainWorld('electronAPI', {
|
||||
onUpdateCounter: (callback) => ipcRenderer.on('update-counter', callback)
|
||||
onUpdateCounter: (callback) => ipcRenderer.on('update-counter', (_event, value) => callback(value))
|
||||
})
|
||||
```
|
||||
|
||||
@@ -439,13 +439,15 @@ After loading the preload script, your renderer process should have access to th
|
||||
:::caution Security warning
|
||||
We don't directly expose the whole `ipcRenderer.on` API for [security reasons][]. Make sure to
|
||||
limit the renderer's access to Electron APIs as much as possible.
|
||||
Also don't just pass the callback to `ipcRenderer.on` as this will leak `ipcRenderer` via `event.sender`.
|
||||
Use a custom handler that invoke the `callback` only with the desired arguments.
|
||||
:::
|
||||
|
||||
:::info
|
||||
In the case of this minimal example, you can call `ipcRenderer.on` directly in the preload script
|
||||
rather than exposing it over the context bridge.
|
||||
|
||||
```javascript title='preload.js (Preload Script)'
|
||||
```js title='preload.js (Preload Script)'
|
||||
const { ipcRenderer } = require('electron')
|
||||
|
||||
window.addEventListener('DOMContentLoaded', () => {
|
||||
@@ -486,10 +488,10 @@ To tie it all together, we'll create an interface in the loaded HTML file that c
|
||||
Finally, to make the values update in the HTML document, we'll add a few lines of DOM manipulation
|
||||
so that the value of the `#counter` element is updated whenever we fire an `update-counter` event.
|
||||
|
||||
```javascript title='renderer.js (Renderer Process)' @ts-window-type={electronAPI:{onUpdateCounter:(callback:(event:Electron.IpcRendererEvent,value:number)=>void)=>void}}
|
||||
```js title='renderer.js (Renderer Process)' @ts-window-type={electronAPI:{onUpdateCounter:(callback:(value:number)=>void)=>void}}
|
||||
const counter = document.getElementById('counter')
|
||||
|
||||
window.electronAPI.onUpdateCounter((_event, value) => {
|
||||
window.electronAPI.onUpdateCounter((value) => {
|
||||
const oldValue = Number(counter.innerText)
|
||||
const newValue = oldValue + value
|
||||
counter.innerText = newValue.toString()
|
||||
@@ -506,23 +508,32 @@ There's no equivalent for `ipcRenderer.invoke` for main-to-renderer IPC. Instead
|
||||
send a reply back to the main process from within the `ipcRenderer.on` callback.
|
||||
|
||||
We can demonstrate this with slight modifications to the code from the previous example. In the
|
||||
renderer process, use the `event` parameter to send a reply back to the main process through the
|
||||
renderer process, expose another API to send a reply back to the main process through the
|
||||
`counter-value` channel.
|
||||
|
||||
```javascript title='renderer.js (Renderer Process)' @ts-window-type={electronAPI:{onUpdateCounter:(callback:(event:Electron.IpcRendererEvent,value:number)=>void)=>void}}
|
||||
```js title='preload.js (Preload Script)'
|
||||
const { contextBridge, ipcRenderer } = require('electron')
|
||||
|
||||
contextBridge.exposeInMainWorld('electronAPI', {
|
||||
onUpdateCounter: (callback) => ipcRenderer.on('update-counter', (_event, value) => callback(value)),
|
||||
counterValue: (value) => ipcRenderer.send('counter-value', value)
|
||||
})
|
||||
```
|
||||
|
||||
```js title='renderer.js (Renderer Process)' @ts-window-type={electronAPI:{onUpdateCounter:(callback:(value:number)=>void)=>void,counterValue:(value:number)=>void}}
|
||||
const counter = document.getElementById('counter')
|
||||
|
||||
window.electronAPI.onUpdateCounter((event, value) => {
|
||||
window.electronAPI.onUpdateCounter((value) => {
|
||||
const oldValue = Number(counter.innerText)
|
||||
const newValue = oldValue + value
|
||||
counter.innerText = newValue.toString()
|
||||
event.sender.send('counter-value', newValue)
|
||||
window.electronAPI.counterValue(newValue)
|
||||
})
|
||||
```
|
||||
|
||||
In the main process, listen for `counter-value` events and handle them appropriately.
|
||||
|
||||
```javascript title='main.js (Main Process)'
|
||||
```js title='main.js (Main Process)'
|
||||
// ...
|
||||
ipcMain.on('counter-value', (_event, value) => {
|
||||
console.log(value) // will print value to Node console
|
||||
|
||||
@@ -14,11 +14,19 @@ To configure a local keyboard shortcut, you need to specify an [`accelerator`][]
|
||||
property when creating a [MenuItem][] within the [Menu][] module.
|
||||
|
||||
Starting with a working application from the
|
||||
[Quick Start Guide](quick-start.md), update the `main.js` file with the
|
||||
following lines:
|
||||
[Quick Start Guide](quick-start.md), update the `main.js` to be:
|
||||
|
||||
```javascript fiddle='docs/fiddles/features/keyboard-shortcuts/local'
|
||||
const { Menu, MenuItem } = require('electron')
|
||||
```fiddle docs/fiddles/features/keyboard-shortcuts/local
|
||||
const { app, BrowserWindow, Menu, MenuItem } = require('electron/main')
|
||||
|
||||
function createWindow () {
|
||||
const win = new BrowserWindow({
|
||||
width: 800,
|
||||
height: 600
|
||||
})
|
||||
|
||||
win.loadFile('index.html')
|
||||
}
|
||||
|
||||
const menu = new Menu()
|
||||
menu.append(new MenuItem({
|
||||
@@ -31,6 +39,20 @@ menu.append(new MenuItem({
|
||||
}))
|
||||
|
||||
Menu.setApplicationMenu(menu)
|
||||
|
||||
app.whenReady().then(createWindow)
|
||||
|
||||
app.on('window-all-closed', () => {
|
||||
if (process.platform !== 'darwin') {
|
||||
app.quit()
|
||||
}
|
||||
})
|
||||
|
||||
app.on('activate', () => {
|
||||
if (BrowserWindow.getAllWindows().length === 0) {
|
||||
createWindow()
|
||||
}
|
||||
})
|
||||
```
|
||||
|
||||
> NOTE: In the code above, you can see that the accelerator differs based on the
|
||||
@@ -53,17 +75,37 @@ module to detect keyboard events even when the application does not have
|
||||
keyboard focus.
|
||||
|
||||
Starting with a working application from the
|
||||
[Quick Start Guide](quick-start.md), update the `main.js` file with the
|
||||
following lines:
|
||||
[Quick Start Guide](quick-start.md), update the `main.js` to be:
|
||||
|
||||
```javascript fiddle='docs/fiddles/features/keyboard-shortcuts/global' @ts-type={createWindow:()=>void}
|
||||
const { app, globalShortcut } = require('electron')
|
||||
```fiddle docs/fiddles/features/keyboard-shortcuts/global
|
||||
const { app, BrowserWindow, globalShortcut } = require('electron/main')
|
||||
|
||||
function createWindow () {
|
||||
const win = new BrowserWindow({
|
||||
width: 800,
|
||||
height: 600
|
||||
})
|
||||
|
||||
win.loadFile('index.html')
|
||||
}
|
||||
|
||||
app.whenReady().then(() => {
|
||||
globalShortcut.register('Alt+CommandOrControl+I', () => {
|
||||
console.log('Electron loves global shortcuts!')
|
||||
})
|
||||
}).then(createWindow)
|
||||
|
||||
app.on('window-all-closed', () => {
|
||||
if (process.platform !== 'darwin') {
|
||||
app.quit()
|
||||
}
|
||||
})
|
||||
|
||||
app.on('activate', () => {
|
||||
if (BrowserWindow.getAllWindows().length === 0) {
|
||||
createWindow()
|
||||
}
|
||||
})
|
||||
```
|
||||
|
||||
> NOTE: In the code above, the `CommandOrControl` combination uses `Command`
|
||||
@@ -81,8 +123,8 @@ If you want to handle keyboard shortcuts within a [BrowserWindow][], you can
|
||||
listen for the `keyup` and `keydown` [DOM events][dom-events] inside the
|
||||
renderer process using the [addEventListener() API][addEventListener-api].
|
||||
|
||||
```javascript fiddle='docs/fiddles/features/keyboard-shortcuts/web-apis|focus=renderer.js'
|
||||
const handleKeyPress = (event) => {
|
||||
```fiddle docs/fiddles/features/keyboard-shortcuts/web-apis|focus=renderer.js
|
||||
function handleKeyPress (event) {
|
||||
// You can put code here to handle the keypress.
|
||||
document.getElementById('last-keypress').innerText = event.key
|
||||
console.log(`You pressed ${event.key}`)
|
||||
@@ -105,8 +147,8 @@ Starting with a working application from the
|
||||
[Quick Start Guide](quick-start.md), update the `main.js` file with the
|
||||
following lines:
|
||||
|
||||
```javascript fiddle='docs/fiddles/features/keyboard-shortcuts/interception-from-main'
|
||||
const { app, BrowserWindow } = require('electron')
|
||||
```fiddle docs/fiddles/features/keyboard-shortcuts/interception-from-main
|
||||
const { app, BrowserWindow } = require('electron/main')
|
||||
|
||||
app.whenReady().then(() => {
|
||||
const win = new BrowserWindow({ width: 800, height: 600 })
|
||||
|
||||
@@ -25,14 +25,14 @@ we will use will be "`electron-fiddle://`".
|
||||
First, we will import the required modules from `electron`. These modules help
|
||||
control our application lifecycle and create a native browser window.
|
||||
|
||||
```javascript
|
||||
```js
|
||||
const { app, BrowserWindow, shell } = require('electron')
|
||||
const path = require('node:path')
|
||||
```
|
||||
|
||||
Next, we will proceed to register our application to handle all "`electron-fiddle://`" protocols.
|
||||
|
||||
```javascript
|
||||
```js
|
||||
if (process.defaultApp) {
|
||||
if (process.argv.length >= 2) {
|
||||
app.setAsDefaultProtocolClient('electron-fiddle', process.execPath, [path.resolve(process.argv[1])])
|
||||
@@ -44,7 +44,7 @@ if (process.defaultApp) {
|
||||
|
||||
We will now define the function in charge of creating our browser window and load our application's `index.html` file.
|
||||
|
||||
```javascript
|
||||
```js
|
||||
let mainWindow
|
||||
|
||||
const createWindow = () => {
|
||||
@@ -67,7 +67,7 @@ This code will be different in Windows and Linux compared to MacOS. This is due
|
||||
|
||||
#### Windows and Linux code:
|
||||
|
||||
```javascript @ts-type={mainWindow:Electron.BrowserWindow} @ts-type={createWindow:()=>void}
|
||||
```js @ts-type={mainWindow:Electron.BrowserWindow} @ts-type={createWindow:()=>void}
|
||||
const gotTheLock = app.requestSingleInstanceLock()
|
||||
|
||||
if (!gotTheLock) {
|
||||
@@ -92,7 +92,7 @@ if (!gotTheLock) {
|
||||
|
||||
#### MacOS code:
|
||||
|
||||
```javascript @ts-type={createWindow:()=>void}
|
||||
```js @ts-type={createWindow:()=>void}
|
||||
// This method will be called when Electron has finished
|
||||
// initialization and is ready to create browser windows.
|
||||
// Some APIs can only be used after this event occurs.
|
||||
@@ -108,7 +108,7 @@ app.on('open-url', (event, url) => {
|
||||
|
||||
Finally, we will add some additional code to handle when someone closes our application.
|
||||
|
||||
```javascript
|
||||
```js
|
||||
// Quit when all windows are closed, except on macOS. There, it's common
|
||||
// for applications and their menu bar to stay active until the user quits
|
||||
// explicitly with Cmd + Q.
|
||||
@@ -159,7 +159,7 @@ shows the bare minimum needed to add the configuration changes)_:
|
||||
}
|
||||
```
|
||||
|
||||
#### [Electron Packager](https://github.com/electron/electron-packager)
|
||||
#### [Electron Packager](https://github.com/electron/packager)
|
||||
|
||||
For macOS support:
|
||||
|
||||
@@ -167,8 +167,8 @@ If you're using Electron Packager's API, adding support for protocol handlers is
|
||||
Electron Forge is handled, except
|
||||
`protocols` is part of the Packager options passed to the `packager` function.
|
||||
|
||||
```javascript @ts-nocheck
|
||||
const packager = require('electron-packager')
|
||||
```js @ts-nocheck
|
||||
const packager = require('@electron/packager')
|
||||
|
||||
packager({
|
||||
// ...other options...
|
||||
|
||||
@@ -23,10 +23,10 @@ To set your custom dock menu, you need to use the
|
||||
[`app.dock.setMenu`](../api/dock.md#docksetmenumenu-macos) API,
|
||||
which is only available on macOS.
|
||||
|
||||
```javascript fiddle='docs/fiddles/features/macos-dock-menu'
|
||||
const { app, BrowserWindow, Menu } = require('electron')
|
||||
```fiddle docs/fiddles/features/macos-dock-menu
|
||||
const { app, BrowserWindow, Menu } = require('electron/main')
|
||||
|
||||
const createWindow = () => {
|
||||
function createWindow () {
|
||||
const win = new BrowserWindow({
|
||||
width: 800,
|
||||
height: 600
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user