mirror of
https://github.com/electron/electron.git
synced 2026-02-26 03:01:17 -05:00
Compare commits
210 Commits
refactor/a
...
v12.0.2
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
17c970b6a2 | ||
|
|
1f4ffe4f68 | ||
|
|
d121bcbbb5 | ||
|
|
d2a342c74d | ||
|
|
c19e1ee30e | ||
|
|
508075f870 | ||
|
|
c34103d912 | ||
|
|
7487fe91fe | ||
|
|
7b21bc543b | ||
|
|
6c09c2c644 | ||
|
|
44eb30fa71 | ||
|
|
c528ed5a8d | ||
|
|
15f29aa971 | ||
|
|
312682d655 | ||
|
|
8397716dab | ||
|
|
23075f8620 | ||
|
|
90d94e468e | ||
|
|
5cc6d79d17 | ||
|
|
8f825d35f7 | ||
|
|
05972074e3 | ||
|
|
21ac61270a | ||
|
|
f0500fae4c | ||
|
|
5f2f4182c4 | ||
|
|
ac8db00a70 | ||
|
|
ab5d0f4c8b | ||
|
|
203116867b | ||
|
|
67a67270f5 | ||
|
|
83a3eb64ec | ||
|
|
8b1260184a | ||
|
|
f13ddca55f | ||
|
|
f1c4265072 | ||
|
|
f5de5e9131 | ||
|
|
a73949315c | ||
|
|
189f7e0e4e | ||
|
|
2950f03e83 | ||
|
|
ca417e435c | ||
|
|
5237108396 | ||
|
|
3ae63c9a06 | ||
|
|
8828382b23 | ||
|
|
0e714d19c5 | ||
|
|
aec412e35d | ||
|
|
4b2d791212 | ||
|
|
fd629c16cb | ||
|
|
007c960f3c | ||
|
|
b2636e171a | ||
|
|
e7e1801443 | ||
|
|
0baf9997ad | ||
|
|
e65e989650 | ||
|
|
26a18c26d7 | ||
|
|
a52c88ec4d | ||
|
|
0ee559cd29 | ||
|
|
dfed04b71b | ||
|
|
d628fa07b5 | ||
|
|
f0c7789544 | ||
|
|
d00e869560 | ||
|
|
b70e42024a | ||
|
|
44adc8ddb4 | ||
|
|
9e30fe0f96 | ||
|
|
7180b2b13f | ||
|
|
c734baf8d4 | ||
|
|
a859436f7a | ||
|
|
3144f992f7 | ||
|
|
98f57a20e7 | ||
|
|
f6007654f9 | ||
|
|
84a4a7a944 | ||
|
|
1b6e3596f2 | ||
|
|
573784967c | ||
|
|
d55b399976 | ||
|
|
b8941d084d | ||
|
|
afffbadf5b | ||
|
|
c3bce9c664 | ||
|
|
33f6ff40fc | ||
|
|
777f23af0d | ||
|
|
f6992db54b | ||
|
|
8cdd20e97a | ||
|
|
962f1aa7d4 | ||
|
|
0961044dc8 | ||
|
|
e1f06510f8 | ||
|
|
b6bdbcf485 | ||
|
|
417230a67a | ||
|
|
fe876bd55b | ||
|
|
4e372b888f | ||
|
|
74ef45315b | ||
|
|
f7d8c806ae | ||
|
|
d4de0b5e50 | ||
|
|
35daa4801a | ||
|
|
5db929ffc1 | ||
|
|
f6b81990fc | ||
|
|
7c67c1d0ee | ||
|
|
509efee4af | ||
|
|
7fa87565c0 | ||
|
|
c67c3aaf74 | ||
|
|
cc4db3359d | ||
|
|
5dbb6356ef | ||
|
|
0c5b6bfd30 | ||
|
|
9faf23509d | ||
|
|
b4ae35a63d | ||
|
|
025abfc1ba | ||
|
|
563bb8559f | ||
|
|
30be5bfa4b | ||
|
|
28fa60fbcb | ||
|
|
37c68d56d6 | ||
|
|
da58ded8f9 | ||
|
|
80a3f10b6b | ||
|
|
889abd0c8e | ||
|
|
0305f08888 | ||
|
|
0604f8727c | ||
|
|
551896c4ce | ||
|
|
c11a5dcf29 | ||
|
|
b86eb74fbf | ||
|
|
e49a88ba53 | ||
|
|
4ab817768d | ||
|
|
f730284113 | ||
|
|
6122f4bece | ||
|
|
017628f84d | ||
|
|
eb132d8b3e | ||
|
|
f26025301a | ||
|
|
a79750b871 | ||
|
|
870d8c0307 | ||
|
|
1f22b2bfdc | ||
|
|
e25de07657 | ||
|
|
6bfccca157 | ||
|
|
58c1ce50d4 | ||
|
|
c46ed96421 | ||
|
|
9278459c46 | ||
|
|
a6af3bd8df | ||
|
|
c74780117e | ||
|
|
a6f01ded4d | ||
|
|
25e4475444 | ||
|
|
162d40cd23 | ||
|
|
a73f00cd47 | ||
|
|
897fd34253 | ||
|
|
0d48f3944d | ||
|
|
82bc14362c | ||
|
|
4010890edd | ||
|
|
b10a908187 | ||
|
|
0e7ff69a4e | ||
|
|
f5af20d1d6 | ||
|
|
3f2ccce9e1 | ||
|
|
8e7862ed4b | ||
|
|
48a8fdfdb6 | ||
|
|
e9c39163bf | ||
|
|
dc657515b7 | ||
|
|
8eb4ab0ae1 | ||
|
|
92c8614e14 | ||
|
|
f3ce79936a | ||
|
|
d498d4bf18 | ||
|
|
df21f17131 | ||
|
|
c6d144d550 | ||
|
|
6553c4418f | ||
|
|
ecf981a91a | ||
|
|
b5cfa03a63 | ||
|
|
1bbf71c090 | ||
|
|
97b40e4e45 | ||
|
|
975123b6bf | ||
|
|
011315574c | ||
|
|
cfd848c32f | ||
|
|
81db78daec | ||
|
|
ce0faeed90 | ||
|
|
e6885668d4 | ||
|
|
a1df860b66 | ||
|
|
ba76f6846e | ||
|
|
ce8d301921 | ||
|
|
39f865e4e3 | ||
|
|
e6727fb7bd | ||
|
|
c9564ff648 | ||
|
|
76be3b9211 | ||
|
|
d132800944 | ||
|
|
558bcc65bc | ||
|
|
bf25d484a4 | ||
|
|
d2c4b594bd | ||
|
|
601af0b016 | ||
|
|
130a65d008 | ||
|
|
fe022df628 | ||
|
|
5b47fd7cbf | ||
|
|
9b1913b613 | ||
|
|
36c695ce2a | ||
|
|
afcdf661a0 | ||
|
|
3d01b83daa | ||
|
|
e77d9ff3b9 | ||
|
|
fb35356b47 | ||
|
|
37d21bb80e | ||
|
|
e84539f2e0 | ||
|
|
d2591ed4f8 | ||
|
|
6b54fe37de | ||
|
|
561fe63813 | ||
|
|
9543f8b30a | ||
|
|
cec2c73733 | ||
|
|
2e9305d964 | ||
|
|
0491cc6906 | ||
|
|
badcdd6566 | ||
|
|
a0d0bd60a5 | ||
|
|
c0f0a02419 | ||
|
|
8046f0560a | ||
|
|
2a8961b52f | ||
|
|
36163af228 | ||
|
|
29f42e943e | ||
|
|
4597cb6499 | ||
|
|
4ba78b81c1 | ||
|
|
80e0473649 | ||
|
|
db0d4c8224 | ||
|
|
4fbb58020c | ||
|
|
c9801ab5a5 | ||
|
|
46441c1bd7 | ||
|
|
1cac3354e7 | ||
|
|
57c69ab3ac | ||
|
|
39b9c40a05 | ||
|
|
66a22a28a5 | ||
|
|
17a8b7724b | ||
|
|
c512995426 |
@@ -295,10 +295,10 @@ step-setup-goma-for-build: &step-setup-goma-for-build
|
|||||||
run:
|
run:
|
||||||
name: Setup Goma
|
name: Setup Goma
|
||||||
command: |
|
command: |
|
||||||
if [ "`uname`" == "Linux" ]; then
|
echo 'export NUMBER_OF_NINJA_PROCESSES=300' >> $BASH_ENV
|
||||||
echo 'export NUMBER_OF_NINJA_PROCESSES=300' >> $BASH_ENV
|
if [ "`uname`" == "Darwin" ]; then
|
||||||
else
|
echo 'ulimit -n 10000' >> $BASH_ENV
|
||||||
echo 'export NUMBER_OF_NINJA_PROCESSES=25' >> $BASH_ENV
|
echo 'sudo launchctl limit maxfiles 65536 200000' >> $BASH_ENV
|
||||||
fi
|
fi
|
||||||
if [ ! -z "$RAW_GOMA_AUTH" ]; then
|
if [ ! -z "$RAW_GOMA_AUTH" ]; then
|
||||||
echo $RAW_GOMA_AUTH > ~/.goma_oauth2_config
|
echo $RAW_GOMA_AUTH > ~/.goma_oauth2_config
|
||||||
@@ -307,8 +307,8 @@ step-setup-goma-for-build: &step-setup-goma-for-build
|
|||||||
cd build-tools
|
cd build-tools
|
||||||
npm install
|
npm install
|
||||||
mkdir third_party
|
mkdir third_party
|
||||||
node -e "require('./src/utils/goma.js').downloadAndPrepare()"
|
node -e "require('./src/utils/goma.js').downloadAndPrepare({ gomaOneForAll: true })"
|
||||||
node -e "require('./src/utils/goma.js').ensure()"
|
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 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 LOCAL_GOMA_DIR='`node -e "console.log(require('./src/utils/goma.js').dir)"` >> $BASH_ENV
|
||||||
cd ..
|
cd ..
|
||||||
@@ -316,15 +316,17 @@ step-setup-goma-for-build: &step-setup-goma-for-build
|
|||||||
step-restore-brew-cache: &step-restore-brew-cache
|
step-restore-brew-cache: &step-restore-brew-cache
|
||||||
restore_cache:
|
restore_cache:
|
||||||
paths:
|
paths:
|
||||||
- /usr/local/Homebrew
|
- /usr/local/Cellar/gnu-tar
|
||||||
|
- /usr/local/bin/gtar
|
||||||
keys:
|
keys:
|
||||||
- v2-brew-cache-{{ arch }}
|
- v4-brew-cache-{{ arch }}
|
||||||
|
|
||||||
step-save-brew-cache: &step-save-brew-cache
|
step-save-brew-cache: &step-save-brew-cache
|
||||||
save_cache:
|
save_cache:
|
||||||
paths:
|
paths:
|
||||||
- /usr/local/Homebrew
|
- /usr/local/Cellar/gnu-tar
|
||||||
key: v2-brew-cache-{{ arch }}
|
- /usr/local/bin/gtar
|
||||||
|
key: v4-brew-cache-{{ arch }}
|
||||||
name: Persisting brew cache
|
name: Persisting brew cache
|
||||||
|
|
||||||
step-get-more-space-on-mac: &step-get-more-space-on-mac
|
step-get-more-space-on-mac: &step-get-more-space-on-mac
|
||||||
@@ -445,9 +447,6 @@ step-fix-sync-on-mac: &step-fix-sync-on-mac
|
|||||||
# Fix Clang Install (wrong binary)
|
# Fix Clang Install (wrong binary)
|
||||||
rm -rf src/third_party/llvm-build
|
rm -rf src/third_party/llvm-build
|
||||||
python src/tools/clang/scripts/update.py
|
python src/tools/clang/scripts/update.py
|
||||||
# Fix Framework Header Installs (symlinks not retained)
|
|
||||||
rm -rf src/electron/external_binaries
|
|
||||||
python src/electron/script/update-external-binaries.py
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
step-install-signing-cert-on-mac: &step-install-signing-cert-on-mac
|
step-install-signing-cert-on-mac: &step-install-signing-cert-on-mac
|
||||||
@@ -464,8 +463,10 @@ step-install-gnutar-on-mac: &step-install-gnutar-on-mac
|
|||||||
name: Install gnu-tar on macos
|
name: Install gnu-tar on macos
|
||||||
command: |
|
command: |
|
||||||
if [ "`uname`" == "Darwin" ]; then
|
if [ "`uname`" == "Darwin" ]; then
|
||||||
brew update
|
if [ ! -d /usr/local/Cellar/gnu-tar/ ]; then
|
||||||
brew install gnu-tar
|
brew update
|
||||||
|
brew install gnu-tar
|
||||||
|
fi
|
||||||
ln -fs /usr/local/bin/gtar /usr/local/bin/tar
|
ln -fs /usr/local/bin/gtar /usr/local/bin/tar
|
||||||
fi
|
fi
|
||||||
|
|
||||||
@@ -483,7 +484,6 @@ step-gn-check: &step-gn-check
|
|||||||
cd src
|
cd src
|
||||||
gn check out/Default //electron:electron_lib
|
gn check out/Default //electron:electron_lib
|
||||||
gn check out/Default //electron:electron_app
|
gn check out/Default //electron:electron_app
|
||||||
gn check out/Default //electron:manifests
|
|
||||||
gn check out/Default //electron/shell/common/api:mojo
|
gn check out/Default //electron/shell/common/api:mojo
|
||||||
# Check the hunspell filenames
|
# Check the hunspell filenames
|
||||||
node electron/script/gen-hunspell-filenames.js --check
|
node electron/script/gen-hunspell-filenames.js --check
|
||||||
@@ -893,6 +893,8 @@ step-ninja-summary: &step-ninja-summary
|
|||||||
run:
|
run:
|
||||||
name: Print ninja summary
|
name: Print ninja summary
|
||||||
command: |
|
command: |
|
||||||
|
set +e
|
||||||
|
set +o pipefail
|
||||||
python depot_tools/post_build_ninja_summary.py -C src/out/Default
|
python depot_tools/post_build_ninja_summary.py -C src/out/Default
|
||||||
|
|
||||||
step-ninja-report: &step-ninja-report
|
step-ninja-report: &step-ninja-report
|
||||||
@@ -1196,7 +1198,6 @@ steps-electron-ts-compile-for-doc-change: &steps-electron-ts-compile-for-doc-cha
|
|||||||
- *step-depot-tools-add-to-path
|
- *step-depot-tools-add-to-path
|
||||||
- *step-setup-env-for-build
|
- *step-setup-env-for-build
|
||||||
- *step-setup-goma-for-build
|
- *step-setup-goma-for-build
|
||||||
- *step-restore-brew-cache
|
|
||||||
- *step-get-more-space-on-mac
|
- *step-get-more-space-on-mac
|
||||||
- *step-install-npm-deps-on-mac
|
- *step-install-npm-deps-on-mac
|
||||||
- *step-fix-sync-on-mac
|
- *step-fix-sync-on-mac
|
||||||
|
|||||||
35
BUILD.gn
35
BUILD.gn
@@ -265,21 +265,6 @@ if (is_linux) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
source_set("manifests") {
|
|
||||||
sources = [
|
|
||||||
"//electron/shell/app/manifests.cc",
|
|
||||||
"//electron/shell/app/manifests.h",
|
|
||||||
]
|
|
||||||
|
|
||||||
include_dirs = [ "//electron" ]
|
|
||||||
|
|
||||||
deps = [
|
|
||||||
"//electron/shell/common/api:mojo",
|
|
||||||
"//printing/buildflags",
|
|
||||||
"//services/service_manager/public/cpp",
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|
||||||
npm_action("electron_version_args") {
|
npm_action("electron_version_args") {
|
||||||
script = "generate-version-json"
|
script = "generate-version-json"
|
||||||
|
|
||||||
@@ -328,7 +313,6 @@ source_set("electron_lib") {
|
|||||||
":electron_fuses",
|
":electron_fuses",
|
||||||
":electron_js2c",
|
":electron_js2c",
|
||||||
":electron_version_header",
|
":electron_version_header",
|
||||||
":manifests",
|
|
||||||
":resources",
|
":resources",
|
||||||
"buildflags",
|
"buildflags",
|
||||||
"chromium_src:chrome",
|
"chromium_src:chrome",
|
||||||
@@ -353,7 +337,6 @@ source_set("electron_lib") {
|
|||||||
"//components/viz/service",
|
"//components/viz/service",
|
||||||
"//content/public/browser",
|
"//content/public/browser",
|
||||||
"//content/public/child",
|
"//content/public/child",
|
||||||
"//content/public/common:service_names",
|
|
||||||
"//content/public/gpu",
|
"//content/public/gpu",
|
||||||
"//content/public/renderer",
|
"//content/public/renderer",
|
||||||
"//content/public/utility",
|
"//content/public/utility",
|
||||||
@@ -508,6 +491,7 @@ source_set("electron_lib") {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (is_linux) {
|
if (is_linux) {
|
||||||
|
libs = [ "xshmfence" ]
|
||||||
deps += [
|
deps += [
|
||||||
":libnotify_loader",
|
":libnotify_loader",
|
||||||
"//build/config/linux/gtk",
|
"//build/config/linux/gtk",
|
||||||
@@ -664,6 +648,7 @@ source_set("electron_lib") {
|
|||||||
}
|
}
|
||||||
if (enable_pdf_viewer) {
|
if (enable_pdf_viewer) {
|
||||||
deps += [
|
deps += [
|
||||||
|
"//chrome/browser/resources/pdf:pdf_resources",
|
||||||
"//components/pdf/browser",
|
"//components/pdf/browser",
|
||||||
"//components/pdf/renderer",
|
"//components/pdf/renderer",
|
||||||
"//pdf:pdf_ppapi",
|
"//pdf:pdf_ppapi",
|
||||||
@@ -1007,6 +992,9 @@ if (is_mac) {
|
|||||||
deps = [
|
deps = [
|
||||||
":electron_app_framework_bundle_data",
|
":electron_app_framework_bundle_data",
|
||||||
":electron_app_resources",
|
":electron_app_resources",
|
||||||
|
":electron_fuses",
|
||||||
|
"//base",
|
||||||
|
"//electron/buildflags",
|
||||||
]
|
]
|
||||||
if (is_mas_build) {
|
if (is_mas_build) {
|
||||||
deps += [ ":electron_login_helper_app" ]
|
deps += [ ":electron_login_helper_app" ]
|
||||||
@@ -1170,6 +1158,19 @@ if (is_mac) {
|
|||||||
ldflags += [ "/guard:cf,nolongjmp" ]
|
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
|
# This is to support renaming of electron.exe. node-gyp has hard-coded
|
||||||
# executable names which it will recognise as node. This module definition
|
# executable names which it will recognise as node. This module definition
|
||||||
# file claims that the electron executable is in fact named "node.exe",
|
# file claims that the electron executable is in fact named "node.exe",
|
||||||
|
|||||||
6
DEPS
6
DEPS
@@ -14,13 +14,13 @@ gclient_gn_args = [
|
|||||||
|
|
||||||
vars = {
|
vars = {
|
||||||
'chromium_version':
|
'chromium_version':
|
||||||
'3a75ada69d1ac06d6903a2c981ab90a8162f1ba0',
|
'89.0.4389.90',
|
||||||
'node_version':
|
'node_version':
|
||||||
'v14.15.1',
|
'v14.16.0',
|
||||||
'nan_version':
|
'nan_version':
|
||||||
'2c4ee8a32a299eada3cd6e468bbd0a473bfea96d',
|
'2c4ee8a32a299eada3cd6e468bbd0a473bfea96d',
|
||||||
'squirrel.mac_version':
|
'squirrel.mac_version':
|
||||||
'a3a5b3f03b824441c014893b18f99a103b2603e9',
|
'cdc0729c8bf8576bfef18629186e1e9ecf1b0d9f',
|
||||||
|
|
||||||
'pyyaml_version': '3.12',
|
'pyyaml_version': '3.12',
|
||||||
'requests_version': 'e4d59bedfd3c7f4f254f4f5d036587bcd8152458',
|
'requests_version': 'e4d59bedfd3c7f4f254f4f5d036587bcd8152458',
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
12.0.0-nightly.20201118
|
12.0.2
|
||||||
@@ -29,15 +29,12 @@ The preferred method is to install Electron as a development dependency in your
|
|||||||
app:
|
app:
|
||||||
|
|
||||||
```sh
|
```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
|
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
|
## Quick start & Electron Fiddle
|
||||||
|
|
||||||
|
|||||||
@@ -141,7 +141,8 @@ build_script:
|
|||||||
- cd build-tools
|
- cd build-tools
|
||||||
- npm install
|
- npm install
|
||||||
- mkdir third_party
|
- mkdir third_party
|
||||||
- node -e "require('./src/utils/goma.js').downloadAndPrepare()"
|
- ps: >-
|
||||||
|
node -e "require('./src/utils/goma.js').downloadAndPrepare({ gomaOneForAll: true })"
|
||||||
- ps: $env:GN_GOMA_FILE = node -e "console.log(require('./src/utils/goma.js').gnFilePath)"
|
- ps: $env:GN_GOMA_FILE = node -e "console.log(require('./src/utils/goma.js').gnFilePath)"
|
||||||
- ps: $env:LOCAL_GOMA_DIR = node -e "console.log(require('./src/utils/goma.js').dir)"
|
- ps: $env:LOCAL_GOMA_DIR = node -e "console.log(require('./src/utils/goma.js').dir)"
|
||||||
- cd ..
|
- cd ..
|
||||||
@@ -151,7 +152,6 @@ build_script:
|
|||||||
- gn gen out/Default "--args=import(\"%BUILD_CONFIG_PATH%\") import(\"%GN_GOMA_FILE%\") %GN_EXTRA_ARGS% "
|
- gn gen out/Default "--args=import(\"%BUILD_CONFIG_PATH%\") import(\"%GN_GOMA_FILE%\") %GN_EXTRA_ARGS% "
|
||||||
- gn check out/Default //electron:electron_lib
|
- gn check out/Default //electron:electron_lib
|
||||||
- gn check out/Default //electron:electron_app
|
- gn check out/Default //electron:electron_app
|
||||||
- gn check out/Default //electron:manifests
|
|
||||||
- gn check out/Default //electron/shell/common/api:mojo
|
- gn check out/Default //electron/shell/common/api:mojo
|
||||||
- if DEFINED GN_GOMA_FILE (ninja -j 300 -C out/Default electron:electron_app) else (ninja -C out/Default electron:electron_app)
|
- if DEFINED GN_GOMA_FILE (ninja -j 300 -C out/Default electron:electron_app) else (ninja -C out/Default electron:electron_app)
|
||||||
- if "%GN_CONFIG%"=="testing" ( python C:\depot_tools\post_build_ninja_summary.py -C out\Default )
|
- if "%GN_CONFIG%"=="testing" ( python C:\depot_tools\post_build_ninja_summary.py -C out\Default )
|
||||||
|
|||||||
@@ -93,6 +93,6 @@ steps:
|
|||||||
condition: always()
|
condition: always()
|
||||||
|
|
||||||
- powershell: |
|
- powershell: |
|
||||||
Remove-Item -path $env:APPDATA/Electron* -Recurse
|
Remove-Item -path $env:APPDATA/Electron* -Recurse -Force -ErrorAction Ignore
|
||||||
displayName: 'Delete user app data directories'
|
displayName: 'Delete user app data directories'
|
||||||
condition: always()
|
condition: always()
|
||||||
|
|||||||
@@ -143,10 +143,17 @@ static_library("chrome") {
|
|||||||
"//chrome/browser/platform_util.h",
|
"//chrome/browser/platform_util.h",
|
||||||
"//chrome/browser/ui/browser_dialogs.h",
|
"//chrome/browser/ui/browser_dialogs.h",
|
||||||
"//chrome/browser/ui/color_chooser.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) {
|
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) {
|
if (!is_win) {
|
||||||
sources += [
|
sources += [
|
||||||
@@ -163,6 +170,8 @@ static_library("chrome") {
|
|||||||
"//chrome/browser/media/webrtc/window_icon_util_mac.mm",
|
"//chrome/browser/media/webrtc/window_icon_util_mac.mm",
|
||||||
"//chrome/browser/ui/cocoa/color_chooser_mac.h",
|
"//chrome/browser/ui/cocoa/color_chooser_mac.h",
|
||||||
"//chrome/browser/ui/cocoa/color_chooser_mac.mm",
|
"//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 += [
|
deps += [
|
||||||
"//components/remote_cocoa/app_shim",
|
"//components/remote_cocoa/app_shim",
|
||||||
@@ -208,8 +217,6 @@ static_library("chrome") {
|
|||||||
"//chrome/browser/printing/print_view_manager_basic.h",
|
"//chrome/browser/printing/print_view_manager_basic.h",
|
||||||
"//chrome/browser/printing/printer_query.cc",
|
"//chrome/browser/printing/printer_query.cc",
|
||||||
"//chrome/browser/printing/printer_query.h",
|
"//chrome/browser/printing/printer_query.h",
|
||||||
"//chrome/browser/printing/printing_message_filter.cc",
|
|
||||||
"//chrome/browser/printing/printing_message_filter.h",
|
|
||||||
"//chrome/browser/printing/printing_service.cc",
|
"//chrome/browser/printing/printing_service.cc",
|
||||||
"//chrome/browser/printing/printing_service.h",
|
"//chrome/browser/printing/printing_service.h",
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -148,6 +148,7 @@ These individual tutorials expand on topics discussed in the guide above.
|
|||||||
|
|
||||||
### Modules for the Renderer Process (Web Page):
|
### Modules for the Renderer Process (Web Page):
|
||||||
|
|
||||||
|
* [contextBridge](api/context-bridge.md)
|
||||||
* [desktopCapturer](api/desktop-capturer.md)
|
* [desktopCapturer](api/desktop-capturer.md)
|
||||||
* [ipcRenderer](api/ipc-renderer.md)
|
* [ipcRenderer](api/ipc-renderer.md)
|
||||||
* [remote](api/remote.md)
|
* [remote](api/remote.md)
|
||||||
|
|||||||
11
docs/api/app.md
Normal file → Executable file
11
docs/api/app.md
Normal file → Executable file
@@ -391,7 +391,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
|
isn't always because it crashed. The `killed` boolean can be replaced by
|
||||||
checking `reason === 'killed'` when you switch to that event.
|
checking `reason === 'killed'` when you switch to that event.
|
||||||
|
|
||||||
#### Event: 'render-process-gone'
|
### Event: 'render-process-gone'
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
|
|
||||||
@@ -406,11 +406,14 @@ Returns:
|
|||||||
* `oom` - Process ran out of memory
|
* `oom` - Process ran out of memory
|
||||||
* `launch-failed` - Process never successfully launched
|
* `launch-failed` - Process never successfully launched
|
||||||
* `integrity-failure` - Windows code integrity checks failed
|
* `integrity-failure` - Windows code integrity checks failed
|
||||||
|
* `exitCode` Integer - The exit code of the process, unless `reason` is
|
||||||
|
`launch-failed`, in which case `exitCode` will be a platform-specific
|
||||||
|
launch failure error code.
|
||||||
|
|
||||||
Emitted when the renderer process unexpectedly disappears. This is normally
|
Emitted when the renderer process unexpectedly disappears. This is normally
|
||||||
because it was crashed or killed.
|
because it was crashed or killed.
|
||||||
|
|
||||||
#### Event: 'child-process-gone'
|
### Event: 'child-process-gone'
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
|
|
||||||
@@ -1174,9 +1177,9 @@ For `infoType` equal to `basic`:
|
|||||||
|
|
||||||
Using `basic` should be preferred if only basic information like `vendorId` or `driverId` is needed.
|
Using `basic` should be preferred if only basic information like `vendorId` or `driverId` is needed.
|
||||||
|
|
||||||
### `app.setBadgeCount(count)` _Linux_ _macOS_
|
### `app.setBadgeCount([count])` _Linux_ _macOS_
|
||||||
|
|
||||||
* `count` Integer
|
* `count` Integer (optional) - If a value is provided, set the badge to the provided value otherwise, on macOS, display a plain white dot (e.g. unknown number of notifications). On Linux, if a value is not provided the badge will not display.
|
||||||
|
|
||||||
Returns `Boolean` - Whether the call succeeded.
|
Returns `Boolean` - Whether the call succeeded.
|
||||||
|
|
||||||
|
|||||||
@@ -337,7 +337,7 @@ It creates a new `BrowserWindow` with native properties as set by the `options`.
|
|||||||
more details.
|
more details.
|
||||||
* `contextIsolation` Boolean (optional) - Whether to run Electron APIs and
|
* `contextIsolation` Boolean (optional) - Whether to run Electron APIs and
|
||||||
the specified `preload` script in a separate JavaScript context. Defaults
|
the specified `preload` script in a separate JavaScript context. Defaults
|
||||||
to `false`. The context that the `preload` script runs in will only have
|
to `true`. The context that the `preload` script runs in will only have
|
||||||
access to its own dedicated `document` and `window` globals, as well as
|
access to its own dedicated `document` and `window` globals, as well as
|
||||||
its own set of JavaScript builtins (`Array`, `Object`, `JSON`, etc.),
|
its own set of JavaScript builtins (`Array`, `Object`, `JSON`, etc.),
|
||||||
which are all invisible to the loaded content. The Electron API will only
|
which are all invisible to the loaded content. The Electron API will only
|
||||||
@@ -349,8 +349,7 @@ It creates a new `BrowserWindow` with native properties as set by the `options`.
|
|||||||
context in the dev tools by selecting the 'Electron Isolated Context'
|
context in the dev tools by selecting the 'Electron Isolated Context'
|
||||||
entry in the combo box at the top of the Console tab.
|
entry in the combo box at the top of the Console tab.
|
||||||
* `worldSafeExecuteJavaScript` Boolean (optional) - If true, values returned from `webFrame.executeJavaScript` will be sanitized to ensure JS values
|
* `worldSafeExecuteJavaScript` Boolean (optional) - If true, values returned from `webFrame.executeJavaScript` will be sanitized to ensure JS values
|
||||||
can't unsafely cross between worlds when using `contextIsolation`. The default
|
can't unsafely cross between worlds when using `contextIsolation`. Defaults to `true`. _Deprecated_
|
||||||
is `false`. In Electron 12, the default will be changed to `true`. _Deprecated_
|
|
||||||
* `nativeWindowOpen` Boolean (optional) - Whether to use native
|
* `nativeWindowOpen` Boolean (optional) - Whether to use native
|
||||||
`window.open()`. Defaults to `false`. Child windows will always have node
|
`window.open()`. Defaults to `false`. Child windows will always have node
|
||||||
integration disabled unless `nodeIntegrationInSubFrames` is true. **Note:** This option is currently
|
integration disabled unless `nodeIntegrationInSubFrames` is true. **Note:** This option is currently
|
||||||
@@ -735,7 +734,7 @@ The method will also not return if the extension's manifest is missing or incomp
|
|||||||
is emitted.
|
is emitted.
|
||||||
|
|
||||||
**Note:** This method is deprecated. Instead, use
|
**Note:** This method is deprecated. Instead, use
|
||||||
[`ses.loadExtension(path)`](session.md#sesloadextensionpath).
|
[`ses.loadExtension(path)`](session.md#sesloadextensionpath-options).
|
||||||
|
|
||||||
#### `BrowserWindow.removeExtension(name)` _Deprecated_
|
#### `BrowserWindow.removeExtension(name)` _Deprecated_
|
||||||
|
|
||||||
@@ -777,7 +776,7 @@ The method will also not return if the extension's manifest is missing or incomp
|
|||||||
is emitted.
|
is emitted.
|
||||||
|
|
||||||
**Note:** This method is deprecated. Instead, use
|
**Note:** This method is deprecated. Instead, use
|
||||||
[`ses.loadExtension(path)`](session.md#sesloadextensionpath).
|
[`ses.loadExtension(path)`](session.md#sesloadextensionpath-options).
|
||||||
|
|
||||||
#### `BrowserWindow.removeDevToolsExtension(name)` _Deprecated_
|
#### `BrowserWindow.removeDevToolsExtension(name)` _Deprecated_
|
||||||
|
|
||||||
@@ -1051,7 +1050,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).
|
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
|
* `aspectRatio` Float - The aspect ratio to maintain for some portion of the
|
||||||
content view.
|
content view.
|
||||||
@@ -1072,6 +1071,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
|
are within the content view--only that they exist. Sum any extra width and
|
||||||
height areas you have within the overall content view.
|
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)`
|
#### `win.setBackgroundColor(backgroundColor)`
|
||||||
|
|
||||||
* `backgroundColor` String - Window's background color as a hexadecimal value,
|
* `backgroundColor` String - Window's background color as a hexadecimal value,
|
||||||
@@ -1402,6 +1404,8 @@ The native type of the handle is `HWND` on Windows, `NSView*` on macOS, and
|
|||||||
|
|
||||||
* `message` Integer
|
* `message` Integer
|
||||||
* `callback` Function
|
* `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
|
Hooks a windows message. The `callback` is called when
|
||||||
the message is received in the WndProc.
|
the message is received in the WndProc.
|
||||||
@@ -1454,7 +1458,7 @@ Returns `Boolean` - Whether the window's document has been edited.
|
|||||||
|
|
||||||
Returns `Promise<NativeImage>` - Resolves with a [NativeImage](native-image.md)
|
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])`
|
#### `win.loadURL(url[, options])`
|
||||||
|
|
||||||
@@ -1864,6 +1868,13 @@ Replacement API for setBrowserView supporting work with multi browser views.
|
|||||||
|
|
||||||
* `browserView` [BrowserView](browser-view.md)
|
* `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_
|
#### `win.getBrowserViews()` _Experimental_
|
||||||
|
|
||||||
Returns `BrowserView[]` - an array of all BrowserViews that have been attached
|
Returns `BrowserView[]` - an array of all BrowserViews that have been attached
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ const { app, contentTracing } = require('electron')
|
|||||||
app.whenReady().then(() => {
|
app.whenReady().then(() => {
|
||||||
(async () => {
|
(async () => {
|
||||||
await contentTracing.startRecording({
|
await contentTracing.startRecording({
|
||||||
include_categories: ['*']
|
included_categories: ['*']
|
||||||
})
|
})
|
||||||
console.log('Tracing started')
|
console.log('Tracing started')
|
||||||
await new Promise(resolve => setTimeout(resolve, 5000))
|
await new Promise(resolve => setTimeout(resolve, 5000))
|
||||||
|
|||||||
@@ -44,19 +44,19 @@ The `contextBridge` module has the following methods:
|
|||||||
### `contextBridge.exposeInMainWorld(apiKey, api)` _Experimental_
|
### `contextBridge.exposeInMainWorld(apiKey, api)` _Experimental_
|
||||||
|
|
||||||
* `apiKey` String - The key to inject the API onto `window` with. The API will be accessible on `window[apiKey]`.
|
* `apiKey` String - The key to inject the API onto `window` with. The API will be accessible on `window[apiKey]`.
|
||||||
* `api` Record<String, any> - Your API object, more information on what this API can be and how it works is available below.
|
* `api` any - Your API, more information on what this API can be and how it works is available below.
|
||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
|
|
||||||
### API Objects
|
### API
|
||||||
|
|
||||||
The `api` object provided to [`exposeInMainWorld`](#contextbridgeexposeinmainworldapikey-api-experimental) must be an object
|
The `api` provided to [`exposeInMainWorld`](#contextbridgeexposeinmainworldapikey-api-experimental) must be a `Function`, `String`, `Number`, `Array`, `Boolean`, or an object
|
||||||
whose keys are strings and values are a `Function`, `String`, `Number`, `Array`, `Boolean`, or another nested object that meets the same conditions.
|
whose keys are strings and values are a `Function`, `String`, `Number`, `Array`, `Boolean`, or another nested object that meets the same conditions.
|
||||||
|
|
||||||
`Function` values are proxied to the other context and all other values are **copied** and **frozen**. Any data / primitives sent in
|
`Function` values are proxied to the other context and all other values are **copied** and **frozen**. Any data / primitives sent in
|
||||||
the API object become immutable and updates on either side of the bridge do not result in an update on the other side.
|
the API become immutable and updates on either side of the bridge do not result in an update on the other side.
|
||||||
|
|
||||||
An example of a complex API object is shown below:
|
An example of a complex API is shown below:
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
const { contextBridge } = require('electron')
|
const { contextBridge } = require('electron')
|
||||||
|
|||||||
@@ -45,6 +45,8 @@ The following events are available on instances of `Cookies`:
|
|||||||
|
|
||||||
#### Event: 'changed'
|
#### Event: 'changed'
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
|
||||||
* `event` Event
|
* `event` Event
|
||||||
* `cookie` [Cookie](structures/cookie.md) - The cookie that was changed.
|
* `cookie` [Cookie](structures/cookie.md) - The cookie that was changed.
|
||||||
* `cause` String - The cause of the change with one of the following values:
|
* `cause` String - The cause of the change with one of the following values:
|
||||||
|
|||||||
@@ -128,7 +128,7 @@ must be at most 39 bytes long, and values must be no longer than 127 bytes.
|
|||||||
Keys with names longer than the maximum will be silently ignored. Key values
|
Keys with names longer than the maximum will be silently ignored. Key values
|
||||||
longer than the maximum length will be truncated.
|
longer than the maximum length will be truncated.
|
||||||
|
|
||||||
**Note:** Calling this method from the renderer process is deprecated.
|
**Note:** This method is only available in the main process.
|
||||||
|
|
||||||
### `crashReporter.getLastCrashReport()`
|
### `crashReporter.getLastCrashReport()`
|
||||||
|
|
||||||
@@ -137,7 +137,7 @@ last crash report. Only crash reports that have been uploaded will be returned;
|
|||||||
even if a crash report is present on disk it will not be returned until it is
|
even if a crash report is present on disk it will not be returned until it is
|
||||||
uploaded. In the case that there are no uploaded reports, `null` is returned.
|
uploaded. In the case that there are no uploaded reports, `null` is returned.
|
||||||
|
|
||||||
**Note:** Calling this method from the renderer process is deprecated.
|
**Note:** This method is only available in the main process.
|
||||||
|
|
||||||
### `crashReporter.getUploadedReports()`
|
### `crashReporter.getUploadedReports()`
|
||||||
|
|
||||||
@@ -146,14 +146,14 @@ Returns [`CrashReport[]`](structures/crash-report.md):
|
|||||||
Returns all uploaded crash reports. Each report contains the date and uploaded
|
Returns all uploaded crash reports. Each report contains the date and uploaded
|
||||||
ID.
|
ID.
|
||||||
|
|
||||||
**Note:** Calling this method from the renderer process is deprecated.
|
**Note:** This method is only available in the main process.
|
||||||
|
|
||||||
### `crashReporter.getUploadToServer()`
|
### `crashReporter.getUploadToServer()`
|
||||||
|
|
||||||
Returns `Boolean` - Whether reports should be submitted to the server. Set through
|
Returns `Boolean` - Whether reports should be submitted to the server. Set through
|
||||||
the `start` method or `setUploadToServer`.
|
the `start` method or `setUploadToServer`.
|
||||||
|
|
||||||
**Note:** Calling this method from the renderer process is deprecated.
|
**Note:** This method is only available in the main process.
|
||||||
|
|
||||||
### `crashReporter.setUploadToServer(uploadToServer)`
|
### `crashReporter.setUploadToServer(uploadToServer)`
|
||||||
|
|
||||||
@@ -162,13 +162,7 @@ the `start` method or `setUploadToServer`.
|
|||||||
This would normally be controlled by user preferences. This has no effect if
|
This would normally be controlled by user preferences. This has no effect if
|
||||||
called before `start` is called.
|
called before `start` is called.
|
||||||
|
|
||||||
**Note:** Calling this method from the renderer process is deprecated.
|
**Note:** This method is only available in the main process.
|
||||||
|
|
||||||
### `crashReporter.getCrashesDirectory()` _Deprecated_
|
|
||||||
|
|
||||||
Returns `String` - The directory where crashes are temporarily stored before being uploaded.
|
|
||||||
|
|
||||||
**Note:** This method is deprecated, use `app.getPath('crashDumps')` instead.
|
|
||||||
|
|
||||||
### `crashReporter.addExtraParameter(key, value)`
|
### `crashReporter.addExtraParameter(key, value)`
|
||||||
|
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ extension capabilities.
|
|||||||
|
|
||||||
Electron only supports loading unpacked extensions (i.e., `.crx` files do not
|
Electron only supports loading unpacked extensions (i.e., `.crx` files do not
|
||||||
work). Extensions are installed per-`session`. To load an extension, call
|
work). Extensions are installed per-`session`. To load an extension, call
|
||||||
[`ses.loadExtension`](session.md#sesloadextensionpath):
|
[`ses.loadExtension`](session.md#sesloadextensionpath-options):
|
||||||
|
|
||||||
```js
|
```js
|
||||||
const { session } = require('electron')
|
const { session } = require('electron')
|
||||||
@@ -115,3 +115,9 @@ The following methods of `chrome.management` are supported:
|
|||||||
- `chrome.management.getPermissionWarningsByManifest`
|
- `chrome.management.getPermissionWarningsByManifest`
|
||||||
- `chrome.management.onEnabled`
|
- `chrome.management.onEnabled`
|
||||||
- `chrome.management.onDisabled`
|
- `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.
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ with the operating system so that you can customize the operations for various
|
|||||||
shortcuts.
|
shortcuts.
|
||||||
|
|
||||||
**Note:** The shortcut is global; it will work even if the app does
|
**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.
|
event of the app module is emitted.
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
|
|||||||
@@ -62,10 +62,9 @@ included. Sending Functions, Promises, Symbols, WeakMaps, or WeakSets will
|
|||||||
throw an exception.
|
throw an exception.
|
||||||
|
|
||||||
> **NOTE:** Sending non-standard JavaScript types such as DOM objects or
|
> **NOTE:** Sending non-standard JavaScript types such as DOM objects or
|
||||||
> special Electron objects is deprecated, and will begin throwing an exception
|
> special Electron objects will throw an exception.
|
||||||
> starting with Electron 9.
|
>
|
||||||
|
> Since the main process does not have support for DOM objects such as
|
||||||
> **NOTE:** 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
|
> `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
|
> 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.
|
> them. Attempting to send such objects over IPC will result in an error.
|
||||||
@@ -90,11 +89,10 @@ Algorithm][SCA], just like [`window.postMessage`][], so prototype chains will no
|
|||||||
included. Sending Functions, Promises, Symbols, WeakMaps, or WeakSets will
|
included. Sending Functions, Promises, Symbols, WeakMaps, or WeakSets will
|
||||||
throw an exception.
|
throw an exception.
|
||||||
|
|
||||||
> **NOTE**: Sending non-standard JavaScript types such as DOM objects or
|
> **NOTE:** Sending non-standard JavaScript types such as DOM objects or
|
||||||
> special Electron objects is deprecated, and will begin throwing an exception
|
> special Electron objects will throw an exception.
|
||||||
> starting with Electron 9.
|
>
|
||||||
|
> Since the main process does not have support for DOM objects such as
|
||||||
> **NOTE:** 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
|
> `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
|
> 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.
|
> them. Attempting to send such objects over IPC will result in an error.
|
||||||
@@ -134,11 +132,10 @@ Algorithm][SCA], just like [`window.postMessage`][], so prototype chains will no
|
|||||||
included. Sending Functions, Promises, Symbols, WeakMaps, or WeakSets will
|
included. Sending Functions, Promises, Symbols, WeakMaps, or WeakSets will
|
||||||
throw an exception.
|
throw an exception.
|
||||||
|
|
||||||
> **NOTE**: Sending non-standard JavaScript types such as DOM objects or
|
> **NOTE:** Sending non-standard JavaScript types such as DOM objects or
|
||||||
> special Electron objects is deprecated, and will begin throwing an exception
|
> special Electron objects will throw an exception.
|
||||||
> starting with Electron 9.
|
>
|
||||||
|
> Since the main process does not have support for DOM objects such as
|
||||||
> **NOTE:** 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
|
> `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
|
> 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.
|
> them. Attempting to send such objects over IPC will result in an error.
|
||||||
|
|||||||
@@ -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`
|
|
||||||
@@ -492,6 +492,7 @@ win.webContents.session.setCertificateVerifyProc((request, callback) => {
|
|||||||
* `permission` String - The type of requested permission.
|
* `permission` String - The type of requested permission.
|
||||||
* `clipboard-read` - Request access to read from the clipboard.
|
* `clipboard-read` - Request access to read from the clipboard.
|
||||||
* `media` - Request access to media devices such as camera, microphone and speakers.
|
* `media` - Request access to media devices such as camera, microphone and speakers.
|
||||||
|
* `display-capture` - Request access to capture the screen.
|
||||||
* `mediaKeySystem` - Request access to DRM protected content.
|
* `mediaKeySystem` - Request access to DRM protected content.
|
||||||
* `geolocation` - Request access to user's current location.
|
* `geolocation` - Request access to user's current location.
|
||||||
* `notifications` - Request notification creation and the ability to display them in the user's system tray.
|
* `notifications` - Request notification creation and the ability to display them in the user's system tray.
|
||||||
@@ -742,9 +743,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
|
**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
|
* `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.
|
Returns `Promise<Extension>` - resolves when the extension is loaded.
|
||||||
|
|
||||||
@@ -767,7 +772,11 @@ const { app, session } = require('electron')
|
|||||||
const path = require('path')
|
const path = require('path')
|
||||||
|
|
||||||
app.on('ready', async () => {
|
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
|
// Note that in order to use the React DevTools extension, you'll need to
|
||||||
// download and unzip a copy of the extension.
|
// download and unzip a copy of the extension.
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -1,8 +1,10 @@
|
|||||||
# IpcMainEvent Object extends `Event`
|
# 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
|
* `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
|
* `returnValue` any - Set this to the value to be returned in a synchronous message
|
||||||
* `sender` WebContents - Returns the `webContents` that sent the message
|
* `sender` WebContents - Returns the `webContents` that sent the message
|
||||||
|
* `senderFrame` WebFrameMain _Readonly_ - The frame that sent this message
|
||||||
* `ports` MessagePortMain[] - A list of MessagePorts that were transferred with this message
|
* `ports` MessagePortMain[] - A list of MessagePorts that were transferred with this message
|
||||||
* `reply` Function - A function that will send an IPC message to the renderer frame that sent the original message that you are currently handling. You should use this method to "reply" to the sent message in order to guarantee the reply will go to the correct process and frame.
|
* `reply` Function - A function that will send an IPC message to the renderer frame that sent the original message that you are currently handling. You should use this method to "reply" to the sent message in order to guarantee the reply will go to the correct process and frame.
|
||||||
* `channel` String
|
* `channel` String
|
||||||
|
|||||||
@@ -1,4 +1,6 @@
|
|||||||
# IpcMainInvokeEvent Object extends `Event`
|
# 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
|
* `frameId` Integer - The ID of the renderer frame that sent this message
|
||||||
* `sender` WebContents - Returns the `webContents` that sent the message
|
* `sender` WebContents - Returns the `webContents` that sent the message
|
||||||
|
* `senderFrame` WebFrameMain _Readonly_ - The frame that sent this message
|
||||||
|
|||||||
@@ -42,7 +42,8 @@ returns `null`.
|
|||||||
|
|
||||||
* `id` Integer
|
* `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
|
## Class: WebContents
|
||||||
|
|
||||||
@@ -155,7 +156,7 @@ Returns:
|
|||||||
be set. If no post data is to be sent, the value will be `null`. Only defined
|
be set. If no post data is to be sent, the value will be `null`. Only defined
|
||||||
when the window is being created by a form that set `target=_blank`.
|
when the window is being created by a form that set `target=_blank`.
|
||||||
|
|
||||||
Deprecated in favor of [`webContents.setWindowOpenHandler`](web-contents.md#contentssetwindowopenhandler-handler).
|
Deprecated in favor of [`webContents.setWindowOpenHandler`](web-contents.md#contentssetwindowopenhandlerhandler).
|
||||||
|
|
||||||
Emitted when the page requests to open a new window for a `url`. It could be
|
Emitted when the page requests to open a new window for a `url`. It could be
|
||||||
requested by `window.open` or an external link like `<a target='_blank'>`.
|
requested by `window.open` or an external link like `<a target='_blank'>`.
|
||||||
@@ -203,7 +204,7 @@ Returns:
|
|||||||
BrowserWindow. They are merged in increasing precedence: options inherited
|
BrowserWindow. They are merged in increasing precedence: options inherited
|
||||||
from the parent, parsed options from the `features` string from
|
from the parent, parsed options from the `features` string from
|
||||||
`window.open()`, and options given by
|
`window.open()`, and options given by
|
||||||
[`webContents.setWindowOpenHandler`](web-contents.md#contentssetwindowopenhandler-handler).
|
[`webContents.setWindowOpenHandler`](web-contents.md#contentssetwindowopenhandlerhandler).
|
||||||
Unrecognized options are not filtered out.
|
Unrecognized options are not filtered out.
|
||||||
* `additionalFeatures` String[] - The non-standard features (features not
|
* `additionalFeatures` String[] - The non-standard features (features not
|
||||||
handled Chromium or Electron) _Deprecated_
|
handled Chromium or Electron) _Deprecated_
|
||||||
@@ -220,7 +221,7 @@ Returns:
|
|||||||
|
|
||||||
Emitted _after_ successful creation of a window via `window.open` in the renderer.
|
Emitted _after_ successful creation of a window via `window.open` in the renderer.
|
||||||
Not emitted if the creation of the window is canceled from
|
Not emitted if the creation of the window is canceled from
|
||||||
[`webContents.setWindowOpenHandler`](web-contents.md#contentssetwindowopenhandler-handler).
|
[`webContents.setWindowOpenHandler`](web-contents.md#contentssetwindowopenhandlerhandler).
|
||||||
|
|
||||||
See [`window.open()`](window-open.md) for more details and how to use this in conjunction with `webContents.setWindowOpenHandler`.
|
See [`window.open()`](window-open.md) for more details and how to use this in conjunction with `webContents.setWindowOpenHandler`.
|
||||||
|
|
||||||
@@ -401,6 +402,9 @@ Returns:
|
|||||||
* `oom` - Process ran out of memory
|
* `oom` - Process ran out of memory
|
||||||
* `launch-failed` - Process never successfully launched
|
* `launch-failed` - Process never successfully launched
|
||||||
* `integrity-failure` - Windows code integrity checks failed
|
* `integrity-failure` - Windows code integrity checks failed
|
||||||
|
* `exitCode` Integer - The exit code of the process, unless `reason` is
|
||||||
|
`launch-failed`, in which case `exitCode` will be a platform-specific
|
||||||
|
launch failure error code.
|
||||||
|
|
||||||
Emitted when the renderer process unexpectedly disappears. This is normally
|
Emitted when the renderer process unexpectedly disappears. This is normally
|
||||||
because it was crashed or killed.
|
because it was crashed or killed.
|
||||||
@@ -1657,8 +1661,7 @@ included. Sending Functions, Promises, Symbols, WeakMaps, or WeakSets will
|
|||||||
throw an exception.
|
throw an exception.
|
||||||
|
|
||||||
> **NOTE**: Sending non-standard JavaScript types such as DOM objects or
|
> **NOTE**: Sending non-standard JavaScript types such as DOM objects or
|
||||||
> special Electron objects is deprecated, and will begin throwing an exception
|
> special Electron objects will throw an exception.
|
||||||
> starting with Electron 9.
|
|
||||||
|
|
||||||
The renderer process can handle the message by listening to `channel` with the
|
The renderer process can handle the message by listening to `channel` with the
|
||||||
[`ipcRenderer`](ipc-renderer.md) module.
|
[`ipcRenderer`](ipc-renderer.md) module.
|
||||||
@@ -1694,7 +1697,9 @@ app.whenReady().then(() => {
|
|||||||
|
|
||||||
#### `contents.sendToFrame(frameId, channel, ...args)`
|
#### `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
|
* `channel` String
|
||||||
* `...args` any[]
|
* `...args` any[]
|
||||||
|
|
||||||
@@ -1704,9 +1709,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
|
chains will not be included. Sending Functions, Promises, Symbols, WeakMaps, or
|
||||||
WeakSets will throw an exception.
|
WeakSets will throw an exception.
|
||||||
|
|
||||||
> **NOTE**: Sending non-standard JavaScript types such as DOM objects or
|
> **NOTE:** Sending non-standard JavaScript types such as DOM objects or
|
||||||
> special Electron objects is deprecated, and will begin throwing an exception
|
> special Electron objects will throw an exception.
|
||||||
> starting with Electron 9.
|
|
||||||
|
|
||||||
The renderer process can handle the message by listening to `channel` with the
|
The renderer process can handle the message by listening to `channel` with the
|
||||||
[`ipcRenderer`](ipc-renderer.md) module.
|
[`ipcRenderer`](ipc-renderer.md) module.
|
||||||
@@ -1869,7 +1873,7 @@ Returns `Boolean` - If *offscreen rendering* is enabled returns whether it is cu
|
|||||||
* `fps` Integer
|
* `fps` Integer
|
||||||
|
|
||||||
If *offscreen rendering* is enabled sets the frame rate to the specified number.
|
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()`
|
#### `contents.getFrameRate()`
|
||||||
|
|
||||||
@@ -1967,7 +1971,7 @@ The zoom factor is the zoom percent divided by 100, so 300% = 3.0.
|
|||||||
#### `contents.frameRate`
|
#### `contents.frameRate`
|
||||||
|
|
||||||
An `Integer` property that sets the frame rate of the web contents to the specified number.
|
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.
|
Only applicable if *offscreen rendering* is enabled.
|
||||||
|
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ win.webContents.on(
|
|||||||
)
|
)
|
||||||
```
|
```
|
||||||
|
|
||||||
You can also access frames of existing pages by using the `webFrame` property
|
You can also access frames of existing pages by using the `mainFrame` property
|
||||||
of [`WebContents`](web-contents.md).
|
of [`WebContents`](web-contents.md).
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
@@ -57,13 +57,14 @@ These methods can be accessed from the `webFrameMain` module:
|
|||||||
|
|
||||||
### `webFrameMain.fromId(processId, routingId)`
|
### `webFrameMain.fromId(processId, routingId)`
|
||||||
|
|
||||||
* `processId` Integer - An `Integer` representing the id of the process which owns the frame.
|
* `processId` Integer - An `Integer` representing the internal ID of the process which owns the frame.
|
||||||
* `routingId` Integer - An `Integer` representing the unique frame id in the
|
* `routingId` Integer - An `Integer` representing the unique frame ID in the
|
||||||
current renderer process. Routing IDs can be retrieved from `WebFrameMain`
|
current renderer process. Routing IDs can be retrieved from `WebFrameMain`
|
||||||
instances (`frame.routingId`) and are also passed by frame
|
instances (`frame.routingId`) and are also passed by frame
|
||||||
specific `WebContents` navigation events (e.g. `did-frame-navigate`).
|
specific `WebContents` navigation events (e.g. `did-frame-navigate`).
|
||||||
|
|
||||||
Returns `WebFrameMain` - A frame with the given process and routing IDs.
|
Returns `WebFrameMain | undefined` - A frame with the given process and routing IDs,
|
||||||
|
or `undefined` if there is no WebFrameMain associated with the given IDs.
|
||||||
|
|
||||||
## Class: WebFrameMain
|
## Class: WebFrameMain
|
||||||
|
|
||||||
@@ -89,6 +90,47 @@ this limitation.
|
|||||||
|
|
||||||
Returns `boolean` - Whether the reload was initiated successfully. Only results in `false` when the frame has no history.
|
Returns `boolean` - Whether the reload was initiated successfully. Only results in `false` when the frame has no history.
|
||||||
|
|
||||||
|
#### `frame.send(channel, ...args)`
|
||||||
|
|
||||||
|
* `channel` String
|
||||||
|
* `...args` any[]
|
||||||
|
|
||||||
|
Send an asynchronous message to the renderer process via `channel`, along with
|
||||||
|
arguments. Arguments will be serialized with the [Structured Clone
|
||||||
|
Algorithm][SCA], just like [`postMessage`][], so prototype chains will not be
|
||||||
|
included. Sending Functions, Promises, Symbols, WeakMaps, or WeakSets will
|
||||||
|
throw an exception.
|
||||||
|
|
||||||
|
The renderer process can handle the message by listening to `channel` with the
|
||||||
|
[`ipcRenderer`](ipc-renderer.md) module.
|
||||||
|
|
||||||
|
#### `frame.postMessage(channel, message, [transfer])`
|
||||||
|
|
||||||
|
* `channel` String
|
||||||
|
* `message` any
|
||||||
|
* `transfer` MessagePortMain[] (optional)
|
||||||
|
|
||||||
|
Send a message to the renderer process, optionally transferring ownership of
|
||||||
|
zero or more [`MessagePortMain`][] objects.
|
||||||
|
|
||||||
|
The transferred `MessagePortMain` objects will be available in the renderer
|
||||||
|
process by accessing the `ports` property of the emitted event. When they
|
||||||
|
arrive in the renderer, they will be native DOM `MessagePort` objects.
|
||||||
|
|
||||||
|
For example:
|
||||||
|
|
||||||
|
```js
|
||||||
|
// Main process
|
||||||
|
const { port1, port2 } = new MessageChannelMain()
|
||||||
|
webContents.mainFrame.postMessage('port', { message: 'hello' }, [port1])
|
||||||
|
|
||||||
|
// Renderer process
|
||||||
|
ipcRenderer.on('port', (e, msg) => {
|
||||||
|
const [port] = e.ports
|
||||||
|
// ...
|
||||||
|
})
|
||||||
|
```
|
||||||
|
|
||||||
### Instance Properties
|
### Instance Properties
|
||||||
|
|
||||||
#### `frame.url` _Readonly_
|
#### `frame.url` _Readonly_
|
||||||
|
|||||||
@@ -51,6 +51,8 @@ The following methods are available on instances of `WebRequest`:
|
|||||||
* `url` String
|
* `url` String
|
||||||
* `method` String
|
* `method` String
|
||||||
* `webContentsId` Integer (optional)
|
* `webContentsId` Integer (optional)
|
||||||
|
* `webContents` WebContents (optional)
|
||||||
|
* `frame` WebFrameMain (optional)
|
||||||
* `resourceType` String
|
* `resourceType` String
|
||||||
* `referrer` String
|
* `referrer` String
|
||||||
* `timestamp` Double
|
* `timestamp` Double
|
||||||
@@ -94,6 +96,8 @@ Some examples of valid `urls`:
|
|||||||
* `url` String
|
* `url` String
|
||||||
* `method` String
|
* `method` String
|
||||||
* `webContentsId` Integer (optional)
|
* `webContentsId` Integer (optional)
|
||||||
|
* `webContents` WebContents (optional)
|
||||||
|
* `frame` WebFrameMain (optional)
|
||||||
* `resourceType` String
|
* `resourceType` String
|
||||||
* `referrer` String
|
* `referrer` String
|
||||||
* `timestamp` Double
|
* `timestamp` Double
|
||||||
@@ -121,6 +125,8 @@ The `callback` has to be called with a `response` object.
|
|||||||
* `url` String
|
* `url` String
|
||||||
* `method` String
|
* `method` String
|
||||||
* `webContentsId` Integer (optional)
|
* `webContentsId` Integer (optional)
|
||||||
|
* `webContents` WebContents (optional)
|
||||||
|
* `frame` WebFrameMain (optional)
|
||||||
* `resourceType` String
|
* `resourceType` String
|
||||||
* `referrer` String
|
* `referrer` String
|
||||||
* `timestamp` Double
|
* `timestamp` Double
|
||||||
@@ -141,6 +147,8 @@ response are visible by the time this listener is fired.
|
|||||||
* `url` String
|
* `url` String
|
||||||
* `method` String
|
* `method` String
|
||||||
* `webContentsId` Integer (optional)
|
* `webContentsId` Integer (optional)
|
||||||
|
* `webContents` WebContents (optional)
|
||||||
|
* `frame` WebFrameMain (optional)
|
||||||
* `resourceType` String
|
* `resourceType` String
|
||||||
* `referrer` String
|
* `referrer` String
|
||||||
* `timestamp` Double
|
* `timestamp` Double
|
||||||
@@ -173,6 +181,8 @@ The `callback` has to be called with a `response` object.
|
|||||||
* `url` String
|
* `url` String
|
||||||
* `method` String
|
* `method` String
|
||||||
* `webContentsId` Integer (optional)
|
* `webContentsId` Integer (optional)
|
||||||
|
* `webContents` WebContents (optional)
|
||||||
|
* `frame` WebFrameMain (optional)
|
||||||
* `resourceType` String
|
* `resourceType` String
|
||||||
* `referrer` String
|
* `referrer` String
|
||||||
* `timestamp` Double
|
* `timestamp` Double
|
||||||
@@ -197,6 +207,8 @@ and response headers are available.
|
|||||||
* `url` String
|
* `url` String
|
||||||
* `method` String
|
* `method` String
|
||||||
* `webContentsId` Integer (optional)
|
* `webContentsId` Integer (optional)
|
||||||
|
* `webContents` WebContents (optional)
|
||||||
|
* `frame` WebFrameMain (optional)
|
||||||
* `resourceType` String
|
* `resourceType` String
|
||||||
* `referrer` String
|
* `referrer` String
|
||||||
* `timestamp` Double
|
* `timestamp` Double
|
||||||
@@ -222,6 +234,8 @@ redirect is about to occur.
|
|||||||
* `url` String
|
* `url` String
|
||||||
* `method` String
|
* `method` String
|
||||||
* `webContentsId` Integer (optional)
|
* `webContentsId` Integer (optional)
|
||||||
|
* `webContents` WebContents (optional)
|
||||||
|
* `frame` WebFrameMain (optional)
|
||||||
* `resourceType` String
|
* `resourceType` String
|
||||||
* `referrer` String
|
* `referrer` String
|
||||||
* `timestamp` Double
|
* `timestamp` Double
|
||||||
@@ -245,6 +259,8 @@ completed.
|
|||||||
* `url` String
|
* `url` String
|
||||||
* `method` String
|
* `method` String
|
||||||
* `webContentsId` Integer (optional)
|
* `webContentsId` Integer (optional)
|
||||||
|
* `webContents` WebContents (optional)
|
||||||
|
* `frame` WebFrameMain (optional)
|
||||||
* `resourceType` String
|
* `resourceType` String
|
||||||
* `referrer` String
|
* `referrer` String
|
||||||
* `timestamp` Double
|
* `timestamp` Double
|
||||||
|
|||||||
@@ -966,4 +966,4 @@ Emitted when DevTools is closed.
|
|||||||
Emitted when DevTools is focused / opened.
|
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
|
[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/
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ BrowserWindow constructor options are set by, in increasing precedence
|
|||||||
order: options inherited from the parent, parsed options
|
order: options inherited from the parent, parsed options
|
||||||
from the `features` string from `window.open()`, security-related webPreferences
|
from the `features` string from `window.open()`, security-related webPreferences
|
||||||
inherited from the parent, and options given by
|
inherited from the parent, and options given by
|
||||||
[`webContents.setWindowOpenHandler`](web-contents.md#contentssetwindowopenhandler-handler).
|
[`webContents.setWindowOpenHandler`](web-contents.md#contentssetwindowopenhandlerhandler).
|
||||||
Note that `webContents.setWindowOpenHandler` has final say and full privilege
|
Note that `webContents.setWindowOpenHandler` has final say and full privilege
|
||||||
because it is invoked in the main process.
|
because it is invoked in the main process.
|
||||||
|
|
||||||
@@ -83,9 +83,9 @@ const mainWindow = new BrowserWindow()
|
|||||||
|
|
||||||
mainWindow.webContents.setWindowOpenHandler(({ url }) => {
|
mainWindow.webContents.setWindowOpenHandler(({ url }) => {
|
||||||
if (url.startsWith('https://github.com/')) {
|
if (url.startsWith('https://github.com/')) {
|
||||||
return true
|
return { action: 'allow' }
|
||||||
}
|
}
|
||||||
return false
|
return { action: 'deny' }
|
||||||
})
|
})
|
||||||
|
|
||||||
mainWindow.webContents.on('did-create-window', (childWindow) => {
|
mainWindow.webContents.on('did-create-window', (childWindow) => {
|
||||||
|
|||||||
@@ -12,6 +12,16 @@ This document uses the following convention to categorize breaking changes:
|
|||||||
- **Deprecated:** An API was marked as deprecated. The API will continue to function, but will emit a deprecation warning, and will be removed in a future release.
|
- **Deprecated:** An API was marked as deprecated. The API will continue to function, but will emit a deprecation warning, and will be removed in a future release.
|
||||||
- **Removed:** An API or feature was removed, and is no longer supported by Electron.
|
- **Removed:** An API or feature was removed, and is no longer supported by Electron.
|
||||||
|
|
||||||
|
## Planned Breaking API Changes (14.0)
|
||||||
|
|
||||||
|
### Removed: `worldSafeExecuteJavaScript`
|
||||||
|
|
||||||
|
In Electron 14, `worldSafeExecuteJavaScript` will be removed. There is no alternative, please
|
||||||
|
ensure your code works with this property enabled. It has been enabled by default since Electron
|
||||||
|
12.
|
||||||
|
|
||||||
|
You will be affected by this change if you use either `webFrame.executeJavaScript` or `webFrame.executeJavaScriptInIsolatedWorld`. You will need to ensure that values returned by either of those methods are supported by the [Context Bridge API](api/context-bridge.md#parameter--error--return-type-support) as these methods use the same value passing semantics.
|
||||||
|
|
||||||
## Planned Breaking API Changes (13.0)
|
## Planned Breaking API Changes (13.0)
|
||||||
|
|
||||||
### Removed: `shell.moveItemToTrash()`
|
### Removed: `shell.moveItemToTrash()`
|
||||||
@@ -34,6 +44,15 @@ Chromium has removed support for Flash, and so we must follow suit. See
|
|||||||
Chromium's [Flash Roadmap](https://www.chromium.org/flash-roadmap) for more
|
Chromium's [Flash Roadmap](https://www.chromium.org/flash-roadmap) for more
|
||||||
details.
|
details.
|
||||||
|
|
||||||
|
### Default Changed: `worldSafeExecuteJavaScript` defaults to `true`
|
||||||
|
|
||||||
|
In Electron 12, `worldSafeExecuteJavaScript` will be enabled by default. To restore
|
||||||
|
the previous behavior, `worldSafeExecuteJavaScript: false` must be specified in WebPreferences.
|
||||||
|
Please note that setting this option to `false` is **insecure**.
|
||||||
|
|
||||||
|
This option will be removed in Electron 14 so please migrate your code to support the default
|
||||||
|
value.
|
||||||
|
|
||||||
### Default Changed: `contextIsolation` defaults to `true`
|
### Default Changed: `contextIsolation` defaults to `true`
|
||||||
|
|
||||||
In Electron 12, `contextIsolation` will be enabled by default. To restore
|
In Electron 12, `contextIsolation` will be enabled by default. To restore
|
||||||
@@ -43,6 +62,18 @@ We [recommend having contextIsolation enabled](https://github.com/electron/elect
|
|||||||
|
|
||||||
For more details see: https://github.com/electron/electron/issues/23506
|
For more details see: https://github.com/electron/electron/issues/23506
|
||||||
|
|
||||||
|
### Removed: `crashReporter.getCrashesDirectory()`
|
||||||
|
|
||||||
|
The `crashReporter.getCrashesDirectory` method has been removed. Usage
|
||||||
|
should be replaced by `app.getPath('crashDumps')`.
|
||||||
|
|
||||||
|
```js
|
||||||
|
// Removed in Electron 12
|
||||||
|
crashReporter.getCrashesDirectory()
|
||||||
|
// Replace with
|
||||||
|
app.getPath('crashDumps')
|
||||||
|
```
|
||||||
|
|
||||||
### Removed: `crashReporter` methods in the renderer process
|
### Removed: `crashReporter` methods in the renderer process
|
||||||
|
|
||||||
The following `crashReporter` methods are no longer available in the renderer
|
The following `crashReporter` methods are no longer available in the renderer
|
||||||
@@ -251,6 +282,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).
|
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()`
|
### Removed: `<webview>.getWebContents()`
|
||||||
|
|
||||||
This API, which was deprecated in Electron 8.0, is now removed.
|
This API, which was deprecated in Electron 8.0, is now removed.
|
||||||
@@ -397,6 +467,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
|
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).
|
[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)
|
## Planned Breaking API Changes (7.0)
|
||||||
|
|
||||||
### Deprecated: Atom.io Node Headers URL
|
### Deprecated: Atom.io Node Headers URL
|
||||||
@@ -496,6 +612,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,
|
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)).
|
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)
|
## Planned Breaking API Changes (6.0)
|
||||||
|
|
||||||
### API Changed: `win.setMenu(null)` is now `win.removeMenu()`
|
### API Changed: `win.setMenu(null)` is now `win.removeMenu()`
|
||||||
@@ -507,19 +672,6 @@ win.setMenu(null)
|
|||||||
win.removeMenu()
|
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`
|
### API Changed: `electron.screen` in the renderer process should be accessed via `remote`
|
||||||
|
|
||||||
```js
|
```js
|
||||||
@@ -658,6 +810,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)
|
## Planned Breaking API Changes (4.0)
|
||||||
|
|
||||||
The following list includes the breaking API changes made in Electron 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
|
If you're developing Electron and don't plan to redistribute your
|
||||||
custom Electron build, you may skip this section.
|
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
|
## Building Electron
|
||||||
|
|
||||||
|
|||||||
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()
|
||||||
|
}
|
||||||
|
})
|
||||||
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 <span id="node-version"></span>,
|
||||||
|
Chrome <span id="chrome-version"></span>,
|
||||||
|
and Electron <span id="electron-version"></span>.
|
||||||
|
</p>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
31
docs/fiddles/quick-start/main.js
Normal file
31
docs/fiddles/quick-start/main.js
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
const { app, BrowserWindow } = require('electron')
|
||||||
|
const path = require('path')
|
||||||
|
|
||||||
|
function createWindow () {
|
||||||
|
const win = new BrowserWindow({
|
||||||
|
width: 800,
|
||||||
|
height: 600,
|
||||||
|
webPreferences: {
|
||||||
|
preload: path.join(__dirname, 'preload.js')
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
win.loadFile('index.html')
|
||||||
|
}
|
||||||
|
|
||||||
|
app.whenReady().then(() => {
|
||||||
|
createWindow()
|
||||||
|
|
||||||
|
app.on('activate', () => {
|
||||||
|
if (BrowserWindow.getAllWindows().length === 0) {
|
||||||
|
createWindow()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
app.on('window-all-closed', () => {
|
||||||
|
if (process.platform !== 'darwin') {
|
||||||
|
app.quit()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
11
docs/fiddles/quick-start/preload.js
Normal file
11
docs/fiddles/quick-start/preload.js
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
window.addEventListener('DOMContentLoaded', () => {
|
||||||
|
const replaceText = (selector, text) => {
|
||||||
|
const element = document.getElementById(selector)
|
||||||
|
if (element) element.innerText = text
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const type of ['chrome', 'node', 'electron']) {
|
||||||
|
replaceText(`${type}-version`, process.versions[type])
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
@@ -1,25 +1,28 @@
|
|||||||
# DevTools Extension
|
# DevTools Extension
|
||||||
|
|
||||||
Electron supports the [Chrome DevTools Extension][devtools-extension], which can
|
Electron supports [Chrome DevTools extensions][devtools-extension], which can
|
||||||
be used to extend the ability of devtools for debugging popular web frameworks.
|
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.
|
The easiest way to load a DevTools extension is to use third-party tooling to automate the
|
||||||
You may also try
|
process for you. [electron-devtools-installer][electron-devtools-installer] is a popular
|
||||||
[electron-devtools-installer](https://github.com/GPMDP/electron-devtools-installer),
|
NPM package that does just that.
|
||||||
a third-party tool that downloads extensions directly from the Chrome WebStore.
|
|
||||||
|
|
||||||
To load an extension in Electron, you need to download it in Chrome browser,
|
## Manually loading a DevTools extension
|
||||||
locate its filesystem path, and then load it by calling the
|
|
||||||
`BrowserWindow.addDevToolsExtension(extension)` API.
|
|
||||||
|
|
||||||
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
|
1. Navigate to `chrome://extensions`, and find its extension ID, which is a hash
|
||||||
string like `fmkadmapgofadopljbjfkapdkoienihi`.
|
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 Windows it is `%LOCALAPPDATA%\Google\Chrome\User Data\Default\Extensions`;
|
||||||
* on Linux it could be:
|
* on Linux it could be:
|
||||||
* `~/.config/google-chrome/Default/Extensions/`
|
* `~/.config/google-chrome/Default/Extensions/`
|
||||||
@@ -27,37 +30,48 @@ Using the [React Developer Tools][react-devtools] as example:
|
|||||||
* `~/.config/google-chrome-canary/Default/Extensions/`
|
* `~/.config/google-chrome-canary/Default/Extensions/`
|
||||||
* `~/.config/chromium/Default/Extensions/`
|
* `~/.config/chromium/Default/Extensions/`
|
||||||
* on macOS it is `~/Library/Application Support/Google/Chrome/Default/Extensions`.
|
* on macOS it is `~/Library/Application Support/Google/Chrome/Default/Extensions`.
|
||||||
1. Pass the location of the extension to `BrowserWindow.addDevToolsExtension`
|
1. Pass the location of the extension to the [`ses.loadExtension`][load-extension]
|
||||||
API, for the React Developer Tools, it is something like:
|
API. For React Developer Tools `v4.9.0`, it looks something like:
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
const path = require('path')
|
const { app, session } = require('electron')
|
||||||
const os = require('os')
|
const path = require('path')
|
||||||
|
const os = require('os')
|
||||||
|
|
||||||
BrowserWindow.addDevToolsExtension(
|
// on macOS
|
||||||
path.join(os.homedir(), '/Library/Application Support/Google/Chrome/Default/Extensions/fmkadmapgofadopljbjfkapdkoienihi/4.3.0_0')
|
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
|
**Notes:**
|
||||||
ready event of the app module is emitted.
|
|
||||||
|
|
||||||
The extension will be remembered so you only need to call this API once per
|
* `loadExtension` returns a Promise with an [Extension object][extension-structure],
|
||||||
extension. If you try to add an extension that has already been loaded, this method
|
which contains metadata about the extension that was loaded. This promise needs to
|
||||||
will not return and instead log a warning to the console.
|
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`
|
You can pass the extension's ID to the [`ses.removeExtension`][remove-extension] API to
|
||||||
API to remove it. The name of the extension is returned by
|
remove it from your Session. Loaded extensions are not persisted between
|
||||||
`BrowserWindow.addDevToolsExtension` and you can get the names of all installed
|
app launches.
|
||||||
DevTools Extensions using the `BrowserWindow.getDevToolsExtensions` API.
|
|
||||||
|
|
||||||
## Supported DevTools Extensions
|
## DevTools extension support
|
||||||
|
|
||||||
Electron only supports a limited set of `chrome.*` APIs, so some extensions
|
Electron only supports
|
||||||
using unsupported `chrome.*` APIs for chrome extension features may not work.
|
[a limited set of `chrome.*` APIs][supported-extension-apis],
|
||||||
Following Devtools Extensions are tested and guaranteed to work in Electron:
|
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)
|
* [Ember Inspector](https://chrome.google.com/webstore/detail/ember-inspector/bmdblncegkenkacieihfhpjfppoconhi)
|
||||||
* [React Developer Tools](https://chrome.google.com/webstore/detail/react-developer-tools/fmkadmapgofadopljbjfkapdkoienihi)
|
* [React Developer Tools](https://chrome.google.com/webstore/detail/react-developer-tools/fmkadmapgofadopljbjfkapdkoienihi)
|
||||||
@@ -69,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)
|
* [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)
|
* [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
|
First, please make sure the extension is still being maintained and is compatible
|
||||||
can not even work for recent versions of Chrome browser, and we are not able to
|
with the latest version of Google Chrome. We cannot provide additional support for
|
||||||
do anything for them.
|
unsupported extensions.
|
||||||
|
|
||||||
Then file a bug at Electron's issues list, and describe which part of the
|
If the extension works on Chrome but not on Electron, file a bug in Electron's
|
||||||
extension is not working as expected.
|
[issue tracker][issue-tracker] and describe which part
|
||||||
|
of the extension is not working as expected.
|
||||||
|
|
||||||
[devtools-extension]: https://developer.chrome.com/extensions/devtools
|
[devtools-extension]: https://developer.chrome.com/extensions/devtools
|
||||||
|
[session]: ../api/session.md
|
||||||
[react-devtools]: https://chrome.google.com/webstore/detail/react-developer-tools/fmkadmapgofadopljbjfkapdkoienihi
|
[react-devtools]: https://chrome.google.com/webstore/detail/react-developer-tools/fmkadmapgofadopljbjfkapdkoienihi
|
||||||
|
[load-extension]: ../api/session.md#sesloadextensionpath-options
|
||||||
|
[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
|
||||||
|
|||||||
@@ -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
|
`'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,
|
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
|
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.
|
performance loss.
|
||||||
|
|
||||||
**Note:** An offscreen window is always created as a [Frameless Window](../api/frameless-window.md).
|
**Note:** An offscreen window is always created as a [Frameless Window](../api/frameless-window.md).
|
||||||
|
|||||||
@@ -32,6 +32,7 @@ From a development perspective, an Electron application is essentially a Node.js
|
|||||||
my-electron-app/
|
my-electron-app/
|
||||||
├── package.json
|
├── package.json
|
||||||
├── main.js
|
├── main.js
|
||||||
|
├── preload.js
|
||||||
└── index.html
|
└── index.html
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -55,13 +56,14 @@ The main script may look as follows:
|
|||||||
|
|
||||||
```js
|
```js
|
||||||
const { app, BrowserWindow } = require('electron')
|
const { app, BrowserWindow } = require('electron')
|
||||||
|
const path = require('path')
|
||||||
|
|
||||||
function createWindow () {
|
function createWindow () {
|
||||||
const win = new BrowserWindow({
|
const win = new BrowserWindow({
|
||||||
width: 800,
|
width: 800,
|
||||||
height: 600,
|
height: 600,
|
||||||
webPreferences: {
|
webPreferences: {
|
||||||
nodeIntegration: true
|
preload: path.join(__dirname, 'preload.js')
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -69,32 +71,35 @@ function createWindow () {
|
|||||||
win.webContents.openDevTools()
|
win.webContents.openDevTools()
|
||||||
}
|
}
|
||||||
|
|
||||||
app.whenReady().then(createWindow)
|
app.whenReady().then(() => {
|
||||||
|
createWindow()
|
||||||
|
|
||||||
|
app.on('activate', () => {
|
||||||
|
if (BrowserWindow.getAllWindows().length === 0) {
|
||||||
|
createWindow()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
app.on('window-all-closed', () => {
|
app.on('window-all-closed', () => {
|
||||||
if (process.platform !== 'darwin') {
|
if (process.platform !== 'darwin') {
|
||||||
app.quit()
|
app.quit()
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
app.on('activate', () => {
|
|
||||||
if (BrowserWindow.getAllWindows().length === 0) {
|
|
||||||
createWindow()
|
|
||||||
}
|
|
||||||
})
|
|
||||||
```
|
```
|
||||||
|
|
||||||
##### What is going on above?
|
##### What is going on above?
|
||||||
|
|
||||||
1. Line 1: First, you import the `app` and `BrowserWindow` modules of the `electron` package to be able to manage your application's lifecycle events, as well as create and control browser windows.
|
1. Line 1: First, you import the `app` and `BrowserWindow` modules of the `electron` package to be able to manage your application's lifecycle events, as well as create and control browser windows.
|
||||||
2. Line 3: After that, you define a function that creates a [new browser window](../api/browser-window.md#new-browserwindowoptions) with node integration enabled, loads `index.html` file into this window (line 12, we will discuss the file later) and opens Developer Tools (line 13).
|
2. Line 2: Second, you import the `path` package which provides utility functions for file paths.
|
||||||
3. Line 16: You create a new browser window by invoking the `createWindow` function once the Electron application [is initialized](../api/app.md#appwhenready).
|
3. Line 4: After that, you define a function that creates a [new browser window](../api/browser-window.md#new-browserwindowoptions) with a preload script, loads `index.html` file into this window (line 13, we will discuss the file later).
|
||||||
4. Line 18: You add a new listener that tries to quit the application when it no longer has any open windows. This listener is a no-op on macOS due to the operating system's [window management behavior](https://support.apple.com/en-ca/guide/mac-help/mchlp2469/mac).
|
4. Line 16: You create a new browser window by invoking the `createWindow` function once the Electron application [is initialized](../api/app.md#appwhenready).
|
||||||
5. Line 24: You add a new listener that creates a new browser window only if when the application has no visible windows after being activated. For example, after launching the application for the first time, or re-launching the already running application.
|
5. Line 18: You add a new listener that creates a new browser window only if when the application has no visible windows after being activated. For example, after launching the application for the first time, or re-launching the already running application.
|
||||||
|
6. Line 25: You add a new listener that tries to quit the application when it no longer has any open windows. This listener is a no-op on macOS due to the operating system's [window management behavior](https://support.apple.com/en-ca/guide/mac-help/mchlp2469/mac).
|
||||||
|
|
||||||
#### Create a web page
|
#### Create a web page
|
||||||
|
|
||||||
This is the web page you want to display once the application is initialized. This web page represents the Renderer process. You can create multiple browser windows, where each window uses its own independent Renderer. Each window can optionally be granted with full access to Node.js API through the `nodeIntegration` preference.
|
This is the web page you want to display once the application is initialized. This web page represents the Renderer process. You can create multiple browser windows, where each window uses its own independent Renderer. You can optionally grant access to additional Node.js APIs by exposing them from your preload script.
|
||||||
|
|
||||||
The `index.html` page looks as follows:
|
The `index.html` page looks as follows:
|
||||||
|
|
||||||
@@ -108,13 +113,37 @@ The `index.html` page looks as follows:
|
|||||||
</head>
|
</head>
|
||||||
<body style="background: white;">
|
<body style="background: white;">
|
||||||
<h1>Hello World!</h1>
|
<h1>Hello World!</h1>
|
||||||
We are using node <script>document.write(process.versions.node)</script>,
|
We are using node <span id="node-version"></span>,
|
||||||
Chrome <script>document.write(process.versions.chrome)</script>,
|
Chrome <span id="chrome-version"></span>,
|
||||||
and Electron <script>document.write(process.versions.electron)</script>.
|
and Electron <span id="electron-version"></span>.
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
```
|
```
|
||||||
|
|
||||||
|
#### Define a preload script
|
||||||
|
|
||||||
|
Your preload script acts as a bridge between Node.js and your web page. It allows you to expose specific APIs and behaviors to your web page rather than insecurely exposing the entire Node.js API. In this example we will use the preload script to read version information from the `process` object and update the web page with that info.
|
||||||
|
|
||||||
|
```javascript fiddle='docs/fiddles/quick-start'
|
||||||
|
window.addEventListener('DOMContentLoaded', () => {
|
||||||
|
const replaceText = (selector, text) => {
|
||||||
|
const element = document.getElementById(selector)
|
||||||
|
if (element) element.innerText = text
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const type of ['chrome', 'node', 'electron']) {
|
||||||
|
replaceText(`${type}-version`, process.versions[type])
|
||||||
|
}
|
||||||
|
})
|
||||||
|
```
|
||||||
|
|
||||||
|
##### What's going on above?
|
||||||
|
|
||||||
|
1. On line 1: First you define an event listener that tells you when the web page has loaded
|
||||||
|
2. On line 2: Second you define a utility function used to set the text of the placeholders in the `index.html`
|
||||||
|
3. On line 7: Next you loop through the list of components whose version you want to display
|
||||||
|
4. On line 8: Finally, you call `replaceText` to look up the version placeholders in `index.html` and set their text value to the values from `process.versions`
|
||||||
|
|
||||||
#### Modify your package.json file
|
#### Modify your package.json file
|
||||||
|
|
||||||
Your Electron application uses the `package.json` file as the main entry point (as any other Node.js application). The main script of your application is `main.js`, so modify the `package.json` file accordingly:
|
Your Electron application uses the `package.json` file as the main entry point (as any other Node.js application). The main script of your application is `main.js`, so modify the `package.json` file accordingly:
|
||||||
@@ -275,7 +304,7 @@ ipcRenderer.invoke('perform-action', ...args)
|
|||||||
|
|
||||||
##### Node.js API
|
##### Node.js API
|
||||||
|
|
||||||
> NOTE: To access the Node.js API from the Renderer process, you need to set the `nodeIntegration` preference to `true`.
|
> NOTE: To access the Node.js API from the Renderer process, you need to set the `nodeIntegration` preference to `true` and the `contextIsolation` preference to `false`. Please note that access to the Node.js API in any renderer that loads remote content is not recommended for [security reasons](../tutorial/security.md#2-do-not-enable-nodejs-integration-for-remote-content).
|
||||||
|
|
||||||
Electron exposes full access to Node.js API and its modules both in the Main and the Renderer processes. For example, you can read all the files from the root directory:
|
Electron exposes full access to Node.js API and its modules both in the Main and the Renderer processes. For example, you can read all the files from the root directory:
|
||||||
|
|
||||||
|
|||||||
@@ -818,7 +818,7 @@ which potential security issues are not as widely known.
|
|||||||
[browser-view]: ../api/browser-view.md
|
[browser-view]: ../api/browser-view.md
|
||||||
[webview-tag]: ../api/webview-tag.md
|
[webview-tag]: ../api/webview-tag.md
|
||||||
[web-contents]: ../api/web-contents.md
|
[web-contents]: ../api/web-contents.md
|
||||||
[window-open-handler]: ../api/web-contents.md#contentssetwindowopenhandler-handler
|
[window-open-handler]: ../api/web-contents.md#contentssetwindowopenhandlerhandler
|
||||||
[will-navigate]: ../api/web-contents.md#event-will-navigate
|
[will-navigate]: ../api/web-contents.md#event-will-navigate
|
||||||
[open-external]: ../api/shell.md#shellopenexternalurl-options
|
[open-external]: ../api/shell.md#shellopenexternalurl-options
|
||||||
[sandbox]: ../api/sandbox-option.md
|
[sandbox]: ../api/sandbox-option.md
|
||||||
|
|||||||
@@ -91,9 +91,15 @@ template("electron_extra_paks") {
|
|||||||
}
|
}
|
||||||
|
|
||||||
# New paks should be added here by default.
|
# New paks should be added here by default.
|
||||||
sources +=
|
sources += [
|
||||||
[ "$root_gen_dir/content/browser/devtools/devtools_resources.pak" ]
|
"$root_gen_dir/content/browser/devtools/devtools_resources.pak",
|
||||||
|
"$root_gen_dir/ui/resources/webui_generated_resources.pak",
|
||||||
|
]
|
||||||
deps += [ "//content/browser/devtools:devtools_resources" ]
|
deps += [ "//content/browser/devtools:devtools_resources" ]
|
||||||
|
if (enable_pdf_viewer) {
|
||||||
|
sources += [ "$root_gen_dir/chrome/pdf_resources.pak" ]
|
||||||
|
deps += [ "//chrome/browser/resources/pdf:pdf_resources" ]
|
||||||
|
}
|
||||||
if (enable_print_preview) {
|
if (enable_print_preview) {
|
||||||
sources += [ "$root_gen_dir/chrome/print_preview_resources.pak" ]
|
sources += [ "$root_gen_dir/chrome/print_preview_resources.pak" ]
|
||||||
deps +=
|
deps +=
|
||||||
|
|||||||
@@ -83,5 +83,18 @@
|
|||||||
<message name="IDS_DOWNLOAD_MORE_ACTIONS"
|
<message name="IDS_DOWNLOAD_MORE_ACTIONS"
|
||||||
desc="Tooltip of a button on the downloads page that shows a menu with actions like 'Open downloads folder' or 'Clear all'">
|
desc="Tooltip of a button on the downloads page that shows a menu with actions like 'Open downloads folder' or 'Clear all'">
|
||||||
More actions
|
More actions
|
||||||
</message>
|
</message>
|
||||||
|
<!-- Badging -->
|
||||||
|
<message name="IDS_SATURATED_BADGE_CONTENT" desc="The content to display when the application's badge is too large to display to indicate that the badge is more than a given maximum. This string should be as short as possible, preferably only one character beyond the content">
|
||||||
|
<ph name="MAXIMUM_VALUE">$1<ex>99</ex></ph>+
|
||||||
|
</message>
|
||||||
|
<message name="IDS_BADGE_UNREAD_NOTIFICATIONS_SATURATED" desc="The accessibility text which will be read by a screen reader when the notification count is too large to display (e.g. greater than 99).">
|
||||||
|
{MAX_UNREAD_NOTIFICATIONS, plural, =1 {More than 1 unread notification} other {More than # unread notifications}}
|
||||||
|
</message>
|
||||||
|
<message name="IDS_BADGE_UNREAD_NOTIFICATIONS_UNSPECIFIED" desc="The accessibility text which will be read by a screen reader when there are some unspecified number of notifications, or user attention is required">
|
||||||
|
Unread Notifications
|
||||||
|
</message>
|
||||||
|
<message name="IDS_BADGE_UNREAD_NOTIFICATIONS" desc="The accessibility text which will be read by a screen reader when there are notifcatications">
|
||||||
|
{UNREAD_NOTIFICATIONS, plural, =1 {1 Unread Notification} other {# Unread Notifications}}
|
||||||
|
</message>
|
||||||
</grit-part>
|
</grit-part>
|
||||||
|
|||||||
@@ -34,7 +34,6 @@ auto_filenames = {
|
|||||||
"docs/api/menu.md",
|
"docs/api/menu.md",
|
||||||
"docs/api/message-channel-main.md",
|
"docs/api/message-channel-main.md",
|
||||||
"docs/api/message-port-main.md",
|
"docs/api/message-port-main.md",
|
||||||
"docs/api/modernization",
|
|
||||||
"docs/api/native-image.md",
|
"docs/api/native-image.md",
|
||||||
"docs/api/native-theme.md",
|
"docs/api/native-theme.md",
|
||||||
"docs/api/net-log.md",
|
"docs/api/net-log.md",
|
||||||
|
|||||||
@@ -328,6 +328,12 @@ filenames = {
|
|||||||
"shell/browser/api/ui_event.h",
|
"shell/browser/api/ui_event.h",
|
||||||
"shell/browser/auto_updater.cc",
|
"shell/browser/auto_updater.cc",
|
||||||
"shell/browser/auto_updater.h",
|
"shell/browser/auto_updater.h",
|
||||||
|
"shell/browser/badging/badge_manager.cc",
|
||||||
|
"shell/browser/badging/badge_manager.h",
|
||||||
|
"shell/browser/badging/badge_manager_factory.cc",
|
||||||
|
"shell/browser/badging/badge_manager_factory.h",
|
||||||
|
"shell/browser/bluetooth/electron_bluetooth_delegate.cc",
|
||||||
|
"shell/browser/bluetooth/electron_bluetooth_delegate.h",
|
||||||
"shell/browser/browser.cc",
|
"shell/browser/browser.cc",
|
||||||
"shell/browser/browser.h",
|
"shell/browser/browser.h",
|
||||||
"shell/browser/browser_observer.h",
|
"shell/browser/browser_observer.h",
|
||||||
@@ -345,6 +351,8 @@ filenames = {
|
|||||||
"shell/browser/electron_browser_client.h",
|
"shell/browser/electron_browser_client.h",
|
||||||
"shell/browser/electron_browser_context.cc",
|
"shell/browser/electron_browser_context.cc",
|
||||||
"shell/browser/electron_browser_context.h",
|
"shell/browser/electron_browser_context.h",
|
||||||
|
"shell/browser/electron_browser_handler_impl.cc",
|
||||||
|
"shell/browser/electron_browser_handler_impl.h",
|
||||||
"shell/browser/electron_browser_main_parts.cc",
|
"shell/browser/electron_browser_main_parts.cc",
|
||||||
"shell/browser/electron_browser_main_parts.h",
|
"shell/browser/electron_browser_main_parts.h",
|
||||||
"shell/browser/electron_download_manager_delegate.cc",
|
"shell/browser/electron_download_manager_delegate.cc",
|
||||||
|
|||||||
@@ -532,15 +532,17 @@ export const wrapFsWithAsar = (fs: Record<string, any>) => {
|
|||||||
return fs.readFile(realPath, options, callback);
|
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);
|
logASARAccess(asarPath, filePath, info.offset);
|
||||||
archive.read(info.offset, info.size).then((buf) => {
|
fs.read(fd, buffer, 0, info.size, info.offset, (error: Error) => {
|
||||||
const buffer = Buffer.from(buf);
|
callback(error, encoding ? buffer.toString(encoding) : buffer);
|
||||||
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);
|
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -573,19 +575,13 @@ export const wrapFsWithAsar = (fs: Record<string, any>) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const { encoding } = options;
|
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);
|
logASARAccess(asarPath, filePath, info.offset);
|
||||||
let arrayBuffer: ArrayBuffer;
|
fs.readSync(fd, buffer, 0, info.size, info.offset);
|
||||||
try {
|
return (encoding) ? buffer.toString(encoding) : buffer;
|
||||||
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;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const { readdir } = fs;
|
const { readdir } = fs;
|
||||||
@@ -615,9 +611,10 @@ export const wrapFsWithAsar = (fs: Record<string, any>) => {
|
|||||||
if (options.withFileTypes) {
|
if (options.withFileTypes) {
|
||||||
const dirents = [];
|
const dirents = [];
|
||||||
for (const file of files) {
|
for (const file of files) {
|
||||||
const stats = archive.stat(file);
|
const childPath = path.join(filePath, file);
|
||||||
|
const stats = archive.stat(childPath);
|
||||||
if (!stats) {
|
if (!stats) {
|
||||||
const error = createError(AsarError.NOT_FOUND, { asarPath, filePath: file });
|
const error = createError(AsarError.NOT_FOUND, { asarPath, filePath: childPath });
|
||||||
nextTick(callback!, [error]);
|
nextTick(callback!, [error]);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -657,9 +654,10 @@ export const wrapFsWithAsar = (fs: Record<string, any>) => {
|
|||||||
if (options && (options as any).withFileTypes) {
|
if (options && (options as any).withFileTypes) {
|
||||||
const dirents = [];
|
const dirents = [];
|
||||||
for (const file of files) {
|
for (const file of files) {
|
||||||
const stats = archive.stat(file);
|
const childPath = path.join(filePath, file);
|
||||||
|
const stats = archive.stat(childPath);
|
||||||
if (!stats) {
|
if (!stats) {
|
||||||
throw createError(AsarError.NOT_FOUND, { asarPath, filePath: file });
|
throw createError(AsarError.NOT_FOUND, { asarPath, filePath: childPath });
|
||||||
}
|
}
|
||||||
if (stats.isFile) {
|
if (stats.isFile) {
|
||||||
dirents.push(new fs.Dirent(file, fs.constants.UV_DIRENT_FILE));
|
dirents.push(new fs.Dirent(file, fs.constants.UV_DIRENT_FILE));
|
||||||
@@ -689,20 +687,16 @@ export const wrapFsWithAsar = (fs: Record<string, any>) => {
|
|||||||
if (info.size === 0) return ['', false];
|
if (info.size === 0) return ['', false];
|
||||||
if (info.unpacked) {
|
if (info.unpacked) {
|
||||||
const realPath = archive.copyFileOut(filePath);
|
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);
|
logASARAccess(asarPath, filePath, info.offset);
|
||||||
let arrayBuffer: ArrayBuffer;
|
fs.readSync(fd, buffer, 0, info.size, info.offset);
|
||||||
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);
|
|
||||||
const str = buffer.toString('utf8');
|
const str = buffer.toString('utf8');
|
||||||
return [str, str.length > 0];
|
return [str, str.length > 0];
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ Object.defineProperty(BaseWindow.prototype, 'kiosk', {
|
|||||||
});
|
});
|
||||||
|
|
||||||
Object.defineProperty(BaseWindow.prototype, 'documentEdited', {
|
Object.defineProperty(BaseWindow.prototype, 'documentEdited', {
|
||||||
get: function () { return this.isFullscreen(); },
|
get: function () { return this.isDocumentEdited(); },
|
||||||
set: function (edited) { this.setDocumentEdited(edited); }
|
set: function (edited) { this.setDocumentEdited(edited); }
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ class CrashReporter {
|
|||||||
|
|
||||||
if (submitURL == null) throw new Error('submitURL is a required option to crashReporter.start');
|
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.');
|
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.');
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -51,10 +51,6 @@ class CrashReporter {
|
|||||||
return binding.getUploadedReports();
|
return binding.getUploadedReports();
|
||||||
}
|
}
|
||||||
|
|
||||||
getCrashesDirectory () {
|
|
||||||
return app.getPath('crashDumps');
|
|
||||||
}
|
|
||||||
|
|
||||||
getUploadToServer () {
|
getUploadToServer () {
|
||||||
if (process.type === 'browser') {
|
if (process.type === 'browser') {
|
||||||
return binding.getUploadToServer();
|
return binding.getUploadToServer();
|
||||||
|
|||||||
@@ -119,10 +119,13 @@ class IncomingMessage extends Readable {
|
|||||||
this._shouldPush = this.push(chunk);
|
this._shouldPush = this.push(chunk);
|
||||||
}
|
}
|
||||||
if (this._shouldPush && this._resume) {
|
if (this._shouldPush && this._resume) {
|
||||||
this._resume();
|
|
||||||
// Reset the callback, so that a new one is used for each
|
// Reset the callback, so that a new one is used for each
|
||||||
// batch of throttled data
|
// batch of throttled data. Do this before calling resume to avoid a
|
||||||
|
// potential race-condition
|
||||||
|
const resume = this._resume;
|
||||||
this._resume = null;
|
this._resume = null;
|
||||||
|
|
||||||
|
resume();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -17,8 +17,12 @@ Object.setPrototypeOf(protocol, new Proxy({}, {
|
|||||||
|
|
||||||
ownKeys () {
|
ownKeys () {
|
||||||
if (!app.isReady()) return [];
|
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 () {
|
getOwnPropertyDescriptor () {
|
||||||
|
|||||||
@@ -1,20 +1,47 @@
|
|||||||
|
import { EventEmitter } from 'events';
|
||||||
const { createScreen } = process._linkedBinding('electron_common_screen');
|
const { createScreen } = process._linkedBinding('electron_common_screen');
|
||||||
|
|
||||||
let _screen: Electron.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
|
// We can't call createScreen until after app.on('ready'), but this module
|
||||||
// exposes an instance created by createScreen. In order to avoid
|
// exposes an instance created by createScreen. In order to avoid
|
||||||
// side-effecting and calling createScreen upon import of this module, instead
|
// side-effecting and calling createScreen upon import of this module, instead
|
||||||
// we export a proxy which lazily calls createScreen on first access.
|
// we export a proxy which lazily calls createScreen on first access.
|
||||||
export default new Proxy({}, {
|
export default new Proxy({}, {
|
||||||
get: (target, prop: keyof Electron.Screen) => {
|
get: (target, property: keyof Electron.Screen) => {
|
||||||
if (_screen === undefined) {
|
createScreenIfNeeded();
|
||||||
_screen = createScreen();
|
const value = _screen[property];
|
||||||
|
if (typeof value === 'function') {
|
||||||
|
return value.bind(_screen);
|
||||||
}
|
}
|
||||||
const v = _screen[prop];
|
return value;
|
||||||
if (typeof v === 'function') {
|
},
|
||||||
return v.bind(_screen);
|
set: (target, property: string, value: unknown) => {
|
||||||
}
|
createScreenIfNeeded();
|
||||||
return v;
|
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) {
|
if ('getEffectiveAppearance' in systemPreferences) {
|
||||||
const nativeEAGetter = systemPreferences.getAppLevelAppearance;
|
const nativeEAGetter = systemPreferences.getEffectiveAppearance;
|
||||||
Object.defineProperty(systemPreferences, 'effectiveAppearance', {
|
Object.defineProperty(systemPreferences, 'effectiveAppearance', {
|
||||||
get: () => nativeEAGetter.call(systemPreferences)
|
get: () => nativeEAGetter.call(systemPreferences)
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { app, ipcMain, session, deprecate, BrowserWindowConstructorOptions } from 'electron/main';
|
import { app, ipcMain, session, deprecate, webFrameMain } from 'electron/main';
|
||||||
import type { MenuItem, MenuItemConstructorOptions, LoadURLOptions } from 'electron/main';
|
import type { BrowserWindowConstructorOptions, MenuItem, MenuItemConstructorOptions, LoadURLOptions } from 'electron/main';
|
||||||
|
|
||||||
import * as url from 'url';
|
import * as url from 'url';
|
||||||
import * as path from 'path';
|
import * as path from 'path';
|
||||||
@@ -126,67 +126,40 @@ const binding = process._linkedBinding('electron_browser_web_contents');
|
|||||||
const printing = process._linkedBinding('electron_browser_printing');
|
const printing = process._linkedBinding('electron_browser_printing');
|
||||||
const { WebContents } = binding as { WebContents: { prototype: Electron.WebContents } };
|
const { WebContents } = binding as { WebContents: { prototype: Electron.WebContents } };
|
||||||
|
|
||||||
WebContents.prototype.send = function (channel, ...args) {
|
WebContents.prototype.postMessage = function (...args) {
|
||||||
if (typeof channel !== 'string') {
|
return this.mainFrame.postMessage(...args);
|
||||||
throw new Error('Missing required channel argument');
|
|
||||||
}
|
|
||||||
|
|
||||||
const internal = false;
|
|
||||||
const sendToAll = false;
|
|
||||||
|
|
||||||
return this._send(internal, sendToAll, channel, args);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
WebContents.prototype.postMessage = function (...args) {
|
WebContents.prototype.send = function (channel, ...args) {
|
||||||
if (Array.isArray(args[2])) {
|
return this.mainFrame.send(channel, ...args);
|
||||||
args[2] = args[2].map(o => o instanceof MessagePortMain ? o._internalPort : o);
|
|
||||||
}
|
|
||||||
this._postMessage(...args);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
WebContents.prototype._sendInternal = function (channel, ...args) {
|
WebContents.prototype._sendInternal = function (channel, ...args) {
|
||||||
if (typeof channel !== 'string') {
|
return this.mainFrame._sendInternal(channel, ...args);
|
||||||
throw new Error('Missing required channel argument');
|
|
||||||
}
|
|
||||||
|
|
||||||
const internal = true;
|
|
||||||
const sendToAll = false;
|
|
||||||
|
|
||||||
return this._send(internal, sendToAll, channel, args);
|
|
||||||
};
|
};
|
||||||
WebContents.prototype._sendInternalToAll = function (channel, ...args) {
|
|
||||||
if (typeof channel !== 'string') {
|
function getWebFrame (contents: Electron.WebContents, frame: number | [number, number]) {
|
||||||
throw new Error('Missing required channel argument');
|
if (typeof frame === 'number') {
|
||||||
|
return webFrameMain.fromId(contents.mainFrame.processId, frame);
|
||||||
|
} else if (Array.isArray(frame) && frame.length === 2 && frame.every(value => typeof value === 'number')) {
|
||||||
|
return webFrameMain.fromId(frame[0], frame[1]);
|
||||||
|
} else {
|
||||||
|
throw new Error('Missing required frame argument (must be number or [processId, frameId])');
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const internal = true;
|
|
||||||
const sendToAll = true;
|
|
||||||
|
|
||||||
return this._send(internal, sendToAll, channel, args);
|
|
||||||
};
|
|
||||||
WebContents.prototype.sendToFrame = function (frameId, channel, ...args) {
|
WebContents.prototype.sendToFrame = function (frameId, channel, ...args) {
|
||||||
if (typeof channel !== 'string') {
|
const frame = getWebFrame(this, frameId);
|
||||||
throw new Error('Missing required channel argument');
|
if (!frame) return false;
|
||||||
} else if (typeof frameId !== 'number') {
|
frame.send(channel, ...args);
|
||||||
throw new Error('Missing required frameId argument');
|
return true;
|
||||||
}
|
|
||||||
|
|
||||||
const internal = false;
|
|
||||||
const sendToAll = false;
|
|
||||||
|
|
||||||
return this._sendToFrame(internal, sendToAll, frameId, channel, args);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
WebContents.prototype._sendToFrameInternal = function (frameId, channel, ...args) {
|
WebContents.prototype._sendToFrameInternal = function (frameId, channel, ...args) {
|
||||||
if (typeof channel !== 'string') {
|
const frame = getWebFrame(this, frameId);
|
||||||
throw new Error('Missing required channel argument');
|
if (!frame) return false;
|
||||||
} else if (typeof frameId !== 'number') {
|
frame._sendInternal(channel, ...args);
|
||||||
throw new Error('Missing required frameId argument');
|
return true;
|
||||||
}
|
|
||||||
|
|
||||||
const internal = true;
|
|
||||||
const sendToAll = false;
|
|
||||||
|
|
||||||
return this._sendToFrame(internal, sendToAll, frameId, channel, args);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// Following methods are mapped to webFrame.
|
// Following methods are mapped to webFrame.
|
||||||
@@ -199,7 +172,7 @@ const webFrameMethods = [
|
|||||||
|
|
||||||
for (const method of webFrameMethods) {
|
for (const method of webFrameMethods) {
|
||||||
WebContents.prototype[method] = function (...args: any[]): Promise<any> {
|
WebContents.prototype[method] = function (...args: any[]): Promise<any> {
|
||||||
return ipcMainUtils.invokeInWebContents(this, false, IPC_MESSAGES.RENDERER_WEB_FRAME_METHOD, method, ...args);
|
return ipcMainUtils.invokeInWebContents(this, IPC_MESSAGES.RENDERER_WEB_FRAME_METHOD, method, ...args);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -217,11 +190,11 @@ const waitTillCanExecuteJavaScript = async (webContents: Electron.WebContents) =
|
|||||||
// WebContents has been loaded.
|
// WebContents has been loaded.
|
||||||
WebContents.prototype.executeJavaScript = async function (code, hasUserGesture) {
|
WebContents.prototype.executeJavaScript = async function (code, hasUserGesture) {
|
||||||
await waitTillCanExecuteJavaScript(this);
|
await waitTillCanExecuteJavaScript(this);
|
||||||
return ipcMainUtils.invokeInWebContents(this, false, IPC_MESSAGES.RENDERER_WEB_FRAME_METHOD, 'executeJavaScript', String(code), !!hasUserGesture);
|
return ipcMainUtils.invokeInWebContents(this, IPC_MESSAGES.RENDERER_WEB_FRAME_METHOD, 'executeJavaScript', String(code), !!hasUserGesture);
|
||||||
};
|
};
|
||||||
WebContents.prototype.executeJavaScriptInIsolatedWorld = async function (worldId, code, hasUserGesture) {
|
WebContents.prototype.executeJavaScriptInIsolatedWorld = async function (worldId, code, hasUserGesture) {
|
||||||
await waitTillCanExecuteJavaScript(this);
|
await waitTillCanExecuteJavaScript(this);
|
||||||
return ipcMainUtils.invokeInWebContents(this, false, IPC_MESSAGES.RENDERER_WEB_FRAME_METHOD, 'executeJavaScriptInIsolatedWorld', worldId, code, !!hasUserGesture);
|
return ipcMainUtils.invokeInWebContents(this, IPC_MESSAGES.RENDERER_WEB_FRAME_METHOD, 'executeJavaScriptInIsolatedWorld', worldId, code, !!hasUserGesture);
|
||||||
};
|
};
|
||||||
|
|
||||||
// Translate the options of printToPDF.
|
// Translate the options of printToPDF.
|
||||||
@@ -478,8 +451,9 @@ WebContents.prototype._callWindowOpenHandler = function (event: any, url: string
|
|||||||
};
|
};
|
||||||
|
|
||||||
const addReplyToEvent = (event: any) => {
|
const addReplyToEvent = (event: any) => {
|
||||||
|
const { processId, frameId } = event;
|
||||||
event.reply = (...args: any[]) => {
|
event.reply = (...args: any[]) => {
|
||||||
event.sender.sendToFrame(event.frameId, ...args);
|
event.sender.sendToFrame([processId, frameId], ...args);
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -493,6 +467,13 @@ const addReplyInternalToEvent = (event: any) => {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const addSenderFrameToEvent = (event: any) => {
|
||||||
|
const { processId, frameId } = event;
|
||||||
|
Object.defineProperty(event, 'senderFrame', {
|
||||||
|
get: () => webFrameMain.fromId(processId, frameId)
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
const addReturnValueToEvent = (event: any) => {
|
const addReturnValueToEvent = (event: any) => {
|
||||||
Object.defineProperty(event, 'returnValue', {
|
Object.defineProperty(event, 'returnValue', {
|
||||||
set: (value) => event.sendReply(value),
|
set: (value) => event.sendReply(value),
|
||||||
@@ -527,6 +508,13 @@ WebContents.prototype._init = function () {
|
|||||||
this.goToOffset = navigationController.goToOffset.bind(navigationController);
|
this.goToOffset = navigationController.goToOffset.bind(navigationController);
|
||||||
this.getActiveIndex = navigationController.getActiveIndex.bind(navigationController);
|
this.getActiveIndex = navigationController.getActiveIndex.bind(navigationController);
|
||||||
this.length = navigationController.length.bind(navigationController);
|
this.length = navigationController.length.bind(navigationController);
|
||||||
|
// Read off the ID at construction time, so that it's accessible even after
|
||||||
|
// the underlying C++ WebContents is destroyed.
|
||||||
|
const id = this.id;
|
||||||
|
Object.defineProperty(this, 'id', {
|
||||||
|
value: id,
|
||||||
|
writable: false
|
||||||
|
});
|
||||||
|
|
||||||
this._windowOpenHandler = null;
|
this._windowOpenHandler = null;
|
||||||
|
|
||||||
@@ -536,6 +524,7 @@ WebContents.prototype._init = function () {
|
|||||||
|
|
||||||
// Dispatch IPC messages to the ipc module.
|
// Dispatch IPC messages to the ipc module.
|
||||||
this.on('-ipc-message' as any, function (this: Electron.WebContents, event: any, internal: boolean, channel: string, args: any[]) {
|
this.on('-ipc-message' as any, function (this: Electron.WebContents, event: any, internal: boolean, channel: string, args: any[]) {
|
||||||
|
addSenderFrameToEvent(event);
|
||||||
if (internal) {
|
if (internal) {
|
||||||
addReplyInternalToEvent(event);
|
addReplyInternalToEvent(event);
|
||||||
ipcMainInternal.emit(channel, event, ...args);
|
ipcMainInternal.emit(channel, event, ...args);
|
||||||
@@ -547,6 +536,7 @@ WebContents.prototype._init = function () {
|
|||||||
});
|
});
|
||||||
|
|
||||||
this.on('-ipc-invoke' as any, function (event: any, internal: boolean, channel: string, args: any[]) {
|
this.on('-ipc-invoke' as any, function (event: any, internal: boolean, channel: string, args: any[]) {
|
||||||
|
addSenderFrameToEvent(event);
|
||||||
event._reply = (result: any) => event.sendReply({ result });
|
event._reply = (result: any) => event.sendReply({ result });
|
||||||
event._throw = (error: Error) => {
|
event._throw = (error: Error) => {
|
||||||
console.error(`Error occurred in handler for '${channel}':`, error);
|
console.error(`Error occurred in handler for '${channel}':`, error);
|
||||||
@@ -561,6 +551,7 @@ WebContents.prototype._init = function () {
|
|||||||
});
|
});
|
||||||
|
|
||||||
this.on('-ipc-message-sync' as any, function (this: Electron.WebContents, event: any, internal: boolean, channel: string, args: any[]) {
|
this.on('-ipc-message-sync' as any, function (this: Electron.WebContents, event: any, internal: boolean, channel: string, args: any[]) {
|
||||||
|
addSenderFrameToEvent(event);
|
||||||
addReturnValueToEvent(event);
|
addReturnValueToEvent(event);
|
||||||
if (internal) {
|
if (internal) {
|
||||||
addReplyInternalToEvent(event);
|
addReplyInternalToEvent(event);
|
||||||
@@ -635,6 +626,7 @@ WebContents.prototype._init = function () {
|
|||||||
// it's technically a BrowserWindowConstructorOptions option because
|
// it's technically a BrowserWindowConstructorOptions option because
|
||||||
// we need to access it in the renderer at init time.
|
// we need to access it in the renderer at init time.
|
||||||
backgroundColor: windowOpenOverriddenOptions.backgroundColor,
|
backgroundColor: windowOpenOverriddenOptions.backgroundColor,
|
||||||
|
transparent: windowOpenOverriddenOptions.transparent,
|
||||||
...windowOpenOverriddenOptions.webPreferences
|
...windowOpenOverriddenOptions.webPreferences
|
||||||
} : undefined;
|
} : undefined;
|
||||||
this._setNextChildWebPreferences(
|
this._setNextChildWebPreferences(
|
||||||
|
|||||||
@@ -1,4 +1,29 @@
|
|||||||
const { fromId } = process._linkedBinding('electron_browser_web_frame_main');
|
import { MessagePortMain } from '@electron/internal/browser/message-port-main';
|
||||||
|
|
||||||
|
const { WebFrameMain, fromId } = process._linkedBinding('electron_browser_web_frame_main');
|
||||||
|
|
||||||
|
WebFrameMain.prototype.send = function (channel, ...args) {
|
||||||
|
if (typeof channel !== 'string') {
|
||||||
|
throw new Error('Missing required channel argument');
|
||||||
|
}
|
||||||
|
|
||||||
|
return this._send(false /* internal */, channel, args);
|
||||||
|
};
|
||||||
|
|
||||||
|
WebFrameMain.prototype._sendInternal = function (channel, ...args) {
|
||||||
|
if (typeof channel !== 'string') {
|
||||||
|
throw new Error('Missing required channel argument');
|
||||||
|
}
|
||||||
|
|
||||||
|
return this._send(true /* internal */, channel, args);
|
||||||
|
};
|
||||||
|
|
||||||
|
WebFrameMain.prototype.postMessage = function (...args) {
|
||||||
|
if (Array.isArray(args[2])) {
|
||||||
|
args[2] = args[2].map(o => o instanceof MessagePortMain ? o._internalPort : o);
|
||||||
|
}
|
||||||
|
this._postMessage(...args);
|
||||||
|
};
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
fromId
|
fromId
|
||||||
|
|||||||
@@ -48,6 +48,9 @@ export const getSourcesImpl = (event: Electron.IpcMainEvent | null, args: Electr
|
|||||||
}
|
}
|
||||||
// Remove from currentlyRunning once we resolve or reject
|
// Remove from currentlyRunning once we resolve or reject
|
||||||
currentlyRunning = currentlyRunning.filter(running => running.options !== options);
|
currentlyRunning = currentlyRunning.filter(running => running.options !== options);
|
||||||
|
if (event) {
|
||||||
|
event.sender.removeListener('destroyed', stopRunning);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
capturer._onerror = (error: string) => {
|
capturer._onerror = (error: string) => {
|
||||||
@@ -66,7 +69,7 @@ export const getSourcesImpl = (event: Electron.IpcMainEvent | null, args: Electr
|
|||||||
// reference to emit and the capturer itself so that it never dispatches
|
// reference to emit and the capturer itself so that it never dispatches
|
||||||
// back to the renderer
|
// back to the renderer
|
||||||
if (event) {
|
if (event) {
|
||||||
event.sender.once('destroyed', () => stopRunning());
|
event.sender.once('destroyed', stopRunning);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -47,6 +47,7 @@ export function openGuestWindow ({ event, embedder, guest, referrer, disposition
|
|||||||
embedder,
|
embedder,
|
||||||
features,
|
features,
|
||||||
frameName,
|
frameName,
|
||||||
|
isNativeWindowOpen,
|
||||||
overrideOptions: overrideBrowserWindowOptions
|
overrideOptions: overrideBrowserWindowOptions
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -199,10 +200,11 @@ const securityWebPreferences: { [key: string]: boolean } = {
|
|||||||
enableWebSQL: false
|
enableWebSQL: false
|
||||||
};
|
};
|
||||||
|
|
||||||
function makeBrowserWindowOptions ({ embedder, features, frameName, overrideOptions, useDeprecatedBehaviorForBareValues = true, useDeprecatedBehaviorForOptionInheritance = true }: {
|
function makeBrowserWindowOptions ({ embedder, features, frameName, isNativeWindowOpen, overrideOptions, useDeprecatedBehaviorForBareValues = true, useDeprecatedBehaviorForOptionInheritance = true }: {
|
||||||
embedder: WebContents,
|
embedder: WebContents,
|
||||||
features: string,
|
features: string,
|
||||||
frameName: string,
|
frameName: string,
|
||||||
|
isNativeWindowOpen: boolean,
|
||||||
overrideOptions?: BrowserWindowConstructorOptions,
|
overrideOptions?: BrowserWindowConstructorOptions,
|
||||||
useDeprecatedBehaviorForBareValues?: boolean
|
useDeprecatedBehaviorForBareValues?: boolean
|
||||||
useDeprecatedBehaviorForOptionInheritance?: boolean
|
useDeprecatedBehaviorForOptionInheritance?: boolean
|
||||||
@@ -216,9 +218,9 @@ function makeBrowserWindowOptions ({ embedder, features, frameName, overrideOpti
|
|||||||
options: {
|
options: {
|
||||||
...(useDeprecatedBehaviorForOptionInheritance && deprecatedInheritedOptions),
|
...(useDeprecatedBehaviorForOptionInheritance && deprecatedInheritedOptions),
|
||||||
show: true,
|
show: true,
|
||||||
title: frameName,
|
|
||||||
width: 800,
|
width: 800,
|
||||||
height: 600,
|
height: 600,
|
||||||
|
...(!isNativeWindowOpen && { title: frameName }),
|
||||||
...parsedOptions,
|
...parsedOptions,
|
||||||
...overrideOptions,
|
...overrideOptions,
|
||||||
webPreferences: makeWebPreferences({ embedder, insecureParsedWebPreferences: parsedWebPreferences, secureOverrideWebPreferences: overrideOptions && overrideOptions.webPreferences, useDeprecatedBehaviorForOptionInheritance: true })
|
webPreferences: makeWebPreferences({ embedder, insecureParsedWebPreferences: parsedWebPreferences, secureOverrideWebPreferences: overrideOptions && overrideOptions.webPreferences, useDeprecatedBehaviorForOptionInheritance: true })
|
||||||
|
|||||||
@@ -145,6 +145,9 @@ require('@electron/internal/browser/api/protocol');
|
|||||||
// Load web-contents module to ensure it is populated on app ready
|
// Load web-contents module to ensure it is populated on app ready
|
||||||
require('@electron/internal/browser/api/web-contents');
|
require('@electron/internal/browser/api/web-contents');
|
||||||
|
|
||||||
|
// Load web-frame-main module to ensure it is populated on app ready
|
||||||
|
require('@electron/internal/browser/api/web-frame-main');
|
||||||
|
|
||||||
// Set main startup script of the app.
|
// Set main startup script of the app.
|
||||||
const mainStartupScript = packageJson.main || 'index.js';
|
const mainStartupScript = packageJson.main || 'index.js';
|
||||||
|
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ export const handleSync = function <T extends IPCHandler> (channel: string, hand
|
|||||||
|
|
||||||
let nextId = 0;
|
let nextId = 0;
|
||||||
|
|
||||||
export function invokeInWebContents<T> (sender: Electron.WebContents, sendToAll: boolean, command: string, ...args: any[]) {
|
export function invokeInWebContents<T> (sender: Electron.WebContents, command: string, ...args: any[]) {
|
||||||
return new Promise<T>((resolve, reject) => {
|
return new Promise<T>((resolve, reject) => {
|
||||||
const requestId = ++nextId;
|
const requestId = ++nextId;
|
||||||
const channel = `${command}_RESPONSE_${requestId}`;
|
const channel = `${command}_RESPONSE_${requestId}`;
|
||||||
@@ -33,10 +33,6 @@ export function invokeInWebContents<T> (sender: Electron.WebContents, sendToAll:
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
if (sendToAll) {
|
sender._sendInternal(command, requestId, ...args);
|
||||||
sender._sendInternalToAll(command, requestId, ...args);
|
|
||||||
} else {
|
|
||||||
sender._sendInternal(command, requestId, ...args);
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ const FUNCTION_PROPERTIES = [
|
|||||||
];
|
];
|
||||||
|
|
||||||
type RendererFunctionId = [string, number] // [contextId, funcId]
|
type RendererFunctionId = [string, number] // [contextId, funcId]
|
||||||
type FinalizerInfo = { id: RendererFunctionId, webContents: electron.WebContents, frameId: number };
|
type FinalizerInfo = { id: RendererFunctionId, webContents: electron.WebContents, frameId: [number, number] };
|
||||||
type CallIntoRenderer = (...args: any[]) => void
|
type CallIntoRenderer = (...args: any[]) => void
|
||||||
|
|
||||||
// The remote functions in renderer processes.
|
// The remote functions in renderer processes.
|
||||||
@@ -31,7 +31,7 @@ const finalizationRegistry = new FinalizationRegistry((fi: FinalizerInfo) => {
|
|||||||
const ref = rendererFunctionCache.get(mapKey);
|
const ref = rendererFunctionCache.get(mapKey);
|
||||||
if (ref !== undefined && ref.deref() === undefined) {
|
if (ref !== undefined && ref.deref() === undefined) {
|
||||||
rendererFunctionCache.delete(mapKey);
|
rendererFunctionCache.delete(mapKey);
|
||||||
if (!fi.webContents.isDestroyed()) { fi.webContents.sendToFrame(fi.frameId, IPC_MESSAGES.RENDERER_RELEASE_CALLBACK, fi.id[0], fi.id[1]); }
|
if (!fi.webContents.isDestroyed()) { fi.webContents._sendToFrameInternal(fi.frameId, IPC_MESSAGES.RENDERER_RELEASE_CALLBACK, fi.id[0], fi.id[1]); }
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -43,7 +43,7 @@ function getCachedRendererFunction (id: RendererFunctionId): CallIntoRenderer |
|
|||||||
if (deref !== undefined) return deref;
|
if (deref !== undefined) return deref;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
function setCachedRendererFunction (id: RendererFunctionId, wc: electron.WebContents, frameId: number, value: CallIntoRenderer) {
|
function setCachedRendererFunction (id: RendererFunctionId, wc: electron.WebContents, frameId: [number, number], value: CallIntoRenderer) {
|
||||||
// eslint-disable-next-line no-undef
|
// eslint-disable-next-line no-undef
|
||||||
const wr = new WeakRef<CallIntoRenderer>(value);
|
const wr = new WeakRef<CallIntoRenderer>(value);
|
||||||
const mapKey = id[0] + '~' + id[1];
|
const mapKey = id[0] + '~' + id[1];
|
||||||
@@ -218,7 +218,7 @@ const fakeConstructor = (constructor: Function, name: string) =>
|
|||||||
});
|
});
|
||||||
|
|
||||||
// Convert array of meta data from renderer into array of real values.
|
// Convert array of meta data from renderer into array of real values.
|
||||||
const unwrapArgs = function (sender: electron.WebContents, frameId: number, contextId: string, args: any[]) {
|
const unwrapArgs = function (sender: electron.WebContents, frameId: [number, number], contextId: string, args: any[]) {
|
||||||
const metaToValue = function (meta: MetaTypeFromRenderer): any {
|
const metaToValue = function (meta: MetaTypeFromRenderer): any {
|
||||||
switch (meta.type) {
|
switch (meta.type) {
|
||||||
case 'nativeimage':
|
case 'nativeimage':
|
||||||
@@ -421,7 +421,7 @@ handleRemoteCommand(IPC_MESSAGES.BROWSER_GET_CURRENT_WEB_CONTENTS, function (eve
|
|||||||
});
|
});
|
||||||
|
|
||||||
handleRemoteCommand(IPC_MESSAGES.BROWSER_CONSTRUCTOR, function (event, contextId, id, args) {
|
handleRemoteCommand(IPC_MESSAGES.BROWSER_CONSTRUCTOR, function (event, contextId, id, args) {
|
||||||
args = unwrapArgs(event.sender, event.frameId, contextId, args);
|
args = unwrapArgs(event.sender, [event.processId, event.frameId], contextId, args);
|
||||||
const constructor = objectsRegistry.get(id);
|
const constructor = objectsRegistry.get(id);
|
||||||
|
|
||||||
if (constructor == null) {
|
if (constructor == null) {
|
||||||
@@ -432,7 +432,7 @@ handleRemoteCommand(IPC_MESSAGES.BROWSER_CONSTRUCTOR, function (event, contextId
|
|||||||
});
|
});
|
||||||
|
|
||||||
handleRemoteCommand(IPC_MESSAGES.BROWSER_FUNCTION_CALL, function (event, contextId, id, args) {
|
handleRemoteCommand(IPC_MESSAGES.BROWSER_FUNCTION_CALL, function (event, contextId, id, args) {
|
||||||
args = unwrapArgs(event.sender, event.frameId, contextId, args);
|
args = unwrapArgs(event.sender, [event.processId, event.frameId], contextId, args);
|
||||||
const func = objectsRegistry.get(id);
|
const func = objectsRegistry.get(id);
|
||||||
|
|
||||||
if (func == null) {
|
if (func == null) {
|
||||||
@@ -449,7 +449,7 @@ handleRemoteCommand(IPC_MESSAGES.BROWSER_FUNCTION_CALL, function (event, context
|
|||||||
});
|
});
|
||||||
|
|
||||||
handleRemoteCommand(IPC_MESSAGES.BROWSER_MEMBER_CONSTRUCTOR, function (event, contextId, id, method, args) {
|
handleRemoteCommand(IPC_MESSAGES.BROWSER_MEMBER_CONSTRUCTOR, function (event, contextId, id, method, args) {
|
||||||
args = unwrapArgs(event.sender, event.frameId, contextId, args);
|
args = unwrapArgs(event.sender, [event.processId, event.frameId], contextId, args);
|
||||||
const object = objectsRegistry.get(id);
|
const object = objectsRegistry.get(id);
|
||||||
|
|
||||||
if (object == null) {
|
if (object == null) {
|
||||||
@@ -460,7 +460,7 @@ handleRemoteCommand(IPC_MESSAGES.BROWSER_MEMBER_CONSTRUCTOR, function (event, co
|
|||||||
});
|
});
|
||||||
|
|
||||||
handleRemoteCommand(IPC_MESSAGES.BROWSER_MEMBER_CALL, function (event, contextId, id, method, args) {
|
handleRemoteCommand(IPC_MESSAGES.BROWSER_MEMBER_CALL, function (event, contextId, id, method, args) {
|
||||||
args = unwrapArgs(event.sender, event.frameId, contextId, args);
|
args = unwrapArgs(event.sender, [event.processId, event.frameId], contextId, args);
|
||||||
const object = objectsRegistry.get(id);
|
const object = objectsRegistry.get(id);
|
||||||
|
|
||||||
if (object == null) {
|
if (object == null) {
|
||||||
@@ -477,7 +477,7 @@ handleRemoteCommand(IPC_MESSAGES.BROWSER_MEMBER_CALL, function (event, contextId
|
|||||||
});
|
});
|
||||||
|
|
||||||
handleRemoteCommand(IPC_MESSAGES.BROWSER_MEMBER_SET, function (event, contextId, id, name, args) {
|
handleRemoteCommand(IPC_MESSAGES.BROWSER_MEMBER_SET, function (event, contextId, id, name, args) {
|
||||||
args = unwrapArgs(event.sender, event.frameId, contextId, args);
|
args = unwrapArgs(event.sender, [event.processId, event.frameId], contextId, args);
|
||||||
const obj = objectsRegistry.get(id);
|
const obj = objectsRegistry.get(id);
|
||||||
|
|
||||||
if (obj == null) {
|
if (obj == null) {
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { app } from 'electron/main';
|
import { app } from 'electron/main';
|
||||||
import type { WebContents } from 'electron/main';
|
import type { WebContents } from 'electron/main';
|
||||||
import { clipboard, crashReporter, nativeImage } from 'electron/common';
|
import { clipboard, nativeImage } from 'electron/common';
|
||||||
import * as fs from 'fs';
|
import * as fs from 'fs';
|
||||||
import { ipcMainInternal } from '@electron/internal/browser/ipc-main-internal';
|
import { ipcMainInternal } from '@electron/internal/browser/ipc-main-internal';
|
||||||
import * as ipcMainUtils from '@electron/internal/browser/ipc-main-internal-utils';
|
import * as ipcMainUtils from '@electron/internal/browser/ipc-main-internal-utils';
|
||||||
@@ -82,7 +82,7 @@ const getPreloadScript = async function (preloadPath: string) {
|
|||||||
let preloadSrc = null;
|
let preloadSrc = null;
|
||||||
let preloadError = null;
|
let preloadError = null;
|
||||||
try {
|
try {
|
||||||
preloadSrc = (await fs.promises.readFile(preloadPath)).toString();
|
preloadSrc = await fs.promises.readFile(preloadPath, 'utf8');
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
preloadError = error;
|
preloadError = error;
|
||||||
}
|
}
|
||||||
@@ -114,26 +114,6 @@ ipcMainInternal.on(IPC_MESSAGES.BROWSER_PRELOAD_ERROR, function (event, preloadP
|
|||||||
event.sender.emit('preload-error', event, preloadPath, error);
|
event.sender.emit('preload-error', event, preloadPath, error);
|
||||||
});
|
});
|
||||||
|
|
||||||
ipcMainUtils.handleSync(IPC_MESSAGES.CRASH_REPORTER_GET_LAST_CRASH_REPORT, () => {
|
|
||||||
return crashReporter.getLastCrashReport();
|
|
||||||
});
|
|
||||||
|
|
||||||
ipcMainUtils.handleSync(IPC_MESSAGES.CRASH_REPORTER_GET_UPLOADED_REPORTS, () => {
|
|
||||||
return crashReporter.getUploadedReports();
|
|
||||||
});
|
|
||||||
|
|
||||||
ipcMainUtils.handleSync(IPC_MESSAGES.CRASH_REPORTER_GET_UPLOAD_TO_SERVER, () => {
|
|
||||||
return crashReporter.getUploadToServer();
|
|
||||||
});
|
|
||||||
|
|
||||||
ipcMainUtils.handleSync(IPC_MESSAGES.CRASH_REPORTER_SET_UPLOAD_TO_SERVER, (event, uploadToServer: boolean) => {
|
|
||||||
return crashReporter.setUploadToServer(uploadToServer);
|
|
||||||
});
|
|
||||||
|
|
||||||
ipcMainUtils.handleSync(IPC_MESSAGES.CRASH_REPORTER_GET_CRASHES_DIRECTORY, () => {
|
|
||||||
return crashReporter.getCrashesDirectory();
|
|
||||||
});
|
|
||||||
|
|
||||||
ipcMainInternal.handle(IPC_MESSAGES.NATIVE_IMAGE_CREATE_THUMBNAIL_FROM_PATH, async (_, path: string, size: Electron.Size) => {
|
ipcMainInternal.handle(IPC_MESSAGES.NATIVE_IMAGE_CREATE_THUMBNAIL_FROM_PATH, async (_, path: string, size: Electron.Size) => {
|
||||||
return typeUtils.serialize(await nativeImage.createThumbnailFromPath(path, size));
|
return typeUtils.serialize(await nativeImage.createThumbnailFromPath(path, size));
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -5,12 +5,6 @@ export const enum IPC_MESSAGES {
|
|||||||
BROWSER_SANDBOX_LOAD = 'BROWSER_SANDBOX_LOAD',
|
BROWSER_SANDBOX_LOAD = 'BROWSER_SANDBOX_LOAD',
|
||||||
BROWSER_WINDOW_CLOSE = 'BROWSER_WINDOW_CLOSE',
|
BROWSER_WINDOW_CLOSE = 'BROWSER_WINDOW_CLOSE',
|
||||||
|
|
||||||
CRASH_REPORTER_GET_LAST_CRASH_REPORT = 'CRASH_REPORTER_GET_LAST_CRASH_REPORT',
|
|
||||||
CRASH_REPORTER_GET_UPLOADED_REPORTS = 'CRASH_REPORTER_GET_UPLOADED_REPORTS',
|
|
||||||
CRASH_REPORTER_GET_UPLOAD_TO_SERVER = 'CRASH_REPORTER_GET_UPLOAD_TO_SERVER',
|
|
||||||
CRASH_REPORTER_SET_UPLOAD_TO_SERVER = 'CRASH_REPORTER_SET_UPLOAD_TO_SERVER',
|
|
||||||
CRASH_REPORTER_GET_CRASHES_DIRECTORY = 'CRASH_REPORTER_GET_CRASHES_DIRECTORY',
|
|
||||||
|
|
||||||
GUEST_INSTANCE_VISIBILITY_CHANGE = 'GUEST_INSTANCE_VISIBILITY_CHANGE',
|
GUEST_INSTANCE_VISIBILITY_CHANGE = 'GUEST_INSTANCE_VISIBILITY_CHANGE',
|
||||||
|
|
||||||
GUEST_VIEW_INTERNAL_DESTROY_GUEST = 'GUEST_VIEW_INTERNAL_DESTROY_GUEST',
|
GUEST_VIEW_INTERNAL_DESTROY_GUEST = 'GUEST_VIEW_INTERNAL_DESTROY_GUEST',
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ const checkContextIsolationEnabled = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const contextBridge: Electron.ContextBridge = {
|
const contextBridge: Electron.ContextBridge = {
|
||||||
exposeInMainWorld: (key: string, api: Record<string, any>) => {
|
exposeInMainWorld: (key: string, api: any) => {
|
||||||
checkContextIsolationEnabled();
|
checkContextIsolationEnabled();
|
||||||
return binding.exposeAPIInMainWorld(key, api);
|
return binding.exposeAPIInMainWorld(key, api);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,42 +1,6 @@
|
|||||||
import { invokeSync } from '../ipc-renderer-internal-utils';
|
|
||||||
import { deprecate } from 'electron';
|
|
||||||
import { IPC_MESSAGES } from '@electron/internal/common/ipc-messages';
|
|
||||||
|
|
||||||
const binding = process._linkedBinding('electron_renderer_crash_reporter');
|
const binding = process._linkedBinding('electron_renderer_crash_reporter');
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
start (options: Electron.CrashReporterStartOptions) {
|
|
||||||
deprecate.log('crashReporter.start is deprecated in the renderer process. Call it from the main process instead.');
|
|
||||||
for (const [k, v] of Object.entries(options.extra || {})) {
|
|
||||||
binding.addExtraParameter(k, String(v));
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
getLastCrashReport (): Electron.CrashReport | null {
|
|
||||||
deprecate.log('crashReporter.getLastCrashReport is deprecated in the renderer process. Call it from the main process instead.');
|
|
||||||
return invokeSync(IPC_MESSAGES.CRASH_REPORTER_GET_LAST_CRASH_REPORT);
|
|
||||||
},
|
|
||||||
|
|
||||||
getUploadedReports () {
|
|
||||||
deprecate.log('crashReporter.getUploadedReports is deprecated in the renderer process. Call it from the main process instead.');
|
|
||||||
return invokeSync(IPC_MESSAGES.CRASH_REPORTER_GET_UPLOADED_REPORTS);
|
|
||||||
},
|
|
||||||
|
|
||||||
getUploadToServer () {
|
|
||||||
deprecate.log('crashReporter.getUploadToServer is deprecated in the renderer process. Call it from the main process instead.');
|
|
||||||
return invokeSync(IPC_MESSAGES.CRASH_REPORTER_GET_UPLOAD_TO_SERVER);
|
|
||||||
},
|
|
||||||
|
|
||||||
setUploadToServer (uploadToServer: boolean) {
|
|
||||||
deprecate.log('crashReporter.setUploadToServer is deprecated in the renderer process. Call it from the main process instead.');
|
|
||||||
return invokeSync(IPC_MESSAGES.CRASH_REPORTER_SET_UPLOAD_TO_SERVER, uploadToServer);
|
|
||||||
},
|
|
||||||
|
|
||||||
getCrashesDirectory () {
|
|
||||||
deprecate.log('crashReporter.getCrashesDirectory is deprecated in the renderer process. Call it from the main process instead.');
|
|
||||||
return invokeSync(IPC_MESSAGES.CRASH_REPORTER_GET_CRASHES_DIRECTORY);
|
|
||||||
},
|
|
||||||
|
|
||||||
addExtraParameter (key: string, value: string) {
|
addExtraParameter (key: string, value: string) {
|
||||||
binding.addExtraParameter(key, value);
|
binding.addExtraParameter(key, value);
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ ipcRenderer.sendToHost = function (channel, ...args) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
ipcRenderer.sendTo = function (webContentsId, channel, ...args) {
|
ipcRenderer.sendTo = function (webContentsId, channel, ...args) {
|
||||||
return ipc.sendTo(internal, false, webContentsId, channel, args);
|
return ipc.sendTo(internal, webContentsId, channel, args);
|
||||||
};
|
};
|
||||||
|
|
||||||
ipcRenderer.invoke = async function (channel, ...args) {
|
ipcRenderer.invoke = async function (channel, ...args) {
|
||||||
|
|||||||
@@ -48,8 +48,10 @@ class WebFrame extends EventEmitter {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const { hasSwitch } = process._linkedBinding('electron_common_command_line');
|
const contextIsolation = binding.getWebPreference(window, 'contextIsolation');
|
||||||
const worldSafeJS = hasSwitch('world-safe-execute-javascript') && hasSwitch('context-isolation');
|
const worldSafeExecuteJavaScript = binding.getWebPreference(window, 'worldSafeExecuteJavaScript');
|
||||||
|
|
||||||
|
const worldSafeJS = worldSafeExecuteJavaScript || !contextIsolation;
|
||||||
|
|
||||||
// Populate the methods.
|
// Populate the methods.
|
||||||
for (const name in binding) {
|
for (const name in binding) {
|
||||||
|
|||||||
@@ -14,11 +14,7 @@ ipcRendererInternal.sendSync = function (channel, ...args) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
ipcRendererInternal.sendTo = function (webContentsId, channel, ...args) {
|
ipcRendererInternal.sendTo = function (webContentsId, channel, ...args) {
|
||||||
return ipc.sendTo(internal, false, webContentsId, channel, args);
|
return ipc.sendTo(internal, webContentsId, channel, args);
|
||||||
};
|
|
||||||
|
|
||||||
ipcRendererInternal.sendToAll = function (webContentsId, channel, ...args) {
|
|
||||||
return ipc.sendTo(internal, true, webContentsId, channel, args);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
ipcRendererInternal.invoke = async function<T> (channel: string, ...args: any[]) {
|
ipcRendererInternal.invoke = async function<T> (channel: string, ...args: any[]) {
|
||||||
|
|||||||
@@ -81,7 +81,7 @@ const isUnsafeEvalEnabled: () => Promise<boolean> = function () {
|
|||||||
// Call _executeJavaScript to bypass the world-safe deprecation warning
|
// Call _executeJavaScript to bypass the world-safe deprecation warning
|
||||||
return (webFrame as any)._executeJavaScript(`(${(() => {
|
return (webFrame as any)._executeJavaScript(`(${(() => {
|
||||||
try {
|
try {
|
||||||
new Function(''); // eslint-disable-line no-new,no-new-func
|
eval(window.trustedTypes.emptyScript); // eslint-disable-line no-eval
|
||||||
} catch {
|
} catch {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -180,7 +180,7 @@ const warnAboutInsecureCSP = function () {
|
|||||||
|
|
||||||
console.warn('%cElectron Security Warning (Insecure Content-Security-Policy)',
|
console.warn('%cElectron Security Warning (Insecure Content-Security-Policy)',
|
||||||
'font-weight: bold;', warning);
|
'font-weight: bold;', warning);
|
||||||
});
|
}).catch(() => {});
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -225,7 +225,7 @@ const warnAboutExperimentalFeatures = function (webPreferences?: Electron.WebPre
|
|||||||
const warnAboutEnableBlinkFeatures = function (webPreferences?: Electron.WebPreferences) {
|
const warnAboutEnableBlinkFeatures = function (webPreferences?: Electron.WebPreferences) {
|
||||||
if (!webPreferences ||
|
if (!webPreferences ||
|
||||||
!Object.prototype.hasOwnProperty.call(webPreferences, 'enableBlinkFeatures') ||
|
!Object.prototype.hasOwnProperty.call(webPreferences, 'enableBlinkFeatures') ||
|
||||||
(webPreferences.enableBlinkFeatures && webPreferences.enableBlinkFeatures.length === 0)) {
|
(webPreferences.enableBlinkFeatures != null && webPreferences.enableBlinkFeatures.length === 0)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -44,7 +44,9 @@ export class WebViewImpl {
|
|||||||
// Create internal iframe element.
|
// Create internal iframe element.
|
||||||
this.internalElement = this.createInternalElement();
|
this.internalElement = this.createInternalElement();
|
||||||
const shadowRoot = this.webviewNode.attachShadow({ mode: 'open' });
|
const shadowRoot = this.webviewNode.attachShadow({ mode: 'open' });
|
||||||
shadowRoot.innerHTML = '<!DOCTYPE html><style type="text/css">:host { display: flex; }</style>';
|
const style = shadowRoot.ownerDocument.createElement('style');
|
||||||
|
style.textContent = ':host { display: flex; }';
|
||||||
|
shadowRoot.appendChild(style);
|
||||||
this.setupWebViewAttributes();
|
this.setupWebViewAttributes();
|
||||||
this.viewInstanceId = getNextId();
|
this.viewInstanceId = getNextId();
|
||||||
shadowRoot.appendChild(this.internalElement);
|
shadowRoot.appendChild(this.internalElement);
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "electron",
|
"name": "electron",
|
||||||
"version": "12.0.0-nightly.20201118",
|
"version": "12.0.2",
|
||||||
"repository": "https://github.com/electron/electron",
|
"repository": "https://github.com/electron/electron",
|
||||||
"description": "Build cross platform desktop apps with JavaScript, HTML, and CSS",
|
"description": "Build cross platform desktop apps with JavaScript, HTML, and CSS",
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user