Compare commits

...

24 Commits

Author SHA1 Message Date
Electron Bot
099246f0e4 Bump v10.0.0-nightly.20200209 2020-02-09 07:32:49 -08:00
Samuel Attard
dafbf04b9a fix: use a WeakPtr so we do not UAF the store in FunctionLifetimeMonitor (#22056) 2020-02-08 20:49:38 -08:00
t57ser
43592f8b71 fix: flash plugin (#22072)
* fix: flash plugin

Fixes https://github.com/electron/electron/issues/20744

* cleanup

* fix linting issue
2020-02-08 17:50:07 -08:00
John Kleinschmidt
058222a9f1 build: try using newer version of xcode/macOS sdk (#22104) 2020-02-08 16:38:14 -05:00
Electron Bot
f989faab5c Bump v10.0.0-nightly.20200208 2020-02-08 07:31:55 -08:00
John Kleinschmidt
5e49aafe55 build: preserve timestamps when stripping files (#22094)
* build: preserve timestamps when stripping files

Resolves an issue where the binaries in mksnapshot.zip were not getting stripped.

* Add missing comma

* Update script/strip-binaries.py

Co-Authored-By: Jeremy Apthorp <jeremya@chromium.org>

* Don't try to run strip on macOS

Co-authored-by: Jeremy Apthorp <nornagon@nornagon.net>
2020-02-07 17:05:04 -05:00
Jeremy Apthorp
ea89120c9e chore: remove debugging log (#22093) 2020-02-07 12:31:08 -08:00
John Kleinschmidt
c6cec97287 build: copy chromedriver to correct location (#22074)
* build: copy chromedriver to correct location

* build: try to free up disk space for macos releases

* get verbose mode working on strip-binaries

* Only use separate chromedriver build arm/arm64
2020-02-07 13:52:36 -05:00
John Kleinschmidt
45591e31ce ci: fix build failure on doc only changes (#22075)
* ci: fix build failure on doc only changes

* ci: fix doc-only check when CI fires on branch before PR is created
2020-02-07 12:58:47 -05:00
Jeremy Apthorp
e2a5de9248 refactor: saner blink_initialization_order.patch (#22054) 2020-02-07 09:45:13 -08:00
Electron Bot
6a7d722c06 Bump v10.0.0-nightly.20200207 2020-02-07 07:32:49 -08:00
John Kleinschmidt
f1f185ee93 test: get native unit tests running (#21914) 2020-02-07 07:56:54 -05:00
Shelley Vohr
83124889e5 feat: enable passing Node.js cli flags (#21110)
* feat: enable passing Node.js cli flags

* Allow cli flags in ELECTRON_RUN_AS_NODE mode
2020-02-07 02:59:38 +00:00
Jeremy Apthorp
9107157073 feat: [extensions] support extension.getBackgroundPage (#21951)
* feat: [extensions] support extension.getBackgroundPage

* cleanup

* how does c++

* tests

* test for runtime.getBackgroundPage too
2020-02-06 16:42:34 -05:00
Jeremy Apthorp
eca1dd7f8b docs: document supported extensions apis (#22021)
* docs: document supported extensions apis

* Update extensions.md

* Update README.md

* Apply suggestions from code review

Co-Authored-By: Mark Lee <malept@users.noreply.github.com>

Co-authored-by: Mark Lee <malept@users.noreply.github.com>
2020-02-06 16:36:02 -05:00
Sesh Sadasivam
c8273e375c fix: add Chromium patch to fix RTL window buttons (#22016)
Classes that inherit from `NSThemeFrame` seem to show window buttons in the
incorrect position when the primary MacOS language is set to an RTL
(right-to-left) language like Arabic or Hebrew. The fix in this commit mirrors
that of `tabbed_browser_window.mm`
(https://chromium-review.googlesource.com/c/chromium/src/+/562603/10/chrome/browser/ui/cocoa/tabbed_browser_window.mm#88).

This change should be upstreamed, and then this patch can be removed.
2020-02-06 16:14:18 -05:00
John Kleinschmidt
f4fd939409 build: copy chromedriver to proper directory for release (#22070) 2020-02-06 14:20:14 -05:00
John Kleinschmidt
e7982623ec ci: enable goma for all testing builds (#21992)
* ci: enable goma for all testing builds

* Use powershell script to start goma on Windows

* Only run ensure_start from PS script.

* add missing percent

* Run stats via command instead of powershell

* use command env var

* Use out cache for faster mac builds

* Disable unneeded logging

* .git directories need to be delete before gn gen

Even though gn gen shows and error about a missing .git directory, the .git delete needs to happen before gn gen.
2020-02-06 12:56:18 -05:00
Erick Zhao
3f880fb7c7 chore: remove teams without write access from CODEOWNERS (#22043)
* chore: update CODEOWNERS for Ecosystem WG

* chore: remove teams w/o write access from CODEOWNERS
2020-02-06 11:31:25 -06:00
Erick Zhao
070e312e8b docs: clarify requirements for GOOGLE_API_KEY (#22034)
* docs: clarify requirements for GOOGLE_API_KEY

* Update docs/api/environment-variables.md

Co-Authored-By: Mark Lee <malept@users.noreply.github.com>

* Update docs/api/environment-variables.md

Co-Authored-By: Mark Lee <malept@users.noreply.github.com>

* Update docs/api/environment-variables.md

Co-Authored-By: Mark Lee <malept@users.noreply.github.com>

* update

Co-authored-by: Mark Lee <malept@users.noreply.github.com>
2020-02-06 11:28:06 -06:00
Cheng Zhao
629c2121ba chore: print more logging for failed tests (#22060) 2020-02-06 11:15:55 -05:00
Electron Bot
b664c824d2 Bump v10.0.0-nightly.20200206 2020-02-06 07:34:52 -08:00
Electron Bot
42a9d72ce1 chore: bump chromium to 28254008f9e7a2aea5d4426906bfd (master) (#22025)
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2020-02-06 07:05:30 +00:00
Samuel Attard
c8fe25e109 build: actually save the brew cache on macOS (#22052) 2020-02-05 14:15:51 -08:00
62 changed files with 1306 additions and 583 deletions

View File

@@ -65,12 +65,12 @@ machine-linux-2xlarge: &machine-linux-2xlarge
machine-mac: &machine-mac
macos:
xcode: "10.3.0"
xcode: "11.1.0"
machine-mac-large: &machine-mac-large
resource_class: large
macos:
xcode: "10.3.0"
xcode: "11.1.0"
# Build configurations options.
env-testing-build: &env-testing-build
@@ -228,15 +228,6 @@ step-setup-env-for-build: &step-setup-env-for-build
command: |
# To find `gn` executable.
echo 'export CHROMIUM_BUILDTOOLS_PATH="'"$PWD"'/src/buildtools"' >> $BASH_ENV
# Setup Goma if applicable
if [ ! -z "$RAW_GOMA_AUTH" ] && [ "`uname`" == "Linux" ]; then
export USE_SCCACHE="false"
echo 'export USE_SCCACHE=false' >> $BASH_ENV
echo 'export USE_GOMA=true' >> $BASH_ENV
echo 'export NUMBER_OF_NINJA_PROCESSES=300' >> $BASH_ENV
echo $RAW_GOMA_AUTH > ~/.goma_oauth2_config
src/electron/external_binaries/goma/goma_ctl.py ensure_start
fi
if [ "$USE_SCCACHE" == "true" ]; then
# https://github.com/mozilla/sccache
@@ -249,6 +240,29 @@ step-setup-env-for-build: &step-setup-env-for-build
fi
fi
step-setup-goma-for-build: &step-setup-goma-for-build
run:
name: Setup Goma
command: |
echo 'export USE_GOMA=true' >> $BASH_ENV
if [ "`uname`" == "Linux" ]; then
echo 'export NUMBER_OF_NINJA_PROCESSES=300' >> $BASH_ENV
else
echo 'export NUMBER_OF_NINJA_PROCESSES=25' >> $BASH_ENV
fi
if [ ! -z "$RAW_GOMA_AUTH" ]; then
echo $RAW_GOMA_AUTH > ~/.goma_oauth2_config
fi
git clone https://github.com/electron/build-tools.git
cd build-tools
npm install
mkdir third_party
node -e "require('./src/utils/goma.js').downloadAndPrepare()"
node -e "require('./src/utils/goma.js').ensure()"
echo 'export GN_GOMA_FILE='`node -e "console.log(require('./src/utils/goma.js').gnFilePath)"` >> $BASH_ENV
echo 'export LOCAL_GOMA_DIR='`node -e "console.log(require('./src/utils/goma.js').dir)"` >> $BASH_ENV
cd ..
step-restore-brew-cache: &step-restore-brew-cache
restore_cache:
paths:
@@ -339,7 +353,7 @@ step-gn-gen-default: &step-gn-gen-default
command: |
cd src
if [ "$USE_GOMA" == "true" ]; then
gn gen out/Default --args="import(\"$GN_CONFIG\") import(\"//electron/build/args/goma.gn\") $GN_EXTRA_ARGS $GN_BUILDFLAG_ARGS"
gn gen out/Default --args="import(\"$GN_CONFIG\") import(\"$GN_GOMA_FILE\") $GN_EXTRA_ARGS $GN_BUILDFLAG_ARGS"
else
gn gen out/Default --args="import(\"$GN_CONFIG\") cc_wrapper=\"$SCCACHE_PATH\" $GN_EXTRA_ARGS $GN_BUILDFLAG_ARGS"
fi
@@ -432,15 +446,17 @@ step-electron-dist-store: &step-electron-dist-store
path: src/out/Default/dist.zip
destination: dist.zip
step-electron-chromedriver-gn-gen: &step-electron-chromedriver-gn-gen
step-electron-maybe-chromedriver-gn-gen: &step-electron-maybe-chromedriver-gn-gen
run:
name: chromedriver GN gen
command: |
cd src
if [ "$USE_GOMA" == "true" ]; then
gn gen out/chromedriver --args="import(\"$GN_CONFIG\") import(\"//electron/build/args/goma.gn\") is_component_ffmpeg=false proprietary_codecs=false $GN_EXTRA_ARGS $GN_BUILDFLAG_ARGS"
else
gn gen out/chromedriver --args="import(\"$GN_CONFIG\") cc_wrapper=\"$SCCACHE_PATH\" is_component_ffmpeg=false proprietary_codecs=false $GN_EXTRA_ARGS $GN_BUILDFLAG_ARGS"
if [ "$TARGET_ARCH" == "arm" ] || [ "$TARGET_ARCH" == "arm64" ]; then
if [ "$USE_GOMA" == "true" ]; then
gn gen out/chromedriver --args="import(\"$GN_CONFIG\") import(\"//electron/build/args/goma.gn\") is_component_ffmpeg=false proprietary_codecs=false $GN_EXTRA_ARGS $GN_BUILDFLAG_ARGS"
else
gn gen out/chromedriver --args="import(\"$GN_CONFIG\") cc_wrapper=\"$SCCACHE_PATH\" is_component_ffmpeg=false proprietary_codecs=false $GN_EXTRA_ARGS $GN_BUILDFLAG_ARGS"
fi
fi
step-electron-chromedriver-build: &step-electron-chromedriver-build
@@ -448,13 +464,23 @@ step-electron-chromedriver-build: &step-electron-chromedriver-build
name: Build chromedriver.zip
command: |
cd src
ninja -C out/chromedriver electron:electron_chromedriver -j $NUMBER_OF_NINJA_PROCESSES
electron/script/strip-binaries.py --target-cpu="$TARGET_ARCH" --file $PWD/out/chromedriver/chromedriver
ninja -C out/chromedriver electron:electron_chromedriver_zip
if [ "$TARGET_ARCH" == "arm" ] || [ "$TARGET_ARCH" == "arm64" ]; then
export CHROMEDRIVER_DIR="out/chromedriver"
else
export CHROMEDRIVER_DIR="out/Default"
fi
ninja -C $CHROMEDRIVER_DIR electron:electron_chromedriver -j $NUMBER_OF_NINJA_PROCESSES
if [ "`uname`" == "Linux" ]; then
electron/script/strip-binaries.py --target-cpu="$TARGET_ARCH" --file $PWD/$CHROMEDRIVER_DIR/chromedriver
fi
ninja -C $CHROMEDRIVER_DIR electron:electron_chromedriver_zip
if [ "$TARGET_ARCH" == "arm" ] || [ "$TARGET_ARCH" == "arm64" ]; then
cp out/chromedriver/chromedriver.zip out/Default
fi
step-electron-chromedriver-store: &step-electron-chromedriver-store
store_artifacts:
path: src/out/chromedriver/chromedriver.zip
path: src/out/Default/chromedriver.zip
destination: chromedriver.zip
step-nodejs-headers-build: &step-nodejs-headers-build
@@ -481,6 +507,7 @@ step-electron-publish: &step-electron-publish
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'
@@ -497,7 +524,7 @@ step-persist-data-for-tests: &step-persist-data-for-tests
# Build artifacts
- src/out/Default/dist.zip
- src/out/Default/mksnapshot.zip
- src/out/chromedriver/chromedriver.zip
- src/out/Default/chromedriver.zip
- src/out/Default/shell_browser_ui_unittests
- src/out/Default/gen/node_headers
- src/out/ffmpeg/ffmpeg.zip
@@ -532,7 +559,7 @@ step-chromedriver-unzip: &step-chromedriver-unzip
run:
name: Unzip chromedriver.zip
command: |
cd src/out/chromedriver
cd src/out/Default
unzip -o chromedriver.zip
step-ffmpeg-gn-gen: &step-ffmpeg-gn-gen
@@ -577,7 +604,7 @@ step-verify-chromedriver: &step-verify-chromedriver
name: Verify ChromeDriver
command: |
cd src
python electron/script/verify-chromedriver.py --source-root "$PWD" --build-dir out/chromedriver
python electron/script/verify-chromedriver.py --source-root "$PWD" --build-dir out/Default
step-setup-linux-for-headless-testing: &step-setup-linux-for-headless-testing
run:
@@ -595,7 +622,7 @@ step-show-sccache-stats: &step-show-sccache-stats
$SCCACHE_PATH -s
fi
if [ "$USE_GOMA" == "true" ]; then
src/electron/external_binaries/goma/goma_ctl.py stat
$LOCAL_GOMA_DIR/goma_ctl.py stat
fi
step-mksnapshot-build: &step-mksnapshot-build
@@ -833,7 +860,7 @@ step-check-for-doc-only-change: &step-check-for-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
if node script/doc-only-change.js --prNumber=$CIRCLE_PR_NUMBER --prURL=$CIRCLE_PULL_REQUEST --prBranch=$CIRCLE_BRANCH; then
#PR is doc only change; save file with value true to indicate doc only change
echo "true" > .skip-ci-build
else
@@ -869,7 +896,7 @@ step-ts-compile: &step-ts-compile
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
ninja -C out/Default electron:electron_js2c -j $NUMBER_OF_NINJA_PROCESSES
# Lists of steps.
steps-lint: &steps-lint
@@ -953,7 +980,6 @@ steps-checkout-and-save-cache: &steps-checkout-and-save-cache
sudo chown -R $(id -u):$(id -g) /portal
mv ./src /portal
- *step-save-src-cache
- *step-save-brew-cache
steps-electron-gn-check: &steps-electron-gn-check
steps:
@@ -965,69 +991,6 @@ steps-electron-gn-check: &steps-electron-gn-check
- *step-gn-gen-default
- *step-gn-check
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-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
# chromedriver
- *step-electron-chromedriver-gn-gen
- *step-electron-chromedriver-build
- *step-electron-chromedriver-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
@@ -1094,7 +1057,7 @@ steps-electron-build-for-publish: &steps-electron-build-for-publish
- *step-mksnapshot-store
# chromedriver
- *step-electron-chromedriver-gn-gen
- *step-electron-maybe-chromedriver-gn-gen
- *step-electron-chromedriver-build
- *step-electron-chromedriver-store
@@ -1125,7 +1088,7 @@ steps-chromedriver-build: &steps-chromedriver-build
- *step-setup-env-for-build
- *step-fix-sync-on-mac
- *step-electron-chromedriver-gn-gen
- *step-electron-maybe-chromedriver-gn-gen
- *step-electron-chromedriver-build
- *step-electron-chromedriver-store
@@ -1349,6 +1312,7 @@ commands:
at: .
- *step-restore-brew-cache
- *step-install-gnutar-on-mac
- *step-save-brew-cache
- when:
condition: << parameters.checkout-and-assume-cache >>
steps:
@@ -1394,10 +1358,10 @@ commands:
steps:
- *step-depot-tools-add-to-path
- *step-setup-env-for-build
- *step-setup-goma-for-build
- *step-get-more-space-on-mac
- *step-fix-sync-on-mac
- *step-delete-git-directories
- *step-gn-gen-default
# Electron app
- when:
@@ -1429,7 +1393,7 @@ commands:
- *step-maybe-cross-arch-snapshot-store
# chromedriver
- *step-electron-chromedriver-gn-gen
- *step-electron-maybe-chromedriver-gn-gen
- *step-electron-chromedriver-build
- *step-electron-chromedriver-store
@@ -1569,7 +1533,6 @@ jobs:
environment:
<<: *env-linux-2xlarge
<<: *env-testing-build
<<: *env-enable-sccache
<<: *env-ninja-status
GCLIENT_EXTRA_ARGS: '--custom-var=checkout_arm=True --custom-var=checkout_arm64=True'
steps:
@@ -1583,7 +1546,6 @@ jobs:
environment:
<<: *env-linux-2xlarge
<<: *env-testing-build
<<: *env-enable-sccache
<<: *env-ninja-status
<<: *env-disable-run-as-node
GCLIENT_EXTRA_ARGS: '--custom-var=checkout_arm=True --custom-var=checkout_arm64=True'
@@ -1605,7 +1567,6 @@ jobs:
environment:
<<: *env-linux-medium
<<: *env-release-build
<<: *env-enable-sccache
<<: *env-send-slack-notifications
<<: *steps-chromedriver-build
@@ -1614,10 +1575,13 @@ jobs:
environment:
<<: *env-linux-2xlarge-release
<<: *env-release-build
<<: *env-enable-sccache
<<: *env-send-slack-notifications
<<: *env-ninja-status
<<: *steps-electron-build
GCLIENT_EXTRA_ARGS: '--custom-var=checkout_arm=True --custom-var=checkout_arm64=True'
steps:
- electron-build:
persist: true
checkout: true
linux-x64-publish:
<<: *machine-linux-2xlarge
@@ -1635,7 +1599,6 @@ jobs:
<<: *env-linux-2xlarge
<<: *env-ia32
<<: *env-testing-build
<<: *env-enable-sccache
<<: *env-ninja-status
GCLIENT_EXTRA_ARGS: '--custom-var=checkout_arm=True --custom-var=checkout_arm64=True'
steps:
@@ -1650,7 +1613,6 @@ jobs:
<<: *env-linux-medium
<<: *env-ia32
<<: *env-release-build
<<: *env-enable-sccache
<<: *env-send-slack-notifications
<<: *steps-chromedriver-build
@@ -1660,10 +1622,13 @@ jobs:
<<: *env-linux-2xlarge-release
<<: *env-ia32
<<: *env-release-build
<<: *env-enable-sccache
<<: *env-send-slack-notifications
<<: *env-ninja-status
<<: *steps-electron-build
GCLIENT_EXTRA_ARGS: '--custom-var=checkout_arm=True --custom-var=checkout_arm64=True'
steps:
- electron-build:
persist: true
checkout: true
linux-ia32-publish:
<<: *machine-linux-2xlarge
@@ -1683,7 +1648,6 @@ jobs:
<<: *env-linux-2xlarge
<<: *env-arm
<<: *env-testing-build
<<: *env-enable-sccache
<<: *env-ninja-status
TRIGGER_ARM_TEST: true
GCLIENT_EXTRA_ARGS: '--custom-var=checkout_arm=True --custom-var=checkout_arm64=True'
@@ -1699,7 +1663,6 @@ jobs:
<<: *env-linux-medium
<<: *env-arm
<<: *env-release-build
<<: *env-enable-sccache
<<: *env-send-slack-notifications
<<: *steps-chromedriver-build
@@ -1709,10 +1672,13 @@ jobs:
<<: *env-linux-2xlarge-release
<<: *env-arm
<<: *env-release-build
<<: *env-enable-sccache
<<: *env-send-slack-notifications
<<: *env-ninja-status
<<: *steps-electron-build
GCLIENT_EXTRA_ARGS: '--custom-var=checkout_arm=True --custom-var=checkout_arm64=True'
steps:
- electron-build:
persist: false
checkout: true
linux-arm-publish:
<<: *machine-linux-2xlarge
@@ -1732,7 +1698,6 @@ jobs:
<<: *env-linux-2xlarge
<<: *env-arm64
<<: *env-testing-build
<<: *env-enable-sccache
<<: *env-ninja-status
TRIGGER_ARM_TEST: true
GCLIENT_EXTRA_ARGS: '--custom-var=checkout_arm=True --custom-var=checkout_arm64=True'
@@ -1756,7 +1721,6 @@ jobs:
<<: *env-linux-medium
<<: *env-arm64
<<: *env-release-build
<<: *env-enable-sccache
<<: *env-send-slack-notifications
<<: *steps-chromedriver-build
@@ -1766,10 +1730,13 @@ jobs:
<<: *env-linux-2xlarge-release
<<: *env-arm64
<<: *env-release-build
<<: *env-enable-sccache
<<: *env-send-slack-notifications
<<: *env-ninja-status
<<: *steps-electron-build
GCLIENT_EXTRA_ARGS: '--custom-var=checkout_arm=True --custom-var=checkout_arm64=True'
steps:
- electron-build:
persist: false
checkout: true
linux-arm64-publish:
<<: *machine-linux-2xlarge
@@ -1787,7 +1754,6 @@ jobs:
environment:
<<: *env-mac-large
<<: *env-testing-build
<<: *env-enable-sccache
<<: *env-ninja-status
<<: *env-macos-build
GCLIENT_EXTRA_ARGS: '--custom-var=checkout_mac=True --custom-var=host_os=mac'
@@ -1810,7 +1776,6 @@ jobs:
environment:
<<: *env-machine-mac
<<: *env-release-build
<<: *env-enable-sccache
<<: *env-send-slack-notifications
<<: *steps-chromedriver-build
@@ -1819,9 +1784,14 @@ jobs:
environment:
<<: *env-mac-large
<<: *env-release-build
<<: *env-enable-sccache
<<: *env-ninja-status
<<: *steps-electron-build
GCLIENT_EXTRA_ARGS: '--custom-var=checkout_mac=True --custom-var=host_os=mac'
steps:
- electron-build:
persist: true
checkout: false
checkout-and-assume-cache: true
attach: false
osx-publish:
<<: *machine-mac-large
@@ -1839,7 +1809,6 @@ jobs:
<<: *env-mac-large
<<: *env-mas
<<: *env-testing-build
<<: *env-enable-sccache
<<: *env-ninja-status
<<: *env-macos-build
GCLIENT_EXTRA_ARGS: '--custom-var=checkout_mac=True --custom-var=host_os=mac'
@@ -1863,7 +1832,6 @@ jobs:
environment:
<<: *env-machine-mac
<<: *env-release-build
<<: *env-enable-sccache
<<: *env-send-slack-notifications
<<: *steps-chromedriver-build
@@ -1873,10 +1841,15 @@ jobs:
<<: *env-mac-large
<<: *env-mas
<<: *env-release-build
<<: *env-enable-sccache
<<: *env-ninja-status
<<: *steps-electron-build
GCLIENT_EXTRA_ARGS: '--custom-var=checkout_mac=True --custom-var=host_os=mac'
steps:
- electron-build:
persist: true
checkout: false
checkout-and-assume-cache: true
attach: false
mas-publish:
<<: *machine-mac-large
environment:
@@ -1894,7 +1867,6 @@ jobs:
environment:
<<: *env-linux-2xlarge
<<: *env-unittests
<<: *env-enable-sccache
<<: *env-headless-testing
<<: *steps-native-tests
@@ -1903,7 +1875,6 @@ jobs:
environment:
<<: *env-linux-2xlarge
<<: *env-unittests
<<: *env-enable-sccache
<<: *env-headless-testing
TESTS_ARGS: '--only-disabled-tests'
<<: *steps-native-tests
@@ -1913,7 +1884,6 @@ jobs:
environment:
<<: *env-linux-2xlarge
<<: *env-unittests
<<: *env-enable-sccache
<<: *env-headless-testing
TESTS_ARGS: '--include-disabled-tests'
<<: *steps-native-tests
@@ -1924,7 +1894,6 @@ jobs:
<<: *env-linux-2xlarge
<<: *env-browsertests
<<: *env-testing-build
<<: *env-enable-sccache
<<: *env-headless-testing
<<: *steps-native-tests
@@ -2302,10 +2271,9 @@ workflows:
- *chromium-upgrade-branches
jobs:
- linux-checkout-fast
- linux-checkout-and-save-cache
- linux-x64-release:
requires:
- linux-checkout-fast
- linux-x64-release
- linux-x64-release-tests:
requires:
- linux-x64-release
@@ -2329,9 +2297,7 @@ workflows:
- linux-x64-verify-ffmpeg
- linux-x64-chromedriver
- linux-ia32-release:
requires:
- linux-checkout-fast
- linux-ia32-release
- linux-ia32-release-tests:
requires:
- linux-ia32-release
@@ -2355,9 +2321,7 @@ workflows:
- linux-ia32-verify-ffmpeg
- linux-ia32-chromedriver
- linux-arm-release:
requires:
- linux-checkout-fast
- linux-arm-release
- linux-arm-chromedriver:
requires:
- linux-checkout-fast
@@ -2366,10 +2330,7 @@ workflows:
- linux-arm-release
- linux-arm-chromedriver
- linux-arm64-release:
requires:
- linux-checkout-fast
- linux-arm64-release
- linux-arm64-chromedriver:
requires:
- linux-checkout-fast
@@ -2389,10 +2350,11 @@ workflows:
- *chromium-upgrade-branches
jobs:
- mac-checkout-fast
- mac-checkout-and-save-cache
- osx-release:
requires:
- mac-checkout-fast
- mac-checkout-and-save-cache
- osx-release-tests:
requires:
- osx-release
@@ -2418,7 +2380,7 @@ workflows:
- mas-release:
requires:
- mac-checkout-fast
- mac-checkout-and-save-cache
- mas-release-tests:
requires:
- mas-release

12
.github/CODEOWNERS vendored
View File

@@ -3,20 +3,10 @@
# https://help.github.com/articles/about-codeowners
# https://git-scm.com/docs/gitignore
# Most stuff in here is owned by the Community & Safety WG...
/.github/* @electron/wg-community
# ...except the Admin WG maintains this file.
/.github/CODEOWNERS @electron/wg-admin
# Upgrades WG
/patches/ @electron/wg-upgrades
DEPS @electron/wg-upgrades
# Docs & Tooling WG
/default_app/ @electron/wg-docs-tools
/docs/ @electron/wg-docs-tools
# Releases WG
/npm/ @electron/wg-releases
/script/release @electron/wg-releases
/script/release @electron/wg-releases

2
DEPS
View File

@@ -12,7 +12,7 @@ gclient_gn_args = [
vars = {
'chromium_version':
'2102ff0fb03469ca5ff317a168e6ad99ca0f23f1',
'ddac4c3cc1528254008f9e7a2aea5d4426906bfd',
'node_version':
'v12.14.1',
'nan_version':

View File

@@ -1 +1 @@
9.0.0-nightly.20200205
10.0.0-nightly.20200209

View File

@@ -118,19 +118,29 @@ build_script:
}
}
- ps: >-
if (Test-Path 'env:RAW_GOMA_AUTH') {
$env:GOMA_OAUTH2_CONFIG_FILE = "$pwd\.goma_oauth2_config"
$env:RAW_GOMA_AUTH | Set-Content $env:GOMA_OAUTH2_CONFIG_FILE
.\src\electron\script\start-goma.ps1 -gomaDir "$pwd\src\electron\external_binaries\goma"
if ($env:GN_CONFIG -ne 'release') {
if (Test-Path 'env:RAW_GOMA_AUTH') {
$env:GOMA_OAUTH2_CONFIG_FILE = "$pwd\.goma_oauth2_config"
$env:RAW_GOMA_AUTH | Set-Content $env:GOMA_OAUTH2_CONFIG_FILE
}
git clone https://github.com/electron/build-tools.git
cd build-tools
npm install
mkdir third_party
node -e "require('./src/utils/goma.js').downloadAndPrepare()"
$env:GN_GOMA_FILE = node -e "console.log(require('./src/utils/goma.js').gnFilePath)"
$env:LOCAL_GOMA_DIR = node -e "console.log(require('./src/utils/goma.js').dir)"
cd ..
.\src\electron\script\start-goma.ps1 -gomaDir $env:LOCAL_GOMA_DIR
}
- cd src
- set BUILD_CONFIG_PATH=//electron/build/args/%GN_CONFIG%.gn
- if DEFINED RAW_GOMA_AUTH (gn gen out/Default "--args=import(\"%BUILD_CONFIG_PATH%\") import(\"//electron/build/args/goma.gn\") %GN_EXTRA_ARGS% ") else (gn gen out/Default "--args=import(\"%BUILD_CONFIG_PATH%\") %GN_EXTRA_ARGS% cc_wrapper=\"%SCCACHE_PATH%\"")
- if DEFINED GN_GOMA_FILE (gn gen out/Default "--args=import(\"%BUILD_CONFIG_PATH%\") import(\"%GN_GOMA_FILE%\") %GN_EXTRA_ARGS% ") else (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
- gn check out/Default //electron/shell/common/api:mojo
- if DEFINED RAW_GOMA_AUTH (ninja -j 300 -C out/Default electron:electron_app) else (ninja -C out/Default electron:electron_app)
- if DEFINED GN_GOMA_FILE (ninja -j 300 -C out/Default electron:electron_app) else (ninja -C out/Default electron:electron_app)
- if "%GN_CONFIG%"=="testing" ( python C:\depot_tools\post_build_ninja_summary.py -C out\Default )
- gn gen out/ffmpeg "--args=import(\"//electron/build/args/ffmpeg.gn\") %GN_EXTRA_ARGS%"
- ninja -C out/ffmpeg electron:electron_ffmpeg_zip
@@ -140,7 +150,7 @@ build_script:
- 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
- if DEFINED RAW_GOMA_AUTH (python electron\external_binaries\goma\goma_ctl.py stat)
- if "%GN_CONFIG%"=="testing" ( python %LOCAL_GOMA_DIR%\goma_ctl.py stat )
- python electron/build/profile_toolchain.py --output-json=out/Default/windows_toolchain_profile.json
- appveyor PushArtifact out/Default/windows_toolchain_profile.json
- appveyor PushArtifact out/Default/dist.zip

View File

@@ -68,7 +68,6 @@ static_library("chrome") {
]
deps = [
"//chrome/browser:resource_prefetch_predictor_proto",
"//chrome/browser/ssl:proto",
"//components/feature_engagement:buildflags",
]

View File

@@ -112,6 +112,7 @@ These individual tutorials expand on topics discussed in the guide above.
* [Process Object](api/process.md)
* [Supported Command Line Switches](api/command-line-switches.md)
* [Environment Variables](api/environment-variables.md)
* [Chrome Extensions Support](api/extensions.md)
* [Breaking API Changes](breaking-changes.md)
### Custom DOM Elements:

View File

@@ -16,80 +16,66 @@ app.whenReady().then(() => {
})
```
## --ignore-connections-limit=`domains`
## Electron CLI Flags
Ignore the connections limit for `domains` list separated by `,`.
### --auth-server-whitelist=`url`
## --disable-http-cache
Disables the disk cache for HTTP requests.
## --disable-http2
Disable HTTP/2 and SPDY/3.1 protocols.
## --lang
Set a custom locale.
## --inspect=`port` and --inspect-brk=`port`
Debug-related flags, see the [Debugging the Main Process][debugging-main-process] guide for details.
## --remote-debugging-port=`port`
Enables remote debugging over HTTP on the specified `port`.
## --disk-cache-size=`size`
Forces the maximum disk space to be used by the disk cache, in bytes.
## --js-flags=`flags`
Specifies the flags passed to the Node.js engine. It has to be passed when starting
Electron if you want to enable the `flags` in the main process.
```sh
$ electron --js-flags="--harmony_proxies --harmony_collections" your-app
```
See the [Node.js documentation][node-cli] or run `node --help` in your terminal for a list of available flags. Additionally, run `node --v8-options` to see a list of flags that specifically refer to Node.js's V8 JavaScript engine.
## --proxy-server=`address:port`
Use a specified proxy server, which overrides the system setting. This switch
only affects requests with HTTP protocol, including HTTPS and WebSocket
requests. It is also noteworthy that not all proxy servers support HTTPS and
WebSocket requests. The proxy URL does not support username and password
authentication [per Chromium issue](https://bugs.chromium.org/p/chromium/issues/detail?id=615947).
## --proxy-bypass-list=`hosts`
Instructs Electron to bypass the proxy server for the given semi-colon-separated
list of hosts. This flag has an effect only if used in tandem with
`--proxy-server`.
A comma-separated list of servers for which integrated authentication is enabled.
For example:
```javascript
const { app } = require('electron')
app.commandLine.appendSwitch('proxy-bypass-list', '<local>;*.google.com;*foo.com;1.2.3.4:5678')
```sh
--auth-server-whitelist='*example.com, *foobar.com, *baz'
```
Will use the proxy server for all hosts except for local addresses (`localhost`,
`127.0.0.1` etc.), `google.com` subdomains, hosts that contain the suffix
`foo.com` and anything at `1.2.3.4:5678`.
then any `url` ending with `example.com`, `foobar.com`, `baz` will be considered
for integrated authentication. Without `*` prefix the URL has to match exactly.
## --proxy-pac-url=`url`
### --auth-negotiate-delegate-whitelist=`url`
Uses the PAC script at the specified `url`.
A comma-separated list of servers for which delegation of user credentials is required.
Without `*` prefix the URL has to match exactly.
## --no-proxy-server
### --disable-http-cache
Don't use a proxy server and always make direct connections. Overrides any other
proxy server flags that are passed.
Disables the disk cache for HTTP requests.
## --host-rules=`rules`
### --disable-http2
Disable HTTP/2 and SPDY/3.1 protocols.
### --disable-renderer-backgrounding
Prevents Chromium from lowering the priority of invisible pages' renderer
processes.
This flag is global to all renderer processes, if you only want to disable
throttling in one window, you can take the hack of
[playing silent audio][play-silent-audio].
### --disk-cache-size=`size`
Forces the maximum disk space to be used by the disk cache, in bytes.
### --enable-api-filtering-logging
Enables caller stack logging for the following APIs (filtering events):
- `desktopCapturer.getSources()` / `desktop-capturer-get-sources`
- `remote.require()` / `remote-require`
- `remote.getGlobal()` / `remote-get-builtin`
- `remote.getBuiltin()` / `remote-get-global`
- `remote.getCurrentWindow()` / `remote-get-current-window`
- `remote.getCurrentWebContents()` / `remote-get-current-web-contents`
### --enable-logging
Prints Chromium's logging into console.
This switch can not be used in `app.commandLine.appendSwitch` since it is parsed
earlier than user's app is loaded, but you can set the `ELECTRON_ENABLE_LOGGING`
environment variable to achieve the same effect.
### --host-rules=`rules`
A comma-separated list of `rules` that control how hostnames are mapped.
@@ -107,69 +93,96 @@ These mappings apply to the endpoint host in a net request (the TCP connect
and host resolver in a direct connection, and the `CONNECT` in an HTTP proxy
connection, and the endpoint host in a `SOCKS` proxy connection).
## --host-resolver-rules=`rules`
### --host-resolver-rules=`rules`
Like `--host-rules` but these `rules` only apply to the host resolver.
## --auth-server-whitelist=`url`
A comma-separated list of servers for which integrated authentication is enabled.
For example:
```sh
--auth-server-whitelist='*example.com, *foobar.com, *baz'
```
then any `url` ending with `example.com`, `foobar.com`, `baz` will be considered
for integrated authentication. Without `*` prefix the URL has to match exactly.
## --auth-negotiate-delegate-whitelist=`url`
A comma-separated list of servers for which delegation of user credentials is required.
Without `*` prefix the URL has to match exactly.
## --ignore-certificate-errors
### --ignore-certificate-errors
Ignores certificate related errors.
## --ppapi-flash-path=`path`
### --ignore-connections-limit=`domains`
Sets the `path` of the pepper flash plugin.
Ignore the connections limit for `domains` list separated by `,`.
## --ppapi-flash-version=`version`
### --js-flags=`flags`
Sets the `version` of the pepper flash plugin.
Specifies the flags passed to the Node.js engine. It has to be passed when starting
Electron if you want to enable the `flags` in the main process.
## --log-net-log=`path`
```sh
$ electron --js-flags="--harmony_proxies --harmony_collections" your-app
```
See the [Node.js documentation][node-cli] or run `node --help` in your terminal for a list of available flags. Additionally, run `node --v8-options` to see a list of flags that specifically refer to Node.js's V8 JavaScript engine.
### --lang
Set a custom locale.
### --log-net-log=`path`
Enables net log events to be saved and writes them to `path`.
## --disable-renderer-backgrounding
### --no-proxy-server
Prevents Chromium from lowering the priority of invisible pages' renderer
processes.
Don't use a proxy server and always make direct connections. Overrides any other
proxy server flags that are passed.
This flag is global to all renderer processes, if you only want to disable
throttling in one window, you can take the hack of
[playing silent audio][play-silent-audio].
### --no-sandbox
## --enable-logging
Disables Chromium sandbox, which is now enabled by default.
Should only be used for testing.
Prints Chromium's logging into console.
### --proxy-bypass-list=`hosts`
This switch can not be used in `app.commandLine.appendSwitch` since it is parsed
earlier than user's app is loaded, but you can set the `ELECTRON_ENABLE_LOGGING`
environment variable to achieve the same effect.
Instructs Electron to bypass the proxy server for the given semi-colon-separated
list of hosts. This flag has an effect only if used in tandem with
`--proxy-server`.
## --v=`log_level`
For example:
```javascript
const { app } = require('electron')
app.commandLine.appendSwitch('proxy-bypass-list', '<local>;*.google.com;*foo.com;1.2.3.4:5678')
```
Will use the proxy server for all hosts except for local addresses (`localhost`,
`127.0.0.1` etc.), `google.com` subdomains, hosts that contain the suffix
`foo.com` and anything at `1.2.3.4:5678`.
### --proxy-pac-url=`url`
Uses the PAC script at the specified `url`.
### --proxy-server=`address:port`
Use a specified proxy server, which overrides the system setting. This switch
only affects requests with HTTP protocol, including HTTPS and WebSocket
requests. It is also noteworthy that not all proxy servers support HTTPS and
WebSocket requests. The proxy URL does not support username and password
authentication [per Chromium issue](https://bugs.chromium.org/p/chromium/issues/detail?id=615947).
### --remote-debugging-port=`port`
Enables remote debugging over HTTP on the specified `port`.
### --ppapi-flash-path=`path`
Sets the `path` of the pepper flash plugin.
### --ppapi-flash-version=`version`
Sets the `version` of the pepper flash plugin.
### --v=`log_level`
Gives the default maximal active V-logging level; 0 is the default. Normally
positive values are used for V-logging levels.
This switch only works when `--enable-logging` is also passed.
## --vmodule=`pattern`
### --vmodule=`pattern`
Gives the per-module maximal V-logging levels to override the value given by
`--v`. E.g. `my_module=2,foo*=3` would change the logging level for all code in
@@ -181,20 +194,38 @@ logging level for all code in the source files under a `foo/bar` directory.
This switch only works when `--enable-logging` is also passed.
## --enable-api-filtering-logging
## Node.js Flags
Enables caller stack logging for the following APIs (filtering events):
- `desktopCapturer.getSources()` / `desktop-capturer-get-sources`
- `remote.require()` / `remote-require`
- `remote.getGlobal()` / `remote-get-builtin`
- `remote.getBuiltin()` / `remote-get-global`
- `remote.getCurrentWindow()` / `remote-get-current-window`
- `remote.getCurrentWebContents()` / `remote-get-current-web-contents`
Electron supports some of the [CLI flags][node-cli] supported by Node.js.
## --no-sandbox
**Note:** Passing unsupported command line switches to Electron when it is not running in `ELECTRON_RUN_AS_NODE` will have no effect.
Disables Chromium sandbox, which is now enabled by default.
Should only be used for testing.
### --inspect-brk[=[host:]port]
Activate inspector on host:port and break at start of user script. Default host:port is 127.0.0.1:9229.
Aliased to `--debug-brk=[host:]port`.
### --inspect-port=[host:]port
Set the `host:port` to be used when the inspector is activated. Useful when activating the inspector by sending the SIGUSR1 signal. Default host is `127.0.0.1`.
Aliased to `--debug-port=[host:]port`.
### --inspect[=[host:]port]
Activate inspector on `host:port`. Default is `127.0.0.1:9229`.
V8 inspector integration allows tools such as Chrome DevTools and IDEs to debug and profile Electron instances. The tools attach to Electron instances via a tcp port and communicate using the [Chrome DevTools Protocol](https://chromedevtools.github.io/devtools-protocol/).
See the [Debugging the Main Process][debugging-main-process] guide for more details.
Aliased to `--debug[=[host:]port`.
### --inspect-publish-uid=stderr,http
Specify ways of the inspector web socket url exposure.
By default inspector websocket url is available in stderr and under /json/list endpoint on http://host:port/json/list.
[app]: app.md
[append-switch]: app.md#appcommandlineappendswitchswitch-value

View File

@@ -53,16 +53,23 @@ Unsupported options are:
### `GOOGLE_API_KEY`
You can provide an API key for making requests to Google's geocoding webservice. To do this, place the following code in your main process
file, before opening any browser windows that will make geocoding requests:
Geolocation support in Electron requires the use of Google Cloud Platform's
geolocation webservice. To enable this feature, acquire a
[Google API key](https://developers.google.com/maps/documentation/geolocation/get-api-key)
and place the following code in your main process file, before opening any
browser windows that will make geolocation requests:
```javascript
process.env.GOOGLE_API_KEY = 'YOUR_KEY_HERE'
```
For instructions on how to acquire a Google API key, visit [this page](https://developers.google.com/maps/documentation/javascript/get-api-key).
By default, a newly generated Google API key may not be allowed to make
geocoding requests. To enable geocoding requests, visit [this page](https://developers.google.com/maps/documentation/geocoding/get-api-key).
By default, a newly generated Google API key may not be allowed to make geolocation requests.
To enable the geolocation webservice for your project, enable it through the
[API library](https://console.cloud.google.com/apis/library).
N.B. You will need to add a
[Billing Account](https://cloud.google.com/billing/docs/how-to/payment-methods#add_a_payment_method)
to the project associated to the API key for the geolocation webservice to work.
### `ELECTRON_NO_ASAR`
@@ -73,6 +80,18 @@ and spawned child processes that set `ELECTRON_RUN_AS_NODE`.
Starts the process as a normal Node.js process.
In this mode, you will be able to pass [cli options](https://nodejs.org/api/cli.html) to Node.js as
you would when running the normal Node.js executable, with the exception of the following flags:
* "--openssl-config"
* "--use-bundled-ca"
* "--use-openssl-ca",
* "--force-fips"
* "--enable-fips"
These flags are disabled owing to the fact that Electron uses BoringSSL instead of OpenSSL when building Node.js'
`crypto` module, and so will not work as designed.
### `ELECTRON_NO_ATTACH_CONSOLE` _Windows_
Don't attach to the current console session.

101
docs/api/extensions.md Normal file
View File

@@ -0,0 +1,101 @@
# Chrome Extension Support
Electron supports a subset of the [Chrome Extensions
API][chrome-extensions-api-index], primarily to support DevTools extensions and
Chromium-internal extensions, but it also happens to support some other
extension capabilities.
[chrome-extensions-api-index]: https://developer.chrome.com/extensions/api_index
> **Note:** Electron does not support arbitrary Chrome extensions from the
> store, and it is a **non-goal** of the Electron project to be perfectly
> compatible with Chrome's implementation of Extensions.
## Loading extensions
Electron only supports loading unpacked extensions (i.e., `.crx` files do not
work). Extensions are installed per-`session`. To load an extension, call
[`ses.loadExtension`](session.md#sesloadextensionpath):
```js
const { session } = require('electron')
session.loadExtension('path/to/unpacked/extension').then(({ id }) => {
// ...
})
```
Loaded extensions will not be automatically remembered across exits; if you do
not call `loadExtension` when the app runs, the extension will not be loaded.
See the [`session`](session.md) documentation for more information about
loading, unloading, and querying active extensions.
## Supported Extensions APIs
We support the following extensions APIs, with some caveats. Other APIs may
additionally be supported, but support for any APIs not listed here is
provisional and may be removed.
### `chrome.devtools.inspectedWindow`
All features of this API are supported.
### `chrome.devtools.network`
All features of this API are supported.
### `chrome.devtools.panels`
All features of this API are supported.
### `chrome.extension`
The following properties of `chrome.extension` are supported:
- `chrome.extension.lastError`
The following methods of `chrome.extension` are supported:
- `chrome.extension.getURL`
- `chrome.extension.getBackgroundPage`
### `chrome.runtime`
The following properties of `chrome.runtime` are supported:
- `chrome.runtime.lastError`
- `chrome.runtime.id`
The following methods of `chrome.runtime` are supported:
- `chrome.runtime.getBackgroundPage`
- `chrome.runtime.getManifest`
- `chrome.runtime.getURL`
- `chrome.runtime.connect`
- `chrome.runtime.sendMessage`
The following events of `chrome.runtime` are supported:
- `chrome.runtime.onStartup`
- `chrome.runtime.onInstalled`
- `chrome.runtime.onSuspend`
- `chrome.runtime.onSuspendCanceled`
- `chrome.runtime.onConnect`
- `chrome.runtime.onMessage`
### `chrome.storage`
Only `chrome.storage.local` is supported; `chrome.storage.sync` and
`chrome.storage.managed` are not.
### `chrome.tabs`
The following methods of `chrome.tabs` are supported:
- `chrome.tabs.sendMessage`
- `chrome.tabs.executeScript`
> **Note:** In Chrome, passing `-1` as a tab ID signifies the "currently active
> tab". Since Electron has no such concept, passing `-1` as a tab ID is not
> supported and will raise an error.

View File

@@ -21,6 +21,7 @@ auto_filenames = {
"docs/api/dock.md",
"docs/api/download-item.md",
"docs/api/environment-variables.md",
"docs/api/extensions.md",
"docs/api/file-object.md",
"docs/api/frameless-window.md",
"docs/api/global-shortcut.md",

View File

@@ -14,7 +14,6 @@ const remoteObjectCache = v8Util.createIDWeakMap()
const contextId = v8Util.getHiddenValue(global, 'contextId')
ipcRendererInternal.invoke('ELECTRON_BROWSER_GET_LAST_WEB_PREFERENCES').then(preferences => {
console.log(preferences)
if (!preferences.enableRemoteModule) {
console.warn('%cElectron Deprecation Warning', 'font-weight: bold', "The 'remote' module is deprecated and will be disabled by default in a future version of Electron. To ensure a smooth upgrade and silence this warning, specify {enableRemoteModule: true} in the WebPreferences for this window.")
}

View File

@@ -1,6 +1,6 @@
{
"name": "electron",
"version": "9.0.0-nightly.20200205",
"version": "10.0.0-nightly.20200209",
"repository": "https://github.com/electron/electron",
"description": "Build cross platform desktop apps with JavaScript, HTML, and CSS",
"devDependencies": {

View File

@@ -35,7 +35,7 @@ mas_disable_remote_accessibility.patch
mas_disable_custom_window_frame.patch
chrome_key_systems.patch
allow_nested_error_trackers.patch
blink_initialization_order.patch
add_didinstallconditionalfeatures.patch
ssl_security_state_tab_helper.patch
desktop_media_list.patch
proxy_config_monitor.patch
@@ -81,3 +81,4 @@ feat_allow_disabling_blink_scheduler_throttling_per_renderview.patch
accessible_pane_view.patch
fixme_grit_conflicts.patch
fix_use_the_new_mediaplaypause_key_listener_for_internal_chrome.patch
fix_use_native_window_button_positions_when_macos_locale_is_rtl.patch

View File

@@ -0,0 +1,137 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Jeremy Apthorp <nornagon@nornagon.net>
Date: Wed, 15 Jan 2020 16:35:18 -0800
Subject: add DidInstallConditionalFeatures
This adds a hook on script context creation _after conditional features
have been installed_. Electron uses this to run preload scripts and
various other initialization. This is necessary because at the time
DidCreateScriptContext is called, not all JS APIs are available in the
context, which can cause some preload scripts to trip.
diff --git a/content/public/renderer/render_frame_observer.h b/content/public/renderer/render_frame_observer.h
index 68654a3e7d5ec6caddccb667f9f8fa2feabfa71b..650ce53e112bd65e1901a09480452855a0c16dda 100644
--- a/content/public/renderer/render_frame_observer.h
+++ b/content/public/renderer/render_frame_observer.h
@@ -115,6 +115,8 @@ class CONTENT_EXPORT RenderFrameObserver : public IPC::Listener,
virtual void DidHandleOnloadEvents() {}
virtual void DidCreateScriptContext(v8::Local<v8::Context> context,
int32_t world_id) {}
+ virtual void DidInstallConditionalFeatures(v8::Local<v8::Context> context,
+ int32_t world_id) {}
virtual void WillReleaseScriptContext(v8::Local<v8::Context> context,
int32_t world_id) {}
virtual void DidClearWindowObject() {}
diff --git a/content/renderer/render_frame_impl.cc b/content/renderer/render_frame_impl.cc
index 6730d6f6eb8448452991ebf5968a8c5a398b6a88..b87f9c7ac0f31ec33f03c36131c3255c8a31c22c 100644
--- a/content/renderer/render_frame_impl.cc
+++ b/content/renderer/render_frame_impl.cc
@@ -5187,6 +5187,12 @@ void RenderFrameImpl::DidCreateScriptContext(v8::Local<v8::Context> context,
observer.DidCreateScriptContext(context, world_id);
}
+void RenderFrameImpl::DidInstallConditionalFeatures(
+ v8::Local<v8::Context> context, int world_id) {
+ for (auto& observer : observers_)
+ observer.DidInstallConditionalFeatures(context, world_id);
+}
+
void RenderFrameImpl::WillReleaseScriptContext(v8::Local<v8::Context> context,
int world_id) {
for (auto& observer : observers_)
diff --git a/content/renderer/render_frame_impl.h b/content/renderer/render_frame_impl.h
index bc896201057832415b5d54dc8987bb74bf7aa778..5c96af71646722b1108a8d6eafba1adaddf0a05a 100644
--- a/content/renderer/render_frame_impl.h
+++ b/content/renderer/render_frame_impl.h
@@ -773,6 +773,8 @@ class CONTENT_EXPORT RenderFrameImpl
bool ShouldTrackUseCounter(const blink::WebURL& url) override;
void DidCreateScriptContext(v8::Local<v8::Context> context,
int world_id) override;
+ void DidInstallConditionalFeatures(v8::Local<v8::Context> context,
+ int world_id) override;
void WillReleaseScriptContext(v8::Local<v8::Context> context,
int world_id) override;
void DidChangeScrollOffset() override;
diff --git a/third_party/blink/public/web/web_local_frame_client.h b/third_party/blink/public/web/web_local_frame_client.h
index 30638c31e30d98bb23292115b25b528ff8e8f62c..e0f2f786b75f861851d1194f57b253a173053299 100644
--- a/third_party/blink/public/web/web_local_frame_client.h
+++ b/third_party/blink/public/web/web_local_frame_client.h
@@ -652,6 +652,9 @@ class BLINK_EXPORT WebLocalFrameClient {
virtual void DidCreateScriptContext(v8::Local<v8::Context>,
int32_t world_id) {}
+ virtual void DidInstallConditionalFeatures(v8::Local<v8::Context>,
+ int32_t world_id) {}
+
// WebKit is about to release its reference to a v8 context for a frame.
virtual void WillReleaseScriptContext(v8::Local<v8::Context>,
int32_t world_id) {}
diff --git a/third_party/blink/renderer/bindings/core/v8/local_window_proxy.cc b/third_party/blink/renderer/bindings/core/v8/local_window_proxy.cc
index 8095edd988c171a8ad7382d1c2f9fa63ee9e5ffc..510dae593d2a0e2ce13a2879dde5c31e01d21c21 100644
--- a/third_party/blink/renderer/bindings/core/v8/local_window_proxy.cc
+++ b/third_party/blink/renderer/bindings/core/v8/local_window_proxy.cc
@@ -231,6 +231,7 @@ void LocalWindowProxy::Initialize() {
}
InstallConditionalFeatures();
+ GetFrame()->Client()->DidInstallConditionalFeatures(context, world_->GetWorldId());
if (World().IsMainWorld()) {
GetFrame()->Loader().DispatchDidClearWindowObjectInMainWorld();
diff --git a/third_party/blink/renderer/core/exported/local_frame_client_impl.cc b/third_party/blink/renderer/core/exported/local_frame_client_impl.cc
index f8c512c9db0b88904a562b7d4195790d4b0f86a6..d31ef9bd5b98f584a3296638662ae0d27aa37b65 100644
--- a/third_party/blink/renderer/core/exported/local_frame_client_impl.cc
+++ b/third_party/blink/renderer/core/exported/local_frame_client_impl.cc
@@ -267,6 +267,13 @@ void LocalFrameClientImpl::DidCreateScriptContext(
web_frame_->Client()->DidCreateScriptContext(context, world_id);
}
+void LocalFrameClientImpl::DidInstallConditionalFeatures(
+ v8::Local<v8::Context> context,
+ int32_t world_id) {
+ if (web_frame_->Client())
+ web_frame_->Client()->DidInstallConditionalFeatures(context, world_id);
+}
+
void LocalFrameClientImpl::WillReleaseScriptContext(
v8::Local<v8::Context> context,
int32_t world_id) {
diff --git a/third_party/blink/renderer/core/exported/local_frame_client_impl.h b/third_party/blink/renderer/core/exported/local_frame_client_impl.h
index a055f4b0cc1ccc30752b65d6dc54e638e9b63001..0e6501adbf6f9696429c3fa95357de399ee30a9d 100644
--- a/third_party/blink/renderer/core/exported/local_frame_client_impl.h
+++ b/third_party/blink/renderer/core/exported/local_frame_client_impl.h
@@ -79,6 +79,8 @@ class LocalFrameClientImpl final : public LocalFrameClient {
void DidCreateScriptContext(v8::Local<v8::Context>,
int32_t world_id) override;
+ void DidInstallConditionalFeatures(v8::Local<v8::Context>,
+ int32_t world_id) override;
void WillReleaseScriptContext(v8::Local<v8::Context>,
int32_t world_id) override;
diff --git a/third_party/blink/renderer/core/frame/local_frame_client.h b/third_party/blink/renderer/core/frame/local_frame_client.h
index 1d6facb9ec63abebc5b79a57860765bc8b3f6638..0b58cb679ed34c54e39af661d4a432d482db8c3c 100644
--- a/third_party/blink/renderer/core/frame/local_frame_client.h
+++ b/third_party/blink/renderer/core/frame/local_frame_client.h
@@ -303,6 +303,8 @@ class CORE_EXPORT LocalFrameClient : public FrameClient {
virtual void DidCreateScriptContext(v8::Local<v8::Context>,
int32_t world_id) = 0;
+ virtual void DidInstallConditionalFeatures(v8::Local<v8::Context>,
+ int32_t world_id) = 0;
virtual void WillReleaseScriptContext(v8::Local<v8::Context>,
int32_t world_id) = 0;
virtual bool AllowScriptExtensions() = 0;
diff --git a/third_party/blink/renderer/core/loader/empty_clients.h b/third_party/blink/renderer/core/loader/empty_clients.h
index f3f00e7d6ac44d77dd75997abf8b93eb59476eb3..2010792697b3443dd6f5058bed5ccd0026c4a152 100644
--- a/third_party/blink/renderer/core/loader/empty_clients.h
+++ b/third_party/blink/renderer/core/loader/empty_clients.h
@@ -370,6 +370,8 @@ class CORE_EXPORT EmptyLocalFrameClient : public LocalFrameClient {
void DidCreateScriptContext(v8::Local<v8::Context>,
int32_t world_id) override {}
+ void DidInstallConditionalFeatures(v8::Local<v8::Context>,
+ int32_t world_id) override {}
void WillReleaseScriptContext(v8::Local<v8::Context>,
int32_t world_id) override {}
bool AllowScriptExtensions() override { return false; }

View File

@@ -1,28 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Samuel Attard <samuel.r.attard@gmail.com>
Date: Thu, 20 Sep 2018 17:50:24 -0700
Subject: blink_initialization_order.patch
Backport of https://chromium-review.googlesource.com/c/chromium/src/+/1030530
to fix the order of V8 and Blink initialization. Also fixes order
of DidCreateScriptContext notification with initialization of window globals
to fix electron/electron#13787. The backport landed in Chromium 67 but the
DidCreateScriptContext re-ordering needs to be upstreamed or kept indefinitely
diff --git a/third_party/blink/renderer/bindings/core/v8/local_window_proxy.cc b/third_party/blink/renderer/bindings/core/v8/local_window_proxy.cc
index c845acb8321e94c916798826a168e06df34ffff4..941ca9d3905c0c2f36606655bf60e9e9bd1f9196 100644
--- a/third_party/blink/renderer/bindings/core/v8/local_window_proxy.cc
+++ b/third_party/blink/renderer/bindings/core/v8/local_window_proxy.cc
@@ -211,11 +211,10 @@ void LocalWindowProxy::Initialize() {
GetFrame()->IsMainFrame());
MainThreadDebugger::Instance()->ContextCreated(script_state_, GetFrame(),
origin);
+ InstallConditionalFeatures();
GetFrame()->Client()->DidCreateScriptContext(context, world_->GetWorldId());
}
- InstallConditionalFeatures();
-
if (World().IsMainWorld()) {
GetFrame()->Loader().DispatchDidClearWindowObjectInMainWorld();
}

View File

@@ -52,15 +52,6 @@ index 392cf3d58c64c088596e8d321a2ce37b0ec60b6e..43e30f47240dc10a3a9b950255d4e487
return modifiers;
}
@@ -151,6 +152,8 @@ void GlobalShortcutListenerX11::OnXKeyPressEvent(::XEvent* x_event) {
modifiers |= (x_event->xkey.state & ShiftMask) ? ui::EF_SHIFT_DOWN : 0;
modifiers |= (x_event->xkey.state & ControlMask) ? ui::EF_CONTROL_DOWN : 0;
modifiers |= (x_event->xkey.state & Mod1Mask) ? ui::EF_ALT_DOWN : 0;
+ // For Windows key
+ modifiers |= (x_event->xkey.state & Mod4Mask) ? ui::EF_COMMAND_DOWN: 0;
ui::Accelerator accelerator(
ui::KeyboardCodeFromXKeyEvent(x_event), modifiers);
diff --git a/ui/base/accelerators/media_keys_listener.cc b/ui/base/accelerators/media_keys_listener.cc
index 1145e1f3d79482b5bb468c3128431ac674310e5f..e9f595045e0c076e0735f27dfc38bfbc7951d372 100644
--- a/ui/base/accelerators/media_keys_listener.cc

View File

@@ -0,0 +1,31 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Sesh Sadasivam <sesh@fb.com>
Date: Fri, 31 Jan 2020 19:02:27 -0800
Subject: fix: use native window button positions when MacOS locale is RTL
Classes that inherit from `NSThemeFrame` seem to show window buttons in the
incorrect position when the primary MacOS language is set to an RTL
(right-to-left) language like Arabic or Hebrew. The fix in this commit mirrors
that of `tabbed_browser_window.mm`
(https://chromium-review.googlesource.com/c/chromium/src/+/562603/10/chrome/browser/ui/cocoa/tabbed_browser_window.mm#88).
This change should be upstreamed, and then this patch can be removed.
diff --git a/components/remote_cocoa/app_shim/native_widget_mac_nswindow.mm b/components/remote_cocoa/app_shim/native_widget_mac_nswindow.mm
index 9905e1c8914f852e250480797f43d17bf9d7f794..0016cc129805726d6518036fb181a2a9715af8c5 100644
--- a/components/remote_cocoa/app_shim/native_widget_mac_nswindow.mm
+++ b/components/remote_cocoa/app_shim/native_widget_mac_nswindow.mm
@@ -69,6 +69,13 @@ - (void)mouseDown:(NSEvent*)event {
- (BOOL)usesCustomDrawing {
return NO;
}
+// AppKit's implementation only returns YES if [self class] == [NSThemeFrame
+// class]. See:
+// https://chromium-review.googlesource.com/c/chromium/src/+/562603/10/chrome/browser/ui/cocoa/tabbed_browser_window.mm#88
+- (BOOL)_shouldFlipTrafficLightsForRTL API_AVAILABLE(macosx(10.13)) {
+ return self.window.windowTitlebarLayoutDirection ==
+ NSUserInterfaceLayoutDirectionRightToLeft;
+}
@end
@implementation NativeWidgetMacNSWindowBorderlessFrame

View File

@@ -1,18 +1,26 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: deepak1556 <hop2deep@gmail.com>
Date: Wed, 23 Oct 2019 15:30:18 -0700
From: Shelley Vohr <shelley.vohr@gmail.com>
Date: Tue, 4 Feb 2020 08:59:32 -0700
Subject: Revert "Remove ContentRendererClient::ShouldFork."
This reverts commit 6b068eb8ca4a3c7350bdafa22fc0cf0636ef8b74.
This reverts the CL at https://chromium-review.googlesource.com/c/chromium/src/+/1812128.
We use it to force a new renderer process for navigations, and need to start a new renderer process
for every navigation to keep Node.js working properly. Once Native Modules in the renderer process
are required to be NAPI or context aware (Electron v11), this patch can be removed.
diff --git a/chrome/renderer/chrome_content_renderer_client.cc b/chrome/renderer/chrome_content_renderer_client.cc
index e03ad3a5a115383143d1324164dfd37f87c6f2f2..1c179e0cca8b0b1fc19971d1c9e93d59af7b9383 100644
index a9b2e3fa8067e0adc7430c5e566d7734c2f75681..c564b64b72a604ee7beee2e4d617ca7c18a00d6b 100644
--- a/chrome/renderer/chrome_content_renderer_client.cc
+++ b/chrome/renderer/chrome_content_renderer_client.cc
@@ -1291,6 +1291,17 @@ bool ChromeContentRendererClient::ShouldFork(WebLocalFrame* frame,
return true;
#endif // BUILDFLAG(ENABLE_EXTENSIONS)
@@ -1269,6 +1269,25 @@ bool ChromeContentRendererClient::AllowPopup() {
#endif
}
+bool ChromeContentRendererClient::ShouldFork(WebLocalFrame* frame,
+ const GURL& url,
+ const std::string& http_method,
+ bool is_initial_navigation,
+ bool is_server_redirect) {
+ DCHECK(!frame->Parent());
+
+ // If |url| matches one of the prerendered URLs, stop this navigation and try
@@ -24,84 +32,90 @@ index e03ad3a5a115383143d1324164dfd37f87c6f2f2..1c179e0cca8b0b1fc19971d1c9e93d59
+ return true;
+ }
+
return false;
}
diff --git a/content/renderer/render_view_browsertest.cc b/content/renderer/render_view_browsertest.cc
index b4895b8770bd58d400cc8ca55c74940b25b3a8d5..3c0d6bc9bb50abc5f02e07c24ed8ae424dcda1a5 100644
--- a/content/renderer/render_view_browsertest.cc
+++ b/content/renderer/render_view_browsertest.cc
@@ -1004,6 +1004,73 @@ TEST_F(RenderViewImplTest, BeginNavigationForWebUI) {
FrameHostMsg_OpenURL::ID));
}
+class AlwaysForkingRenderViewTest : public RenderViewImplTest {
+ public:
+ ContentRendererClient* CreateContentRendererClient() override {
+ return new TestContentRendererClient;
+ }
+ return false;
+}
+
+ private:
+ class TestContentRendererClient : public ContentRendererClient {
+ public:
+ bool ShouldFork(blink::WebLocalFrame* frame,
+ const GURL& url,
+ const std::string& http_method,
+ bool is_initial_navigation,
+ bool is_server_redirect) override {
+ return true;
void ChromeContentRendererClient::WillSendRequest(
WebLocalFrame* frame,
ui::PageTransition transition_type,
diff --git a/chrome/renderer/chrome_content_renderer_client.h b/chrome/renderer/chrome_content_renderer_client.h
index b5d52afedb94475f05318bfc35f7e0b595047ee3..c40a6ec13f3ee366dcf9cc5b6440045c89c310b8 100644
--- a/chrome/renderer/chrome_content_renderer_client.h
+++ b/chrome/renderer/chrome_content_renderer_client.h
@@ -131,6 +131,11 @@ class ChromeContentRendererClient
base::SingleThreadTaskRunner* compositor_thread_task_runner) override;
bool RunIdleHandlerWhenWidgetsHidden() override;
bool AllowPopup() override;
+ bool ShouldFork(blink::WebLocalFrame* frame,
+ const GURL& url,
+ const std::string& http_method,
+ bool is_initial_navigation,
+ bool is_server_redirect) override;
void WillSendRequest(blink::WebLocalFrame* frame,
ui::PageTransition transition_type,
const blink::WebURL& url,
diff --git a/content/public/renderer/content_renderer_client.cc b/content/public/renderer/content_renderer_client.cc
index c4c0e27127ff2976db4e78cf5a02bd22d1c667d3..a4318511d1081d4f101cb2f18ca5fa200fb9773c 100644
--- a/content/public/renderer/content_renderer_client.cc
+++ b/content/public/renderer/content_renderer_client.cc
@@ -104,6 +104,14 @@ bool ContentRendererClient::HandleNavigation(
}
#endif
+bool ContentRendererClient::ShouldFork(blink::WebLocalFrame* frame,
+ const GURL& url,
+ const std::string& http_method,
+ bool is_initial_navigation,
+ bool is_server_redirect) {
+ return false;
+}
+
void ContentRendererClient::WillSendRequest(
blink::WebLocalFrame* frame,
ui::PageTransition transition_type,
diff --git a/content/public/renderer/content_renderer_client.h b/content/public/renderer/content_renderer_client.h
index 0a4ec619e96a840b4b4d5b51246de6c91e0f94f2..5dabb49f061b4e0643256cbf9162d128c1e0bacf 100644
--- a/content/public/renderer/content_renderer_client.h
+++ b/content/public/renderer/content_renderer_client.h
@@ -213,6 +213,13 @@ class CONTENT_EXPORT ContentRendererClient {
bool is_redirect);
#endif
+ // Returns true if we should fork a new process for the given navigation.
+ virtual bool ShouldFork(blink::WebLocalFrame* frame,
+ const GURL& url,
+ const std::string& http_method,
+ bool is_initial_navigation,
+ bool is_server_redirect);
+
// Notifies the embedder that the given frame is requesting the resource at
// |url|. If the function returns a valid |new_url|, the request must be
// updated to use it. The |attach_same_site_cookies| output parameter
diff --git a/content/renderer/render_frame_impl.cc b/content/renderer/render_frame_impl.cc
index 3800b761af945bc1592eda7f054199da03183b05..6cabed55988cdfaab422b36a697fc8b0310870a8 100644
--- a/content/renderer/render_frame_impl.cc
+++ b/content/renderer/render_frame_impl.cc
@@ -5798,6 +5798,23 @@ void RenderFrameImpl::BeginNavigation(
int cumulative_bindings = RenderProcess::current()->GetEnabledBindings();
bool should_fork = HasWebUIScheme(url) || HasWebUIScheme(old_url) ||
(cumulative_bindings & kWebUIBindingsPolicyMask);
+
+ if (!should_fork && url.SchemeIs(url::kFileScheme)) {
+ // Fork non-file to file opens (see https://crbug.com/1031119). Note that
+ // this may fork unnecessarily if another tab (hosting a file or not)
+ // targeted this one before its initial navigation, but that shouldn't
+ // cause a problem.
+ should_fork = !old_url.SchemeIs(url::kFileScheme);
+ }
+ };
+};
+
+TEST_F(AlwaysForkingRenderViewTest, BeginNavigationDoesNotForkEmptyUrl) {
+ GURL example_url("http://example.com");
+ GURL empty_url("");
+ if (!should_fork) {
+ // Give the embedder a chance.
+ bool is_initial_navigation = render_view_->history_list_length_ == 0;
+ should_fork = GetContentClient()->renderer()->ShouldFork(
+ frame_, url, info->url_request.HttpMethod().Utf8(),
+ is_initial_navigation, false /* is_redirect */);
+ }
+
+ LoadHTMLWithUrlOverride("<body></body", example_url.spec().c_str());
+ EXPECT_EQ(example_url,
+ GURL(frame()->GetWebFrame()->GetDocumentLoader()->GetUrl()));
+
+ // Empty url should never fork.
+ blink::WebURLRequest request(empty_url);
+ request.SetMode(network::mojom::RequestMode::kNavigate);
+ request.SetRedirectMode(network::mojom::RedirectMode::kManual);
+ request.SetRequestContext(blink::mojom::RequestContextType::INTERNAL);
+ request.SetRequestorOrigin(blink::WebSecurityOrigin::Create(example_url));
+ auto navigation_info = std::make_unique<blink::WebNavigationInfo>();
+ navigation_info->url_request = request;
+ navigation_info->frame_type =
+ network::mojom::RequestContextFrameType::kTopLevel;
+ navigation_info->navigation_policy = blink::kWebNavigationPolicyCurrentTab;
+ frame()->BeginNavigation(std::move(navigation_info));
+ EXPECT_FALSE(render_thread_->sink().GetUniqueMessageMatching(
+ FrameHostMsg_OpenURL::ID));
+}
+
+TEST_F(AlwaysForkingRenderViewTest, BeginNavigationDoesNotForkAboutBlank) {
+ GURL example_url("http://example.com");
+ GURL blank_url(url::kAboutBlankURL);
+
+ LoadHTMLWithUrlOverride("<body></body", example_url.spec().c_str());
+ EXPECT_EQ(example_url,
+ GURL(frame()->GetWebFrame()->GetDocumentLoader()->GetUrl()));
+
+ // about:blank should never fork.
+ blink::WebURLRequest request(blank_url);
+ request.SetMode(network::mojom::RequestMode::kNavigate);
+ request.SetRedirectMode(network::mojom::RedirectMode::kManual);
+ request.SetRequestContext(blink::mojom::RequestContextType::INTERNAL);
+ request.SetRequestorOrigin(blink::WebSecurityOrigin::Create(example_url));
+ auto navigation_info = std::make_unique<blink::WebNavigationInfo>();
+ navigation_info->url_request = request;
+ navigation_info->frame_type =
+ network::mojom::RequestContextFrameType::kTopLevel;
+ navigation_info->navigation_policy = blink::kWebNavigationPolicyCurrentTab;
+ frame()->BeginNavigation(std::move(navigation_info));
+ EXPECT_FALSE(render_thread_->sink().GetUniqueMessageMatching(
+ FrameHostMsg_OpenURL::ID));
+}
+
// This test verifies that when device emulation is enabled, RenderFrameProxy
// continues to receive the original ScreenInfo and not the emualted
// ScreenInfo.
if (should_fork) {
OpenURL(std::move(info));
return; // Suppress the load here.

View File

@@ -36,3 +36,4 @@ remove_serialization_deserialization_of_wasmmoduleobject.patch
64bit_bump_typedarray_max_length_to_2_32-1_elements.patch
test_use_tmpdir_refresh_in_test-esm-windows_js.patch
override_existing_v8_reallocate.patch
feat_enable_passing_cli_flags.patch

View File

@@ -0,0 +1,108 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Shelley Vohr <shelley.vohr@gmail.com>
Date: Wed, 13 Nov 2019 15:39:48 +0000
Subject: feat: enable passing cli flags
This patches enables passing safelisted cli flags to Node.js.
Upstreamed in https://github.com/nodejs/node/pull/30466.
diff --git a/src/node.cc b/src/node.cc
index 461f736beacec67b35c89a42319f99178a1e38e9..c00bfb6ccbe603604fca29268d15d67b208b2e6a 100644
--- a/src/node.cc
+++ b/src/node.cc
@@ -113,8 +113,6 @@
namespace node {
using native_module::NativeModuleEnv;
-using options_parser::kAllowedInEnvironment;
-using options_parser::kDisallowedInEnvironment;
using v8::Boolean;
using v8::EscapableHandleScope;
@@ -670,7 +668,7 @@ void ResetStdio() {
int ProcessGlobalArgs(std::vector<std::string>* args,
std::vector<std::string>* exec_args,
std::vector<std::string>* errors,
- bool is_env) {
+ OptionEnvvarSettings settings) {
// Parse a few arguments which are specific to Node.
std::vector<std::string> v8_args;
@@ -680,7 +678,7 @@ int ProcessGlobalArgs(std::vector<std::string>* args,
exec_args,
&v8_args,
per_process::cli_options.get(),
- is_env ? kAllowedInEnvironment : kDisallowedInEnvironment,
+ settings,
errors);
if (!errors->empty()) return 9;
@@ -851,7 +849,7 @@ int InitializeNodeWithArgs(std::vector<std::string>* argv,
return 9;
}
- const int exit_code = ProcessGlobalArgs(&env_argv, nullptr, errors, true);
+ const int exit_code = ProcessGlobalArgs(&env_argv, nullptr, errors, kAllowedInEnvironment);
if (exit_code != 0) return exit_code;
}
#endif
@@ -859,7 +857,7 @@ int InitializeNodeWithArgs(std::vector<std::string>* argv,
if (g_upstream_node_mode) {
// NOTE(jeremy): indentation is intentionally wrong here, to ease rebasing.
- const int exit_code = ProcessGlobalArgs(argv, exec_argv, errors, false);
+ const int exit_code = ProcessGlobalArgs(argv, exec_argv, errors, kDisallowedInEnvironment);
if (exit_code != 0) return exit_code;
// Set the process.title immediately after processing argv if --title is set.
diff --git a/src/node.h b/src/node.h
index 9c6dcbf7014f7cf87f7f66886cbf255978c244fa..4f2da9a46966199465a33c1fa275d0116d395a56 100644
--- a/src/node.h
+++ b/src/node.h
@@ -223,6 +223,16 @@ NODE_EXTERN void Init(int* argc,
int* exec_argc,
const char*** exec_argv);
+enum OptionEnvvarSettings {
+ kAllowedInEnvironment,
+ kDisallowedInEnvironment
+};
+
+NODE_EXTERN int ProcessGlobalArgs(std::vector<std::string>* args,
+ std::vector<std::string>* exec_args,
+ std::vector<std::string>* errors,
+ OptionEnvvarSettings settings);
+
class NodeArrayBufferAllocator;
// An ArrayBuffer::Allocator class with some Node.js-specific tweaks. If you do
diff --git a/src/node_options.h b/src/node_options.h
index 4ce5551284bb5b1b4194905a9fe619f852933405..404cb72536cdaf8f0320770392e02ac75c303cae 100644
--- a/src/node_options.h
+++ b/src/node_options.h
@@ -248,11 +248,6 @@ HostPort NODE_EXTERN SplitHostPort(const std::string& arg,
std::vector<std::string>* errors);
void GetOptions(const v8::FunctionCallbackInfo<v8::Value>& args);
-enum OptionEnvvarSettings {
- kAllowedInEnvironment,
- kDisallowedInEnvironment
-};
-
enum OptionType {
kNoOp,
kV8Option,
diff --git a/src/node_worker.cc b/src/node_worker.cc
index c8b2e1699f26ac9bfeb373653d35271f9b6c841f..a4db86ad99c75e07960a95247a41ed78e5bf55ca 100644
--- a/src/node_worker.cc
+++ b/src/node_worker.cc
@@ -16,7 +16,7 @@
#include <string>
#include <vector>
-using node::options_parser::kDisallowedInEnvironment;
+using node::kDisallowedInEnvironment;
using v8::Array;
using v8::Boolean;
using v8::Context;

View File

@@ -9,7 +9,11 @@ async function checkIfDocOnlyChange () {
try {
let pullRequestNumber = args.prNumber
if (!pullRequestNumber || isNaN(pullRequestNumber)) {
if (args.prBranch) {
if (args.prURL) {
// CircleCI doesn't provide the PR number for branch builds, but it does provide the PR URL
const pullRequestParts = args.prURL.split('/')
pullRequestNumber = pullRequestParts[pullRequestParts.length - 1]
} else if (args.prBranch) {
// AppVeyor doesn't provide a PR number for branch builds - figure it out from the branch
const prsForBranch = await octokit.pulls.list({
owner: 'electron',
@@ -23,10 +27,6 @@ async function checkIfDocOnlyChange () {
// If there are 0 PRs or more than one PR on a branch, just assume that this is more than a doc change
process.exit(1)
}
} else if (args.prURL) {
// CircleCI doesn't provide the PR number for branch builds, but it does provide the PR URL
const pullRequestParts = args.prURL.split('/')
pullRequestNumber = pullRequestParts[pullRequestParts.length - 1]
}
}
const filesChanged = await octokit.pulls.listFiles({

View File

@@ -51,14 +51,8 @@
"parallel/test-buffer-constructor-node-modules-paths",
"parallel/test-buffer-constructor-outside-node-modules",
"parallel/test-child-process-fork-exec-path",
"parallel/test-child-process-windows-hide",
"parallel/test-cli-bad-options",
"parallel/test-cli-eval",
"parallel/test-cli-node-options",
"parallel/test-cli-node-print-help",
"parallel/test-cli-syntax-eval",
"parallel/test-cli-syntax-piped-bad",
"parallel/test-cli-syntax-piped-good",
"parallel/test-cli-eval",
"parallel/test-code-cache",
"parallel/test-common-gc",
"parallel/test-crypto",
@@ -86,7 +80,6 @@
"parallel/test-debug-usage",
"parallel/test-debugger-pid",
"parallel/test-domain-abort-on-uncaught",
"parallel/test-domain-async-id-map-leak",
"parallel/test-domain-with-abort-on-uncaught-exception",
"parallel/test-dummy-stdio",
"parallel/test-freeze-intrinsics",
@@ -108,8 +101,7 @@
"parallel/test-inspector-tracing-domain",
"parallel/test-inspector-vm-global-accessors-getter-sideeffect",
"parallel/test-inspector-vm-global-accessors-sideeffects",
"parallel/test-inspector-workers-flat-list",
"parallel/test-internal-util-weakreference",
"parallel/test-inspector-heap-allocation-tracker",
"parallel/test-module-loading-globalpaths",
"parallel/test-module-version",
"parallel/test-openssl-ca-options",
@@ -121,12 +113,11 @@
"parallel/test-process-exception-capture",
"parallel/test-process-exception-capture-should-abort-on-uncaught",
"parallel/test-process-exception-capture-should-abort-on-uncaught-setflagsfromstring",
"parallel/test-process-exec-argv",
"parallel/test-process-exit-code",
"parallel/test-process-external-stdio-close",
"parallel/test-process-external-stdio-close-spawn",
"parallel/test-process-versions",
"parallel/test-readline-interface",
"parallel/test-inspector-tracing-domain",
"parallel/test-repl",
"parallel/test-repl-harmony",
"parallel/test-repl-pretty-custom-stack",
@@ -136,7 +127,6 @@
"parallel/test-repl-tab-complete",
"parallel/test-repl-uncaught-exception",
"parallel/test-repl-underscore",
"parallel/test-security-revert-unknown",
"parallel/test-signal-handler",
"parallel/test-source-map",
"parallel/test-stdout-close-catch",
@@ -242,9 +232,6 @@
"report/test-report-uncaught-exception",
"report/test-report-writereport",
"sequential/test-child-process-execsync",
"sequential/test-cli-syntax-bad",
"sequential/test-cli-syntax-good",
"sequential/test-cli-syntax-require",
"sequential/test-cpu-prof-default",
"sequential/test-cpu-prof-dir-absolute",
"sequential/test-cpu-prof-dir-and-name",
@@ -252,11 +239,9 @@
"sequential/test-cpu-prof-dir-worker",
"sequential/test-cpu-prof-drained",
"sequential/test-cpu-prof-exit",
"sequential/test-cpu-prof-invalid-options",
"sequential/test-cpu-prof-kill",
"sequential/test-cpu-prof-name",
"sequential/test-cpu-prof-worker-argv",
"sequential/test-deprecation-flags",
"sequential/test-fs-watch",
"sequential/test-heap-prof",
"sequential/test-heapdump",

View File

@@ -35,9 +35,8 @@ const NPX_CMD = process.platform === 'win32' ? 'npx.cmd' : 'npx'
const runners = new Map([
['main', { description: 'Main process specs', run: runMainProcessElectronTests }],
['remote', { description: 'Remote based specs', run: runRemoteBasedElectronTests }]
// TODO(codebytere): refactor native tests to only depend on what we need
/* ['native', { description: 'Native specs', run: runNativeElectronTests }] */
['remote', { description: 'Remote based specs', run: runRemoteBasedElectronTests }],
['native', { description: 'Native specs', run: runNativeElectronTests }]
])
const specHashPath = path.resolve(__dirname, '../spec/.hash')

View File

@@ -1,7 +1,6 @@
param([string]$gomaDir=$PWD)
$cmdPath = Join-Path -Path $gomaDir -ChildPath "goma_ctl.py"
Start-Process -FilePath cmd -ArgumentList "/C", "python", "$cmdPath", "ensure_start"
$env:GLOG_logtostderr = "true"
$timedOut = $false; $waitTime = 0; $waitIncrement = 5; $timeout=120;
Do { sleep $waitIncrement; $timedOut = (($waitTime+=$waitIncrement) -gt $timeout); iex "$gomaDir\gomacc.exe port 2" > $null; } Until(($LASTEXITCODE -eq 0) -or $timedOut)
if ($timedOut) {

View File

@@ -4,7 +4,7 @@ import argparse
import os
import sys
from lib.config import LINUX_BINARIES
from lib.config import LINUX_BINARIES, enable_verbose_mode
from lib.util import execute, get_out_dir
def strip_binaries(directory, target_cpu):
@@ -22,10 +22,12 @@ def strip_binary(binary_path, target_cpu):
strip = 'mips64el-redhat-linux-strip'
else:
strip = 'strip'
execute([strip, binary_path])
execute([strip, '--preserve-dates', binary_path])
def main():
args = parse_args()
if args.verbose:
enable_verbose_mode()
if args.file:
strip_binary(args.file, args.target_cpu)
else:

View File

@@ -6,10 +6,14 @@
#include <memory>
#include <string>
#include <unordered_set>
#include <utility>
#include <vector>
#include "base/command_line.h"
#include "base/feature_list.h"
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
#include "base/task/thread_pool/thread_pool_instance.h"
#include "base/threading/thread_task_runner_handle.h"
#include "electron/electron_version.h"
@@ -29,6 +33,49 @@
#include "shell/common/crash_reporter/crash_reporter_win.h"
#endif
namespace {
// Initialize Node.js cli options to pass to Node.js
// See https://nodejs.org/api/cli.html#cli_options
void SetNodeCliFlags() {
// Options that are unilaterally disallowed
const std::unordered_set<base::StringPiece, base::StringPieceHash>
disallowed = {"--openssl-config", "--use-bundled-ca", "--use-openssl-ca",
"--force-fips", "--enable-fips"};
const auto argv = base::CommandLine::ForCurrentProcess()->argv();
std::vector<std::string> args;
// TODO(codebytere): We need to set the first entry in args to the
// process name owing to src/node_options-inl.h#L286-L290 but this is
// redundant and so should be refactored upstream.
args.reserve(argv.size() + 1);
args.emplace_back("electron");
for (const auto& arg : argv) {
#if defined(OS_WIN)
const auto& option = base::UTF16ToUTF8(arg);
#else
const auto& option = arg;
#endif
const auto stripped = base::StringPiece(option).substr(0, option.find('='));
if (disallowed.count(stripped) != 0) {
LOG(ERROR) << "The Node.js cli flag " << stripped
<< " is not supported in Electron";
} else {
args.push_back(option);
}
}
std::vector<std::string> errors;
// Node.js itself will output parsing errors to
// console so we don't need to handle that ourselves
ProcessGlobalArgs(&args, nullptr, &errors, node::kDisallowedInEnvironment);
}
} // namespace
namespace electron {
#if !defined(OS_LINUX)
@@ -64,6 +111,9 @@ int NodeMain(int argc, char* argv[]) {
// Explicitly register electron's builtin modules.
NodeBindings::RegisterBuiltinModules();
// Parse and set Node.js cli flags.
SetNodeCliFlags();
int exec_argc;
const char** exec_argv;
node::Init(&argc, const_cast<const char**>(argv), &exec_argc, &exec_argv);

View File

@@ -767,17 +767,18 @@ void SetSpellCheckerDictionaryDownloadURL(gin_helper::ErrorThrower thrower,
}
bool Session::AddWordToSpellCheckerDictionary(const std::string& word) {
#if BUILDFLAG(USE_BROWSER_SPELLCHECKER)
if (spellcheck::UseBrowserSpellChecker()) {
spellcheck_platform::AddWord(base::UTF8ToUTF16(word));
}
#endif
SpellcheckService* spellcheck =
SpellcheckService* service =
SpellcheckServiceFactory::GetForContext(browser_context_.get());
if (!spellcheck)
if (!service)
return false;
return spellcheck->GetCustomDictionary()->AddWord(word);
#if BUILDFLAG(USE_BROWSER_SPELLCHECKER)
if (spellcheck::UseBrowserSpellChecker()) {
spellcheck_platform::AddWord(service->platform_spell_checker(),
base::UTF8ToUTF16(word));
}
#endif
return service->GetCustomDictionary()->AddWord(word);
}
#endif

View File

@@ -38,30 +38,30 @@ struct Converter<URLPattern> {
};
template <>
struct Converter<content::ResourceType> {
struct Converter<blink::mojom::ResourceType> {
static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
content::ResourceType type) {
blink::mojom::ResourceType type) {
const char* result;
switch (type) {
case content::ResourceType::kMainFrame:
case blink::mojom::ResourceType::kMainFrame:
result = "mainFrame";
break;
case content::ResourceType::kSubFrame:
case blink::mojom::ResourceType::kSubFrame:
result = "subFrame";
break;
case content::ResourceType::kStylesheet:
case blink::mojom::ResourceType::kStylesheet:
result = "stylesheet";
break;
case content::ResourceType::kScript:
case blink::mojom::ResourceType::kScript:
result = "script";
break;
case content::ResourceType::kImage:
case blink::mojom::ResourceType::kImage:
result = "image";
break;
case content::ResourceType::kObject:
case blink::mojom::ResourceType::kObject:
result = "object";
break;
case content::ResourceType::kXhr:
case blink::mojom::ResourceType::kXhr:
result = "xhr";
break;
default:

View File

@@ -77,6 +77,11 @@ void BrowserProcessImpl::ApplyProxyModeFromCommandLine(
}
}
BuildState* BrowserProcessImpl::GetBuildState() {
NOTIMPLEMENTED();
return nullptr;
}
void BrowserProcessImpl::PostEarlyInitialization() {
// Mock user prefs, as we only need to track changes for a
// in memory pref store. There are no persistent preferences

View File

@@ -38,6 +38,7 @@ class BrowserProcessImpl : public BrowserProcess {
static void ApplyProxyModeFromCommandLine(ValueMapPrefStore* pref_store);
BuildState* GetBuildState() override;
void PostEarlyInitialization();
void PreCreateThreads();
void PostDestroyThreads() {}

View File

@@ -186,6 +186,63 @@ const base::FilePath::StringPieceType kPathDelimiter = FILE_PATH_LITERAL(";");
const base::FilePath::StringPieceType kPathDelimiter = FILE_PATH_LITERAL(":");
#endif
#if BUILDFLAG(ENABLE_ELECTRON_EXTENSIONS)
// Used by the GetPrivilegeRequiredByUrl() and GetProcessPrivilege() functions
// below. Extension, and isolated apps require different privileges to be
// granted to their RenderProcessHosts. This classification allows us to make
// sure URLs are served by hosts with the right set of privileges.
enum RenderProcessHostPrivilege {
PRIV_NORMAL,
PRIV_HOSTED,
PRIV_ISOLATED,
PRIV_EXTENSION,
};
RenderProcessHostPrivilege GetPrivilegeRequiredByUrl(
const GURL& url,
extensions::ExtensionRegistry* registry) {
// Default to a normal renderer cause it is lower privileged. This should only
// occur if the URL on a site instance is either malformed, or uninitialized.
// If it is malformed, then there is no need for better privileges anyways.
// If it is uninitialized, but eventually settles on being an a scheme other
// than normal webrenderer, the navigation logic will correct us out of band
// anyways.
if (!url.is_valid())
return PRIV_NORMAL;
if (!url.SchemeIs(extensions::kExtensionScheme))
return PRIV_NORMAL;
return PRIV_EXTENSION;
}
RenderProcessHostPrivilege GetProcessPrivilege(
content::RenderProcessHost* process_host,
extensions::ProcessMap* process_map,
extensions::ExtensionRegistry* registry) {
std::set<std::string> extension_ids =
process_map->GetExtensionsInProcess(process_host->GetID());
if (extension_ids.empty())
return PRIV_NORMAL;
return PRIV_EXTENSION;
}
const extensions::Extension* GetEnabledExtensionFromEffectiveURL(
content::BrowserContext* context,
const GURL& effective_url) {
if (!effective_url.SchemeIs(extensions::kExtensionScheme))
return nullptr;
extensions::ExtensionRegistry* registry =
extensions::ExtensionRegistry::Get(context);
if (!registry)
return nullptr;
return registry->enabled_extensions().GetByID(effective_url.host());
}
#endif // BUILDFLAG(ENABLE_ELECTRON_EXTENSIONS)
} // namespace
// static
@@ -760,6 +817,40 @@ void ElectronBrowserClient::SiteInstanceGotProcess(
#endif // BUILDFLAG(ENABLE_ELECTRON_EXTENSIONS)
}
bool ElectronBrowserClient::IsSuitableHost(
content::RenderProcessHost* process_host,
const GURL& site_url) {
#if BUILDFLAG(ENABLE_ELECTRON_EXTENSIONS)
auto* browser_context = process_host->GetBrowserContext();
extensions::ExtensionRegistry* registry =
extensions::ExtensionRegistry::Get(browser_context);
extensions::ProcessMap* process_map =
extensions::ProcessMap::Get(browser_context);
// Otherwise, just make sure the process privilege matches the privilege
// required by the site.
RenderProcessHostPrivilege privilege_required =
GetPrivilegeRequiredByUrl(site_url, registry);
return GetProcessPrivilege(process_host, process_map, registry) ==
privilege_required;
#else
return content::ContentBrowserClient::IsSuitableHost(process_host, site_url);
#endif
}
bool ElectronBrowserClient::ShouldUseProcessPerSite(
content::BrowserContext* browser_context,
const GURL& effective_url) {
#if BUILDFLAG(ENABLE_ELECTRON_EXTENSIONS)
const extensions::Extension* extension =
GetEnabledExtensionFromEffectiveURL(browser_context, effective_url);
return extension != nullptr;
#else
return content::ContentBrowserClient::ShouldUseProcessPerSite(browser_context,
effective_url);
#endif
}
void ElectronBrowserClient::SiteInstanceDeleting(
content::SiteInstance* site_instance) {
// We are storing weak_ptr, is it fundamental to maintain the map up-to-date

View File

@@ -221,6 +221,10 @@ class ElectronBrowserClient : public content::ContentBrowserClient,
bool first_auth_attempt,
LoginAuthRequiredCallback auth_required_callback) override;
void SiteInstanceGotProcess(content::SiteInstance* site_instance) override;
bool IsSuitableHost(content::RenderProcessHost* process_host,
const GURL& site_url) override;
bool ShouldUseProcessPerSite(content::BrowserContext* browser_context,
const GURL& effective_url) override;
// content::RenderProcessHostObserver:
void RenderProcessHostDestroyed(content::RenderProcessHost* host) override;

View File

@@ -143,7 +143,7 @@ void ElectronExtensionsBrowserClient::LoadResourceFromResourceBundle(
namespace {
bool AllowCrossRendererResourceLoad(const GURL& url,
content::ResourceType resource_type,
blink::mojom::ResourceType resource_type,
ui::PageTransition page_transition,
int child_id,
bool is_incognito,
@@ -174,7 +174,7 @@ bool AllowCrossRendererResourceLoad(const GURL& url,
bool ElectronExtensionsBrowserClient::AllowCrossRendererResourceLoad(
const GURL& url,
content::ResourceType resource_type,
blink::mojom::ResourceType resource_type,
ui::PageTransition page_transition,
int child_id,
bool is_incognito,

View File

@@ -14,6 +14,7 @@
#include "build/build_config.h"
#include "extensions/browser/extensions_browser_client.h"
#include "mojo/public/cpp/bindings/pending_remote.h"
#include "third_party/blink/public/mojom/loader/resource_load_info.mojom-shared.h"
class PrefService;
@@ -70,7 +71,7 @@ class ElectronExtensionsBrowserClient
bool send_cors_header) override;
bool AllowCrossRendererResourceLoad(
const GURL& url,
content::ResourceType resource_type,
blink::mojom::ResourceType resource_type,
ui::PageTransition page_transition,
int child_id,
bool is_incognito,

View File

@@ -11,6 +11,7 @@
#include "chrome/browser/browser_process.h"
#include "chrome/browser/net/chrome_mojo_proxy_resolver_factory.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/cors_exempt_headers.h"
#include "content/public/browser/network_service_instance.h"
#include "content/public/common/content_features.h"
#include "content/public/common/service_names.mojom.h"
@@ -154,6 +155,10 @@ SystemNetworkContextManager::CreateDefaultNetworkContextParams() {
network::mojom::NetworkContextParamsPtr network_context_params =
network::mojom::NetworkContextParams::New();
// This is required to avoid blocking X-Requested-With headers sent by PPAPI
// plugins, more info crbug.com/940331
content::UpdateCorsExemptHeader(network_context_params.get());
network_context_params->enable_brotli = true;
network_context_params->enable_referrers = true;

View File

@@ -41,9 +41,9 @@ void NodeDebugger::Start() {
std::vector<std::string> v8_args;
std::vector<std::string> errors;
// TODO(codebytere): remove this parsing and use ProcessGlobalArgs
node::options_parser::Parse(&args, &exec_args, &v8_args, &options,
node::options_parser::kDisallowedInEnvironment,
&errors);
node::kDisallowedInEnvironment, &errors);
if (!errors.empty()) {
// TODO(jeremy): what's the appropriate behaviour here?

View File

@@ -50,8 +50,8 @@ END
//
VS_VERSION_INFO VERSIONINFO
FILEVERSION 9,0,0,20200205
PRODUCTVERSION 9,0,0,20200205
FILEVERSION 10,0,0,20200209
PRODUCTVERSION 10,0,0,20200209
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
FILEFLAGS 0x1L
@@ -68,12 +68,12 @@ BEGIN
BEGIN
VALUE "CompanyName", "GitHub, Inc."
VALUE "FileDescription", "Electron"
VALUE "FileVersion", "9.0.0"
VALUE "FileVersion", "10.0.0"
VALUE "InternalName", "electron.exe"
VALUE "LegalCopyright", "Copyright (C) 2015 GitHub, Inc. All rights reserved."
VALUE "OriginalFilename", "electron.exe"
VALUE "ProductName", "Electron"
VALUE "ProductVersion", "9.0.0"
VALUE "ProductVersion", "10.0.0"
VALUE "SquirrelAwareVersion", "1"
END
END

View File

@@ -3,8 +3,6 @@
// found in the LICENSE file.
#include "shell/browser/ui/x/window_state_watcher.h"
#include "ui/events/platform/platform_event_source.h"
#include "ui/gfx/x/x11.h"
#include "ui/gfx/x/x11_atom_cache.h"
@@ -12,22 +10,22 @@ namespace electron {
WindowStateWatcher::WindowStateWatcher(NativeWindowViews* window)
: window_(window), widget_(window->GetAcceleratedWidget()) {
ui::PlatformEventSource::GetInstance()->AddPlatformEventObserver(this);
ui::X11EventSource::GetInstance()->AddXEventObserver(this);
}
WindowStateWatcher::~WindowStateWatcher() {
ui::PlatformEventSource::GetInstance()->RemovePlatformEventObserver(this);
ui::X11EventSource::GetInstance()->RemoveXEventObserver(this);
}
void WindowStateWatcher::WillProcessEvent(const ui::PlatformEvent& event) {
if (IsWindowStateEvent(event)) {
void WindowStateWatcher::WillProcessXEvent(XEvent* xev) {
if (IsWindowStateEvent(xev)) {
was_minimized_ = window_->IsMinimized();
was_maximized_ = window_->IsMaximized();
}
}
void WindowStateWatcher::DidProcessEvent(const ui::PlatformEvent& event) {
if (IsWindowStateEvent(event)) {
void WindowStateWatcher::DidProcessXEvent(XEvent* xev) {
if (IsWindowStateEvent(xev)) {
bool is_minimized = window_->IsMinimized();
bool is_maximized = window_->IsMaximized();
bool is_fullscreen = window_->IsFullscreen();
@@ -55,10 +53,10 @@ void WindowStateWatcher::DidProcessEvent(const ui::PlatformEvent& event) {
}
}
bool WindowStateWatcher::IsWindowStateEvent(const ui::PlatformEvent& event) {
::Atom changed_atom = event->xproperty.atom;
bool WindowStateWatcher::IsWindowStateEvent(XEvent* xev) {
::Atom changed_atom = xev->xproperty.atom;
return (changed_atom == gfx::GetAtom("_NET_WM_STATE") &&
event->type == PropertyNotify && event->xproperty.window == widget_);
xev->type == PropertyNotify && xev->xproperty.window == widget_);
}
} // namespace electron

View File

@@ -5,24 +5,24 @@
#ifndef SHELL_BROWSER_UI_X_WINDOW_STATE_WATCHER_H_
#define SHELL_BROWSER_UI_X_WINDOW_STATE_WATCHER_H_
#include "ui/events/platform/platform_event_observer.h"
#include "ui/events/platform/x11/x11_event_source.h"
#include "shell/browser/native_window_views.h"
namespace electron {
class WindowStateWatcher : public ui::PlatformEventObserver {
class WindowStateWatcher : public ui::XEventObserver {
public:
explicit WindowStateWatcher(NativeWindowViews* window);
~WindowStateWatcher() override;
protected:
// ui::PlatformEventObserver:
void WillProcessEvent(const ui::PlatformEvent& event) override;
void DidProcessEvent(const ui::PlatformEvent& event) override;
// ui::XEventObserver:
void WillProcessXEvent(XEvent* xev) override;
void DidProcessXEvent(XEvent* xev) override;
private:
bool IsWindowStateEvent(const ui::PlatformEvent& event);
bool IsWindowStateEvent(XEvent* xev);
NativeWindowViews* window_;
gfx::AcceleratedWidget widget_;

View File

@@ -9,6 +9,10 @@
"extension_types": ["extension"],
"contexts": ["blessed_extension"]
},
"extension.getBackgroundPage": {
"contexts": ["blessed_extension"],
"disallow_for_service_workers": true
},
"extension.getURL": {
"contexts": ["blessed_extension", "unblessed_extension", "content_script"]
}

View File

@@ -12,6 +12,20 @@
"properties": {
},
"functions": [
{
"name": "getBackgroundPage",
"nocompile": true,
"type": "function",
"description": "Returns the JavaScript 'window' object for the background page running inside the current extension. Returns null if the extension has no background page.",
"parameters": [],
"returns": {
"type": "object",
"optional": true,
"name": "backgroundPageGlobal",
"isInstanceOf": "Window",
"additionalProperties": { "type": "any" }
}
},
{
"name": "getURL",
"deprecated": "Please use $(ref:runtime.getURL).",

View File

@@ -1,6 +1,7 @@
[
{
"namespace": "tabs",
"description": "Use the <code>chrome.tabs</code> API to interact with the browser's tab system. You can use this API to create, modify, and rearrange tabs in the browser.",
"functions": [
{
"name": "executeScript",

View File

@@ -8,6 +8,7 @@
#include <memory>
#include <set>
#include <string>
#include <unordered_set>
#include <utility>
#include <vector>
@@ -136,7 +137,51 @@ bool IsPackagedApp() {
#endif
}
// Initialize Node.js cli options to pass to Node.js
// See https://nodejs.org/api/cli.html#cli_options
void SetNodeCliFlags() {
// Only allow DebugOptions in non-ELECTRON_RUN_AS_NODE mode
const std::unordered_set<base::StringPiece, base::StringPieceHash> allowed = {
"--inspect", "--inspect-brk",
"--inspect-port", "--debug",
"--debug-brk", "--debug-port",
"--inspect-brk-node", "--inspect-publish-uid",
};
const auto argv = base::CommandLine::ForCurrentProcess()->argv();
std::vector<std::string> args;
// TODO(codebytere): We need to set the first entry in args to the
// process name owing to src/node_options-inl.h#L286-L290 but this is
// redundant and so should be refactored upstream.
args.reserve(argv.size() + 1);
args.emplace_back("electron");
for (const auto& arg : argv) {
#if defined(OS_WIN)
const auto& option = base::UTF16ToUTF8(arg);
#else
const auto& option = arg;
#endif
const auto stripped = base::StringPiece(option).substr(0, option.find('='));
if (allowed.count(stripped) != 0)
args.push_back(option);
}
std::vector<std::string> errors;
const int exit_code = ProcessGlobalArgs(&args, nullptr, &errors,
node::kDisallowedInEnvironment);
if (exit_code != 0) {
if (!errors.empty())
LOG(INFO) << base::JoinString(errors, " ");
else
LOG(INFO) << "Error parsing Node.js cli flags";
}
}
// Initialize NODE_OPTIONS to pass to Node.js
// See https://nodejs.org/api/cli.html#cli_node_options_options
void SetNodeOptions(base::Environment* env) {
// Options that are unilaterally disallowed
const std::set<std::string> disallowed = {
@@ -157,7 +202,7 @@ void SetNodeOptions(base::Environment* env) {
for (const auto& part : parts) {
// Strip off values passed to individual NODE_OPTIONs
std::string option = part.substr(0, part.find("="));
std::string option = part.substr(0, part.find('='));
if (is_packaged_app &&
allowed_in_packaged.find(option) == allowed_in_packaged.end()) {
@@ -270,6 +315,9 @@ void NodeBindings::Initialize() {
// Explicitly register electron's builtin modules.
RegisterBuiltinModules();
// Parse and set Node.js cli flags.
SetNodeCliFlags();
// pass non-null program name to argv so it doesn't crash
// trying to index into a nullptr
int argc = 1;

View File

@@ -50,6 +50,10 @@ class RenderFramePersistenceStore final : public content::RenderFrameObserver {
v8::Local<v8::Value> proxy_value);
v8::MaybeLocal<v8::Value> GetCachedProxiedObject(v8::Local<v8::Value> from);
base::WeakPtr<RenderFramePersistenceStore> GetWeakPtr() {
return weak_factory_.GetWeakPtr();
}
private:
// func_id ==> { function, owning_context }
std::map<size_t, FunctionContextPair> functions_;

View File

@@ -111,25 +111,31 @@ bool IsPlainArray(const v8::Local<v8::Value>& arr) {
class FunctionLifeMonitor final : public ObjectLifeMonitor {
public:
static void BindTo(v8::Isolate* isolate,
v8::Local<v8::Object> target,
context_bridge::RenderFramePersistenceStore* store,
size_t func_id) {
static void BindTo(
v8::Isolate* isolate,
v8::Local<v8::Object> target,
base::WeakPtr<context_bridge::RenderFramePersistenceStore> store,
size_t func_id) {
new FunctionLifeMonitor(isolate, target, store, func_id);
}
protected:
FunctionLifeMonitor(v8::Isolate* isolate,
v8::Local<v8::Object> target,
context_bridge::RenderFramePersistenceStore* store,
size_t func_id)
FunctionLifeMonitor(
v8::Isolate* isolate,
v8::Local<v8::Object> target,
base::WeakPtr<context_bridge::RenderFramePersistenceStore> store,
size_t func_id)
: ObjectLifeMonitor(isolate, target), store_(store), func_id_(func_id) {}
~FunctionLifeMonitor() override = default;
void RunDestructor() override { store_->functions().erase(func_id_); }
void RunDestructor() override {
if (!store_)
return;
store_->functions().erase(func_id_);
}
private:
context_bridge::RenderFramePersistenceStore* store_;
base::WeakPtr<context_bridge::RenderFramePersistenceStore> store_;
size_t func_id_;
};
@@ -176,7 +182,7 @@ v8::MaybeLocal<v8::Value> PassValueToOtherContext(
base::BindRepeating(&ProxyFunctionWrapper, store, func_id));
FunctionLifeMonitor::BindTo(destination_context->GetIsolate(),
v8::Local<v8::Object>::Cast(proxy_func),
store, func_id);
store->GetWeakPtr(), func_id);
store->CacheProxiedObject(value, proxy_func);
return v8::MaybeLocal<v8::Value>(proxy_func);
}

View File

@@ -57,7 +57,7 @@ void ElectronRenderFrameObserver::DidClearWindowObject() {
renderer_client_->DidClearWindowObject(render_frame_);
}
void ElectronRenderFrameObserver::DidCreateScriptContext(
void ElectronRenderFrameObserver::DidInstallConditionalFeatures(
v8::Handle<v8::Context> context,
int world_id) {
if (ShouldNotifyClient(world_id))

View File

@@ -45,8 +45,8 @@ class ElectronRenderFrameObserver : public content::RenderFrameObserver {
// content::RenderFrameObserver:
void DidClearWindowObject() override;
void DidCreateScriptContext(v8::Handle<v8::Context> context,
int world_id) override;
void DidInstallConditionalFeatures(v8::Handle<v8::Context> context,
int world_id) override;
void DraggableRegionsChanged() override;
void WillReleaseScriptContext(v8::Local<v8::Context> context,
int world_id) override;

View File

@@ -888,8 +888,12 @@ describe('Menu module', function () {
let output = ''
appProcess.stdout.on('data', data => { output += data })
appProcess.stderr.on('data', data => { output += data })
await emittedOnce(appProcess, 'exit')
const [code] = await emittedOnce(appProcess, 'exit')
if (!output.includes('Window has no menu')) {
console.log(code, output)
}
expect(output).to.include('Window has no menu')
})
})

View File

@@ -29,8 +29,14 @@ describe('WebContentsView', () => {
it('does not crash on exit', async () => {
const appPath = path.join(__dirname, 'fixtures', 'api', 'leak-exit-webcontentsview.js')
const electronPath = process.execPath
const appProcess = ChildProcess.spawn(electronPath, [appPath])
const appProcess = ChildProcess.spawn(electronPath, ['--enable-logging', appPath])
let output = ''
appProcess.stdout.on('data', data => { output += data })
appProcess.stderr.on('data', data => { output += data })
const [code] = await emittedOnce(appProcess, 'exit')
if (code !== 0) {
console.log(code, output)
}
expect(code).to.equal(0)
})
})

View File

@@ -31,8 +31,8 @@ ifdescribe(process.electronBinding('features').isExtensionsEnabled())('chrome ex
// extension registry is redirected to the main session. so installing an
// extension in an in-memory session results in it being installed in the
// default session.
const customSession = session.fromPartition(`persist:${require('uuid').v4()}`);
(customSession as any).loadExtension(path.join(fixtures, 'extensions', 'red-bg'))
const customSession = session.fromPartition(`persist:${require('uuid').v4()}`)
await customSession.loadExtension(path.join(fixtures, 'extensions', 'red-bg'))
const w = new BrowserWindow({ show: false, webPreferences: { session: customSession } })
await w.loadURL(url)
const bg = await w.webContents.executeJavaScript('document.documentElement.style.backgroundColor')
@@ -41,14 +41,14 @@ ifdescribe(process.electronBinding('features').isExtensionsEnabled())('chrome ex
it('removes an extension', async () => {
const customSession = session.fromPartition(`persist:${require('uuid').v4()}`)
const { id } = await (customSession as any).loadExtension(path.join(fixtures, 'extensions', 'red-bg'))
const { id } = await customSession.loadExtension(path.join(fixtures, 'extensions', 'red-bg'))
{
const w = new BrowserWindow({ show: false, webPreferences: { session: customSession } })
await w.loadURL(url)
const bg = await w.webContents.executeJavaScript('document.documentElement.style.backgroundColor')
expect(bg).to.equal('red')
}
(customSession as any).removeExtension(id)
customSession.removeExtension(id)
{
const w = new BrowserWindow({ show: false, webPreferences: { session: customSession } })
await w.loadURL(url)
@@ -59,21 +59,21 @@ ifdescribe(process.electronBinding('features').isExtensionsEnabled())('chrome ex
it('lists loaded extensions in getAllExtensions', async () => {
const customSession = session.fromPartition(`persist:${require('uuid').v4()}`)
const e = await (customSession as any).loadExtension(path.join(fixtures, 'extensions', 'red-bg'))
expect((customSession as any).getAllExtensions()).to.deep.equal([e]);
(customSession as any).removeExtension(e.id)
expect((customSession as any).getAllExtensions()).to.deep.equal([])
const e = await customSession.loadExtension(path.join(fixtures, 'extensions', 'red-bg'))
expect(customSession.getAllExtensions()).to.deep.equal([e])
customSession.removeExtension(e.id)
expect(customSession.getAllExtensions()).to.deep.equal([])
})
it('gets an extension by id', async () => {
const customSession = session.fromPartition(`persist:${require('uuid').v4()}`)
const e = await (customSession as any).loadExtension(path.join(fixtures, 'extensions', 'red-bg'))
expect((customSession as any).getExtension(e.id)).to.deep.equal(e)
const e = await customSession.loadExtension(path.join(fixtures, 'extensions', 'red-bg'))
expect(customSession.getExtension(e.id)).to.deep.equal(e)
})
it('confines an extension to the session it was loaded in', async () => {
const customSession = session.fromPartition(`persist:${require('uuid').v4()}`);
(customSession as any).loadExtension(path.join(fixtures, 'extensions', 'red-bg'))
const customSession = session.fromPartition(`persist:${require('uuid').v4()}`)
customSession.loadExtension(path.join(fixtures, 'extensions', 'red-bg'))
const w = new BrowserWindow({ show: false }) // not in the session
await w.loadURL(url)
const bg = await w.webContents.executeJavaScript('document.documentElement.style.backgroundColor')
@@ -83,8 +83,8 @@ ifdescribe(process.electronBinding('features').isExtensionsEnabled())('chrome ex
describe('chrome.runtime', () => {
let content: any
before(async () => {
const customSession = session.fromPartition(`persist:${require('uuid').v4()}`);
(customSession as any).loadExtension(path.join(fixtures, 'extensions', 'chrome-runtime'))
const customSession = session.fromPartition(`persist:${require('uuid').v4()}`)
customSession.loadExtension(path.join(fixtures, 'extensions', 'chrome-runtime'))
const w = new BrowserWindow({ show: false, webPreferences: { session: customSession } })
try {
await w.loadURL(url)
@@ -107,8 +107,8 @@ ifdescribe(process.electronBinding('features').isExtensionsEnabled())('chrome ex
describe('chrome.storage', () => {
it('stores and retrieves a key', async () => {
const customSession = session.fromPartition(`persist:${require('uuid').v4()}`);
(customSession as any).loadExtension(path.join(fixtures, 'extensions', 'chrome-storage'))
const customSession = session.fromPartition(`persist:${require('uuid').v4()}`)
await customSession.loadExtension(path.join(fixtures, 'extensions', 'chrome-storage'))
const w = new BrowserWindow({ show: false, webPreferences: { session: customSession, nodeIntegration: true } })
try {
const p = emittedOnce(ipcMain, 'storage-success')
@@ -124,7 +124,7 @@ ifdescribe(process.electronBinding('features').isExtensionsEnabled())('chrome ex
describe('chrome.tabs', () => {
it('executeScript', async () => {
const customSession = session.fromPartition(`persist:${require('uuid').v4()}`)
;(customSession as any).loadExtension(path.join(fixtures, 'extensions', 'chrome-api'))
await customSession.loadExtension(path.join(fixtures, 'extensions', 'chrome-api'))
const w = new BrowserWindow({ show: false, webPreferences: { session: customSession, nodeIntegration: true } })
await w.loadURL(url)
@@ -139,7 +139,7 @@ ifdescribe(process.electronBinding('features').isExtensionsEnabled())('chrome ex
it('sendMessage receives the response', async function () {
const customSession = session.fromPartition(`persist:${require('uuid').v4()}`)
;(customSession as any).loadExtension(path.join(fixtures, 'extensions', 'chrome-api'))
await customSession.loadExtension(path.join(fixtures, 'extensions', 'chrome-api'))
const w = new BrowserWindow({ show: false, webPreferences: { session: customSession, nodeIntegration: true } })
await w.loadURL(url)
@@ -157,7 +157,7 @@ ifdescribe(process.electronBinding('features').isExtensionsEnabled())('chrome ex
describe('background pages', () => {
it('loads a lazy background page when sending a message', async () => {
const customSession = session.fromPartition(`persist:${require('uuid').v4()}`)
;(customSession as any).loadExtension(path.join(fixtures, 'extensions', 'lazy-background-page'))
await customSession.loadExtension(path.join(fixtures, 'extensions', 'lazy-background-page'))
const w = new BrowserWindow({ show: false, webPreferences: { session: customSession, nodeIntegration: true } })
try {
w.loadURL(url)
@@ -170,6 +170,33 @@ ifdescribe(process.electronBinding('features').isExtensionsEnabled())('chrome ex
w.destroy()
}
})
it('can use extension.getBackgroundPage from a ui page', async () => {
const customSession = session.fromPartition(`persist:${require('uuid').v4()}`)
const { id } = await customSession.loadExtension(path.join(fixtures, 'extensions', 'lazy-background-page'))
const w = new BrowserWindow({ show: false, webPreferences: { session: customSession } })
await w.loadURL(`chrome-extension://${id}/page-get-background.html`)
const receivedMessage = await w.webContents.executeJavaScript(`window.completionPromise`)
expect(receivedMessage).to.deep.equal({ some: 'message' })
})
it('can use extension.getBackgroundPage from a ui page', async () => {
const customSession = session.fromPartition(`persist:${require('uuid').v4()}`)
const { id } = await customSession.loadExtension(path.join(fixtures, 'extensions', 'lazy-background-page'))
const w = new BrowserWindow({ show: false, webPreferences: { session: customSession } })
await w.loadURL(`chrome-extension://${id}/page-get-background.html`)
const receivedMessage = await w.webContents.executeJavaScript(`window.completionPromise`)
expect(receivedMessage).to.deep.equal({ some: 'message' })
})
it('can use runtime.getBackgroundPage from a ui page', async () => {
const customSession = session.fromPartition(`persist:${require('uuid').v4()}`)
const { id } = await customSession.loadExtension(path.join(fixtures, 'extensions', 'lazy-background-page'))
const w = new BrowserWindow({ show: false, webPreferences: { session: customSession } })
await w.loadURL(`chrome-extension://${id}/page-runtime-get-background.html`)
const receivedMessage = await w.webContents.executeJavaScript(`window.completionPromise`)
expect(receivedMessage).to.deep.equal({ some: 'message' })
})
})
describe('devtools extensions', () => {
@@ -201,8 +228,8 @@ ifdescribe(process.electronBinding('features').isExtensionsEnabled())('chrome ex
}
it('loads a devtools extension', async () => {
const customSession = session.fromPartition(`persist:${require('uuid').v4()}`);
(customSession as any).loadExtension(path.join(fixtures, 'extensions', 'devtools-extension'))
const customSession = session.fromPartition(`persist:${require('uuid').v4()}`)
customSession.loadExtension(path.join(fixtures, 'extensions', 'devtools-extension'))
const w = new BrowserWindow({ show: true, webPreferences: { session: customSession, nodeIntegration: true } })
await w.loadURL('data:text/html,hello')
w.webContents.openDevTools()
@@ -213,8 +240,8 @@ ifdescribe(process.electronBinding('features').isExtensionsEnabled())('chrome ex
describe('deprecation shims', () => {
afterEach(() => {
(session.defaultSession as any).getAllExtensions().forEach((e: any) => {
(session.defaultSession as any).removeExtension(e.id)
session.defaultSession.getAllExtensions().forEach((e: any) => {
session.defaultSession.removeExtension(e.id)
})
})
@@ -387,6 +414,30 @@ ifdescribe(process.electronBinding('features').isExtensionsEnabled())('chrome ex
generateTests(true, false)
generateTests(true, true)
})
describe('extension ui pages', () => {
afterEach(() => {
session.defaultSession.getAllExtensions().forEach(e => {
session.defaultSession.removeExtension(e.id)
})
})
it('loads a ui page of an extension', async () => {
const { id } = await session.defaultSession.loadExtension(path.join(fixtures, 'extensions', 'ui-page'))
const w = new BrowserWindow({ show: false })
await w.loadURL(`chrome-extension://${id}/bare-page.html`)
const textContent = await w.webContents.executeJavaScript(`document.body.textContent`)
expect(textContent).to.equal('ui page loaded ok\n')
})
it('can load resources', async () => {
const { id } = await session.defaultSession.loadExtension(path.join(fixtures, 'extensions', 'ui-page'))
const w = new BrowserWindow({ show: false })
await w.loadURL(`chrome-extension://${id}/page-script-load.html`)
const textContent = await w.webContents.executeJavaScript(`document.body.textContent`)
expect(textContent).to.equal('script loaded ok\n')
})
})
})
ifdescribe(!process.electronBinding('features').isExtensionsEnabled())('chrome extensions', () => {

View File

@@ -1,4 +1,5 @@
/* eslint-disable no-undef */
chrome.runtime.onMessage.addListener((message, sender, reply) => {
window.receivedMessage = message
reply({ message, sender })
})

View File

@@ -0,0 +1,7 @@
/* global chrome */
window.completionPromise = new Promise((resolve) => {
window.completionPromiseResolve = resolve
})
chrome.runtime.sendMessage({ some: 'message' }, (response) => {
window.completionPromiseResolve(chrome.extension.getBackgroundPage().receivedMessage)
})

View File

@@ -0,0 +1 @@
<script src="get-background-page.js"></script>

View File

@@ -0,0 +1 @@
<script src="runtime-get-background-page.js"></script>

View File

@@ -0,0 +1,9 @@
/* global chrome */
window.completionPromise = new Promise((resolve) => {
window.completionPromiseResolve = resolve
})
chrome.runtime.sendMessage({ some: 'message' }, (response) => {
chrome.runtime.getBackgroundPage((bgPage) => {
window.completionPromiseResolve(bgPage.receivedMessage)
})
})

View File

@@ -0,0 +1,2 @@
<!doctype html>
<body>ui page loaded ok</body>

View File

@@ -0,0 +1,5 @@
{
"name": "ui-page",
"version": "1.0",
"manifest_version": 2
}

View File

@@ -0,0 +1 @@
<script src="get-background-page.js"></script>

View File

@@ -0,0 +1 @@
<script src="script.js"></script>

View File

@@ -0,0 +1 @@
document.write('script loaded ok')

View File

@@ -12,7 +12,7 @@ describe('node feature', () => {
const fixtures = path.join(__dirname, '..', 'spec', 'fixtures')
describe('child_process', () => {
describe('child_process.fork', () => {
it('works in browser process', (done) => {
it('Works in browser process', (done) => {
const child = childProcess.fork(path.join(fixtures, 'module', 'ping.js'))
child.on('message', (msg) => {
expect(msg).to.equal('message')
@@ -25,11 +25,11 @@ describe('node feature', () => {
describe('contexts', () => {
describe('setTimeout called under Chromium event loop in browser process', () => {
it('can be scheduled in time', (done) => {
it('Can be scheduled in time', (done) => {
setTimeout(done, 0)
})
it('can be promisified', (done) => {
it('Can be promisified', (done) => {
util.promisify(setTimeout)(0).then(done)
})
})
@@ -57,54 +57,104 @@ describe('node feature', () => {
let child: childProcess.ChildProcessWithoutNullStreams
let exitPromise: Promise<any[]>
afterEach(async () => {
if (child && exitPromise) {
it('Fails for options disallowed by Node.js itself', (done) => {
after(async () => {
const [code, signal] = await exitPromise
expect(signal).to.equal(null)
expect(code).to.equal(0)
} else if (child) {
child.kill()
}
})
it('fails for options disallowed by Node.js itself', (done) => {
// Exit code 9 indicates cli flag parsing failure
expect(code).to.equal(9)
child.kill()
})
const env = Object.assign({}, process.env, { NODE_OPTIONS: '--v8-options' })
child = childProcess.spawn(process.execPath, { env })
exitPromise = emittedOnce(child, 'exit')
function cleanup () {
let output = ''
let success = false
const cleanup = () => {
child.stderr.removeListener('data', listener)
child.stdout.removeListener('data', listener)
}
let output = ''
function listener (data: Buffer) {
const listener = (data: Buffer) => {
output += data
if (/electron: --v8-options is not allowed in NODE_OPTIONS/m.test(output)) {
success = true
cleanup()
done()
}
}
child.stderr.on('data', listener)
child.stdout.on('data', listener)
child.on('exit', () => {
if (!success) {
cleanup()
done(new Error(`Unexpected output: ${output.toString()}`))
}
})
})
it('disallows crypto-related options', (done) => {
it('Disallows crypto-related options', (done) => {
after(() => {
child.kill()
})
const env = Object.assign({}, process.env, { NODE_OPTIONS: '--use-openssl-ca' })
child = childProcess.spawn(process.execPath, ['--enable-logging'], { env })
function cleanup () {
let output = ''
const cleanup = () => {
child.stderr.removeListener('data', listener)
child.stdout.removeListener('data', listener)
}
let output = ''
function listener (data: Buffer) {
const listener = (data: Buffer) => {
output += data
if (/The NODE_OPTION --use-openssl-ca is not supported in Electron/m.test(output)) {
cleanup()
done()
}
}
child.stderr.on('data', listener)
child.stdout.on('data', listener)
})
})
describe('Node.js cli flags', () => {
let child: childProcess.ChildProcessWithoutNullStreams
let exitPromise: Promise<any[]>
it('Prohibits crypto-related flags in ELECTRON_RUN_AS_NODE mode', (done) => {
after(async () => {
const [code, signal] = await exitPromise
expect(signal).to.equal(null)
expect(code).to.equal(9)
child.kill()
})
child = childProcess.spawn(process.execPath, ['--force-fips'], {
env: { ELECTRON_RUN_AS_NODE: 'true' }
})
exitPromise = emittedOnce(child, 'exit')
let output = ''
const cleanup = () => {
child.stderr.removeListener('data', listener)
child.stdout.removeListener('data', listener)
}
const listener = (data: Buffer) => {
output += data
if (/.*The Node.js cli flag --force-fips is not supported in Electron/m.test(output)) {
cleanup()
done()
}
}
child.stderr.on('data', listener)
child.stdout.on('data', listener)
})
@@ -124,72 +174,63 @@ describe('node feature', () => {
}
})
it('supports starting the v8 inspector with --inspect/--inspect-brk', (done) => {
it('Supports starting the v8 inspector with --inspect/--inspect-brk', (done) => {
child = childProcess.spawn(process.execPath, ['--inspect-brk', path.join(fixtures, 'module', 'run-as-node.js')], {
env: {
ELECTRON_RUN_AS_NODE: 'true'
}
env: { ELECTRON_RUN_AS_NODE: 'true' }
})
let output = ''
function cleanup () {
child.stderr.removeListener('data', errorDataListener)
child.stdout.removeListener('data', outDataHandler)
const cleanup = () => {
child.stderr.removeListener('data', listener)
child.stdout.removeListener('data', listener)
}
function errorDataListener (data: Buffer) {
const listener = (data: Buffer) => {
output += data
if (/^Debugger listening on ws:/m.test(output)) {
if (/Debugger listening on ws:/m.test(output)) {
cleanup()
done()
}
}
function outDataHandler (data: Buffer) {
cleanup()
done(new Error(`Unexpected output: ${data.toString()}`))
}
child.stderr.on('data', errorDataListener)
child.stdout.on('data', outDataHandler)
child.stderr.on('data', listener)
child.stdout.on('data', listener)
})
it('supports starting the v8 inspector with --inspect and a provided port', (done) => {
it('Supports starting the v8 inspector with --inspect and a provided port', (done) => {
child = childProcess.spawn(process.execPath, ['--inspect=17364', path.join(fixtures, 'module', 'run-as-node.js')], {
env: {
ELECTRON_RUN_AS_NODE: 'true'
}
env: { ELECTRON_RUN_AS_NODE: 'true' }
})
exitPromise = emittedOnce(child, 'exit')
let output = ''
function cleanup () {
child.stderr.removeListener('data', errorDataListener)
child.stdout.removeListener('data', outDataHandler)
const listener = (data: Buffer) => { output += data }
const cleanup = () => {
child.stderr.removeListener('data', listener)
child.stdout.removeListener('data', listener)
}
function errorDataListener (data: Buffer) {
output += data
child.stderr.on('data', listener)
child.stdout.on('data', listener)
child.on('exit', () => {
cleanup()
if (/^Debugger listening on ws:/m.test(output)) {
expect(output.trim()).to.contain(':17364', 'should be listening on port 17364')
cleanup()
done()
} else {
done(new Error(`Unexpected output: ${output.toString()}`))
}
}
function outDataHandler (data: Buffer) {
cleanup()
done(new Error(`Unexpected output: ${data.toString()}`))
}
child.stderr.on('data', errorDataListener)
child.stdout.on('data', outDataHandler)
})
})
it('does not start the v8 inspector when --inspect is after a -- argument', (done) => {
it('Does not start the v8 inspector when --inspect is after a -- argument', (done) => {
child = childProcess.spawn(process.execPath, [path.join(fixtures, 'module', 'noop.js'), '--', '--inspect'])
exitPromise = emittedOnce(child, 'exit')
let output = ''
function dataListener (data: Buffer) {
output += data
}
child.stderr.on('data', dataListener)
child.stdout.on('data', dataListener)
const listener = (data: Buffer) => { output += data }
child.stderr.on('data', listener)
child.stdout.on('data', listener)
child.on('exit', () => {
if (output.trim().startsWith('Debugger listening on ws://')) {
done(new Error('Inspector was started when it should not have been'))
@@ -200,22 +241,24 @@ describe('node feature', () => {
})
// IPC Electron child process not supported on Windows
ifit(process.platform !== 'win32')('does does not crash when quitting with the inspector connected', function (done) {
ifit(process.platform !== 'win32')('Does does not crash when quitting with the inspector connected', function (done) {
child = childProcess.spawn(process.execPath, [path.join(fixtures, 'module', 'delay-exit'), '--inspect=0'], {
stdio: ['ipc']
}) as childProcess.ChildProcessWithoutNullStreams
exitPromise = emittedOnce(child, 'exit')
let output = ''
function dataListener (data: Buffer) {
output += data
const cleanup = () => {
child.stderr.removeListener('data', listener)
child.stdout.removeListener('data', listener)
}
let output = ''
let success = false
function listener (data: Buffer) {
output += data
if (output.trim().indexOf('Debugger listening on ws://') > -1 && output.indexOf('\n') > -1) {
const socketMatch = output.trim().match(/(ws:\/\/.+:[0-9]+\/.+?)\n/gm)
if (socketMatch && socketMatch[0]) {
child.stderr.removeListener('data', dataListener)
child.stdout.removeListener('data', dataListener)
const w = (webContents as any).create({}) as WebContents
w.loadURL('about:blank')
.then(() => w.executeJavaScript(`new Promise(resolve => {
@@ -228,20 +271,24 @@ describe('node feature', () => {
.then(() => {
(w as any).destroy()
child.send('plz-quit')
success = true
cleanup()
done()
})
}
}
}
child.stderr.on('data', dataListener)
child.stdout.on('data', dataListener)
child.stderr.on('data', listener)
child.stdout.on('data', listener)
child.on('exit', () => {
if (!success) cleanup()
})
})
it('supports js binding', (done) => {
it('Supports js binding', (done) => {
child = childProcess.spawn(process.execPath, ['--inspect', path.join(fixtures, 'module', 'inspector-binding.js')], {
env: {
ELECTRON_RUN_AS_NODE: 'true'
},
env: { ELECTRON_RUN_AS_NODE: 'true' },
stdio: ['ipc']
}) as childProcess.ChildProcessWithoutNullStreams
exitPromise = emittedOnce(child, 'exit')
@@ -256,7 +303,7 @@ describe('node feature', () => {
})
})
it('can find a module using a package.json main field', () => {
it('Can find a module using a package.json main field', () => {
const result = childProcess.spawnSync(process.execPath, [path.resolve(fixtures, 'api', 'electron-main-module', 'app.asar')])
expect(result.status).to.equal(0)
})