mirror of
https://github.com/electron/electron.git
synced 2026-02-19 03:14:51 -05:00
Compare commits
274 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
717b5263d5 | ||
|
|
108e20a623 | ||
|
|
966a8623ab | ||
|
|
74ac9c2e13 | ||
|
|
776a6102e6 | ||
|
|
2ed8e63cfe | ||
|
|
90b6db93a2 | ||
|
|
48605866c4 | ||
|
|
38020822e1 | ||
|
|
04852b8efc | ||
|
|
19156d793b | ||
|
|
0af1751932 | ||
|
|
ecb162ccea | ||
|
|
8545815af3 | ||
|
|
e5f7f68b95 | ||
|
|
a4674b4bc4 | ||
|
|
1e77167863 | ||
|
|
d86d3aa565 | ||
|
|
ade351d562 | ||
|
|
0f35811af2 | ||
|
|
2b2f0c67aa | ||
|
|
cdf32f2567 | ||
|
|
99b1d18d3f | ||
|
|
03f74ae307 | ||
|
|
af85dc602f | ||
|
|
215324a035 | ||
|
|
bb031bf7a2 | ||
|
|
f5533950d6 | ||
|
|
698fc73c23 | ||
|
|
8cf127de07 | ||
|
|
a03607cacc | ||
|
|
7ea754dbed | ||
|
|
67dbb7b0ba | ||
|
|
66667d29e2 | ||
|
|
8ef702ab17 | ||
|
|
a0f594184d | ||
|
|
21f79de667 | ||
|
|
d124760879 | ||
|
|
e90fd172b6 | ||
|
|
37bcb55f15 | ||
|
|
c19f0073fd | ||
|
|
3db858c6a2 | ||
|
|
c9dba4862b | ||
|
|
6b7acbee4f | ||
|
|
d18cd4c8b9 | ||
|
|
4b6b82d9c5 | ||
|
|
f5811f1a3a | ||
|
|
e1a71b065d | ||
|
|
7202213ce0 | ||
|
|
0eb29dd13e | ||
|
|
35a559a988 | ||
|
|
36f3ae0803 | ||
|
|
be663f71db | ||
|
|
26da9c8b74 | ||
|
|
f9744a8865 | ||
|
|
dee9c62ed4 | ||
|
|
4887d50726 | ||
|
|
04991376d5 | ||
|
|
946d2cbd9f | ||
|
|
487c5c9352 | ||
|
|
758c8e6327 | ||
|
|
fb0b474368 | ||
|
|
21d45e613a | ||
|
|
f28dab8881 | ||
|
|
3b063d6bbb | ||
|
|
086d5563a1 | ||
|
|
b9cc819362 | ||
|
|
491e391cde | ||
|
|
6252a9f734 | ||
|
|
b91354b9e0 | ||
|
|
ce6af063a7 | ||
|
|
b5a7944d7c | ||
|
|
b660d2db3e | ||
|
|
834f27c12b | ||
|
|
932aef2db2 | ||
|
|
0ae60390da | ||
|
|
d6fe972744 | ||
|
|
c4116a22b9 | ||
|
|
2f25c10818 | ||
|
|
bc3b181575 | ||
|
|
ea778bea3a | ||
|
|
86658890fe | ||
|
|
ea1b8a32bb | ||
|
|
bbdd71dd54 | ||
|
|
0a6d4a9875 | ||
|
|
3159edeff6 | ||
|
|
6665d2be19 | ||
|
|
bf3ddcaeb8 | ||
|
|
2783fbf550 | ||
|
|
3cba3f4d7e | ||
|
|
418e0c174f | ||
|
|
c38a7c1a7a | ||
|
|
18e10fe1a9 | ||
|
|
5fa579c607 | ||
|
|
27045abeeb | ||
|
|
fb75073955 | ||
|
|
fce83c48f2 | ||
|
|
f790637e12 | ||
|
|
56c9e259a1 | ||
|
|
f1f0ed1ecd | ||
|
|
570db18ef2 | ||
|
|
43b9988c57 | ||
|
|
b740cd2202 | ||
|
|
592430f918 | ||
|
|
3445fbf7dc | ||
|
|
df5ff97144 | ||
|
|
3bb800ce04 | ||
|
|
413fbcfa18 | ||
|
|
8877087e51 | ||
|
|
275eecdfcb | ||
|
|
6ecf43c8c4 | ||
|
|
aec62a9874 | ||
|
|
291b4f9980 | ||
|
|
a841bd195c | ||
|
|
4a5a18f003 | ||
|
|
5c29d3b533 | ||
|
|
e0172c45f0 | ||
|
|
3fa9826b8b | ||
|
|
e262b5040a | ||
|
|
e5eafc8ee9 | ||
|
|
2bcf583bcf | ||
|
|
c50d0e49c1 | ||
|
|
26c5cc2801 | ||
|
|
fb5822af43 | ||
|
|
97626aeac8 | ||
|
|
b8d136aeea | ||
|
|
eed55d5923 | ||
|
|
ef4d98ac7f | ||
|
|
8ae9c5c7cf | ||
|
|
1631fc9b0c | ||
|
|
cc0848a86e | ||
|
|
c7a2b32c5a | ||
|
|
18cfdb1c82 | ||
|
|
1105931d0a | ||
|
|
234309497e | ||
|
|
6fa2ab2edd | ||
|
|
527c767107 | ||
|
|
15468432c8 | ||
|
|
af34655cb7 | ||
|
|
111b737ae4 | ||
|
|
e33df2c7b6 | ||
|
|
f30018b4b0 | ||
|
|
795200a838 | ||
|
|
64d4e5969f | ||
|
|
be670059a6 | ||
|
|
5d64c42801 | ||
|
|
5b81463423 | ||
|
|
92df786066 | ||
|
|
59aaa65381 | ||
|
|
715ffe4e51 | ||
|
|
51bb0ad36d | ||
|
|
4636dfe68e | ||
|
|
e3f6b2b082 | ||
|
|
968db9285f | ||
|
|
19f8ea37a5 | ||
|
|
99eb8ac059 | ||
|
|
3bcdc276e1 | ||
|
|
85dad8fb18 | ||
|
|
5f60640ddc | ||
|
|
f9e6e6eff9 | ||
|
|
7695f3f1ee | ||
|
|
3492077f33 | ||
|
|
0933c6796c | ||
|
|
137f45750f | ||
|
|
a0175137fb | ||
|
|
90eee5f909 | ||
|
|
a09dada8e4 | ||
|
|
805e442ff8 | ||
|
|
02a1b42db3 | ||
|
|
5c44dc2a0a | ||
|
|
210c406ab1 | ||
|
|
15a96413b6 | ||
|
|
13e017c861 | ||
|
|
bb1299bbb5 | ||
|
|
42d15f0536 | ||
|
|
70526f8070 | ||
|
|
47640eaa9a | ||
|
|
1f5a8b6894 | ||
|
|
b1f438245f | ||
|
|
a73d563390 | ||
|
|
6a1ef337a7 | ||
|
|
63677086c2 | ||
|
|
8805b996e0 | ||
|
|
47adc0a2b7 | ||
|
|
1559dc74da | ||
|
|
207dbb8d4e | ||
|
|
3bda527e83 | ||
|
|
e3b76f71de | ||
|
|
6be5244111 | ||
|
|
f398ba08a9 | ||
|
|
aa4f3550fd | ||
|
|
095de8114e | ||
|
|
5737bac6f4 | ||
|
|
c95eda8420 | ||
|
|
7fb97f041b | ||
|
|
b4ea9e0fc8 | ||
|
|
19b7336fc3 | ||
|
|
f809e74905 | ||
|
|
f6eb88ac08 | ||
|
|
56e926ce23 | ||
|
|
5e0e91510a | ||
|
|
9bfd5d4a4b | ||
|
|
8afd7877f6 | ||
|
|
bf0b82dc8e | ||
|
|
122d8910d5 | ||
|
|
cb281b7954 | ||
|
|
91cfa96c80 | ||
|
|
a21ed83751 | ||
|
|
c0b48658d8 | ||
|
|
c68f0f04d0 | ||
|
|
a2b61f9b97 | ||
|
|
fc478f4e96 | ||
|
|
b710412e7b | ||
|
|
9a7bda51a3 | ||
|
|
615e467a15 | ||
|
|
f8a900fdde | ||
|
|
c188ed065d | ||
|
|
dcd216984f | ||
|
|
e012f61aee | ||
|
|
50e3a2ae20 | ||
|
|
b4413e9398 | ||
|
|
25df0f5d31 | ||
|
|
6b91371b6e | ||
|
|
8e6d332e96 | ||
|
|
eebd7cfa05 | ||
|
|
a4d73be9c5 | ||
|
|
0e9214a82b | ||
|
|
24c7365bef | ||
|
|
686aefb2cd | ||
|
|
0e0a1421fd | ||
|
|
c4e8c0fd0e | ||
|
|
101a2282ab | ||
|
|
429400040e | ||
|
|
ca7528a2d0 | ||
|
|
d58812b517 | ||
|
|
5942c84288 | ||
|
|
f920463b47 | ||
|
|
296cba563e | ||
|
|
90a96c0b73 | ||
|
|
2c325cd654 | ||
|
|
c26b78bbc0 | ||
|
|
6951c09b61 | ||
|
|
fe21892974 | ||
|
|
0fd6a8ca83 | ||
|
|
de12232df5 | ||
|
|
d12674f9f1 | ||
|
|
75cdd02697 | ||
|
|
08b7f5a569 | ||
|
|
a5077e2586 | ||
|
|
4fa9122151 | ||
|
|
56fa037a46 | ||
|
|
13a9e15a27 | ||
|
|
badc01c2d8 | ||
|
|
b0862a6e63 | ||
|
|
18cde2ef04 | ||
|
|
e6c94854a0 | ||
|
|
94d8b7d4c1 | ||
|
|
c0769d77e5 | ||
|
|
2a6c3bb7d1 | ||
|
|
d892fde98b | ||
|
|
edb6723157 | ||
|
|
9dda9a894a | ||
|
|
90ab868b50 | ||
|
|
4dc98f1347 | ||
|
|
2189ddb14e | ||
|
|
680569e404 | ||
|
|
e119699ae2 | ||
|
|
63e6f08768 | ||
|
|
b14c57e30c | ||
|
|
8a68a304e0 | ||
|
|
60cef385d5 | ||
|
|
4f281e3d31 | ||
|
|
eb2710e483 | ||
|
|
7a15dca09c |
@@ -158,10 +158,6 @@ env-mas-apple-silicon: &env-mas-apple-silicon
|
||||
TARGET_ARCH: arm64
|
||||
USE_PREBUILT_V8_CONTEXT_SNAPSHOT: 1
|
||||
|
||||
# Misc build configuration options.
|
||||
env-enable-sccache: &env-enable-sccache
|
||||
USE_SCCACHE: true
|
||||
|
||||
env-send-slack-notifications: &env-send-slack-notifications
|
||||
NOTIFY_SLACK: true
|
||||
|
||||
@@ -265,7 +261,7 @@ step-gclient-sync: &step-gclient-sync
|
||||
if ! git diff-index --quiet HEAD --; then
|
||||
# There are changes to the patches. Make a git commit with the updated patches
|
||||
git add patches
|
||||
GIT_COMMITTER_NAME="Electron Bot" GIT_COMMITTER_EMAIL="electron@github.com" git commit -m "update patches" --author="Electron Bot <electron@github.com>"
|
||||
GIT_COMMITTER_NAME="PatchUp" GIT_COMMITTER_EMAIL="73610968+patchup[bot]@users.noreply.github.com" git commit -m "chore: update patches" --author="PatchUp <73610968+patchup[bot]@users.noreply.github.com>"
|
||||
# Export it
|
||||
mkdir -p ../../patches
|
||||
git format-patch -1 --stdout --keep-subject --no-stat --full-index > ../../patches/update-patches.patch
|
||||
@@ -295,26 +291,14 @@ step-setup-env-for-build: &step-setup-env-for-build
|
||||
# To find `gn` executable.
|
||||
echo 'export CHROMIUM_BUILDTOOLS_PATH="'"$PWD"'/src/buildtools"' >> $BASH_ENV
|
||||
|
||||
if [ "$USE_SCCACHE" == "true" ]; then
|
||||
# https://github.com/mozilla/sccache
|
||||
SCCACHE_PATH="$PWD/src/electron/external_binaries/sccache"
|
||||
echo 'export SCCACHE_PATH="'"$SCCACHE_PATH"'"' >> $BASH_ENV
|
||||
if [ "$CIRCLE_PR_NUMBER" != "" ]; then
|
||||
#if building a fork set readonly access to sccache
|
||||
echo 'export SCCACHE_BUCKET="electronjs-sccache-ci"' >> $BASH_ENV
|
||||
echo 'export SCCACHE_TWO_TIER=true' >> $BASH_ENV
|
||||
fi
|
||||
fi
|
||||
|
||||
step-setup-goma-for-build: &step-setup-goma-for-build
|
||||
run:
|
||||
name: Setup Goma
|
||||
command: |
|
||||
echo 'export USE_GOMA=true' >> $BASH_ENV
|
||||
if [ "`uname`" == "Linux" ]; then
|
||||
echo 'export NUMBER_OF_NINJA_PROCESSES=300' >> $BASH_ENV
|
||||
else
|
||||
echo 'export NUMBER_OF_NINJA_PROCESSES=25' >> $BASH_ENV
|
||||
echo 'export NUMBER_OF_NINJA_PROCESSES=300' >> $BASH_ENV
|
||||
if [ "`uname`" == "Darwin" ]; then
|
||||
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
|
||||
@@ -323,24 +307,27 @@ step-setup-goma-for-build: &step-setup-goma-for-build
|
||||
cd build-tools
|
||||
npm install
|
||||
mkdir third_party
|
||||
node -e "require('./src/utils/goma.js').downloadAndPrepare()"
|
||||
node -e "require('./src/utils/goma.js').ensure()"
|
||||
node -e "require('./src/utils/goma.js').downloadAndPrepare({ gomaOneForAll: true })"
|
||||
third_party/goma/goma_ctl.py ensure_start
|
||||
echo 'export GN_GOMA_FILE='`node -e "console.log(require('./src/utils/goma.js').gnFilePath)"` >> $BASH_ENV
|
||||
echo 'export LOCAL_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 ..
|
||||
|
||||
step-restore-brew-cache: &step-restore-brew-cache
|
||||
restore_cache:
|
||||
paths:
|
||||
- /usr/local/Homebrew
|
||||
- /usr/local/Cellar/gnu-tar
|
||||
- /usr/local/bin/gtar
|
||||
keys:
|
||||
- v1-brew-cache-{{ arch }}
|
||||
- v4-brew-cache-{{ arch }}
|
||||
|
||||
step-save-brew-cache: &step-save-brew-cache
|
||||
save_cache:
|
||||
paths:
|
||||
- /usr/local/Homebrew
|
||||
key: v1-brew-cache-{{ arch }}
|
||||
- /usr/local/Cellar/gnu-tar
|
||||
- /usr/local/bin/gtar
|
||||
key: v4-brew-cache-{{ arch }}
|
||||
name: Persisting brew cache
|
||||
|
||||
step-get-more-space-on-mac: &step-get-more-space-on-mac
|
||||
@@ -480,8 +467,10 @@ step-install-gnutar-on-mac: &step-install-gnutar-on-mac
|
||||
name: Install gnu-tar on macos
|
||||
command: |
|
||||
if [ "`uname`" == "Darwin" ]; then
|
||||
brew update
|
||||
brew install gnu-tar
|
||||
if [ ! -d /usr/local/Cellar/gnu-tar/ ]; then
|
||||
brew update
|
||||
brew install gnu-tar
|
||||
fi
|
||||
ln -fs /usr/local/bin/gtar /usr/local/bin/tar
|
||||
fi
|
||||
|
||||
@@ -490,11 +479,7 @@ step-gn-gen-default: &step-gn-gen-default
|
||||
name: Default GN gen
|
||||
command: |
|
||||
cd src
|
||||
if [ "$USE_GOMA" == "true" ]; then
|
||||
gn gen out/Default --args="import(\"$GN_CONFIG\") import(\"$GN_GOMA_FILE\") $GN_EXTRA_ARGS $GN_BUILDFLAG_ARGS"
|
||||
else
|
||||
gn gen out/Default --args="import(\"$GN_CONFIG\") cc_wrapper=\"$SCCACHE_PATH\" $GN_EXTRA_ARGS $GN_BUILDFLAG_ARGS"
|
||||
fi
|
||||
gn gen out/Default --args="import(\"$GN_CONFIG\") import(\"$GN_GOMA_FILE\") $GN_EXTRA_ARGS $GN_BUILDFLAG_ARGS"
|
||||
|
||||
step-gn-check: &step-gn-check
|
||||
run:
|
||||
@@ -534,12 +519,8 @@ step-electron-build: &step-electron-build
|
||||
gn desc out/Default v8:run_mksnapshot_default args > out/Default/mksnapshot_args
|
||||
rm -rf out/Default/clang_x64_v8_arm64/obj
|
||||
|
||||
# Regenerate because we just deleted some ninja files
|
||||
if [ "$USE_GOMA" == "true" ]; then
|
||||
gn gen out/Default --args="import(\"$GN_CONFIG\") import(\"$GN_GOMA_FILE\") $GN_EXTRA_ARGS $GN_BUILDFLAG_ARGS"
|
||||
else
|
||||
gn gen out/Default --args="import(\"$GN_CONFIG\") cc_wrapper=\"$SCCACHE_PATH\" $GN_EXTRA_ARGS $GN_BUILDFLAG_ARGS"
|
||||
fi
|
||||
# Regenerate because we just deleted some ninja files
|
||||
gn gen out/Default --args="import(\"$GN_CONFIG\") import(\"$GN_GOMA_FILE\") $GN_EXTRA_ARGS $GN_BUILDFLAG_ARGS"
|
||||
fi
|
||||
ninja -C out/Default electron -j $NUMBER_OF_NINJA_PROCESSES
|
||||
node electron/script/check-symlinks.js
|
||||
@@ -615,11 +596,7 @@ step-electron-maybe-chromedriver-gn-gen: &step-electron-maybe-chromedriver-gn-ge
|
||||
command: |
|
||||
cd src
|
||||
if [ "$TARGET_ARCH" == "arm" ] || [ "$TARGET_ARCH" == "arm64" ]; then
|
||||
if [ "$USE_GOMA" == "true" ]; 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"
|
||||
else
|
||||
gn gen out/chromedriver --args="import(\"$GN_CONFIG\") cc_wrapper=\"$SCCACHE_PATH\" is_component_ffmpeg=false proprietary_codecs=false $GN_EXTRA_ARGS $GN_BUILDFLAG_ARGS"
|
||||
fi
|
||||
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"
|
||||
fi
|
||||
|
||||
step-electron-chromedriver-build: &step-electron-chromedriver-build
|
||||
@@ -730,11 +707,7 @@ step-ffmpeg-gn-gen: &step-ffmpeg-gn-gen
|
||||
name: ffmpeg GN gen
|
||||
command: |
|
||||
cd src
|
||||
if [ "$USE_GOMA" == "true" ]; then
|
||||
gn gen out/ffmpeg --args="import(\"//electron/build/args/ffmpeg.gn\") import(\"$GN_GOMA_FILE\") $GN_EXTRA_ARGS"
|
||||
else
|
||||
gn gen out/ffmpeg --args="import(\"//electron/build/args/ffmpeg.gn\") cc_wrapper=\"$SCCACHE_PATH\" $GN_EXTRA_ARGS"
|
||||
fi
|
||||
gn gen out/ffmpeg --args="import(\"//electron/build/args/ffmpeg.gn\") import(\"$GN_GOMA_FILE\") $GN_EXTRA_ARGS"
|
||||
|
||||
step-ffmpeg-build: &step-ffmpeg-build
|
||||
run:
|
||||
@@ -777,21 +750,16 @@ step-setup-linux-for-headless-testing: &step-setup-linux-for-headless-testing
|
||||
sh -e /etc/init.d/xvfb start
|
||||
fi
|
||||
|
||||
step-show-sccache-stats: &step-show-sccache-stats
|
||||
step-show-goma-stats: &step-show-goma-stats
|
||||
run:
|
||||
shell: /bin/bash
|
||||
name: Check sccache/goma stats after build
|
||||
command: |
|
||||
if [ "$SCCACHE_PATH" != "" ]; then
|
||||
$SCCACHE_PATH -s
|
||||
fi
|
||||
if [ "$USE_GOMA" == "true" ]; then
|
||||
set +e
|
||||
set +o pipefail
|
||||
$LOCAL_GOMA_DIR/goma_ctl.py stat
|
||||
$LOCAL_GOMA_DIR/diagnose_goma_log.py
|
||||
true
|
||||
fi
|
||||
name: Check goma stats after build
|
||||
command: |
|
||||
set +e
|
||||
set +o pipefail
|
||||
$LOCAL_GOMA_DIR/goma_ctl.py stat
|
||||
$LOCAL_GOMA_DIR/diagnose_goma_log.py
|
||||
true
|
||||
when: always
|
||||
|
||||
step-mksnapshot-build: &step-mksnapshot-build
|
||||
@@ -930,6 +898,8 @@ step-ninja-summary: &step-ninja-summary
|
||||
run:
|
||||
name: Print ninja summary
|
||||
command: |
|
||||
set +e
|
||||
set +o pipefail
|
||||
python depot_tools/post_build_ninja_summary.py -C src/out/Default
|
||||
|
||||
step-ninja-report: &step-ninja-report
|
||||
@@ -1156,7 +1126,6 @@ steps-checkout-and-save-cache: &steps-checkout-and-save-cache
|
||||
- *step-maybe-early-exit-doc-only-change
|
||||
- *step-depot-tools-get
|
||||
- *step-depot-tools-add-to-path
|
||||
- *step-restore-brew-cache
|
||||
- *step-get-more-space-on-mac
|
||||
- *step-install-gnutar-on-mac
|
||||
|
||||
@@ -1198,6 +1167,7 @@ steps-electron-gn-check: &steps-electron-gn-check
|
||||
- *step-maybe-early-exit-doc-only-change
|
||||
- *step-depot-tools-add-to-path
|
||||
- *step-setup-env-for-build
|
||||
- *step-setup-goma-for-build
|
||||
- *step-gn-gen-default
|
||||
- *step-gn-check
|
||||
|
||||
@@ -1231,6 +1201,7 @@ steps-electron-ts-compile-for-doc-change: &steps-electron-ts-compile-for-doc-cha
|
||||
|
||||
- *step-depot-tools-add-to-path
|
||||
- *step-setup-env-for-build
|
||||
- *step-setup-goma-for-build
|
||||
- *step-restore-brew-cache
|
||||
- *step-get-more-space-on-mac
|
||||
- *step-install-npm-deps-on-mac
|
||||
@@ -1240,26 +1211,13 @@ steps-electron-ts-compile-for-doc-change: &steps-electron-ts-compile-for-doc-cha
|
||||
#Compile ts/js to verify doc change didn't break anything
|
||||
- *step-ts-compile
|
||||
|
||||
steps-chromedriver-build: &steps-chromedriver-build
|
||||
steps:
|
||||
- attach_workspace:
|
||||
at: .
|
||||
- *step-depot-tools-add-to-path
|
||||
- *step-setup-env-for-build
|
||||
- *step-fix-sync-on-mac
|
||||
|
||||
- *step-electron-maybe-chromedriver-gn-gen
|
||||
- *step-electron-chromedriver-build
|
||||
- *step-electron-chromedriver-store
|
||||
|
||||
- *step-maybe-notify-slack-failure
|
||||
|
||||
steps-native-tests: &steps-native-tests
|
||||
steps:
|
||||
- attach_workspace:
|
||||
at: .
|
||||
- *step-depot-tools-add-to-path
|
||||
- *step-setup-env-for-build
|
||||
- *step-setup-goma-for-build
|
||||
- *step-gn-gen-default
|
||||
|
||||
- run:
|
||||
@@ -1267,7 +1225,7 @@ steps-native-tests: &steps-native-tests
|
||||
command: |
|
||||
cd src
|
||||
ninja -C out/Default $BUILD_TARGET
|
||||
- *step-show-sccache-stats
|
||||
- *step-show-goma-stats
|
||||
|
||||
- *step-setup-linux-for-headless-testing
|
||||
- run:
|
||||
@@ -1575,7 +1533,7 @@ commands:
|
||||
- *step-nodejs-headers-build
|
||||
- *step-nodejs-headers-store
|
||||
|
||||
- *step-show-sccache-stats
|
||||
- *step-show-goma-stats
|
||||
|
||||
# mksnapshot
|
||||
- *step-mksnapshot-build
|
||||
@@ -1663,13 +1621,14 @@ commands:
|
||||
- *step-gclient-sync
|
||||
- *step-delete-git-directories
|
||||
- *step-minimize-workspace-size-from-checkout
|
||||
- *step-fix-sync-on-mac
|
||||
- *step-fix-sync-on-mac
|
||||
- *step-setup-env-for-build
|
||||
- *step-setup-goma-for-build
|
||||
- *step-gn-gen-default
|
||||
|
||||
# Electron app
|
||||
- *step-electron-build
|
||||
- *step-show-sccache-stats
|
||||
- *step-show-goma-stats
|
||||
- *step-maybe-generate-breakpad-symbols
|
||||
- *step-maybe-electron-dist-strip
|
||||
- *step-electron-dist-build
|
||||
@@ -1853,14 +1812,6 @@ jobs:
|
||||
<<: *env-testing-build
|
||||
<<: *steps-electron-gn-check
|
||||
|
||||
linux-x64-chromedriver:
|
||||
<<: *machine-linux-medium
|
||||
environment:
|
||||
<<: *env-linux-medium
|
||||
<<: *env-release-build
|
||||
<<: *env-send-slack-notifications
|
||||
<<: *steps-chromedriver-build
|
||||
|
||||
linux-x64-release:
|
||||
<<: *machine-linux-2xlarge
|
||||
environment:
|
||||
@@ -1880,8 +1831,8 @@ jobs:
|
||||
<<: *env-linux-2xlarge-release
|
||||
GCLIENT_EXTRA_ARGS: '--custom-var=checkout_boto=True --custom-var=checkout_requests=True'
|
||||
<<: *env-release-build
|
||||
<<: *env-enable-sccache
|
||||
UPLOAD_TO_S3: << pipeline.parameters.upload-to-s3 >>
|
||||
<<: *env-ninja-status
|
||||
steps:
|
||||
- electron-publish:
|
||||
attach: false
|
||||
@@ -1892,8 +1843,8 @@ jobs:
|
||||
environment:
|
||||
<<: *env-linux-2xlarge-release
|
||||
<<: *env-release-build
|
||||
<<: *env-enable-sccache
|
||||
UPLOAD_TO_S3: << pipeline.parameters.upload-to-s3 >>
|
||||
<<: *env-ninja-status
|
||||
steps:
|
||||
- electron-publish:
|
||||
attach: true
|
||||
@@ -1913,15 +1864,6 @@ jobs:
|
||||
checkout: true
|
||||
use-out-cache: false
|
||||
|
||||
linux-ia32-chromedriver:
|
||||
<<: *machine-linux-medium
|
||||
environment:
|
||||
<<: *env-linux-medium
|
||||
<<: *env-ia32
|
||||
<<: *env-release-build
|
||||
<<: *env-send-slack-notifications
|
||||
<<: *steps-chromedriver-build
|
||||
|
||||
linux-ia32-release:
|
||||
<<: *machine-linux-2xlarge
|
||||
environment:
|
||||
@@ -1943,9 +1885,9 @@ jobs:
|
||||
GCLIENT_EXTRA_ARGS: '--custom-var=checkout_boto=True --custom-var=checkout_requests=True'
|
||||
<<: *env-ia32
|
||||
<<: *env-release-build
|
||||
<<: *env-enable-sccache
|
||||
<<: *env-32bit-release
|
||||
UPLOAD_TO_S3: << pipeline.parameters.upload-to-s3 >>
|
||||
<<: *env-ninja-status
|
||||
steps:
|
||||
- electron-publish:
|
||||
attach: false
|
||||
@@ -1957,9 +1899,9 @@ jobs:
|
||||
<<: *env-linux-2xlarge-release
|
||||
<<: *env-ia32
|
||||
<<: *env-release-build
|
||||
<<: *env-enable-sccache
|
||||
<<: *env-32bit-release
|
||||
UPLOAD_TO_S3: << pipeline.parameters.upload-to-s3 >>
|
||||
<<: *env-ninja-status
|
||||
steps:
|
||||
- electron-publish:
|
||||
attach: true
|
||||
@@ -1980,15 +1922,6 @@ jobs:
|
||||
checkout: true
|
||||
use-out-cache: false
|
||||
|
||||
linux-arm-chromedriver:
|
||||
<<: *machine-linux-medium
|
||||
environment:
|
||||
<<: *env-linux-medium
|
||||
<<: *env-arm
|
||||
<<: *env-release-build
|
||||
<<: *env-send-slack-notifications
|
||||
<<: *steps-chromedriver-build
|
||||
|
||||
linux-arm-release:
|
||||
<<: *machine-linux-2xlarge
|
||||
environment:
|
||||
@@ -2009,10 +1942,10 @@ jobs:
|
||||
<<: *env-linux-2xlarge-release
|
||||
<<: *env-arm
|
||||
<<: *env-release-build
|
||||
<<: *env-enable-sccache
|
||||
<<: *env-32bit-release
|
||||
GCLIENT_EXTRA_ARGS: '--custom-var=checkout_arm=True --custom-var=checkout_boto=True --custom-var=checkout_requests=True'
|
||||
UPLOAD_TO_S3: << pipeline.parameters.upload-to-s3 >>
|
||||
<<: *env-ninja-status
|
||||
steps:
|
||||
- electron-publish:
|
||||
attach: false
|
||||
@@ -2024,9 +1957,9 @@ jobs:
|
||||
<<: *env-linux-2xlarge-release
|
||||
<<: *env-arm
|
||||
<<: *env-release-build
|
||||
<<: *env-enable-sccache
|
||||
<<: *env-32bit-release
|
||||
UPLOAD_TO_S3: << pipeline.parameters.upload-to-s3 >>
|
||||
<<: *env-ninja-status
|
||||
steps:
|
||||
- electron-publish:
|
||||
attach: true
|
||||
@@ -2055,15 +1988,6 @@ jobs:
|
||||
<<: *env-testing-build
|
||||
<<: *steps-electron-gn-check
|
||||
|
||||
linux-arm64-chromedriver:
|
||||
<<: *machine-linux-medium
|
||||
environment:
|
||||
<<: *env-linux-medium
|
||||
<<: *env-arm64
|
||||
<<: *env-release-build
|
||||
<<: *env-send-slack-notifications
|
||||
<<: *steps-chromedriver-build
|
||||
|
||||
linux-arm64-release:
|
||||
<<: *machine-linux-2xlarge
|
||||
environment:
|
||||
@@ -2084,9 +2008,9 @@ jobs:
|
||||
<<: *env-linux-2xlarge-release
|
||||
<<: *env-arm64
|
||||
<<: *env-release-build
|
||||
<<: *env-enable-sccache
|
||||
GCLIENT_EXTRA_ARGS: '--custom-var=checkout_arm64=True --custom-var=checkout_boto=True --custom-var=checkout_requests=True'
|
||||
UPLOAD_TO_S3: << pipeline.parameters.upload-to-s3 >>
|
||||
<<: *env-ninja-status
|
||||
steps:
|
||||
- electron-publish:
|
||||
attach: false
|
||||
@@ -2098,8 +2022,8 @@ jobs:
|
||||
<<: *env-linux-2xlarge-release
|
||||
<<: *env-arm64
|
||||
<<: *env-release-build
|
||||
<<: *env-enable-sccache
|
||||
UPLOAD_TO_S3: << pipeline.parameters.upload-to-s3 >>
|
||||
<<: *env-ninja-status
|
||||
steps:
|
||||
- electron-publish:
|
||||
attach: true
|
||||
@@ -2146,9 +2070,9 @@ jobs:
|
||||
environment:
|
||||
<<: *env-mac-large-release
|
||||
<<: *env-release-build
|
||||
<<: *env-enable-sccache
|
||||
GCLIENT_EXTRA_ARGS: '--custom-var=checkout_boto=True --custom-var=checkout_requests=True'
|
||||
UPLOAD_TO_S3: << pipeline.parameters.upload-to-s3 >>
|
||||
<<: *env-ninja-status
|
||||
steps:
|
||||
- electron-publish:
|
||||
attach: false
|
||||
@@ -2159,10 +2083,10 @@ jobs:
|
||||
environment:
|
||||
<<: *env-mac-large-release
|
||||
<<: *env-release-build
|
||||
<<: *env-enable-sccache
|
||||
<<: *env-apple-silicon
|
||||
GCLIENT_EXTRA_ARGS: '--custom-var=checkout_boto=True --custom-var=checkout_requests=True'
|
||||
UPLOAD_TO_S3: << pipeline.parameters.upload-to-s3 >>
|
||||
<<: *env-ninja-status
|
||||
steps:
|
||||
- electron-publish:
|
||||
attach: false
|
||||
@@ -2173,8 +2097,8 @@ jobs:
|
||||
environment:
|
||||
<<: *env-mac-large-release
|
||||
<<: *env-release-build
|
||||
<<: *env-enable-sccache
|
||||
UPLOAD_TO_S3: << pipeline.parameters.upload-to-s3 >>
|
||||
<<: *env-ninja-status
|
||||
steps:
|
||||
- electron-publish:
|
||||
attach: true
|
||||
@@ -2185,9 +2109,9 @@ jobs:
|
||||
environment:
|
||||
<<: *env-mac-large-release
|
||||
<<: *env-release-build
|
||||
<<: *env-enable-sccache
|
||||
<<: *env-apple-silicon
|
||||
UPLOAD_TO_S3: << pipeline.parameters.upload-to-s3 >>
|
||||
<<: *env-ninja-status
|
||||
steps:
|
||||
- electron-publish:
|
||||
attach: true
|
||||
@@ -2254,9 +2178,9 @@ jobs:
|
||||
<<: *env-mac-large-release
|
||||
<<: *env-mas
|
||||
<<: *env-release-build
|
||||
<<: *env-enable-sccache
|
||||
GCLIENT_EXTRA_ARGS: '--custom-var=checkout_boto=True --custom-var=checkout_requests=True'
|
||||
UPLOAD_TO_S3: << pipeline.parameters.upload-to-s3 >>
|
||||
<<: *env-ninja-status
|
||||
steps:
|
||||
- electron-publish:
|
||||
attach: false
|
||||
@@ -2268,9 +2192,9 @@ jobs:
|
||||
<<: *env-mac-large-release
|
||||
<<: *env-mas-apple-silicon
|
||||
<<: *env-release-build
|
||||
<<: *env-enable-sccache
|
||||
GCLIENT_EXTRA_ARGS: '--custom-var=checkout_boto=True --custom-var=checkout_requests=True'
|
||||
UPLOAD_TO_S3: << pipeline.parameters.upload-to-s3 >>
|
||||
<<: *env-ninja-status
|
||||
steps:
|
||||
- electron-publish:
|
||||
attach: false
|
||||
@@ -2282,7 +2206,6 @@ jobs:
|
||||
<<: *env-mac-large-release
|
||||
<<: *env-mas
|
||||
<<: *env-release-build
|
||||
<<: *env-enable-sccache
|
||||
UPLOAD_TO_S3: << pipeline.parameters.upload-to-s3 >>
|
||||
steps:
|
||||
- electron-publish:
|
||||
@@ -2295,8 +2218,8 @@ jobs:
|
||||
<<: *env-mac-large-release
|
||||
<<: *env-mas-apple-silicon
|
||||
<<: *env-release-build
|
||||
<<: *env-enable-sccache
|
||||
UPLOAD_TO_S3: << pipeline.parameters.upload-to-s3 >>
|
||||
<<: *env-ninja-status
|
||||
steps:
|
||||
- electron-publish:
|
||||
attach: true
|
||||
@@ -2621,15 +2544,19 @@ workflows:
|
||||
- osx-publish-x64-skip-checkout:
|
||||
requires:
|
||||
- mac-checkout
|
||||
context: release-env
|
||||
- mas-publish-x64-skip-checkout:
|
||||
requires:
|
||||
- mac-checkout
|
||||
context: release-env
|
||||
- osx-publish-arm64-skip-checkout:
|
||||
requires:
|
||||
- mac-checkout
|
||||
context: release-env
|
||||
- mas-publish-arm64-skip-checkout:
|
||||
requires:
|
||||
- mac-checkout
|
||||
context: release-env
|
||||
|
||||
lint:
|
||||
when: << pipeline.parameters.run-lint >>
|
||||
|
||||
@@ -4,4 +4,3 @@
|
||||
APPVEYOR_CLOUD_TOKEN=
|
||||
CIRCLE_TOKEN=
|
||||
ELECTRON_GITHUB_TOKEN=
|
||||
VSTS_TOKEN=
|
||||
13
BUILD.gn
13
BUILD.gn
@@ -1155,6 +1155,19 @@ if (is_mac) {
|
||||
ldflags += [ "/guard:cf,nolongjmp" ]
|
||||
}
|
||||
|
||||
if (current_cpu == "x86") {
|
||||
# Set the initial stack size to 0.5MiB, instead of the 1.5MiB needed by
|
||||
# Chrome's main thread. This saves significant memory on threads (like
|
||||
# those in the Windows thread pool, and others) whose stack size we can
|
||||
# only control through this setting. Because Chrome's main thread needs
|
||||
# a minimum 1.5 MiB stack, the main thread (in 32-bit builds only) uses
|
||||
# fibers to switch to a 1.5 MiB stack before running any other code.
|
||||
ldflags += [ "/STACK:0x80000" ]
|
||||
} else {
|
||||
# Increase the initial stack size. The default is 1MB, this is 8MB.
|
||||
ldflags += [ "/STACK:0x800000" ]
|
||||
}
|
||||
|
||||
# This is to support renaming of electron.exe. node-gyp has hard-coded
|
||||
# executable names which it will recognise as node. This module definition
|
||||
# file claims that the electron executable is in fact named "node.exe",
|
||||
|
||||
2
DEPS
2
DEPS
@@ -14,7 +14,7 @@ gclient_gn_args = [
|
||||
|
||||
vars = {
|
||||
'chromium_version':
|
||||
'87.0.4280.60',
|
||||
'87.0.4280.141',
|
||||
'node_version':
|
||||
'v12.18.3',
|
||||
'nan_version':
|
||||
|
||||
@@ -1 +1 @@
|
||||
11.0.0
|
||||
11.4.7
|
||||
11
README.md
11
README.md
@@ -5,7 +5,7 @@
|
||||
[](https://ci.appveyor.com/project/electron-bot/electron-ljo26/branch/master)
|
||||
[](https://david-dm.org/electron/electron?type=dev)
|
||||
|
||||
:memo: Available Translations: 🇨🇳 🇹🇼 🇧🇷 🇪🇸 🇰🇷 🇯🇵 🇷🇺 🇫🇷 🇹🇭 🇳🇱 🇹🇷 🇮🇩 🇺🇦 🇨🇿 🇮🇹 🇵🇱.
|
||||
:memo: Available Translations: 🇨🇳 🇧🇷 🇪🇸 🇯🇵 🇷🇺 🇫🇷 🇺🇸 🇩🇪.
|
||||
View these docs in other languages at [electron/i18n](https://github.com/electron/i18n/tree/master/content/).
|
||||
|
||||
The Electron framework lets you write cross-platform desktop applications
|
||||
@@ -28,15 +28,12 @@ The preferred method is to install Electron as a development dependency in your
|
||||
app:
|
||||
|
||||
```sh
|
||||
npm install electron --save-dev [--save-exact]
|
||||
npm install electron --save-dev
|
||||
```
|
||||
|
||||
The `--save-exact` flag is recommended for Electron prior to version 2, as it does not follow semantic
|
||||
versioning. As of version 2.0.0, Electron follows semver, so you don't need `--save-exact` flag. For info on how to manage Electron versions in your apps, see
|
||||
[Electron versioning](docs/tutorial/electron-versioning.md).
|
||||
|
||||
For more installation options and troubleshooting tips, see
|
||||
[installation](docs/tutorial/installation.md).
|
||||
[installation](docs/tutorial/installation.md). For info on how to manage Electron versions in your apps, see
|
||||
[Electron versioning](docs/tutorial/electron-versioning.md).
|
||||
|
||||
## Quick start & Electron Fiddle
|
||||
|
||||
|
||||
@@ -36,6 +36,7 @@ environment:
|
||||
ELECTRON_ENABLE_STACK_DUMPING: 1
|
||||
MOCHA_REPORTER: mocha-multi-reporters
|
||||
MOCHA_MULTI_REPORTERS: mocha-appveyor-reporter, tap
|
||||
GOMA_FALLBACK_ON_AUTH_FAILURE: true
|
||||
notifications:
|
||||
- provider: Webhook
|
||||
url: https://electron-mission-control.herokuapp.com/rest/appveyor-hook
|
||||
@@ -143,7 +144,7 @@ build_script:
|
||||
cd build-tools
|
||||
npm install
|
||||
mkdir third_party
|
||||
node -e "require('./src/utils/goma.js').downloadAndPrepare()"
|
||||
node -e "require('./src/utils/goma.js').downloadAndPrepare({ gomaOneForAll: true })"
|
||||
$env:GN_GOMA_FILE = node -e "console.log(require('./src/utils/goma.js').gnFilePath)"
|
||||
$env:LOCAL_GOMA_DIR = node -e "console.log(require('./src/utils/goma.js').dir)"
|
||||
cd ..
|
||||
|
||||
@@ -93,6 +93,6 @@ steps:
|
||||
condition: always()
|
||||
|
||||
- powershell: |
|
||||
Remove-Item -path $env:APPDATA/Electron* -Recurse
|
||||
Remove-Item -path $env:APPDATA/Electron* -Recurse -Force -ErrorAction Ignore
|
||||
displayName: 'Delete user app data directories'
|
||||
condition: always()
|
||||
|
||||
@@ -134,10 +134,17 @@ static_library("chrome") {
|
||||
"//chrome/browser/platform_util.h",
|
||||
"//chrome/browser/ui/browser_dialogs.h",
|
||||
"//chrome/browser/ui/color_chooser.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",
|
||||
]
|
||||
|
||||
if (use_aura) {
|
||||
sources += [ "//chrome/browser/platform_util_aura.cc" ]
|
||||
sources += [
|
||||
"//chrome/browser/platform_util_aura.cc",
|
||||
"//chrome/browser/ui/views/eye_dropper/eye_dropper_view_aura.cc",
|
||||
]
|
||||
|
||||
if (!is_win) {
|
||||
sources += [
|
||||
@@ -154,6 +161,8 @@ static_library("chrome") {
|
||||
"//chrome/browser/media/webrtc/window_icon_util_mac.mm",
|
||||
"//chrome/browser/ui/cocoa/color_chooser_mac.h",
|
||||
"//chrome/browser/ui/cocoa/color_chooser_mac.mm",
|
||||
"//chrome/browser/ui/views/eye_dropper/eye_dropper_view_mac.h",
|
||||
"//chrome/browser/ui/views/eye_dropper/eye_dropper_view_mac.mm",
|
||||
]
|
||||
deps += [
|
||||
"//components/remote_cocoa/app_shim",
|
||||
@@ -277,13 +286,15 @@ static_library("chrome") {
|
||||
}
|
||||
}
|
||||
|
||||
sources += [ "//chrome/browser/hang_monitor/hang_crash_dump.h" ]
|
||||
if (is_mac) {
|
||||
sources += [ "//chrome/browser/hang_monitor/hang_crash_dump_mac.cc" ]
|
||||
} else if (is_win) {
|
||||
sources += [ "//chrome/browser/hang_monitor/hang_crash_dump_win.cc" ]
|
||||
} else {
|
||||
sources += [ "//chrome/browser/hang_monitor/hang_crash_dump.cc" ]
|
||||
if (!is_mas_build) {
|
||||
sources += [ "//chrome/browser/hang_monitor/hang_crash_dump.h" ]
|
||||
if (is_mac) {
|
||||
sources += [ "//chrome/browser/hang_monitor/hang_crash_dump_mac.cc" ]
|
||||
} else if (is_win) {
|
||||
sources += [ "//chrome/browser/hang_monitor/hang_crash_dump_win.cc" ]
|
||||
} else {
|
||||
sources += [ "//chrome/browser/hang_monitor/hang_crash_dump.cc" ]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -41,14 +41,14 @@ ipcMain.handle('bootstrap', (event) => {
|
||||
return isTrustedSender(event.sender) ? electronPath : null;
|
||||
});
|
||||
|
||||
async function createWindow () {
|
||||
async function createWindow (backgroundColor?: string) {
|
||||
await app.whenReady();
|
||||
|
||||
const options: Electron.BrowserWindowConstructorOptions = {
|
||||
width: 960,
|
||||
height: 620,
|
||||
autoHideMenuBar: true,
|
||||
backgroundColor: '#2f3241',
|
||||
backgroundColor,
|
||||
webPreferences: {
|
||||
preload: path.resolve(__dirname, 'preload.js'),
|
||||
contextIsolation: true,
|
||||
@@ -96,7 +96,7 @@ export const loadURL = async (appUrl: string) => {
|
||||
};
|
||||
|
||||
export const loadFile = async (appPath: string) => {
|
||||
mainWindow = await createWindow();
|
||||
mainWindow = await createWindow(appPath === 'index.html' ? '#2f3241' : undefined);
|
||||
mainWindow.loadFile(appPath);
|
||||
mainWindow.focus();
|
||||
};
|
||||
|
||||
@@ -148,7 +148,7 @@ These individual tutorials expand on topics discussed in the guide above.
|
||||
|
||||
### Modules for the Renderer Process (Web Page):
|
||||
|
||||
* [desktopCapturer](api/desktop-capturer.md)
|
||||
* [contextBridge](api/context-bridge.md)
|
||||
* [ipcRenderer](api/ipc-renderer.md)
|
||||
* [remote](api/remote.md)
|
||||
* [webFrame](api/web-frame.md)
|
||||
@@ -157,6 +157,7 @@ These individual tutorials expand on topics discussed in the guide above.
|
||||
|
||||
* [clipboard](api/clipboard.md)
|
||||
* [crashReporter](api/crash-reporter.md)
|
||||
* [desktopCapturer](api/desktop-capturer.md)
|
||||
* [nativeImage](api/native-image.md)
|
||||
* [shell](api/shell.md)
|
||||
|
||||
|
||||
@@ -390,7 +390,7 @@ 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'
|
||||
### Event: 'render-process-gone'
|
||||
|
||||
Returns:
|
||||
|
||||
@@ -409,7 +409,7 @@ Returns:
|
||||
Emitted when the renderer process unexpectedly disappears. This is normally
|
||||
because it was crashed or killed.
|
||||
|
||||
#### Event: 'child-process-gone'
|
||||
### Event: 'child-process-gone'
|
||||
|
||||
Returns:
|
||||
|
||||
@@ -502,7 +502,7 @@ Returns:
|
||||
Emitted when `desktopCapturer.getSources()` is called in the renderer process of `webContents`.
|
||||
Calling `event.preventDefault()` will make it return empty sources.
|
||||
|
||||
### Event: 'remote-require'
|
||||
### Event: 'remote-require' _Deprecated_
|
||||
|
||||
Returns:
|
||||
|
||||
@@ -514,7 +514,7 @@ Emitted when `remote.require()` is called in the renderer process of `webContent
|
||||
Calling `event.preventDefault()` will prevent the module from being returned.
|
||||
Custom value can be returned by setting `event.returnValue`.
|
||||
|
||||
### Event: 'remote-get-global'
|
||||
### Event: 'remote-get-global' _Deprecated_
|
||||
|
||||
Returns:
|
||||
|
||||
@@ -526,7 +526,7 @@ Emitted when `remote.getGlobal()` is called in the renderer process of `webConte
|
||||
Calling `event.preventDefault()` will prevent the global from being returned.
|
||||
Custom value can be returned by setting `event.returnValue`.
|
||||
|
||||
### Event: 'remote-get-builtin'
|
||||
### Event: 'remote-get-builtin' _Deprecated_
|
||||
|
||||
Returns:
|
||||
|
||||
@@ -538,7 +538,7 @@ Emitted when `remote.getBuiltin()` is called in the renderer process of `webCont
|
||||
Calling `event.preventDefault()` will prevent the module from being returned.
|
||||
Custom value can be returned by setting `event.returnValue`.
|
||||
|
||||
### Event: 'remote-get-current-window'
|
||||
### Event: 'remote-get-current-window' _Deprecated_
|
||||
|
||||
Returns:
|
||||
|
||||
@@ -549,7 +549,7 @@ Emitted when `remote.getCurrentWindow()` is called in the renderer process of `w
|
||||
Calling `event.preventDefault()` will prevent the object from being returned.
|
||||
Custom value can be returned by setting `event.returnValue`.
|
||||
|
||||
### Event: 'remote-get-current-web-contents'
|
||||
### Event: 'remote-get-current-web-contents' _Deprecated_
|
||||
|
||||
Returns:
|
||||
|
||||
@@ -749,7 +749,8 @@ Overrides the current application's name.
|
||||
|
||||
### `app.getLocale()`
|
||||
|
||||
Returns `String` - The current application locale. Possible return values are documented [here](locales.md).
|
||||
Returns `String` - The current application locale, fetched using Chromium's `l10n_util` library.
|
||||
Possible return values are documented [here](https://source.chromium.org/chromium/chromium/src/+/master:ui/base/l10n/l10n_util.cc).
|
||||
|
||||
To set the locale, you'll want to use a command line switch at app startup, which may be found [here](https://github.com/electron/electron/blob/master/docs/api/command-line-switches.md).
|
||||
|
||||
@@ -924,6 +925,10 @@ re-add a removed item to a custom category earlier than that will result in the
|
||||
entire custom category being omitted from the Jump List. The list of removed
|
||||
items can be obtained using `app.getJumpListSettings()`.
|
||||
|
||||
**Note:** The maximum length of a Jump List item's `description` property is
|
||||
260 characters. Beyond this limit, the item will not be added to the Jump
|
||||
List, nor will it be displayed.
|
||||
|
||||
Here's a very simple example of creating a custom Jump List:
|
||||
|
||||
```javascript
|
||||
|
||||
@@ -8,9 +8,6 @@ Process: [Main](../glossary.md#main-process)
|
||||
// In the main process.
|
||||
const { BrowserWindow } = require('electron')
|
||||
|
||||
// Or use `remote` from the renderer process.
|
||||
// const { BrowserWindow } = require('electron').remote
|
||||
|
||||
const win = new BrowserWindow({ width: 800, height: 600 })
|
||||
|
||||
// Load a remote URL
|
||||
@@ -733,7 +730,7 @@ The method will also not return if the extension's manifest is missing or incomp
|
||||
is emitted.
|
||||
|
||||
**Note:** This method is deprecated. Instead, use
|
||||
[`ses.loadExtension(path)`](session.md#sesloadextensionpath).
|
||||
[`ses.loadExtension(path)`](session.md#sesloadextensionpath-options).
|
||||
|
||||
#### `BrowserWindow.removeExtension(name)` _Deprecated_
|
||||
|
||||
@@ -775,7 +772,7 @@ The method will also not return if the extension's manifest is missing or incomp
|
||||
is emitted.
|
||||
|
||||
**Note:** This method is deprecated. Instead, use
|
||||
[`ses.loadExtension(path)`](session.md#sesloadextensionpath).
|
||||
[`ses.loadExtension(path)`](session.md#sesloadextensionpath-options).
|
||||
|
||||
#### `BrowserWindow.removeDevToolsExtension(name)` _Deprecated_
|
||||
|
||||
@@ -1049,7 +1046,7 @@ Returns `Boolean` - Whether the window is in simple (pre-Lion) fullscreen mode.
|
||||
|
||||
Returns `Boolean` - Whether the window is in normal state (not maximized, not minimized, not in fullscreen mode).
|
||||
|
||||
#### `win.setAspectRatio(aspectRatio[, extraSize])` _macOS_ _Linux_
|
||||
#### `win.setAspectRatio(aspectRatio[, extraSize])`
|
||||
|
||||
* `aspectRatio` Float - The aspect ratio to maintain for some portion of the
|
||||
content view.
|
||||
@@ -1070,6 +1067,9 @@ the player itself we would call this function with arguments of 16/9 and
|
||||
are within the content view--only that they exist. Sum any extra width and
|
||||
height areas you have within the overall content view.
|
||||
|
||||
The aspect ratio is not respected when window is resized programmingly with
|
||||
APIs like `win.setSize`.
|
||||
|
||||
#### `win.setBackgroundColor(backgroundColor)`
|
||||
|
||||
* `backgroundColor` String - Window's background color as a hexadecimal value,
|
||||
@@ -1389,6 +1389,8 @@ The native type of the handle is `HWND` on Windows, `NSView*` on macOS, and
|
||||
|
||||
* `message` Integer
|
||||
* `callback` Function
|
||||
* `wParam` any - The `wParam` provided to the WndProc
|
||||
* `lParam` any - The `lParam` provided to the WndProc
|
||||
|
||||
Hooks a windows message. The `callback` is called when
|
||||
the message is received in the WndProc.
|
||||
@@ -1441,7 +1443,7 @@ Returns `Boolean` - Whether the window's document has been edited.
|
||||
|
||||
Returns `Promise<NativeImage>` - Resolves with a [NativeImage](native-image.md)
|
||||
|
||||
Captures a snapshot of the page within `rect`. Omitting `rect` will capture the whole visible page.
|
||||
Captures a snapshot of the page within `rect`. Omitting `rect` will capture the whole visible page. If the page is not visible, `rect` may be empty.
|
||||
|
||||
#### `win.loadURL(url[, options])`
|
||||
|
||||
@@ -1849,6 +1851,13 @@ Replacement API for setBrowserView supporting work with multi browser views.
|
||||
|
||||
* `browserView` [BrowserView](browser-view.md)
|
||||
|
||||
#### `win.setTopBrowserView(browserView)` _Experimental_
|
||||
|
||||
* `browserView` [BrowserView](browser-view.md)
|
||||
|
||||
Raises `browserView` above other `BrowserView`s attached to `win`.
|
||||
Throws an error if `browserView` is not attached to `win`.
|
||||
|
||||
#### `win.getBrowserViews()` _Experimental_
|
||||
|
||||
Returns `BrowserView[]` - an array of all BrowserViews that have been attached
|
||||
|
||||
@@ -79,6 +79,12 @@ This switch can not be used in `app.commandLine.appendSwitch` since it is parsed
|
||||
earlier than user's app is loaded, but you can set the `ELECTRON_ENABLE_LOGGING`
|
||||
environment variable to achieve the same effect.
|
||||
|
||||
### --force-fieldtrials=`trials`
|
||||
|
||||
Field trials to be forcefully enabled or disabled.
|
||||
|
||||
For example: `WebRTC-Audio-Red-For-Opus/Enabled/`
|
||||
|
||||
### --host-rules=`rules`
|
||||
|
||||
A comma-separated list of `rules` that control how hostnames are mapped.
|
||||
|
||||
@@ -16,7 +16,7 @@ const { app, contentTracing } = require('electron')
|
||||
app.whenReady().then(() => {
|
||||
(async () => {
|
||||
await contentTracing.startRecording({
|
||||
include_categories: ['*']
|
||||
included_categories: ['*']
|
||||
})
|
||||
console.log('Tracing started')
|
||||
await new Promise(resolve => setTimeout(resolve, 5000))
|
||||
|
||||
@@ -45,6 +45,8 @@ The following events are available on instances of `Cookies`:
|
||||
|
||||
#### Event: 'changed'
|
||||
|
||||
Returns:
|
||||
|
||||
* `event` Event
|
||||
* `cookie` [Cookie](structures/cookie.md) - The cookie that was changed.
|
||||
* `cause` String - The cause of the change with one of the following values:
|
||||
|
||||
@@ -11,14 +11,6 @@ const { dialog } = require('electron')
|
||||
console.log(dialog.showOpenDialog({ properties: ['openFile', 'multiSelections'] }))
|
||||
```
|
||||
|
||||
The Dialog is opened from Electron's main thread. If you want to use the dialog
|
||||
object from a renderer process, remember to access it using the remote:
|
||||
|
||||
```javascript
|
||||
const { dialog } = require('electron').remote
|
||||
console.log(dialog)
|
||||
```
|
||||
|
||||
## Methods
|
||||
|
||||
The `dialog` module has the following methods:
|
||||
|
||||
@@ -15,7 +15,7 @@ extension capabilities.
|
||||
|
||||
Electron only supports loading unpacked extensions (i.e., `.crx` files do not
|
||||
work). Extensions are installed per-`session`. To load an extension, call
|
||||
[`ses.loadExtension`](session.md#sesloadextensionpath):
|
||||
[`ses.loadExtension`](session.md#sesloadextensionpath-options):
|
||||
|
||||
```js
|
||||
const { session } = require('electron')
|
||||
@@ -114,3 +114,9 @@ The following methods of `chrome.management` are supported:
|
||||
- `chrome.management.getPermissionWarningsByManifest`
|
||||
- `chrome.management.onEnabled`
|
||||
- `chrome.management.onDisabled`
|
||||
|
||||
### `chrome.webRequest`
|
||||
|
||||
All features of this API are supported.
|
||||
|
||||
> **NOTE:** Electron's [`webRequest`](web-request.md) module takes precedence over `chrome.webRequest` if there are conflicting handlers.
|
||||
|
||||
@@ -83,8 +83,11 @@ win.show()
|
||||
* The `blur` filter only applies to the web page, so there is no way to apply
|
||||
blur effect to the content below the window (i.e. other applications open on
|
||||
the user's system).
|
||||
* On Windows operating systems, transparent windows will not work when DWM is
|
||||
* The window will not be transparent when DevTools is opened.
|
||||
* On Windows operating systems,
|
||||
* transparent windows will not work when DWM is
|
||||
disabled.
|
||||
* transparent windows can not be maximized using the Windows system menu or by double clicking the title bar. The reasoning behind this can be seen on [this pull request](https://github.com/electron/electron/pull/28207).
|
||||
* On Linux, users have to put `--enable-transparent-visuals --disable-gpu` in
|
||||
the command line to disable GPU and allow ARGB to make transparent window,
|
||||
this is caused by an upstream bug that [alpha channel doesn't work on some
|
||||
@@ -112,13 +115,19 @@ optional parameter can be used to forward mouse move messages to the web page,
|
||||
allowing events such as `mouseleave` to be emitted:
|
||||
|
||||
```javascript
|
||||
const win = require('electron').remote.getCurrentWindow()
|
||||
const { ipcRenderer } = require('electron')
|
||||
const el = document.getElementById('clickThroughElement')
|
||||
el.addEventListener('mouseenter', () => {
|
||||
win.setIgnoreMouseEvents(true, { forward: true })
|
||||
ipcRenderer.send('set-ignore-mouse-events', true, { forward: true })
|
||||
})
|
||||
el.addEventListener('mouseleave', () => {
|
||||
win.setIgnoreMouseEvents(false)
|
||||
ipcRenderer.send('set-ignore-mouse-events', false)
|
||||
})
|
||||
|
||||
// Main process
|
||||
const { ipcMain } = require('electron')
|
||||
ipcMain.on('set-ignore-mouse-events', (event, ...args) => {
|
||||
BrowserWindow.fromWebContents(event.sender).setIgnoreMouseEvents(...args)
|
||||
})
|
||||
```
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@ with the operating system so that you can customize the operations for various
|
||||
shortcuts.
|
||||
|
||||
**Note:** The shortcut is global; it will work even if the app does
|
||||
not have the keyboard focus. You should not use this module until the `ready`
|
||||
not have the keyboard focus. This module cannot be used before the `ready`
|
||||
event of the app module is emitted.
|
||||
|
||||
```javascript
|
||||
|
||||
@@ -61,9 +61,13 @@ Algorithm][SCA], just like [`window.postMessage`][], so prototype chains will no
|
||||
included. Sending Functions, Promises, Symbols, WeakMaps, or WeakSets will
|
||||
throw an exception.
|
||||
|
||||
> **NOTE**: Sending non-standard JavaScript types such as DOM objects or
|
||||
> special Electron objects is deprecated, and will begin throwing an exception
|
||||
> starting with Electron 9.
|
||||
> **NOTE:** Sending non-standard JavaScript types such as DOM objects or
|
||||
> special Electron objects will throw an exception.
|
||||
>
|
||||
> Since the main process does not have support for DOM objects such as
|
||||
> `ImageBitmap`, `File`, `DOMMatrix` and so on, such objects cannot be sent over
|
||||
> Electron's IPC to the main process, as the main process would have no way to decode
|
||||
> them. Attempting to send such objects over IPC will result in an error.
|
||||
|
||||
The main process handles it by listening for `channel` with the
|
||||
[`ipcMain`](ipc-main.md) module.
|
||||
@@ -85,9 +89,13 @@ Algorithm][SCA], just like [`window.postMessage`][], so prototype chains will no
|
||||
included. Sending Functions, Promises, Symbols, WeakMaps, or WeakSets will
|
||||
throw an exception.
|
||||
|
||||
> **NOTE**: Sending non-standard JavaScript types such as DOM objects or
|
||||
> special Electron objects is deprecated, and will begin throwing an exception
|
||||
> starting with Electron 9.
|
||||
> **NOTE:** Sending non-standard JavaScript types such as DOM objects or
|
||||
> special Electron objects will throw an exception.
|
||||
>
|
||||
> Since the main process does not have support for DOM objects such as
|
||||
> `ImageBitmap`, `File`, `DOMMatrix` and so on, such objects cannot be sent over
|
||||
> Electron's IPC to the main process, as the main process would have no way to decode
|
||||
> them. Attempting to send such objects over IPC will result in an error.
|
||||
|
||||
The main process should listen for `channel` with
|
||||
[`ipcMain.handle()`](ipc-main.md#ipcmainhandlechannel-listener).
|
||||
@@ -123,9 +131,13 @@ Algorithm][SCA], just like [`window.postMessage`][], so prototype chains will no
|
||||
included. Sending Functions, Promises, Symbols, WeakMaps, or WeakSets will
|
||||
throw an exception.
|
||||
|
||||
> **NOTE**: Sending non-standard JavaScript types such as DOM objects or
|
||||
> special Electron objects is deprecated, and will begin throwing an exception
|
||||
> starting with Electron 9.
|
||||
> **NOTE:** Sending non-standard JavaScript types such as DOM objects or
|
||||
> special Electron objects will throw an exception.
|
||||
>
|
||||
> Since the main process does not have support for DOM objects such as
|
||||
> `ImageBitmap`, `File`, `DOMMatrix` and so on, such objects cannot be sent over
|
||||
> Electron's IPC to the main process, as the main process would have no way to decode
|
||||
> them. Attempting to send such objects over IPC will result in an error.
|
||||
|
||||
The main process handles it by listening for `channel` with [`ipcMain`](ipc-main.md) module,
|
||||
and replies by setting `event.returnValue`.
|
||||
|
||||
@@ -1,142 +0,0 @@
|
||||
# Locales
|
||||
|
||||
> Locale values returned by `app.getLocale()`.
|
||||
|
||||
Electron uses Chromium's `l10n_util` library to fetch the locale. Possible
|
||||
values are listed below:
|
||||
|
||||
| Language Code | Language Name |
|
||||
|---------------|---------------|
|
||||
| af | Afrikaans |
|
||||
| am | Amharic |
|
||||
| ar | Arabic |
|
||||
| az | Azerbaijani |
|
||||
| be | Belarusian |
|
||||
| bg | Bulgarian |
|
||||
| bh | Bihari |
|
||||
| bn | Bengali |
|
||||
| br | Breton |
|
||||
| bs | Bosnian |
|
||||
| ca | Catalan |
|
||||
| co | Corsican |
|
||||
| cs | Czech |
|
||||
| cy | Welsh |
|
||||
| da | Danish |
|
||||
| de | German |
|
||||
| de-AT | German (Austria) |
|
||||
| de-CH | German (Switzerland) |
|
||||
| de-DE | German (Germany) |
|
||||
| el | Greek |
|
||||
| en | English |
|
||||
| en-AU | English (Australia) |
|
||||
| en-CA | English (Canada) |
|
||||
| en-GB | English (UK) |
|
||||
| en-NZ | English (New Zealand) |
|
||||
| en-US | English (US) |
|
||||
| en-ZA | English (South Africa) |
|
||||
| eo | Esperanto |
|
||||
| es | Spanish |
|
||||
| es-419 | Spanish (Latin America) |
|
||||
| et | Estonian |
|
||||
| eu | Basque |
|
||||
| fa | Persian |
|
||||
| fi | Finnish |
|
||||
| fil | Filipino |
|
||||
| fo | Faroese |
|
||||
| fr | French |
|
||||
| fr-CA | French (Canada) |
|
||||
| fr-CH | French (Switzerland) |
|
||||
| fr-FR | French (France) |
|
||||
| fy | Frisian |
|
||||
| ga | Irish |
|
||||
| gd | Scots Gaelic |
|
||||
| gl | Galician |
|
||||
| gn | Guarani |
|
||||
| gu | Gujarati |
|
||||
| ha | Hausa |
|
||||
| haw | Hawaiian |
|
||||
| he | Hebrew |
|
||||
| hi | Hindi |
|
||||
| hr | Croatian |
|
||||
| hu | Hungarian |
|
||||
| hy | Armenian |
|
||||
| ia | Interlingua |
|
||||
| id | Indonesian |
|
||||
| is | Icelandic |
|
||||
| it | Italian |
|
||||
| it-CH | Italian (Switzerland) |
|
||||
| it-IT | Italian (Italy) |
|
||||
| ja | Japanese |
|
||||
| jw | Javanese |
|
||||
| ka | Georgian |
|
||||
| kk | Kazakh |
|
||||
| km | Cambodian |
|
||||
| kn | Kannada |
|
||||
| ko | Korean |
|
||||
| ku | Kurdish |
|
||||
| ky | Kyrgyz |
|
||||
| la | Latin |
|
||||
| ln | Lingala |
|
||||
| lo | Laothian |
|
||||
| lt | Lithuanian |
|
||||
| lv | Latvian |
|
||||
| mk | Macedonian |
|
||||
| ml | Malayalam |
|
||||
| mn | Mongolian |
|
||||
| mo | Moldavian |
|
||||
| mr | Marathi |
|
||||
| ms | Malay |
|
||||
| mt | Maltese |
|
||||
| nb | Norwegian (Bokmal) |
|
||||
| ne | Nepali |
|
||||
| nl | Dutch |
|
||||
| nn | Norwegian (Nynorsk) |
|
||||
| no | Norwegian |
|
||||
| oc | Occitan |
|
||||
| om | Oromo |
|
||||
| or | Oriya |
|
||||
| pa | Punjabi |
|
||||
| pl | Polish |
|
||||
| ps | Pashto |
|
||||
| pt | Portuguese |
|
||||
| pt-BR | Portuguese (Brazil) |
|
||||
| pt-PT | Portuguese (Portugal) |
|
||||
| qu | Quechua |
|
||||
| rm | Romansh |
|
||||
| ro | Romanian |
|
||||
| ru | Russian |
|
||||
| sd | Sindhi |
|
||||
| sh | Serbo-Croatian |
|
||||
| si | Sinhalese |
|
||||
| sk | Slovak |
|
||||
| sl | Slovenian |
|
||||
| sn | Shona |
|
||||
| so | Somali |
|
||||
| sq | Albanian |
|
||||
| sr | Serbian |
|
||||
| st | Sesotho |
|
||||
| su | Sundanese |
|
||||
| sv | Swedish |
|
||||
| sw | Swahili |
|
||||
| ta | Tamil |
|
||||
| te | Telugu |
|
||||
| tg | Tajik |
|
||||
| th | Thai |
|
||||
| ti | Tigrinya |
|
||||
| tk | Turkmen |
|
||||
| to | Tonga |
|
||||
| tr | Turkish |
|
||||
| tt | Tatar |
|
||||
| tw | Twi |
|
||||
| ug | Uighur |
|
||||
| uk | Ukrainian |
|
||||
| ur | Urdu |
|
||||
| uz | Uzbek |
|
||||
| vi | Vietnamese |
|
||||
| xh | Xhosa |
|
||||
| yi | Yiddish |
|
||||
| yo | Yoruba |
|
||||
| zh | Chinese |
|
||||
| zh-CN | Chinese (Simplified) |
|
||||
| zh-TW | Chinese (Traditional) |
|
||||
| zu | Zulu |
|
||||
@@ -22,8 +22,10 @@ Sets `menu` as the application menu on macOS. On Windows and Linux, the
|
||||
Also on Windows and Linux, you can use a `&` in the top-level item name to
|
||||
indicate which letter should get a generated accelerator. For example, using
|
||||
`&File` for the file menu would result in a generated `Alt-F` accelerator that
|
||||
opens the associated menu. The indicated character in the button label gets an
|
||||
underline. The `&` character is not displayed on the button label.
|
||||
opens the associated menu. The indicated character in the button label then gets an
|
||||
underline, and the `&` character is not displayed on the button label.
|
||||
|
||||
In order to escape the `&` character in an item name, add a proceeding `&`. For example, `&&File` would result in `&File` displayed on the button label.
|
||||
|
||||
Passing `null` will suppress the default menu. On Windows and Linux,
|
||||
this has the additional effect of removing the menu bar from the window.
|
||||
@@ -141,13 +143,7 @@ can have a submenu.
|
||||
|
||||
## Examples
|
||||
|
||||
The `Menu` class is only available in the main process, but you can also use it
|
||||
in the render process via the [`remote`](remote.md) module.
|
||||
|
||||
### Main process
|
||||
|
||||
An example of creating the application menu in the main process with the
|
||||
simple template API:
|
||||
An example of creating the application menu with the simple template API:
|
||||
|
||||
```javascript
|
||||
const { app, Menu } = require('electron')
|
||||
@@ -257,26 +253,36 @@ Menu.setApplicationMenu(menu)
|
||||
|
||||
### Render process
|
||||
|
||||
Below is an example of creating a menu dynamically in a web page
|
||||
(render process) by using the [`remote`](remote.md) module, and showing it when
|
||||
the user right clicks the page:
|
||||
To create menus initiated by the renderer process, send the required
|
||||
information to the main process using IPC and have the main process display the
|
||||
menu on behalf of the renderer.
|
||||
|
||||
```html
|
||||
<!-- index.html -->
|
||||
<script>
|
||||
const { remote } = require('electron')
|
||||
const { Menu, MenuItem } = remote
|
||||
|
||||
const menu = new Menu()
|
||||
menu.append(new MenuItem({ label: 'MenuItem1', click() { console.log('item 1 clicked') } }))
|
||||
menu.append(new MenuItem({ type: 'separator' }))
|
||||
menu.append(new MenuItem({ label: 'MenuItem2', type: 'checkbox', checked: true }))
|
||||
Below is an example of showing a menu when the user right clicks the page:
|
||||
|
||||
```js
|
||||
// renderer
|
||||
window.addEventListener('contextmenu', (e) => {
|
||||
e.preventDefault()
|
||||
menu.popup({ window: remote.getCurrentWindow() })
|
||||
}, false)
|
||||
</script>
|
||||
ipcRenderer.send('show-context-menu')
|
||||
})
|
||||
|
||||
ipcRenderer.on('context-menu-command', (e, command) => {
|
||||
// ...
|
||||
})
|
||||
|
||||
// main
|
||||
ipcMain.on('show-context-menu', (event) => {
|
||||
const template = [
|
||||
{
|
||||
label: 'Menu Item 1',
|
||||
click: () => { event.sender.send('context-menu-command', 'menu-item-1') }
|
||||
},
|
||||
{ type: 'separator' },
|
||||
{ label: 'Menu Item 2', type: 'checkbox', checked: true }
|
||||
]
|
||||
const menu = Menu.buildFromTemplate(template)
|
||||
menu.popup(BrowserWindow.fromWebContents(event.sender))
|
||||
})
|
||||
```
|
||||
|
||||
## Notes on macOS Application Menu
|
||||
|
||||
@@ -1,10 +0,0 @@
|
||||
## Modernization
|
||||
|
||||
The Electron team is currently undergoing an initiative to modernize our API in a few concrete ways. These include: updating our modules to use idiomatic JS properties instead of separate `getPropertyX` and `setpropertyX`, converting callbacks to promises, and removing some other anti-patterns present in our APIs. The current status of the Promise initiative can be tracked in the [promisification](promisification.md) tracking file.
|
||||
|
||||
As we work to perform these updates, we seek to create the least disruptive amount of change at any given time, so as many changes as possible will be introduced in a backward compatible manner and deprecated after enough time has passed to give users a chance to upgrade their API calls.
|
||||
|
||||
This document and its child documents will be updated to reflect the latest status of our API changes.
|
||||
|
||||
* [Promisification](promisification.md)
|
||||
* [Property Updates](property-updates.md)
|
||||
@@ -1,42 +0,0 @@
|
||||
## Promisification
|
||||
|
||||
The Electron team recently underwent an initiative to convert callback-based APIs to Promise-based ones. See converted functions below:
|
||||
|
||||
- [app.getFileIcon(path[, options], callback)](https://github.com/electron/electron/blob/master/docs/api/app.md#getFileIcon)
|
||||
- [contents.capturePage([rect, ]callback)](https://github.com/electron/electron/blob/master/docs/api/web-contents.md#capturePage)
|
||||
- [contents.executeJavaScript(code[, userGesture, callback])](https://github.com/electron/electron/blob/master/docs/api/web-contents.md#executeJavaScript)
|
||||
- [contents.printToPDF(options, callback)](https://github.com/electron/electron/blob/master/docs/api/web-contents.md#printToPDF)
|
||||
- [contents.savePage(fullPath, saveType, callback)](https://github.com/electron/electron/blob/master/docs/api/web-contents.md#savePage)
|
||||
- [contentTracing.getCategories(callback)](https://github.com/electron/electron/blob/master/docs/api/content-tracing.md#getCategories)
|
||||
- [contentTracing.startRecording(options, callback)](https://github.com/electron/electron/blob/master/docs/api/content-tracing.md#startRecording)
|
||||
- [contentTracing.stopRecording(resultFilePath, callback)](https://github.com/electron/electron/blob/master/docs/api/content-tracing.md#stopRecording)
|
||||
- [contentTracing.getTraceBufferUsage(callback)](https://github.com/electron/electron/blob/master/docs/api/content-tracing.md#getTraceBufferUsage)
|
||||
- [cookies.flushStore(callback)](https://github.com/electron/electron/blob/master/docs/api/cookies.md#flushStore)
|
||||
- [cookies.get(filter, callback)](https://github.com/electron/electron/blob/master/docs/api/cookies.md#get)
|
||||
- [cookies.remove(url, name, callback)](https://github.com/electron/electron/blob/master/docs/api/cookies.md#remove)
|
||||
- [cookies.set(details, callback)](https://github.com/electron/electron/blob/master/docs/api/cookies.md#set)
|
||||
- [debugger.sendCommand(method[, commandParams, callback])](https://github.com/electron/electron/blob/master/docs/api/debugger.md#sendCommand)
|
||||
- [desktopCapturer.getSources(options, callback)](https://github.com/electron/electron/blob/master/docs/api/desktop-capturer.md#getSources)
|
||||
- [dialog.showOpenDialog([browserWindow, ]options[, callback])](https://github.com/electron/electron/blob/master/docs/api/dialog.md#showOpenDialog)
|
||||
- [dialog.showSaveDialog([browserWindow, ]options[, callback])](https://github.com/electron/electron/blob/master/docs/api/dialog.md#showSaveDialog)
|
||||
- [inAppPurchase.purchaseProduct(productID, quantity, callback)](https://github.com/electron/electron/blob/master/docs/api/in-app-purchase.md#purchaseProduct)
|
||||
- [inAppPurchase.getProducts(productIDs, callback)](https://github.com/electron/electron/blob/master/docs/api/in-app-purchase.md#getProducts)
|
||||
- [dialog.showMessageBox([browserWindow, ]options[, callback])](https://github.com/electron/electron/blob/master/docs/api/dialog.md#showMessageBox)
|
||||
- [dialog.showCertificateTrustDialog([browserWindow, ]options, callback)](https://github.com/electron/electron/blob/master/docs/api/dialog.md#showCertificateTrustDialog)
|
||||
- [netLog.stopLogging([callback])](https://github.com/electron/electron/blob/master/docs/api/net-log.md#stopLogging)
|
||||
- [protocol.isProtocolHandled(scheme, callback)](https://github.com/electron/electron/blob/master/docs/api/protocol.md#isProtocolHandled)
|
||||
- [ses.clearHostResolverCache([callback])](https://github.com/electron/electron/blob/master/docs/api/session.md#clearHostResolverCache)
|
||||
- [ses.clearStorageData([options, callback])](https://github.com/electron/electron/blob/master/docs/api/session.md#clearStorageData)
|
||||
- [ses.setProxy(config, callback)](https://github.com/electron/electron/blob/master/docs/api/session.md#setProxy)
|
||||
- [ses.resolveProxy(url, callback)](https://github.com/electron/electron/blob/master/docs/api/session.md#resolveProxy)
|
||||
- [ses.getCacheSize(callback)](https://github.com/electron/electron/blob/master/docs/api/session.md#getCacheSize)
|
||||
- [ses.clearAuthCache(options[, callback])](https://github.com/electron/electron/blob/master/docs/api/session.md#clearAuthCache)
|
||||
- [ses.clearCache(callback)](https://github.com/electron/electron/blob/master/docs/api/session.md#clearCache)
|
||||
- [ses.getBlobData(identifier, callback)](https://github.com/electron/electron/blob/master/docs/api/session.md#getBlobData)
|
||||
- [shell.openExternal(url[, options, callback])](https://github.com/electron/electron/blob/master/docs/api/shell.md#openExternal)
|
||||
- [webFrame.executeJavaScript(code[, userGesture, callback])](https://github.com/electron/electron/blob/master/docs/api/web-frame.md#executeJavaScript)
|
||||
- [webFrame.executeJavaScriptInIsolatedWorld(worldId, scripts[, userGesture, callback])](https://github.com/electron/electron/blob/master/docs/api/web-frame.md#executeJavaScriptInIsolatedWorld)
|
||||
- [webviewTag.capturePage([rect, ]callback)](https://github.com/electron/electron/blob/master/docs/api/webview-tag.md#capturePage)
|
||||
- [webviewTag.executeJavaScript(code[, userGesture, callback])](https://github.com/electron/electron/blob/master/docs/api/webview-tag.md#executeJavaScript)
|
||||
- [webviewTag.printToPDF(options, callback)](https://github.com/electron/electron/blob/master/docs/api/webview-tag.md#printToPDF)
|
||||
- [win.capturePage([rect, ]callback)](https://github.com/electron/electron/blob/master/docs/api/browser-window.md#capturePage)
|
||||
@@ -1,41 +0,0 @@
|
||||
## Property Updates
|
||||
|
||||
The Electron team is currently undergoing an initiative to convert separate getter and setter functions in Electron to bespoke properties with `get` and `set` functionality. During this transition period, both the new properties and old getters and setters of these functions will work correctly and be documented.
|
||||
|
||||
## Candidates
|
||||
|
||||
* `BrowserWindow`
|
||||
* `menubarVisible`
|
||||
* `crashReporter` module
|
||||
* `uploadToServer`
|
||||
* `webFrame` modules
|
||||
* `zoomFactor`
|
||||
* `zoomLevel`
|
||||
* `audioMuted`
|
||||
* `<webview>`
|
||||
* `zoomFactor`
|
||||
* `zoomLevel`
|
||||
* `audioMuted`
|
||||
|
||||
## Converted Properties
|
||||
|
||||
* `app` module
|
||||
* `accessibilitySupport`
|
||||
* `applicationMenu`
|
||||
* `badgeCount`
|
||||
* `name`
|
||||
* `DownloadItem` class
|
||||
* `savePath`
|
||||
* `BrowserWindow` module
|
||||
* `autohideMenuBar`
|
||||
* `resizable`
|
||||
* `maximizable`
|
||||
* `minimizable`
|
||||
* `fullscreenable`
|
||||
* `movable`
|
||||
* `closable`
|
||||
* `backgroundThrottling`
|
||||
* `NativeImage`
|
||||
* `isMacTemplateImage`
|
||||
* `SystemPreferences` module
|
||||
* `appLevelAppearance`
|
||||
@@ -88,26 +88,17 @@ and preload.js:
|
||||
|
||||
```js
|
||||
// This file is loaded whenever a javascript context is created. It runs in a
|
||||
// private scope that can access a subset of Electron renderer APIs. We must be
|
||||
// careful to not leak any objects into the global scope!
|
||||
const { ipcRenderer, remote } = require('electron')
|
||||
const fs = remote.require('fs')
|
||||
|
||||
// read a configuration file using the `fs` module
|
||||
const buf = fs.readFileSync('allowed-popup-urls.json')
|
||||
const allowedUrls = JSON.parse(buf.toString('utf8'))
|
||||
// private scope that can access a subset of Electron renderer APIs. Without
|
||||
// contextIsolation enabled, it's possible to accidentally leak privileged
|
||||
// globals like ipcRenderer to web content.
|
||||
const { ipcRenderer } = require('electron')
|
||||
|
||||
const defaultWindowOpen = window.open
|
||||
|
||||
function customWindowOpen (url, ...args) {
|
||||
if (allowedUrls.indexOf(url) === -1) {
|
||||
ipcRenderer.sendSync('blocked-popup-notification', location.origin, url)
|
||||
return null
|
||||
}
|
||||
return defaultWindowOpen(url, ...args)
|
||||
window.open = function customWindowOpen (url, ...args) {
|
||||
ipcRenderer.send('report-window-open', location.origin, url, args)
|
||||
return defaultWindowOpen(url + '?from_electron=1', ...args)
|
||||
}
|
||||
|
||||
window.open = customWindowOpen
|
||||
```
|
||||
|
||||
Important things to notice in the preload script:
|
||||
@@ -115,8 +106,6 @@ Important things to notice in the preload script:
|
||||
- Even though the sandboxed renderer doesn't have Node.js running, it still has
|
||||
access to a limited node-like environment: `Buffer`, `process`, `setImmediate`,
|
||||
`clearImmediate` and `require` are available.
|
||||
- The preload script can indirectly access all APIs from the main process through the
|
||||
`remote` and `ipcRenderer` modules.
|
||||
- The preload script must be contained in a single script, but it is possible to have
|
||||
complex preload code composed with multiple modules by using a tool like
|
||||
webpack or browserify. An example of using browserify is below.
|
||||
@@ -144,15 +133,12 @@ following modules:
|
||||
- `desktopCapturer`
|
||||
- `ipcRenderer`
|
||||
- `nativeImage`
|
||||
- `remote`
|
||||
- `webFrame`
|
||||
- `events`
|
||||
- `timers`
|
||||
- `url`
|
||||
|
||||
More may be added as needed to expose more Electron APIs in the sandbox, but any
|
||||
module in the main process can already be used through
|
||||
`electron.remote.require`.
|
||||
More may be added as needed to expose more Electron APIs in the sandbox.
|
||||
|
||||
## Rendering untrusted content
|
||||
|
||||
|
||||
@@ -568,9 +568,13 @@ will not work on non-persistent (in-memory) sessions.
|
||||
|
||||
**Note:** On macOS and Windows 10 this word will be removed from the OS custom dictionary as well
|
||||
|
||||
#### `ses.loadExtension(path)`
|
||||
#### `ses.loadExtension(path[, options])`
|
||||
|
||||
* `path` String - Path to a directory containing an unpacked Chrome extension
|
||||
* `options` Object (optional)
|
||||
* `allowFileAccess` Boolean - Whether to allow the extension to read local files over `file://`
|
||||
protocol and inject content scripts into `file://` pages. This is required e.g. for loading
|
||||
devtools extensions on `file://` URLs. Defaults to false.
|
||||
|
||||
Returns `Promise<Extension>` - resolves when the extension is loaded.
|
||||
|
||||
@@ -593,7 +597,11 @@ const { app, session } = require('electron')
|
||||
const path = require('path')
|
||||
|
||||
app.on('ready', async () => {
|
||||
await session.defaultSession.loadExtension(path.join(__dirname, 'react-devtools'))
|
||||
await session.defaultSession.loadExtension(
|
||||
path.join(__dirname, 'react-devtools'),
|
||||
// allowFileAccess is required to load the devtools extension on file:// URLs.
|
||||
{ allowFileAccess: true }
|
||||
)
|
||||
// Note that in order to use the React DevTools extension, you'll need to
|
||||
// download and unzip a copy of the extension.
|
||||
})
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
# IpcMainEvent Object extends `Event`
|
||||
|
||||
* `processId` Integer - The internal ID of the renderer process that sent this message
|
||||
* `frameId` Integer - The ID of the renderer frame that sent this message
|
||||
* `returnValue` any - Set this to the value to be returned in a synchronous message
|
||||
* `sender` WebContents - Returns the `webContents` that sent the message
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
# IpcMainInvokeEvent Object extends `Event`
|
||||
|
||||
* `processId` Integer - The internal ID of the renderer process that sent this message
|
||||
* `frameId` Integer - The ID of the renderer frame that sent this message
|
||||
* `sender` WebContents - Returns the `webContents` that sent the message
|
||||
|
||||
@@ -19,3 +19,7 @@
|
||||
property set then its `type` is assumed to be `tasks`. If the `name` property
|
||||
is set but the `type` property is omitted then the `type` is assumed to be
|
||||
`custom`.
|
||||
|
||||
**Note:** The maximum length of a Jump List item's `description` property is
|
||||
260 characters. Beyond this limit, the item will not be added to the Jump
|
||||
List, nor will it be displayed.
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
* `title` String (optional) - The text to be displayed for the item in the Jump List.
|
||||
Should only be set if `type` is `task`.
|
||||
* `description` String (optional) - Description of the task (displayed in a tooltip).
|
||||
Should only be set if `type` is `task`.
|
||||
Should only be set if `type` is `task`. Maximum length 260 characters.
|
||||
* `iconPath` String (optional) - The absolute path to an icon to be displayed in a
|
||||
Jump List, which can be an arbitrary resource file that contains an icon
|
||||
(e.g. `.ico`, `.exe`, `.dll`). You can usually specify `process.execPath` to
|
||||
|
||||
@@ -9,7 +9,7 @@ the [native modules](../tutorial/using-native-node-modules.md)).
|
||||
Electron also provides some extra built-in modules for developing native
|
||||
desktop applications. Some modules are only available in the main process, some
|
||||
are only available in the renderer process (web page), and some can be used in
|
||||
both processes.
|
||||
either process type.
|
||||
|
||||
The basic rule is: if a module is [GUI][gui] or low-level system related, then
|
||||
it should be only available in the main process. You need to be familiar with
|
||||
@@ -29,15 +29,15 @@ app.whenReady().then(() => {
|
||||
```
|
||||
|
||||
The renderer process is no different than a normal web page, except for the
|
||||
extra ability to use node modules:
|
||||
extra ability to use node modules if `nodeIntegration` is enabled:
|
||||
|
||||
```html
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<body>
|
||||
<script>
|
||||
const { app } = require('electron').remote
|
||||
console.log(app.getVersion())
|
||||
const fs = require('fs')
|
||||
console.log(fs.readFileSync(__filename, 'utf8'))
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -132,6 +132,8 @@ This is necessary for events such as `NSUserDefaultsDidChangeNotification`.
|
||||
* `userInfo` Record<String, unknown>
|
||||
* `object` String
|
||||
|
||||
Returns `Number` - The ID of this subscription
|
||||
|
||||
Same as `subscribeNotification`, but uses `NSWorkspace.sharedWorkspace.notificationCenter`.
|
||||
This is necessary for events such as `NSWorkspaceDidActivateApplicationNotification`.
|
||||
|
||||
|
||||
@@ -42,7 +42,8 @@ returns `null`.
|
||||
|
||||
* `id` Integer
|
||||
|
||||
Returns `WebContents` - A WebContents instance with the given ID.
|
||||
Returns `WebContents` | undefined - A WebContents instance with the given ID, or
|
||||
`undefined` if there is no WebContents associated with the given ID.
|
||||
|
||||
## Class: WebContents
|
||||
|
||||
@@ -784,7 +785,7 @@ Returns:
|
||||
Emitted when `desktopCapturer.getSources()` is called in the renderer process.
|
||||
Calling `event.preventDefault()` will make it return empty sources.
|
||||
|
||||
#### Event: 'remote-require'
|
||||
#### Event: 'remote-require' _Deprecated_
|
||||
|
||||
Returns:
|
||||
|
||||
@@ -795,7 +796,7 @@ Emitted when `remote.require()` is called in the renderer process.
|
||||
Calling `event.preventDefault()` will prevent the module from being returned.
|
||||
Custom value can be returned by setting `event.returnValue`.
|
||||
|
||||
#### Event: 'remote-get-global'
|
||||
#### Event: 'remote-get-global' _Deprecated_
|
||||
|
||||
Returns:
|
||||
|
||||
@@ -806,7 +807,7 @@ Emitted when `remote.getGlobal()` is called in the renderer process.
|
||||
Calling `event.preventDefault()` will prevent the global from being returned.
|
||||
Custom value can be returned by setting `event.returnValue`.
|
||||
|
||||
#### Event: 'remote-get-builtin'
|
||||
#### Event: 'remote-get-builtin' _Deprecated_
|
||||
|
||||
Returns:
|
||||
|
||||
@@ -817,7 +818,7 @@ Emitted when `remote.getBuiltin()` is called in the renderer process.
|
||||
Calling `event.preventDefault()` will prevent the module from being returned.
|
||||
Custom value can be returned by setting `event.returnValue`.
|
||||
|
||||
#### Event: 'remote-get-current-window'
|
||||
#### Event: 'remote-get-current-window' _Deprecated_
|
||||
|
||||
Returns:
|
||||
|
||||
@@ -827,7 +828,7 @@ Emitted when `remote.getCurrentWindow()` is called in the renderer process.
|
||||
Calling `event.preventDefault()` will prevent the object from being returned.
|
||||
Custom value can be returned by setting `event.returnValue`.
|
||||
|
||||
#### Event: 'remote-get-current-web-contents'
|
||||
#### Event: 'remote-get-current-web-contents' _Deprecated_
|
||||
|
||||
Returns:
|
||||
|
||||
@@ -1232,8 +1233,7 @@ Inserts `text` to the focused element.
|
||||
* `text` String - Content to be searched, must not be empty.
|
||||
* `options` Object (optional)
|
||||
* `forward` Boolean (optional) - Whether to search forward or backward, defaults to `true`.
|
||||
* `findNext` Boolean (optional) - Whether the operation is first request or a follow up,
|
||||
defaults to `false`.
|
||||
* `findNext` Boolean (optional) - Whether to begin a new text finding session with this request. Should be `true` for initial requests, and `false` for follow-up requests. Defaults to `false`.
|
||||
* `matchCase` Boolean (optional) - Whether search should be case-sensitive,
|
||||
defaults to `false`.
|
||||
* `wordStart` Boolean (optional) - Whether to look only at the start of words.
|
||||
@@ -1481,7 +1481,7 @@ An example of showing devtools in a `<webview>` tag:
|
||||
<webview id="browser" src="https://github.com"></webview>
|
||||
<webview id="devtools" src="about:blank"></webview>
|
||||
<script>
|
||||
const { webContents } = require('electron').remote
|
||||
const { ipcRenderer } = require('electron')
|
||||
const emittedOnce = (element, eventName) => new Promise(resolve => {
|
||||
element.addEventListener(eventName, event => resolve(event), { once: true })
|
||||
})
|
||||
@@ -1490,16 +1490,26 @@ An example of showing devtools in a `<webview>` tag:
|
||||
const browserReady = emittedOnce(browserView, 'dom-ready')
|
||||
const devtoolsReady = emittedOnce(devtoolsView, 'dom-ready')
|
||||
Promise.all([browserReady, devtoolsReady]).then(() => {
|
||||
const browser = webContents.fromId(browserView.getWebContentsId())
|
||||
const devtools = webContents.fromId(devtoolsView.getWebContentsId())
|
||||
browser.setDevToolsWebContents(devtools)
|
||||
browser.openDevTools()
|
||||
const targetId = browserView.getWebContentsId()
|
||||
const devtoolsId = devtoolsView.getWebContentsId()
|
||||
ipcRenderer.send('open-devtools', targetId, devtoolsId)
|
||||
})
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
|
||||
```js
|
||||
// Main process
|
||||
const { ipcMain, webContents } = require('electron')
|
||||
ipcMain.on('open-devtools', (event, targetContentsId, devtoolsContentsId) => {
|
||||
const target = webContents.fromId(targetContentsId)
|
||||
const devtools = webContents.fromId(devtoolsContentsId)
|
||||
target.setDevToolsWebContents(devtools)
|
||||
target.openDevTools()
|
||||
})
|
||||
```
|
||||
|
||||
An example of showing devtools in a `BrowserWindow`:
|
||||
|
||||
```js
|
||||
@@ -1584,8 +1594,7 @@ included. Sending Functions, Promises, Symbols, WeakMaps, or WeakSets will
|
||||
throw an exception.
|
||||
|
||||
> **NOTE**: Sending non-standard JavaScript types such as DOM objects or
|
||||
> special Electron objects is deprecated, and will begin throwing an exception
|
||||
> starting with Electron 9.
|
||||
> special Electron objects will throw an exception.
|
||||
|
||||
The renderer process can handle the message by listening to `channel` with the
|
||||
[`ipcRenderer`](ipc-renderer.md) module.
|
||||
@@ -1621,7 +1630,9 @@ app.whenReady().then(() => {
|
||||
|
||||
#### `contents.sendToFrame(frameId, channel, ...args)`
|
||||
|
||||
* `frameId` Integer
|
||||
* `frameId` Integer | [number, number] - the ID of the frame to send to, or a
|
||||
pair of `[processId, frameId]` if the frame is in a different process to the
|
||||
main frame.
|
||||
* `channel` String
|
||||
* `...args` any[]
|
||||
|
||||
@@ -1631,9 +1642,8 @@ Send an asynchronous message to a specific frame in a renderer process via
|
||||
chains will not be included. Sending Functions, Promises, Symbols, WeakMaps, or
|
||||
WeakSets will throw an exception.
|
||||
|
||||
> **NOTE**: Sending non-standard JavaScript types such as DOM objects or
|
||||
> special Electron objects is deprecated, and will begin throwing an exception
|
||||
> starting with Electron 9.
|
||||
> **NOTE:** Sending non-standard JavaScript types such as DOM objects or
|
||||
> special Electron objects will throw an exception.
|
||||
|
||||
The renderer process can handle the message by listening to `channel` with the
|
||||
[`ipcRenderer`](ipc-renderer.md) module.
|
||||
@@ -1795,7 +1805,7 @@ Returns `Boolean` - If *offscreen rendering* is enabled returns whether it is cu
|
||||
* `fps` Integer
|
||||
|
||||
If *offscreen rendering* is enabled sets the frame rate to the specified number.
|
||||
Only values between 1 and 60 are accepted.
|
||||
Only values between 1 and 240 are accepted.
|
||||
|
||||
#### `contents.getFrameRate()`
|
||||
|
||||
@@ -1893,7 +1903,7 @@ The zoom factor is the zoom percent divided by 100, so 300% = 3.0.
|
||||
#### `contents.frameRate`
|
||||
|
||||
An `Integer` property that sets the frame rate of the web contents to the specified number.
|
||||
Only values between 1 and 60 are accepted.
|
||||
Only values between 1 and 240 are accepted.
|
||||
|
||||
Only applicable if *offscreen rendering* is enabled.
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
Electron's `webview` tag is based on [Chromium's `webview`][chrome-webview], which
|
||||
is undergoing dramatic architectural changes. This impacts the stability of `webviews`,
|
||||
including rendering, navigation, and event routing. We currently recommend to not
|
||||
use the `webview` tag and to consider alternatives, like `iframe`, Electron's `BrowserView`,
|
||||
use the `webview` tag and to consider alternatives, like `iframe`, [Electron's `BrowserView`](browser-view.md),
|
||||
or an architecture that avoids embedded content altogether.
|
||||
|
||||
## Enabling
|
||||
@@ -137,7 +137,7 @@ This option is disabled by default in the guest page.
|
||||
```
|
||||
|
||||
A `Boolean`. When this attribute is `false` the guest page in `webview` will not have access
|
||||
to the [`remote`](remote.md) module. The remote module is available by default.
|
||||
to the [`remote`](remote.md) module. The remote module is unavailable by default.
|
||||
|
||||
### `plugins`
|
||||
|
||||
@@ -515,8 +515,7 @@ Inserts `text` to the focused element.
|
||||
* `text` String - Content to be searched, must not be empty.
|
||||
* `options` Object (optional)
|
||||
* `forward` Boolean (optional) - Whether to search forward or backward, defaults to `true`.
|
||||
* `findNext` Boolean (optional) - Whether the operation is first request or a follow up,
|
||||
defaults to `false`.
|
||||
* `findNext` Boolean (optional) - Whether to begin a new text finding session with this request. Should be `true` for initial requests, and `false` for follow-up requests. Defaults to `false`.
|
||||
* `matchCase` Boolean (optional) - Whether search should be case-sensitive,
|
||||
defaults to `false`.
|
||||
* `wordStart` Boolean (optional) - Whether to look only at the start of words.
|
||||
@@ -968,4 +967,4 @@ Emitted when DevTools is closed.
|
||||
Emitted when DevTools is focused / opened.
|
||||
|
||||
[runtime-enabled-features]: https://cs.chromium.org/chromium/src/third_party/blink/renderer/platform/runtime_enabled_features.json5?l=70
|
||||
[chrome-webview]: https://developer.chrome.com/apps/tags/webview
|
||||
[chrome-webview]: https://developer.chrome.com/docs/extensions/reference/webviewTag/
|
||||
|
||||
@@ -195,6 +195,45 @@ you should plan to update your native modules to be context aware.
|
||||
|
||||
For more detailed information see [#18397](https://github.com/electron/electron/issues/18397).
|
||||
|
||||
### Deprecated: `BrowserWindow` extension APIs
|
||||
|
||||
The following extension APIs have been deprecated:
|
||||
* `BrowserWindow.addExtension(path)`
|
||||
* `BrowserWindow.addDevToolsExtension(path)`
|
||||
* `BrowserWindow.removeExtension(name)`
|
||||
* `BrowserWindow.removeDevToolsExtension(name)`
|
||||
* `BrowserWindow.getExtensions()`
|
||||
* `BrowserWindow.getDevToolsExtensions()`
|
||||
|
||||
Use the session APIs instead:
|
||||
* `ses.loadExtension(path)`
|
||||
* `ses.removeExtension(extension_id)`
|
||||
* `ses.getAllExtensions()`
|
||||
|
||||
```js
|
||||
// Deprecated in Electron 9
|
||||
BrowserWindow.addExtension(path)
|
||||
BrowserWindow.addDevToolsExtension(path)
|
||||
// Replace with
|
||||
session.defaultSession.loadExtension(path)
|
||||
```
|
||||
|
||||
```js
|
||||
// Deprecated in Electron 9
|
||||
BrowserWindow.removeExtension(name)
|
||||
BrowserWindow.removeDevToolsExtension(name)
|
||||
// Replace with
|
||||
session.defaultSession.removeExtension(extension_id)
|
||||
```
|
||||
|
||||
```js
|
||||
// Deprecated in Electron 9
|
||||
BrowserWindow.getExtensions()
|
||||
BrowserWindow.getDevToolsExtensions()
|
||||
// Replace with
|
||||
session.defaultSession.getAllExtensions()
|
||||
```
|
||||
|
||||
### Removed: `<webview>.getWebContents()`
|
||||
|
||||
This API, which was deprecated in Electron 8.0, is now removed.
|
||||
@@ -338,6 +377,52 @@ in Electron 8.x, and cease to exist in Electron 9.x. The layout zoom level
|
||||
limits are now fixed at a minimum of 0.25 and a maximum of 5.0, as defined
|
||||
[here](https://chromium.googlesource.com/chromium/src/+/938b37a6d2886bf8335fc7db792f1eb46c65b2ae/third_party/blink/common/page/page_zoom.cc#11).
|
||||
|
||||
### Deprecated events in `systemPreferences`
|
||||
|
||||
The following `systemPreferences` events have been deprecated:
|
||||
* `inverted-color-scheme-changed`
|
||||
* `high-contrast-color-scheme-changed`
|
||||
|
||||
Use the new `updated` event on the `nativeTheme` module instead.
|
||||
|
||||
```js
|
||||
// Deprecated
|
||||
systemPreferences.on('inverted-color-scheme-changed', () => { /* ... */ })
|
||||
systemPreferences.on('high-contrast-color-scheme-changed', () => { /* ... */ })
|
||||
|
||||
// Replace with
|
||||
nativeTheme.on('updated', () => { /* ... */ })
|
||||
```
|
||||
|
||||
### Deprecated: methods in `systemPreferences`
|
||||
|
||||
The following `systemPreferences` methods have been deprecated:
|
||||
* `systemPreferences.isDarkMode()`
|
||||
* `systemPreferences.isInvertedColorScheme()`
|
||||
* `systemPreferences.isHighContrastColorScheme()`
|
||||
|
||||
Use the following `nativeTheme` properties instead:
|
||||
* `nativeTheme.shouldUseDarkColors`
|
||||
* `nativeTheme.shouldUseInvertedColorScheme`
|
||||
* `nativeTheme.shouldUseHighContrastColors`
|
||||
|
||||
```js
|
||||
// Deprecated
|
||||
systemPreferences.isDarkMode()
|
||||
// Replace with
|
||||
nativeTheme.shouldUseDarkColors
|
||||
|
||||
// Deprecated
|
||||
systemPreferences.isInvertedColorScheme()
|
||||
// Replace with
|
||||
nativeTheme.shouldUseInvertedColorScheme
|
||||
|
||||
// Deprecated
|
||||
systemPreferences.isHighContrastColorScheme()
|
||||
// Replace with
|
||||
nativeTheme.shouldUseHighContrastColors
|
||||
```
|
||||
|
||||
## Planned Breaking API Changes (7.0)
|
||||
|
||||
### Deprecated: Atom.io Node Headers URL
|
||||
@@ -434,6 +519,55 @@ Note that `webkitdirectory` no longer exposes the path to the selected folder.
|
||||
If you require the path to the selected folder rather than the folder contents,
|
||||
see the `dialog.showOpenDialog` API ([link](https://github.com/electron/electron/blob/master/docs/api/dialog.md#dialogshowopendialogbrowserwindow-options)).
|
||||
|
||||
### API Changed: Callback-based versions of promisified APIs
|
||||
|
||||
Electron 5 and Electron 6 introduced Promise-based versions of existing
|
||||
asynchronous APIs and deprecated their older, callback-based counterparts.
|
||||
In Electron 7, all deprecated callback-based APIs are now removed.
|
||||
|
||||
These functions now only return Promises:
|
||||
|
||||
* `app.getFileIcon()` [#15742](https://github.com/electron/electron/pull/15742)
|
||||
* `app.dock.show()` [#16904](https://github.com/electron/electron/pull/16904)
|
||||
* `contentTracing.getCategories()` [#16583](https://github.com/electron/electron/pull/16583)
|
||||
* `contentTracing.getTraceBufferUsage()` [#16600](https://github.com/electron/electron/pull/16600)
|
||||
* `contentTracing.startRecording()` [#16584](https://github.com/electron/electron/pull/16584)
|
||||
* `contentTracing.stopRecording()` [#16584](https://github.com/electron/electron/pull/16584)
|
||||
* `contents.executeJavaScript()` [#17312](https://github.com/electron/electron/pull/17312)
|
||||
* `cookies.flushStore()` [#16464](https://github.com/electron/electron/pull/16464)
|
||||
* `cookies.get()` [#16464](https://github.com/electron/electron/pull/16464)
|
||||
* `cookies.remove()` [#16464](https://github.com/electron/electron/pull/16464)
|
||||
* `cookies.set()` [#16464](https://github.com/electron/electron/pull/16464)
|
||||
* `debugger.sendCommand()` [#16861](https://github.com/electron/electron/pull/16861)
|
||||
* `dialog.showCertificateTrustDialog()` [#17181](https://github.com/electron/electron/pull/17181)
|
||||
* `inAppPurchase.getProducts()` [#17355](https://github.com/electron/electron/pull/17355)
|
||||
* `inAppPurchase.purchaseProduct()`[#17355](https://github.com/electron/electron/pull/17355)
|
||||
* `netLog.stopLogging()` [#16862](https://github.com/electron/electron/pull/16862)
|
||||
* `session.clearAuthCache()` [#17259](https://github.com/electron/electron/pull/17259)
|
||||
* `session.clearCache()` [#17185](https://github.com/electron/electron/pull/17185)
|
||||
* `session.clearHostResolverCache()` [#17229](https://github.com/electron/electron/pull/17229)
|
||||
* `session.clearStorageData()` [#17249](https://github.com/electron/electron/pull/17249)
|
||||
* `session.getBlobData()` [#17303](https://github.com/electron/electron/pull/17303)
|
||||
* `session.getCacheSize()` [#17185](https://github.com/electron/electron/pull/17185)
|
||||
* `session.resolveProxy()` [#17222](https://github.com/electron/electron/pull/17222)
|
||||
* `session.setProxy()` [#17222](https://github.com/electron/electron/pull/17222)
|
||||
* `shell.openExternal()` [#16176](https://github.com/electron/electron/pull/16176)
|
||||
* `webContents.loadFile()` [#15855](https://github.com/electron/electron/pull/15855)
|
||||
* `webContents.loadURL()` [#15855](https://github.com/electron/electron/pull/15855)
|
||||
* `webContents.hasServiceWorker()` [#16535](https://github.com/electron/electron/pull/16535)
|
||||
* `webContents.printToPDF()` [#16795](https://github.com/electron/electron/pull/16795)
|
||||
* `webContents.savePage()` [#16742](https://github.com/electron/electron/pull/16742)
|
||||
* `webFrame.executeJavaScript()` [#17312](https://github.com/electron/electron/pull/17312)
|
||||
* `webFrame.executeJavaScriptInIsolatedWorld()` [#17312](https://github.com/electron/electron/pull/17312)
|
||||
* `webviewTag.executeJavaScript()` [#17312](https://github.com/electron/electron/pull/17312)
|
||||
* `win.capturePage()` [#15743](https://github.com/electron/electron/pull/15743)
|
||||
|
||||
These functions now have two forms, synchronous and Promise-based asynchronous:
|
||||
|
||||
* `dialog.showMessageBox()`/`dialog.showMessageBoxSync()` [#17298](https://github.com/electron/electron/pull/17298)
|
||||
* `dialog.showOpenDialog()`/`dialog.showOpenDialogSync()` [#16973](https://github.com/electron/electron/pull/16973)
|
||||
* `dialog.showSaveDialog()`/`dialog.showSaveDialogSync()` [#17054](https://github.com/electron/electron/pull/17054)
|
||||
|
||||
## Planned Breaking API Changes (6.0)
|
||||
|
||||
### API Changed: `win.setMenu(null)` is now `win.removeMenu()`
|
||||
@@ -445,19 +579,6 @@ win.setMenu(null)
|
||||
win.removeMenu()
|
||||
```
|
||||
|
||||
### API Changed: `contentTracing.getTraceBufferUsage()` is now a promise
|
||||
|
||||
```js
|
||||
// Deprecated
|
||||
contentTracing.getTraceBufferUsage((percentage, value) => {
|
||||
// do something
|
||||
})
|
||||
// Replace with
|
||||
contentTracing.getTraceBufferUsage().then(infoObject => {
|
||||
// infoObject has percentage and value fields
|
||||
})
|
||||
```
|
||||
|
||||
### API Changed: `electron.screen` in the renderer process should be accessed via `remote`
|
||||
|
||||
```js
|
||||
@@ -594,6 +715,31 @@ webFrame.setSpellCheckProvider('en-US', {
|
||||
})
|
||||
```
|
||||
|
||||
### API Changed: `webContents.getZoomLevel` and `webContents.getZoomFactor` are now synchronous
|
||||
|
||||
`webContents.getZoomLevel` and `webContents.getZoomFactor` no longer take callback parameters,
|
||||
instead directly returning their number values.
|
||||
|
||||
```js
|
||||
// Deprecated
|
||||
webContents.getZoomLevel((level) => {
|
||||
console.log(level)
|
||||
})
|
||||
// Replace with
|
||||
const level = webContents.getZoomLevel()
|
||||
console.log(level)
|
||||
```
|
||||
|
||||
```js
|
||||
// Deprecated
|
||||
webContents.getZoomFactor((factor) => {
|
||||
console.log(factor)
|
||||
})
|
||||
// Replace with
|
||||
const factor = webContents.getZoomFactor()
|
||||
console.log(factor)
|
||||
```
|
||||
|
||||
## Planned Breaking API Changes (4.0)
|
||||
|
||||
The following list includes the breaking API changes made in Electron 4.0.
|
||||
|
||||
@@ -42,7 +42,7 @@ $ pip install pyobjc
|
||||
If you're developing Electron and don't plan to redistribute your
|
||||
custom Electron build, you may skip this section.
|
||||
|
||||
Official Electron builds are built with [Xcode 9.4.1](http://adcdownload.apple.com/Developer_Tools/Xcode_9.4.1/Xcode_9.4.1.xip), and the macOS 10.13 SDK. Building with a newer SDK works too, but the releases currently use the 10.13 SDK.
|
||||
Official Electron builds are built with [Xcode 12.2](https://download.developer.apple.com/Developer_Tools/Xcode_12.2/Xcode_12.2.xip), and the macOS 11.0 SDK. Building with a newer SDK works too, but the releases currently use the 11.0 SDK.
|
||||
|
||||
## Building Electron
|
||||
|
||||
|
||||
@@ -69,8 +69,7 @@ way of figuring out which is which.
|
||||
### Which Process Should I Attach to?
|
||||
|
||||
Code executed within the main process (that is, code found in or eventually run
|
||||
by your main JavaScript file) as well as code called using the remote
|
||||
(`require('electron').remote`) will run inside the main process, while other
|
||||
by your main JavaScript file) will run inside the main process, while other
|
||||
code will execute inside its respective renderer process.
|
||||
|
||||
You can be attached to multiple programs when you are debugging, but only one
|
||||
|
||||
18
docs/fiddles/features/drag-and-drop/index.html
Normal file
18
docs/fiddles/features/drag-and-drop/index.html
Normal file
@@ -0,0 +1,18 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Hello World!</title>
|
||||
<meta http-equiv="Content-Security-Policy" content="script-src 'self' 'unsafe-inline';" />
|
||||
</head>
|
||||
<body>
|
||||
<h1>Hello World!</h1>
|
||||
<p>
|
||||
We are using node <script>document.write(process.versions.node)</script>,
|
||||
Chrome <script>document.write(process.versions.chrome)</script>,
|
||||
and Electron <script>document.write(process.versions.electron)</script>.
|
||||
</p>
|
||||
<a href="#" id="drag">Drag me</a>
|
||||
<script src="renderer.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
41
docs/fiddles/features/drag-and-drop/main.js
Normal file
41
docs/fiddles/features/drag-and-drop/main.js
Normal file
@@ -0,0 +1,41 @@
|
||||
const { app, BrowserWindow, ipcMain, nativeImage, NativeImage } = require('electron')
|
||||
const fs = require('fs');
|
||||
const http = require('http');
|
||||
|
||||
function createWindow () {
|
||||
const win = new BrowserWindow({
|
||||
width: 800,
|
||||
height: 600,
|
||||
webPreferences: {
|
||||
nodeIntegration: true
|
||||
}
|
||||
})
|
||||
|
||||
win.loadFile('index.html')
|
||||
}
|
||||
const iconName = 'iconForDragAndDrop.png';
|
||||
const icon = fs.createWriteStream(`${process.cwd()}/${iconName}`);
|
||||
http.get('http://img.icons8.com/ios/452/drag-and-drop.png', (response) => {
|
||||
response.pipe(icon);
|
||||
});
|
||||
|
||||
app.whenReady().then(createWindow)
|
||||
|
||||
ipcMain.on('ondragstart', (event, filePath) => {
|
||||
event.sender.startDrag({
|
||||
file: filePath,
|
||||
icon: `${process.cwd()}/${iconName}`
|
||||
})
|
||||
})
|
||||
|
||||
app.on('window-all-closed', () => {
|
||||
if (process.platform !== 'darwin') {
|
||||
app.quit()
|
||||
}
|
||||
})
|
||||
|
||||
app.on('activate', () => {
|
||||
if (BrowserWindow.getAllWindows().length === 0) {
|
||||
createWindow()
|
||||
}
|
||||
})
|
||||
9
docs/fiddles/features/drag-and-drop/renderer.js
Normal file
9
docs/fiddles/features/drag-and-drop/renderer.js
Normal file
@@ -0,0 +1,9 @@
|
||||
const { ipcRenderer } = require('electron')
|
||||
const fs = require('fs')
|
||||
|
||||
document.getElementById('drag').ondragstart = (event) => {
|
||||
const fileName = 'drag-and-drop.md'
|
||||
fs.writeFileSync(fileName, '# Test drag and drop');
|
||||
event.preventDefault()
|
||||
ipcRenderer.send('ondragstart', process.cwd() + `/${fileName}`)
|
||||
}
|
||||
16
docs/fiddles/features/keyboard-shortcuts/global/index.html
Normal file
16
docs/fiddles/features/keyboard-shortcuts/global/index.html
Normal file
@@ -0,0 +1,16 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Hello World!</title>
|
||||
<meta http-equiv="Content-Security-Policy" content="script-src 'self' 'unsafe-inline';" />
|
||||
</head>
|
||||
<body>
|
||||
<h1>Hello World!</h1>
|
||||
<p>
|
||||
We are using node <script>document.write(process.versions.node)</script>,
|
||||
Chrome <script>document.write(process.versions.chrome)</script>,
|
||||
and Electron <script>document.write(process.versions.electron)</script>.
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
31
docs/fiddles/features/keyboard-shortcuts/global/main.js
Normal file
31
docs/fiddles/features/keyboard-shortcuts/global/main.js
Normal file
@@ -0,0 +1,31 @@
|
||||
const { app, BrowserWindow, globalShortcut } = require('electron')
|
||||
|
||||
function createWindow () {
|
||||
const win = new BrowserWindow({
|
||||
width: 800,
|
||||
height: 600,
|
||||
webPreferences: {
|
||||
nodeIntegration: true
|
||||
}
|
||||
})
|
||||
|
||||
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()
|
||||
}
|
||||
})
|
||||
@@ -0,0 +1,14 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Hello World!</title>
|
||||
<meta http-equiv="Content-Security-Policy" content="script-src 'self' 'unsafe-inline';" />
|
||||
</head>
|
||||
<body>
|
||||
<h1>Hello World!</h1>
|
||||
We are using node <script>document.write(process.versions.node)</script>,
|
||||
Chrome <script>document.write(process.versions.chrome)</script>,
|
||||
and Electron <script>document.write(process.versions.electron)</script>.
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,13 @@
|
||||
const { app, BrowserWindow } = require('electron')
|
||||
|
||||
app.whenReady().then(() => {
|
||||
const win = new BrowserWindow({ width: 800, height: 600, webPreferences: { nodeIntegration: true } })
|
||||
|
||||
win.loadFile('index.html')
|
||||
win.webContents.on('before-input-event', (event, input) => {
|
||||
if (input.control && input.key.toLowerCase() === 'i') {
|
||||
console.log('Pressed Control+I')
|
||||
event.preventDefault()
|
||||
}
|
||||
})
|
||||
})
|
||||
16
docs/fiddles/features/keyboard-shortcuts/local/index.html
Normal file
16
docs/fiddles/features/keyboard-shortcuts/local/index.html
Normal file
@@ -0,0 +1,16 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Hello World!</title>
|
||||
<meta http-equiv="Content-Security-Policy" content="script-src 'self' 'unsafe-inline';" />
|
||||
</head>
|
||||
<body>
|
||||
<h1>Hello World!</h1>
|
||||
<p>
|
||||
We are using node <script>document.write(process.versions.node)</script>,
|
||||
Chrome <script>document.write(process.versions.chrome)</script>,
|
||||
and Electron <script>document.write(process.versions.electron)</script>.
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
39
docs/fiddles/features/keyboard-shortcuts/local/main.js
Normal file
39
docs/fiddles/features/keyboard-shortcuts/local/main.js
Normal file
@@ -0,0 +1,39 @@
|
||||
const { app, BrowserWindow, Menu, MenuItem } = require('electron')
|
||||
|
||||
function createWindow () {
|
||||
const win = new BrowserWindow({
|
||||
width: 800,
|
||||
height: 600,
|
||||
webPreferences: {
|
||||
nodeIntegration: true
|
||||
}
|
||||
})
|
||||
|
||||
win.loadFile('index.html')
|
||||
}
|
||||
|
||||
const menu = new Menu()
|
||||
menu.append(new MenuItem({
|
||||
label: 'Electron',
|
||||
submenu: [{
|
||||
role: 'help',
|
||||
accelerator: process.platform === 'darwin' ? 'Alt+Cmd+I' : 'Alt+Shift+I',
|
||||
click: () => { console.log('Electron rocks!') }
|
||||
}]
|
||||
}))
|
||||
|
||||
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()
|
||||
}
|
||||
})
|
||||
19
docs/fiddles/features/macos-dark-mode/index.html
Normal file
19
docs/fiddles/features/macos-dark-mode/index.html
Normal file
@@ -0,0 +1,19 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Hello World!</title>
|
||||
<meta http-equiv="Content-Security-Policy" content="script-src 'self' 'unsafe-inline';" />
|
||||
<link rel="stylesheet" type="text/css" href="./styles.css">
|
||||
</head>
|
||||
<body>
|
||||
<h1>Hello World!</h1>
|
||||
<p>Current theme source: <strong id="theme-source">System</strong></p>
|
||||
|
||||
<button id="toggle-dark-mode">Toggle Dark Mode</button>
|
||||
<button id="reset-to-system">Reset to System Theme</button>
|
||||
|
||||
<script src="renderer.js"></script>
|
||||
</body>
|
||||
</body>
|
||||
</html>
|
||||
40
docs/fiddles/features/macos-dark-mode/main.js
Normal file
40
docs/fiddles/features/macos-dark-mode/main.js
Normal file
@@ -0,0 +1,40 @@
|
||||
const { app, BrowserWindow, ipcMain, nativeTheme } = require('electron')
|
||||
|
||||
function createWindow () {
|
||||
const win = new BrowserWindow({
|
||||
width: 800,
|
||||
height: 600,
|
||||
webPreferences: {
|
||||
nodeIntegration: true
|
||||
}
|
||||
})
|
||||
|
||||
win.loadFile('index.html')
|
||||
|
||||
ipcMain.handle('dark-mode:toggle', () => {
|
||||
if (nativeTheme.shouldUseDarkColors) {
|
||||
nativeTheme.themeSource = 'light'
|
||||
} else {
|
||||
nativeTheme.themeSource = 'dark'
|
||||
}
|
||||
return nativeTheme.shouldUseDarkColors
|
||||
})
|
||||
|
||||
ipcMain.handle('dark-mode:system', () => {
|
||||
nativeTheme.themeSouce = 'system'
|
||||
})
|
||||
}
|
||||
|
||||
app.whenReady().then(createWindow)
|
||||
|
||||
app.on('window-all-closed', () => {
|
||||
if (process.platform !== 'darwin') {
|
||||
app.quit()
|
||||
}
|
||||
})
|
||||
|
||||
app.on('activate', () => {
|
||||
if (BrowserWindow.getAllWindows().length === 0) {
|
||||
createWindow()
|
||||
}
|
||||
})
|
||||
11
docs/fiddles/features/macos-dark-mode/renderer.js
Normal file
11
docs/fiddles/features/macos-dark-mode/renderer.js
Normal file
@@ -0,0 +1,11 @@
|
||||
const { ipcRenderer } = require('electron')
|
||||
|
||||
document.getElementById('toggle-dark-mode').addEventListener('click', async () => {
|
||||
const isDarkMode = await ipcRenderer.invoke('dark-mode:toggle')
|
||||
document.getElementById('theme-source').innerHTML = isDarkMode ? 'Dark' : 'Light'
|
||||
})
|
||||
|
||||
document.getElementById('reset-to-system').addEventListener('click', async () => {
|
||||
await ipcRenderer.invoke('dark-mode:system')
|
||||
document.getElementById('theme-source').innerHTML = 'System'
|
||||
})
|
||||
7
docs/fiddles/features/macos-dark-mode/styles.css
Normal file
7
docs/fiddles/features/macos-dark-mode/styles.css
Normal file
@@ -0,0 +1,7 @@
|
||||
@media (prefers-color-scheme: dark) {
|
||||
body { background: #333; color: white; }
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: light) {
|
||||
body { background: #ddd; color: black; }
|
||||
}
|
||||
16
docs/fiddles/features/macos-dock-menu/index.html
Normal file
16
docs/fiddles/features/macos-dock-menu/index.html
Normal file
@@ -0,0 +1,16 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Hello World!</title>
|
||||
<meta http-equiv="Content-Security-Policy" content="script-src 'self' 'unsafe-inline';" />
|
||||
</head>
|
||||
<body>
|
||||
<h1>Hello World!</h1>
|
||||
<p>
|
||||
We are using node <script>document.write(process.versions.node)</script>,
|
||||
Chrome <script>document.write(process.versions.chrome)</script>,
|
||||
and Electron <script>document.write(process.versions.electron)</script>.
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
43
docs/fiddles/features/macos-dock-menu/main.js
Normal file
43
docs/fiddles/features/macos-dock-menu/main.js
Normal file
@@ -0,0 +1,43 @@
|
||||
const { app, BrowserWindow, Menu } = require('electron')
|
||||
|
||||
function createWindow () {
|
||||
const win = new BrowserWindow({
|
||||
width: 800,
|
||||
height: 600,
|
||||
webPreferences: {
|
||||
nodeIntegration: true
|
||||
}
|
||||
})
|
||||
|
||||
win.loadFile('index.html')
|
||||
}
|
||||
|
||||
const dockMenu = Menu.buildFromTemplate([
|
||||
{
|
||||
label: 'New Window',
|
||||
click () { console.log('New Window') }
|
||||
}, {
|
||||
label: 'New Window with Settings',
|
||||
submenu: [
|
||||
{ label: 'Basic' },
|
||||
{ label: 'Pro' }
|
||||
]
|
||||
},
|
||||
{ label: 'New Command...' }
|
||||
])
|
||||
|
||||
app.whenReady().then(() => {
|
||||
app.dock.setMenu(dockMenu)
|
||||
}).then(createWindow)
|
||||
|
||||
app.on('window-all-closed', () => {
|
||||
if (process.platform !== 'darwin') {
|
||||
app.quit()
|
||||
}
|
||||
})
|
||||
|
||||
app.on('activate', () => {
|
||||
if (BrowserWindow.getAllWindows().length === 0) {
|
||||
createWindow()
|
||||
}
|
||||
})
|
||||
16
docs/fiddles/features/notifications/main/index.html
Normal file
16
docs/fiddles/features/notifications/main/index.html
Normal file
@@ -0,0 +1,16 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Hello World!</title>
|
||||
<meta http-equiv="Content-Security-Policy" content="script-src 'self' 'unsafe-inline';" />
|
||||
</head>
|
||||
<body>
|
||||
<h1>Hello World!</h1>
|
||||
<p>
|
||||
We are using node <script>document.write(process.versions.node)</script>,
|
||||
Chrome <script>document.write(process.versions.chrome)</script>,
|
||||
and Electron <script>document.write(process.versions.electron)</script>.
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
35
docs/fiddles/features/notifications/main/main.js
Normal file
35
docs/fiddles/features/notifications/main/main.js
Normal file
@@ -0,0 +1,35 @@
|
||||
const { app, BrowserWindow, Notification } = require('electron')
|
||||
|
||||
function createWindow () {
|
||||
const win = new BrowserWindow({
|
||||
width: 800,
|
||||
height: 600,
|
||||
webPreferences: {
|
||||
nodeIntegration: true
|
||||
}
|
||||
})
|
||||
|
||||
win.loadFile('index.html')
|
||||
}
|
||||
|
||||
function showNotification () {
|
||||
const notification = {
|
||||
title: 'Basic Notification',
|
||||
body: 'Notification from the Main process'
|
||||
}
|
||||
new Notification(notification).show()
|
||||
}
|
||||
|
||||
app.whenReady().then(createWindow).then(showNotification)
|
||||
|
||||
app.on('window-all-closed', () => {
|
||||
if (process.platform !== 'darwin') {
|
||||
app.quit()
|
||||
}
|
||||
})
|
||||
|
||||
app.on('activate', () => {
|
||||
if (BrowserWindow.getAllWindows().length === 0) {
|
||||
createWindow()
|
||||
}
|
||||
})
|
||||
17
docs/fiddles/features/notifications/renderer/index.html
Normal file
17
docs/fiddles/features/notifications/renderer/index.html
Normal file
@@ -0,0 +1,17 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Hello World!</title>
|
||||
<meta http-equiv="Content-Security-Policy" content="script-src 'self' 'unsafe-inline';" />
|
||||
</head>
|
||||
<body>
|
||||
<h1>Hello World!</h1>
|
||||
<p>
|
||||
We are using node <script>document.write(process.versions.node)</script>,
|
||||
Chrome <script>document.write(process.versions.chrome)</script>,
|
||||
and Electron <script>document.write(process.versions.electron)</script>.
|
||||
</p>
|
||||
<script src="renderer.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
27
docs/fiddles/features/notifications/renderer/main.js
Normal file
27
docs/fiddles/features/notifications/renderer/main.js
Normal file
@@ -0,0 +1,27 @@
|
||||
const { app, BrowserWindow } = require('electron')
|
||||
|
||||
function createWindow () {
|
||||
const win = new BrowserWindow({
|
||||
width: 800,
|
||||
height: 600,
|
||||
webPreferences: {
|
||||
nodeIntegration: true
|
||||
}
|
||||
})
|
||||
|
||||
win.loadFile('index.html')
|
||||
}
|
||||
|
||||
app.whenReady().then(createWindow)
|
||||
|
||||
app.on('window-all-closed', () => {
|
||||
if (process.platform !== 'darwin') {
|
||||
app.quit()
|
||||
}
|
||||
})
|
||||
|
||||
app.on('activate', () => {
|
||||
if (BrowserWindow.getAllWindows().length === 0) {
|
||||
createWindow()
|
||||
}
|
||||
})
|
||||
7
docs/fiddles/features/notifications/renderer/renderer.js
Normal file
7
docs/fiddles/features/notifications/renderer/renderer.js
Normal file
@@ -0,0 +1,7 @@
|
||||
const myNotification = new Notification('Title', {
|
||||
body: 'Notification from the Renderer process'
|
||||
})
|
||||
|
||||
myNotification.onclick = () => {
|
||||
console.log('Notification clicked')
|
||||
}
|
||||
15
docs/fiddles/features/offscreen-rendering/index.html
Normal file
15
docs/fiddles/features/offscreen-rendering/index.html
Normal file
@@ -0,0 +1,15 @@
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Hello World!</title>
|
||||
<meta http-equiv="Content-Security-Policy" content="script-src 'self' 'unsafe-inline';" />
|
||||
</head>
|
||||
<body>
|
||||
<h1>Hello World!</h1>
|
||||
<p>
|
||||
We are using node <script>document.write(process.versions.node)</script>,
|
||||
Chrome <script>document.write(process.versions.chrome)</script>,
|
||||
and Electron <script>document.write(process.versions.electron)</script>.
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
28
docs/fiddles/features/offscreen-rendering/main.js
Normal file
28
docs/fiddles/features/offscreen-rendering/main.js
Normal file
@@ -0,0 +1,28 @@
|
||||
const { app, BrowserWindow } = require('electron')
|
||||
const fs = require('fs')
|
||||
|
||||
app.disableHardwareAcceleration()
|
||||
|
||||
let win
|
||||
|
||||
app.whenReady().then(() => {
|
||||
win = new BrowserWindow({ webPreferences: { offscreen: true } })
|
||||
win.loadURL('https://github.com')
|
||||
win.webContents.on('paint', (event, dirty, image) => {
|
||||
fs.writeFileSync('ex.png', image.toPNG())
|
||||
})
|
||||
win.webContents.setFrameRate(60)
|
||||
console.log(`The screenshot has been successfully saved to ${process.cwd()}/ex.png`)
|
||||
})
|
||||
|
||||
app.on('window-all-closed', () => {
|
||||
if (process.platform !== 'darwin') {
|
||||
app.quit()
|
||||
}
|
||||
})
|
||||
|
||||
app.on('activate', () => {
|
||||
if (BrowserWindow.getAllWindows().length === 0) {
|
||||
createWindow()
|
||||
}
|
||||
})
|
||||
17
docs/fiddles/features/online-detection/main/index.html
Normal file
17
docs/fiddles/features/online-detection/main/index.html
Normal file
@@ -0,0 +1,17 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Hello World!</title>
|
||||
<meta http-equiv="Content-Security-Policy" content="script-src 'self' 'unsafe-inline';" />
|
||||
</head>
|
||||
<body>
|
||||
<h1>Hello World!</h1>
|
||||
<p>
|
||||
We are using node <script>document.write(process.versions.node)</script>,
|
||||
Chrome <script>document.write(process.versions.chrome)</script>,
|
||||
and Electron <script>document.write(process.versions.electron)</script>.
|
||||
</p>
|
||||
<script src="renderer.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
24
docs/fiddles/features/online-detection/main/main.js
Normal file
24
docs/fiddles/features/online-detection/main/main.js
Normal file
@@ -0,0 +1,24 @@
|
||||
const { app, BrowserWindow, ipcMain } = require('electron')
|
||||
|
||||
let onlineStatusWindow
|
||||
|
||||
app.whenReady().then(() => {
|
||||
onlineStatusWindow = new BrowserWindow({ width: 0, height: 0, show: false, webPreferences: { nodeIntegration: true } })
|
||||
onlineStatusWindow.loadURL(`file://${__dirname}/index.html`)
|
||||
})
|
||||
|
||||
ipcMain.on('online-status-changed', (event, status) => {
|
||||
console.log(status)
|
||||
})
|
||||
|
||||
app.on('window-all-closed', () => {
|
||||
if (process.platform !== 'darwin') {
|
||||
app.quit()
|
||||
}
|
||||
})
|
||||
|
||||
app.on('activate', () => {
|
||||
if (BrowserWindow.getAllWindows().length === 0) {
|
||||
createWindow()
|
||||
}
|
||||
})
|
||||
7
docs/fiddles/features/online-detection/main/renderer.js
Normal file
7
docs/fiddles/features/online-detection/main/renderer.js
Normal file
@@ -0,0 +1,7 @@
|
||||
const { ipcRenderer } = require('electron')
|
||||
const updateOnlineStatus = () => { ipcRenderer.send('online-status-changed', navigator.onLine ? 'online' : 'offline') }
|
||||
|
||||
window.addEventListener('online', updateOnlineStatus)
|
||||
window.addEventListener('offline', updateOnlineStatus)
|
||||
|
||||
updateOnlineStatus()
|
||||
17
docs/fiddles/features/online-detection/renderer/index.html
Normal file
17
docs/fiddles/features/online-detection/renderer/index.html
Normal file
@@ -0,0 +1,17 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Hello World!</title>
|
||||
<meta http-equiv="Content-Security-Policy" content="script-src 'self' 'unsafe-inline';" />
|
||||
</head>
|
||||
<body>
|
||||
<h1>Hello World!</h1>
|
||||
<p>
|
||||
We are using node <script>document.write(process.versions.node)</script>,
|
||||
Chrome <script>document.write(process.versions.chrome)</script>,
|
||||
and Electron <script>document.write(process.versions.electron)</script>.
|
||||
</p>
|
||||
<script src="renderer.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
20
docs/fiddles/features/online-detection/renderer/main.js
Normal file
20
docs/fiddles/features/online-detection/renderer/main.js
Normal file
@@ -0,0 +1,20 @@
|
||||
const { app, BrowserWindow } = require('electron')
|
||||
|
||||
let onlineStatusWindow
|
||||
|
||||
app.whenReady().then(() => {
|
||||
onlineStatusWindow = new BrowserWindow({ width: 0, height: 0, show: false })
|
||||
onlineStatusWindow.loadURL(`file://${__dirname}/index.html`)
|
||||
})
|
||||
|
||||
app.on('window-all-closed', () => {
|
||||
if (process.platform !== 'darwin') {
|
||||
app.quit()
|
||||
}
|
||||
})
|
||||
|
||||
app.on('activate', () => {
|
||||
if (BrowserWindow.getAllWindows().length === 0) {
|
||||
createWindow()
|
||||
}
|
||||
})
|
||||
@@ -0,0 +1,6 @@
|
||||
const alertOnlineStatus = () => { window.alert(navigator.onLine ? 'online' : 'offline') }
|
||||
|
||||
window.addEventListener('online', alertOnlineStatus)
|
||||
window.addEventListener('offline', alertOnlineStatus)
|
||||
|
||||
alertOnlineStatus()
|
||||
16
docs/fiddles/features/progress-bar/index.html
Normal file
16
docs/fiddles/features/progress-bar/index.html
Normal file
@@ -0,0 +1,16 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Hello World!</title>
|
||||
<meta http-equiv="Content-Security-Policy" content="script-src 'self' 'unsafe-inline';" />
|
||||
</head>
|
||||
<body>
|
||||
<h1>Hello World!</h1>
|
||||
<p>
|
||||
We are using node <script>document.write(process.versions.node)</script>,
|
||||
Chrome <script>document.write(process.versions.chrome)</script>,
|
||||
and Electron <script>document.write(process.versions.electron)</script>.
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
30
docs/fiddles/features/progress-bar/main.js
Normal file
30
docs/fiddles/features/progress-bar/main.js
Normal file
@@ -0,0 +1,30 @@
|
||||
const { app, BrowserWindow } = require('electron')
|
||||
|
||||
function createWindow () {
|
||||
const win = new BrowserWindow({
|
||||
width: 800,
|
||||
height: 600,
|
||||
webPreferences: {
|
||||
nodeIntegration: true
|
||||
}
|
||||
})
|
||||
|
||||
win.loadFile('index.html')
|
||||
win.setProgressBar(0.5)
|
||||
}
|
||||
|
||||
|
||||
app.whenReady().then(createWindow)
|
||||
|
||||
|
||||
app.on('window-all-closed', () => {
|
||||
if (process.platform !== 'darwin') {
|
||||
app.quit()
|
||||
}
|
||||
})
|
||||
|
||||
app.on('activate', () => {
|
||||
if (BrowserWindow.getAllWindows().length === 0) {
|
||||
createWindow()
|
||||
}
|
||||
})
|
||||
16
docs/fiddles/features/recent-documents/index.html
Normal file
16
docs/fiddles/features/recent-documents/index.html
Normal file
@@ -0,0 +1,16 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Hello World!</title>
|
||||
<meta http-equiv="Content-Security-Policy" content="script-src 'self' 'unsafe-inline';" />
|
||||
</head>
|
||||
<body>
|
||||
<h1>Hello World!</h1>
|
||||
<p>
|
||||
We are using node <script>document.write(process.versions.node)</script>,
|
||||
Chrome <script>document.write(process.versions.chrome)</script>,
|
||||
and Electron <script>document.write(process.versions.electron)</script>.
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
34
docs/fiddles/features/recent-documents/main.js
Normal file
34
docs/fiddles/features/recent-documents/main.js
Normal file
@@ -0,0 +1,34 @@
|
||||
const { app, BrowserWindow } = require('electron')
|
||||
const fs = require('fs')
|
||||
const path = require('path')
|
||||
|
||||
function createWindow () {
|
||||
const win = new BrowserWindow({
|
||||
width: 800,
|
||||
height: 600,
|
||||
webPreferences: {
|
||||
nodeIntegration: true
|
||||
}
|
||||
})
|
||||
|
||||
win.loadFile('index.html')
|
||||
}
|
||||
const fileName = 'recently-used.md'
|
||||
fs.writeFile(fileName, 'Lorem Ipsum', () => {
|
||||
app.addRecentDocument(path.join(process.cwd(), `${fileName}`))
|
||||
})
|
||||
|
||||
app.whenReady().then(createWindow)
|
||||
|
||||
app.on('window-all-closed', () => {
|
||||
app.clearRecentDocuments()
|
||||
if (process.platform !== 'darwin') {
|
||||
app.quit()
|
||||
}
|
||||
})
|
||||
|
||||
app.on('activate', () => {
|
||||
if (BrowserWindow.getAllWindows().length === 0) {
|
||||
createWindow()
|
||||
}
|
||||
})
|
||||
16
docs/fiddles/features/represented-file/index.html
Normal file
16
docs/fiddles/features/represented-file/index.html
Normal file
@@ -0,0 +1,16 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Hello World!</title>
|
||||
<meta http-equiv="Content-Security-Policy" content="script-src 'self' 'unsafe-inline';" />
|
||||
</head>
|
||||
<body>
|
||||
<h1>Hello World!</h1>
|
||||
<p>
|
||||
We are using node <script>document.write(process.versions.node)</script>,
|
||||
Chrome <script>document.write(process.versions.chrome)</script>,
|
||||
and Electron <script>document.write(process.versions.electron)</script>.
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
33
docs/fiddles/features/represented-file/main.js
Normal file
33
docs/fiddles/features/represented-file/main.js
Normal file
@@ -0,0 +1,33 @@
|
||||
const { app, BrowserWindow } = require('electron')
|
||||
const os = require('os');
|
||||
|
||||
function createWindow () {
|
||||
const win = new BrowserWindow({
|
||||
width: 800,
|
||||
height: 600,
|
||||
webPreferences: {
|
||||
nodeIntegration: true
|
||||
}
|
||||
})
|
||||
|
||||
win.loadFile('index.html')
|
||||
}
|
||||
|
||||
app.whenReady().then(() => {
|
||||
const win = new BrowserWindow()
|
||||
|
||||
win.setRepresentedFilename(os.homedir())
|
||||
win.setDocumentEdited(true)
|
||||
})
|
||||
|
||||
app.on('window-all-closed', () => {
|
||||
if (process.platform !== 'darwin') {
|
||||
app.quit()
|
||||
}
|
||||
})
|
||||
|
||||
app.on('activate', () => {
|
||||
if (BrowserWindow.getAllWindows().length === 0) {
|
||||
createWindow()
|
||||
}
|
||||
})
|
||||
@@ -1,7 +1,11 @@
|
||||
const { BrowserWindow, app } = require('electron')
|
||||
const { BrowserWindow, app, screen, ipcMain } = require('electron')
|
||||
|
||||
let mainWindow = null
|
||||
|
||||
ipcMain.handle('get-screen-size', () => {
|
||||
return screen.getPrimaryDisplay().workAreaSize
|
||||
})
|
||||
|
||||
function createWindow () {
|
||||
const windowOptions = {
|
||||
width: 600,
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
const { desktopCapturer } = require('electron')
|
||||
const { screen, shell } = require('electron').remote
|
||||
const { desktopCapturer, shell, ipcRenderer } = require('electron')
|
||||
|
||||
const fs = require('fs')
|
||||
const os = require('os')
|
||||
@@ -8,9 +7,9 @@ const path = require('path')
|
||||
const screenshot = document.getElementById('screen-shot')
|
||||
const screenshotMsg = document.getElementById('screenshot-path')
|
||||
|
||||
screenshot.addEventListener('click', (event) => {
|
||||
screenshot.addEventListener('click', async (event) => {
|
||||
screenshotMsg.textContent = 'Gathering screens...'
|
||||
const thumbSize = determineScreenShotSize()
|
||||
const thumbSize = await determineScreenShotSize()
|
||||
const options = { types: ['screen'], thumbnailSize: thumbSize }
|
||||
|
||||
desktopCapturer.getSources(options, (error, sources) => {
|
||||
@@ -33,8 +32,8 @@ screenshot.addEventListener('click', (event) => {
|
||||
})
|
||||
})
|
||||
|
||||
function determineScreenShotSize () {
|
||||
const screenSize = screen.getPrimaryDisplay().workAreaSize
|
||||
async function determineScreenShotSize () {
|
||||
const screenSize = await ipcRenderer.invoke('get-screen-size')
|
||||
const maxDimension = Math.max(screenSize.width, screenSize.height)
|
||||
return {
|
||||
width: maxDimension * window.devicePixelRatio,
|
||||
|
||||
16
docs/fiddles/quick-start/index.html
Normal file
16
docs/fiddles/quick-start/index.html
Normal file
@@ -0,0 +1,16 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Hello World!</title>
|
||||
<meta http-equiv="Content-Security-Policy" content="script-src 'self' 'unsafe-inline';" />
|
||||
</head>
|
||||
<body>
|
||||
<h1>Hello World!</h1>
|
||||
<p>
|
||||
We are using node <script>document.write(process.versions.node)</script>,
|
||||
Chrome <script>document.write(process.versions.chrome)</script>,
|
||||
and Electron <script>document.write(process.versions.electron)</script>.
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
27
docs/fiddles/quick-start/main.js
Normal file
27
docs/fiddles/quick-start/main.js
Normal file
@@ -0,0 +1,27 @@
|
||||
const { app, BrowserWindow } = require('electron')
|
||||
|
||||
function createWindow () {
|
||||
const win = new BrowserWindow({
|
||||
width: 800,
|
||||
height: 600,
|
||||
webPreferences: {
|
||||
nodeIntegration: true
|
||||
}
|
||||
})
|
||||
|
||||
win.loadFile('index.html')
|
||||
}
|
||||
|
||||
app.whenReady().then(createWindow)
|
||||
|
||||
app.on('window-all-closed', () => {
|
||||
if (process.platform !== 'darwin') {
|
||||
app.quit()
|
||||
}
|
||||
})
|
||||
|
||||
app.on('activate', () => {
|
||||
if (BrowserWindow.getAllWindows().length === 0) {
|
||||
createWindow()
|
||||
}
|
||||
})
|
||||
@@ -1,23 +1,20 @@
|
||||
const { app, BrowserWindow } = require('electron')
|
||||
const { app, BrowserWindow, ipcMain } = require('electron')
|
||||
|
||||
let mainWindow = null
|
||||
ipcMain.on('create-frameless-window', (event, {url}) => {
|
||||
const win = new BrowserWindow({ frame: false })
|
||||
win.loadURL(url)
|
||||
})
|
||||
|
||||
function createWindow () {
|
||||
const windowOptions = {
|
||||
const mainWindow = new BrowserWindow({
|
||||
width: 600,
|
||||
height: 400,
|
||||
title: 'Create a frameless window',
|
||||
webPreferences: {
|
||||
nodeIntegration: true
|
||||
}
|
||||
}
|
||||
|
||||
mainWindow = new BrowserWindow(windowOptions)
|
||||
mainWindow.loadFile('index.html')
|
||||
|
||||
mainWindow.on('closed', () => {
|
||||
mainWindow = null
|
||||
})
|
||||
mainWindow.loadFile('index.html')
|
||||
}
|
||||
|
||||
app.whenReady().then(() => {
|
||||
|
||||
@@ -1,12 +1,8 @@
|
||||
const { BrowserWindow } = require('electron').remote
|
||||
const { ipcRenderer } = require('electron')
|
||||
|
||||
const newWindowBtn = document.getElementById('frameless-window')
|
||||
|
||||
newWindowBtn.addEventListener('click', (event) => {
|
||||
let win = new BrowserWindow({ frame: false })
|
||||
|
||||
win.on('close', () => { win = null })
|
||||
|
||||
win.loadURL('data:text/html,<h2>Hello World!</h2><a id="close" href="javascript:window.close()">Close this Window</a>')
|
||||
win.show()
|
||||
newWindowBtn.addEventListener('click', () => {
|
||||
const url = 'data:text/html,<h2>Hello World!</h2><a id="close" href="javascript:window.close()">Close this Window</a>'
|
||||
ipcRenderer.send('create-frameless-window', { url })
|
||||
})
|
||||
|
||||
@@ -1,13 +1,14 @@
|
||||
// Modules to control application life and create native browser window
|
||||
const { app, BrowserWindow } = require('electron')
|
||||
|
||||
// Keep a global reference of the window object, if you don't, the window will
|
||||
// be closed automatically when the JavaScript object is garbage collected.
|
||||
let mainWindow
|
||||
ipcMain.on('create-frameless-window', (event, {url}) => {
|
||||
const win = new BrowserWindow({ frame: false })
|
||||
win.loadURL(url)
|
||||
})
|
||||
|
||||
function createWindow () {
|
||||
// Create the browser window.
|
||||
mainWindow = new BrowserWindow({
|
||||
const mainWindow = new BrowserWindow({
|
||||
width: 800,
|
||||
height: 600,
|
||||
webPreferences: {
|
||||
@@ -17,17 +18,6 @@ function createWindow () {
|
||||
|
||||
// and load the index.html of the app.
|
||||
mainWindow.loadFile('index.html')
|
||||
|
||||
// Open the DevTools.
|
||||
// mainWindow.webContents.openDevTools()
|
||||
|
||||
// Emitted when the window is closed.
|
||||
mainWindow.on('closed', function () {
|
||||
// Dereference the window object, usually you would store windows
|
||||
// in an array if your app supports multi windows, this is the time
|
||||
// when you should delete the corresponding element.
|
||||
mainWindow = null
|
||||
})
|
||||
}
|
||||
|
||||
// This method will be called when Electron has finished
|
||||
|
||||
@@ -1,25 +1,8 @@
|
||||
const { BrowserWindow } = require('electron').remote
|
||||
const shell = require('electron').shell
|
||||
const { ipcRenderer } = require('electron')
|
||||
|
||||
const framelessWindowBtn = document.getElementById('frameless-window')
|
||||
const newWindowBtn = document.getElementById('frameless-window')
|
||||
|
||||
const links = document.querySelectorAll('a[href]')
|
||||
|
||||
framelessWindowBtn.addEventListener('click', (event) => {
|
||||
const modalPath = 'https://electronjs.org'
|
||||
let win = new BrowserWindow({ frame: false })
|
||||
|
||||
win.on('close', () => { win = null })
|
||||
win.loadURL(modalPath)
|
||||
win.show()
|
||||
})
|
||||
|
||||
Array.prototype.forEach.call(links, (link) => {
|
||||
const url = link.getAttribute('href')
|
||||
if (url.indexOf('http') === 0) {
|
||||
link.addEventListener('click', (e) => {
|
||||
e.preventDefault()
|
||||
shell.openExternal(url)
|
||||
})
|
||||
}
|
||||
newWindowBtn.addEventListener('click', () => {
|
||||
const url = 'data:text/html,<h2>Hello World!</h2><a id="close" href="javascript:window.close()">Close this Window</a>'
|
||||
ipcRenderer.send('create-frameless-window', { url })
|
||||
})
|
||||
|
||||
@@ -1,9 +1,20 @@
|
||||
// Modules to control application life and create native browser window
|
||||
const { app, BrowserWindow } = require('electron')
|
||||
const { app, BrowserWindow, ipcMain } = require('electron')
|
||||
|
||||
// Keep a global reference of the window object, if you don't, the window will
|
||||
// be closed automatically when the JavaScript object is garbage collected.
|
||||
let mainWindow
|
||||
ipcMain.on('create-demo-window', (event) => {
|
||||
const win = new BrowserWindow({ width: 400, height: 275 })
|
||||
|
||||
function updateReply() {
|
||||
event.sender.send('bounds-changed', {
|
||||
size: win.getSize(),
|
||||
position: win.getPosition()
|
||||
})
|
||||
}
|
||||
|
||||
win.on('resize', updateReply)
|
||||
win.on('move', updateReply)
|
||||
win.loadURL('https://electronjs.org')
|
||||
})
|
||||
|
||||
function createWindow () {
|
||||
// Create the browser window.
|
||||
@@ -17,17 +28,6 @@ function createWindow () {
|
||||
|
||||
// and load the index.html of the app.
|
||||
mainWindow.loadFile('index.html')
|
||||
|
||||
// Open the DevTools.
|
||||
// mainWindow.webContents.openDevTools()
|
||||
|
||||
// Emitted when the window is closed.
|
||||
mainWindow.on('closed', function () {
|
||||
// Dereference the window object, usually you would store windows
|
||||
// in an array if your app supports multi windows, this is the time
|
||||
// when you should delete the corresponding element.
|
||||
mainWindow = null
|
||||
})
|
||||
}
|
||||
|
||||
// This method will be called when Electron has finished
|
||||
|
||||
@@ -1,27 +1,17 @@
|
||||
const { BrowserWindow } = require('electron').remote
|
||||
const shell = require('electron').shell
|
||||
const { shell, ipcRenderer } = require('electron')
|
||||
|
||||
const manageWindowBtn = document.getElementById('manage-window')
|
||||
|
||||
const links = document.querySelectorAll('a[href]')
|
||||
|
||||
let win
|
||||
ipcRenderer.on('bounds-changed', (event, bounds) => {
|
||||
const manageWindowReply = document.getElementById('manage-window-reply')
|
||||
const message = `Size: ${bounds.size} Position: ${bounds.position}`
|
||||
manageWindowReply.textContent = message
|
||||
})
|
||||
|
||||
manageWindowBtn.addEventListener('click', (event) => {
|
||||
const modalPath = 'https://electronjs.org'
|
||||
win = new BrowserWindow({ width: 400, height: 275 })
|
||||
|
||||
win.on('resize', updateReply)
|
||||
win.on('move', updateReply)
|
||||
win.on('close', () => { win = null })
|
||||
win.loadURL(modalPath)
|
||||
win.show()
|
||||
|
||||
function updateReply () {
|
||||
const manageWindowReply = document.getElementById('manage-window-reply')
|
||||
const message = `Size: ${win.getSize()} Position: ${win.getPosition()}`
|
||||
manageWindowReply.innerText = message
|
||||
}
|
||||
ipcRenderer.send('create-demo-window')
|
||||
})
|
||||
|
||||
Array.prototype.forEach.call(links, (link) => {
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
<h2>Create a new window</h2>
|
||||
<h3>Supports: Win, macOS, Linux <span>|</span> Process: Main</h3>
|
||||
<button id="new-window">View Demo</button>
|
||||
<p>The <code>BrowserWindow</code> module gives you the ability to create new windows in your app. This main process module can be used from the renderer process with the <code>remote</code> module, as is shown in this demo.</p>
|
||||
<p>The <code>BrowserWindow</code> module gives you the ability to create new windows in your app.</p>
|
||||
<p>There are a lot of options when creating a new window. A few are in this demo, but visit the <a id="browser-window-link" href="">documentation<span>(opens in new window)</span></a>
|
||||
<div>
|
||||
<h2>ProTip</h2>
|
||||
|
||||
@@ -1,13 +1,14 @@
|
||||
// Modules to control application life and create native browser window
|
||||
const { app, BrowserWindow } = require('electron')
|
||||
const { app, BrowserWindow, ipcMain } = require('electron')
|
||||
|
||||
// Keep a global reference of the window object, if you don't, the window will
|
||||
// be closed automatically when the JavaScript object is garbage collected.
|
||||
let mainWindow
|
||||
ipcMain.on('new-window', (event, { url, width, height }) => {
|
||||
const win = new BrowserWindow({ width, height })
|
||||
win.loadURL(url)
|
||||
})
|
||||
|
||||
function createWindow () {
|
||||
// Create the browser window.
|
||||
mainWindow = new BrowserWindow({
|
||||
const mainWindow = new BrowserWindow({
|
||||
width: 800,
|
||||
height: 600,
|
||||
webPreferences: {
|
||||
@@ -17,17 +18,6 @@ function createWindow () {
|
||||
|
||||
// and load the index.html of the app.
|
||||
mainWindow.loadFile('index.html')
|
||||
|
||||
// Open the DevTools.
|
||||
// mainWindow.webContents.openDevTools()
|
||||
|
||||
// Emitted when the window is closed.
|
||||
mainWindow.on('closed', function () {
|
||||
// Dereference the window object, usually you would store windows
|
||||
// in an array if your app supports multi windows, this is the time
|
||||
// when you should delete the corresponding element.
|
||||
mainWindow = null
|
||||
})
|
||||
}
|
||||
|
||||
// This method will be called when Electron has finished
|
||||
|
||||
@@ -1,16 +1,11 @@
|
||||
const { BrowserWindow } = require('electron').remote
|
||||
const { shell } = require('electron').remote
|
||||
const { shell, ipcRenderer } = require('electron')
|
||||
|
||||
const newWindowBtn = document.getElementById('new-window')
|
||||
const link = document.getElementById('browser-window-link')
|
||||
|
||||
newWindowBtn.addEventListener('click', (event) => {
|
||||
|
||||
let win = new BrowserWindow({ width: 400, height: 320 })
|
||||
|
||||
win.on('close', () => { win = null })
|
||||
win.loadURL('https://electronjs.org')
|
||||
win.show()
|
||||
const url = 'https://electronjs.org'
|
||||
ipcRenderer.send('new-window', { url, width: 400, height: 320 });
|
||||
})
|
||||
|
||||
link.addEventListener('click', (e) => {
|
||||
|
||||
@@ -1,13 +1,9 @@
|
||||
// Modules to control application life and create native browser window
|
||||
const { app, BrowserWindow } = require('electron')
|
||||
|
||||
// Keep a global reference of the window object, if you don't, the window will
|
||||
// be closed automatically when the JavaScript object is garbage collected.
|
||||
let mainWindow
|
||||
const { app, BrowserWindow, ipcMain } = require('electron')
|
||||
|
||||
function createWindow () {
|
||||
// Create the browser window.
|
||||
mainWindow = new BrowserWindow({
|
||||
const mainWindow = new BrowserWindow({
|
||||
width: 800,
|
||||
height: 600,
|
||||
webPreferences: {
|
||||
@@ -18,15 +14,27 @@ function createWindow () {
|
||||
// and load the index.html of the app.
|
||||
mainWindow.loadFile('index.html')
|
||||
|
||||
// Open the DevTools.
|
||||
// mainWindow.webContents.openDevTools()
|
||||
let demoWindow
|
||||
ipcMain.on('show-demo-window', () => {
|
||||
if (demoWindow) {
|
||||
demoWindow.focus()
|
||||
return
|
||||
}
|
||||
demoWindow = new BrowserWindow({ width: 600, height: 400 })
|
||||
demoWindow.loadURL('https://electronjs.org')
|
||||
demoWindow.on('close', () => {
|
||||
mainWindow.webContents.send('window-close')
|
||||
})
|
||||
demoWindow.on('focus', () => {
|
||||
mainWindow.webContents.send('window-focus')
|
||||
})
|
||||
demoWindow.on('blur', () => {
|
||||
mainWindow.webContents.send('window-blur')
|
||||
})
|
||||
})
|
||||
|
||||
// Emitted when the window is closed.
|
||||
mainWindow.on('closed', function () {
|
||||
// Dereference the window object, usually you would store windows
|
||||
// in an array if your app supports multi windows, this is the time
|
||||
// when you should delete the corresponding element.
|
||||
mainWindow = null
|
||||
ipcMain.on('focus-demo-window', () => {
|
||||
if (demoWindow) demoWindow.focus()
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@@ -1,42 +1,33 @@
|
||||
const { BrowserWindow } = require('electron').remote
|
||||
const shell = require('electron').shell
|
||||
const { shell, ipcRenderer } = require('electron')
|
||||
|
||||
const listenToWindowBtn = document.getElementById('listen-to-window')
|
||||
const focusModalBtn = document.getElementById('focus-on-modal-window')
|
||||
|
||||
const links = document.querySelectorAll('a[href]')
|
||||
const hideFocusBtn = () => {
|
||||
focusModalBtn.classList.add('disappear')
|
||||
focusModalBtn.classList.remove('smooth-appear')
|
||||
focusModalBtn.removeEventListener('click', focusWindow)
|
||||
}
|
||||
|
||||
let win
|
||||
const showFocusBtn = (btn) => {
|
||||
focusModalBtn.classList.add('smooth-appear')
|
||||
focusModalBtn.classList.remove('disappear')
|
||||
focusModalBtn.addEventListener('click', focusWindow)
|
||||
}
|
||||
const focusWindow = () => {
|
||||
ipcRenderer.send('focus-demo-window')
|
||||
}
|
||||
|
||||
ipcRenderer.on('window-focus', hideFocusBtn)
|
||||
ipcRenderer.on('window-close', hideFocusBtn)
|
||||
ipcRenderer.on('window-blur', showFocusBtn)
|
||||
|
||||
listenToWindowBtn.addEventListener('click', () => {
|
||||
const modalPath = 'https://electronjs.org'
|
||||
win = new BrowserWindow({ width: 600, height: 400 })
|
||||
|
||||
const hideFocusBtn = () => {
|
||||
focusModalBtn.classList.add('disappear')
|
||||
focusModalBtn.classList.remove('smooth-appear')
|
||||
focusModalBtn.removeEventListener('click', clickHandler)
|
||||
}
|
||||
|
||||
const showFocusBtn = (btn) => {
|
||||
if (!win) return
|
||||
focusModalBtn.classList.add('smooth-appear')
|
||||
focusModalBtn.classList.remove('disappear')
|
||||
focusModalBtn.addEventListener('click', clickHandler)
|
||||
}
|
||||
|
||||
win.on('focus', hideFocusBtn)
|
||||
win.on('blur', showFocusBtn)
|
||||
win.on('close', () => {
|
||||
hideFocusBtn()
|
||||
win = null
|
||||
})
|
||||
win.loadURL(modalPath)
|
||||
win.show()
|
||||
|
||||
const clickHandler = () => { win.focus() }
|
||||
ipcRenderer.send('show-demo-window')
|
||||
})
|
||||
|
||||
const links = document.querySelectorAll('a[href]')
|
||||
|
||||
Array.prototype.forEach.call(links, (link) => {
|
||||
const url = link.getAttribute('href')
|
||||
if (url.indexOf('http') === 0) {
|
||||
|
||||
@@ -1,25 +1,28 @@
|
||||
# DevTools Extension
|
||||
|
||||
Electron supports the [Chrome DevTools Extension][devtools-extension], which can
|
||||
be used to extend the ability of devtools for debugging popular web frameworks.
|
||||
Electron supports [Chrome DevTools extensions][devtools-extension], which can
|
||||
be used to extend the ability of Chrome's developer tools for debugging
|
||||
popular web frameworks.
|
||||
|
||||
## How to load a DevTools Extension
|
||||
## Loading a DevTools extension with tooling
|
||||
|
||||
This document outlines the process for manually loading an extension.
|
||||
You may also try
|
||||
[electron-devtools-installer](https://github.com/GPMDP/electron-devtools-installer),
|
||||
a third-party tool that downloads extensions directly from the Chrome WebStore.
|
||||
The easiest way to load a DevTools extension is to use third-party tooling to automate the
|
||||
process for you. [electron-devtools-installer][electron-devtools-installer] is a popular
|
||||
NPM package that does just that.
|
||||
|
||||
To load an extension in Electron, you need to download it in Chrome browser,
|
||||
locate its filesystem path, and then load it by calling the
|
||||
`BrowserWindow.addDevToolsExtension(extension)` API.
|
||||
## Manually loading a DevTools extension
|
||||
|
||||
Using the [React Developer Tools][react-devtools] as example:
|
||||
If you don't want to use the tooling approach, you can also do all of the necessary
|
||||
operations by hand. To load an extension in Electron, you need to download it via Chrome,
|
||||
locate its filesystem path, and then load it into your [Session][session] by calling the
|
||||
[`ses.loadExtension`] API.
|
||||
|
||||
1. Install it in Chrome browser.
|
||||
Using the [React Developer Tools][react-devtools] as an example:
|
||||
|
||||
1. Install the extension in Google Chrome.
|
||||
1. Navigate to `chrome://extensions`, and find its extension ID, which is a hash
|
||||
string like `fmkadmapgofadopljbjfkapdkoienihi`.
|
||||
1. Find out filesystem location used by Chrome for storing extensions:
|
||||
1. Find out the filesystem location used by Chrome for storing extensions:
|
||||
* on Windows it is `%LOCALAPPDATA%\Google\Chrome\User Data\Default\Extensions`;
|
||||
* on Linux it could be:
|
||||
* `~/.config/google-chrome/Default/Extensions/`
|
||||
@@ -27,36 +30,48 @@ Using the [React Developer Tools][react-devtools] as example:
|
||||
* `~/.config/google-chrome-canary/Default/Extensions/`
|
||||
* `~/.config/chromium/Default/Extensions/`
|
||||
* on macOS it is `~/Library/Application Support/Google/Chrome/Default/Extensions`.
|
||||
1. Pass the location of the extension to `BrowserWindow.addDevToolsExtension`
|
||||
API, for the React Developer Tools, it is something like:
|
||||
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
|
||||
const path = require('path')
|
||||
const os = require('os')
|
||||
const { app, session } = require('electron')
|
||||
const path = require('path')
|
||||
const os = require('os')
|
||||
|
||||
BrowserWindow.addDevToolsExtension(
|
||||
path.join(os.homedir(), '/Library/Application Support/Google/Chrome/Default/Extensions/fmkadmapgofadopljbjfkapdkoienihi/4.3.0_0')
|
||||
)
|
||||
// on macOS
|
||||
const reactDevToolsPath = path.join(
|
||||
os.homedir(),
|
||||
'/Library/Application Support/Google/Chrome/Default/Extensions/fmkadmapgofadopljbjfkapdkoienihi/4.9.0_0'
|
||||
)
|
||||
|
||||
app.whenReady().then(async () => {
|
||||
await session.defaultSession.loadExtension(reactDevToolsPath)
|
||||
})
|
||||
```
|
||||
|
||||
**Note:** The `BrowserWindow.addDevToolsExtension` API cannot be called before the
|
||||
ready event of the app module is emitted.
|
||||
**Notes:**
|
||||
|
||||
The extension will be remembered so you only need to call this API once per
|
||||
extension. If you try to add an extension that has already been loaded, this method
|
||||
will not return and instead log a warning to the console.
|
||||
* `loadExtension` returns a Promise with an [Extension object][extension-structure],
|
||||
which contains metadata about the extension that was loaded. This promise needs to
|
||||
resolve (e.g. with an `await` expression) before loading a page. Otherwise, the
|
||||
extension won't be guaranteed to load.
|
||||
* `loadExtension` cannot be called before the `ready` event of the `app` module
|
||||
is emitted, nor can it be called on in-memory (non-persistent) sessions.
|
||||
* `loadExtension` must be called on every boot of your app if you want the
|
||||
extension to be loaded.
|
||||
|
||||
### How to remove a DevTools Extension
|
||||
### Removing a DevTools extension
|
||||
|
||||
You can pass the name of the extension to the `BrowserWindow.removeDevToolsExtension`
|
||||
API to remove it. The name of the extension is returned by
|
||||
`BrowserWindow.addDevToolsExtension` and you can get the names of all installed
|
||||
DevTools Extensions using the `BrowserWindow.getDevToolsExtensions` API.
|
||||
You can pass the extension's ID to the [`ses.removeExtension`][remove-extension] API to
|
||||
remove it from your Session. Loaded extensions are not persisted between
|
||||
app launches.
|
||||
|
||||
## Supported DevTools Extensions
|
||||
## DevTools extension support
|
||||
|
||||
Electron only supports a limited set of `chrome.*` APIs, so some extensions
|
||||
using unsupported `chrome.*` APIs for chrome extension features may not work.
|
||||
Following Devtools Extensions are tested and guaranteed to work in Electron:
|
||||
Electron only supports
|
||||
[a limited set of `chrome.*` APIs][supported-extension-apis],
|
||||
so extensions using unsupported `chrome.*` APIs under the hood may not work.
|
||||
|
||||
The following Devtools extensions have been tested to work in Electron:
|
||||
|
||||
* [Ember Inspector](https://chrome.google.com/webstore/detail/ember-inspector/bmdblncegkenkacieihfhpjfppoconhi)
|
||||
* [React Developer Tools](https://chrome.google.com/webstore/detail/react-developer-tools/fmkadmapgofadopljbjfkapdkoienihi)
|
||||
@@ -68,14 +83,22 @@ Following Devtools Extensions are tested and guaranteed to work in Electron:
|
||||
* [Redux DevTools Extension](https://chrome.google.com/webstore/detail/redux-devtools/lmhkpmbekcpmknklioeibfkpmmfibljd)
|
||||
* [MobX Developer Tools](https://chrome.google.com/webstore/detail/mobx-developer-tools/pfgnfdagidkfgccljigdamigbcnndkod)
|
||||
|
||||
### What should I do if a DevTools Extension is not working?
|
||||
### What should I do if a DevTools extension is not working?
|
||||
|
||||
First please make sure the extension is still being maintained, some extensions
|
||||
can not even work for recent versions of Chrome browser, and we are not able to
|
||||
do anything for them.
|
||||
First, please make sure the extension is still being maintained and is compatible
|
||||
with the latest version of Google Chrome. We cannot provide additional support for
|
||||
unsupported extensions.
|
||||
|
||||
Then file a bug at Electron's issues list, and describe which part of the
|
||||
extension is not working as expected.
|
||||
If the extension works on Chrome but not on Electron, file a bug in Electron's
|
||||
[issue tracker][issue-tracker] and describe which part
|
||||
of the extension is not working as expected.
|
||||
|
||||
[devtools-extension]: https://developer.chrome.com/extensions/devtools
|
||||
[session]: ../api/session.md
|
||||
[react-devtools]: https://chrome.google.com/webstore/detail/react-developer-tools/fmkadmapgofadopljbjfkapdkoienihi
|
||||
[load-extension]: ../api/session.md#sesloadextensionpath
|
||||
[extension-structure]: ../api/structures/extension.md
|
||||
[remove-extension]: ../api/session.md#sesremoveextensionextensionid
|
||||
[electron-devtools-installer]: https://github.com/MarshallOfSound/electron-devtools-installer
|
||||
[supported-extension-apis]: ../api/extensions.md
|
||||
[issue-tracker]: https://github.com/electron/electron/issues
|
||||
|
||||
@@ -26,7 +26,8 @@ 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
|
||||
const { inAppPurchase } = require('electron').remote
|
||||
// Main process
|
||||
const { inAppPurchase } = require('electron')
|
||||
const PRODUCT_IDS = ['id1', 'id2']
|
||||
|
||||
// Listen for transactions as soon as possible.
|
||||
|
||||
@@ -9,7 +9,7 @@ Two modes of rendering can be used and only the dirty area is passed in the
|
||||
`'paint'` event to be more efficient. The rendering can be stopped, continued
|
||||
and the frame rate can be set. The specified frame rate is a top limit value,
|
||||
when there is nothing happening on a webpage, no frames are generated. The
|
||||
maximum frame rate is 60, because above that there is no benefit, only
|
||||
maximum frame rate is 240, because above that there is no benefit, only
|
||||
performance loss.
|
||||
|
||||
**Note:** An offscreen window is always created as a [Frameless Window](../api/frameless-window.md).
|
||||
|
||||
@@ -29,12 +29,10 @@ auto_filenames = {
|
||||
"docs/api/incoming-message.md",
|
||||
"docs/api/ipc-main.md",
|
||||
"docs/api/ipc-renderer.md",
|
||||
"docs/api/locales.md",
|
||||
"docs/api/menu-item.md",
|
||||
"docs/api/menu.md",
|
||||
"docs/api/message-channel-main.md",
|
||||
"docs/api/message-port-main.md",
|
||||
"docs/api/modernization",
|
||||
"docs/api/native-image.md",
|
||||
"docs/api/native-theme.md",
|
||||
"docs/api/net-log.md",
|
||||
|
||||
@@ -529,15 +529,17 @@ export const wrapFsWithAsar = (fs: Record<string, any>) => {
|
||||
return fs.readFile(realPath, options, callback);
|
||||
}
|
||||
|
||||
const buffer = Buffer.alloc(info.size);
|
||||
const fd = archive.getFd();
|
||||
if (!(fd >= 0)) {
|
||||
const error = createError(AsarError.NOT_FOUND, { asarPath, filePath });
|
||||
nextTick(callback, [error]);
|
||||
return;
|
||||
}
|
||||
|
||||
logASARAccess(asarPath, filePath, info.offset);
|
||||
archive.read(info.offset, info.size).then((buf) => {
|
||||
const buffer = Buffer.from(buf);
|
||||
callback(null, encoding ? buffer.toString(encoding) : buffer);
|
||||
}, (err) => {
|
||||
const error: AsarErrorObject = new Error(`EINVAL, ${err.message} while reading ${filePath} in ${asarPath}`);
|
||||
error.code = 'EINVAL';
|
||||
error.errno = -22;
|
||||
callback(error);
|
||||
fs.read(fd, buffer, 0, info.size, info.offset, (error: Error) => {
|
||||
callback(error, encoding ? buffer.toString(encoding) : buffer);
|
||||
});
|
||||
};
|
||||
|
||||
@@ -570,19 +572,13 @@ export const wrapFsWithAsar = (fs: Record<string, any>) => {
|
||||
}
|
||||
|
||||
const { encoding } = options;
|
||||
const buffer = Buffer.alloc(info.size);
|
||||
const fd = archive.getFd();
|
||||
if (!(fd >= 0)) throw createError(AsarError.NOT_FOUND, { asarPath, filePath });
|
||||
|
||||
logASARAccess(asarPath, filePath, info.offset);
|
||||
let arrayBuffer: ArrayBuffer;
|
||||
try {
|
||||
arrayBuffer = archive.readSync(info.offset, info.size);
|
||||
} catch (err) {
|
||||
const error: AsarErrorObject = new Error(`EINVAL, ${err.message} while reading ${filePath} in ${asarPath}`);
|
||||
error.code = 'EINVAL';
|
||||
error.errno = -22;
|
||||
throw error;
|
||||
}
|
||||
const buffer = Buffer.from(arrayBuffer);
|
||||
return encoding ? buffer.toString(encoding) : buffer;
|
||||
fs.readSync(fd, buffer, 0, info.size, info.offset);
|
||||
return (encoding) ? buffer.toString(encoding) : buffer;
|
||||
};
|
||||
|
||||
const { readdir } = fs;
|
||||
@@ -612,9 +608,10 @@ export const wrapFsWithAsar = (fs: Record<string, any>) => {
|
||||
if (options.withFileTypes) {
|
||||
const dirents = [];
|
||||
for (const file of files) {
|
||||
const stats = archive.stat(file);
|
||||
const childPath = path.join(filePath, file);
|
||||
const stats = archive.stat(childPath);
|
||||
if (!stats) {
|
||||
const error = createError(AsarError.NOT_FOUND, { asarPath, filePath: file });
|
||||
const error = createError(AsarError.NOT_FOUND, { asarPath, filePath: childPath });
|
||||
nextTick(callback!, [error]);
|
||||
return;
|
||||
}
|
||||
@@ -654,9 +651,10 @@ export const wrapFsWithAsar = (fs: Record<string, any>) => {
|
||||
if (options && (options as any).withFileTypes) {
|
||||
const dirents = [];
|
||||
for (const file of files) {
|
||||
const stats = archive.stat(file);
|
||||
const childPath = path.join(filePath, file);
|
||||
const stats = archive.stat(childPath);
|
||||
if (!stats) {
|
||||
throw createError(AsarError.NOT_FOUND, { asarPath, filePath: file });
|
||||
throw createError(AsarError.NOT_FOUND, { asarPath, filePath: childPath });
|
||||
}
|
||||
if (stats.isFile) {
|
||||
dirents.push(new fs.Dirent(file, fs.constants.UV_DIRENT_FILE));
|
||||
@@ -686,20 +684,16 @@ export const wrapFsWithAsar = (fs: Record<string, any>) => {
|
||||
if (info.size === 0) return ['', false];
|
||||
if (info.unpacked) {
|
||||
const realPath = archive.copyFileOut(filePath);
|
||||
return fs.readFileSync(realPath, { encoding: 'utf8' });
|
||||
const str = fs.readFileSync(realPath, { encoding: 'utf8' });
|
||||
return [str, str.length > 0];
|
||||
}
|
||||
|
||||
const buffer = Buffer.alloc(info.size);
|
||||
const fd = archive.getFd();
|
||||
if (!(fd >= 0)) return [];
|
||||
|
||||
logASARAccess(asarPath, filePath, info.offset);
|
||||
let arrayBuffer: ArrayBuffer;
|
||||
try {
|
||||
arrayBuffer = archive.readSync(info.offset, info.size);
|
||||
} catch (err) {
|
||||
const error: AsarErrorObject = new Error(`EINVAL, ${err.message} while reading ${filePath} in ${asarPath}`);
|
||||
error.code = 'EINVAL';
|
||||
error.errno = -22;
|
||||
throw error;
|
||||
}
|
||||
const buffer = Buffer.from(arrayBuffer);
|
||||
fs.readSync(fd, buffer, 0, info.size, info.offset);
|
||||
const str = buffer.toString('utf8');
|
||||
return [str, str.length > 0];
|
||||
};
|
||||
|
||||
@@ -43,7 +43,7 @@ Object.defineProperty(BaseWindow.prototype, 'kiosk', {
|
||||
});
|
||||
|
||||
Object.defineProperty(BaseWindow.prototype, 'documentEdited', {
|
||||
get: function () { return this.isFullscreen(); },
|
||||
get: function () { return this.isDocumentEdited(); },
|
||||
set: function (edited) { this.setDocumentEdited(edited); }
|
||||
});
|
||||
|
||||
|
||||
@@ -92,11 +92,7 @@ BrowserWindow.getFocusedWindow = () => {
|
||||
};
|
||||
|
||||
BrowserWindow.fromWebContents = (webContents: WebContents) => {
|
||||
for (const window of BrowserWindow.getAllWindows()) {
|
||||
if (window.webContents && window.webContents.equal(webContents)) return window;
|
||||
}
|
||||
|
||||
return null;
|
||||
return webContents.getOwnerBrowserWindow();
|
||||
};
|
||||
|
||||
BrowserWindow.fromBrowserView = (browserView: BrowserView) => {
|
||||
|
||||
@@ -18,7 +18,7 @@ class CrashReporter {
|
||||
|
||||
if (submitURL == null) throw new Error('submitURL is a required option to crashReporter.start');
|
||||
|
||||
if (!compress) {
|
||||
if (!compress && uploadToServer) {
|
||||
deprecate.log('Sending uncompressed crash reports is deprecated and will be removed in a future version of Electron. Set { compress: true } to opt-in to the new behavior. Crash reports will be uploaded gzipped, which most crash reporting servers support.');
|
||||
}
|
||||
|
||||
|
||||
@@ -173,6 +173,11 @@ class ChunkedBodyStream extends Writable {
|
||||
this._downstream = pipe;
|
||||
if (this._pendingChunk) {
|
||||
const doneWriting = (maybeError: Error | void) => {
|
||||
// If the underlying request has been aborted, we honeslty don't care about the error
|
||||
// all work should cease as soon as we abort anyway, this error is probably a
|
||||
// "mojo pipe disconnected" error (code=9)
|
||||
if (this._clientRequest._aborted) return;
|
||||
|
||||
const cb = this._pendingCallback!;
|
||||
delete this._pendingCallback;
|
||||
delete this._pendingChunk;
|
||||
|
||||
@@ -17,8 +17,12 @@ Object.setPrototypeOf(protocol, new Proxy({}, {
|
||||
|
||||
ownKeys () {
|
||||
if (!app.isReady()) return [];
|
||||
return Reflect.ownKeys(session.defaultSession!.protocol);
|
||||
},
|
||||
|
||||
return Object.getOwnPropertyNames(Object.getPrototypeOf(session.defaultSession!.protocol));
|
||||
has: (target, property: string) => {
|
||||
if (!app.isReady()) return false;
|
||||
return Reflect.has(session.defaultSession!.protocol, property);
|
||||
},
|
||||
|
||||
getOwnPropertyDescriptor () {
|
||||
|
||||
@@ -1,20 +1,47 @@
|
||||
import { EventEmitter } from 'events';
|
||||
const { createScreen } = process._linkedBinding('electron_common_screen');
|
||||
|
||||
let _screen: Electron.Screen;
|
||||
|
||||
const createScreenIfNeeded = () => {
|
||||
if (_screen === undefined) {
|
||||
_screen = createScreen();
|
||||
}
|
||||
};
|
||||
|
||||
// We can't call createScreen until after app.on('ready'), but this module
|
||||
// exposes an instance created by createScreen. In order to avoid
|
||||
// side-effecting and calling createScreen upon import of this module, instead
|
||||
// we export a proxy which lazily calls createScreen on first access.
|
||||
export default new Proxy({}, {
|
||||
get: (target, prop) => {
|
||||
if (_screen === undefined) {
|
||||
_screen = createScreen();
|
||||
get: (target, property: keyof Electron.Screen) => {
|
||||
createScreenIfNeeded();
|
||||
const value = _screen[property];
|
||||
if (typeof value === 'function') {
|
||||
return value.bind(_screen);
|
||||
}
|
||||
const v = (_screen as any)[prop];
|
||||
if (typeof v === 'function') {
|
||||
return v.bind(_screen);
|
||||
}
|
||||
return v;
|
||||
return value;
|
||||
},
|
||||
set: (target, property: string, value: unknown) => {
|
||||
createScreenIfNeeded();
|
||||
return Reflect.set(_screen, property, value);
|
||||
},
|
||||
ownKeys: () => {
|
||||
createScreenIfNeeded();
|
||||
return Reflect.ownKeys(_screen);
|
||||
},
|
||||
has: (target, property: string) => {
|
||||
createScreenIfNeeded();
|
||||
return property in _screen;
|
||||
},
|
||||
getOwnPropertyDescriptor: (target, property: string) => {
|
||||
createScreenIfNeeded();
|
||||
return Reflect.getOwnPropertyDescriptor(_screen, property);
|
||||
},
|
||||
getPrototypeOf: () => {
|
||||
// This is necessary as a result of weirdness with EventEmitterMixin
|
||||
// and FunctionTemplate - we need to explicitly ensure it's returned
|
||||
// in the prototype.
|
||||
return EventEmitter.prototype;
|
||||
}
|
||||
});
|
||||
|
||||
@@ -11,7 +11,7 @@ if ('getAppLevelAppearance' in systemPreferences) {
|
||||
}
|
||||
|
||||
if ('getEffectiveAppearance' in systemPreferences) {
|
||||
const nativeEAGetter = systemPreferences.getAppLevelAppearance;
|
||||
const nativeEAGetter = systemPreferences.getEffectiveAppearance;
|
||||
Object.defineProperty(systemPreferences, 'effectiveAppearance', {
|
||||
get: () => nativeEAGetter.call(systemPreferences)
|
||||
});
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user