mirror of
https://github.com/electron/electron.git
synced 2026-04-10 03:01:51 -04:00
Compare commits
185 Commits
v8.0.0-nig
...
v8.0.0-bet
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
eb419946ad | ||
|
|
1b204a4369 | ||
|
|
ee2de310f5 | ||
|
|
e81aa83a14 | ||
|
|
96cae44f32 | ||
|
|
757e7a91a9 | ||
|
|
6faef05095 | ||
|
|
ee65a190fa | ||
|
|
da45f0341a | ||
|
|
c6517c0b7f | ||
|
|
2c92573978 | ||
|
|
fa7326af64 | ||
|
|
aca96553fc | ||
|
|
37592cdaee | ||
|
|
64e48ad0e6 | ||
|
|
68566583f0 | ||
|
|
6a56aa2240 | ||
|
|
7e8c1108e0 | ||
|
|
f5ce5f8218 | ||
|
|
28e44b31ca | ||
|
|
606ca98df0 | ||
|
|
acd2eabdfd | ||
|
|
07972c2892 | ||
|
|
70079d1c8a | ||
|
|
4def69876f | ||
|
|
61a2c7bd16 | ||
|
|
f53262d58f | ||
|
|
8c15619905 | ||
|
|
4a66bed930 | ||
|
|
8dabb3fe33 | ||
|
|
3f88934025 | ||
|
|
296dcc3405 | ||
|
|
5f6de7053a | ||
|
|
6c1eb46f68 | ||
|
|
05cde0d945 | ||
|
|
696c94c08a | ||
|
|
4284691cb3 | ||
|
|
2ab56802cb | ||
|
|
353d12b231 | ||
|
|
cbd734faf9 | ||
|
|
cf282c177f | ||
|
|
e8c8afb1b4 | ||
|
|
dd0d06448c | ||
|
|
3527fdc291 | ||
|
|
a6b9d68897 | ||
|
|
e1e7ec737f | ||
|
|
4fd03f59f4 | ||
|
|
e64e0f00ca | ||
|
|
1bfead2f6b | ||
|
|
c79f1ee720 | ||
|
|
e18c369e4a | ||
|
|
1953ab3bf2 | ||
|
|
d998bf9fed | ||
|
|
40eff3a778 | ||
|
|
9dd089fc56 | ||
|
|
5e2bd0e55f | ||
|
|
95b8be4cc4 | ||
|
|
d48f99fd6e | ||
|
|
3a9b934cc5 | ||
|
|
768f372675 | ||
|
|
9e3f0d5190 | ||
|
|
5a297f409f | ||
|
|
57335cea69 | ||
|
|
3331f51571 | ||
|
|
f122268ca8 | ||
|
|
bfc817fd28 | ||
|
|
2bd83d0e89 | ||
|
|
f29f3418ed | ||
|
|
c87a0077dd | ||
|
|
23c1dcea46 | ||
|
|
41e64d2469 | ||
|
|
5fdc24d3bf | ||
|
|
64dc86c8c2 | ||
|
|
9d1ec6b0eb | ||
|
|
8919480ebc | ||
|
|
bb9e68beee | ||
|
|
88c1f2caf7 | ||
|
|
88375be2b2 | ||
|
|
2aa69505f9 | ||
|
|
e78fe7c8da | ||
|
|
7a7b944c74 | ||
|
|
09f5a2b741 | ||
|
|
cbf50eabd9 | ||
|
|
90a74139c1 | ||
|
|
3a6cc1b786 | ||
|
|
f5fde13b14 | ||
|
|
c6d429d533 | ||
|
|
73df925241 | ||
|
|
269f4ba2bb | ||
|
|
9b304beb54 | ||
|
|
5ffad09e91 | ||
|
|
b694315cd3 | ||
|
|
8566315902 | ||
|
|
cd94ab9de3 | ||
|
|
09ebadaf5b | ||
|
|
990189ab35 | ||
|
|
049e536c5f | ||
|
|
7fe2f25341 | ||
|
|
c79809ddb9 | ||
|
|
b3edf86914 | ||
|
|
7044122f5d | ||
|
|
b7bcce9576 | ||
|
|
2560776888 | ||
|
|
d5d5fef931 | ||
|
|
6b158872fc | ||
|
|
a4ef2d4356 | ||
|
|
14cc902ad8 | ||
|
|
a62a367b9f | ||
|
|
8d67f16512 | ||
|
|
59cb78e9aa | ||
|
|
032552df57 | ||
|
|
1913926ebc | ||
|
|
dc979388ba | ||
|
|
bcabc25b93 | ||
|
|
ab6d22c958 | ||
|
|
806925ee79 | ||
|
|
a46b50fc7b | ||
|
|
517a5915d7 | ||
|
|
1de38af8cc | ||
|
|
66a95db3df | ||
|
|
7b779c6e6a | ||
|
|
429dfd7054 | ||
|
|
03f7a85cfb | ||
|
|
2d2a753dd9 | ||
|
|
028e3889f0 | ||
|
|
47eb123649 | ||
|
|
45ab098079 | ||
|
|
6cfc05ded2 | ||
|
|
40e0e8e499 | ||
|
|
beff8b8b51 | ||
|
|
311723396a | ||
|
|
d39d75321a | ||
|
|
55201d7db6 | ||
|
|
ac46d5b16e | ||
|
|
a1fb069624 | ||
|
|
3aa33dd220 | ||
|
|
9b74d0d54a | ||
|
|
018fc2ca46 | ||
|
|
e286b78df7 | ||
|
|
f77bd19a70 | ||
|
|
cff63d32a0 | ||
|
|
a8e7696674 | ||
|
|
5fc689dc4e | ||
|
|
895bdc0ee0 | ||
|
|
c99f1d317e | ||
|
|
315e3e325d | ||
|
|
8acce4279b | ||
|
|
c8943cdc3c | ||
|
|
f74f009648 | ||
|
|
467409458e | ||
|
|
f5e5bcd943 | ||
|
|
db4d01c517 | ||
|
|
5abce7ec08 | ||
|
|
18907389da | ||
|
|
ba8f80267c | ||
|
|
2abea22b4b | ||
|
|
cde2aae6b5 | ||
|
|
97fa8c824c | ||
|
|
2658cae3ea | ||
|
|
e3b30a825c | ||
|
|
aa26e8b946 | ||
|
|
9a5cd4c8d2 | ||
|
|
138af75ff8 | ||
|
|
13cb21a684 | ||
|
|
620ac9c2b4 | ||
|
|
417f9e27e1 | ||
|
|
0abbb35c4e | ||
|
|
7b28cd33cb | ||
|
|
4e88633d89 | ||
|
|
eb0e55c514 | ||
|
|
b155ebeeb3 | ||
|
|
820dab295f | ||
|
|
956127ee5e | ||
|
|
43fa9166c9 | ||
|
|
9f23bb581e | ||
|
|
2b890827ef | ||
|
|
3ac3fbdbfb | ||
|
|
0090616f7b | ||
|
|
8099e6137d | ||
|
|
e74b21bff5 | ||
|
|
825e67140e | ||
|
|
19223952a8 | ||
|
|
58115c1cae | ||
|
|
86258c6cff | ||
|
|
b29f0b9348 |
@@ -65,18 +65,22 @@ machine-linux-2xlarge: &machine-linux-2xlarge
|
||||
|
||||
machine-mac: &machine-mac
|
||||
macos:
|
||||
xcode: "9.4.1"
|
||||
xcode: "10.3.0"
|
||||
|
||||
machine-mac-large: &machine-mac-large
|
||||
resource_class: large
|
||||
macos:
|
||||
xcode: "9.4.1"
|
||||
xcode: "10.3.0"
|
||||
|
||||
# Build configurations options.
|
||||
env-debug-build: &env-debug-build
|
||||
GN_CONFIG: //electron/build/args/debug.gn
|
||||
SKIP_DIST_ZIP: '1'
|
||||
|
||||
env-mac-debug-build: &env-mac-debug-build
|
||||
# Set symbol level to 1 so that debug builds do not run out of disk space
|
||||
GN_BUILDFLAG_ARGS: 'symbol_level = 1'
|
||||
|
||||
env-testing-build: &env-testing-build
|
||||
GN_CONFIG: //electron/build/args/testing.gn
|
||||
CHECK_DIST_MANIFEST: '1'
|
||||
@@ -85,6 +89,7 @@ env-release-build: &env-release-build
|
||||
GN_CONFIG: //electron/build/args/release.gn
|
||||
STRIP_BINARIES: true
|
||||
GENERATE_SYMBOLS: true
|
||||
CHECK_DIST_MANIFEST: '1'
|
||||
|
||||
env-headless-testing: &env-headless-testing
|
||||
DISPLAY: ':99.0'
|
||||
@@ -155,6 +160,10 @@ env-ninja-status: &env-ninja-status
|
||||
env-disable-run-as-node: &env-disable-run-as-node
|
||||
GN_BUILDFLAG_ARGS: 'enable_run_as_node = false'
|
||||
|
||||
env-32bit-release: &env-32bit-release
|
||||
# Set symbol level to 1 for 32 bit releases because of https://crbug.com/648948
|
||||
GN_BUILDFLAG_ARGS: 'symbol_level = 1'
|
||||
|
||||
# Individual (shared) steps.
|
||||
step-maybe-notify-slack-failure: &step-maybe-notify-slack-failure
|
||||
run:
|
||||
@@ -246,14 +255,21 @@ step-get-more-space-on-mac: &step-get-more-space-on-mac
|
||||
command: |
|
||||
if [ "`uname`" == "Darwin" ]; then
|
||||
sudo rm -rf /Library/Developer/CoreSimulator
|
||||
sudo rm -rf /Applications/Xcode.app/Contents/Developer/Platforms/AppleTVOS.platform
|
||||
sudo rm -rf /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform
|
||||
sudo rm -rf /Applications/Xcode.app/Contents/Developer/Platforms/WatchOS.platform
|
||||
sudo rm -rf /Applications/Xcode.app/Contents/Developer/Platforms/WatchSimulator.platform
|
||||
sudo rm -rf /Applications/Xcode.app/Contents/Developer/Platforms/AppleTVSimulator.platform
|
||||
sudo rm -rf /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform
|
||||
fi
|
||||
|
||||
step-delete-git-directories: &step-delete-git-directories
|
||||
run:
|
||||
name: Delete src/.git directory on MacOS to free space
|
||||
name: Delete all .git directories under src on MacOS to free space
|
||||
command: |
|
||||
if [ "`uname`" == "Darwin" ]; then
|
||||
sudo rm -rf src/.git
|
||||
cd src
|
||||
( find . -type d -name ".git" ) | xargs rm -rf
|
||||
fi
|
||||
|
||||
# On macOS the yarn install command during gclient sync was run on a linux
|
||||
@@ -319,6 +335,8 @@ step-gn-check: &step-gn-check
|
||||
gn check out/Default //electron:electron_app
|
||||
gn check out/Default //electron:manifests
|
||||
gn check out/Default //electron/shell/common/api:mojo
|
||||
# Check the hunspell filenames
|
||||
node electron/script/gen-hunspell-filenames.js --check
|
||||
|
||||
step-electron-build: &step-electron-build
|
||||
run:
|
||||
@@ -340,9 +358,18 @@ step-maybe-electron-dist-strip: &step-maybe-electron-dist-strip
|
||||
run:
|
||||
name: Strip electron binaries
|
||||
command: |
|
||||
if [ "$STRIP_BINARIES" == "true" ] && [ "`uname`" != "Darwin" ]; then
|
||||
if [ "$STRIP_BINARIES" == "true" ] && [ "`uname`" == "Linux" ]; then
|
||||
if [ x"$TARGET_ARCH" == x ]; then
|
||||
target_cpu=x64
|
||||
elif [ "$TARGET_ARCH" == "ia32" ]; then
|
||||
target_cpu=x86
|
||||
else
|
||||
target_cpu="$TARGET_ARCH"
|
||||
fi
|
||||
cd src
|
||||
electron/script/strip-binaries.py --target-cpu="$TARGET_ARCH"
|
||||
electron/script/copy-debug-symbols.py --target-cpu="$target_cpu" --out-dir=out/Default/debug --compress
|
||||
electron/script/strip-binaries.py --target-cpu="$target_cpu"
|
||||
electron/script/add-debug-link.py --target-cpu="$target_cpu" --debug-dir=out/Default/debug
|
||||
fi
|
||||
|
||||
step-electron-dist-build: &step-electron-dist-build
|
||||
@@ -416,6 +443,9 @@ step-electron-publish: &step-electron-publish
|
||||
run:
|
||||
name: Publish Electron Dist
|
||||
command: |
|
||||
if [ "`uname`" == "Darwin" ]; then
|
||||
rm -rf src/out/Default/obj
|
||||
fi
|
||||
cd src/electron
|
||||
if [ "$UPLOAD_TO_S3" == "1" ]; then
|
||||
echo 'Uploading Electron release distribution to S3'
|
||||
@@ -534,6 +564,20 @@ step-mksnapshot-store: &step-mksnapshot-store
|
||||
path: src/out/Default/mksnapshot.zip
|
||||
destination: mksnapshot.zip
|
||||
|
||||
step-hunspell-build: &step-hunspell-build
|
||||
run:
|
||||
name: hunspell build
|
||||
command: |
|
||||
cd src
|
||||
if [ "$SKIP_DIST_ZIP" != "1" ]; then
|
||||
ninja -C out/Default electron:hunspell_dictionaries_zip -j $NUMBER_OF_NINJA_PROCESSES
|
||||
fi
|
||||
|
||||
step-hunspell-store: &step-hunspell-store
|
||||
store_artifacts:
|
||||
path: src/out/Default/hunspell_dictionaries.zip
|
||||
destination: hunspell_dictionaries.zip
|
||||
|
||||
step-maybe-generate-breakpad-symbols: &step-maybe-generate-breakpad-symbols
|
||||
run:
|
||||
name: Generate breakpad symbols
|
||||
@@ -693,7 +737,6 @@ step-minimize-workspace-size-from-checkout: &step-minimize-workspace-size-from-c
|
||||
rm -rf src/ios
|
||||
rm -rf src/third_party/blink/web_tests
|
||||
rm -rf src/third_party/blink/perf_tests
|
||||
rm -rf src/third_party/hunspell_dictionaries
|
||||
rm -rf src/third_party/WebKit/LayoutTests
|
||||
|
||||
# Save the src cache based on the deps hash
|
||||
@@ -704,6 +747,51 @@ step-save-src-cache: &step-save-src-cache
|
||||
key: v5-src-cache-{{ arch }}-{{ checksum "src/electron/.depshash" }}
|
||||
name: Persisting src cache
|
||||
|
||||
# Check for doc only change
|
||||
step-check-for-doc-only-change: &step-check-for-doc-only-change
|
||||
run:
|
||||
name: Check if commit is doc only change
|
||||
command: |
|
||||
cd src/electron
|
||||
node script/yarn install --frozen-lockfile
|
||||
if node script/doc-only-change.js --prNumber=$CIRCLE_PR_NUMBER --prURL=$CIRCLE_PULL_REQUEST; then
|
||||
#PR is doc only change; save file with value true to indicate doc only change
|
||||
echo "true" > .skip-ci-build
|
||||
else
|
||||
#PR is not a doc only change; create empty file to indicate check has been done
|
||||
touch .skip-ci-build
|
||||
fi
|
||||
|
||||
step-persist-doc-only-change: &step-persist-doc-only-change
|
||||
persist_to_workspace:
|
||||
root: .
|
||||
paths:
|
||||
- src/electron/.skip-ci-build
|
||||
|
||||
step-maybe-early-exit-doc-only-change: &step-maybe-early-exit-doc-only-change
|
||||
run:
|
||||
name: Shortcircuit build if doc only change
|
||||
command: |
|
||||
if [ -s src/electron/.skip-ci-build ]; then
|
||||
circleci-agent step halt
|
||||
fi
|
||||
|
||||
step-maybe-early-exit-no-doc-change: &step-maybe-early-exit-no-doc-change
|
||||
run:
|
||||
name: Shortcircuit job if change is not doc only
|
||||
command: |
|
||||
if [ ! -s src/electron/.skip-ci-build ]; then
|
||||
circleci-agent step halt
|
||||
fi
|
||||
|
||||
step-ts-compile: &step-ts-compile
|
||||
run:
|
||||
name: Run TS/JS compile on doc only change
|
||||
command: |
|
||||
cd src
|
||||
ninja -C out/Default electron:default_app_js -j $NUMBER_OF_NINJA_PROCESSES
|
||||
ninja -C out/Default electron:atom_js2c -j $NUMBER_OF_NINJA_PROCESSES
|
||||
|
||||
# Lists of steps.
|
||||
steps-lint: &steps-lint
|
||||
steps:
|
||||
@@ -752,6 +840,9 @@ steps-lint: &steps-lint
|
||||
steps-checkout-fast: &steps-checkout-fast
|
||||
steps:
|
||||
- *step-checkout-electron
|
||||
- *step-check-for-doc-only-change
|
||||
- *step-persist-doc-only-change
|
||||
- *step-maybe-early-exit-doc-only-change
|
||||
- *step-depot-tools-get
|
||||
- *step-depot-tools-add-to-path
|
||||
- *step-restore-brew-cache
|
||||
@@ -783,6 +874,9 @@ steps-checkout-fast: &steps-checkout-fast
|
||||
steps-checkout-and-save-cache: &steps-checkout-and-save-cache
|
||||
steps:
|
||||
- *step-checkout-electron
|
||||
- *step-check-for-doc-only-change
|
||||
- *step-persist-doc-only-change
|
||||
- *step-maybe-early-exit-doc-only-change
|
||||
- *step-depot-tools-get
|
||||
- *step-depot-tools-add-to-path
|
||||
- *step-restore-brew-cache
|
||||
@@ -813,6 +907,7 @@ steps-electron-gn-check: &steps-electron-gn-check
|
||||
steps:
|
||||
- attach_workspace:
|
||||
at: .
|
||||
- *step-maybe-early-exit-doc-only-change
|
||||
- *step-depot-tools-add-to-path
|
||||
- *step-setup-env-for-build
|
||||
- *step-gn-gen-default
|
||||
@@ -822,14 +917,15 @@ steps-electron-build: &steps-electron-build
|
||||
steps:
|
||||
- attach_workspace:
|
||||
at: .
|
||||
- *step-maybe-early-exit-doc-only-change
|
||||
- *step-depot-tools-add-to-path
|
||||
- *step-setup-env-for-build
|
||||
- *step-restore-brew-cache
|
||||
- *step-get-more-space-on-mac
|
||||
- *step-install-npm-deps-on-mac
|
||||
- *step-fix-sync-on-mac
|
||||
- *step-gn-gen-default
|
||||
- *step-delete-git-directories
|
||||
- *step-gn-gen-default
|
||||
|
||||
# Electron app
|
||||
- *step-electron-build
|
||||
@@ -859,6 +955,10 @@ steps-electron-build: &steps-electron-build
|
||||
- *step-ffmpeg-build
|
||||
- *step-ffmpeg-store
|
||||
|
||||
# hunspell
|
||||
- *step-hunspell-build
|
||||
- *step-hunspell-store
|
||||
|
||||
# Save all data needed for a further tests run.
|
||||
- *step-persist-data-for-tests
|
||||
|
||||
@@ -875,6 +975,90 @@ steps-electron-build-with-inline-checkout-for-tests: &steps-electron-build-with-
|
||||
steps:
|
||||
# Checkout - Copied ffrom steps-checkout
|
||||
- *step-checkout-electron
|
||||
- *step-check-for-doc-only-change
|
||||
- *step-persist-doc-only-change
|
||||
- *step-maybe-early-exit-doc-only-change
|
||||
- *step-depot-tools-get
|
||||
- *step-depot-tools-add-to-path
|
||||
- *step-restore-brew-cache
|
||||
- *step-get-more-space-on-mac
|
||||
- *step-install-gnutar-on-mac
|
||||
- *step-generate-deps-hash
|
||||
- *step-touch-sync-done
|
||||
- *step-maybe-restore-src-cache
|
||||
- *step-maybe-restore-git-cache
|
||||
- *step-set-git-cache-path
|
||||
# This sync call only runs if .circle-sync-done is an EMPTY file
|
||||
- *step-gclient-sync
|
||||
# These next few steps reset Electron to the correct commit regardless of which cache was restored
|
||||
- run:
|
||||
name: Wipe Electron
|
||||
command: rm -rf src/electron
|
||||
- *step-checkout-electron
|
||||
- *step-run-electron-only-hooks
|
||||
- *step-generate-deps-hash-cleanly
|
||||
- *step-mark-sync-done
|
||||
- *step-minimize-workspace-size-from-checkout
|
||||
|
||||
- *step-depot-tools-add-to-path
|
||||
- *step-setup-env-for-build
|
||||
- *step-restore-brew-cache
|
||||
- *step-get-more-space-on-mac
|
||||
- *step-install-npm-deps-on-mac
|
||||
- *step-fix-sync-on-mac
|
||||
- *step-delete-git-directories
|
||||
- *step-gn-gen-default
|
||||
|
||||
# Electron app
|
||||
- *step-electron-build
|
||||
- *step-maybe-electron-dist-strip
|
||||
- *step-electron-dist-build
|
||||
- *step-electron-dist-store
|
||||
- *step-ninja-summary
|
||||
|
||||
# Native test targets
|
||||
- *step-native-unittests-build
|
||||
- *step-native-unittests-store
|
||||
|
||||
# Node.js headers
|
||||
- *step-nodejs-headers-build
|
||||
- *step-nodejs-headers-store
|
||||
|
||||
- *step-show-sccache-stats
|
||||
|
||||
# mksnapshot
|
||||
- *step-mksnapshot-build
|
||||
- *step-mksnapshot-store
|
||||
- *step-maybe-cross-arch-snapshot
|
||||
- *step-maybe-cross-arch-snapshot-store
|
||||
|
||||
# ffmpeg
|
||||
- *step-ffmpeg-gn-gen
|
||||
- *step-ffmpeg-build
|
||||
- *step-ffmpeg-store
|
||||
|
||||
# hunspell
|
||||
- *step-hunspell-build
|
||||
- *step-hunspell-store
|
||||
|
||||
# Save all data needed for a further tests run.
|
||||
- *step-persist-data-for-tests
|
||||
|
||||
- *step-maybe-generate-breakpad-symbols
|
||||
- *step-maybe-zip-symbols
|
||||
- *step-symbols-store
|
||||
|
||||
# Trigger tests on arm hardware if needed
|
||||
- *step-maybe-trigger-arm-test
|
||||
|
||||
- *step-maybe-notify-slack-failure
|
||||
|
||||
steps-electron-ts-compile-for-doc-change: &steps-electron-ts-compile-for-doc-change
|
||||
steps:
|
||||
# Checkout - Copied ffrom steps-checkout
|
||||
- *step-checkout-electron
|
||||
- *step-check-for-doc-only-change
|
||||
- *step-maybe-early-exit-no-doc-change
|
||||
- *step-depot-tools-get
|
||||
- *step-depot-tools-add-to-path
|
||||
- *step-restore-brew-cache
|
||||
@@ -904,47 +1088,9 @@ steps-electron-build-with-inline-checkout-for-tests: &steps-electron-build-with-
|
||||
- *step-install-npm-deps-on-mac
|
||||
- *step-fix-sync-on-mac
|
||||
- *step-gn-gen-default
|
||||
- *step-delete-git-directories
|
||||
|
||||
# Electron app
|
||||
- *step-electron-build
|
||||
- *step-maybe-electron-dist-strip
|
||||
- *step-electron-dist-build
|
||||
- *step-electron-dist-store
|
||||
- *step-ninja-summary
|
||||
|
||||
# Native test targets
|
||||
- *step-native-unittests-build
|
||||
- *step-native-unittests-store
|
||||
|
||||
# Node.js headers
|
||||
- *step-nodejs-headers-build
|
||||
- *step-nodejs-headers-store
|
||||
|
||||
- *step-show-sccache-stats
|
||||
|
||||
# mksnapshot
|
||||
- *step-mksnapshot-build
|
||||
- *step-mksnapshot-store
|
||||
- *step-maybe-cross-arch-snapshot
|
||||
- *step-maybe-cross-arch-snapshot-store
|
||||
|
||||
# ffmpeg
|
||||
- *step-ffmpeg-gn-gen
|
||||
- *step-ffmpeg-build
|
||||
- *step-ffmpeg-store
|
||||
|
||||
# Save all data needed for a further tests run.
|
||||
- *step-persist-data-for-tests
|
||||
|
||||
- *step-maybe-generate-breakpad-symbols
|
||||
- *step-maybe-zip-symbols
|
||||
- *step-symbols-store
|
||||
|
||||
# Trigger tests on arm hardware if needed
|
||||
- *step-maybe-trigger-arm-test
|
||||
|
||||
- *step-maybe-notify-slack-failure
|
||||
#Compile ts/js to verify doc change didn't break anything
|
||||
- *step-ts-compile
|
||||
|
||||
steps-electron-build-for-publish: &steps-electron-build-for-publish
|
||||
steps:
|
||||
@@ -955,8 +1101,9 @@ steps-electron-build-for-publish: &steps-electron-build-for-publish
|
||||
- *step-get-more-space-on-mac
|
||||
- *step-gclient-sync
|
||||
- *step-setup-env-for-build
|
||||
- *step-gn-gen-default
|
||||
- *step-delete-git-directories
|
||||
- *step-minimize-workspace-size-from-checkout
|
||||
- *step-gn-gen-default
|
||||
|
||||
# Electron app
|
||||
- *step-electron-build
|
||||
@@ -984,6 +1131,10 @@ steps-electron-build-for-publish: &steps-electron-build-for-publish
|
||||
- *step-ffmpeg-build
|
||||
- *step-ffmpeg-store
|
||||
|
||||
# hunspell
|
||||
- *step-hunspell-build
|
||||
- *step-hunspell-store
|
||||
|
||||
# typescript defs
|
||||
- *step-maybe-generate-typescript-defs
|
||||
|
||||
@@ -1064,6 +1215,7 @@ steps-tests: &steps-tests
|
||||
steps:
|
||||
- attach_workspace:
|
||||
at: .
|
||||
- *step-maybe-early-exit-doc-only-change
|
||||
- *step-depot-tools-add-to-path
|
||||
- *step-electron-dist-unzip
|
||||
- *step-mksnapshot-unzip
|
||||
@@ -1106,6 +1258,7 @@ steps-test-nan: &steps-test-nan
|
||||
steps:
|
||||
- attach_workspace:
|
||||
at: .
|
||||
- *step-maybe-early-exit-doc-only-change
|
||||
- *step-depot-tools-add-to-path
|
||||
- *step-electron-dist-unzip
|
||||
- *step-setup-linux-for-headless-testing
|
||||
@@ -1121,6 +1274,7 @@ steps-test-node: &steps-test-node
|
||||
steps:
|
||||
- attach_workspace:
|
||||
at: .
|
||||
- *step-maybe-early-exit-doc-only-change
|
||||
- *step-depot-tools-add-to-path
|
||||
- *step-electron-dist-unzip
|
||||
- *step-setup-linux-for-headless-testing
|
||||
@@ -1146,6 +1300,13 @@ jobs:
|
||||
<<: *env-linux-medium
|
||||
<<: *steps-lint
|
||||
|
||||
ts-compile-doc-change:
|
||||
<<: *machine-linux-medium
|
||||
environment:
|
||||
<<: *env-linux-medium
|
||||
<<: *env-testing-build
|
||||
<<: *steps-electron-ts-compile-for-doc-change
|
||||
|
||||
# Layer 1: Checkout.
|
||||
linux-checkout-fast:
|
||||
<<: *machine-linux-2xlarge
|
||||
@@ -1315,6 +1476,7 @@ jobs:
|
||||
<<: *env-ia32
|
||||
<<: *env-release-build
|
||||
<<: *env-enable-sccache
|
||||
<<: *env-32bit-release
|
||||
UPLOAD_TO_S3: << pipeline.parameters.upload-to-s3 >>
|
||||
<<: *steps-electron-build-for-publish
|
||||
|
||||
@@ -1369,6 +1531,7 @@ jobs:
|
||||
<<: *env-arm
|
||||
<<: *env-release-build
|
||||
<<: *env-enable-sccache
|
||||
<<: *env-32bit-release
|
||||
GCLIENT_EXTRA_ARGS: '--custom-var=checkout_arm=True --custom-var=checkout_boto=True --custom-var=checkout_requests=True'
|
||||
UPLOAD_TO_S3: << pipeline.parameters.upload-to-s3 >>
|
||||
<<: *steps-electron-build-for-publish
|
||||
@@ -1458,6 +1621,7 @@ jobs:
|
||||
environment:
|
||||
<<: *env-mac-large
|
||||
<<: *env-debug-build
|
||||
<<: *env-mac-debug-build
|
||||
<<: *env-enable-sccache
|
||||
<<: *env-ninja-status
|
||||
<<: *steps-electron-build
|
||||
@@ -1520,6 +1684,7 @@ jobs:
|
||||
<<: *env-mac-large
|
||||
<<: *env-mas
|
||||
<<: *env-debug-build
|
||||
<<: *env-mac-debug-build
|
||||
<<: *env-enable-sccache
|
||||
<<: *env-ninja-status
|
||||
<<: *steps-electron-build
|
||||
@@ -1917,6 +2082,7 @@ workflows:
|
||||
- linux-arm64-testing-gn-check:
|
||||
requires:
|
||||
- linux-checkout-fast
|
||||
- ts-compile-doc-change
|
||||
|
||||
build-mac:
|
||||
when: << pipeline.parameters.run-build-mac >>
|
||||
@@ -1928,14 +2094,6 @@ workflows:
|
||||
requires:
|
||||
- mac-checkout-fast
|
||||
|
||||
- osx-debug:
|
||||
requires:
|
||||
- mac-checkout-fast
|
||||
|
||||
- osx-debug-gn-check:
|
||||
requires:
|
||||
- mac-checkout-fast
|
||||
|
||||
- osx-testing-gn-check:
|
||||
requires:
|
||||
- mac-checkout-fast
|
||||
@@ -1948,14 +2106,6 @@ workflows:
|
||||
requires:
|
||||
- mac-checkout-fast
|
||||
|
||||
- mas-debug:
|
||||
requires:
|
||||
- mac-checkout-fast
|
||||
|
||||
- mas-debug-gn-check:
|
||||
requires:
|
||||
- mac-checkout-fast
|
||||
|
||||
- mas-testing-gn-check:
|
||||
requires:
|
||||
- mac-checkout-fast
|
||||
|
||||
2
.github/config.yml
vendored
2
.github/config.yml
vendored
@@ -29,13 +29,11 @@ firstPRMergeComment: >
|
||||
# Users authorized to run manual trop backports
|
||||
authorizedUsers:
|
||||
- alexeykuzmin
|
||||
- BinaryMuse
|
||||
- ckerr
|
||||
- codebytere
|
||||
- deepak1556
|
||||
- jkleinsc
|
||||
- MarshallOfSound
|
||||
- miniak
|
||||
- nitsakh
|
||||
- nornagon
|
||||
- zcbenz
|
||||
|
||||
48
BUILD.gn
48
BUILD.gn
@@ -1,6 +1,7 @@
|
||||
import("//build/config/locales.gni")
|
||||
import("//build/config/ui.gni")
|
||||
import("//build/config/win/manifest.gni")
|
||||
import("//components/spellcheck/spellcheck_build_features.gni")
|
||||
import("//content/public/app/mac_helpers.gni")
|
||||
import("//pdf/features.gni")
|
||||
import("//printing/buildflags/buildflags.gni")
|
||||
@@ -21,12 +22,14 @@ import("buildflags/buildflags.gni")
|
||||
import("electron_paks.gni")
|
||||
import("filenames.auto.gni")
|
||||
import("filenames.gni")
|
||||
import("filenames.hunspell.gni")
|
||||
|
||||
if (is_mac) {
|
||||
import("//build/config/mac/rules.gni")
|
||||
import("//third_party/icu/config.gni")
|
||||
import("//ui/gl/features.gni")
|
||||
import("//v8/gni/v8.gni")
|
||||
import("build/rules.gni")
|
||||
}
|
||||
|
||||
if (is_linux) {
|
||||
@@ -350,6 +353,7 @@ source_set("electron_lib") {
|
||||
":resources",
|
||||
"buildflags",
|
||||
"chromium_src:chrome",
|
||||
"chromium_src:chrome_spellchecker",
|
||||
"native_mate",
|
||||
"shell/common/api:mojo",
|
||||
"//base:base_static",
|
||||
@@ -357,12 +361,13 @@ source_set("electron_lib") {
|
||||
"//chrome/app/resources:platform_locale_settings",
|
||||
"//chrome/services/printing/public/mojom",
|
||||
"//components/certificate_transparency",
|
||||
"//components/language/core/browser",
|
||||
"//components/net_log",
|
||||
"//components/network_hints/common",
|
||||
"//components/network_hints/browser",
|
||||
"//components/network_hints/common:mojo_bindings",
|
||||
"//components/network_hints/renderer",
|
||||
"//components/network_session_configurator/common",
|
||||
"//components/prefs",
|
||||
"//components/spellcheck/renderer",
|
||||
"//components/viz/host",
|
||||
"//components/viz/service",
|
||||
"//content/public/browser",
|
||||
@@ -378,12 +383,10 @@ source_set("electron_lib") {
|
||||
"//media/mojo/mojom",
|
||||
"//net:extras",
|
||||
"//net:net_resources",
|
||||
"//net:net_with_v8",
|
||||
"//ppapi/host",
|
||||
"//ppapi/proxy",
|
||||
"//ppapi/shared_impl",
|
||||
"//printing/buildflags",
|
||||
"//services/audio/public/mojom:constants",
|
||||
"//services/device/public/cpp/geolocation",
|
||||
"//services/device/public/mojom",
|
||||
"//services/proxy_resolver:lib",
|
||||
@@ -395,7 +398,7 @@ source_set("electron_lib") {
|
||||
"//third_party/electron_node:node_lib",
|
||||
"//third_party/leveldatabase",
|
||||
"//third_party/libyuv",
|
||||
"//third_party/webrtc_overrides:init_webrtc",
|
||||
"//third_party/webrtc_overrides:webrtc_component",
|
||||
"//third_party/widevine/cdm:headers",
|
||||
"//ui/base/idle",
|
||||
"//ui/events:dom_keycode_converter",
|
||||
@@ -545,6 +548,10 @@ source_set("electron_lib") {
|
||||
]
|
||||
|
||||
sources += filenames.lib_sources_nss
|
||||
sources += [
|
||||
"shell/browser/ui/gtk_util.cc",
|
||||
"shell/browser/ui/gtk_util.h",
|
||||
]
|
||||
}
|
||||
if (is_win) {
|
||||
libs += [ "dwmapi.lib" ]
|
||||
@@ -688,6 +695,12 @@ if (is_mac) {
|
||||
electron_framework_version = "A"
|
||||
electron_version = read_file("ELECTRON_VERSION", "trim string")
|
||||
|
||||
mac_xib_bundle_data("electron_xibs") {
|
||||
sources = [
|
||||
"shell/common/resources/mac/MainMenu.xib",
|
||||
]
|
||||
}
|
||||
|
||||
bundle_data("electron_framework_resources") {
|
||||
public_deps = [
|
||||
":packed_resources",
|
||||
@@ -698,7 +711,6 @@ if (is_mac) {
|
||||
public_deps += [ "//third_party/icu:icudata" ]
|
||||
}
|
||||
if (v8_use_external_startup_data) {
|
||||
sources += [ "$root_out_dir/natives_blob.bin" ]
|
||||
public_deps += [ "//v8" ]
|
||||
if (use_v8_context_snapshot) {
|
||||
sources += [ "$root_out_dir/v8_context_snapshot.bin" ]
|
||||
@@ -803,6 +815,7 @@ if (is_mac) {
|
||||
":electron_framework_libraries",
|
||||
":electron_framework_resources",
|
||||
":electron_swiftshader_library",
|
||||
":electron_xibs",
|
||||
]
|
||||
if (!is_mas_build) {
|
||||
deps += [ ":electron_crashpad_helper" ]
|
||||
@@ -1257,9 +1270,14 @@ template("dist_zip") {
|
||||
"outputs",
|
||||
"testonly",
|
||||
])
|
||||
flatten = false
|
||||
if (defined(invoker.flatten)) {
|
||||
flatten = invoker.flatten
|
||||
}
|
||||
args = rebase_path(outputs + [ _runtime_deps_file ], root_build_dir) + [
|
||||
target_cpu,
|
||||
target_os,
|
||||
"$flatten",
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -1345,6 +1363,24 @@ dist_zip("electron_mksnapshot_zip") {
|
||||
]
|
||||
}
|
||||
|
||||
copy("hunspell_dictionaries") {
|
||||
sources = hunspell_dictionaries + hunspell_licenses
|
||||
outputs = [
|
||||
"$target_gen_dir/electron_hunspell/{{source_file_part}}",
|
||||
]
|
||||
}
|
||||
|
||||
dist_zip("hunspell_dictionaries_zip") {
|
||||
data_deps = [
|
||||
":hunspell_dictionaries",
|
||||
]
|
||||
flatten = true
|
||||
|
||||
outputs = [
|
||||
"$root_build_dir/hunspell_dictionaries.zip",
|
||||
]
|
||||
}
|
||||
|
||||
group("electron") {
|
||||
public_deps = [
|
||||
":electron_app",
|
||||
|
||||
6
DEPS
6
DEPS
@@ -11,9 +11,9 @@ gclient_gn_args = [
|
||||
|
||||
vars = {
|
||||
'chromium_version':
|
||||
'6c775c358b709f4353bc693623bf58820adf3918',
|
||||
'80.0.3987.51',
|
||||
'node_version':
|
||||
'v12.10.0',
|
||||
'v12.13.0',
|
||||
'nan_version':
|
||||
'2ee313aaca52e2b478965ac50eb5082520380d1b',
|
||||
|
||||
@@ -114,7 +114,7 @@ hooks = [
|
||||
'pattern': 'src/electron/script/update-external-binaries.py',
|
||||
'condition': 'download_external_binaries',
|
||||
'action': [
|
||||
'python',
|
||||
'python3',
|
||||
'src/electron/script/update-external-binaries.py',
|
||||
],
|
||||
},
|
||||
|
||||
@@ -1 +1 @@
|
||||
8.0.0-nightly.20191016
|
||||
8.0.0-beta.6
|
||||
12
README.md
12
README.md
@@ -58,13 +58,13 @@ npm start
|
||||
|
||||
## Resources for learning Electron
|
||||
|
||||
- [electronjs.org/docs](https://electronjs.org/docs) - all of Electron's documentation
|
||||
- [electronjs.org/docs](https://electronjs.org/docs) - All of Electron's documentation
|
||||
- [electron/fiddle](https://github.com/electron/fiddle) - A tool to build, run, and package small Electron experiments
|
||||
- [electron/electron-quick-start](https://github.com/electron/electron-quick-start) - a very basic starter Electron app
|
||||
- [electronjs.org/community#boilerplates](https://electronjs.org/community#boilerplates) - sample starter apps created by the community
|
||||
- [electron/simple-samples](https://github.com/electron/simple-samples) - small applications with ideas for taking them further
|
||||
- [electron/electron-api-demos](https://github.com/electron/electron-api-demos) - an Electron app that teaches you how to use Electron
|
||||
- [hokein/electron-sample-apps](https://github.com/hokein/electron-sample-apps) - small demo apps for the various Electron APIs
|
||||
- [electron/electron-quick-start](https://github.com/electron/electron-quick-start) - A very basic starter Electron app
|
||||
- [electronjs.org/community#boilerplates](https://electronjs.org/community#boilerplates) - Sample starter apps created by the community
|
||||
- [electron/simple-samples](https://github.com/electron/simple-samples) - Small applications with ideas for taking them further
|
||||
- [electron/electron-api-demos](https://github.com/electron/electron-api-demos) - An Electron app that teaches you how to use Electron
|
||||
- [hokein/electron-sample-apps](https://github.com/hokein/electron-sample-apps) - Small demo apps for the various Electron APIs
|
||||
|
||||
## Programmatic usage
|
||||
|
||||
|
||||
15
appveyor.yml
15
appveyor.yml
@@ -29,7 +29,7 @@
|
||||
|
||||
version: 1.0.{build}
|
||||
build_cloud: libcc-20
|
||||
image: vs2017-15.9-10.0.18362
|
||||
image: vs2019-16.3-10.0.18362
|
||||
environment:
|
||||
GIT_CACHE_PATH: C:\Users\electron\libcc_cache
|
||||
ELECTRON_OUT_DIR: Default
|
||||
@@ -50,6 +50,12 @@ build_script:
|
||||
- ps: >-
|
||||
if(($env:APPVEYOR_PULL_REQUEST_HEAD_REPO_NAME -split "/")[0] -eq ($env:APPVEYOR_REPO_NAME -split "/")[0]) {
|
||||
Write-warning "Skipping PR build for branch"; Exit-AppveyorBuild
|
||||
} else {
|
||||
node script/yarn.js install --frozen-lockfile
|
||||
|
||||
if ($(node script/doc-only-change.js --prNumber=$env:APPVEYOR_PULL_REQUEST_NUMBER --prBranch=$env:APPVEYOR_REPO_BRANCH;$LASTEXITCODE -eq 0)) {
|
||||
Write-warning "Skipping build for doc only change"; Exit-AppveyorBuild
|
||||
}
|
||||
}
|
||||
- echo "Building $env:GN_CONFIG build"
|
||||
- git config --global core.longpaths true
|
||||
@@ -70,10 +76,10 @@ build_script:
|
||||
--unmanaged
|
||||
%GCLIENT_EXTRA_ARGS%
|
||||
"https://github.com/electron/electron"
|
||||
- gclient sync --with_branch_heads --with_tags --reset
|
||||
- gclient sync --with_branch_heads --with_tags --ignore_locks --break_repo_locks
|
||||
- cd src
|
||||
- ps: $env:BUILD_CONFIG_PATH="//electron/build/args/%GN_CONFIG%.gn"
|
||||
- gn gen out/Default "--args=import(\"%BUILD_CONFIG_PATH%\") %GN_EXTRA_ARGS%"
|
||||
- gn gen out/Default "--args=import(\"%BUILD_CONFIG_PATH%\") %GN_EXTRA_ARGS% cc_wrapper=\"%SCCACHE_PATH%\""
|
||||
- gn check out/Default //electron:electron_lib
|
||||
- gn check out/Default //electron:electron_app
|
||||
- gn check out/Default //electron:manifests
|
||||
@@ -85,8 +91,10 @@ build_script:
|
||||
- ninja -C out/Default electron:electron_dist_zip
|
||||
- ninja -C out/Default shell_browser_ui_unittests
|
||||
- ninja -C out/Default electron:electron_mksnapshot_zip
|
||||
- ninja -C out/Default electron:hunspell_dictionaries_zip
|
||||
- ninja -C out/Default electron:electron_chromedriver_zip
|
||||
- ninja -C out/Default third_party/electron_node:headers
|
||||
- cmd /C %SCCACHE_PATH% --show-stats
|
||||
- appveyor PushArtifact out/Default/dist.zip
|
||||
- appveyor PushArtifact out/Default/shell_browser_ui_unittests.exe
|
||||
- appveyor PushArtifact out/Default/chromedriver.zip
|
||||
@@ -94,6 +102,7 @@ build_script:
|
||||
- 7z a node_headers.zip out\Default\gen\node_headers
|
||||
- appveyor PushArtifact node_headers.zip
|
||||
- appveyor PushArtifact out/Default/mksnapshot.zip
|
||||
- appveyor PushArtifact out/Default/hunspell_dictionaries.zip
|
||||
- appveyor PushArtifact out/Default/electron.lib
|
||||
- ps: >-
|
||||
if ($env:GN_CONFIG -eq 'release') {
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
is_electron_build = true
|
||||
use_jumbo_build = true
|
||||
root_extra_deps = [ "//electron" ]
|
||||
|
||||
# Registry of NMVs --> https://github.com/nodejs/node/blob/master/doc/abi_version_registry.json
|
||||
@@ -9,6 +8,12 @@ v8_promise_internal_field_count = 1
|
||||
v8_typed_array_max_size_in_heap = 0
|
||||
v8_embedder_string = "-electron.0"
|
||||
|
||||
# TODO: this breaks native modules. See e.g. https://www.github.com/nodejs/node/pull/30463
|
||||
# We can probably enable this as long as we make sure node native modules
|
||||
# also build with the relevant #defines (V8_COMPRESS_POINTERS etc.)
|
||||
v8_enable_pointer_compression = false
|
||||
v8_enable_31bit_smis_on_64bit_arch = false
|
||||
|
||||
# TODO: this breaks mksnapshot
|
||||
v8_enable_snapshot_native_code_counters = false
|
||||
|
||||
@@ -18,12 +23,9 @@ ffmpeg_branding = "Chrome"
|
||||
|
||||
enable_basic_printing = true
|
||||
angle_enable_vulkan_validation_layers = false
|
||||
dawn_enable_vulkan_validation_layers = false
|
||||
|
||||
is_cfi = false
|
||||
|
||||
# TODO: Remove this and update CI to contain 10.14 SDK once
|
||||
# crbug.com/986701 is fixed.
|
||||
mac_sdk_min = "10.13"
|
||||
|
||||
# TODO: disabled due to crashes. re-enable.
|
||||
enable_osr = false
|
||||
|
||||
@@ -5,4 +5,3 @@ is_debug = false
|
||||
is_component_build = false
|
||||
is_component_ffmpeg = false
|
||||
symbol_level = 1
|
||||
use_jumbo_build = true
|
||||
|
||||
98
build/rules.gni
Normal file
98
build/rules.gni
Normal file
@@ -0,0 +1,98 @@
|
||||
import("//build/config/mac/mac_sdk.gni")
|
||||
|
||||
# Template to compile .xib and .storyboard files.
|
||||
# (copied from src/build/config/ios/rules.gni)
|
||||
#
|
||||
# Arguments
|
||||
#
|
||||
# sources:
|
||||
# list of string, sources to compile
|
||||
#
|
||||
# ibtool_flags:
|
||||
# (optional) list of string, additional flags to pass to the ibtool
|
||||
template("compile_ib_files") {
|
||||
action_foreach(target_name) {
|
||||
forward_variables_from(invoker,
|
||||
[
|
||||
"testonly",
|
||||
"visibility",
|
||||
])
|
||||
assert(defined(invoker.sources),
|
||||
"sources must be specified for $target_name")
|
||||
assert(defined(invoker.output_extension),
|
||||
"output_extension must be specified for $target_name")
|
||||
|
||||
ibtool_flags = []
|
||||
if (defined(invoker.ibtool_flags)) {
|
||||
ibtool_flags = invoker.ibtool_flags
|
||||
}
|
||||
|
||||
_output_extension = invoker.output_extension
|
||||
|
||||
script = "//build/config/ios/compile_ib_files.py"
|
||||
sources = invoker.sources
|
||||
outputs = [
|
||||
"$target_gen_dir/$target_name/{{source_name_part}}.$_output_extension",
|
||||
]
|
||||
args = [
|
||||
"--input",
|
||||
"{{source}}",
|
||||
"--output",
|
||||
rebase_path(
|
||||
"$target_gen_dir/$target_name/{{source_name_part}}.$_output_extension",
|
||||
root_build_dir),
|
||||
]
|
||||
args += ibtool_flags
|
||||
}
|
||||
}
|
||||
|
||||
# Template is copied here from Chromium but was removed in
|
||||
# https://chromium-review.googlesource.com/c/chromium/src/+/1637981
|
||||
# Template to compile and package Mac XIB files as bundle data.
|
||||
# Arguments
|
||||
# sources:
|
||||
# list of string, sources to comiple
|
||||
# output_path:
|
||||
# (optional) string, the path to use for the outputs list in the
|
||||
# bundle_data step. If unspecified, defaults to bundle_resources_dir.
|
||||
template("mac_xib_bundle_data") {
|
||||
_target_name = target_name
|
||||
_compile_target_name = _target_name + "_compile_ibtool"
|
||||
|
||||
compile_ib_files(_compile_target_name) {
|
||||
forward_variables_from(invoker, [ "testonly" ])
|
||||
visibility = [ ":$_target_name" ]
|
||||
sources = invoker.sources
|
||||
output_extension = "nib"
|
||||
ibtool_flags = [
|
||||
"--minimum-deployment-target",
|
||||
mac_deployment_target,
|
||||
|
||||
# TODO(rsesek): Enable this once all the bots are on Xcode 7+.
|
||||
# "--target-device",
|
||||
# "mac",
|
||||
]
|
||||
}
|
||||
|
||||
bundle_data(_target_name) {
|
||||
forward_variables_from(invoker,
|
||||
[
|
||||
"testonly",
|
||||
"visibility",
|
||||
])
|
||||
|
||||
public_deps = [
|
||||
":$_compile_target_name",
|
||||
]
|
||||
sources = get_target_outputs(":$_compile_target_name")
|
||||
|
||||
_output_path = "{{bundle_resources_dir}}"
|
||||
if (defined(invoker.output_path)) {
|
||||
_output_path = invoker.output_path
|
||||
}
|
||||
|
||||
outputs = [
|
||||
"$_output_path/{{source_file_part}}",
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -74,7 +74,10 @@ module.exports = ({
|
||||
global: ['@electron/internal/renderer/webpack-provider', '_global'],
|
||||
Buffer: ['@electron/internal/renderer/webpack-provider', 'Buffer'],
|
||||
})
|
||||
] : [])
|
||||
] : []),
|
||||
new webpack.ProvidePlugin({
|
||||
Promise: ['@electron/internal/common/webpack-globals-provider', 'Promise'],
|
||||
}),
|
||||
]
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
16
build/zip.py
16
build/zip.py
@@ -16,6 +16,10 @@ PATHS_TO_SKIP = [
|
||||
'./libVkICD_mock_', #Skipping because these are outputs that we don't need
|
||||
'./VkICD_mock_', #Skipping because these are outputs that we don't need
|
||||
|
||||
# Skipping because its an output of create_bundle from //build/config/mac/rules.gni
|
||||
# that we don't need
|
||||
'Electron.dSYM',
|
||||
|
||||
# //chrome/browser:resources depends on this via
|
||||
# //chrome/browser/resources/ssl/ssl_error_assistant, but we don't need to
|
||||
# ship it.
|
||||
@@ -46,19 +50,19 @@ def execute(argv):
|
||||
raise e
|
||||
|
||||
def main(argv):
|
||||
dist_zip, runtime_deps, target_cpu, target_os = argv
|
||||
dist_zip, runtime_deps, target_cpu, target_os, flatten_val = argv
|
||||
should_flatten = flatten_val == "true"
|
||||
dist_files = set()
|
||||
with open(runtime_deps) as f:
|
||||
for dep in f.readlines():
|
||||
dep = dep.strip()
|
||||
dist_files.add(dep)
|
||||
if sys.platform == 'darwin':
|
||||
if not skip_path(dep, dist_zip, target_cpu):
|
||||
dist_files.add(dep)
|
||||
if sys.platform == 'darwin' and not should_flatten:
|
||||
execute(['zip', '-r', '-y', dist_zip] + list(dist_files))
|
||||
else:
|
||||
with zipfile.ZipFile(dist_zip, 'w', zipfile.ZIP_DEFLATED, allowZip64=True) as z:
|
||||
for dep in dist_files:
|
||||
if skip_path(dep, dist_zip, target_cpu):
|
||||
continue
|
||||
if os.path.isdir(dep):
|
||||
for root, dirs, files in os.walk(dep):
|
||||
for file in files:
|
||||
@@ -67,7 +71,7 @@ def main(argv):
|
||||
basename = os.path.basename(dep)
|
||||
dirname = os.path.dirname(dep)
|
||||
arcname = os.path.join(dirname, 'chrome-sandbox') if basename == 'chrome_sandbox' else dep
|
||||
z.write(dep, arcname)
|
||||
z.write(dep, os.path.basename(arcname) if should_flatten else arcname)
|
||||
|
||||
if __name__ == '__main__':
|
||||
sys.exit(main(sys.argv[1:]))
|
||||
|
||||
@@ -19,7 +19,9 @@ buildflag_header("buildflags") {
|
||||
"ENABLE_TTS=$enable_tts",
|
||||
"ENABLE_COLOR_CHOOSER=$enable_color_chooser",
|
||||
"ENABLE_ELECTRON_EXTENSIONS=$enable_electron_extensions",
|
||||
"ENABLE_BUILTIN_SPELLCHECKER=$enable_builtin_spellchecker",
|
||||
"ENABLE_PICTURE_IN_PICTURE=$enable_picture_in_picture",
|
||||
"ENABLE_MEDIA_KEY_OVERRIDES=$enable_media_key_overrides",
|
||||
"OVERRIDE_LOCATION_PROVIDER=$enable_fake_location_provider",
|
||||
]
|
||||
}
|
||||
|
||||
@@ -22,6 +22,8 @@ declare_args() {
|
||||
|
||||
enable_picture_in_picture = true
|
||||
|
||||
enable_media_key_overrides = true
|
||||
|
||||
# Provide a fake location provider for mocking
|
||||
# the geolocation responses. Disable it if you
|
||||
# need to test with chromium's location provider.
|
||||
@@ -33,4 +35,7 @@ declare_args() {
|
||||
|
||||
# Enable Chrome extensions support.
|
||||
enable_electron_extensions = false
|
||||
|
||||
# Enable Spellchecker support
|
||||
enable_builtin_spellchecker = true
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
# found in the LICENSE file.
|
||||
|
||||
import("//build/config/ui.gni")
|
||||
import("//components/spellcheck/spellcheck_build_features.gni")
|
||||
import("//electron/buildflags/buildflags.gni")
|
||||
import("//printing/buildflags/buildflags.gni")
|
||||
import("//third_party/widevine/cdm/widevine.gni")
|
||||
@@ -31,6 +32,8 @@ static_library("chrome") {
|
||||
"//chrome/browser/icon_loader_win.cc",
|
||||
"//chrome/browser/icon_manager.cc",
|
||||
"//chrome/browser/icon_manager.h",
|
||||
"//chrome/browser/media/webrtc/system_media_capture_permissions_mac.h",
|
||||
"//chrome/browser/media/webrtc/system_media_capture_permissions_mac.mm",
|
||||
"//chrome/browser/net/chrome_mojo_proxy_resolver_factory.cc",
|
||||
"//chrome/browser/net/chrome_mojo_proxy_resolver_factory.h",
|
||||
"//chrome/browser/net/proxy_config_monitor.cc",
|
||||
@@ -39,12 +42,15 @@ static_library("chrome") {
|
||||
"//chrome/browser/net/proxy_service_factory.h",
|
||||
"//chrome/browser/predictors/preconnect_manager.cc",
|
||||
"//chrome/browser/predictors/preconnect_manager.h",
|
||||
"//chrome/browser/predictors/predictors_features.cc",
|
||||
"//chrome/browser/predictors/predictors_features.h",
|
||||
"//chrome/browser/predictors/proxy_lookup_client_impl.cc",
|
||||
"//chrome/browser/predictors/proxy_lookup_client_impl.h",
|
||||
"//chrome/browser/predictors/resolve_host_client_impl.cc",
|
||||
"//chrome/browser/predictors/resolve_host_client_impl.h",
|
||||
"//chrome/browser/ssl/security_state_tab_helper.cc",
|
||||
"//chrome/browser/ssl/security_state_tab_helper.h",
|
||||
"//chrome/browser/ssl/tls_deprecation_config.cc",
|
||||
"//chrome/browser/ui/autofill/popup_view_common.cc",
|
||||
"//chrome/browser/ui/autofill/popup_view_common.h",
|
||||
"//chrome/browser/win/chrome_process_finder.cc",
|
||||
@@ -70,6 +76,14 @@ static_library("chrome") {
|
||||
sources += [
|
||||
"//chrome/browser/extensions/global_shortcut_listener_x11.cc",
|
||||
"//chrome/browser/extensions/global_shortcut_listener_x11.h",
|
||||
"//chrome/browser/ui/views/status_icons/concat_menu_model.cc",
|
||||
"//chrome/browser/ui/views/status_icons/concat_menu_model.h",
|
||||
"//chrome/browser/ui/views/status_icons/status_icon_linux_dbus.cc",
|
||||
"//chrome/browser/ui/views/status_icons/status_icon_linux_dbus.h",
|
||||
]
|
||||
public_deps += [
|
||||
"//components/dbus/menu",
|
||||
"//components/dbus/thread_linux",
|
||||
]
|
||||
}
|
||||
|
||||
@@ -216,3 +230,58 @@ static_library("chrome") {
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
# This source set is just so we don't have to depend on all of //chrome/browser
|
||||
# You may have to add new files here during the upgrade if //chrome/browser/spellchecker
|
||||
# gets more files
|
||||
source_set("chrome_spellchecker") {
|
||||
sources = []
|
||||
deps = []
|
||||
libs = []
|
||||
|
||||
if (enable_builtin_spellchecker) {
|
||||
sources += [
|
||||
"//chrome/browser/spellchecker/spell_check_host_chrome_impl.cc",
|
||||
"//chrome/browser/spellchecker/spell_check_host_chrome_impl.h",
|
||||
"//chrome/browser/spellchecker/spellcheck_custom_dictionary.cc",
|
||||
"//chrome/browser/spellchecker/spellcheck_custom_dictionary.h",
|
||||
"//chrome/browser/spellchecker/spellcheck_factory.cc",
|
||||
"//chrome/browser/spellchecker/spellcheck_factory.h",
|
||||
"//chrome/browser/spellchecker/spellcheck_hunspell_dictionary.cc",
|
||||
"//chrome/browser/spellchecker/spellcheck_hunspell_dictionary.h",
|
||||
"//chrome/browser/spellchecker/spellcheck_language_blacklist_policy_handler.cc",
|
||||
"//chrome/browser/spellchecker/spellcheck_language_blacklist_policy_handler.h",
|
||||
"//chrome/browser/spellchecker/spellcheck_language_policy_handler.cc",
|
||||
"//chrome/browser/spellchecker/spellcheck_language_policy_handler.h",
|
||||
"//chrome/browser/spellchecker/spellcheck_service.cc",
|
||||
"//chrome/browser/spellchecker/spellcheck_service.h",
|
||||
]
|
||||
|
||||
if (has_spellcheck_panel) {
|
||||
sources += [
|
||||
"//chrome/browser/spellchecker/spell_check_panel_host_impl.cc",
|
||||
"//chrome/browser/spellchecker/spell_check_panel_host_impl.h",
|
||||
]
|
||||
}
|
||||
|
||||
if (use_browser_spellchecker) {
|
||||
sources += [
|
||||
"//chrome/browser/spellchecker/spelling_request.cc",
|
||||
"//chrome/browser/spellchecker/spelling_request.h",
|
||||
]
|
||||
}
|
||||
|
||||
deps += [
|
||||
"//base:base_static",
|
||||
"//components/language/core/browser",
|
||||
"//components/spellcheck:buildflags",
|
||||
"//components/sync",
|
||||
]
|
||||
}
|
||||
|
||||
public_deps = [
|
||||
"//components/spellcheck/browser",
|
||||
"//components/spellcheck/common",
|
||||
"//components/spellcheck/renderer",
|
||||
]
|
||||
}
|
||||
|
||||
@@ -37,10 +37,8 @@ net::NSSCertDatabase* GetNSSCertDatabaseForResourceContext(
|
||||
// public and private slot.
|
||||
// Redirect any slot usage to this persistent slot on Linux.
|
||||
g_nss_cert_database = new net::NSSCertDatabase(
|
||||
crypto::ScopedPK11Slot(
|
||||
crypto::GetPersistentNSSKeySlot()) /* public slot */,
|
||||
crypto::ScopedPK11Slot(
|
||||
crypto::GetPersistentNSSKeySlot()) /* private slot */);
|
||||
crypto::ScopedPK11Slot(PK11_GetInternalKeySlot()) /* public slot */,
|
||||
crypto::ScopedPK11Slot(PK11_GetInternalKeySlot()) /* private slot */);
|
||||
}
|
||||
return g_nss_cert_database;
|
||||
}
|
||||
|
||||
@@ -3,6 +3,8 @@ import * as path from 'path'
|
||||
|
||||
let mainWindow: BrowserWindow | null = null
|
||||
|
||||
app.allowRendererProcessReuse = true
|
||||
|
||||
// Quit when all windows are closed.
|
||||
app.on('window-all-closed', () => {
|
||||
app.quit()
|
||||
|
||||
@@ -2,10 +2,9 @@
|
||||
|
||||
<head>
|
||||
<title>Electron</title>
|
||||
<meta http-equiv="Content-Security-Policy" content="default-src 'none'; script-src 'self'; style-src 'self'; img-src 'self'; connect-src 'self'" />
|
||||
<meta http-equiv="Content-Security-Policy" content="default-src 'none'; script-src 'sha256-6PH54BfkNq/EMMhUY7nhHf3c+AxloOwfy7hWyT01CM8='; style-src 'self'; img-src 'self'; connect-src 'self'" />
|
||||
<link href="./styles.css" type="text/css" rel="stylesheet" />
|
||||
<link href="./octicon/build.css" type="text/css" rel="stylesheet" />
|
||||
<script defer src="./index.js"></script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
@@ -84,6 +83,9 @@
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
<script>
|
||||
window.electronDefaultApp.initialize()
|
||||
</script>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
@@ -1,30 +0,0 @@
|
||||
async function getOcticonSvg (name: string) {
|
||||
try {
|
||||
const response = await fetch(`octicon/${name}.svg`)
|
||||
const div = document.createElement('div')
|
||||
div.innerHTML = await response.text()
|
||||
return div
|
||||
} catch {
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
async function loadSVG (element: HTMLSpanElement) {
|
||||
for (const cssClass of element.classList) {
|
||||
if (cssClass.startsWith('octicon-')) {
|
||||
const icon = await getOcticonSvg(cssClass.substr(8))
|
||||
if (icon) {
|
||||
for (const elemClass of element.classList) {
|
||||
icon.classList.add(elemClass)
|
||||
}
|
||||
element.before(icon)
|
||||
element.remove()
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (const element of document.querySelectorAll<HTMLSpanElement>('.octicon')) {
|
||||
loadSVG(element)
|
||||
}
|
||||
@@ -1,4 +1,31 @@
|
||||
import { ipcRenderer } from 'electron'
|
||||
import { ipcRenderer, contextBridge } from 'electron'
|
||||
|
||||
async function getOcticonSvg (name: string) {
|
||||
try {
|
||||
const response = await fetch(`octicon/${name}.svg`)
|
||||
const div = document.createElement('div')
|
||||
div.innerHTML = await response.text()
|
||||
return div
|
||||
} catch {
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
async function loadSVG (element: HTMLSpanElement) {
|
||||
for (const cssClass of element.classList) {
|
||||
if (cssClass.startsWith('octicon-')) {
|
||||
const icon = await getOcticonSvg(cssClass.substr(8))
|
||||
if (icon) {
|
||||
for (const elemClass of element.classList) {
|
||||
icon.classList.add(elemClass)
|
||||
}
|
||||
element.before(icon)
|
||||
element.remove()
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async function initialize () {
|
||||
const electronPath = await ipcRenderer.invoke('bootstrap')
|
||||
@@ -15,6 +42,12 @@ async function initialize () {
|
||||
replaceText('.node-version', `Node v${process.versions.node}`)
|
||||
replaceText('.v8-version', `v8 v${process.versions.v8}`)
|
||||
replaceText('.command-example', `${electronPath} path-to-app`)
|
||||
|
||||
for (const element of document.querySelectorAll<HTMLSpanElement>('.octicon')) {
|
||||
loadSVG(element)
|
||||
}
|
||||
}
|
||||
|
||||
document.addEventListener('DOMContentLoaded', initialize)
|
||||
contextBridge.exposeInMainWorld('electronDefaultApp', {
|
||||
initialize
|
||||
})
|
||||
|
||||
@@ -314,10 +314,8 @@ Returns:
|
||||
|
||||
* `event` Event
|
||||
* `webContents` [WebContents](web-contents.md)
|
||||
* `request` Object
|
||||
* `method` String
|
||||
* `authenticationResponseDetails` Object
|
||||
* `url` URL
|
||||
* `referrer` URL
|
||||
* `authInfo` Object
|
||||
* `isProxy` Boolean
|
||||
* `scheme` String
|
||||
@@ -325,8 +323,8 @@ Returns:
|
||||
* `port` Integer
|
||||
* `realm` String
|
||||
* `callback` Function
|
||||
* `username` String
|
||||
* `password` String
|
||||
* `username` String (optional)
|
||||
* `password` String (optional)
|
||||
|
||||
Emitted when `webContents` wants to do basic auth.
|
||||
|
||||
@@ -337,12 +335,16 @@ should prevent the default behavior with `event.preventDefault()` and call
|
||||
```javascript
|
||||
const { app } = require('electron')
|
||||
|
||||
app.on('login', (event, webContents, request, authInfo, callback) => {
|
||||
app.on('login', (event, webContents, details, authInfo, callback) => {
|
||||
event.preventDefault()
|
||||
callback('username', 'secret')
|
||||
})
|
||||
```
|
||||
|
||||
If `callback` is called without a username or password, the authentication
|
||||
request will be cancelled and the authentication error will be returned to the
|
||||
page.
|
||||
|
||||
### Event: 'gpu-info-update'
|
||||
|
||||
Emitted whenever there is a GPU info update.
|
||||
@@ -770,6 +772,21 @@ macOS machine. Please refer to
|
||||
|
||||
The API uses the Windows Registry and LSCopyDefaultHandlerForURLScheme internally.
|
||||
|
||||
### `app.getApplicationNameForProtocol(url)`
|
||||
|
||||
* `url` String - a URL with the protocol name to check. Unlike the other
|
||||
methods in this family, this accepts an entire URL, including `://` at a
|
||||
minimum (e.g. `https://`).
|
||||
|
||||
Returns `String` - Name of the application handling the protocol, or an empty
|
||||
string if there is no handler. For instance, if Electron is the default
|
||||
handler of the URL, this could be `Electron` on Windows and Mac. However,
|
||||
don't rely on the precise format which is not guaranteed to remain unchanged.
|
||||
Expect a different format on Linux, possibly with a `.desktop` suffix.
|
||||
|
||||
This method returns the application name of the default handler for the protocol
|
||||
(aka URI scheme) of a URL.
|
||||
|
||||
### `app.setUserTasks(tasks)` _Windows_
|
||||
|
||||
* `tasks` [Task[]](structures/task.md) - Array of `Task` objects
|
||||
|
||||
@@ -59,6 +59,55 @@ these kinds of objects will throw a 'could not be cloned' error.
|
||||
|
||||
[SCA]: https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Structured_clone_algorithm
|
||||
|
||||
### `<webview>.getWebContents()`
|
||||
|
||||
This API is implemented using the `remote` module, which has both performance
|
||||
and security implications. Therefore its usage should be explicit.
|
||||
|
||||
```js
|
||||
// Deprecated
|
||||
webview.getWebContents()
|
||||
// Replace with
|
||||
const { remote } = require('electron')
|
||||
remote.webContents.fromId(webview.getWebContentsId())
|
||||
```
|
||||
|
||||
However, it is recommended to avoid using the `remote` module altogether.
|
||||
|
||||
```js
|
||||
// main
|
||||
const { ipcMain, webContents } = require('electron')
|
||||
|
||||
const getGuestForWebContents = function (webContentsId, contents) {
|
||||
const guest = webContents.fromId(webContentsId)
|
||||
if (!guest) {
|
||||
throw new Error(`Invalid webContentsId: ${webContentsId}`)
|
||||
}
|
||||
if (guest.hostWebContents !== contents) {
|
||||
throw new Error(`Access denied to webContents`)
|
||||
}
|
||||
return guest
|
||||
}
|
||||
|
||||
ipcMain.handle('openDevTools', (event, webContentsId) => {
|
||||
const guest = getGuestForWebContents(webContentsId, event.sender)
|
||||
guest.openDevTools()
|
||||
})
|
||||
|
||||
// renderer
|
||||
const { ipcRenderer } = require('electron')
|
||||
|
||||
ipcRenderer.invoke('openDevTools', webview.getWebContentsId())
|
||||
```
|
||||
|
||||
### `webFrame.setLayoutZoomLevelLimits()`
|
||||
|
||||
Chromium has removed support for changing the layout zoom level limits, and it
|
||||
is beyond Electron's capacity to maintain it. The function will emit a warning
|
||||
in Electron 8.x, and cease to exist in Electron 9.x. The layout zoom level
|
||||
limits are now fixed at a minimum of 0.25 and a maximum of 5.0, as defined
|
||||
[here](https://chromium.googlesource.com/chromium/src/+/938b37a6d2886bf8335fc7db792f1eb46c65b2ae/third_party/blink/common/page/page_zoom.cc#11).
|
||||
|
||||
## Planned Breaking API Changes (7.0)
|
||||
|
||||
### Node Headers URL
|
||||
@@ -103,7 +152,7 @@ const idleTime = getSystemIdleTime()
|
||||
### webFrame Isolated World APIs
|
||||
|
||||
```js
|
||||
// Removed in Elecron 7.0
|
||||
// Removed in Electron 7.0
|
||||
webFrame.setIsolatedWorldContentSecurityPolicy(worldId, csp)
|
||||
webFrame.setIsolatedWorldHumanReadableName(worldId, name)
|
||||
webFrame.setIsolatedWorldSecurityOrigin(worldId, securityOrigin)
|
||||
@@ -121,6 +170,40 @@ webFrame.setIsolatedWorldInfo(
|
||||
|
||||
This property was removed in Chromium 77, and as such is no longer available.
|
||||
|
||||
### `webkitdirectory` attribute for `<input type="file"/>`
|
||||

|
||||
The `webkitdirectory` property on HTML file inputs allows them to select folders.
|
||||
Previous versions of Electron had an incorrect implementation where the `event.target.files`
|
||||
of the input returned a `FileList` that returned one `File` corresponding to the selected folder.
|
||||

|
||||
As of Electron 7, that `FileList` is now list of all files contained within
|
||||
the folder, similarly to Chrome, Firefox, and Edge
|
||||
([link to MDN docs](https://developer.mozilla.org/en-US/docs/Web/API/HTMLInputElement/webkitdirectory)).
|
||||

|
||||
As an illustration, take a folder with this structure:
|
||||
```console
|
||||
folder
|
||||
├── file1
|
||||
├── file2
|
||||
└── file3
|
||||
```
|
||||

|
||||
In Electron <=6, this would return a `FileList` with a `File` object for:
|
||||
```console
|
||||
path/to/folder
|
||||
```
|
||||

|
||||
In Electron 7, this now returns a `FileList` with a `File` object for:
|
||||
```console
|
||||
/path/to/folder/file3
|
||||
/path/to/folder/file2
|
||||
/path/to/folder/file1
|
||||
```
|
||||

|
||||
Note that `webkitdirectory` no longer exposes the path to the selected folder.
|
||||
If you require the path to the selected folder rather than the folder contents,
|
||||
see the `dialog.showOpenDialog` API ([link](https://github.com/electron/electron/blob/master/docs/api/dialog.md#dialogshowopendialogbrowserwindow-options)).
|
||||
|
||||
## Planned Breaking API Changes (6.0)
|
||||
|
||||
### `win.setMenu(null)`
|
||||
|
||||
@@ -385,6 +385,8 @@ It creates a new `BrowserWindow` with native properties as set by the `options`.
|
||||
* `accessibleTitle` String (optional) - An alternative title string provided only
|
||||
to accessibility tools such as screen readers. This string is not directly
|
||||
visible to users.
|
||||
* `spellcheck` Boolean (optional) - Whether to enable the builtin spellchecker.
|
||||
Default is `false`.
|
||||
|
||||
When setting minimum or maximum window size with `minWidth`/`maxWidth`/
|
||||
`minHeight`/`maxHeight`, it only constrains the users. It won't prevent you from
|
||||
@@ -515,7 +517,7 @@ Emitted when the window is restored from a minimized state.
|
||||
Returns:
|
||||
|
||||
* `event` Event
|
||||
* `newBounds` [`Rectangle`](structures/rectangle.md) - Size the window is being resized to.
|
||||
* `newBounds` [Rectangle](structures/rectangle.md) - Size the window is being resized to.
|
||||
|
||||
Emitted before the window is resized. Calling `event.preventDefault()` will prevent the window from being resized.
|
||||
|
||||
@@ -530,7 +532,7 @@ Emitted after the window has been resized.
|
||||
Returns:
|
||||
|
||||
* `event` Event
|
||||
* `newBounds` [`Rectangle`](structures/rectangle.md) - Location the window is being moved to.
|
||||
* `newBounds` [Rectangle](structures/rectangle.md) - Location the window is being moved to.
|
||||
|
||||
Emitted before the window is moved. On Windows, calling `event.preventDefault()` will prevent the window from being moved.
|
||||
|
||||
@@ -1579,7 +1581,7 @@ Same as `webContents.showDefinitionForSelection()`.
|
||||
|
||||
#### `win.setIcon(icon)` _Windows_ _Linux_
|
||||
|
||||
* `icon` [NativeImage](native-image.md)
|
||||
* `icon` [NativeImage](native-image.md) | String
|
||||
|
||||
Changes window icon.
|
||||
|
||||
@@ -1625,7 +1627,7 @@ Returns `Boolean` - Whether the menu bar is visible.
|
||||
* `visible` Boolean
|
||||
* `options` Object (optional)
|
||||
* `visibleOnFullScreen` Boolean (optional) _macOS_ - Sets whether
|
||||
the window should be visible above fullscreen windows
|
||||
the window should be visible above fullscreen windows _deprecated_
|
||||
|
||||
Sets whether the window should be visible on all workspaces.
|
||||
|
||||
|
||||
@@ -32,8 +32,8 @@ the hostname and the port number 'hostname:port'.
|
||||
* `redirect` String (optional) - The redirect mode for this request. Should be
|
||||
one of `follow`, `error` or `manual`. Defaults to `follow`. When mode is `error`,
|
||||
any redirection will be aborted. When mode is `manual` the redirection will be
|
||||
deferred until [`request.followRedirect`](#requestfollowredirect) is invoked. Listen for the [`redirect`](#event-redirect) event in
|
||||
this mode to get more details about the redirect request.
|
||||
cancelled unless [`request.followRedirect`](#requestfollowredirect) is invoked
|
||||
synchronously during the [`redirect`](#event-redirect) event.
|
||||
|
||||
`options` properties such as `protocol`, `host`, `hostname`, `port` and `path`
|
||||
strictly follow the Node.js model as described in the
|
||||
@@ -70,8 +70,8 @@ Returns:
|
||||
* `port` Integer
|
||||
* `realm` String
|
||||
* `callback` Function
|
||||
* `username` String
|
||||
* `password` String
|
||||
* `username` String (optional)
|
||||
* `password` String (optional)
|
||||
|
||||
Emitted when an authenticating proxy is asking for user credentials.
|
||||
|
||||
@@ -136,8 +136,11 @@ Returns:
|
||||
* `redirectUrl` String
|
||||
* `responseHeaders` Record<String, String[]>
|
||||
|
||||
Emitted when there is redirection and the mode is `manual`. Calling
|
||||
[`request.followRedirect`](#requestfollowredirect) will continue with the redirection.
|
||||
Emitted when the server returns a redirect response (e.g. 301 Moved
|
||||
Permanently). Calling [`request.followRedirect`](#requestfollowredirect) will
|
||||
continue with the redirection. If this event is handled,
|
||||
[`request.followRedirect`](#requestfollowredirect) must be called
|
||||
**synchronously**, otherwise the request will be cancelled.
|
||||
|
||||
### Instance Properties
|
||||
|
||||
@@ -214,7 +217,8 @@ response object,it will emit the `aborted` event.
|
||||
|
||||
#### `request.followRedirect()`
|
||||
|
||||
Continues any deferred redirection request when the redirection mode is `manual`.
|
||||
Continues any pending redirection. Can only be called during a `'redirect'`
|
||||
event.
|
||||
|
||||
#### `request.getUploadProgress()`
|
||||
|
||||
|
||||
111
docs/api/context-bridge.md
Normal file
111
docs/api/context-bridge.md
Normal file
@@ -0,0 +1,111 @@
|
||||
# contextBridge
|
||||
|
||||
> Create a safe, bi-directional, synchronous bridge across isolated contexts
|
||||
|
||||
Process: [Renderer](../glossary.md#renderer-process)
|
||||
|
||||
An example of exposing an API to a renderer from an isolated preload script is given below:
|
||||
|
||||
```javascript
|
||||
// Preload (Isolated World)
|
||||
const { contextBridge, ipcRenderer } = require('electron')
|
||||
|
||||
contextBridge.exposeInMainWorld(
|
||||
'electron',
|
||||
{
|
||||
doThing: () => ipcRenderer.send('do-a-thing')
|
||||
}
|
||||
)
|
||||
```
|
||||
|
||||
```javascript
|
||||
// Renderer (Main World)
|
||||
|
||||
window.electron.doThing()
|
||||
```
|
||||
|
||||
## Glossary
|
||||
|
||||
### Main World
|
||||
|
||||
The "Main World" is the javascript context that your main renderer code runs in. By default the page you load in your renderer
|
||||
executes code in this world.
|
||||
|
||||
### Isolated World
|
||||
|
||||
When `contextIsolation` is enabled in your `webPreferences` your `preload` scripts run in an "Isolated World". You can read more about
|
||||
context isolation and what it affects in the [BrowserWindow](browser-window.md) docs.
|
||||
|
||||
## Methods
|
||||
|
||||
The `contextBridge` module has the following methods:
|
||||
|
||||
### `contextBridge.exposeInMainWorld(apiKey, api)` _Experimental_
|
||||
|
||||
* `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.
|
||||
|
||||
## Usage
|
||||
|
||||
### API Objects
|
||||
|
||||
The `api` object provided to [`exposeInMainWorld`](#contextbridgeexposeinmainworldapikey-api-experimental) must be an object
|
||||
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**. I.e. 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.
|
||||
|
||||
An example of a complex API object is shown below.
|
||||
|
||||
```javascript
|
||||
const { contextBridge } = require('electron')
|
||||
|
||||
contextBridge.exposeInMainWorld(
|
||||
'electron',
|
||||
{
|
||||
doThing: () => ipcRenderer.send('do-a-thing'),
|
||||
myPromises: [Promise.resolve(), Promise.reject(new Error('whoops'))],
|
||||
anAsyncFunction: async () => 123,
|
||||
data: {
|
||||
myFlags: ['a', 'b', 'c'],
|
||||
bootTime: 1234
|
||||
},
|
||||
nestedAPI: {
|
||||
evenDeeper: {
|
||||
youCanDoThisAsMuchAsYouWant: {
|
||||
fn: () => ({
|
||||
returnData: 123
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
)
|
||||
```
|
||||
|
||||
### API Functions
|
||||
|
||||
`Function` values that you bind through the `contextBridge` are proxied through Electron to ensure that contexts remain isolated. This
|
||||
results in some key limitations that we've outlined below.
|
||||
|
||||
#### Parameter / Error / Return Type support
|
||||
|
||||
Because parameters, errors and return values are **copied** when they are sent over the bridge there are only certain types that can be used.
|
||||
At a high level if the type you want to use can be serialized and un-serialized into the same object it will work. A table of type support
|
||||
has been included below for completeness.
|
||||
|
||||
| Type | Complexity | Parameter Support | Return Value Support | Limitations |
|
||||
| ---- | ---------- | ----------------- | -------------------- | ----------- |
|
||||
| `String` | Simple | ✅ | ✅ | N/A |
|
||||
| `Number` | Simple | ✅ | ✅ | N/A |
|
||||
| `Boolean` | Simple | ✅ | ✅ | N/A |
|
||||
| `Object` | Complex | ✅ | ✅ | Keys must be supported "Simple" types in this table. Values must be supported in this table. Prototype modifications are dropped. Sending custom classes will copy values but not the prototype. |
|
||||
| `Array` | Complex | ✅ | ✅ | Same limitations as the `Object` type |
|
||||
| `Error` | Complex | ✅ | ✅ | Errors that are thrown are also copied, this can result in the message and stack trace of the error changing slightly due to being thrown in a different context |
|
||||
| `Promise` | Complex | ✅ | ✅ | Promises are only proxied if they are a the return value or exact parameter. Promises nested in arrays or obejcts will be dropped. |
|
||||
| `Function` | Complex | ✅ | ✅ | Prototype modifications are dropped. Sending classes or constructors will not work. |
|
||||
| [Cloneable Types](https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Structured_clone_algorithm) | Simple | ✅ | ✅ | See the linked document on cloneable types |
|
||||
| `Symbol` | N/A | ❌ | ❌ | Symbols cannot be copied across contexts so they are dropped |
|
||||
|
||||
|
||||
If the type you care about is not in the above table it is probably not supported.
|
||||
@@ -91,7 +91,11 @@ The `desktopCapturer` module has the following methods:
|
||||
|
||||
Returns `Promise<DesktopCapturerSource[]>` - Resolves with an array of [`DesktopCapturerSource`](structures/desktop-capturer-source.md) objects, each `DesktopCapturerSource` represents a screen or an individual window that can be captured.
|
||||
|
||||
**Note** Capturing the screen contents requires user consent on macOS 10.15 Catalina or higher,
|
||||
which can detected by [`systemPreferences.getMediaAccessStatus`].
|
||||
|
||||
[`navigator.mediaDevices.getUserMedia`]: https://developer.mozilla.org/en/docs/Web/API/MediaDevices/getUserMedia
|
||||
[`systemPreferences.getMediaAccessStatus`]: system-preferences.md#systempreferencesgetmediaaccessstatusmediatype-macos
|
||||
|
||||
## Caveats
|
||||
|
||||
|
||||
@@ -77,6 +77,7 @@ only the next time a message is sent to `channel`, after which it is removed.
|
||||
|
||||
* `channel` String
|
||||
* `listener` Function
|
||||
* `...args` any[]
|
||||
|
||||
Removes the specified `listener` from the listener array for the specified
|
||||
`channel`.
|
||||
|
||||
@@ -329,9 +329,9 @@ can be called on empty images.
|
||||
|
||||
[buffer]: https://nodejs.org/api/buffer.html#buffer_class_buffer
|
||||
|
||||
## Properties
|
||||
### Instance Properties
|
||||
|
||||
### `nativeImage.isMacTemplateImage` _macOS_
|
||||
#### `nativeImage.isMacTemplateImage` _macOS_
|
||||
|
||||
A `Boolean` property that determines whether the image is considered a [template image](https://developer.apple.com/documentation/appkit/nsimage/1520017-template).
|
||||
|
||||
|
||||
@@ -217,11 +217,15 @@ that all statistics are reported in Kilobytes.
|
||||
|
||||
Returns `String` - The version of the host operating system.
|
||||
|
||||
Examples:
|
||||
Example:
|
||||
|
||||
* `macOS` -> `10.13.6`
|
||||
* `Windows` -> `10.0.17763`
|
||||
* `Linux` -> `4.15.0-45-generic`
|
||||
```js
|
||||
const version = process.getSystemVersion()
|
||||
console.log(version)
|
||||
// On macOS -> '10.13.6'
|
||||
// On Windows -> '10.0.17763'
|
||||
// On Linux -> '4.15.0-45-generic'
|
||||
```
|
||||
|
||||
**Note:** It returns the actual operating system version instead of kernel version on macOS unlike `os.release()`.
|
||||
|
||||
|
||||
@@ -389,9 +389,7 @@ which sends a `Buffer` as a response.
|
||||
* `url` String
|
||||
* `method` String (optional)
|
||||
* `session` Session | null (optional)
|
||||
* `uploadData` Object (optional)
|
||||
* `contentType` String - MIME type of the content.
|
||||
* `data` String - Content to be sent.
|
||||
* `uploadData` [ProtocolResponseUploadData](structures/protocol-response-upload-data.md) (optional)
|
||||
* `completion` Function (optional)
|
||||
* `error` Error
|
||||
|
||||
|
||||
@@ -456,10 +456,38 @@ this session just before normal `preload` scripts run.
|
||||
Returns `String[]` an array of paths to preload scripts that have been
|
||||
registered.
|
||||
|
||||
#### `ses.setSpellCheckerLanguages(languages)`
|
||||
|
||||
* `languages` String[] - An array of language codes to enable the spellchecker for.
|
||||
|
||||
The built in spellchecker does not automatically detect what language a user is typing in. In order for the
|
||||
spell checker to correctly check their words you must call this API with an array of language codes. You can
|
||||
get the list of supported language codes with the `ses.availableSpellCheckerLanguages` property.
|
||||
|
||||
#### `ses.getSpellCheckerLanguages()`
|
||||
|
||||
Returns `String[]` - An array of language codes the spellchecker is enabled for. If this list is empty the spellchecker
|
||||
will fallback to using `en-US`. By default on launch if this setting is an empty list Electron will try to populate this
|
||||
setting with the current OS locale. This setting is persisted across restarts.
|
||||
|
||||
#### `ses.setSpellCheckerDictionaryDownloadURL(url)`
|
||||
|
||||
* `url` String - A base URL for Electron to download hunspell dictionaries from.
|
||||
|
||||
By default Electron will download hunspell dictionaries from the Chromium CDN. If you want to override this
|
||||
behavior you can use this API to point the dictionary downloader at your own hosted version of the hunspell
|
||||
dictionaries. We publish a `hunspell_dictionaries.zip` file with each release which contains the files you need
|
||||
to host here.
|
||||
|
||||
### Instance Properties
|
||||
|
||||
The following properties are available on instances of `Session`:
|
||||
|
||||
#### `ses.availableSpellCheckerLanguages` _Readonly_
|
||||
|
||||
A `String[]` array which consists of all the known available spell checker languages. Providing a language
|
||||
code to the `setSpellCheckerLanaguages` API that isn't in this array will result in an error.
|
||||
|
||||
#### `ses.cookies` _Readonly_
|
||||
|
||||
A [`Cookies`](cookies.md) object for this session.
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# ProtocolResponseUploadData Object
|
||||
|
||||
* `contentType` String - MIME type of the content.
|
||||
* `data` String - Content to be sent.
|
||||
* `data` String | Buffer - Content to be sent.
|
||||
|
||||
@@ -291,7 +291,7 @@ This API is only available on macOS 10.14 Mojave or newer.
|
||||
* `window-frame` - Window frame.
|
||||
* `window-text` - Text in windows.
|
||||
* On **macOS**
|
||||
* `alternate-selected-control-text` - The text on a selected surface in a list or table.
|
||||
* `alternate-selected-control-text` - The text on a selected surface in a list or table. _deprecated_
|
||||
* `control-background` - The background of a large interface element, such as a browser or table.
|
||||
* `control` - The surface of a control.
|
||||
* `control-text` -The text of a control that isn’t disabled.
|
||||
@@ -310,7 +310,7 @@ This API is only available on macOS 10.14 Mojave or newer.
|
||||
* `selected-content-background` - The background for selected content in a key window or view.
|
||||
* `selected-control` - The surface of a selected control.
|
||||
* `selected-control-text` - The text of a selected control.
|
||||
* `selected-menu-item` - The text of a selected menu.
|
||||
* `selected-menu-item-text` - The text of a selected menu.
|
||||
* `selected-text-background` - The background of selected text.
|
||||
* `selected-text` - Selected text.
|
||||
* `separator` - A separator between different sections of content.
|
||||
@@ -328,6 +328,8 @@ This API is only available on macOS 10.14 Mojave or newer.
|
||||
Returns `String` - The system color setting in RGB hexadecimal form (`#ABCDEF`).
|
||||
See the [Windows docs][windows-colors] and the [MacOS docs][macos-colors] for more details.
|
||||
|
||||
The following colors are only available on macOS 10.14: `find-highlight`, `selected-content-background`, `separator`, `unemphasized-selected-content-background`, `unemphasized-selected-text-background`, and `unemphasized-selected-text`.
|
||||
|
||||
[windows-colors]:https://msdn.microsoft.com/en-us/library/windows/desktop/ms724371(v=vs.85).aspx
|
||||
[macos-colors]:https://developer.apple.com/design/human-interface-guidelines/macos/visual-design/color#dynamic-system-colors
|
||||
|
||||
@@ -432,11 +434,13 @@ Returns `Boolean` - `true` if the current process is a trusted accessibility cli
|
||||
|
||||
### `systemPreferences.getMediaAccessStatus(mediaType)` _macOS_
|
||||
|
||||
* `mediaType` String - `microphone` or `camera`.
|
||||
* `mediaType` String - Can be `microphone`, `camera` or `screen`.
|
||||
|
||||
Returns `String` - Can be `not-determined`, `granted`, `denied`, `restricted` or `unknown`.
|
||||
|
||||
This user consent was not required until macOS 10.14 Mojave, so this method will always return `granted` if your system is running 10.13 High Sierra or lower.
|
||||
This user consent was not required on macOS 10.13 High Sierra or lower so this method will always return `granted`.
|
||||
macOS 10.14 Mojave or higher requires consent for `microphone` and `camera` access.
|
||||
macOS 10.15 Catalina or higher requires consent for `screen` access.
|
||||
|
||||
### `systemPreferences.askForMediaAccess(mediaType)` _macOS_
|
||||
|
||||
|
||||
@@ -454,10 +454,8 @@ The usage is the same with [the `select-client-certificate` event of
|
||||
Returns:
|
||||
|
||||
* `event` Event
|
||||
* `request` Object
|
||||
* `method` String
|
||||
* `authenticationResponseDetails` Object
|
||||
* `url` URL
|
||||
* `referrer` URL
|
||||
* `authInfo` Object
|
||||
* `isProxy` Boolean
|
||||
* `scheme` String
|
||||
@@ -465,8 +463,8 @@ Returns:
|
||||
* `port` Integer
|
||||
* `realm` String
|
||||
* `callback` Function
|
||||
* `username` String
|
||||
* `password` String
|
||||
* `username` String (optional)
|
||||
* `password` String (optional)
|
||||
|
||||
Emitted when `webContents` wants to do basic auth.
|
||||
|
||||
@@ -570,6 +568,9 @@ Returns:
|
||||
* `titleText` String - Title or alt text of the selection that the context
|
||||
was invoked on.
|
||||
* `misspelledWord` String - The misspelled word under the cursor, if any.
|
||||
* `dictionarySuggestions` String[] - An array of suggested words to show the
|
||||
user to replace the `misspelledWord`. Only available if there is a misspelled
|
||||
word and spellchecker is enabled.
|
||||
* `frameCharset` String - The character encoding of the frame on which the
|
||||
menu was invoked.
|
||||
* `inputFieldType` String - If the context menu was invoked on an input
|
||||
@@ -1041,6 +1042,17 @@ contents.executeJavaScript('fetch("https://jsonplaceholder.typicode.com/users/1"
|
||||
})
|
||||
```
|
||||
|
||||
#### `contents.executeJavaScriptInIsolatedWorld(worldId, scripts[, userGesture])`
|
||||
|
||||
* `worldId` Integer - The ID of the world to run the javascript in, `0` is the default world, `999` is the world used by Electron's `contextIsolation` feature. You can provide any integer here.
|
||||
* `scripts` [WebSource[]](structures/web-source.md)
|
||||
* `userGesture` Boolean (optional) - Default is `false`.
|
||||
|
||||
Returns `Promise<any>` - A promise that resolves with the result of the executed code
|
||||
or is rejected if the result of the code is a rejected promise.
|
||||
|
||||
Works like `executeJavaScript` but evaluates `scripts` in an isolated context.
|
||||
|
||||
#### `contents.setIgnoreMenuShortcuts(ignore)` _Experimental_
|
||||
|
||||
* `ignore` Boolean
|
||||
@@ -1112,7 +1124,7 @@ Sets the maximum and minimum pinch-to-zoom level.
|
||||
> contents.setVisualZoomLevelLimits(1, 3)
|
||||
> ```
|
||||
|
||||
#### `contents.setLayoutZoomLevelLimits(minimumLevel, maximumLevel)`
|
||||
#### `contents.setLayoutZoomLevelLimits(minimumLevel, maximumLevel)` _Deprecated_
|
||||
|
||||
* `minimumLevel` Number
|
||||
* `maximumLevel` Number
|
||||
@@ -1121,6 +1133,8 @@ Returns `Promise<void>`
|
||||
|
||||
Sets the maximum and minimum layout-based (i.e. non-visual) zoom level.
|
||||
|
||||
**Deprecated:** This API is no longer supported by Chromium.
|
||||
|
||||
#### `contents.undo()`
|
||||
|
||||
Executes the editing command `undo` in web page.
|
||||
@@ -1237,7 +1251,7 @@ Captures a snapshot of the page within `rect`. Omitting `rect` will capture the
|
||||
|
||||
Get the system printer list.
|
||||
|
||||
Returns [`PrinterInfo[]`](structures/printer-info.md).
|
||||
Returns [`PrinterInfo[]`](structures/printer-info.md)
|
||||
|
||||
#### `contents.print([options], [callback])`
|
||||
|
||||
@@ -1326,12 +1340,13 @@ win.loadURL('http://github.com')
|
||||
|
||||
win.webContents.on('did-finish-load', () => {
|
||||
// Use default printing options
|
||||
win.webContents.printToPDF({}, (error, data) => {
|
||||
if (error) throw error
|
||||
win.webContents.printToPDF({}).then(data => {
|
||||
fs.writeFile('/tmp/print.pdf', data, (error) => {
|
||||
if (error) throw error
|
||||
console.log('Write PDF successfully.')
|
||||
})
|
||||
}).catch(error => {
|
||||
console.log(error)
|
||||
})
|
||||
})
|
||||
```
|
||||
|
||||
@@ -56,13 +56,15 @@ Sets the maximum and minimum pinch-to-zoom level.
|
||||
> webFrame.setVisualZoomLevelLimits(1, 3)
|
||||
> ```
|
||||
|
||||
### `webFrame.setLayoutZoomLevelLimits(minimumLevel, maximumLevel)`
|
||||
### `webFrame.setLayoutZoomLevelLimits(minimumLevel, maximumLevel)` _Deprecated_
|
||||
|
||||
* `minimumLevel` Number
|
||||
* `maximumLevel` Number
|
||||
|
||||
Sets the maximum and minimum layout-based (i.e. non-visual) zoom level.
|
||||
|
||||
**Deprecated:** This API is no longer supported by Chromium.
|
||||
|
||||
### `webFrame.setSpellCheckProvider(language, provider)`
|
||||
|
||||
* `language` String
|
||||
@@ -74,6 +76,17 @@ Sets the maximum and minimum layout-based (i.e. non-visual) zoom level.
|
||||
|
||||
Sets a provider for spell checking in input fields and text areas.
|
||||
|
||||
If you want to use this method you must disable the builtin spellchecker when you
|
||||
construct the window.
|
||||
|
||||
```js
|
||||
const mainWindow = new BrowserWindow({
|
||||
webPreferences: {
|
||||
spellcheck: false
|
||||
}
|
||||
})
|
||||
```
|
||||
|
||||
The `provider` must be an object that has a `spellCheck` method that accepts
|
||||
an array of individual words for spellchecking.
|
||||
The `spellCheck` function runs asynchronously and calls the `callback` function
|
||||
|
||||
@@ -146,7 +146,7 @@ response are visible by the time this listener is fired.
|
||||
* `timestamp` Double
|
||||
* `statusLine` String
|
||||
* `statusCode` Integer
|
||||
* `responseHeaders` Record<string, string> (optional)
|
||||
* `responseHeaders` Record<string, string[]> (optional)
|
||||
* `callback` Function
|
||||
* `headersReceivedResponse` Object
|
||||
* `cancel` Boolean (optional)
|
||||
@@ -175,7 +175,7 @@ The `callback` has to be called with a `response` object.
|
||||
* `resourceType` String
|
||||
* `referrer` String
|
||||
* `timestamp` Double
|
||||
* `responseHeaders` Record<string, string> (optional)
|
||||
* `responseHeaders` Record<string, string[]> (optional)
|
||||
* `fromCache` Boolean - Indicates whether the response was fetched from disk
|
||||
cache.
|
||||
* `statusCode` Integer
|
||||
@@ -205,7 +205,7 @@ and response headers are available.
|
||||
* `ip` String (optional) - The server IP address that the request was
|
||||
actually sent to.
|
||||
* `fromCache` Boolean
|
||||
* `responseHeaders` Record<string, string> (optional)
|
||||
* `responseHeaders` Record<string, string[]> (optional)
|
||||
|
||||
The `listener` will be called with `listener(details)` when a server initiated
|
||||
redirect is about to occur.
|
||||
@@ -224,7 +224,7 @@ redirect is about to occur.
|
||||
* `resourceType` String
|
||||
* `referrer` String
|
||||
* `timestamp` Double
|
||||
* `responseHeaders` Record<string, string> (optional)
|
||||
* `responseHeaders` Record<string, string[]> (optional)
|
||||
* `fromCache` Boolean
|
||||
* `statusCode` Integer
|
||||
* `statusLine` String
|
||||
|
||||
@@ -635,7 +635,7 @@ Returns `Promise<void>`
|
||||
|
||||
Sets the maximum and minimum pinch-to-zoom level.
|
||||
|
||||
### `<webview>.setLayoutZoomLevelLimits(minimumLevel, maximumLevel)`
|
||||
### `<webview>.setLayoutZoomLevelLimits(minimumLevel, maximumLevel)` _Deprecated_
|
||||
|
||||
* `minimumLevel` Number
|
||||
* `maximumLevel` Number
|
||||
@@ -644,11 +644,13 @@ Returns `Promise<void>`
|
||||
|
||||
Sets the maximum and minimum layout-based (i.e. non-visual) zoom level.
|
||||
|
||||
**Deprecated:** This API is no longer supported by Chromium.
|
||||
|
||||
### `<webview>.showDefinitionForSelection()` _macOS_
|
||||
|
||||
Shows pop-up dictionary that searches the selected word on the page.
|
||||
|
||||
### `<webview>.getWebContents()`
|
||||
### `<webview>.getWebContents()` _Deprecated_
|
||||
|
||||
Returns [`WebContents`](web-contents.md) - The web contents associated with
|
||||
this `webview`.
|
||||
|
||||
76
docs/fiddles/native-ui/drag-and-drop/index.html
Normal file
76
docs/fiddles/native-ui/drag-and-drop/index.html
Normal file
@@ -0,0 +1,76 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<title>Drag and drop files</title>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div>
|
||||
<h1>Drag and drop files</h1>
|
||||
<div>Supports: Win, macOS, Linux <span>|</span> Process: Both</div>
|
||||
<h3>
|
||||
Electron supports dragging files and content out from web content into
|
||||
the operating system's world.
|
||||
</h3>
|
||||
|
||||
<p>
|
||||
Open the
|
||||
<a href="https://electronjs.org/docs/tutorial/native-file-drag-drop">
|
||||
full API documentation (opens in new window)
|
||||
</a>
|
||||
in your browser.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<div>
|
||||
<h2>Dragging files</h2>
|
||||
<div>
|
||||
<div>
|
||||
<a href="#" id="drag-file-link">Drag Demo</a>
|
||||
</div>
|
||||
<p>
|
||||
Click and drag the link above to copy the renderer process
|
||||
javascript file on to your machine.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
In this demo, the <code>webContents.startDrag()</code> API is called
|
||||
in response to the <code>ondragstart</code> event.
|
||||
</p>
|
||||
<h5>Renderer Process</h5>
|
||||
<pre><code>
|
||||
const {ipcRenderer} = require('electron')
|
||||
|
||||
const dragFileLink = document.getElementById('drag-file-link')
|
||||
|
||||
dragFileLink.addEventListener('dragstart', (event) => {
|
||||
event.preventDefault()
|
||||
ipcRenderer.send('ondragstart', __filename)
|
||||
})
|
||||
</code></pre>
|
||||
<h5>Main Process</h5>
|
||||
<pre>
|
||||
<code>
|
||||
const {ipcMain} = require('electron')
|
||||
const path = require('path')
|
||||
|
||||
ipcMain.on('ondragstart', (event, filepath) => {
|
||||
const iconName = 'codeIcon.png'
|
||||
event.sender.startDrag({
|
||||
file: filepath,
|
||||
icon: path.join(__dirname, iconName)
|
||||
})
|
||||
})
|
||||
</code></pre>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
// You can also require other files to run in this process
|
||||
require("./renderer.js");
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
64
docs/fiddles/native-ui/drag-and-drop/main.js
Normal file
64
docs/fiddles/native-ui/drag-and-drop/main.js
Normal file
@@ -0,0 +1,64 @@
|
||||
// Modules to control application life and create native browser window
|
||||
const { app, BrowserWindow, ipcMain, nativeImage } = require('electron')
|
||||
// Keep a global reference of the window object, if you don't, the window will
|
||||
// be closed automatically when the JavaScript object is garbage collected.
|
||||
let mainWindow
|
||||
|
||||
function createWindow () {
|
||||
// Create the browser window.
|
||||
mainWindow = new BrowserWindow({
|
||||
width: 800,
|
||||
height: 600,
|
||||
webPreferences: {
|
||||
nodeIntegration: true
|
||||
}
|
||||
})
|
||||
|
||||
// and load the index.html of the app.
|
||||
mainWindow.loadFile('index.html')
|
||||
|
||||
// Open the DevTools.
|
||||
// mainWindow.webContents.openDevTools()
|
||||
|
||||
// Emitted when the window is closed.
|
||||
mainWindow.on('closed', function () {
|
||||
// Dereference the window object, usually you would store windows
|
||||
// in an array if your app supports multi windows, this is the time
|
||||
// when you should delete the corresponding element.
|
||||
mainWindow = null
|
||||
})
|
||||
}
|
||||
|
||||
// This method will be called when Electron has finished
|
||||
// initialization and is ready to create browser windows.
|
||||
// Some APIs can only be used after this event occurs.
|
||||
app.on('ready', createWindow)
|
||||
|
||||
// Quit when all windows are closed.
|
||||
app.on('window-all-closed', function () {
|
||||
// On OS X it is common for applications and their menu bar
|
||||
// to stay active until the user quits explicitly with Cmd + Q
|
||||
if (process.platform !== 'darwin') {
|
||||
app.quit()
|
||||
}
|
||||
})
|
||||
|
||||
app.on('activate', function () {
|
||||
// On OS X it's common to re-create a window in the app when the
|
||||
// dock icon is clicked and there are no other windows open.
|
||||
if (mainWindow === null) {
|
||||
createWindow()
|
||||
}
|
||||
})
|
||||
|
||||
ipcMain.on('ondragstart', (event, filepath) => {
|
||||
const icon = nativeImage.createFromDataURL('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACQAAAAkCAYAAADhAJiYAAAAAXNSR0IArs4c6QAAAAlwSFlzAAALEwAACxMBAJqcGAAAAVlpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IlhNUCBDb3JlIDUuNC4wIj4KICAgPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4KICAgICAgPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIKICAgICAgICAgICAgeG1sbnM6dGlmZj0iaHR0cDovL25zLmFkb2JlLmNvbS90aWZmLzEuMC8iPgogICAgICAgICA8dGlmZjpPcmllbnRhdGlvbj4xPC90aWZmOk9yaWVudGF0aW9uPgogICAgICA8L3JkZjpEZXNjcmlwdGlvbj4KICAgPC9yZGY6UkRGPgo8L3g6eG1wbWV0YT4KTMInWQAACsZJREFUWAmtWFlsXFcZ/u82++Jt7IyT2Em6ZFHTpAtWIzspEgjEUhA8VNAiIYEQUvuABBIUwUMkQIVKPCIoEiABLShISEBbhFJwIGRpIKRpbNeJ7bh2HHvssR3PPnPnLnzfmRlju6EQqUc+c++c8y/fv54z1uQOh+/7Glh0TD59TE/TND7lnfa4/64OKsM071QoeZpA/y9WWvk/B4XCC06TUC+Xyw8HTXNQ1+Ww6PpOrMebewXxvBueJ6/XHOdMJBL5J9Y97m2R0SS/wweE6JxkGx5dilWr1S/7dXsEa2o4+LyFmcFcaL5zbX3Y9gh5hpeWYpSB9XV5/H678V89BGYDXnHJlCsWn4gHrGc1K9CXxferOdvPOOKUfF8cH7nUyCtklQZXih/VNNlmirk3GdBSoIcRswW7/vVkLPYi5W2Uze8bh7J+4wLfh4dViFx5/nmrUi7/MhGNvrCkBfpeWqnW/7BUdadqntQ8zwr6vhUV34xpYnDynWvcmwQNaclDXsqgLMqkocPDw7fNx7d5qIX+/PmJxKGD6VdDkeh7ztyqOFfrokGCEWiiZ1mp0uITnuKAosaT7+pNxMYTyefutcQfbA+b1XLpH5fnF97/yD335Fu6mqTqsclDINBVmI4fDxw80KPAvJSt1MZtMcLiGxYUu83p4UkgnJZlqcl3LAj3WnTkIS9lUBYNPJjueVWgg7qocyOgliFqjZsg8gq5tRdiieQTf1gq15Y8CUbRZtyWOzZwc8lEqS3PTCtgqd13ieO68BQ2uNl64tXAewktrFuX2mPdkWAxn3sxnmx7sqUTJGqso8MGS9tbXFz8DMH8bblUX3T9QARVi8RV8qljfcJy0zRlaf6mzHEuzEtmekqCoZB4rqp0OmudHtUnlEWZlE0d1EWd1N3EozourcO65pw4eTIZQTW9VazJtbqvw9XwKVFQMsKDBuNhtp4uvGGFI+IDgKnpMjYyIis3ZsQMBIR7pONsIaMsyqRs6ohY1rPUSd3EQFDqo+kdZ3Fh4aupbdu+99uFQr2A1CBs4uEAjZjIFUMHi4dVxMXzCdCXQj4vBrwVCofl0ulTcv/DAxJJJBUPc8mpoyI2JDw7bFyT+ifTcSubyXytJ51+roWBxwG9Q73WWjZ7eSUU3//nXM0NI+x0PBGrTSgsLS9JFuFxHFrvSqIrJV279gi6tjiVspTza3JjZhY+0CQZj0mlWJSeHTslCro6eFqymCcVVN77kkGjs1p4sy2VOoSlOrFwT+XR+PjkgGaZ+ycKVbRTYUdVrmaImCvzk1dlFCEJdHRJ284+ie/ol0h7p7jFvExcvCCXzp2Rqem3pAMAiqWS6JGYhFI9Mjo6KjevXVUyKEuFHrKpY6JQ8TXT3D8+OTkAHBw6o6LCFo9ag3o4JtlCyTHEt5AxKvS6YUi5kJeZG3Py0NAxlLcJ9xti+K7Mjo/JfGZRuvv6Ze+9+yWEhDZAvzg3JyhX2d6/S7q6e+TimdOS7ElLKBZDwqvmj6rztayr1fVI1IoXi4PAcYZY1tPEEO1wEVlXgRFBDcmIXTqJsS+XyhKLJ5A/OpIVXXptWUYv/UvaenfIocEhMQ2EzHHErlXFCgQl3paU1eVl6QAY8sQTCSmVihKJx1V/ogvgIYF/pACdcMBhqONoHhF88/2d+bojyA6cRvje2IdFjoSjUSnBS8hgyS9lZOzKFdmPxO3o6gQIGzwuDn1dVSCtCKPy1pZXlATXqUsVYMLRmKo87vP4Y1ioqwCdCegmMYx3W/VPn8RrSDwwIMMbcEjkYo29JZVOy+ybI7K4eksODx1VSqvligpReSVLgySM/FI5h2q062jNyL3s7FtoAyGJIlx1225UmwJF6aJRJ3XzHXO9bWvsJa3jQFlBJkz6iuXdu32HzM7MyP0PPNgAU6ko4Qzp6b+flr8MD9OYJg9CwtzL5+T65ITs2bsP3mGxN/ZbBcOn0sk20gAkLQ+huXpFi8vkoY9AoyDjxTR1mbo6Ltt275HpN0dlNxQE40mVM8Ajjxx9VAGhAvQR1akZFCq799ADysMuQqOxh2FNmamEaz51ItGLfFD9+oUJoZkLowHoFA2mljUacqOMflKuVmHpfmnfvlMuvXZeStmMBIMhcWEdjgFJtrUjXI0KchAuAg0ilxLJNoRVBxhIBm0TjjKAuqjTqTs3CQZ6QUUMGFW7eiWMUg6w+yo8YMW7DqtqlZLkUDV2ISfd29KyDwk9MjYmMyOXxQIIKuShqo4VGFNBEgeDQYqVam5N5tEePFQgURIUBCsd1EWd1XrtDUUMLARD9bKaK5ytQ2Gb75g8WMiEP6VkfnZGevv6UF1vSBW5E0PFDAweFRvlfun8WVmamhDNrkmweQ0pwaPt6M4m8mgKTTFXqcrV0ZH1FKBg6qAu6qTuJiCV1Cp2Q0NDr9Uq5Ym+oMEDlSewsoRwrVBEaij7AJ4s7zrOpumxEdm15y6558GHJVe1Zezy6zJx6aJkpq5JFB4z6zVZmBiX1VWUP0IY4CFMYcpQdZ3xqIs6oftCE5DHKwd0q/tzOV8svdDb3nk8VnG9qmgQC0ZURz8Ur91alXgSByZ6ES9kZZTr/PR16UOCh+7dq0CWyyXJ4xqCQ0nKt9YQSlPue2gAeYZzD7yNLk0wmqAreb2WYSxAJ8Dget64wxtEBlDaqVOn/K5dB67t6+t5MhoMJuc8w8UPKiQ9CQR9JK5czhZAQxPt7TKF3OiAIisUViAD2Lg5d0P2HDgoKeRaW0enyqVwBJcO5fFG5dqa7h406qaeX8384uTZL5w9+UqxhYHFp0YLIYA9ddfu3T+4UJF6Rg+YAc9D0+RoIGP1ULhpWspr10evyK7+ftWTrk9PS/++A9KZSm26cih2mMOErem6n/ZsZwA2TM/MPHXs2LEftnSTbh0Q36mIIbx44cLvOnu3f+xUwbWLmoHTCUlF6g2jBQo/GnFrnGNqSHdvr+rIKGMW1KahwEBdzHft98aNwMr8zd8/NDDwccihc0hLi3GubRjY0Bm6H19fPvnZI4c/fHd7PJ2peXYZ+WQ26JufZELjQ6lbAQtnWre0d3apY8TFIdtAo+Qri6mupsB49lBMC+QXF0YefObZT8j0eKWlswVjEyCCOXHihPGb575VCvVuf3lvetsH9rXF0rla3cnhpoIGjgsUPhR3I4TMKYJQV1Z6WO02aEjHa5mNe3OPW3OPRHVrbXFh9Ocvv/KR1372owx1Pf3005uc35Ddgtd8rsf06IdS5777zZ+mUqmPzjm6TPpmvayZOq4LyATeCzkanmiy4qEuC/yXiO8CSMRzvLs1x9phepLNZl868sy3Pyen/5hd1/EfRvWmuvSWNeaRS/RkPDI4+NjE1NSXEoXlpaNB1zqo20abi59/vu/UfM2pie7WUDVq8l3wTwnskeZ+zTbIQ17KoCzKpGzq2KqX32/roRbh8ePHdUzl0s9/5Rv9n/7go19MxCKfCkZiu3V06wrO5gocxL7Dgd/IEobEMH6rejg+auXidL5Y/vWv/vTX53/y/e/MkGajTH7fOt4RUJOY1df4RdtY6ICFRzqTySOhUOA+3Ai3o31H1ZbnlXBruFmt2iMrudy5xx9//BzWV7nXDBGN2xpjbt/5oGUEdhtO3iD47xZOvm8a5CHvpsV38wsUaMwBWsz3rbK5xr0mzdv2t9Jv/f5vhsF4J+Q63IUAAAAASUVORK5CYII=')
|
||||
|
||||
event.sender.startDrag({
|
||||
file: filepath,
|
||||
icon
|
||||
})
|
||||
})
|
||||
|
||||
// In this file you can include the rest of your app's specific main process
|
||||
// code. You can also put them in separate files and require them here.
|
||||
21
docs/fiddles/native-ui/drag-and-drop/renderer.js
Normal file
21
docs/fiddles/native-ui/drag-and-drop/renderer.js
Normal file
@@ -0,0 +1,21 @@
|
||||
const { ipcRenderer } = require('electron')
|
||||
const shell = require('electron').shell
|
||||
|
||||
const links = document.querySelectorAll('a[href]')
|
||||
|
||||
Array.prototype.forEach.call(links, (link) => {
|
||||
const url = link.getAttribute('href')
|
||||
if (url.indexOf('http') === 0) {
|
||||
link.addEventListener('click', (e) => {
|
||||
e.preventDefault()
|
||||
shell.openExternal(url)
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
const dragFileLink = document.getElementById('drag-file-link')
|
||||
|
||||
dragFileLink.addEventListener('dragstart', event => {
|
||||
event.preventDefault()
|
||||
ipcRenderer.send('ondragstart', __filename)
|
||||
})
|
||||
@@ -0,0 +1,24 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
</head>
|
||||
<body>
|
||||
<div>
|
||||
<div>
|
||||
<h1>Open Path in File Manager</h1>
|
||||
<i>Supports: Win, macOS, Linux <span>|</span> Process: Both</i>
|
||||
<div>
|
||||
<p>This demonstrates using the <code>shell</code> module to open the system file manager at a particular location.</p>
|
||||
<p>Clicking the demo button will open your file manager at the root.</p>
|
||||
<div>
|
||||
<button id="open-file-manager">View Demo</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
<script>
|
||||
require('./renderer.js')
|
||||
</script>
|
||||
</html>
|
||||
@@ -0,0 +1,25 @@
|
||||
const { app, BrowserWindow } = require('electron')
|
||||
|
||||
let mainWindow = null
|
||||
|
||||
function createWindow () {
|
||||
const windowOptions = {
|
||||
width: 600,
|
||||
height: 400,
|
||||
title: 'Open Path in File Manager',
|
||||
webPreferences: {
|
||||
nodeIntegration: true
|
||||
}
|
||||
}
|
||||
|
||||
mainWindow = new BrowserWindow(windowOptions)
|
||||
mainWindow.loadFile('index.html')
|
||||
|
||||
mainWindow.on('closed', () => {
|
||||
mainWindow = null
|
||||
})
|
||||
}
|
||||
|
||||
app.on('ready', () => {
|
||||
createWindow()
|
||||
})
|
||||
@@ -0,0 +1,8 @@
|
||||
const { shell } = require('electron')
|
||||
const os = require('os')
|
||||
|
||||
const fileManagerBtn = document.getElementById('open-file-manager')
|
||||
|
||||
fileManagerBtn.addEventListener('click', (event) => {
|
||||
shell.showItemInFolder(os.homedir())
|
||||
})
|
||||
BIN
docs/images/performance-cpu-prof.png
Normal file
BIN
docs/images/performance-cpu-prof.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 868 KiB |
BIN
docs/images/performance-heap-prof.png
Normal file
BIN
docs/images/performance-heap-prof.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.1 MiB |
@@ -13,4 +13,5 @@
|
||||
| 5.0.0 | 2019-01-22 | 2019-04-24 | M73 | v12 |
|
||||
| 6.0.0 | 2019-05-01 | 2019-07-30 | M76 | v12 |
|
||||
| 7.0.0 | 2019-08-01 | 2019-10-22 | M78 | v12 |
|
||||
| 8.0.0 | TBD | TBD | TBD | TBD |
|
||||
| 8.0.0 | 2019-10-24 | 2020-02-04 | M80 | v12 |
|
||||
| 9.0.0 | TBD | TBD | TBD | TBD |
|
||||
|
||||
@@ -38,11 +38,15 @@ npm install --platform=win32 electron
|
||||
|
||||
## Proxies
|
||||
|
||||
If you need to use an HTTP proxy you can [set these environment variables][proxy-env].
|
||||
If you need to use an HTTP proxy, you need to set the `ELECTRON_GET_USE_PROXY` variable to any
|
||||
value, plus additional environment variables depending on your host system's Node version:
|
||||
|
||||
* [Node 10 and above][proxy-env-10]
|
||||
* [Before Node 10][proxy-env]
|
||||
|
||||
## Custom Mirrors and Caches
|
||||
During installation, the `electron` module will call out to
|
||||
[`electron-download`][electron-download] to download prebuilt binaries of
|
||||
[`@electron/get`][electron-get] to download prebuilt binaries of
|
||||
Electron for your platform. It will do so by contacting GitHub's
|
||||
release download page (`https://github.com/electron/electron/releases/tag/v$VERSION`,
|
||||
where `$VERSION` is the exact version of Electron).
|
||||
@@ -52,7 +56,7 @@ can do so by either providing a mirror or an existing cache directory.
|
||||
|
||||
#### Mirror
|
||||
You can use environment variables to override the base URL, the path at which to
|
||||
look for Electron binaries, and the binary filename. The url used by `electron-download`
|
||||
look for Electron binaries, and the binary filename. The url used by `@electron/get`
|
||||
is composed as follows:
|
||||
|
||||
```plaintext
|
||||
@@ -62,11 +66,11 @@ url = ELECTRON_MIRROR + ELECTRON_CUSTOM_DIR + '/' + ELECTRON_CUSTOM_FILENAME
|
||||
For instance, to use the China mirror:
|
||||
|
||||
```plaintext
|
||||
ELECTRON_MIRROR="https://npm.taobao.org/mirrors/electron/"
|
||||
ELECTRON_MIRROR="https://cdn.npm.taobao.org/dist/electron/"
|
||||
```
|
||||
|
||||
#### Cache
|
||||
Alternatively, you can override the local cache. `electron-download` will cache
|
||||
Alternatively, you can override the local cache. `@electron/get` will cache
|
||||
downloaded binaries in a local directory to not stress your network. You can use
|
||||
that cache folder to provide custom builds of Electron or to avoid making contact
|
||||
with the network at all.
|
||||
@@ -85,16 +89,26 @@ The cache contains the version's official zip file as well as a checksum, stored
|
||||
a text file. A typical cache might look like this:
|
||||
|
||||
```sh
|
||||
├── electron-v1.7.9-darwin-x64.zip
|
||||
├── electron-v1.8.1-darwin-x64.zip
|
||||
├── electron-v1.8.2-beta.1-darwin-x64.zip
|
||||
├── electron-v1.8.2-beta.2-darwin-x64.zip
|
||||
├── electron-v1.8.2-beta.3-darwin-x64.zip
|
||||
├── SHASUMS256.txt-1.7.9
|
||||
├── SHASUMS256.txt-1.8.1
|
||||
├── SHASUMS256.txt-1.8.2-beta.1
|
||||
├── SHASUMS256.txt-1.8.2-beta.2
|
||||
├── SHASUMS256.txt-1.8.2-beta.3
|
||||
├── httpsgithub.comelectronelectronreleasesdownloadv1.7.9electron-v1.7.9-darwin-x64.zip
|
||||
│ └── electron-v1.7.9-darwin-x64.zip
|
||||
├── httpsgithub.comelectronelectronreleasesdownloadv1.7.9SHASUMS256.txt
|
||||
│ └── SHASUMS256.txt
|
||||
├── httpsgithub.comelectronelectronreleasesdownloadv1.8.1electron-v1.8.1-darwin-x64.zip
|
||||
│ └── electron-v1.8.1-darwin-x64.zip
|
||||
├── httpsgithub.comelectronelectronreleasesdownloadv1.8.1SHASUMS256.txt
|
||||
│ └── SHASUMS256.txt
|
||||
├── httpsgithub.comelectronelectronreleasesdownloadv1.8.2-beta.1electron-v1.8.2-beta.1-darwin-x64.zip
|
||||
│ └── electron-v1.8.2-beta.1-darwin-x64.zip
|
||||
├── httpsgithub.comelectronelectronreleasesdownloadv1.8.2-beta.1SHASUMS256.txt
|
||||
│ └── SHASUMS256.txt
|
||||
├── httpsgithub.comelectronelectronreleasesdownloadv1.8.2-beta.2electron-v1.8.2-beta.2-darwin-x64.zip
|
||||
│ └── electron-v1.8.2-beta.2-darwin-x64.zip
|
||||
├── httpsgithub.comelectronelectronreleasesdownloadv1.8.2-beta.2SHASUMS256.txt
|
||||
│ └── SHASUMS256.txt
|
||||
├── httpsgithub.comelectronelectronreleasesdownloadv1.8.2-beta.3electron-v1.8.2-beta.3-darwin-x64.zip
|
||||
│ └── electron-v1.8.2-beta.3-darwin-x64.zip
|
||||
└── httpsgithub.comelectronelectronreleasesdownloadv1.8.2-beta.3SHASUMS256.txt
|
||||
└── SHASUMS256.txt
|
||||
```
|
||||
|
||||
## Skip binary download
|
||||
@@ -146,7 +160,8 @@ If you need to force a re-download of the asset and the SHASUM file set the
|
||||
[npm]: https://docs.npmjs.com
|
||||
[versioning]: ./electron-versioning.md
|
||||
[releases]: https://github.com/electron/electron/releases
|
||||
[proxy-env]: https://github.com/request/request/tree/f0c4ec061141051988d1216c24936ad2e7d5c45d#controlling-proxy-behaviour-using-environment-variables
|
||||
[electron-download]: https://github.com/electron-userland/electron-download
|
||||
[proxy-env-10]: https://github.com/gajus/global-agent/blob/v2.1.5/README.md#environment-variables
|
||||
[proxy-env]: https://github.com/np-maintain/global-tunnel/blob/v2.7.1/README.md#auto-config
|
||||
[electron-get]: https://github.com/electron/get
|
||||
[npm-permissions]: https://docs.npmjs.com/getting-started/fixing-npm-permissions
|
||||
[unsafe-perm]: https://docs.npmjs.com/misc/config#unsafe-perm
|
||||
|
||||
431
docs/tutorial/performance.md
Normal file
431
docs/tutorial/performance.md
Normal file
@@ -0,0 +1,431 @@
|
||||
# Performance
|
||||
|
||||
Developers frequently ask about strategies to optimize the performance of
|
||||
Electron applications. Software engineers, consumers, and framework developers
|
||||
do not always agree on one single definition of what "performance" means. This
|
||||
document outlines some of the Electron maintainers' favorite ways to reduce the
|
||||
amount of memory, CPU, and disk resources being used while ensuring that your
|
||||
app is responsive to user input and completes operations as quickly as
|
||||
possible. Furthermore, we want all performance strategies to maintain a high
|
||||
standard for your app's security.
|
||||
|
||||
Wisdom and information about how to build performant websites with JavaScript
|
||||
generally applies to Electron apps, too. To a certain extent, resources
|
||||
discussing how to build performant Node.js applications also apply, but be
|
||||
careful to understand that the term "performance" means different things for
|
||||
a Node.js backend than it does for an application running on a client.
|
||||
|
||||
This list is provided for your convenience – and is, much like our
|
||||
[security checklist][security] – not meant to exhaustive. It is probably possible
|
||||
to build a slow Electron app that follows all the steps outlined below. Electron
|
||||
is a powerful development platform that enables you, the developer, to do more
|
||||
or less whatever you want. All that freedom means that performance is largely
|
||||
your responsibility.
|
||||
|
||||
## Measure, Measure, Measure
|
||||
|
||||
The list below contains a number of steps that are fairly straightforward and
|
||||
easy to implement. However, building the most performant version of your app
|
||||
will require you to go beyond a number of steps. Instead, you will have to
|
||||
closely examine all the code running in your app by carefully profiling and
|
||||
measuring. Where are the bottlenecks? When the user clicks a button, what
|
||||
operations take up the brunt of the time? While the app is simply idling, which
|
||||
objects take up the most memory?
|
||||
|
||||
Time and time again, we have seen that the most successful strategy for building
|
||||
a performant Electron app is to profile the running code, find the most
|
||||
resource-hungry piece of it, and to optimize it. Repeating this seemingly
|
||||
laborious process over and over again will dramatically increase your app's
|
||||
performance. Experience from working with major apps like Visual Studio Code or
|
||||
Slack has shown that this practice is by far the most reliable strategy to
|
||||
improve performance.
|
||||
|
||||
To learn more about how to profile your app's code, familiarize yourself with
|
||||
the Chrome Developer Tools. For advanced analysis looking at multiple processes
|
||||
at once, consider the [Chrome Tracing] tool.
|
||||
|
||||
### Recommended Reading
|
||||
|
||||
* [Get Started With Analyzing Runtime Performance][chrome-devtools-tutorial]
|
||||
* [Talk: "Visual Studio Code - The First Second"][vscode-first-second]
|
||||
|
||||
## Checklist
|
||||
|
||||
Chances are that your app could be a little leaner, faster, and generally less
|
||||
resource-hungry if you attempt these steps.
|
||||
|
||||
1. [Carelessly including modules](#1-carelessly-including-modules)
|
||||
2. [Loading and running code too soon](#2-loading-and-running-code-too-soon)
|
||||
3. [Blocking the main process](#3-blocking-the-main-process)
|
||||
4. [Blocking the renderer process](#4-blocking-the-renderer-process)
|
||||
5. [Unnecessary polyfills](#5-unnecessary-polyfills)
|
||||
6. [Unnecessary or blocking network requests](#6-unnecessary-or-blocking-network-requests)
|
||||
7. [Bundle your code](#7-bundle-your-code)
|
||||
|
||||
## 1) Carelessly including modules
|
||||
|
||||
Before adding a Node.js module to your application, examine said module. How
|
||||
many dependencies does that module include? What kind of resources does
|
||||
it need to simply be called in a `require()` statement? You might find
|
||||
that the module with the most downloads on the NPM package registry or the most stars on GitHub
|
||||
is not in fact the leanest or smallest one available.
|
||||
|
||||
### Why?
|
||||
|
||||
The reasoning behind this recommendation is best illustrated with a real-world
|
||||
example. During the early days of Electron, reliable detection of network
|
||||
connectivity was a problem, resulting many apps to use a module that exposed a
|
||||
simple `isOnline()` method.
|
||||
|
||||
That module detected your network connectivity by attempting to reach out to a
|
||||
number of well-known endpoints. For the list of those endpoints, it depended on
|
||||
a different module, which also contained a list of well-known ports. This
|
||||
dependency itself relied on a module containing information about ports, which
|
||||
came in the form of a JSON file with more than 100,000 lines of content.
|
||||
Whenever the module was loaded (usually in a `require('module')` statement),
|
||||
it would load all its dependencies and eventually read and parse this JSON
|
||||
file. Parsing many thousands lines of JSON is a very expensive operation. On
|
||||
a slow machine it can take up whole seconds of time.
|
||||
|
||||
In many server contexts, startup time is virtually irrelevant. A Node.js server
|
||||
that requires information about all ports is likely actually "more performant"
|
||||
if it loads all required information into memory whenever the server boots at
|
||||
the benefit of serving requests faster. The module discussed in this example is
|
||||
not a "bad" module. Electron apps, however, should not be loading, parsing, and
|
||||
storing in memory information that it does not actually need.
|
||||
|
||||
In short, a seemingly excellent module written primarily for Node.js servers
|
||||
running Linux might be bad news for your app's performance. In this particular
|
||||
example, the correct solution was to use no module at all, and to instead use
|
||||
connectivity checks included in later versions of Chromium.
|
||||
|
||||
### How?
|
||||
|
||||
When considering a module, we recommend that you check:
|
||||
|
||||
1. the size of dependencies included
|
||||
2) the resources required to load (`require()`) it
|
||||
3. the resources required to perform the action you're interested in
|
||||
|
||||
Generating a CPU profile and a heap memory profile for loading a module can be done
|
||||
with a single command on the command line. In the example below, we're looking at
|
||||
the popular module `request`.
|
||||
|
||||
```sh
|
||||
node --cpu-prof --heap-prof -e "require('request')"
|
||||
```
|
||||
|
||||
Executing this command results in a `.cpuprofile` file and a `.heapprofile`
|
||||
file in the directory you executed it in. Both files can be analyzed using
|
||||
the Chrome Developer Tools, using the `Performance` and `Memory` tabs
|
||||
respectively.
|
||||
|
||||
![performance-cpu-prof]
|
||||
|
||||
![performance-heap-prof]
|
||||
|
||||
In this example, on the author's machine, we saw that loading `request` took
|
||||
almost half a second, whereas `node-fetch` took dramatically less memory
|
||||
and less than 50ms.
|
||||
|
||||
## 2) Loading and running code too soon
|
||||
|
||||
If you have expensive setup operations, consider deferring those. Inspect all
|
||||
the work being executed right after the application starts. Instead of firing
|
||||
off all operations right away, consider staggering them in a sequence more
|
||||
closely aligned with the user's journey.
|
||||
|
||||
In traditional Node.js development, we're used to putting all our `require()`
|
||||
statements at the top. If you're currently writing your Electron application
|
||||
using the same strategy _and_ are using sizable modules that you do not
|
||||
immediately need, apply the same strategy and defer loading to a more
|
||||
opportune time.
|
||||
|
||||
### Why?
|
||||
|
||||
Loading modules is a surprisingly expensive operation, especially on Windows.
|
||||
When your app starts, it should not make users wait for operations that are
|
||||
currently not necessary.
|
||||
|
||||
This might seem obvious, but many applications tend to do a large amount of
|
||||
work immediately after the app has launched - like checking for updates,
|
||||
downloading content used in a later flow, or performing heavy disk I/O
|
||||
operations.
|
||||
|
||||
Let's consider Visual Studio Code as an example. When you open a file, it will
|
||||
immediately display the file to you without any code highlighting, prioritizing
|
||||
your ability to interact with the text. Once it has done that work, it will
|
||||
move on to code highlighting.
|
||||
|
||||
### How?
|
||||
|
||||
Let's consider an example and assume that your application is parsing files
|
||||
in the fictitious `.foo` format. In order to do that, it relies on the
|
||||
equally fictitious `foo-parser` module. In traditional Node.js development,
|
||||
you might write code that eagerly loads dependencies:
|
||||
|
||||
```js
|
||||
const fs = require('fs')
|
||||
const fooParser = require('foo-parser')
|
||||
|
||||
class Parser {
|
||||
constructor () {
|
||||
this.files = fs.readdirSync('.')
|
||||
}
|
||||
|
||||
getParsedFiles () {
|
||||
return fooParser.parse(this.files)
|
||||
}
|
||||
}
|
||||
|
||||
const parser = new Parser()
|
||||
|
||||
module.exports = { parser }
|
||||
```
|
||||
|
||||
In the above example, we're doing a lot of work that's being executed as soon
|
||||
as the file is loaded. Do we need to get parsed files right away? Could we
|
||||
do this work a little later, when `getParsedFiles()` is actually called?
|
||||
|
||||
```js
|
||||
// "fs" is likely already being loaded, so the `require()` call is cheap
|
||||
const fs = require('fs')
|
||||
|
||||
class Parser {
|
||||
async getFiles () {
|
||||
// Touch the disk as soon as `getFiles` is called, not sooner.
|
||||
// Also, ensure that we're not blocking other operations by using
|
||||
// the asynchronous version.
|
||||
this.files = this.files || await fs.readdir('.')
|
||||
|
||||
return this.files
|
||||
}
|
||||
|
||||
async getParsedFiles () {
|
||||
// Our fictitious foo-parser is a big and expensive module to load, so
|
||||
// defer that work until we actually need to parse files.
|
||||
// Since `require()` comes with a module cache, the `require()` call
|
||||
// will only be expensive once - subsequent calls of `getParsedFiles()`
|
||||
// will be faster.
|
||||
const fooParser = require('foo-parser')
|
||||
const files = await this.getFiles()
|
||||
|
||||
return fooParser.parse(files)
|
||||
}
|
||||
}
|
||||
|
||||
// This operation is now a lot cheaper than in our previous example
|
||||
const parser = new Parser()
|
||||
|
||||
module.exports = { parser }
|
||||
```
|
||||
|
||||
In short, allocate resources "just in time" rather than allocating them all
|
||||
when your app starts.
|
||||
|
||||
## 3) Blocking the main process
|
||||
|
||||
Electron's main process (sometimes called "browser process") is special: It is
|
||||
the parent process to all your app's other processes and the primary process
|
||||
the operating system interacts with. It handles windows, interactions, and the
|
||||
communication between various components inside your app. It also houses the
|
||||
UI thread.
|
||||
|
||||
Under no circumstances should you block this process and the UI thread with
|
||||
long-running operations. Blocking the UI thread means that your entire app
|
||||
will freeze until the main process is ready to continue processing.
|
||||
|
||||
### Why?
|
||||
|
||||
The main process and its UI thread are essentially the control tower for major
|
||||
operations inside your app. When the operating system tells your app about a
|
||||
mouse click, it'll go through the main process before it reaches your window.
|
||||
If your window is rendering a buttery-smooth animation, it'll need to talk to
|
||||
the GPU process about that – once again going through the main process.
|
||||
|
||||
Electron and Chromium are careful to put heavy disk I/O and CPU-bound operations
|
||||
onto new threads to avoid blocking the UI thread. You should do the same.
|
||||
|
||||
### How?
|
||||
|
||||
Electron's powerful multi-process architecture stands ready to assist you with
|
||||
your long-running tasks, but also includes a small number of performance traps.
|
||||
|
||||
1) For long running CPU-heavy tasks, make use of
|
||||
[worker threads][worker-threads], consider moving them to the BrowserWindow, or
|
||||
(as a last resort) spawn a dedicated process.
|
||||
|
||||
2) Avoid using the synchronous IPC and the `remote` module as much as possible.
|
||||
While there are legitimate use cases, it is far too easy to unknowingly block
|
||||
the UI thread using the `remote` module.
|
||||
|
||||
3) Avoid using blocking I/O operations in the main process. In short, whenever
|
||||
core Node.js modules (like `fs` or `child_process`) offer a synchronous or an
|
||||
asynchronous version, you should prefer the asynchronous and non-blocking
|
||||
variant.
|
||||
|
||||
|
||||
## 4) Blocking the renderer process
|
||||
|
||||
Since Electron ships with a current version of Chrome, you can make use of the
|
||||
latest and greatest features the Web Platform offers to defer or offload heavy
|
||||
operations in a way that keeps your app smooth and responsive.
|
||||
|
||||
### Why?
|
||||
|
||||
Your app probably has a lot of JavaScript to run in the renderer process. The
|
||||
trick is to execute operations as quickly as possible without taking away
|
||||
resources needed to keep scrolling smooth, respond to user input, or animations
|
||||
at 60fps.
|
||||
|
||||
Orchestrating the flow of operations in your renderer's code is
|
||||
particularly useful if users complain about your app sometimes "stuttering".
|
||||
|
||||
### How?
|
||||
|
||||
Generally speaking, all advice for building performant web apps for modern
|
||||
browsers apply to Electron's renderers, too. The two primary tools at your
|
||||
disposal are currently `requestIdleCallback()` for small operations and
|
||||
`Web Workers` for long-running operations.
|
||||
|
||||
*`requestIdleCallback()`* allows developers to queue up a function to be
|
||||
executed as soon as the process is entering an idle period. It enables you to
|
||||
perform low-priority or background work without impacting the user experience.
|
||||
For more information about how to use it,
|
||||
[check out its documentation on MDN][request-idle-callback].
|
||||
|
||||
*Web Workers* are a powerful tool to run code on a separate thread. There are
|
||||
some caveats to consider – consult Electron's
|
||||
[multithreading documentation][multithreading] and the
|
||||
[MDN documentation for Web Workers][web-workers]. They're an ideal solution
|
||||
for any operation that requires a lot of CPU power for an extended period of
|
||||
time.
|
||||
|
||||
|
||||
## 5) Unnecessary polyfills
|
||||
|
||||
One of Electron's great benefits is that you know exactly which engine will
|
||||
parse your JavaScript, HTML, and CSS. If you're re-purposing code that was
|
||||
written for the web at large, make sure to not polyfill features included in
|
||||
Electron.
|
||||
|
||||
### Why?
|
||||
|
||||
When building a web application for today's Internet, the oldest environments
|
||||
dictate what features you can and cannot use. Even though Electron supports
|
||||
well-performing CSS filters and animations, an older browser might not. Where
|
||||
you could use WebGL, your developers may have chosen a more resource-hungry
|
||||
solution to support older phones.
|
||||
|
||||
When it comes to JavaScript, you may have included toolkit libraries like
|
||||
jQuery for DOM selectors or polyfills like the `regenerator-runtime` to support
|
||||
`async/await`.
|
||||
|
||||
It is rare for a JavaScript-based polyfill to be faster than the equivalent
|
||||
native feature in Electron. Do not slow down your Electron app by shipping your
|
||||
own version of standard web platform features.
|
||||
|
||||
### How?
|
||||
|
||||
Operate under the assumption that polyfills in current versions of Electron
|
||||
are unnecessary. If you have doubts, check [caniuse.com][https://caniuse.com/]
|
||||
and check if the [version of Chromium used in your Electron version](../api/process.md#processversionschrome-readonly)
|
||||
supports the feature you desire.
|
||||
|
||||
In addition, carefully examine the libraries you use. Are they really necessary?
|
||||
`jQuery`, for example, was such a success that many of its features are now part
|
||||
of the [standard JavaScript feature set available][jquery-need].
|
||||
|
||||
If you're using a transpiler/compiler like TypeScript, examine its configuration
|
||||
and ensure that you're targeting the latest ECMAScript version supported by
|
||||
Electron.
|
||||
|
||||
|
||||
## 6) Unnecessary or blocking network requests
|
||||
|
||||
Avoid fetching rarely changing resources from the internet if they could easily
|
||||
be bundled with your application.
|
||||
|
||||
### Why?
|
||||
|
||||
Many users of Electron start with an entirely web-based app that they're
|
||||
turning into a desktop application. As web developers, we are used to loading
|
||||
resources from a variety of content delivery networks. Now that you are
|
||||
shipping a proper desktop application, attempt to "cut the cord" where possible
|
||||
- and avoid letting your users wait for resources that never change and could
|
||||
easily be included in your app.
|
||||
|
||||
A typical example is Google Fonts. Many developers make use of Google's
|
||||
impressive collection of free fonts, which comes with a content delivery
|
||||
network. The pitch is straightforward: Include a few lines of CSS and Google
|
||||
will take care of the rest.
|
||||
|
||||
When building an Electron app, your users are better served if you download
|
||||
the fonts and include them in your app's bundle.
|
||||
|
||||
### How?
|
||||
|
||||
In an ideal world, your application wouldn't need the network to operate at
|
||||
all. To get there, you must understand what resources your app is downloading
|
||||
\- and how large those resources are.
|
||||
|
||||
To do so, open up the developer tools. Navigate to the `Network` tab and check
|
||||
the `Disable cache` option. Then, reload your renderer. Unless your app
|
||||
prohibits such reloads, you can usually trigger a reload by hitting `Cmd + R`
|
||||
or `Ctrl + R` with the developer tools in focus.
|
||||
|
||||
The tools will now meticulously record all network requests. In a first pass,
|
||||
take stock of all the resources being downloaded, focusing on the larger files
|
||||
first. Are any of them images, fonts, or media files that don't change and
|
||||
could be included with your bundle? If so, include them.
|
||||
|
||||
As a next step, enable `Network Throttling`. Find the drop-down that currently
|
||||
reads `Online` and select a slower speed such as `Fast 3G`. Reload your
|
||||
renderer and see if there are any resources that your app is unnecessarily
|
||||
waiting for. In many cases, an app will wait for a network request to complete
|
||||
despite not actually needing the involved resource.
|
||||
|
||||
As a tip, loading resources from the Internet that you might want to change
|
||||
without shipping an application update is a powerful strategy. For advanced
|
||||
control over how resources are being loaded, consider investing in
|
||||
[Service Workers][service-workers].
|
||||
|
||||
## 7) Bundle your code
|
||||
|
||||
As already pointed out in
|
||||
"[Loading and running code too soon](#2-loading-and-running-code-too-soon)",
|
||||
calling `require()` is an expensive operation. If you are able to do so,
|
||||
bundle your application's code into a single file.
|
||||
|
||||
### Why?
|
||||
|
||||
Modern JavaScript development usually involves many files and modules. While
|
||||
that's perfectly fine for developing with Electron, we heavily recommend that
|
||||
you bundle all your code into one single file to ensure that the overhead
|
||||
included in calling `require()` is only paid once when your application loads.
|
||||
|
||||
### How?
|
||||
|
||||
There are numerous JavaScript bundlers out there and we know better than to
|
||||
anger the community by recommending one tool over another. We do however
|
||||
recommend that you use a bundler that is able to handle Electron's unique
|
||||
environment that needs to handle both Node.js and browser environments.
|
||||
|
||||
As of writing this article, the popular choices include [Webpack][webpack],
|
||||
[Parcel][parcel], and [rollup.js][rollup].
|
||||
|
||||
[security]: ./security.md
|
||||
[performance-cpu-prof]: ../images/performance-cpu-prof.png
|
||||
[performance-heap-prof]: ../images/performance-heap-prof.png
|
||||
[chrome-devtools-tutorial]: https://developers.google.com/web/tools/chrome-devtools/evaluate-performance/
|
||||
[worker-threads]: https://nodejs.org/api/worker_threads.html
|
||||
[web-workers]: https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Using_web_workers
|
||||
[request-idle-callback]: https://developer.mozilla.org/en-US/docs/Web/API/Window/requestIdleCallback
|
||||
[multithreading]: ./multithreading.md
|
||||
[caniuse]: https://caniuse.com/
|
||||
[jquery-need]: http://youmightnotneedjquery.com/
|
||||
[service-workers]: https://developer.mozilla.org/en-US/docs/Web/API/Service_Worker_API
|
||||
[webpack]: https://webpack.js.org/
|
||||
[parcel]: https://parceljs.org/
|
||||
[rollup]: https://rollupjs.org/
|
||||
[vscode-first-second]: https://www.youtube.com/watch?v=r0OeHRUCCb4
|
||||
@@ -61,7 +61,6 @@ The output should look roughly like this:
|
||||
├── libgcrypt.so.11
|
||||
├── libnode.so
|
||||
├── locales
|
||||
├── natives_blob.bin
|
||||
├── resources
|
||||
├── v8_context_snapshot.bin
|
||||
└── version
|
||||
|
||||
@@ -48,9 +48,9 @@ basis for some older supported lines. All contested decisions around release
|
||||
line backports will be resolved by the [Releases Working Group](https://github.com/electron/governance/tree/master/wg-releases) as an agenda item at their weekly meeting the week the backport PR is raised.
|
||||
|
||||
### Currently supported versions
|
||||
- 7.x.y
|
||||
- 6.x.y
|
||||
- 5.x.y
|
||||
- 4.x.y
|
||||
|
||||
### End-of-life
|
||||
|
||||
|
||||
@@ -62,7 +62,6 @@ The output should look roughly like this:
|
||||
│ ├── am.pak
|
||||
│ ├── ar.pak
|
||||
│ ├── [...]
|
||||
├── natives_blob.bin
|
||||
├── node.dll
|
||||
├── resources
|
||||
│ ├── app
|
||||
|
||||
@@ -69,4 +69,10 @@
|
||||
<message name="IDS_PICTURE_IN_PICTURE_PREVIOUS_TRACK_CONTROL_ACCESSIBLE_TEXT" desc="Accessible text label used for the controls button in the Picture-in-Picture window. The button invokes previous track action.">
|
||||
Previous track
|
||||
</message>
|
||||
<message name="IDS_SPELLCHECK_DICTIONARY" use_name_for_id="true">
|
||||
en-US
|
||||
</message>
|
||||
<message name="IDS_ACCEPT_LANGUAGES" use_name_for_id="true">
|
||||
en-US,en
|
||||
</message>
|
||||
</grit-part>
|
||||
|
||||
@@ -14,6 +14,7 @@ auto_filenames = {
|
||||
"docs/api/command-line-switches.md",
|
||||
"docs/api/command-line.md",
|
||||
"docs/api/content-tracing.md",
|
||||
"docs/api/context-bridge.md",
|
||||
"docs/api/cookies.md",
|
||||
"docs/api/crash-reporter.md",
|
||||
"docs/api/debugger.md",
|
||||
@@ -134,12 +135,13 @@ auto_filenames = {
|
||||
"lib/common/api/module-list.ts",
|
||||
"lib/common/api/native-image.js",
|
||||
"lib/common/api/shell.js",
|
||||
"lib/common/clipboard-utils.ts",
|
||||
"lib/common/crash-reporter.js",
|
||||
"lib/common/define-properties.ts",
|
||||
"lib/common/electron-binding-setup.ts",
|
||||
"lib/common/remote/type-utils.ts",
|
||||
"lib/common/type-utils.ts",
|
||||
"lib/common/web-view-methods.ts",
|
||||
"lib/common/webpack-globals-provider.ts",
|
||||
"lib/renderer/api/context-bridge.ts",
|
||||
"lib/renderer/api/crash-reporter.js",
|
||||
"lib/renderer/api/desktop-capturer.ts",
|
||||
"lib/renderer/api/ipc-renderer.ts",
|
||||
@@ -163,6 +165,7 @@ auto_filenames = {
|
||||
"lib/renderer/web-view/web-view-element.ts",
|
||||
"lib/renderer/web-view/web-view-impl.ts",
|
||||
"lib/renderer/web-view/web-view-init.ts",
|
||||
"lib/renderer/window-setup.ts",
|
||||
"lib/sandboxed_renderer/api/exports/electron.ts",
|
||||
"lib/sandboxed_renderer/api/module-list.ts",
|
||||
"lib/sandboxed_renderer/init.js",
|
||||
@@ -186,6 +189,7 @@ auto_filenames = {
|
||||
|
||||
content_script_bundle_deps = [
|
||||
"lib/common/electron-binding-setup.ts",
|
||||
"lib/common/webpack-globals-provider.ts",
|
||||
"lib/content_script/init.js",
|
||||
"lib/renderer/chrome-api.ts",
|
||||
"lib/renderer/extensions/event.ts",
|
||||
@@ -264,15 +268,15 @@ auto_filenames = {
|
||||
"lib/common/api/module-list.ts",
|
||||
"lib/common/api/native-image.js",
|
||||
"lib/common/api/shell.js",
|
||||
"lib/common/clipboard-utils.ts",
|
||||
"lib/common/crash-reporter.js",
|
||||
"lib/common/define-properties.ts",
|
||||
"lib/common/electron-binding-setup.ts",
|
||||
"lib/common/init.ts",
|
||||
"lib/common/parse-features-string.js",
|
||||
"lib/common/remote/type-utils.ts",
|
||||
"lib/common/reset-search-paths.ts",
|
||||
"lib/common/type-utils.ts",
|
||||
"lib/common/web-view-methods.ts",
|
||||
"lib/common/webpack-globals-provider.ts",
|
||||
"lib/renderer/ipc-renderer-internal-utils.ts",
|
||||
"lib/renderer/ipc-renderer-internal.ts",
|
||||
"package.json",
|
||||
@@ -287,14 +291,15 @@ auto_filenames = {
|
||||
"lib/common/api/module-list.ts",
|
||||
"lib/common/api/native-image.js",
|
||||
"lib/common/api/shell.js",
|
||||
"lib/common/clipboard-utils.ts",
|
||||
"lib/common/crash-reporter.js",
|
||||
"lib/common/define-properties.ts",
|
||||
"lib/common/electron-binding-setup.ts",
|
||||
"lib/common/init.ts",
|
||||
"lib/common/remote/type-utils.ts",
|
||||
"lib/common/reset-search-paths.ts",
|
||||
"lib/common/type-utils.ts",
|
||||
"lib/common/web-view-methods.ts",
|
||||
"lib/common/webpack-globals-provider.ts",
|
||||
"lib/renderer/api/context-bridge.ts",
|
||||
"lib/renderer/api/crash-reporter.js",
|
||||
"lib/renderer/api/desktop-capturer.ts",
|
||||
"lib/renderer/api/exports/electron.ts",
|
||||
@@ -335,13 +340,14 @@ auto_filenames = {
|
||||
"lib/common/api/module-list.ts",
|
||||
"lib/common/api/native-image.js",
|
||||
"lib/common/api/shell.js",
|
||||
"lib/common/clipboard-utils.ts",
|
||||
"lib/common/crash-reporter.js",
|
||||
"lib/common/define-properties.ts",
|
||||
"lib/common/electron-binding-setup.ts",
|
||||
"lib/common/init.ts",
|
||||
"lib/common/remote/type-utils.ts",
|
||||
"lib/common/reset-search-paths.ts",
|
||||
"lib/common/type-utils.ts",
|
||||
"lib/common/webpack-globals-provider.ts",
|
||||
"lib/renderer/api/context-bridge.ts",
|
||||
"lib/renderer/api/crash-reporter.js",
|
||||
"lib/renderer/api/desktop-capturer.ts",
|
||||
"lib/renderer/api/exports/electron.ts",
|
||||
|
||||
211
filenames.gni
211
filenames.gni
@@ -1,7 +1,6 @@
|
||||
filenames = {
|
||||
default_app_ts_sources = [
|
||||
"default_app/default_app.ts",
|
||||
"default_app/index.ts",
|
||||
"default_app/main.ts",
|
||||
"default_app/preload.ts",
|
||||
]
|
||||
@@ -23,6 +22,11 @@ filenames = {
|
||||
]
|
||||
|
||||
lib_sources = [
|
||||
"chromium_src/chrome/browser/process_singleton.h",
|
||||
"chromium_src/chrome/browser/process_singleton_posix.cc",
|
||||
"chromium_src/chrome/browser/process_singleton_win.cc",
|
||||
"chromium_src/chrome/browser/ui/views/frame/global_menu_bar_registrar_x11.cc",
|
||||
"chromium_src/chrome/browser/ui/views/frame/global_menu_bar_registrar_x11.h",
|
||||
"shell/app/atom_content_client.cc",
|
||||
"shell/app/atom_content_client.h",
|
||||
"shell/app/atom_main_delegate.cc",
|
||||
@@ -33,17 +37,17 @@ filenames = {
|
||||
"shell/app/command_line_args.h",
|
||||
"shell/app/uv_task_runner.cc",
|
||||
"shell/app/uv_task_runner.h",
|
||||
"shell/browser/api/atom_api_app_mac.mm",
|
||||
"shell/browser/api/atom_api_app.cc",
|
||||
"shell/browser/font_defaults.cc",
|
||||
"shell/browser/font_defaults.h",
|
||||
"shell/browser/feature_list.cc",
|
||||
"shell/browser/feature_list.h",
|
||||
"shell/browser/api/atom_api_app.h",
|
||||
"shell/browser/api/atom_api_app_mac.mm",
|
||||
"shell/browser/api/atom_api_auto_updater.cc",
|
||||
"shell/browser/api/atom_api_auto_updater.h",
|
||||
"shell/browser/api/atom_api_browser_view.cc",
|
||||
"shell/browser/api/atom_api_browser_view.h",
|
||||
"shell/browser/api/atom_api_browser_window.cc",
|
||||
"shell/browser/api/atom_api_browser_window.h",
|
||||
"shell/browser/api/atom_api_browser_window_mac.mm",
|
||||
"shell/browser/api/atom_api_browser_window_views.cc",
|
||||
"shell/browser/api/atom_api_content_tracing.cc",
|
||||
"shell/browser/api/atom_api_cookies.cc",
|
||||
"shell/browser/api/atom_api_cookies.h",
|
||||
@@ -74,10 +78,10 @@ filenames = {
|
||||
"shell/browser/api/atom_api_net_log.h",
|
||||
"shell/browser/api/atom_api_notification.cc",
|
||||
"shell/browser/api/atom_api_notification.h",
|
||||
"shell/browser/api/atom_api_power_monitor_mac.mm",
|
||||
"shell/browser/api/atom_api_power_monitor_win.cc",
|
||||
"shell/browser/api/atom_api_power_monitor.cc",
|
||||
"shell/browser/api/atom_api_power_monitor.h",
|
||||
"shell/browser/api/atom_api_power_monitor_mac.mm",
|
||||
"shell/browser/api/atom_api_power_monitor_win.cc",
|
||||
"shell/browser/api/atom_api_power_save_blocker.cc",
|
||||
"shell/browser/api/atom_api_power_save_blocker.h",
|
||||
"shell/browser/api/atom_api_protocol_ns.cc",
|
||||
@@ -94,8 +98,8 @@ filenames = {
|
||||
"shell/browser/api/atom_api_top_level_window.h",
|
||||
"shell/browser/api/atom_api_tray.cc",
|
||||
"shell/browser/api/atom_api_tray.h",
|
||||
"shell/browser/api/atom_api_url_request_ns.cc",
|
||||
"shell/browser/api/atom_api_url_request_ns.h",
|
||||
"shell/browser/api/atom_api_url_loader.cc",
|
||||
"shell/browser/api/atom_api_url_loader.h",
|
||||
"shell/browser/api/atom_api_view.cc",
|
||||
"shell/browser/api/atom_api_view.h",
|
||||
"shell/browser/api/atom_api_web_contents.cc",
|
||||
@@ -107,16 +111,10 @@ filenames = {
|
||||
"shell/browser/api/atom_api_web_request_ns.cc",
|
||||
"shell/browser/api/atom_api_web_request_ns.h",
|
||||
"shell/browser/api/atom_api_web_view_manager.cc",
|
||||
"shell/browser/api/atom_api_browser_window.cc",
|
||||
"shell/browser/api/atom_api_browser_window.h",
|
||||
"shell/browser/api/atom_api_browser_window_mac.mm",
|
||||
"shell/browser/api/atom_api_browser_window_views.cc",
|
||||
"shell/browser/api/event.cc",
|
||||
"shell/browser/api/event.h",
|
||||
"shell/browser/api/event_emitter.cc",
|
||||
"shell/browser/api/event_emitter.h",
|
||||
"shell/browser/api/trackable_object.cc",
|
||||
"shell/browser/api/trackable_object.h",
|
||||
"shell/browser/api/event_emitter_deprecated.cc",
|
||||
"shell/browser/api/event_emitter_deprecated.h",
|
||||
"shell/browser/api/frame_subscriber.cc",
|
||||
"shell/browser/api/frame_subscriber.h",
|
||||
"shell/browser/api/gpu_info_enumerator.cc",
|
||||
@@ -127,29 +125,28 @@ filenames = {
|
||||
"shell/browser/api/process_metric.h",
|
||||
"shell/browser/api/save_page_handler.cc",
|
||||
"shell/browser/api/save_page_handler.h",
|
||||
"shell/browser/auto_updater.cc",
|
||||
"shell/browser/auto_updater.h",
|
||||
"shell/browser/auto_updater_mac.mm",
|
||||
"shell/browser/atom_autofill_driver_factory.cc",
|
||||
"shell/browser/atom_autofill_driver_factory.h",
|
||||
"shell/browser/api/trackable_object.cc",
|
||||
"shell/browser/api/trackable_object.h",
|
||||
"shell/browser/atom_autofill_driver.cc",
|
||||
"shell/browser/atom_autofill_driver.h",
|
||||
"shell/browser/atom_autofill_driver_factory.cc",
|
||||
"shell/browser/atom_autofill_driver_factory.h",
|
||||
"shell/browser/atom_browser_client.cc",
|
||||
"shell/browser/atom_browser_client.h",
|
||||
"shell/browser/atom_browser_context.cc",
|
||||
"shell/browser/atom_browser_context.h",
|
||||
"shell/browser/atom_download_manager_delegate.cc",
|
||||
"shell/browser/atom_download_manager_delegate.h",
|
||||
"shell/browser/atom_gpu_client.cc",
|
||||
"shell/browser/atom_gpu_client.h",
|
||||
"shell/browser/atom_browser_main_parts.cc",
|
||||
"shell/browser/atom_browser_main_parts.h",
|
||||
"shell/browser/atom_browser_main_parts_mac.mm",
|
||||
"shell/browser/atom_browser_main_parts_posix.cc",
|
||||
"shell/browser/atom_download_manager_delegate.cc",
|
||||
"shell/browser/atom_download_manager_delegate.h",
|
||||
"shell/browser/atom_gpu_client.cc",
|
||||
"shell/browser/atom_gpu_client.h",
|
||||
"shell/browser/atom_javascript_dialog_manager.cc",
|
||||
"shell/browser/atom_javascript_dialog_manager.h",
|
||||
"shell/browser/atom_navigation_throttle.h",
|
||||
"shell/browser/atom_navigation_throttle.cc",
|
||||
"shell/browser/atom_navigation_throttle.h",
|
||||
"shell/browser/atom_paths.h",
|
||||
"shell/browser/atom_permission_manager.cc",
|
||||
"shell/browser/atom_permission_manager.h",
|
||||
@@ -159,29 +156,38 @@ filenames = {
|
||||
"shell/browser/atom_speech_recognition_manager_delegate.h",
|
||||
"shell/browser/atom_web_ui_controller_factory.cc",
|
||||
"shell/browser/atom_web_ui_controller_factory.h",
|
||||
"shell/browser/auto_updater.cc",
|
||||
"shell/browser/auto_updater.h",
|
||||
"shell/browser/auto_updater_mac.mm",
|
||||
"shell/browser/browser.cc",
|
||||
"shell/browser/browser.h",
|
||||
"shell/browser/browser_linux.cc",
|
||||
"shell/browser/browser_mac.mm",
|
||||
"shell/browser/browser_win.cc",
|
||||
"shell/browser/browser_observer.h",
|
||||
"shell/browser/browser_process_impl.cc",
|
||||
"shell/browser/browser_process_impl.h",
|
||||
"shell/browser/browser_win.cc",
|
||||
"shell/browser/child_web_contents_tracker.cc",
|
||||
"shell/browser/child_web_contents_tracker.h",
|
||||
"shell/browser/common_web_contents_delegate_mac.mm",
|
||||
"shell/browser/common_web_contents_delegate_views.cc",
|
||||
"shell/browser/common_web_contents_delegate.cc",
|
||||
"shell/browser/common_web_contents_delegate.h",
|
||||
"shell/browser/common_web_contents_delegate_mac.mm",
|
||||
"shell/browser/common_web_contents_delegate_views.cc",
|
||||
"shell/browser/cookie_change_notifier.cc",
|
||||
"shell/browser/cookie_change_notifier.h",
|
||||
"shell/browser/feature_list.cc",
|
||||
"shell/browser/feature_list.h",
|
||||
"shell/browser/font_defaults.cc",
|
||||
"shell/browser/font_defaults.h",
|
||||
"shell/browser/javascript_environment.cc",
|
||||
"shell/browser/javascript_environment.h",
|
||||
"shell/browser/lib/bluetooth_chooser.cc",
|
||||
"shell/browser/lib/bluetooth_chooser.h",
|
||||
"shell/browser/lib/power_observer.h",
|
||||
"shell/browser/lib/power_observer_linux.h",
|
||||
"shell/browser/lib/power_observer_linux.cc",
|
||||
"shell/browser/lib/power_observer_linux.h",
|
||||
"shell/browser/linux/unity_service.cc",
|
||||
"shell/browser/linux/unity_service.h",
|
||||
"shell/browser/login_handler.cc",
|
||||
"shell/browser/login_handler.h",
|
||||
"shell/browser/mac/atom_application.h",
|
||||
@@ -196,48 +202,52 @@ filenames = {
|
||||
"shell/browser/mac/in_app_purchase_observer.mm",
|
||||
"shell/browser/mac/in_app_purchase_product.h",
|
||||
"shell/browser/mac/in_app_purchase_product.mm",
|
||||
"shell/browser/microtasks_runner.cc",
|
||||
"shell/browser/microtasks_runner.h",
|
||||
"shell/browser/native_browser_view.cc",
|
||||
"shell/browser/native_browser_view.h",
|
||||
"shell/browser/native_browser_view_mac.h",
|
||||
"shell/browser/native_browser_view_mac.mm",
|
||||
"shell/browser/native_browser_view_views.h",
|
||||
"shell/browser/native_browser_view_views.cc",
|
||||
"shell/browser/native_window.cc",
|
||||
"shell/browser/native_window.h",
|
||||
"shell/browser/native_window_views_win.cc",
|
||||
"shell/browser/native_window_views.cc",
|
||||
"shell/browser/native_window_views.h",
|
||||
"shell/browser/native_window_mac.h",
|
||||
"shell/browser/native_window_mac.mm",
|
||||
"shell/browser/native_window_observer.h",
|
||||
"shell/browser/media/media_capture_devices_dispatcher.cc",
|
||||
"shell/browser/media/media_capture_devices_dispatcher.h",
|
||||
"shell/browser/media/media_device_id_salt.cc",
|
||||
"shell/browser/media/media_device_id_salt.h",
|
||||
"shell/browser/media/media_stream_devices_controller.cc",
|
||||
"shell/browser/media/media_stream_devices_controller.h",
|
||||
"shell/browser/microtasks_runner.cc",
|
||||
"shell/browser/microtasks_runner.h",
|
||||
"shell/browser/native_browser_view.cc",
|
||||
"shell/browser/native_browser_view.h",
|
||||
"shell/browser/native_browser_view_mac.h",
|
||||
"shell/browser/native_browser_view_mac.mm",
|
||||
"shell/browser/native_browser_view_views.cc",
|
||||
"shell/browser/native_browser_view_views.h",
|
||||
"shell/browser/native_window.cc",
|
||||
"shell/browser/native_window.h",
|
||||
"shell/browser/native_window_mac.h",
|
||||
"shell/browser/native_window_mac.mm",
|
||||
"shell/browser/native_window_observer.h",
|
||||
"shell/browser/native_window_views.cc",
|
||||
"shell/browser/native_window_views.h",
|
||||
"shell/browser/native_window_views_win.cc",
|
||||
"shell/browser/net/asar/asar_url_loader.cc",
|
||||
"shell/browser/net/asar/asar_url_loader.h",
|
||||
"shell/browser/net/atom_url_loader_factory.cc",
|
||||
"shell/browser/net/atom_url_loader_factory.h",
|
||||
"shell/browser/net/cert_verifier_client.cc",
|
||||
"shell/browser/net/cert_verifier_client.h",
|
||||
"shell/browser/net/proxying_url_loader_factory.cc",
|
||||
"shell/browser/net/proxying_url_loader_factory.h",
|
||||
"shell/browser/net/network_context_service_factory.cc",
|
||||
"shell/browser/net/network_context_service_factory.h",
|
||||
"shell/browser/net/network_context_service.cc",
|
||||
"shell/browser/net/network_context_service.h",
|
||||
"shell/browser/net/network_context_service_factory.cc",
|
||||
"shell/browser/net/network_context_service_factory.h",
|
||||
"shell/browser/net/node_stream_loader.cc",
|
||||
"shell/browser/net/node_stream_loader.h",
|
||||
"shell/browser/net/proxying_url_loader_factory.cc",
|
||||
"shell/browser/net/proxying_url_loader_factory.h",
|
||||
"shell/browser/net/resolve_proxy_helper.cc",
|
||||
"shell/browser/net/resolve_proxy_helper.h",
|
||||
"shell/browser/net/system_network_context_manager.cc",
|
||||
"shell/browser/net/system_network_context_manager.h",
|
||||
"shell/browser/net/url_pipe_loader.cc",
|
||||
"shell/browser/net/url_pipe_loader.h",
|
||||
"shell/browser/network_hints_handler_impl.cc",
|
||||
"shell/browser/network_hints_handler_impl.h",
|
||||
"shell/browser/node_debugger.cc",
|
||||
"shell/browser/node_debugger.h",
|
||||
"shell/browser/notifications/linux/libnotify_notification.cc",
|
||||
"shell/browser/notifications/linux/libnotify_notification.h",
|
||||
"shell/browser/notifications/linux/notification_presenter_linux.cc",
|
||||
@@ -270,17 +280,13 @@ filenames = {
|
||||
"shell/browser/notifications/win/win32_notification.h",
|
||||
"shell/browser/notifications/win/windows_toast_notification.cc",
|
||||
"shell/browser/notifications/win/windows_toast_notification.h",
|
||||
"shell/browser/node_debugger.cc",
|
||||
"shell/browser/node_debugger.h",
|
||||
"shell/browser/pref_store_delegate.cc",
|
||||
"shell/browser/pref_store_delegate.h",
|
||||
"shell/browser/relauncher.cc",
|
||||
"shell/browser/relauncher.h",
|
||||
"shell/browser/relauncher_linux.cc",
|
||||
"shell/browser/relauncher_mac.cc",
|
||||
"shell/browser/relauncher_win.cc",
|
||||
"shell/browser/relauncher.cc",
|
||||
"shell/browser/relauncher.h",
|
||||
"shell/browser/renderer_host/electron_render_message_filter.cc",
|
||||
"shell/browser/renderer_host/electron_render_message_filter.h",
|
||||
"shell/browser/session_preferences.cc",
|
||||
"shell/browser/session_preferences.h",
|
||||
"shell/browser/special_storage_policy.cc",
|
||||
@@ -294,8 +300,14 @@ filenames = {
|
||||
"shell/browser/ui/certificate_trust.h",
|
||||
"shell/browser/ui/certificate_trust_mac.mm",
|
||||
"shell/browser/ui/certificate_trust_win.cc",
|
||||
"shell/browser/ui/cocoa/NSColor+Hex.h",
|
||||
"shell/browser/ui/cocoa/NSColor+Hex.mm",
|
||||
"shell/browser/ui/cocoa/NSString+ANSI.h",
|
||||
"shell/browser/ui/cocoa/NSString+ANSI.mm",
|
||||
"shell/browser/ui/cocoa/atom_bundle_mover.h",
|
||||
"shell/browser/ui/cocoa/atom_bundle_mover.mm",
|
||||
"shell/browser/ui/cocoa/atom_inspectable_web_contents_view.h",
|
||||
"shell/browser/ui/cocoa/atom_inspectable_web_contents_view.mm",
|
||||
"shell/browser/ui/cocoa/atom_menu_controller.h",
|
||||
"shell/browser/ui/cocoa/atom_menu_controller.mm",
|
||||
"shell/browser/ui/cocoa/atom_native_widget_mac.h",
|
||||
@@ -310,27 +322,23 @@ filenames = {
|
||||
"shell/browser/ui/cocoa/atom_touch_bar.mm",
|
||||
"shell/browser/ui/cocoa/delayed_native_view_host.cc",
|
||||
"shell/browser/ui/cocoa/delayed_native_view_host.h",
|
||||
"shell/browser/ui/cocoa/views_delegate_mac.h",
|
||||
"shell/browser/ui/cocoa/views_delegate_mac.mm",
|
||||
"shell/browser/ui/cocoa/root_view_mac.mm",
|
||||
"shell/browser/ui/cocoa/root_view_mac.h",
|
||||
"shell/browser/ui/cocoa/atom_inspectable_web_contents_view.h",
|
||||
"shell/browser/ui/cocoa/atom_inspectable_web_contents_view.mm",
|
||||
"shell/browser/ui/cocoa/event_dispatching_window.h",
|
||||
"shell/browser/ui/cocoa/event_dispatching_window.mm",
|
||||
"shell/browser/ui/cocoa/root_view_mac.h",
|
||||
"shell/browser/ui/cocoa/root_view_mac.mm",
|
||||
"shell/browser/ui/cocoa/views_delegate_mac.h",
|
||||
"shell/browser/ui/cocoa/views_delegate_mac.mm",
|
||||
"shell/browser/ui/devtools_manager_delegate.cc",
|
||||
"shell/browser/ui/devtools_manager_delegate.h",
|
||||
"shell/browser/ui/devtools_ui.cc",
|
||||
"shell/browser/ui/devtools_ui.h",
|
||||
"shell/browser/ui/drag_util.h",
|
||||
"shell/browser/ui/drag_util_mac.mm",
|
||||
"shell/browser/ui/drag_util_views.cc",
|
||||
"shell/browser/ui/drag_util.h",
|
||||
"shell/browser/ui/file_dialog.h",
|
||||
"shell/browser/ui/file_dialog_gtk.cc",
|
||||
"shell/browser/ui/file_dialog_mac.mm",
|
||||
"shell/browser/ui/file_dialog_win.cc",
|
||||
"shell/browser/ui/util_gtk.cc",
|
||||
"shell/browser/ui/util_gtk.h",
|
||||
"shell/browser/ui/inspectable_web_contents.cc",
|
||||
"shell/browser/ui/inspectable_web_contents.h",
|
||||
"shell/browser/ui/inspectable_web_contents_delegate.h",
|
||||
@@ -345,19 +353,16 @@ filenames = {
|
||||
"shell/browser/ui/message_box_gtk.cc",
|
||||
"shell/browser/ui/message_box_mac.mm",
|
||||
"shell/browser/ui/message_box_win.cc",
|
||||
"shell/browser/ui/cocoa/NSColor+Hex.mm",
|
||||
"shell/browser/ui/cocoa/NSColor+Hex.h",
|
||||
"shell/browser/ui/cocoa/NSString+ANSI.mm",
|
||||
"shell/browser/ui/cocoa/NSString+ANSI.h",
|
||||
"shell/browser/ui/tray_icon.cc",
|
||||
"shell/browser/ui/tray_icon.h",
|
||||
"shell/browser/ui/tray_icon_gtk.cc",
|
||||
"shell/browser/ui/tray_icon_gtk.h",
|
||||
"shell/browser/ui/tray_icon_cocoa.h",
|
||||
"shell/browser/ui/tray_icon_cocoa.mm",
|
||||
"shell/browser/ui/tray_icon_gtk.cc",
|
||||
"shell/browser/ui/tray_icon_gtk.h",
|
||||
"shell/browser/ui/tray_icon_observer.h",
|
||||
"shell/browser/ui/tray_icon_win.cc",
|
||||
"shell/browser/ui/views/atom_views_delegate.cc",
|
||||
"shell/browser/ui/views/atom_views_delegate_win.cc",
|
||||
"shell/browser/ui/views/atom_views_delegate.h",
|
||||
"shell/browser/ui/views/autofill_popup_view.cc",
|
||||
"shell/browser/ui/views/autofill_popup_view.h",
|
||||
@@ -387,10 +392,10 @@ filenames = {
|
||||
"shell/browser/ui/win/atom_desktop_window_tree_host_win.h",
|
||||
"shell/browser/ui/win/jump_list.cc",
|
||||
"shell/browser/ui/win/jump_list.h",
|
||||
"shell/browser/ui/win/notify_icon_host.cc",
|
||||
"shell/browser/ui/win/notify_icon_host.h",
|
||||
"shell/browser/ui/win/notify_icon.cc",
|
||||
"shell/browser/ui/win/notify_icon.h",
|
||||
"shell/browser/ui/win/notify_icon_host.cc",
|
||||
"shell/browser/ui/win/notify_icon_host.h",
|
||||
"shell/browser/ui/win/taskbar_host.cc",
|
||||
"shell/browser/ui/win/taskbar_host.h",
|
||||
"shell/browser/ui/x/event_disabler.cc",
|
||||
@@ -401,8 +406,6 @@ filenames = {
|
||||
"shell/browser/ui/x/x_window_utils.h",
|
||||
"shell/browser/unresponsive_suppressor.cc",
|
||||
"shell/browser/unresponsive_suppressor.h",
|
||||
"shell/browser/win/scoped_hstring.cc",
|
||||
"shell/browser/win/scoped_hstring.h",
|
||||
"shell/browser/web_contents_permission_helper.cc",
|
||||
"shell/browser/web_contents_permission_helper.h",
|
||||
"shell/browser/web_contents_preferences.cc",
|
||||
@@ -415,6 +418,8 @@ filenames = {
|
||||
"shell/browser/web_view_guest_delegate.h",
|
||||
"shell/browser/web_view_manager.cc",
|
||||
"shell/browser/web_view_manager.h",
|
||||
"shell/browser/win/scoped_hstring.cc",
|
||||
"shell/browser/win/scoped_hstring.h",
|
||||
"shell/browser/window_list.cc",
|
||||
"shell/browser/window_list.h",
|
||||
"shell/browser/window_list_observer.h",
|
||||
@@ -432,25 +437,25 @@ filenames = {
|
||||
"shell/common/api/atom_api_native_image_mac.mm",
|
||||
"shell/common/api/atom_api_shell.cc",
|
||||
"shell/common/api/atom_api_v8_util.cc",
|
||||
"shell/common/api/constructor.h",
|
||||
"shell/common/api/electron_bindings.cc",
|
||||
"shell/common/api/electron_bindings.h",
|
||||
"shell/common/api/constructor.h",
|
||||
"shell/common/api/event_emitter_caller_deprecated.cc",
|
||||
"shell/common/api/event_emitter_caller_deprecated.h",
|
||||
"shell/common/api/features.cc",
|
||||
"shell/common/api/locker.cc",
|
||||
"shell/common/api/locker.h",
|
||||
"shell/common/application_info.cc",
|
||||
"shell/common/application_info.h",
|
||||
"shell/common/application_info_linux.cc",
|
||||
"shell/common/application_info_mac.mm",
|
||||
"shell/common/application_info_win.cc",
|
||||
"shell/common/asar/archive.cc",
|
||||
"shell/common/asar/archive.h",
|
||||
"shell/common/asar/asar_util.cc",
|
||||
"shell/common/asar/asar_util.h",
|
||||
"shell/common/asar/scoped_temporary_file.cc",
|
||||
"shell/common/asar/scoped_temporary_file.h",
|
||||
"shell/common/application_info_linux.cc",
|
||||
"shell/common/application_info_mac.mm",
|
||||
"shell/common/application_info_win.cc",
|
||||
"shell/common/application_info.cc",
|
||||
"shell/common/application_info.h",
|
||||
"shell/common/atom_command_line.cc",
|
||||
"shell/common/atom_command_line.h",
|
||||
"shell/common/atom_constants.cc",
|
||||
@@ -463,16 +468,21 @@ filenames = {
|
||||
"shell/common/crash_reporter/crash_reporter_linux.h",
|
||||
"shell/common/crash_reporter/crash_reporter_mac.h",
|
||||
"shell/common/crash_reporter/crash_reporter_mac.mm",
|
||||
"shell/common/crash_reporter/crash_reporter_win.h",
|
||||
"shell/common/crash_reporter/crash_reporter_win.cc",
|
||||
"shell/common/crash_reporter/crash_reporter_win.h",
|
||||
"shell/common/crash_reporter/linux/crash_dump_handler.cc",
|
||||
"shell/common/crash_reporter/linux/crash_dump_handler.h",
|
||||
"shell/common/crash_reporter/win/crash_service_main.cc",
|
||||
"shell/common/crash_reporter/win/crash_service_main.h",
|
||||
"shell/common/deprecate_util.cc",
|
||||
"shell/common/deprecate_util.h",
|
||||
"shell/common/gin_converters/blink_converter_gin_adapter.h",
|
||||
"shell/common/gin_converters/callback_converter.h",
|
||||
"shell/common/gin_converters/file_dialog_converter.cc",
|
||||
"shell/common/gin_converters/file_dialog_converter.h",
|
||||
"shell/common/gin_converters/file_path_converter.h",
|
||||
"shell/common/gin_converters/gfx_converter.cc",
|
||||
"shell/common/gin_converters/gfx_converter.h",
|
||||
"shell/common/gin_converters/gurl_converter.h",
|
||||
"shell/common/gin_converters/image_converter.cc",
|
||||
"shell/common/gin_converters/image_converter.h",
|
||||
@@ -482,8 +492,9 @@ filenames = {
|
||||
"shell/common/gin_converters/net_converter.cc",
|
||||
"shell/common/gin_converters/net_converter.h",
|
||||
"shell/common/gin_converters/std_converter.h",
|
||||
"shell/common/gin_converters/blink_converter_gin_adapter.h",
|
||||
"shell/common/gin_converters/value_converter_gin_adapter.h",
|
||||
"shell/common/gin_helper/arguments.cc",
|
||||
"shell/common/gin_helper/arguments.h",
|
||||
"shell/common/gin_helper/callback.cc",
|
||||
"shell/common/gin_helper/callback.h",
|
||||
"shell/common/gin_helper/destroyable.cc",
|
||||
@@ -491,6 +502,8 @@ filenames = {
|
||||
"shell/common/gin_helper/dictionary.h",
|
||||
"shell/common/gin_helper/error_thrower.cc",
|
||||
"shell/common/gin_helper/error_thrower.h",
|
||||
"shell/common/gin_helper/event_emitter.cc",
|
||||
"shell/common/gin_helper/event_emitter.h",
|
||||
"shell/common/gin_helper/event_emitter_caller.cc",
|
||||
"shell/common/gin_helper/event_emitter_caller.h",
|
||||
"shell/common/gin_helper/function_template.cc",
|
||||
@@ -502,12 +515,10 @@ filenames = {
|
||||
"shell/common/key_weak_map.h",
|
||||
"shell/common/keyboard_util.cc",
|
||||
"shell/common/keyboard_util.h",
|
||||
"shell/common/deprecate_util.cc",
|
||||
"shell/common/deprecate_util.h",
|
||||
"shell/common/mouse_util.cc",
|
||||
"shell/common/mouse_util.h",
|
||||
"shell/common/mac/main_application_bundle.h",
|
||||
"shell/common/mac/main_application_bundle.mm",
|
||||
"shell/common/mouse_util.cc",
|
||||
"shell/common/mouse_util.h",
|
||||
"shell/common/native_mate_converters/accelerator_converter.cc",
|
||||
"shell/common/native_mate_converters/accelerator_converter.h",
|
||||
"shell/common/native_mate_converters/blink_converter.cc",
|
||||
@@ -518,11 +529,8 @@ filenames = {
|
||||
"shell/common/native_mate_converters/content_converter.h",
|
||||
"shell/common/native_mate_converters/file_dialog_converter.h",
|
||||
"shell/common/native_mate_converters/file_path_converter.h",
|
||||
"shell/common/native_mate_converters/gfx_converter.cc",
|
||||
"shell/common/native_mate_converters/gfx_converter.h",
|
||||
"shell/common/native_mate_converters/gurl_converter.h",
|
||||
"shell/common/native_mate_converters/image_converter.h",
|
||||
"shell/common/native_mate_converters/map_converter.h",
|
||||
"shell/common/native_mate_converters/native_window_converter.h",
|
||||
"shell/common/native_mate_converters/net_converter.h",
|
||||
"shell/common/native_mate_converters/network_converter.cc",
|
||||
@@ -543,32 +551,38 @@ filenames = {
|
||||
"shell/common/node_bindings_win.cc",
|
||||
"shell/common/node_bindings_win.h",
|
||||
"shell/common/node_includes.h",
|
||||
"shell/common/node_util.cc",
|
||||
"shell/common/node_util.h",
|
||||
"shell/common/options_switches.cc",
|
||||
"shell/common/options_switches.h",
|
||||
"shell/common/platform_util.h",
|
||||
"shell/common/platform_util_linux.cc",
|
||||
"shell/common/platform_util_mac.mm",
|
||||
"shell/common/platform_util_win.cc",
|
||||
"shell/common/promise_util.h",
|
||||
"shell/common/promise_util.cc",
|
||||
"shell/common/skia_util.h",
|
||||
"shell/common/promise_util.h",
|
||||
"shell/common/skia_util.cc",
|
||||
"shell/common/skia_util.h",
|
||||
"shell/renderer/api/atom_api_context_bridge.cc",
|
||||
"shell/renderer/api/atom_api_context_bridge.h",
|
||||
"shell/renderer/api/atom_api_renderer_ipc.cc",
|
||||
"shell/renderer/api/atom_api_spell_check_client.cc",
|
||||
"shell/renderer/api/atom_api_spell_check_client.h",
|
||||
"shell/renderer/api/atom_api_web_frame.cc",
|
||||
"shell/renderer/api/context_bridge/render_frame_context_bridge_store.cc",
|
||||
"shell/renderer/api/context_bridge/render_frame_context_bridge_store.h",
|
||||
"shell/renderer/atom_autofill_agent.cc",
|
||||
"shell/renderer/atom_autofill_agent.h",
|
||||
"shell/renderer/atom_render_frame_observer.cc",
|
||||
"shell/renderer/atom_render_frame_observer.h",
|
||||
"shell/renderer/atom_renderer_client.cc",
|
||||
"shell/renderer/atom_renderer_client.h",
|
||||
"shell/renderer/atom_sandboxed_renderer_client.cc",
|
||||
"shell/renderer/atom_sandboxed_renderer_client.h",
|
||||
"shell/renderer/content_settings_observer.cc",
|
||||
"shell/renderer/content_settings_observer.h",
|
||||
"shell/renderer/electron_api_service_impl.cc",
|
||||
"shell/renderer/electron_api_service_impl.h",
|
||||
"shell/renderer/atom_sandboxed_renderer_client.cc",
|
||||
"shell/renderer/atom_sandboxed_renderer_client.h",
|
||||
"shell/renderer/guest_view_container.cc",
|
||||
"shell/renderer/guest_view_container.h",
|
||||
"shell/renderer/renderer_client_base.cc",
|
||||
@@ -577,11 +591,6 @@ filenames = {
|
||||
"shell/renderer/web_worker_observer.h",
|
||||
"shell/utility/atom_content_utility_client.cc",
|
||||
"shell/utility/atom_content_utility_client.h",
|
||||
"chromium_src/chrome/browser/process_singleton_posix.cc",
|
||||
"chromium_src/chrome/browser/process_singleton_win.cc",
|
||||
"chromium_src/chrome/browser/process_singleton.h",
|
||||
"chromium_src/chrome/browser/ui/views/frame/global_menu_bar_registrar_x11.cc",
|
||||
"chromium_src/chrome/browser/ui/views/frame/global_menu_bar_registrar_x11.h",
|
||||
]
|
||||
|
||||
lib_sources_nss = [
|
||||
|
||||
60
filenames.hunspell.gni
Normal file
60
filenames.hunspell.gni
Normal file
@@ -0,0 +1,60 @@
|
||||
hunspell_dictionaries = [
|
||||
"//third_party/hunspell_dictionaries/af-ZA-3-0.bdic",
|
||||
"//third_party/hunspell_dictionaries/bg-BG-3-0.bdic",
|
||||
"//third_party/hunspell_dictionaries/ca-ES-3-0.bdic",
|
||||
"//third_party/hunspell_dictionaries/cs-CZ-3-0.bdic",
|
||||
"//third_party/hunspell_dictionaries/cy-GB-1-0.bdic",
|
||||
"//third_party/hunspell_dictionaries/da-DK-3-0.bdic",
|
||||
"//third_party/hunspell_dictionaries/de-DE-3-0.bdic",
|
||||
"//third_party/hunspell_dictionaries/el-GR-3-0.bdic",
|
||||
"//third_party/hunspell_dictionaries/en-AU-8-0.bdic",
|
||||
"//third_party/hunspell_dictionaries/en-CA-8-0.bdic",
|
||||
"//third_party/hunspell_dictionaries/en-GB-8-0.bdic",
|
||||
"//third_party/hunspell_dictionaries/en-US-8-0.bdic",
|
||||
"//third_party/hunspell_dictionaries/es-ES-3-0.bdic",
|
||||
"//third_party/hunspell_dictionaries/et-EE-3-0.bdic",
|
||||
"//third_party/hunspell_dictionaries/fa-IR-8-0.bdic",
|
||||
"//third_party/hunspell_dictionaries/fo-FO-3-0.bdic",
|
||||
"//third_party/hunspell_dictionaries/fr-FR-3-0.bdic",
|
||||
"//third_party/hunspell_dictionaries/he-IL-3-0.bdic",
|
||||
"//third_party/hunspell_dictionaries/hi-IN-3-0.bdic",
|
||||
"//third_party/hunspell_dictionaries/hr-HR-3-0.bdic",
|
||||
"//third_party/hunspell_dictionaries/hu-HU-3-0.bdic",
|
||||
"//third_party/hunspell_dictionaries/hy-1-0.bdic",
|
||||
"//third_party/hunspell_dictionaries/id-ID-3-0.bdic",
|
||||
"//third_party/hunspell_dictionaries/it-IT-3-0.bdic",
|
||||
"//third_party/hunspell_dictionaries/ko-3-0.bdic",
|
||||
"//third_party/hunspell_dictionaries/lt-LT-3-0.bdic",
|
||||
"//third_party/hunspell_dictionaries/lv-LV-3-0.bdic",
|
||||
"//third_party/hunspell_dictionaries/nb-NO-3-0.bdic",
|
||||
"//third_party/hunspell_dictionaries/nl-NL-3-0.bdic",
|
||||
"//third_party/hunspell_dictionaries/pl-PL-3-0.bdic",
|
||||
"//third_party/hunspell_dictionaries/pt-BR-3-0.bdic",
|
||||
"//third_party/hunspell_dictionaries/pt-PT-3-0.bdic",
|
||||
"//third_party/hunspell_dictionaries/ro-RO-3-0.bdic",
|
||||
"//third_party/hunspell_dictionaries/ru-RU-3-0.bdic",
|
||||
"//third_party/hunspell_dictionaries/sh-3-0.bdic",
|
||||
"//third_party/hunspell_dictionaries/sh-4-0.bdic",
|
||||
"//third_party/hunspell_dictionaries/sk-SK-3-0.bdic",
|
||||
"//third_party/hunspell_dictionaries/sl-SI-3-0.bdic",
|
||||
"//third_party/hunspell_dictionaries/sq-3-0.bdic",
|
||||
"//third_party/hunspell_dictionaries/sr-3-0.bdic",
|
||||
"//third_party/hunspell_dictionaries/sr-4-0.bdic",
|
||||
"//third_party/hunspell_dictionaries/sv-SE-3-0.bdic",
|
||||
"//third_party/hunspell_dictionaries/ta-IN-3-0.bdic",
|
||||
"//third_party/hunspell_dictionaries/tg-TG-5-0.bdic",
|
||||
"//third_party/hunspell_dictionaries/tr-TR-4-0.bdic",
|
||||
"//third_party/hunspell_dictionaries/uk-UA-3-0.bdic",
|
||||
"//third_party/hunspell_dictionaries/vi-VN-3-0.bdic",
|
||||
"//third_party/hunspell_dictionaries/xx-XX-3-0.bdic",
|
||||
]
|
||||
|
||||
hunspell_licenses = [
|
||||
"//third_party/hunspell_dictionaries/COPYING",
|
||||
"//third_party/hunspell_dictionaries/COPYING.Apache",
|
||||
"//third_party/hunspell_dictionaries/COPYING.LESSER",
|
||||
"//third_party/hunspell_dictionaries/COPYING.LGPL",
|
||||
"//third_party/hunspell_dictionaries/COPYING.MIT",
|
||||
"//third_party/hunspell_dictionaries/COPYING.MPL",
|
||||
"//third_party/hunspell_dictionaries/LICENSE",
|
||||
]
|
||||
@@ -105,9 +105,9 @@ if (process.platform === 'linux') {
|
||||
}
|
||||
|
||||
// Routes the events to webContents.
|
||||
const events = ['login', 'certificate-error', 'select-client-certificate']
|
||||
const events = ['certificate-error', 'select-client-certificate']
|
||||
for (const name of events) {
|
||||
app.on(name as 'login', (event, webContents, ...args: any[]) => {
|
||||
app.on(name as 'certificate-error', (event, webContents, ...args: any[]) => {
|
||||
webContents.emit(name, event, ...args)
|
||||
})
|
||||
}
|
||||
|
||||
@@ -33,7 +33,7 @@ BrowserWindow.prototype._init = function () {
|
||||
|
||||
// Hide the auto-hide menu when webContents is focused.
|
||||
this.webContents.on('activate', () => {
|
||||
if (process.platform !== 'darwin' && this.isMenuBarAutoHide() && this.isMenuBarVisible()) {
|
||||
if (process.platform !== 'darwin' && this.autoHideMenuBar && this.isMenuBarVisible()) {
|
||||
this.setMenuBarVisibility(false)
|
||||
}
|
||||
})
|
||||
|
||||
@@ -163,6 +163,7 @@ const messageBox = (sync, window, options) => {
|
||||
defaultId = -1,
|
||||
detail = '',
|
||||
icon = null,
|
||||
noLink = false,
|
||||
message = '',
|
||||
title = '',
|
||||
type = 'none'
|
||||
@@ -173,11 +174,15 @@ const messageBox = (sync, window, options) => {
|
||||
if (!Array.isArray(buttons)) throw new TypeError('Buttons must be an array')
|
||||
if (options.normalizeAccessKeys) buttons = buttons.map(normalizeAccessKey)
|
||||
if (typeof title !== 'string') throw new TypeError('Title must be a string')
|
||||
if (typeof noLink !== 'boolean') throw new TypeError('noLink must be a boolean')
|
||||
if (typeof message !== 'string') throw new TypeError('Message must be a string')
|
||||
if (typeof detail !== 'string') throw new TypeError('Detail must be a string')
|
||||
if (typeof checkboxLabel !== 'string') throw new TypeError('checkboxLabel must be a string')
|
||||
|
||||
checkboxChecked = !!checkboxChecked
|
||||
if (checkboxChecked && !checkboxLabel) {
|
||||
throw new Error('checkboxChecked requires that checkboxLabel also be passed')
|
||||
}
|
||||
|
||||
// Choose a default button to get selected when dialog is cancelled.
|
||||
if (cancelId == null) {
|
||||
@@ -192,15 +197,13 @@ const messageBox = (sync, window, options) => {
|
||||
}
|
||||
}
|
||||
|
||||
const flags = options.noLink ? messageBoxOptions.noLink : 0
|
||||
|
||||
const settings = {
|
||||
window,
|
||||
messageBoxType,
|
||||
buttons,
|
||||
defaultId,
|
||||
cancelId,
|
||||
flags,
|
||||
noLink,
|
||||
title,
|
||||
message,
|
||||
detail,
|
||||
|
||||
@@ -2,5 +2,7 @@ import { defineProperties } from '@electron/internal/common/define-properties'
|
||||
import { commonModuleList } from '@electron/internal/common/api/module-list'
|
||||
import { browserModuleList } from '@electron/internal/browser/api/module-list'
|
||||
|
||||
defineProperties(exports, commonModuleList)
|
||||
defineProperties(exports, browserModuleList)
|
||||
module.exports = {}
|
||||
|
||||
defineProperties(module.exports, commonModuleList)
|
||||
defineProperties(module.exports, browserModuleList)
|
||||
|
||||
@@ -21,6 +21,7 @@ module.exports = [
|
||||
{ name: 'inAppPurchase' },
|
||||
{ name: 'Menu' },
|
||||
{ name: 'MenuItem' },
|
||||
{ name: 'nativeTheme' },
|
||||
{ name: 'net' },
|
||||
{ name: 'netLog' },
|
||||
{ name: 'Notification' },
|
||||
|
||||
@@ -2,17 +2,13 @@
|
||||
|
||||
const url = require('url')
|
||||
const { EventEmitter } = require('events')
|
||||
const { Readable } = require('stream')
|
||||
const { Readable, Writable } = require('stream')
|
||||
const { app } = require('electron')
|
||||
const { Session } = process.electronBinding('session')
|
||||
const { net, Net } = process.electronBinding('net')
|
||||
const { URLRequest } = net
|
||||
const { net, Net, _isValidHeaderName, _isValidHeaderValue } = process.electronBinding('net')
|
||||
const { URLLoader } = net
|
||||
|
||||
// Net is an EventEmitter.
|
||||
Object.setPrototypeOf(Net.prototype, EventEmitter.prototype)
|
||||
EventEmitter.call(net)
|
||||
|
||||
Object.setPrototypeOf(URLRequest.prototype, EventEmitter.prototype)
|
||||
Object.setPrototypeOf(URLLoader.prototype, EventEmitter.prototype)
|
||||
|
||||
const kSupportedProtocols = new Set(['http:', 'https:'])
|
||||
|
||||
@@ -40,32 +36,24 @@ const discardableDuplicateHeaders = new Set([
|
||||
])
|
||||
|
||||
class IncomingMessage extends Readable {
|
||||
constructor (urlRequest) {
|
||||
constructor (responseHead) {
|
||||
super()
|
||||
this.urlRequest = urlRequest
|
||||
this.shouldPush = false
|
||||
this.data = []
|
||||
this.urlRequest.on('data', (event, chunk) => {
|
||||
this._storeInternalData(chunk)
|
||||
this._pushInternalData()
|
||||
})
|
||||
this.urlRequest.on('end', () => {
|
||||
this._storeInternalData(null)
|
||||
this._pushInternalData()
|
||||
})
|
||||
this._shouldPush = false
|
||||
this._data = []
|
||||
this._responseHead = responseHead
|
||||
}
|
||||
|
||||
get statusCode () {
|
||||
return this.urlRequest.statusCode
|
||||
return this._responseHead.statusCode
|
||||
}
|
||||
|
||||
get statusMessage () {
|
||||
return this.urlRequest.statusMessage
|
||||
return this._responseHead.statusMessage
|
||||
}
|
||||
|
||||
get headers () {
|
||||
const filteredHeaders = {}
|
||||
const rawHeaders = this.urlRequest.rawResponseHeaders
|
||||
const rawHeaders = this._responseHead.headers
|
||||
Object.keys(rawHeaders).forEach(header => {
|
||||
if (header in filteredHeaders && discardableDuplicateHeaders.has(header)) {
|
||||
// do nothing with discardable duplicate headers
|
||||
@@ -88,11 +76,11 @@ class IncomingMessage extends Readable {
|
||||
}
|
||||
|
||||
get httpVersionMajor () {
|
||||
return this.urlRequest.httpVersionMajor
|
||||
return this._responseHead.httpVersion.major
|
||||
}
|
||||
|
||||
get httpVersionMinor () {
|
||||
return this.urlRequest.httpVersionMinor
|
||||
return this._responseHead.httpVersion.minor
|
||||
}
|
||||
|
||||
get rawTrailers () {
|
||||
@@ -104,181 +92,197 @@ class IncomingMessage extends Readable {
|
||||
}
|
||||
|
||||
_storeInternalData (chunk) {
|
||||
this.data.push(chunk)
|
||||
this._data.push(chunk)
|
||||
this._pushInternalData()
|
||||
}
|
||||
|
||||
_pushInternalData () {
|
||||
while (this.shouldPush && this.data.length > 0) {
|
||||
const chunk = this.data.shift()
|
||||
this.shouldPush = this.push(chunk)
|
||||
while (this._shouldPush && this._data.length > 0) {
|
||||
const chunk = this._data.shift()
|
||||
this._shouldPush = this.push(chunk)
|
||||
}
|
||||
}
|
||||
|
||||
_read () {
|
||||
this.shouldPush = true
|
||||
this._shouldPush = true
|
||||
this._pushInternalData()
|
||||
}
|
||||
}
|
||||
|
||||
URLRequest.prototype._emitRequestEvent = function (isAsync, ...rest) {
|
||||
if (isAsync) {
|
||||
process.nextTick(() => {
|
||||
this.clientRequest.emit(...rest)
|
||||
})
|
||||
} else {
|
||||
this.clientRequest.emit(...rest)
|
||||
}
|
||||
}
|
||||
|
||||
URLRequest.prototype._emitResponseEvent = function (isAsync, ...rest) {
|
||||
if (isAsync) {
|
||||
process.nextTick(() => {
|
||||
this._response.emit(...rest)
|
||||
})
|
||||
} else {
|
||||
this._response.emit(...rest)
|
||||
}
|
||||
}
|
||||
|
||||
class ClientRequest extends EventEmitter {
|
||||
constructor (options, callback) {
|
||||
/** Writable stream that buffers up everything written to it. */
|
||||
class SlurpStream extends Writable {
|
||||
constructor () {
|
||||
super()
|
||||
this._data = Buffer.alloc(0)
|
||||
}
|
||||
_write (chunk, encoding, callback) {
|
||||
this._data = Buffer.concat([this._data, chunk])
|
||||
callback()
|
||||
}
|
||||
data () { return this._data }
|
||||
}
|
||||
|
||||
class ChunkedBodyStream extends Writable {
|
||||
constructor (clientRequest) {
|
||||
super()
|
||||
this._clientRequest = clientRequest
|
||||
}
|
||||
|
||||
_write (chunk, encoding, callback) {
|
||||
if (this._downstream) {
|
||||
this._downstream.write(chunk).then(callback, callback)
|
||||
} else {
|
||||
// the contract of _write is that we won't be called again until we call
|
||||
// the callback, so we're good to just save a single chunk.
|
||||
this._pendingChunk = chunk
|
||||
this._pendingCallback = callback
|
||||
|
||||
// The first write to a chunked body stream begins the request.
|
||||
this._clientRequest._startRequest()
|
||||
}
|
||||
}
|
||||
|
||||
_final (callback) {
|
||||
this._downstream.done()
|
||||
callback()
|
||||
}
|
||||
|
||||
startReading (pipe) {
|
||||
if (this._downstream) {
|
||||
throw new Error('two startReading calls???')
|
||||
}
|
||||
this._downstream = pipe
|
||||
if (this._pendingChunk) {
|
||||
const doneWriting = (maybeError) => {
|
||||
const cb = this._pendingCallback
|
||||
delete this._pendingCallback
|
||||
delete this._pendingChunk
|
||||
cb(maybeError)
|
||||
}
|
||||
this._downstream.write(this._pendingChunk).then(doneWriting, doneWriting)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function parseOptions (options) {
|
||||
if (typeof options === 'string') {
|
||||
options = url.parse(options)
|
||||
} else {
|
||||
options = { ...options }
|
||||
}
|
||||
|
||||
const method = (options.method || 'GET').toUpperCase()
|
||||
let urlStr = options.url
|
||||
|
||||
if (!urlStr) {
|
||||
const urlObj = {}
|
||||
const protocol = options.protocol || 'http:'
|
||||
if (!kSupportedProtocols.has(protocol)) {
|
||||
throw new Error('Protocol "' + protocol + '" not supported')
|
||||
}
|
||||
urlObj.protocol = protocol
|
||||
|
||||
if (options.host) {
|
||||
urlObj.host = options.host
|
||||
} else {
|
||||
if (options.hostname) {
|
||||
urlObj.hostname = options.hostname
|
||||
} else {
|
||||
urlObj.hostname = 'localhost'
|
||||
}
|
||||
|
||||
if (options.port) {
|
||||
urlObj.port = options.port
|
||||
}
|
||||
}
|
||||
|
||||
if (options.path && / /.test(options.path)) {
|
||||
// The actual regex is more like /[^A-Za-z0-9\-._~!$&'()*+,;=/:@]/
|
||||
// with an additional rule for ignoring percentage-escaped characters
|
||||
// but that's a) hard to capture in a regular expression that performs
|
||||
// well, and b) possibly too restrictive for real-world usage. That's
|
||||
// why it only scans for spaces because those are guaranteed to create
|
||||
// an invalid request.
|
||||
throw new TypeError('Request path contains unescaped characters')
|
||||
}
|
||||
const pathObj = url.parse(options.path || '/')
|
||||
urlObj.pathname = pathObj.pathname
|
||||
urlObj.search = pathObj.search
|
||||
urlObj.hash = pathObj.hash
|
||||
urlStr = url.format(urlObj)
|
||||
}
|
||||
|
||||
const redirectPolicy = options.redirect || 'follow'
|
||||
if (!['follow', 'error', 'manual'].includes(redirectPolicy)) {
|
||||
throw new Error('redirect mode should be one of follow, error or manual')
|
||||
}
|
||||
|
||||
if (options.headers != null && typeof options.headers !== 'object') {
|
||||
throw new TypeError('headers must be an object')
|
||||
}
|
||||
|
||||
const urlLoaderOptions = {
|
||||
method: method,
|
||||
url: urlStr,
|
||||
redirectPolicy,
|
||||
extraHeaders: options.headers || {}
|
||||
}
|
||||
for (const [name, value] of Object.entries(urlLoaderOptions.extraHeaders)) {
|
||||
if (!_isValidHeaderName(name)) {
|
||||
throw new Error(`Invalid header name: '${name}'`)
|
||||
}
|
||||
if (!_isValidHeaderValue(value.toString())) {
|
||||
throw new Error(`Invalid value for header '${name}': '${value}'`)
|
||||
}
|
||||
}
|
||||
if (options.session) {
|
||||
if (options.session instanceof Session) {
|
||||
urlLoaderOptions.session = options.session
|
||||
} else {
|
||||
throw new TypeError('`session` should be an instance of the Session class')
|
||||
}
|
||||
} else if (options.partition) {
|
||||
if (typeof options.partition === 'string') {
|
||||
urlLoaderOptions.partition = options.partition
|
||||
} else {
|
||||
throw new TypeError('`partition` should be a string')
|
||||
}
|
||||
}
|
||||
return urlLoaderOptions
|
||||
}
|
||||
|
||||
class ClientRequest extends Writable {
|
||||
constructor (options, callback) {
|
||||
super({ autoDestroy: true })
|
||||
|
||||
if (!app.isReady()) {
|
||||
throw new Error('net module can only be used after app is ready')
|
||||
}
|
||||
|
||||
if (typeof options === 'string') {
|
||||
options = url.parse(options)
|
||||
} else {
|
||||
options = Object.assign({}, options)
|
||||
}
|
||||
|
||||
const method = (options.method || 'GET').toUpperCase()
|
||||
let urlStr = options.url
|
||||
|
||||
if (!urlStr) {
|
||||
const urlObj = {}
|
||||
const protocol = options.protocol || 'http:'
|
||||
if (!kSupportedProtocols.has(protocol)) {
|
||||
throw new Error('Protocol "' + protocol + '" not supported')
|
||||
}
|
||||
urlObj.protocol = protocol
|
||||
|
||||
if (options.host) {
|
||||
urlObj.host = options.host
|
||||
} else {
|
||||
if (options.hostname) {
|
||||
urlObj.hostname = options.hostname
|
||||
} else {
|
||||
urlObj.hostname = 'localhost'
|
||||
}
|
||||
|
||||
if (options.port) {
|
||||
urlObj.port = options.port
|
||||
}
|
||||
}
|
||||
|
||||
if (options.path && / /.test(options.path)) {
|
||||
// The actual regex is more like /[^A-Za-z0-9\-._~!$&'()*+,;=/:@]/
|
||||
// with an additional rule for ignoring percentage-escaped characters
|
||||
// but that's a) hard to capture in a regular expression that performs
|
||||
// well, and b) possibly too restrictive for real-world usage. That's
|
||||
// why it only scans for spaces because those are guaranteed to create
|
||||
// an invalid request.
|
||||
throw new TypeError('Request path contains unescaped characters')
|
||||
}
|
||||
const pathObj = url.parse(options.path || '/')
|
||||
urlObj.pathname = pathObj.pathname
|
||||
urlObj.search = pathObj.search
|
||||
urlObj.hash = pathObj.hash
|
||||
urlStr = url.format(urlObj)
|
||||
}
|
||||
|
||||
const redirectPolicy = options.redirect || 'follow'
|
||||
if (!['follow', 'error', 'manual'].includes(redirectPolicy)) {
|
||||
throw new Error('redirect mode should be one of follow, error or manual')
|
||||
}
|
||||
|
||||
const urlRequestOptions = {
|
||||
method: method,
|
||||
url: urlStr,
|
||||
redirect: redirectPolicy
|
||||
}
|
||||
if (options.session) {
|
||||
if (options.session instanceof Session) {
|
||||
urlRequestOptions.session = options.session
|
||||
} else {
|
||||
throw new TypeError('`session` should be an instance of the Session class')
|
||||
}
|
||||
} else if (options.partition) {
|
||||
if (typeof options.partition === 'string') {
|
||||
urlRequestOptions.partition = options.partition
|
||||
} else {
|
||||
throw new TypeError('`partition` should be a string')
|
||||
}
|
||||
}
|
||||
|
||||
const urlRequest = new URLRequest(urlRequestOptions)
|
||||
|
||||
// Set back and forward links.
|
||||
this.urlRequest = urlRequest
|
||||
urlRequest.clientRequest = this
|
||||
|
||||
// This is a copy of the extra headers structure held by the native
|
||||
// net::URLRequest. The main reason is to keep the getHeader API synchronous
|
||||
// after the request starts.
|
||||
this.extraHeaders = {}
|
||||
|
||||
if (options.headers) {
|
||||
for (const key in options.headers) {
|
||||
this.setHeader(key, options.headers[key])
|
||||
}
|
||||
}
|
||||
|
||||
// Set when the request uses chunked encoding. Can be switched
|
||||
// to true only once and never set back to false.
|
||||
this.chunkedEncodingEnabled = false
|
||||
|
||||
urlRequest.on('response', () => {
|
||||
const response = new IncomingMessage(urlRequest)
|
||||
urlRequest._response = response
|
||||
this.emit('response', response)
|
||||
})
|
||||
|
||||
urlRequest.on('login', (event, authInfo, callback) => {
|
||||
this.emit('login', authInfo, (username, password) => {
|
||||
// If null or undefined username/password, force to empty string.
|
||||
if (username === null || username === undefined) {
|
||||
username = ''
|
||||
}
|
||||
if (typeof username !== 'string') {
|
||||
throw new Error('username must be a string')
|
||||
}
|
||||
if (password === null || password === undefined) {
|
||||
password = ''
|
||||
}
|
||||
if (typeof password !== 'string') {
|
||||
throw new Error('password must be a string')
|
||||
}
|
||||
callback(username, password)
|
||||
})
|
||||
})
|
||||
|
||||
if (callback) {
|
||||
this.once('response', callback)
|
||||
}
|
||||
}
|
||||
|
||||
get chunkedEncoding () {
|
||||
return this.chunkedEncodingEnabled
|
||||
const { redirectPolicy, ...urlLoaderOptions } = parseOptions(options)
|
||||
this._urlLoaderOptions = urlLoaderOptions
|
||||
this._redirectPolicy = redirectPolicy
|
||||
this._started = false
|
||||
}
|
||||
|
||||
set chunkedEncoding (value) {
|
||||
if (!this.urlRequest.notStarted) {
|
||||
throw new Error('Can\'t set the transfer encoding, headers have been sent')
|
||||
if (this._started) {
|
||||
throw new Error('chunkedEncoding can only be set before the request is started')
|
||||
}
|
||||
if (typeof this._chunkedEncoding !== 'undefined') {
|
||||
throw new Error('chunkedEncoding can only be set once')
|
||||
}
|
||||
this._chunkedEncoding = !!value
|
||||
if (this._chunkedEncoding) {
|
||||
this._body = new ChunkedBodyStream(this)
|
||||
this._urlLoaderOptions.body = (pipe) => {
|
||||
this._body.startReading(pipe)
|
||||
}
|
||||
}
|
||||
this.chunkedEncodingEnabled = value
|
||||
}
|
||||
|
||||
setHeader (name, value) {
|
||||
@@ -288,13 +292,18 @@ class ClientRequest extends EventEmitter {
|
||||
if (value == null) {
|
||||
throw new Error('`value` required in setHeader("' + name + '", value)')
|
||||
}
|
||||
if (!this.urlRequest.notStarted) {
|
||||
if (this._started || this._firstWrite) {
|
||||
throw new Error('Can\'t set headers after they are sent')
|
||||
}
|
||||
if (!_isValidHeaderName(name)) {
|
||||
throw new Error(`Invalid header name: '${name}'`)
|
||||
}
|
||||
if (!_isValidHeaderValue(value.toString())) {
|
||||
throw new Error(`Invalid value for header '${name}': '${value}'`)
|
||||
}
|
||||
|
||||
const key = name.toLowerCase()
|
||||
this.extraHeaders[key] = value
|
||||
this.urlRequest.setExtraHeader(name, value.toString())
|
||||
this._urlLoaderOptions.extraHeaders[key] = value
|
||||
}
|
||||
|
||||
getHeader (name) {
|
||||
@@ -302,12 +311,8 @@ class ClientRequest extends EventEmitter {
|
||||
throw new Error('`name` is required for getHeader(name)')
|
||||
}
|
||||
|
||||
if (!this.extraHeaders) {
|
||||
return
|
||||
}
|
||||
|
||||
const key = name.toLowerCase()
|
||||
return this.extraHeaders[key]
|
||||
return this._urlLoaderOptions.extraHeaders[key]
|
||||
}
|
||||
|
||||
removeHeader (name) {
|
||||
@@ -315,93 +320,144 @@ class ClientRequest extends EventEmitter {
|
||||
throw new Error('`name` is required for removeHeader(name)')
|
||||
}
|
||||
|
||||
if (!this.urlRequest.notStarted) {
|
||||
if (this._started || this._firstWrite) {
|
||||
throw new Error('Can\'t remove headers after they are sent')
|
||||
}
|
||||
|
||||
const key = name.toLowerCase()
|
||||
delete this.extraHeaders[key]
|
||||
this.urlRequest.removeExtraHeader(name)
|
||||
delete this._urlLoaderOptions.extraHeaders[key]
|
||||
}
|
||||
|
||||
_write (chunk, encoding, callback, isLast) {
|
||||
const chunkIsString = typeof chunk === 'string'
|
||||
const chunkIsBuffer = chunk instanceof Buffer
|
||||
if (!chunkIsString && !chunkIsBuffer) {
|
||||
throw new TypeError('First argument must be a string or Buffer')
|
||||
_write (chunk, encoding, callback) {
|
||||
this._firstWrite = true
|
||||
if (!this._body) {
|
||||
this._body = new SlurpStream()
|
||||
this._body.on('finish', () => {
|
||||
this._urlLoaderOptions.body = this._body.data()
|
||||
this._startRequest()
|
||||
})
|
||||
}
|
||||
|
||||
if (chunkIsString) {
|
||||
// We convert all strings into binary buffers.
|
||||
chunk = Buffer.from(chunk, encoding)
|
||||
}
|
||||
|
||||
// Since writing to the network is asynchronous, we conservatively
|
||||
// assume that request headers are written after delivering the first
|
||||
// buffer to the network IO thread.
|
||||
if (this.urlRequest.notStarted) {
|
||||
this.urlRequest.setChunkedUpload(this.chunkedEncoding)
|
||||
}
|
||||
|
||||
// Headers are assumed to be sent on first call to _writeBuffer,
|
||||
// i.e. after the first call to write or end.
|
||||
const result = this.urlRequest.write(chunk, isLast)
|
||||
|
||||
// The write callback is fired asynchronously to mimic Node.js.
|
||||
if (callback) {
|
||||
process.nextTick(callback)
|
||||
}
|
||||
|
||||
return result
|
||||
// TODO: is this the right way to forward to another stream?
|
||||
this._body.write(chunk, encoding, callback)
|
||||
}
|
||||
|
||||
write (data, encoding, callback) {
|
||||
if (this.urlRequest.finished) {
|
||||
const error = new Error('Write after end')
|
||||
process.nextTick(writeAfterEndNT, this, error, callback)
|
||||
return true
|
||||
_final (callback) {
|
||||
if (this._body) {
|
||||
// TODO: is this the right way to forward to another stream?
|
||||
this._body.end(callback)
|
||||
} else {
|
||||
// end() called without a body, go ahead and start the request
|
||||
this._startRequest()
|
||||
callback()
|
||||
}
|
||||
|
||||
return this._write(data, encoding, callback, false)
|
||||
}
|
||||
|
||||
end (data, encoding, callback) {
|
||||
if (this.urlRequest.finished) {
|
||||
return false
|
||||
_startRequest () {
|
||||
this._started = true
|
||||
const stringifyValues = (obj) => {
|
||||
const ret = {}
|
||||
for (const k in obj) {
|
||||
ret[k] = obj[k].toString()
|
||||
}
|
||||
return ret
|
||||
}
|
||||
const opts = { ...this._urlLoaderOptions, extraHeaders: stringifyValues(this._urlLoaderOptions.extraHeaders) }
|
||||
this._urlLoader = new URLLoader(opts)
|
||||
this._urlLoader.on('response-started', (event, finalUrl, responseHead) => {
|
||||
const response = this._response = new IncomingMessage(responseHead)
|
||||
this.emit('response', response)
|
||||
})
|
||||
this._urlLoader.on('data', (event, data) => {
|
||||
this._response._storeInternalData(Buffer.from(data))
|
||||
})
|
||||
this._urlLoader.on('complete', () => {
|
||||
if (this._response) { this._response._storeInternalData(null) }
|
||||
})
|
||||
this._urlLoader.on('error', (event, netErrorString) => {
|
||||
const error = new Error(netErrorString)
|
||||
if (this._response) this._response.destroy(error)
|
||||
this._die(error)
|
||||
})
|
||||
|
||||
if (typeof data === 'function') {
|
||||
callback = data
|
||||
encoding = null
|
||||
data = null
|
||||
} else if (typeof encoding === 'function') {
|
||||
callback = encoding
|
||||
encoding = null
|
||||
}
|
||||
this._urlLoader.on('login', (event, authInfo, callback) => {
|
||||
const handled = this.emit('login', authInfo, callback)
|
||||
if (!handled) {
|
||||
// If there were no listeners, cancel the authentication request.
|
||||
callback()
|
||||
}
|
||||
})
|
||||
|
||||
data = data || ''
|
||||
this._urlLoader.on('redirect', (event, redirectInfo, headers) => {
|
||||
const { statusCode, newMethod, newUrl } = redirectInfo
|
||||
if (this._redirectPolicy === 'error') {
|
||||
this._die(new Error(`Attempted to redirect, but redirect policy was 'error'`))
|
||||
} else if (this._redirectPolicy === 'manual') {
|
||||
let _followRedirect = false
|
||||
this._followRedirectCb = () => { _followRedirect = true }
|
||||
try {
|
||||
this.emit('redirect', statusCode, newMethod, newUrl, headers)
|
||||
} finally {
|
||||
this._followRedirectCb = null
|
||||
if (!_followRedirect && !this._aborted) {
|
||||
this._die(new Error('Redirect was cancelled'))
|
||||
}
|
||||
}
|
||||
} else if (this._redirectPolicy === 'follow') {
|
||||
// Calling followRedirect() when the redirect policy is 'follow' is
|
||||
// allowed but does nothing. (Perhaps it should throw an error
|
||||
// though...? Since the redirect will happen regardless.)
|
||||
try {
|
||||
this._followRedirectCb = () => {}
|
||||
this.emit('redirect', statusCode, newMethod, newUrl, headers)
|
||||
} finally {
|
||||
this._followRedirectCb = null
|
||||
}
|
||||
} else {
|
||||
this._die(new Error(`Unexpected redirect policy '${this._redirectPolicy}'`))
|
||||
}
|
||||
})
|
||||
|
||||
return this._write(data, encoding, callback, true)
|
||||
this._urlLoader.on('upload-progress', (event, position, total) => {
|
||||
this._uploadProgress = { active: true, started: true, current: position, total }
|
||||
this.emit('upload-progress', position, total) // Undocumented, for now
|
||||
})
|
||||
|
||||
this._urlLoader.on('download-progress', (event, current) => {
|
||||
if (this._response) {
|
||||
this._response.emit('download-progress', current) // Undocumented, for now
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
followRedirect () {
|
||||
this.urlRequest.followRedirect()
|
||||
if (this._followRedirectCb) {
|
||||
this._followRedirectCb()
|
||||
} else {
|
||||
throw new Error('followRedirect() called, but was not waiting for a redirect')
|
||||
}
|
||||
}
|
||||
|
||||
abort () {
|
||||
this.urlRequest.cancel()
|
||||
if (!this._aborted) {
|
||||
process.nextTick(() => { this.emit('abort') })
|
||||
}
|
||||
this._aborted = true
|
||||
this._die()
|
||||
}
|
||||
|
||||
_die (err) {
|
||||
this.destroy(err)
|
||||
if (this._urlLoader) {
|
||||
this._urlLoader.cancel()
|
||||
if (this._response) this._response.destroy(err)
|
||||
}
|
||||
}
|
||||
|
||||
getUploadProgress () {
|
||||
return this.urlRequest.getUploadProgress()
|
||||
return this._uploadProgress ? { ...this._uploadProgress } : { active: false }
|
||||
}
|
||||
}
|
||||
|
||||
function writeAfterEndNT (self, error, callback) {
|
||||
self.emit('error', error)
|
||||
if (callback) callback(error)
|
||||
}
|
||||
|
||||
Net.prototype.request = function (options, callback) {
|
||||
return new ClientRequest(options, callback)
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@ const path = require('path')
|
||||
const url = require('url')
|
||||
const { app, ipcMain, session, deprecate } = electron
|
||||
|
||||
const { internalWindowOpen } = require('@electron/internal/browser/guest-window-manager')
|
||||
const NavigationController = require('@electron/internal/browser/navigation-controller')
|
||||
const { ipcMainInternal } = require('@electron/internal/browser/ipc-main-internal')
|
||||
const ipcMainUtils = require('@electron/internal/browser/ipc-main-internal-utils')
|
||||
@@ -71,7 +72,6 @@ const defaultPrintingSetting = {
|
||||
headerFooterEnabled: false,
|
||||
marginsType: 0,
|
||||
isFirstRequest: false,
|
||||
requestID: getNextId(),
|
||||
previewUIID: 0,
|
||||
previewModifiable: true,
|
||||
printToPDF: true,
|
||||
@@ -82,7 +82,7 @@ const defaultPrintingSetting = {
|
||||
deviceName: 'Save as PDF',
|
||||
generateDraftData: true,
|
||||
fitToPageEnabled: false,
|
||||
scaleFactor: 1,
|
||||
scaleFactor: 100,
|
||||
dpiHorizontal: 72,
|
||||
dpiVertical: 72,
|
||||
rasterizePDF: false,
|
||||
@@ -184,30 +184,42 @@ for (const method of webFrameMethods) {
|
||||
}
|
||||
}
|
||||
|
||||
const executeJavaScript = (contents, code, hasUserGesture) => {
|
||||
return ipcMainUtils.invokeInWebContents(contents, false, 'ELECTRON_INTERNAL_RENDERER_WEB_FRAME_METHOD', 'executeJavaScript', code, hasUserGesture)
|
||||
const waitTillCanExecuteJavaScript = async (webContents) => {
|
||||
if (webContents.getURL() && !webContents.isLoadingMainFrame()) return
|
||||
|
||||
return new Promise((resolve) => {
|
||||
webContents.once('did-stop-loading', () => {
|
||||
resolve()
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
// Make sure WebContents::executeJavaScript would run the code only when the
|
||||
// WebContents has been loaded.
|
||||
WebContents.prototype.executeJavaScript = function (code, hasUserGesture) {
|
||||
if (this.getURL() && !this.isLoadingMainFrame()) {
|
||||
return executeJavaScript(this, code, hasUserGesture)
|
||||
} else {
|
||||
return new Promise((resolve, reject) => {
|
||||
this.once('did-stop-loading', () => {
|
||||
executeJavaScript(this, code, hasUserGesture).then(resolve, reject)
|
||||
})
|
||||
})
|
||||
}
|
||||
WebContents.prototype.executeJavaScript = async function (code, hasUserGesture) {
|
||||
await waitTillCanExecuteJavaScript(this)
|
||||
return ipcMainUtils.invokeInWebContents(this, false, 'ELECTRON_INTERNAL_RENDERER_WEB_FRAME_METHOD', 'executeJavaScript', code, hasUserGesture)
|
||||
}
|
||||
WebContents.prototype.executeJavaScriptInIsolatedWorld = async function (code, hasUserGesture) {
|
||||
await waitTillCanExecuteJavaScript(this)
|
||||
return ipcMainUtils.invokeInWebContents(this, false, 'ELECTRON_INTERNAL_RENDERER_WEB_FRAME_METHOD', 'executeJavaScriptInIsolatedWorld', code, hasUserGesture)
|
||||
}
|
||||
|
||||
// Translate the options of printToPDF.
|
||||
WebContents.prototype.printToPDF = function (options) {
|
||||
const printingSetting = Object.assign({}, defaultPrintingSetting)
|
||||
const printingSetting = {
|
||||
...defaultPrintingSetting,
|
||||
requestID: getNextId()
|
||||
}
|
||||
if (options.landscape) {
|
||||
printingSetting.landscape = options.landscape
|
||||
}
|
||||
if (options.fitToPageEnabled) {
|
||||
printingSetting.fitToPageEnabled = options.fitToPageEnabled
|
||||
}
|
||||
if (options.scaleFactor) {
|
||||
printingSetting.scaleFactor = options.scaleFactor
|
||||
}
|
||||
if (options.marginsType) {
|
||||
printingSetting.marginsType = options.marginsType
|
||||
}
|
||||
@@ -242,7 +254,9 @@ WebContents.prototype.printToPDF = function (options) {
|
||||
}
|
||||
|
||||
// Chromium expects this in a 0-100 range number, not as float
|
||||
printingSetting.scaleFactor *= 100
|
||||
printingSetting.scaleFactor = Math.ceil(printingSetting.scaleFactor) % 100
|
||||
// PrinterType enum from //printing/print_job_constants.h
|
||||
printingSetting.printerType = 2
|
||||
if (features.isPrintingEnabled()) {
|
||||
return this._printToPDF(printingSetting)
|
||||
} else {
|
||||
@@ -263,6 +277,7 @@ WebContents.prototype.getPrinters = function () {
|
||||
return this._getPrinters()
|
||||
} else {
|
||||
console.error('Error: Printing feature is disabled.')
|
||||
return []
|
||||
}
|
||||
}
|
||||
|
||||
@@ -305,8 +320,14 @@ const addReturnValueToEvent = (event) => {
|
||||
})
|
||||
}
|
||||
|
||||
let warnedAboutRendererProcessReuse = false
|
||||
|
||||
// Add JavaScript wrappers for WebContents class.
|
||||
WebContents.prototype._init = function () {
|
||||
if (!process.noDeprecation && !warnedAboutRendererProcessReuse && app._allowRendererProcessReuseIsDefaultValue) {
|
||||
deprecate.log('The default value of app.allowRendererProcessReuse is deprecated, it is currently "false". It will change to be "true" in Electron 9. For more information please check https://github.com/electron/electron/issues/18397')
|
||||
warnedAboutRendererProcessReuse = true
|
||||
}
|
||||
// The navigation controller.
|
||||
NavigationController.call(this, this)
|
||||
|
||||
@@ -384,9 +405,7 @@ WebContents.prototype._init = function () {
|
||||
width: 800,
|
||||
height: 600
|
||||
}
|
||||
ipcMainInternal.emit('ELECTRON_GUEST_WINDOW_MANAGER_INTERNAL_WINDOW_OPEN',
|
||||
event, url, referrer, frameName, disposition,
|
||||
options, additionalFeatures, postData)
|
||||
internalWindowOpen(event, url, referrer, frameName, disposition, options, additionalFeatures, postData)
|
||||
})
|
||||
|
||||
// Create a new browser window for the native implementation of
|
||||
@@ -408,11 +427,14 @@ WebContents.prototype._init = function () {
|
||||
webContents
|
||||
}
|
||||
const referrer = { url: '', policy: 'default' }
|
||||
ipcMainInternal.emit('ELECTRON_GUEST_WINDOW_MANAGER_INTERNAL_WINDOW_OPEN',
|
||||
event, url, referrer, frameName, disposition, options)
|
||||
internalWindowOpen(event, url, referrer, frameName, disposition, options)
|
||||
})
|
||||
}
|
||||
|
||||
this.on('login', (event, ...args) => {
|
||||
app.emit('login', event, this, ...args)
|
||||
})
|
||||
|
||||
const event = process.electronBinding('event').createEmpty()
|
||||
app.emit('web-contents-created', event, this)
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ const { ipcMainInternal } = require('@electron/internal/browser/ipc-main-interna
|
||||
const ipcMainUtils = require('@electron/internal/browser/ipc-main-internal-utils')
|
||||
const parseFeaturesString = require('@electron/internal/common/parse-features-string')
|
||||
const { syncMethods, asyncMethods } = require('@electron/internal/common/web-view-methods')
|
||||
const { serialize } = require('@electron/internal/common/type-utils')
|
||||
|
||||
// Doesn't exist in early initialization.
|
||||
let webViewManager = null
|
||||
@@ -200,7 +201,7 @@ const attachGuest = function (event, embedderFrameId, elementInstanceId, guestIn
|
||||
nodeIntegrationInSubFrames: params.nodeintegrationinsubframes != null ? params.nodeintegrationinsubframes : false,
|
||||
enableRemoteModule: params.enableremotemodule,
|
||||
plugins: params.plugins,
|
||||
zoomFactor: embedder.getZoomFactor(),
|
||||
zoomFactor: embedder.zoomFactor,
|
||||
disablePopups: !params.allowpopups,
|
||||
webSecurity: !params.disablewebsecurity,
|
||||
enableBlinkFeatures: params.blinkfeatures,
|
||||
@@ -387,6 +388,12 @@ handleMessageSync('ELECTRON_GUEST_VIEW_MANAGER_CALL', function (event, guestInst
|
||||
return guest[method](...args)
|
||||
})
|
||||
|
||||
handleMessage('ELECTRON_GUEST_VIEW_MANAGER_CAPTURE_PAGE', async function (event, guestInstanceId, args) {
|
||||
const guest = getGuestForWebContents(guestInstanceId, event.sender)
|
||||
|
||||
return serialize(await guest.capturePage(...args))
|
||||
})
|
||||
|
||||
// Returns WebContents from its guest id hosted in given webContents.
|
||||
const getGuestForWebContents = function (guestInstanceId, contents) {
|
||||
const guest = getGuest(guestInstanceId)
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
'use strict'
|
||||
|
||||
const { BrowserWindow, webContents } = require('electron')
|
||||
const electron = require('electron')
|
||||
const { BrowserWindow } = electron
|
||||
const { isSameOrigin } = process.electronBinding('v8_util')
|
||||
const { ipcMainInternal } = require('@electron/internal/browser/ipc-main-internal')
|
||||
const ipcMainUtils = require('@electron/internal/browser/ipc-main-internal-utils')
|
||||
@@ -74,8 +75,10 @@ const mergeBrowserWindowOptions = function (embedder, options) {
|
||||
}
|
||||
}
|
||||
|
||||
// Sets correct openerId here to give correct options to 'new-window' event handler
|
||||
options.webPreferences.openerId = embedder.id
|
||||
if (!webPreferences.nativeWindowOpen) {
|
||||
// Sets correct openerId here to give correct options to 'new-window' event handler
|
||||
options.webPreferences.openerId = embedder.id
|
||||
}
|
||||
|
||||
return options
|
||||
}
|
||||
@@ -244,13 +247,11 @@ ipcMainInternal.on('ELECTRON_GUEST_WINDOW_MANAGER_WINDOW_OPEN', (event, url, fra
|
||||
}
|
||||
|
||||
const referrer = { url: '', policy: 'default' }
|
||||
ipcMainInternal.emit('ELECTRON_GUEST_WINDOW_MANAGER_INTERNAL_WINDOW_OPEN', event,
|
||||
url, referrer, frameName, disposition, options, additionalFeatures)
|
||||
internalWindowOpen(event, url, referrer, frameName, disposition, options, additionalFeatures)
|
||||
})
|
||||
|
||||
// Routed window.open messages with fully parsed options
|
||||
ipcMainInternal.on('ELECTRON_GUEST_WINDOW_MANAGER_INTERNAL_WINDOW_OPEN', function (event, url, referrer,
|
||||
frameName, disposition, options, additionalFeatures, postData) {
|
||||
function internalWindowOpen (event, url, referrer, frameName, disposition, options, additionalFeatures, postData) {
|
||||
options = mergeBrowserWindowOptions(event.sender, options)
|
||||
event.sender.emit('new-window', event, url, frameName, disposition, options, additionalFeatures, referrer)
|
||||
const { newGuest } = event
|
||||
@@ -268,11 +269,12 @@ ipcMainInternal.on('ELECTRON_GUEST_WINDOW_MANAGER_INTERNAL_WINDOW_OPEN', functio
|
||||
} else {
|
||||
event.returnValue = createGuest(event.sender, url, referrer, frameName, options, postData)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
const makeSafeHandler = function (handler) {
|
||||
return (event, guestId, ...args) => {
|
||||
const guestContents = webContents.fromId(guestId)
|
||||
// Access webContents via electron to prevent circular require.
|
||||
const guestContents = electron.webContents.fromId(guestId)
|
||||
if (!guestContents) {
|
||||
throw new Error(`Invalid guestId: ${guestId}`)
|
||||
}
|
||||
@@ -289,8 +291,8 @@ const handleMessageSync = function (channel, handler) {
|
||||
ipcMainUtils.handleSync(channel, makeSafeHandler(handler))
|
||||
}
|
||||
|
||||
const assertCanAccessWindow = function (contents, guestContents) {
|
||||
if (!canAccessWindow(contents, guestContents)) {
|
||||
const securityCheck = function (contents, guestContents, check) {
|
||||
if (!check(contents, guestContents)) {
|
||||
console.error(`Blocked ${contents.getURL()} from accessing guestId: ${guestContents.id}`)
|
||||
throw new Error(`Access denied to guestId: ${guestContents.id}`)
|
||||
}
|
||||
@@ -303,7 +305,7 @@ const windowMethods = new Set([
|
||||
])
|
||||
|
||||
handleMessage('ELECTRON_GUEST_WINDOW_MANAGER_WINDOW_METHOD', (event, guestContents, method, ...args) => {
|
||||
assertCanAccessWindow(event.sender, guestContents)
|
||||
securityCheck(event.sender, guestContents, canAccessWindow)
|
||||
|
||||
if (!windowMethods.has(method)) {
|
||||
console.error(`Blocked ${event.sender.getURL()} from calling method: ${method}`)
|
||||
@@ -321,6 +323,8 @@ handleMessage('ELECTRON_GUEST_WINDOW_MANAGER_WINDOW_POSTMESSAGE', (event, guestC
|
||||
// The W3C does not seem to have word on how postMessage should work when the
|
||||
// origins do not match, so we do not do |canAccessWindow| check here since
|
||||
// postMessage across origins is useful and not harmful.
|
||||
securityCheck(event.sender, guestContents, isRelatedWindow)
|
||||
|
||||
if (targetOrigin === '*' || isSameOrigin(guestContents.getURL(), targetOrigin)) {
|
||||
const sourceId = event.sender.id
|
||||
guestContents._sendInternal('ELECTRON_GUEST_WINDOW_POSTMESSAGE', sourceId, message, sourceOrigin)
|
||||
@@ -334,7 +338,7 @@ const webContentsMethodsAsync = new Set([
|
||||
])
|
||||
|
||||
handleMessage('ELECTRON_GUEST_WINDOW_MANAGER_WEB_CONTENTS_METHOD', (event, guestContents, method, ...args) => {
|
||||
assertCanAccessWindow(event.sender, guestContents)
|
||||
securityCheck(event.sender, guestContents, canAccessWindow)
|
||||
|
||||
if (!webContentsMethodsAsync.has(method)) {
|
||||
console.error(`Blocked ${event.sender.getURL()} from calling method: ${method}`)
|
||||
@@ -349,7 +353,7 @@ const webContentsMethodsSync = new Set([
|
||||
])
|
||||
|
||||
handleMessageSync('ELECTRON_GUEST_WINDOW_MANAGER_WEB_CONTENTS_METHOD', (event, guestContents, method, ...args) => {
|
||||
assertCanAccessWindow(event.sender, guestContents)
|
||||
securityCheck(event.sender, guestContents, canAccessWindow)
|
||||
|
||||
if (!webContentsMethodsSync.has(method)) {
|
||||
console.error(`Blocked ${event.sender.getURL()} from calling method: ${method}`)
|
||||
@@ -358,3 +362,5 @@ handleMessageSync('ELECTRON_GUEST_WINDOW_MANAGER_WEB_CONTENTS_METHOD', (event, g
|
||||
|
||||
return guestContents[method](...args)
|
||||
})
|
||||
|
||||
exports.internalWindowOpen = internalWindowOpen
|
||||
|
||||
@@ -195,13 +195,14 @@ app.on('window-all-closed', () => {
|
||||
}
|
||||
})
|
||||
|
||||
Promise.all([
|
||||
import('@electron/internal/browser/default-menu'),
|
||||
app.whenReady()
|
||||
]).then(([{ setDefaultApplicationMenu }]) => {
|
||||
// Create default menu
|
||||
setDefaultApplicationMenu()
|
||||
})
|
||||
const { setDefaultApplicationMenu } = require('@electron/internal/browser/default-menu')
|
||||
|
||||
// Create default menu.
|
||||
//
|
||||
// Note that the task must be added before loading any app, so we can make sure
|
||||
// the call is maded before any user window is created, otherwise the default
|
||||
// menu may show even when user explicitly hides the menu.
|
||||
app.once('ready', setDefaultApplicationMenu)
|
||||
|
||||
if (packagePath) {
|
||||
// Finally load app's main.js and transfer control to C++.
|
||||
|
||||
@@ -152,7 +152,8 @@ const NavigationController = (function () {
|
||||
NavigationController.prototype.reloadIgnoringCache = function () {
|
||||
this.pendingIndex = this.currentIndex
|
||||
return this.webContents._loadURL(this.getURL(), {
|
||||
extraHeaders: 'pragma: no-cache\n'
|
||||
extraHeaders: 'pragma: no-cache\n',
|
||||
reloadIgnoringCache: true
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@@ -127,6 +127,10 @@ class ObjectsRegistry {
|
||||
this.clear(webContents, contextId)
|
||||
}
|
||||
}
|
||||
// Note that the "render-view-deleted" event may not be emitted on time when
|
||||
// the renderer process get destroyed because of navigation, we rely on the
|
||||
// renderer process to send "ELECTRON_BROWSER_CONTEXT_RELEASE" message to
|
||||
// guard this situation.
|
||||
webContents.on('render-view-deleted' as any, listener)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@ import { EventEmitter } from 'events'
|
||||
import objectsRegistry from './objects-registry'
|
||||
import { ipcMainInternal } from '../ipc-main-internal'
|
||||
import * as guestViewManager from '@electron/internal/browser/guest-view-manager'
|
||||
import { isPromise, isSerializableObject } from '@electron/internal/common/remote/type-utils'
|
||||
import { isPromise, isSerializableObject } from '@electron/internal/common/type-utils'
|
||||
|
||||
const v8Util = process.electronBinding('v8_util')
|
||||
const eventBinding = process.electronBinding('event')
|
||||
@@ -245,6 +245,17 @@ type MetaTypeFromRenderer = {
|
||||
length: number
|
||||
}
|
||||
|
||||
const fakeConstructor = (constructor: Function, name: string) =>
|
||||
new Proxy(Object, {
|
||||
get (target, prop, receiver) {
|
||||
if (prop === 'name') {
|
||||
return name
|
||||
} else {
|
||||
return Reflect.get(target, prop, receiver)
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
// 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 metaToValue = function (meta: MetaTypeFromRenderer): any {
|
||||
@@ -262,8 +273,9 @@ const unwrapArgs = function (sender: electron.WebContents, frameId: number, cont
|
||||
then: metaToValue(meta.then)
|
||||
})
|
||||
case 'object': {
|
||||
const ret: any = {}
|
||||
Object.defineProperty(ret.constructor, 'name', { value: meta.name })
|
||||
const ret: any = meta.name !== 'Object' ? Object.create({
|
||||
constructor: fakeConstructor(Object, meta.name)
|
||||
}) : {}
|
||||
|
||||
for (const { name, value } of meta.members) {
|
||||
ret[name] = metaToValue(value)
|
||||
@@ -297,7 +309,7 @@ const unwrapArgs = function (sender: electron.WebContents, frameId: number, cont
|
||||
v8Util.setHiddenValue(callIntoRenderer, 'location', meta.location)
|
||||
Object.defineProperty(callIntoRenderer, 'length', { value: meta.length })
|
||||
|
||||
v8Util.setRemoteCallbackFreer(callIntoRenderer, contextId, meta.id, sender)
|
||||
v8Util.setRemoteCallbackFreer(callIntoRenderer, frameId, contextId, meta.id, sender)
|
||||
rendererFunctions.set(objectId, callIntoRenderer)
|
||||
return callIntoRenderer
|
||||
}
|
||||
@@ -529,7 +541,6 @@ handleRemoteCommand('ELECTRON_BROWSER_DEREFERENCE', function (event, contextId,
|
||||
|
||||
handleRemoteCommand('ELECTRON_BROWSER_CONTEXT_RELEASE', (event, contextId) => {
|
||||
objectsRegistry.clear(event.sender, contextId)
|
||||
return null
|
||||
})
|
||||
|
||||
handleRemoteCommand('ELECTRON_BROWSER_GUEST_WEB_CONTENTS', function (event, contextId, guestInstanceId, stack) {
|
||||
|
||||
@@ -11,7 +11,7 @@ const { crashReporterInit } = require('@electron/internal/browser/crash-reporter
|
||||
const { ipcMainInternal } = require('@electron/internal/browser/ipc-main-internal')
|
||||
const ipcMainUtils = require('@electron/internal/browser/ipc-main-internal-utils')
|
||||
const guestViewManager = require('@electron/internal/browser/guest-view-manager')
|
||||
const clipboardUtils = require('@electron/internal/common/clipboard-utils')
|
||||
const typeUtils = require('@electron/internal/common/type-utils')
|
||||
|
||||
const emitCustomEvent = function (contents, eventName, ...args) {
|
||||
const event = eventBinding.createWithSender(contents)
|
||||
@@ -62,7 +62,7 @@ ipcMainUtils.handleSync('ELECTRON_BROWSER_CLIPBOARD', function (event, method, .
|
||||
throw new Error(`Invalid method: ${method}`)
|
||||
}
|
||||
|
||||
return clipboardUtils.serialize(electron.clipboard[method](...clipboardUtils.deserialize(args)))
|
||||
return typeUtils.serialize(electron.clipboard[method](...typeUtils.deserialize(args)))
|
||||
})
|
||||
|
||||
if (features.isDesktopCapturerEnabled()) {
|
||||
@@ -112,11 +112,15 @@ ipcMainUtils.handleSync('ELECTRON_BROWSER_SANDBOX_LOAD', async function (event)
|
||||
contentScripts = getContentScripts()
|
||||
}
|
||||
|
||||
const webPreferences = event.sender.getLastWebPreferences() || {}
|
||||
|
||||
return {
|
||||
contentScripts,
|
||||
preloadScripts: await Promise.all(preloadPaths.map(path => getPreloadScript(path))),
|
||||
isRemoteModuleEnabled: isRemoteModuleEnabled(event.sender),
|
||||
isWebViewTagEnabled: guestViewManager.isWebViewTagEnabled(event.sender),
|
||||
guestInstanceId: webPreferences.guestInstanceId,
|
||||
openerId: webPreferences.openerId,
|
||||
process: {
|
||||
arch: process.arch,
|
||||
platform: process.platform,
|
||||
|
||||
@@ -4,13 +4,13 @@ const clipboard = process.electronBinding('clipboard')
|
||||
|
||||
if (process.type === 'renderer') {
|
||||
const ipcRendererUtils = require('@electron/internal/renderer/ipc-renderer-internal-utils')
|
||||
const clipboardUtils = require('@electron/internal/common/clipboard-utils')
|
||||
const typeUtils = require('@electron/internal/common/type-utils')
|
||||
|
||||
const makeRemoteMethod = function (method) {
|
||||
return (...args) => {
|
||||
args = clipboardUtils.serialize(args)
|
||||
args = typeUtils.serialize(args)
|
||||
const result = ipcRendererUtils.invokeSync('ELECTRON_BROWSER_CLIPBOARD', method, ...args)
|
||||
return clipboardUtils.deserialize(result)
|
||||
return typeUtils.deserialize(result)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -8,6 +8,8 @@
|
||||
const path = require('path')
|
||||
const util = require('util')
|
||||
|
||||
const Promise = global.Promise
|
||||
|
||||
const envNoAsar = process.env.ELECTRON_NO_ASAR &&
|
||||
process.type !== 'browser' &&
|
||||
process.type !== 'renderer'
|
||||
|
||||
@@ -54,7 +54,12 @@ class CrashReporter {
|
||||
}
|
||||
|
||||
getUploadedReports () {
|
||||
return binding.getUploadedReports(this.getCrashesDirectory())
|
||||
const crashDir = this.getCrashesDirectory()
|
||||
if (!crashDir) {
|
||||
throw new Error('crashReporter has not been started')
|
||||
}
|
||||
|
||||
return binding.getUploadedReports(crashDir)
|
||||
}
|
||||
|
||||
getCrashesDirectory () {
|
||||
|
||||
@@ -1,25 +0,0 @@
|
||||
export function isPromise (val: any) {
|
||||
return (
|
||||
val &&
|
||||
val.then &&
|
||||
val.then instanceof Function &&
|
||||
val.constructor &&
|
||||
val.constructor.reject &&
|
||||
val.constructor.reject instanceof Function &&
|
||||
val.constructor.resolve &&
|
||||
val.constructor.resolve instanceof Function
|
||||
)
|
||||
}
|
||||
|
||||
const serializableTypes = [
|
||||
Boolean,
|
||||
Number,
|
||||
String,
|
||||
Date,
|
||||
RegExp,
|
||||
ArrayBuffer
|
||||
]
|
||||
|
||||
export function isSerializableObject (value: any) {
|
||||
return value === null || ArrayBuffer.isView(value) || serializableTypes.some(type => value instanceof type)
|
||||
}
|
||||
@@ -1,5 +1,32 @@
|
||||
const { nativeImage, NativeImage } = process.electronBinding('native_image')
|
||||
|
||||
export function isPromise (val: any) {
|
||||
return (
|
||||
val &&
|
||||
val.then &&
|
||||
val.then instanceof Function &&
|
||||
val.constructor &&
|
||||
val.constructor.reject &&
|
||||
val.constructor.reject instanceof Function &&
|
||||
val.constructor.resolve &&
|
||||
val.constructor.resolve instanceof Function
|
||||
)
|
||||
}
|
||||
|
||||
const serializableTypes = [
|
||||
Boolean,
|
||||
Number,
|
||||
String,
|
||||
Date,
|
||||
Error,
|
||||
RegExp,
|
||||
ArrayBuffer
|
||||
]
|
||||
|
||||
export function isSerializableObject (value: any) {
|
||||
return value === null || ArrayBuffer.isView(value) || serializableTypes.some(type => value instanceof type)
|
||||
}
|
||||
|
||||
const objectMap = function (source: Object, mapper: (value: any) => any) {
|
||||
const sourceEntries = Object.entries(source)
|
||||
const targetEntries = sourceEntries.map(([key, val]) => [key, mapper(val)])
|
||||
@@ -15,7 +42,7 @@ export function serialize (value: any): any {
|
||||
}
|
||||
} else if (Array.isArray(value)) {
|
||||
return value.map(serialize)
|
||||
} else if (value instanceof Buffer) {
|
||||
} else if (isSerializableObject(value)) {
|
||||
return value
|
||||
} else if (value instanceof Object) {
|
||||
return objectMap(value, serialize)
|
||||
@@ -29,7 +56,7 @@ export function deserialize (value: any): any {
|
||||
return nativeImage.createFromBitmap(value.buffer, value.size)
|
||||
} else if (Array.isArray(value)) {
|
||||
return value.map(deserialize)
|
||||
} else if (value instanceof Buffer) {
|
||||
} else if (isSerializableObject(value)) {
|
||||
return value
|
||||
} else if (value instanceof Object) {
|
||||
return objectMap(value, deserialize)
|
||||
@@ -52,7 +52,6 @@ export const syncMethods = new Set([
|
||||
|
||||
export const asyncMethods = new Set([
|
||||
'loadURL',
|
||||
'capturePage',
|
||||
'executeJavaScript',
|
||||
'insertCSS',
|
||||
'insertText',
|
||||
|
||||
8
lib/common/webpack-globals-provider.ts
Normal file
8
lib/common/webpack-globals-provider.ts
Normal file
@@ -0,0 +1,8 @@
|
||||
// Captures original globals into a scope to ensure that userland modifications do
|
||||
// not impact Electron. Note that users doing:
|
||||
//
|
||||
// global.Promise.resolve = myFn
|
||||
//
|
||||
// Will mutate this captured one as well and that is OK.
|
||||
|
||||
export const Promise = global.Promise
|
||||
20
lib/renderer/api/context-bridge.ts
Normal file
20
lib/renderer/api/context-bridge.ts
Normal file
@@ -0,0 +1,20 @@
|
||||
const { hasSwitch } = process.electronBinding('command_line')
|
||||
const binding = process.electronBinding('context_bridge')
|
||||
|
||||
const contextIsolationEnabled = hasSwitch('context-isolation')
|
||||
|
||||
const checkContextIsolationEnabled = () => {
|
||||
if (!contextIsolationEnabled) throw new Error('contextBridge API can only be used when contextIsolation is enabled')
|
||||
}
|
||||
|
||||
const contextBridge = {
|
||||
exposeInMainWorld: (key: string, api: Record<string, any>) => {
|
||||
checkContextIsolationEnabled()
|
||||
return binding.exposeAPIInMainWorld(key, api)
|
||||
},
|
||||
debugGC: () => binding._debugGCMaps({})
|
||||
}
|
||||
|
||||
if (!binding._debugGCMaps) delete contextBridge.debugGC
|
||||
|
||||
export default contextBridge
|
||||
@@ -2,5 +2,7 @@ import { defineProperties } from '@electron/internal/common/define-properties'
|
||||
import { commonModuleList } from '@electron/internal/common/api/module-list'
|
||||
import { rendererModuleList } from '@electron/internal/renderer/api/module-list'
|
||||
|
||||
defineProperties(exports, commonModuleList)
|
||||
defineProperties(exports, rendererModuleList)
|
||||
module.exports = {}
|
||||
|
||||
defineProperties(module.exports, commonModuleList)
|
||||
defineProperties(module.exports, rendererModuleList)
|
||||
|
||||
@@ -5,6 +5,7 @@ const enableRemoteModule = v8Util.getHiddenValue<boolean>(global, 'enableRemoteM
|
||||
|
||||
// Renderer side modules, please sort alphabetically.
|
||||
export const rendererModuleList: ElectronInternal.ModuleEntry[] = [
|
||||
{ name: 'contextBridge', loader: () => require('./context-bridge') },
|
||||
{ name: 'crashReporter', loader: () => require('./crash-reporter') },
|
||||
{ name: 'ipcRenderer', loader: () => require('./ipc-renderer') },
|
||||
{ name: 'webFrame', loader: () => require('./web-frame') }
|
||||
|
||||
@@ -4,7 +4,7 @@ const v8Util = process.electronBinding('v8_util')
|
||||
const { hasSwitch } = process.electronBinding('command_line')
|
||||
|
||||
const { CallbacksRegistry } = require('@electron/internal/renderer/remote/callbacks-registry')
|
||||
const { isPromise, isSerializableObject } = require('@electron/internal/common/remote/type-utils')
|
||||
const { isPromise, isSerializableObject } = require('@electron/internal/common/type-utils')
|
||||
const { ipcRendererInternal } = require('@electron/internal/renderer/ipc-renderer-internal')
|
||||
|
||||
const callbacksRegistry = new CallbacksRegistry()
|
||||
@@ -19,7 +19,7 @@ const contextId = v8Util.getHiddenValue(global, 'contextId')
|
||||
// to guard that situation.
|
||||
process.on('exit', () => {
|
||||
const command = 'ELECTRON_BROWSER_CONTEXT_RELEASE'
|
||||
ipcRendererInternal.sendSync(command, contextId)
|
||||
ipcRendererInternal.send(command, contextId)
|
||||
})
|
||||
|
||||
// Convert the arguments object into an array of meta data.
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
import { EventEmitter } from 'events'
|
||||
import { deprecate } from 'electron'
|
||||
|
||||
const binding = process.electronBinding('web_frame')
|
||||
|
||||
const setLayoutZoomLevelLimitsWarning = deprecate.warnOnce('setLayoutZoomLevelLimits')
|
||||
|
||||
class WebFrame extends EventEmitter {
|
||||
constructor (public context: Window) {
|
||||
super()
|
||||
@@ -45,6 +48,10 @@ class WebFrame extends EventEmitter {
|
||||
get routingId () {
|
||||
return binding._getRoutingId(this.context)
|
||||
}
|
||||
|
||||
setLayoutZoomLevelLimits () {
|
||||
setLayoutZoomLevelLimitsWarning()
|
||||
}
|
||||
}
|
||||
|
||||
// Populate the methods.
|
||||
|
||||
@@ -120,7 +120,11 @@ export function injectTo (extensionId: string, context: any) {
|
||||
let targetExtensionId = extensionId
|
||||
let connectInfo = { name: '' }
|
||||
if (args.length === 1) {
|
||||
targetExtensionId = args[0]
|
||||
if (typeof args[0] === 'string') {
|
||||
targetExtensionId = args[0]
|
||||
} else {
|
||||
connectInfo = args[0]
|
||||
}
|
||||
} else if (args.length === 2) {
|
||||
[targetExtensionId, connectInfo] = args
|
||||
}
|
||||
|
||||
@@ -192,6 +192,8 @@ if (nodeIntegration) {
|
||||
delete global.setImmediate
|
||||
delete global.clearImmediate
|
||||
delete global.global
|
||||
delete global.root
|
||||
delete global.GLOBAL
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ import * as ipcRendererUtils from '@electron/internal/renderer/ipc-renderer-inte
|
||||
import * as guestViewInternal from '@electron/internal/renderer/web-view/guest-view-internal'
|
||||
import { WEB_VIEW_CONSTANTS } from '@electron/internal/renderer/web-view/web-view-constants'
|
||||
import { syncMethods, asyncMethods } from '@electron/internal/common/web-view-methods'
|
||||
import { deserialize } from '@electron/internal/common/type-utils'
|
||||
const { webFrame } = electron
|
||||
|
||||
const v8Util = process.electronBinding('v8_util')
|
||||
@@ -238,6 +239,12 @@ export const setupMethods = (WebViewElement: typeof ElectronInternal.WebViewElem
|
||||
return remote.getGuestWebContents(internal.guestInstanceId!)
|
||||
}
|
||||
|
||||
WebViewElement.prototype.getWebContents = electron.deprecate.moveAPI(
|
||||
WebViewElement.prototype.getWebContents,
|
||||
'webview.getWebContents()',
|
||||
'remote.webContents.fromId(webview.getWebContentsId())'
|
||||
) as any
|
||||
|
||||
// Focusing the webview should move page focus to the underlying iframe.
|
||||
WebViewElement.prototype.focus = function () {
|
||||
this.contentWindow.focus()
|
||||
@@ -263,6 +270,10 @@ export const setupMethods = (WebViewElement: typeof ElectronInternal.WebViewElem
|
||||
for (const method of asyncMethods) {
|
||||
(WebViewElement.prototype as Record<string, any>)[method] = createNonBlockHandler(method)
|
||||
}
|
||||
|
||||
WebViewElement.prototype.capturePage = async function (...args) {
|
||||
return deserialize(await ipcRendererInternal.invoke('ELECTRON_GUEST_VIEW_MANAGER_CAPTURE_PAGE', this.getWebContentsId(), args))
|
||||
}
|
||||
}
|
||||
|
||||
export const webViewImplModule = {
|
||||
|
||||
@@ -28,19 +28,19 @@ const toString = (value: any) => {
|
||||
return value != null ? `${value}` : value
|
||||
}
|
||||
|
||||
const windowProxies: Record<number, BrowserWindowProxy> = {}
|
||||
const windowProxies = new Map<number, BrowserWindowProxy>()
|
||||
|
||||
const getOrCreateProxy = (guestId: number) => {
|
||||
let proxy = windowProxies[guestId]
|
||||
let proxy = windowProxies.get(guestId)
|
||||
if (proxy == null) {
|
||||
proxy = new BrowserWindowProxy(guestId)
|
||||
windowProxies[guestId] = proxy
|
||||
windowProxies.set(guestId, proxy)
|
||||
}
|
||||
return proxy
|
||||
}
|
||||
|
||||
const removeProxy = (guestId: number) => {
|
||||
delete windowProxies[guestId]
|
||||
windowProxies.delete(guestId)
|
||||
}
|
||||
|
||||
type LocationProperties = 'hash' | 'href' | 'host' | 'hostname' | 'origin' | 'pathname' | 'port' | 'protocol' | 'search'
|
||||
@@ -177,7 +177,7 @@ class BrowserWindowProxy {
|
||||
export const windowSetup = (
|
||||
guestInstanceId: number, openerId: number, isHiddenPage: boolean, usesNativeWindowOpen: boolean
|
||||
) => {
|
||||
if (guestInstanceId == null) {
|
||||
if (!process.sandboxed && guestInstanceId == null) {
|
||||
// Override default window.close.
|
||||
window.close = function () {
|
||||
ipcRendererInternal.sendSync('ELECTRON_BROWSER_WINDOW_CLOSE')
|
||||
@@ -197,10 +197,10 @@ export const windowSetup = (
|
||||
return null
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (openerId != null) {
|
||||
window.opener = getOrCreateProxy(openerId)
|
||||
}
|
||||
if (openerId != null) {
|
||||
window.opener = getOrCreateProxy(openerId)
|
||||
}
|
||||
|
||||
// But we do not support prompt().
|
||||
@@ -208,42 +208,46 @@ export const windowSetup = (
|
||||
throw new Error('prompt() is and will not be supported.')
|
||||
}
|
||||
|
||||
ipcRendererInternal.on('ELECTRON_GUEST_WINDOW_POSTMESSAGE', function (
|
||||
_event, sourceId: number, message: any, sourceOrigin: string
|
||||
) {
|
||||
// Manually dispatch event instead of using postMessage because we also need to
|
||||
// set event.source.
|
||||
//
|
||||
// Why any? We can't construct a MessageEvent and we can't
|
||||
// use `as MessageEvent` because you're not supposed to override
|
||||
// data, origin, and source
|
||||
const event: any = document.createEvent('Event')
|
||||
event.initEvent('message', false, false)
|
||||
if (!usesNativeWindowOpen || openerId != null) {
|
||||
ipcRendererInternal.on('ELECTRON_GUEST_WINDOW_POSTMESSAGE', function (
|
||||
_event, sourceId: number, message: any, sourceOrigin: string
|
||||
) {
|
||||
// Manually dispatch event instead of using postMessage because we also need to
|
||||
// set event.source.
|
||||
//
|
||||
// Why any? We can't construct a MessageEvent and we can't
|
||||
// use `as MessageEvent` because you're not supposed to override
|
||||
// data, origin, and source
|
||||
const event: any = document.createEvent('Event')
|
||||
event.initEvent('message', false, false)
|
||||
|
||||
event.data = message
|
||||
event.origin = sourceOrigin
|
||||
event.source = getOrCreateProxy(sourceId)
|
||||
event.data = message
|
||||
event.origin = sourceOrigin
|
||||
event.source = getOrCreateProxy(sourceId)
|
||||
|
||||
window.dispatchEvent(event as MessageEvent)
|
||||
})
|
||||
|
||||
window.history.back = function () {
|
||||
ipcRendererInternal.send('ELECTRON_NAVIGATION_CONTROLLER_GO_BACK')
|
||||
window.dispatchEvent(event as MessageEvent)
|
||||
})
|
||||
}
|
||||
|
||||
window.history.forward = function () {
|
||||
ipcRendererInternal.send('ELECTRON_NAVIGATION_CONTROLLER_GO_FORWARD')
|
||||
}
|
||||
|
||||
window.history.go = function (offset: number) {
|
||||
ipcRendererInternal.send('ELECTRON_NAVIGATION_CONTROLLER_GO_TO_OFFSET', +offset)
|
||||
}
|
||||
|
||||
Object.defineProperty(window.history, 'length', {
|
||||
get: function () {
|
||||
return ipcRendererInternal.sendSync('ELECTRON_NAVIGATION_CONTROLLER_LENGTH')
|
||||
if (!process.sandboxed) {
|
||||
window.history.back = function () {
|
||||
ipcRendererInternal.send('ELECTRON_NAVIGATION_CONTROLLER_GO_BACK')
|
||||
}
|
||||
})
|
||||
|
||||
window.history.forward = function () {
|
||||
ipcRendererInternal.send('ELECTRON_NAVIGATION_CONTROLLER_GO_FORWARD')
|
||||
}
|
||||
|
||||
window.history.go = function (offset: number) {
|
||||
ipcRendererInternal.send('ELECTRON_NAVIGATION_CONTROLLER_GO_TO_OFFSET', +offset)
|
||||
}
|
||||
|
||||
Object.defineProperty(window.history, 'length', {
|
||||
get: function () {
|
||||
return ipcRendererInternal.sendSync('ELECTRON_NAVIGATION_CONTROLLER_LENGTH')
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
if (guestInstanceId != null) {
|
||||
// Webview `document.visibilityState` tracks window visibility (and ignores
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
import { defineProperties } from '@electron/internal/common/define-properties'
|
||||
import { moduleList } from '@electron/internal/sandboxed_renderer/api/module-list'
|
||||
|
||||
defineProperties(exports, moduleList)
|
||||
module.exports = {}
|
||||
|
||||
defineProperties(module.exports, moduleList)
|
||||
|
||||
@@ -1,6 +1,10 @@
|
||||
const features = process.electronBinding('features')
|
||||
|
||||
export const moduleList: ElectronInternal.ModuleEntry[] = [
|
||||
{
|
||||
name: 'contextBridge',
|
||||
loader: () => require('@electron/internal/renderer/api/context-bridge')
|
||||
},
|
||||
{
|
||||
name: 'crashReporter',
|
||||
loader: () => require('@electron/internal/renderer/api/crash-reporter')
|
||||
|
||||
@@ -30,7 +30,13 @@ const { ipcRendererInternal } = require('@electron/internal/renderer/ipc-rendere
|
||||
const ipcRendererUtils = require('@electron/internal/renderer/ipc-renderer-internal-utils')
|
||||
|
||||
const {
|
||||
contentScripts, preloadScripts, isRemoteModuleEnabled, isWebViewTagEnabled, process: processProps
|
||||
contentScripts,
|
||||
preloadScripts,
|
||||
isRemoteModuleEnabled,
|
||||
isWebViewTagEnabled,
|
||||
guestInstanceId,
|
||||
openerId,
|
||||
process: processProps
|
||||
} = ipcRendererUtils.invokeSync('ELECTRON_BROWSER_SANDBOX_LOAD')
|
||||
|
||||
process.isRemoteModuleEnabled = isRemoteModuleEnabled
|
||||
@@ -94,6 +100,8 @@ Object.defineProperty(preloadProcess, 'noDeprecation', {
|
||||
|
||||
process.on('loaded', () => preloadProcess.emit('loaded'))
|
||||
process.on('exit', () => preloadProcess.emit('exit'))
|
||||
process.on('document-start', () => preloadProcess.emit('document-start'))
|
||||
process.on('document-end', () => preloadProcess.emit('document-end'))
|
||||
|
||||
// This is the `require` function that will be visible to the preload script
|
||||
function preloadRequire (module) {
|
||||
@@ -107,6 +115,11 @@ function preloadRequire (module) {
|
||||
const { hasSwitch } = process.electronBinding('command_line')
|
||||
|
||||
const contextIsolation = hasSwitch('context-isolation')
|
||||
const isHiddenPage = hasSwitch('hidden-page')
|
||||
const usesNativeWindowOpen = true
|
||||
|
||||
// The arguments to be passed to isolated world.
|
||||
const isolatedWorldArgs = { ipcRendererInternal, guestInstanceId, isHiddenPage, openerId, usesNativeWindowOpen }
|
||||
|
||||
switch (window.location.protocol) {
|
||||
case 'devtools:': {
|
||||
@@ -125,6 +138,10 @@ switch (window.location.protocol) {
|
||||
break
|
||||
}
|
||||
default: {
|
||||
// Override default web functions.
|
||||
const { windowSetup } = require('@electron/internal/renderer/window-setup')
|
||||
windowSetup(guestInstanceId, openerId, isHiddenPage, usesNativeWindowOpen)
|
||||
|
||||
// Inject content scripts.
|
||||
if (!process.electronBinding('features').isExtensionsEnabled()) {
|
||||
require('@electron/internal/renderer/content-scripts-injector')(contentScripts)
|
||||
@@ -132,14 +149,17 @@ switch (window.location.protocol) {
|
||||
}
|
||||
}
|
||||
|
||||
const guestInstanceId = binding.guestInstanceId && parseInt(binding.guestInstanceId)
|
||||
|
||||
// Load webview tag implementation.
|
||||
if (process.isMainFrame) {
|
||||
const { webViewInit } = require('@electron/internal/renderer/web-view/web-view-init')
|
||||
webViewInit(contextIsolation, isWebViewTagEnabled, guestInstanceId)
|
||||
}
|
||||
|
||||
// Pass the arguments to isolatedWorld.
|
||||
if (contextIsolation) {
|
||||
v8Util.setHiddenValue(global, 'isolated-world-args', isolatedWorldArgs)
|
||||
}
|
||||
|
||||
// Wrap the script into a function executed in global scope. It won't have
|
||||
// access to the current scope, so we'll expose a few objects as arguments:
|
||||
//
|
||||
|
||||
@@ -31,7 +31,7 @@ class Arguments {
|
||||
|
||||
template <typename T>
|
||||
bool GetHolder(T* out) {
|
||||
return ConvertFromV8(isolate_, info_->Holder(), out);
|
||||
return mate::ConvertFromV8(isolate_, info_->Holder(), out);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
@@ -57,7 +57,7 @@ class Arguments {
|
||||
return false;
|
||||
}
|
||||
v8::Local<v8::Value> val = (*info_)[next_];
|
||||
bool success = ConvertFromV8(isolate_, val, out);
|
||||
bool success = mate::ConvertFromV8(isolate_, val, out);
|
||||
if (success)
|
||||
next_++;
|
||||
return success;
|
||||
|
||||
@@ -40,6 +40,12 @@ class Dictionary {
|
||||
|
||||
static Dictionary CreateEmpty(v8::Isolate* isolate);
|
||||
|
||||
bool Has(base::StringPiece key) const {
|
||||
v8::Local<v8::Context> context = isolate_->GetCurrentContext();
|
||||
v8::Local<v8::String> v8_key = StringToV8(isolate_, key);
|
||||
return internal::IsTrue(GetHandle()->Has(context, v8_key));
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
bool Get(base::StringPiece key, T* out) const {
|
||||
// Check for existence before getting, otherwise this method will always
|
||||
@@ -76,6 +82,17 @@ class Dictionary {
|
||||
return !result.IsNothing() && result.FromJust();
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
bool SetReadOnlyNonConfigurable(base::StringPiece key, T val) {
|
||||
v8::Local<v8::Value> v8_value;
|
||||
if (!TryConvertToV8(isolate_, val, &v8_value))
|
||||
return false;
|
||||
v8::Maybe<bool> result = GetHandle()->DefineOwnProperty(
|
||||
isolate_->GetCurrentContext(), StringToV8(isolate_, key), v8_value,
|
||||
static_cast<v8::PropertyAttribute>(v8::ReadOnly | v8::DontDelete));
|
||||
return !result.IsNothing() && result.FromJust();
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
bool SetMethod(base::StringPiece key, const T& callback) {
|
||||
return GetHandle()
|
||||
|
||||
@@ -5,6 +5,8 @@
|
||||
#ifndef NATIVE_MATE_NATIVE_MATE_FUNCTION_TEMPLATE_H_
|
||||
#define NATIVE_MATE_NATIVE_MATE_FUNCTION_TEMPLATE_H_
|
||||
|
||||
#include <utility>
|
||||
|
||||
#include "base/callback.h"
|
||||
#include "native_mate/arguments.h"
|
||||
#include "native_mate/wrappable_base.h"
|
||||
@@ -194,7 +196,8 @@ class Invoker<IndicesHolder<indices...>, ArgTypes...>
|
||||
void DispatchToCallback(base::Callback<ReturnType(ArgTypes...)> callback) {
|
||||
v8::MicrotasksScope script_scope(args_->isolate(),
|
||||
v8::MicrotasksScope::kRunMicrotasks);
|
||||
args_->Return(callback.Run(ArgumentHolder<indices, ArgTypes>::value...));
|
||||
args_->Return(
|
||||
callback.Run(std::move(ArgumentHolder<indices, ArgTypes>::value)...));
|
||||
}
|
||||
|
||||
// In C++, you can declare the function foo(void), but you can't pass a void
|
||||
@@ -203,7 +206,7 @@ class Invoker<IndicesHolder<indices...>, ArgTypes...>
|
||||
void DispatchToCallback(base::Callback<void(ArgTypes...)> callback) {
|
||||
v8::MicrotasksScope script_scope(args_->isolate(),
|
||||
v8::MicrotasksScope::kRunMicrotasks);
|
||||
callback.Run(ArgumentHolder<indices, ArgTypes>::value...);
|
||||
callback.Run(std::move(ArgumentHolder<indices, ArgTypes>::value)...);
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
@@ -34,4 +34,18 @@ struct Converter<PersistentDictionary> {
|
||||
|
||||
} // namespace mate
|
||||
|
||||
namespace gin {
|
||||
|
||||
// Keep compatibility with gin.
|
||||
template <>
|
||||
struct Converter<mate::PersistentDictionary> {
|
||||
static bool FromV8(v8::Isolate* isolate,
|
||||
v8::Local<v8::Value> val,
|
||||
mate::PersistentDictionary* out) {
|
||||
return mate::ConvertFromV8(isolate, val, out);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace gin
|
||||
|
||||
#endif // NATIVE_MATE_NATIVE_MATE_PERSISTENT_DICTIONARY_H_
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
{
|
||||
"name": "electron",
|
||||
"version": "8.0.0-nightly.20191016",
|
||||
"version": "8.0.0-beta.6",
|
||||
"repository": "https://github.com/electron/electron",
|
||||
"description": "Build cross platform desktop apps with JavaScript, HTML, and CSS",
|
||||
"devDependencies": {
|
||||
"@electron/docs-parser": "^0.4.2",
|
||||
"@electron/typescript-definitions": "^8.6.1",
|
||||
"@electron/typescript-definitions": "^8.6.4",
|
||||
"@octokit/rest": "^16.3.2",
|
||||
"@primer/octicons": "^9.1.1",
|
||||
"@types/basic-auth": "^1.1.2",
|
||||
@@ -129,6 +129,9 @@
|
||||
"node script/gen-filenames.js",
|
||||
"python script/check-trailing-whitespace.py --fix",
|
||||
"git add filenames.auto.gni"
|
||||
],
|
||||
"DEPS": [
|
||||
"node script/gen-hunspell-filenames.js"
|
||||
]
|
||||
},
|
||||
"dependencies": {
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
gles2_use_constant_initialization_for_g_mutex.patch
|
||||
@@ -1,60 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Jaime Bernardo <jaime@janeasystems.com>
|
||||
Date: Mon, 30 Sep 2019 17:53:56 +0100
|
||||
Subject: GLES2: Use require_constant_initialization for g_Mutex
|
||||
|
||||
A static assert to verify that the global mutex g_Mutex is trivially
|
||||
constructed fails to compile with clang when using the STL shipped
|
||||
with Visual Studio 2019.
|
||||
|
||||
Use __attribute__((require_constant_initialization)) instead to verify
|
||||
for constant initialization.
|
||||
|
||||
BUG=angleproject:3936
|
||||
|
||||
Change-Id: I5969762ad5a99033143513d7c4992344da276b1a
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/1832164
|
||||
Reviewed-by: Jamie Madill <jmadill@chromium.org>
|
||||
Reviewed-by: Geoff Lang <geofflang@chromium.org>
|
||||
Commit-Queue: Geoff Lang <geofflang@chromium.org>
|
||||
|
||||
diff --git a/AUTHORS b/AUTHORS
|
||||
index ab39ee01a47c15da57b531d2c711649f1685091b..7a0f3b32b101b34195c57637b227062d9b173d6a 100644
|
||||
--- a/AUTHORS
|
||||
+++ b/AUTHORS
|
||||
@@ -58,3 +58,4 @@ Jérôme Duval
|
||||
Thomas Miller
|
||||
Till Rathmann
|
||||
Nick Shaforostov
|
||||
+Jaime Bernardo
|
||||
diff --git a/src/common/angleutils.h b/src/common/angleutils.h
|
||||
index 131d5796da4399df1144bc349c506cde8220973a..3a1391e29b72e7ec356e44c7ced202cc29773fb3 100644
|
||||
--- a/src/common/angleutils.h
|
||||
+++ b/src/common/angleutils.h
|
||||
@@ -345,4 +345,10 @@ std::string ToString(const T &value)
|
||||
# define ANGLE_MAYBE_UNUSED
|
||||
#endif // __has_cpp_attribute(maybe_unused)
|
||||
|
||||
+#if __has_cpp_attribute(require_constant_initialization)
|
||||
+# define ANGLE_REQUIRE_CONSTANT_INIT [[require_constant_initialization]]
|
||||
+#else
|
||||
+# define ANGLE_REQUIRE_CONSTANT_INIT
|
||||
+#endif // __has_cpp_attribute(require_constant_initialization)
|
||||
+
|
||||
#endif // COMMON_ANGLEUTILS_H_
|
||||
diff --git a/src/libGLESv2/global_state.cpp b/src/libGLESv2/global_state.cpp
|
||||
index 8ea912eea045c912ef64dfedcfd8f07db4337a9d..c8c9a732fbad5cc50ed2a7fc4b5387a30274435b 100644
|
||||
--- a/src/libGLESv2/global_state.cpp
|
||||
+++ b/src/libGLESv2/global_state.cpp
|
||||
@@ -35,9 +35,8 @@ namespace
|
||||
{
|
||||
static TLSIndex threadTLS = TLS_INVALID_INDEX;
|
||||
Debug *g_Debug = nullptr;
|
||||
-std::atomic<std::mutex *> g_Mutex;
|
||||
-static_assert(std::is_trivially_constructible<decltype(g_Mutex)>::value,
|
||||
- "global mutex is not trivially constructible");
|
||||
+
|
||||
+ANGLE_REQUIRE_CONSTANT_INIT std::atomic<std::mutex *> g_Mutex(nullptr);
|
||||
static_assert(std::is_trivially_destructible<decltype(g_Mutex)>::value,
|
||||
"global mutex is not trivially destructible");
|
||||
|
||||
@@ -1,2 +1,3 @@
|
||||
expose_ripemd160.patch
|
||||
expose_aes-cfb.patch
|
||||
fix_add_RSA-PSS_keygen_functions.patch
|
||||
@@ -80,7 +80,7 @@ index d540144b293297791c087e0b968a47d368a73695..53cb9d2dc8f1962a70dc12b648d27c32
|
||||
+ callback(EVP_ripemd160(), "ripemd160", NULL, arg);
|
||||
}
|
||||
diff --git a/include/openssl/digest.h b/include/openssl/digest.h
|
||||
index c7c679760a30329311b4a6c0db475b2375537028..991fa00b8330a663625719436075bcc8ae32e17a 100644
|
||||
index c3ceb7f22a123353f23cb33de9cc2931fb5e1c11..704d43a326e7cced925c9db1c2a6094a16f9abe9 100644
|
||||
--- a/include/openssl/digest.h
|
||||
+++ b/include/openssl/digest.h
|
||||
@@ -88,6 +88,9 @@ OPENSSL_EXPORT const EVP_MD *EVP_sha512(void);
|
||||
|
||||
33
patches/boringssl/fix_add_RSA-PSS_keygen_functions.patch
Normal file
33
patches/boringssl/fix_add_RSA-PSS_keygen_functions.patch
Normal file
@@ -0,0 +1,33 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Shelley Vohr <shelley.vohr@gmail.com>
|
||||
Date: Wed, 23 Oct 2019 12:54:32 -0700
|
||||
Subject: fix: add RSA-PSS keygen functions
|
||||
|
||||
This adds support for missing RSA_PSS key generation functions.
|
||||
Refs https://github.com/nodejs/node/pull/26960.
|
||||
|
||||
Upstreamed at https://boringssl-review.googlesource.com/c/boringssl/+/38524.
|
||||
|
||||
diff --git a/include/openssl/evp.h b/include/openssl/evp.h
|
||||
index 19baa64ddba84c3dd59e65aef77d1ebbf49e43df..37217c49f7e05eb25562023bf356fdadae1bc66f 100644
|
||||
--- a/include/openssl/evp.h
|
||||
+++ b/include/openssl/evp.h
|
||||
@@ -723,6 +723,18 @@ OPENSSL_EXPORT int EVP_PKEY_CTX_set_rsa_padding(EVP_PKEY_CTX *ctx, int padding);
|
||||
OPENSSL_EXPORT int EVP_PKEY_CTX_get_rsa_padding(EVP_PKEY_CTX *ctx,
|
||||
int *out_padding);
|
||||
|
||||
+// EVP_PKEY_CTX_set_rsa_pss_keygen_md() always returns 0.
|
||||
+OPENSSL_EXPORT int EVP_PKEY_CTX_set_rsa_pss_keygen_md(EVP_PKEY_CTX *ctx,
|
||||
+ const EVP_MD *md);
|
||||
+
|
||||
+// EVP_PKEY_CTX_set_rsa_pss_keygen_saltlen() always returns 0.
|
||||
+OPENSSL_EXPORT int EVP_PKEY_CTX_set_rsa_pss_keygen_saltlen(EVP_PKEY_CTX *ctx,
|
||||
+ int salt_len);
|
||||
+
|
||||
+// EVP_PKEY_CTX_set_rsa_pss_keygen_mgf1_md() always returns 0.
|
||||
+OPENSSL_EXPORT int EVP_PKEY_CTX_set_rsa_pss_keygen_mgf1_md(EVP_PKEY_CTX *ctx,
|
||||
+ const EVP_MD *md);
|
||||
+
|
||||
// EVP_PKEY_CTX_set_rsa_pss_saltlen sets the length of the salt in a PSS-padded
|
||||
// signature. A value of -1 cause the salt to be the same length as the digest
|
||||
// in the signature. A value of -2 causes the salt to be the maximum length
|
||||
@@ -0,0 +1,30 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Charles Kerr <ckerr@github.com>
|
||||
Date: Fri, 15 Nov 2019 17:14:54 -0600
|
||||
Subject: chore: fix FTBFS from stl features used but not included
|
||||
|
||||
|
||||
diff --git a/src/common/windows/pe_util.cc b/src/common/windows/pe_util.cc
|
||||
index 6fa63fa3b5699b79d3479c6d4a37a1c68553223f..59c1c1d74f70dca8f871fdddd8e27da102ec9148 100644
|
||||
--- a/src/common/windows/pe_util.cc
|
||||
+++ b/src/common/windows/pe_util.cc
|
||||
@@ -119,7 +119,6 @@ private:
|
||||
|
||||
namespace google_breakpad {
|
||||
|
||||
-using std::unique_ptr;
|
||||
using google_breakpad::GUIDString;
|
||||
|
||||
bool ReadModuleInfo(const wstring & pe_file, PDBModuleInfo * info) {
|
||||
diff --git a/src/tools/windows/dump_syms/dump_syms.cc b/src/tools/windows/dump_syms/dump_syms.cc
|
||||
index 5b7d1777538cd3cfefd0bef45558f900798d6c51..2b2fdaf3f908db1d6f3f96a6bc23f0698cf879dc 100644
|
||||
--- a/src/tools/windows/dump_syms/dump_syms.cc
|
||||
+++ b/src/tools/windows/dump_syms/dump_syms.cc
|
||||
@@ -41,7 +41,6 @@
|
||||
using std::wstring;
|
||||
using google_breakpad::PDBSourceLineWriter;
|
||||
using google_breakpad::PESourceLineWriter;
|
||||
-using std::unique_ptr;
|
||||
|
||||
int wmain(int argc, wchar_t **argv) {
|
||||
bool success;
|
||||
@@ -34,13 +34,12 @@ scroll_bounce_flag.patch
|
||||
mas-cfisobjc.patch
|
||||
mas-cgdisplayusesforcetogray.patch
|
||||
mas-audiodeviceduck.patch
|
||||
mas-lssetapplicationlaunchservicesserverconnectionstatus.patch
|
||||
ignore_rc_check.patch
|
||||
mas_disable_remote_accessibility.patch
|
||||
mas_disable_custom_window_frame.patch
|
||||
chrome_key_systems.patch
|
||||
allow_nested_error_trackers.patch
|
||||
blink_initialization_order.patch
|
||||
ssl_security_state_tab_helper.patch
|
||||
exclude-a-few-test-files-from-build.patch
|
||||
desktop_media_list.patch
|
||||
proxy_config_monitor.patch
|
||||
gritsettings_resource_ids.patch
|
||||
@@ -60,7 +59,6 @@ fix_disable_usage_of_setapplicationisdaemon_and.patch
|
||||
unsandboxed_ppapi_processes_skip_zygote.patch
|
||||
patch_the_ensure_gn_version_py_script_to_work_on_mac_ci.patch
|
||||
build_add_electron_tracing_category.patch
|
||||
disable_custom_libcxx_on_windows.patch
|
||||
worker_context_will_destroy.patch
|
||||
fix_breakpad_symbol_generation_on_linux_arm.patch
|
||||
frame_host_manager.patch
|
||||
@@ -68,7 +66,6 @@ crashpad_pid_check.patch
|
||||
preconnect_feature.patch
|
||||
network_service_allow_remote_certificate_verification_logic.patch
|
||||
put_back_deleted_colors_for_autofill.patch
|
||||
build_win_disable_zc_twophase.patch
|
||||
disable_color_correct_rendering.patch
|
||||
add_contentgpuclient_precreatemessageloop_callback.patch
|
||||
picture-in-picture.patch
|
||||
@@ -77,7 +74,11 @@ allow_new_privileges_in_unsandboxed_child_processes.patch
|
||||
expose_setuseragent_on_networkcontext.patch
|
||||
feat_add_set_theme_source_to_allow_apps_to.patch
|
||||
revert_cleanup_remove_menu_subtitles_sublabels.patch
|
||||
ui_views_fix_jumbo_build.patch
|
||||
export_fetchapi_mojo_traits_to_fix_component_build.patch
|
||||
fix_windows_build.patch
|
||||
build_fix_when_building_with_enable_plugins_false.patch
|
||||
revert_remove_contentrendererclient_shouldfork.patch
|
||||
ignore_rc_check.patch
|
||||
remove_usage_of_incognito_apis_in_the_spellchecker.patch
|
||||
chore_use_electron_resources_not_chrome_for_spellchecker.patch
|
||||
add_trustedauthclient_to_urlloaderfactory.patch
|
||||
feat_allow_disbaling_blink_scheduler_throttling_per_renderview.patch
|
||||
accessible_pane_view.patch
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user