mirror of
https://github.com/electron/electron.git
synced 2026-02-19 03:14:51 -05:00
Compare commits
63 Commits
v12.0.12
...
v9.0.0-bet
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
df2d03fe9b | ||
|
|
80967287ad | ||
|
|
2855f1d237 | ||
|
|
5e25649e77 | ||
|
|
3e90e523eb | ||
|
|
c702aec1f8 | ||
|
|
ede40f260e | ||
|
|
ca53cc8380 | ||
|
|
7ec9b4e252 | ||
|
|
0d7e13d2a6 | ||
|
|
a5c56684b9 | ||
|
|
68d96459c3 | ||
|
|
6cf4757019 | ||
|
|
6e80d6fba5 | ||
|
|
ec07954d5d | ||
|
|
7fd2d39f72 | ||
|
|
64880c75a3 | ||
|
|
cc94689db1 | ||
|
|
806e483049 | ||
|
|
8129e92d2b | ||
|
|
660706ba2c | ||
|
|
2feca9d35a | ||
|
|
3a4118703a | ||
|
|
bd669f72ee | ||
|
|
1f3c3eee83 | ||
|
|
6e84ebee8e | ||
|
|
f22376ef32 | ||
|
|
324b49a5eb | ||
|
|
0e9727e8d5 | ||
|
|
44ee90e5cf | ||
|
|
2b9ef75d82 | ||
|
|
4dc2b4d55f | ||
|
|
69f77d309d | ||
|
|
9cd1744a2b | ||
|
|
c6e411173e | ||
|
|
8b11adc6f2 | ||
|
|
57ec30e459 | ||
|
|
c4a836f95a | ||
|
|
9b2de2583e | ||
|
|
7b2bfb4a0f | ||
|
|
0e31826043 | ||
|
|
7b3c073b3e | ||
|
|
2dc900b95d | ||
|
|
f41423501a | ||
|
|
07d9728b63 | ||
|
|
d4c90e80a5 | ||
|
|
91141028e6 | ||
|
|
9d69d4b9ef | ||
|
|
d57d5c544e | ||
|
|
74d4dab157 | ||
|
|
94246dabe3 | ||
|
|
4fe91e56ac | ||
|
|
0d7440d676 | ||
|
|
60edd2d3b1 | ||
|
|
d4d06660f3 | ||
|
|
8d8f15121b | ||
|
|
1f8cb5144d | ||
|
|
667ee359a1 | ||
|
|
4b009159ba | ||
|
|
89f66bd00c | ||
|
|
2d542c6028 | ||
|
|
68346fec55 | ||
|
|
23f32ca9f3 |
@@ -41,6 +41,14 @@ parameters:
|
||||
type: boolean
|
||||
default: false
|
||||
|
||||
run-linux-publish:
|
||||
type: boolean
|
||||
default: false
|
||||
|
||||
run-macos-publish:
|
||||
type: boolean
|
||||
default: false
|
||||
|
||||
# The config expects the following environment variables to be set:
|
||||
# - "SLACK_WEBHOOK" Slack hook URL to send notifications.
|
||||
#
|
||||
@@ -65,12 +73,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 +236,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 +248,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 +361,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 +454,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 +472,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 +515,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 +532,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 +567,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 +612,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 +630,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 +868,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 +904,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
|
||||
@@ -965,69 +1000,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
|
||||
@@ -1067,56 +1039,6 @@ steps-electron-ts-compile-for-doc-change: &steps-electron-ts-compile-for-doc-cha
|
||||
#Compile ts/js to verify doc change didn't break anything
|
||||
- *step-ts-compile
|
||||
|
||||
steps-electron-build-for-publish: &steps-electron-build-for-publish
|
||||
steps:
|
||||
- *step-checkout-electron
|
||||
- *step-depot-tools-get
|
||||
- *step-depot-tools-add-to-path
|
||||
- *step-restore-brew-cache
|
||||
- *step-get-more-space-on-mac
|
||||
- *step-gclient-sync
|
||||
- *step-setup-env-for-build
|
||||
- *step-delete-git-directories
|
||||
- *step-minimize-workspace-size-from-checkout
|
||||
- *step-gn-gen-default
|
||||
|
||||
# Electron app
|
||||
- *step-electron-build
|
||||
- *step-maybe-generate-breakpad-symbols
|
||||
- *step-maybe-electron-dist-strip
|
||||
- *step-electron-dist-build
|
||||
- *step-electron-dist-store
|
||||
- *step-maybe-zip-symbols
|
||||
- *step-symbols-store
|
||||
|
||||
# mksnapshot
|
||||
- *step-mksnapshot-build
|
||||
- *step-mksnapshot-store
|
||||
|
||||
# chromedriver
|
||||
- *step-electron-chromedriver-gn-gen
|
||||
- *step-electron-chromedriver-build
|
||||
- *step-electron-chromedriver-store
|
||||
|
||||
# Node.js headers
|
||||
- *step-nodejs-headers-build
|
||||
- *step-nodejs-headers-store
|
||||
|
||||
# ffmpeg
|
||||
- *step-ffmpeg-gn-gen
|
||||
- *step-ffmpeg-build
|
||||
- *step-ffmpeg-store
|
||||
|
||||
# hunspell
|
||||
- *step-hunspell-build
|
||||
- *step-hunspell-store
|
||||
|
||||
# typescript defs
|
||||
- *step-maybe-generate-typescript-defs
|
||||
|
||||
# Publish
|
||||
- *step-electron-publish
|
||||
|
||||
steps-chromedriver-build: &steps-chromedriver-build
|
||||
steps:
|
||||
- attach_workspace:
|
||||
@@ -1125,7 +1047,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
|
||||
|
||||
@@ -1272,7 +1194,7 @@ steps-test-node: &steps-test-node
|
||||
name: Run Node Tests
|
||||
command: |
|
||||
cd src
|
||||
node electron/script/node-spec-runner.js junit
|
||||
node electron/script/node-spec-runner.js --default --jUnitDir=junit
|
||||
- store_test_results:
|
||||
path: src/junit
|
||||
|
||||
@@ -1341,6 +1263,12 @@ commands:
|
||||
use-out-cache:
|
||||
type: boolean
|
||||
default: true
|
||||
restore-src-cache:
|
||||
type: boolean
|
||||
default: true
|
||||
preserve-vendor-dirs:
|
||||
type: boolean
|
||||
default: false
|
||||
steps:
|
||||
- when:
|
||||
condition: << parameters.attach >>
|
||||
@@ -1366,17 +1294,38 @@ commands:
|
||||
- *step-get-more-space-on-mac
|
||||
- *step-generate-deps-hash
|
||||
- *step-touch-sync-done
|
||||
- maybe-restore-portaled-src-cache
|
||||
- when:
|
||||
condition: << parameters.restore-src-cache >>
|
||||
steps:
|
||||
- maybe-restore-portaled-src-cache
|
||||
- *step-maybe-restore-git-cache
|
||||
- *step-set-git-cache-path
|
||||
# This sync call only runs if .circle-sync-done is an EMPTY file
|
||||
- *step-gclient-sync
|
||||
# These next few steps reset Electron to the correct commit regardless of which cache was restored
|
||||
- when:
|
||||
condition: << parameters.preserve-vendor-dirs >>
|
||||
steps:
|
||||
- run:
|
||||
name: Preserve vendor dirs for release
|
||||
command: |
|
||||
mv src/electron/vendor/boto .
|
||||
mv src/electron/vendor/requests .
|
||||
- run:
|
||||
name: Wipe Electron
|
||||
command: rm -rf src/electron
|
||||
- *step-checkout-electron
|
||||
- *step-run-electron-only-hooks
|
||||
- when:
|
||||
condition: << parameters.preserve-vendor-dirs >>
|
||||
steps:
|
||||
- run:
|
||||
name: Preserve vendor dirs for release
|
||||
command: |
|
||||
rm -rf src/electron/vendor/boto
|
||||
rm -rf src/electron/vendor/requests
|
||||
mv boto src/electron/vendor
|
||||
mv requests src/electron/vendor/requests
|
||||
- *step-generate-deps-hash-cleanly
|
||||
- *step-mark-sync-done
|
||||
- *step-minimize-workspace-size-from-checkout
|
||||
@@ -1394,10 +1343,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 +1378,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
|
||||
|
||||
@@ -1475,10 +1424,80 @@ commands:
|
||||
steps:
|
||||
- *step-save-out-cache
|
||||
|
||||
# Trigger tests on arm hardware if needed
|
||||
- *step-maybe-trigger-arm-test
|
||||
# Trigger tests on arm hardware if needed
|
||||
- *step-maybe-trigger-arm-test
|
||||
|
||||
- *step-maybe-notify-slack-failure
|
||||
- *step-maybe-notify-slack-failure
|
||||
|
||||
electron-publish:
|
||||
parameters:
|
||||
attach:
|
||||
type: boolean
|
||||
default: false
|
||||
checkout:
|
||||
type: boolean
|
||||
default: true
|
||||
steps:
|
||||
- when:
|
||||
condition: << parameters.attach >>
|
||||
steps:
|
||||
- attach_workspace:
|
||||
at: .
|
||||
- when:
|
||||
condition: << parameters.checkout >>
|
||||
steps:
|
||||
- *step-depot-tools-get
|
||||
- *step-depot-tools-add-to-path
|
||||
- *step-restore-brew-cache
|
||||
- *step-get-more-space-on-mac
|
||||
- when:
|
||||
condition: << parameters.checkout >>
|
||||
steps:
|
||||
- *step-checkout-electron
|
||||
- *step-gclient-sync
|
||||
- *step-delete-git-directories
|
||||
- *step-minimize-workspace-size-from-checkout
|
||||
- *step-fix-sync-on-mac
|
||||
- *step-setup-env-for-build
|
||||
- *step-gn-gen-default
|
||||
|
||||
# Electron app
|
||||
- *step-electron-build
|
||||
- *step-show-sccache-stats
|
||||
- *step-maybe-generate-breakpad-symbols
|
||||
- *step-maybe-electron-dist-strip
|
||||
- *step-electron-dist-build
|
||||
- *step-electron-dist-store
|
||||
- *step-maybe-zip-symbols
|
||||
- *step-symbols-store
|
||||
|
||||
# mksnapshot
|
||||
- *step-mksnapshot-build
|
||||
- *step-mksnapshot-store
|
||||
|
||||
# chromedriver
|
||||
- *step-electron-maybe-chromedriver-gn-gen
|
||||
- *step-electron-chromedriver-build
|
||||
- *step-electron-chromedriver-store
|
||||
|
||||
# Node.js headers
|
||||
- *step-nodejs-headers-build
|
||||
- *step-nodejs-headers-store
|
||||
|
||||
# ffmpeg
|
||||
- *step-ffmpeg-gn-gen
|
||||
- *step-ffmpeg-build
|
||||
- *step-ffmpeg-store
|
||||
|
||||
# hunspell
|
||||
- *step-hunspell-build
|
||||
- *step-hunspell-store
|
||||
|
||||
# typescript defs
|
||||
- *step-maybe-generate-typescript-defs
|
||||
|
||||
# Publish
|
||||
- *step-electron-publish
|
||||
|
||||
# List of all jobs.
|
||||
jobs:
|
||||
@@ -1497,6 +1516,20 @@ jobs:
|
||||
<<: *steps-electron-ts-compile-for-doc-change
|
||||
|
||||
# Layer 1: Checkout.
|
||||
linux-checkout:
|
||||
<<: *machine-linux-2xlarge
|
||||
environment:
|
||||
<<: *env-linux-2xlarge
|
||||
GCLIENT_EXTRA_ARGS: '--custom-var=checkout_arm=True --custom-var=checkout_arm64=True --custom-var=checkout_boto=True --custom-var=checkout_requests=True'
|
||||
steps:
|
||||
- electron-build:
|
||||
persist: false
|
||||
build: false
|
||||
checkout: true
|
||||
persist-checkout: true
|
||||
restore-src-cache: false
|
||||
preserve-vendor-dirs: true
|
||||
|
||||
linux-checkout-fast:
|
||||
<<: *machine-linux-2xlarge
|
||||
environment:
|
||||
@@ -1540,6 +1573,22 @@ jobs:
|
||||
checkout: true
|
||||
persist-checkout: true
|
||||
|
||||
mac-checkout:
|
||||
<<: *machine-linux-2xlarge
|
||||
environment:
|
||||
<<: *env-linux-2xlarge
|
||||
<<: *env-testing-build
|
||||
<<: *env-macos-build
|
||||
GCLIENT_EXTRA_ARGS: '--custom-var=checkout_mac=True --custom-var=host_os=mac --custom-var=checkout_boto=True --custom-var=checkout_requests=True'
|
||||
steps:
|
||||
- electron-build:
|
||||
persist: false
|
||||
build: false
|
||||
checkout: true
|
||||
persist-checkout: true
|
||||
restore-src-cache: false
|
||||
preserve-vendor-dirs: true
|
||||
|
||||
mac-checkout-fast:
|
||||
<<: *machine-linux-2xlarge
|
||||
environment:
|
||||
@@ -1569,7 +1618,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 +1631,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 +1652,6 @@ jobs:
|
||||
environment:
|
||||
<<: *env-linux-medium
|
||||
<<: *env-release-build
|
||||
<<: *env-enable-sccache
|
||||
<<: *env-send-slack-notifications
|
||||
<<: *steps-chromedriver-build
|
||||
|
||||
@@ -1614,12 +1660,27 @@ 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
|
||||
environment:
|
||||
<<: *env-linux-2xlarge-release
|
||||
<<: *env-release-build
|
||||
<<: *env-enable-sccache
|
||||
UPLOAD_TO_S3: << pipeline.parameters.upload-to-s3 >>
|
||||
steps:
|
||||
- electron-publish:
|
||||
attach: false
|
||||
checkout: true
|
||||
|
||||
linux-x64-publish-skip-checkout:
|
||||
<<: *machine-linux-2xlarge
|
||||
environment:
|
||||
<<: *env-linux-2xlarge-release
|
||||
@@ -1627,7 +1688,10 @@ jobs:
|
||||
<<: *env-release-build
|
||||
<<: *env-enable-sccache
|
||||
UPLOAD_TO_S3: << pipeline.parameters.upload-to-s3 >>
|
||||
<<: *steps-electron-build-for-publish
|
||||
steps:
|
||||
- electron-publish:
|
||||
attach: true
|
||||
checkout: false
|
||||
|
||||
linux-ia32-testing:
|
||||
<<: *machine-linux-2xlarge
|
||||
@@ -1635,7 +1699,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 +1713,6 @@ jobs:
|
||||
<<: *env-linux-medium
|
||||
<<: *env-ia32
|
||||
<<: *env-release-build
|
||||
<<: *env-enable-sccache
|
||||
<<: *env-send-slack-notifications
|
||||
<<: *steps-chromedriver-build
|
||||
|
||||
@@ -1660,12 +1722,29 @@ 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
|
||||
environment:
|
||||
<<: *env-linux-2xlarge-release
|
||||
<<: *env-ia32
|
||||
<<: *env-release-build
|
||||
<<: *env-enable-sccache
|
||||
<<: *env-32bit-release
|
||||
UPLOAD_TO_S3: << pipeline.parameters.upload-to-s3 >>
|
||||
steps:
|
||||
- electron-publish:
|
||||
attach: false
|
||||
checkout: true
|
||||
|
||||
linux-ia32-publish-skip-checkout:
|
||||
<<: *machine-linux-2xlarge
|
||||
environment:
|
||||
<<: *env-linux-2xlarge-release
|
||||
@@ -1675,7 +1754,10 @@ jobs:
|
||||
<<: *env-enable-sccache
|
||||
<<: *env-32bit-release
|
||||
UPLOAD_TO_S3: << pipeline.parameters.upload-to-s3 >>
|
||||
<<: *steps-electron-build-for-publish
|
||||
steps:
|
||||
- electron-publish:
|
||||
attach: true
|
||||
checkout: false
|
||||
|
||||
linux-arm-testing:
|
||||
<<: *machine-linux-2xlarge
|
||||
@@ -1683,7 +1765,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 +1780,6 @@ jobs:
|
||||
<<: *env-linux-medium
|
||||
<<: *env-arm
|
||||
<<: *env-release-build
|
||||
<<: *env-enable-sccache
|
||||
<<: *env-send-slack-notifications
|
||||
<<: *steps-chromedriver-build
|
||||
|
||||
@@ -1709,12 +1789,29 @@ 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
|
||||
environment:
|
||||
<<: *env-linux-2xlarge-release
|
||||
<<: *env-arm
|
||||
<<: *env-release-build
|
||||
<<: *env-enable-sccache
|
||||
<<: *env-32bit-release
|
||||
UPLOAD_TO_S3: << pipeline.parameters.upload-to-s3 >>
|
||||
steps:
|
||||
- electron-publish:
|
||||
attach: false
|
||||
checkout: true
|
||||
|
||||
linux-arm-publish-skip-checkout:
|
||||
<<: *machine-linux-2xlarge
|
||||
environment:
|
||||
<<: *env-linux-2xlarge-release
|
||||
@@ -1724,7 +1821,10 @@ jobs:
|
||||
<<: *env-32bit-release
|
||||
GCLIENT_EXTRA_ARGS: '--custom-var=checkout_arm=True --custom-var=checkout_boto=True --custom-var=checkout_requests=True'
|
||||
UPLOAD_TO_S3: << pipeline.parameters.upload-to-s3 >>
|
||||
<<: *steps-electron-build-for-publish
|
||||
steps:
|
||||
- electron-publish:
|
||||
attach: true
|
||||
checkout: false
|
||||
|
||||
linux-arm64-testing:
|
||||
<<: *machine-linux-2xlarge
|
||||
@@ -1732,7 +1832,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 +1855,6 @@ jobs:
|
||||
<<: *env-linux-medium
|
||||
<<: *env-arm64
|
||||
<<: *env-release-build
|
||||
<<: *env-enable-sccache
|
||||
<<: *env-send-slack-notifications
|
||||
<<: *steps-chromedriver-build
|
||||
|
||||
@@ -1766,12 +1864,28 @@ 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
|
||||
environment:
|
||||
<<: *env-linux-2xlarge-release
|
||||
<<: *env-arm64
|
||||
<<: *env-release-build
|
||||
<<: *env-enable-sccache
|
||||
UPLOAD_TO_S3: << pipeline.parameters.upload-to-s3 >>
|
||||
steps:
|
||||
- electron-publish:
|
||||
attach: false
|
||||
checkout: true
|
||||
|
||||
linux-arm64-publish-skip-checkout:
|
||||
<<: *machine-linux-2xlarge
|
||||
environment:
|
||||
<<: *env-linux-2xlarge-release
|
||||
@@ -1780,14 +1894,16 @@ jobs:
|
||||
<<: *env-enable-sccache
|
||||
GCLIENT_EXTRA_ARGS: '--custom-var=checkout_arm64=True --custom-var=checkout_boto=True --custom-var=checkout_requests=True'
|
||||
UPLOAD_TO_S3: << pipeline.parameters.upload-to-s3 >>
|
||||
<<: *steps-electron-build-for-publish
|
||||
steps:
|
||||
- electron-publish:
|
||||
attach: true
|
||||
checkout: false
|
||||
|
||||
osx-testing:
|
||||
<<: *machine-mac-large
|
||||
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 +1926,6 @@ jobs:
|
||||
environment:
|
||||
<<: *env-machine-mac
|
||||
<<: *env-release-build
|
||||
<<: *env-enable-sccache
|
||||
<<: *env-send-slack-notifications
|
||||
<<: *steps-chromedriver-build
|
||||
|
||||
@@ -1819,11 +1934,28 @@ 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
|
||||
environment:
|
||||
<<: *env-mac-large-release
|
||||
<<: *env-release-build
|
||||
<<: *env-enable-sccache
|
||||
UPLOAD_TO_S3: << pipeline.parameters.upload-to-s3 >>
|
||||
steps:
|
||||
- electron-publish:
|
||||
attach: false
|
||||
checkout: true
|
||||
|
||||
osx-publish-skip-checkout:
|
||||
<<: *machine-mac-large
|
||||
environment:
|
||||
<<: *env-mac-large-release
|
||||
@@ -1831,7 +1963,10 @@ jobs:
|
||||
<<: *env-enable-sccache
|
||||
GCLIENT_EXTRA_ARGS: '--custom-var=checkout_boto=True --custom-var=checkout_requests=True'
|
||||
UPLOAD_TO_S3: << pipeline.parameters.upload-to-s3 >>
|
||||
<<: *steps-electron-build-for-publish
|
||||
steps:
|
||||
- electron-publish:
|
||||
attach: true
|
||||
checkout: false
|
||||
|
||||
mas-testing:
|
||||
<<: *machine-mac-large
|
||||
@@ -1839,7 +1974,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 +1997,6 @@ jobs:
|
||||
environment:
|
||||
<<: *env-machine-mac
|
||||
<<: *env-release-build
|
||||
<<: *env-enable-sccache
|
||||
<<: *env-send-slack-notifications
|
||||
<<: *steps-chromedriver-build
|
||||
|
||||
@@ -1873,11 +2006,29 @@ 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:
|
||||
<<: *env-mac-large-release
|
||||
<<: *env-mas
|
||||
<<: *env-release-build
|
||||
<<: *env-enable-sccache
|
||||
UPLOAD_TO_S3: << pipeline.parameters.upload-to-s3 >>
|
||||
steps:
|
||||
- electron-publish:
|
||||
attach: false
|
||||
checkout: true
|
||||
|
||||
mas-publish-skip-checkout:
|
||||
<<: *machine-mac-large
|
||||
environment:
|
||||
<<: *env-mac-large-release
|
||||
@@ -1886,7 +2037,10 @@ jobs:
|
||||
<<: *env-enable-sccache
|
||||
GCLIENT_EXTRA_ARGS: '--custom-var=checkout_boto=True --custom-var=checkout_requests=True'
|
||||
UPLOAD_TO_S3: << pipeline.parameters.upload-to-s3 >>
|
||||
<<: *steps-electron-build-for-publish
|
||||
steps:
|
||||
- electron-publish:
|
||||
attach: true
|
||||
checkout: false
|
||||
|
||||
# Layer 3: Tests.
|
||||
linux-x64-unittests:
|
||||
@@ -1894,7 +2048,6 @@ jobs:
|
||||
environment:
|
||||
<<: *env-linux-2xlarge
|
||||
<<: *env-unittests
|
||||
<<: *env-enable-sccache
|
||||
<<: *env-headless-testing
|
||||
<<: *steps-native-tests
|
||||
|
||||
@@ -1903,7 +2056,6 @@ jobs:
|
||||
environment:
|
||||
<<: *env-linux-2xlarge
|
||||
<<: *env-unittests
|
||||
<<: *env-enable-sccache
|
||||
<<: *env-headless-testing
|
||||
TESTS_ARGS: '--only-disabled-tests'
|
||||
<<: *steps-native-tests
|
||||
@@ -1913,7 +2065,6 @@ jobs:
|
||||
environment:
|
||||
<<: *env-linux-2xlarge
|
||||
<<: *env-unittests
|
||||
<<: *env-enable-sccache
|
||||
<<: *env-headless-testing
|
||||
TESTS_ARGS: '--include-disabled-tests'
|
||||
<<: *steps-native-tests
|
||||
@@ -1924,7 +2075,6 @@ jobs:
|
||||
<<: *env-linux-2xlarge
|
||||
<<: *env-browsertests
|
||||
<<: *env-testing-build
|
||||
<<: *env-enable-sccache
|
||||
<<: *env-headless-testing
|
||||
<<: *steps-native-tests
|
||||
|
||||
@@ -2180,6 +2330,27 @@ workflows:
|
||||
# will need to be updated and there will most likely need to be changes to
|
||||
# sudowoodo
|
||||
|
||||
publish-linux:
|
||||
when: << pipeline.parameters.run-linux-publish >>
|
||||
jobs:
|
||||
- linux-checkout
|
||||
- linux-x64-publish-skip-checkout:
|
||||
requires:
|
||||
- linux-checkout
|
||||
context: release-env
|
||||
- linux-ia32-publish-skip-checkout:
|
||||
requires:
|
||||
- linux-checkout
|
||||
context: release-env
|
||||
- linux-arm-publish-skip-checkout:
|
||||
requires:
|
||||
- linux-checkout
|
||||
context: release-env
|
||||
- linux-arm64-publish-skip-checkout:
|
||||
requires:
|
||||
- linux-checkout
|
||||
context: release-env
|
||||
|
||||
publish-x64-linux:
|
||||
when: << pipeline.parameters.run-linux-x64-publish >>
|
||||
jobs:
|
||||
@@ -2216,6 +2387,17 @@ workflows:
|
||||
- mas-publish:
|
||||
context: release-env
|
||||
|
||||
publish-macos:
|
||||
when: << pipeline.parameters.run-macos-publish >>
|
||||
jobs:
|
||||
- mac-checkout
|
||||
- osx-publish-skip-checkout:
|
||||
requires:
|
||||
- mac-checkout
|
||||
- mas-publish-skip-checkout:
|
||||
requires:
|
||||
- mac-checkout
|
||||
|
||||
lint:
|
||||
when: << pipeline.parameters.run-lint >>
|
||||
jobs:
|
||||
@@ -2302,10 +2484,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 +2510,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 +2534,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 +2543,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 +2563,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 +2593,7 @@ workflows:
|
||||
|
||||
- mas-release:
|
||||
requires:
|
||||
- mac-checkout-fast
|
||||
- mac-checkout-and-save-cache
|
||||
- mas-release-tests:
|
||||
requires:
|
||||
- mas-release
|
||||
|
||||
14
BUILD.gn
14
BUILD.gn
@@ -629,8 +629,6 @@ source_set("electron_lib") {
|
||||
deps += [ "//components/printing/common:mojo_interfaces" ]
|
||||
}
|
||||
|
||||
deps += [ "shell/common/extensions/api:extensions_features" ]
|
||||
deps += [ "shell/common/extensions/api" ]
|
||||
deps += [
|
||||
"//components/pref_registry",
|
||||
"//components/user_prefs",
|
||||
@@ -642,12 +640,22 @@ source_set("electron_lib") {
|
||||
]
|
||||
if (enable_electron_extensions) {
|
||||
sources += filenames.lib_sources_extensions
|
||||
deps += [
|
||||
"shell/browser/extensions/api:api_registration",
|
||||
"shell/common/extensions/api",
|
||||
"shell/common/extensions/api:extensions_features",
|
||||
"//chrome/browser/resources:component_extension_resources",
|
||||
"//components/zoom",
|
||||
]
|
||||
}
|
||||
|
||||
if (enable_pdf) {
|
||||
# Printing depends on some //pdf code, so it needs to be built even if the
|
||||
# pdf viewer isn't enabled.
|
||||
deps += [ "//pdf" ]
|
||||
deps += [
|
||||
"//pdf",
|
||||
"//pdf:features",
|
||||
]
|
||||
}
|
||||
if (enable_pdf_viewer) {
|
||||
deps += [
|
||||
|
||||
@@ -1 +1 @@
|
||||
9.0.0-nightly.20200205
|
||||
9.0.0-beta.5
|
||||
24
appveyor.yml
24
appveyor.yml
@@ -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
|
||||
|
||||
@@ -2,7 +2,7 @@ is_electron_build = true
|
||||
root_extra_deps = [ "//electron" ]
|
||||
|
||||
# Registry of NMVs --> https://github.com/nodejs/node/blob/master/doc/abi_version_registry.json
|
||||
node_module_version = 76
|
||||
node_module_version = 80
|
||||
|
||||
v8_promise_internal_field_count = 1
|
||||
v8_typed_array_max_size_in_heap = 0
|
||||
|
||||
@@ -14,7 +14,7 @@ declare_args() {
|
||||
|
||||
enable_view_api = false
|
||||
|
||||
enable_pdf_viewer = false
|
||||
enable_pdf_viewer = true
|
||||
|
||||
enable_tts = true
|
||||
|
||||
|
||||
@@ -233,6 +233,12 @@ static_library("chrome") {
|
||||
|
||||
if (enable_electron_extensions) {
|
||||
sources += [
|
||||
"//chrome/browser/extensions/chrome_url_request_util.cc",
|
||||
"//chrome/browser/extensions/chrome_url_request_util.h",
|
||||
"//chrome/browser/pdf/pdf_extension_util.cc",
|
||||
"//chrome/browser/pdf/pdf_extension_util.h",
|
||||
"//chrome/browser/plugins/plugin_response_interceptor_url_loader_throttle.cc",
|
||||
"//chrome/browser/plugins/plugin_response_interceptor_url_loader_throttle.h",
|
||||
"//chrome/renderer/extensions/extension_hooks_delegate.cc",
|
||||
"//chrome/renderer/extensions/extension_hooks_delegate.h",
|
||||
"//chrome/renderer/extensions/tabs_hooks_delegate.cc",
|
||||
|
||||
@@ -703,34 +703,34 @@ Clears the recent documents list.
|
||||
|
||||
### `app.setAsDefaultProtocolClient(protocol[, path, args])`
|
||||
|
||||
* `protocol` String - The name of your protocol, without `://`. If you want your
|
||||
app to handle `electron://` links, call this method with `electron` as the
|
||||
parameter.
|
||||
* `path` String (optional) _Windows_ - Defaults to `process.execPath`
|
||||
* `args` String[] (optional) _Windows_ - Defaults to an empty array
|
||||
* `protocol` String - The name of your protocol, without `://`. For example,
|
||||
if you want your app to handle `electron://` links, call this method with
|
||||
`electron` as the parameter.
|
||||
* `path` String (optional) _Windows_ - The path to the Electron executable.
|
||||
Defaults to `process.execPath`
|
||||
* `args` String[] (optional) _Windows_ - Arguments passed to the executable.
|
||||
Defaults to an empty array
|
||||
|
||||
Returns `Boolean` - Whether the call succeeded.
|
||||
|
||||
This method sets the current executable as the default handler for a protocol
|
||||
(aka URI scheme). It allows you to integrate your app deeper into the operating
|
||||
system. Once registered, all links with `your-protocol://` will be opened with
|
||||
the current executable. The whole link, including protocol, will be passed to
|
||||
your application as a parameter.
|
||||
|
||||
On Windows, you can provide optional parameters path, the path to your executable,
|
||||
and args, an array of arguments to be passed to your executable when it launches.
|
||||
Sets the current executable as the default handler for a protocol (aka URI
|
||||
scheme). It allows you to integrate your app deeper into the operating system.
|
||||
Once registered, all links with `your-protocol://` will be opened with the
|
||||
current executable. The whole link, including protocol, will be passed to your
|
||||
application as a parameter.
|
||||
|
||||
**Note:** On macOS, you can only register protocols that have been added to
|
||||
your app's `info.plist`, which can not be modified at runtime. You can however
|
||||
change the file with a simple text editor or script during build time.
|
||||
Please refer to [Apple's documentation][CFBundleURLTypes] for details.
|
||||
your app's `info.plist`, which cannot be modified at runtime. However, you can
|
||||
change the file during build time via [Electron Forge][electron-forge],
|
||||
[Electron Packager][electron-packager], or by editing `info.plist` with a text
|
||||
editor. Please refer to [Apple's documentation][CFBundleURLTypes] for details.
|
||||
|
||||
**Note:** In a Windows Store environment (when packaged as an `appx`) this API
|
||||
will return `true` for all calls but the registry key it sets won't be accessible
|
||||
by other applications. In order to register your Windows Store application
|
||||
as a default protocol handler you must [declare the protocol in your manifest](https://docs.microsoft.com/en-us/uwp/schemas/appxpackage/uapmanifestschema/element-uap-protocol).
|
||||
|
||||
The API uses the Windows Registry and LSSetDefaultHandlerForURLScheme internally.
|
||||
The API uses the Windows Registry and `LSSetDefaultHandlerForURLScheme` internally.
|
||||
|
||||
### `app.removeAsDefaultProtocolClient(protocol[, path, args])` _macOS_ _Windows_
|
||||
|
||||
@@ -749,10 +749,8 @@ protocol (aka URI scheme). If so, it will remove the app as the default handler.
|
||||
* `path` String (optional) _Windows_ - Defaults to `process.execPath`
|
||||
* `args` String[] (optional) _Windows_ - Defaults to an empty array
|
||||
|
||||
Returns `Boolean`
|
||||
|
||||
This method checks if the current executable is the default handler for a protocol
|
||||
(aka URI scheme). If so, it will return true. Otherwise, it will return false.
|
||||
Returns `Boolean` - Whether the current executable is the default handler for a
|
||||
protocol (aka URI scheme).
|
||||
|
||||
**Note:** On macOS, you can use this method to check if the app has been
|
||||
registered as the default protocol handler for a protocol. You can also verify
|
||||
@@ -760,7 +758,7 @@ this by checking `~/Library/Preferences/com.apple.LaunchServices.plist` on the
|
||||
macOS machine. Please refer to
|
||||
[Apple's documentation][LSCopyDefaultHandlerForURLScheme] for details.
|
||||
|
||||
The API uses the Windows Registry and LSCopyDefaultHandlerForURLScheme internally.
|
||||
The API uses the Windows Registry and `LSCopyDefaultHandlerForURLScheme` internally.
|
||||
|
||||
### `app.getApplicationNameForProtocol(url)`
|
||||
|
||||
@@ -1327,6 +1325,8 @@ A `Boolean` property that returns `true` if the app is packaged, `false` otherw
|
||||
[dock-menu]:https://developer.apple.com/macos/human-interface-guidelines/menus/dock-menus/
|
||||
[tasks]:https://msdn.microsoft.com/en-us/library/windows/desktop/dd378460(v=vs.85).aspx#tasks
|
||||
[app-user-model-id]: https://msdn.microsoft.com/en-us/library/windows/desktop/dd378459(v=vs.85).aspx
|
||||
[electron-forge]: https://www.electronforge.io/
|
||||
[electron-packager]: https://github.com/electron/electron-packager
|
||||
[CFBundleURLTypes]: https://developer.apple.com/library/ios/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html#//apple_ref/doc/uid/TP40009249-102207-TPXREF115
|
||||
[LSCopyDefaultHandlerForURLScheme]: https://developer.apple.com/library/mac/documentation/Carbon/Reference/LaunchServicesReference/#//apple_ref/c/func/LSCopyDefaultHandlerForURLScheme
|
||||
[handoff]: https://developer.apple.com/library/ios/documentation/UserExperience/Conceptual/Handoff/HandoffFundamentals/HandoffFundamentals.html
|
||||
|
||||
@@ -289,7 +289,7 @@ It creates a new `BrowserWindow` with native properties as set by the `options`.
|
||||
between the web pages even when you specified different values for them,
|
||||
including but not limited to `preload`, `sandbox` and `nodeIntegration`.
|
||||
So it is suggested to use exact same `webPreferences` for web pages with
|
||||
the same `affinity`. _This property is experimental_
|
||||
the same `affinity`. _Deprecated_
|
||||
* `zoomFactor` Number (optional) - The default zoom factor of the page, `3.0` represents
|
||||
`300%`. Default is `1.0`.
|
||||
* `javascript` Boolean (optional) - Enables JavaScript support. Default is `true`.
|
||||
|
||||
@@ -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`
|
||||
|
||||
|
||||
62
docs/api/service-workers.md
Normal file
62
docs/api/service-workers.md
Normal file
@@ -0,0 +1,62 @@
|
||||
## Class: ServiceWorkers
|
||||
|
||||
> Query and receive events from a sessions active service workers.
|
||||
|
||||
Process: [Main](../glossary.md#main-process)
|
||||
|
||||
Instances of the `ServiceWorkers` class are accessed by using `serviceWorkers` property of
|
||||
a `Session`.
|
||||
|
||||
For example:
|
||||
|
||||
```javascript
|
||||
const { session } = require('electron')
|
||||
|
||||
// Get all service workers.
|
||||
console.log(session.defaultSession.serviceWorkers.getAllRunning())
|
||||
|
||||
// Handle logs and get service worker info
|
||||
session.defaultSession.serviceWorkers.on('console-message', (event, messageDetails) => {
|
||||
console.log(
|
||||
'Got service worker message',
|
||||
messageDetails,
|
||||
'from',
|
||||
session.defaultSession.serviceWorkers.getFromVersionID(messageDetails.versionId)
|
||||
)
|
||||
})
|
||||
```
|
||||
|
||||
### Instance Events
|
||||
|
||||
The following events are available on instances of `ServiceWorkers`:
|
||||
|
||||
#### Event: 'console-message'
|
||||
|
||||
Returns:
|
||||
|
||||
* `event` Event
|
||||
* `messageDetails` Object - Information about the console message
|
||||
* `message` String - The actual console message
|
||||
* `versionId` Number - The version ID of the service worker that sent the log message
|
||||
* `source` String - The type of source for this message. Can be `javascript`, `xml`, `network`, `console-api`, `storage`, `app-cache`, `rendering`, `security`, `deprecation`, `worker`, `violation`, `intervention`, `recommendation` or `other`.
|
||||
* `level` Number - The log level, from 0 to 3. In order it matches `verbose`, `info`, `warning` and `error`.
|
||||
* `sourceUrl` String - The URL the message came from
|
||||
* `lineNumber` Number - The line number of the source that triggered this console message
|
||||
|
||||
Emitted when a service worker logs something to the console.
|
||||
|
||||
### Instance Methods
|
||||
|
||||
The following methods are available on instances of `ServiceWorkers`:
|
||||
|
||||
#### `serviceWorkers.getAllRunning()`
|
||||
|
||||
Returns `Record<Number, ServiceWorkerInfo>` - A [ServiceWorkerInfo](structures/service-worker-info.md) object where the keys are the service worker version ID and the values are the information about that service worker.
|
||||
|
||||
#### `serviceWorkers.getFromVersionID(versionId)`
|
||||
|
||||
* `versionId` Number
|
||||
|
||||
Returns [`ServiceWorkerInfo`](structures/service-worker-info.md) - Information about this service worker
|
||||
|
||||
If the service worker does not exist or is not running this method will throw an exception.
|
||||
@@ -485,8 +485,17 @@ behavior you can use this API to point the dictionary downloader at your own hos
|
||||
dictionaries. We publish a `hunspell_dictionaries.zip` file with each release which contains the files you need
|
||||
to host here.
|
||||
|
||||
If the files present in `hunspell_dictionaries.zip` are available at `https://example.com/dictionaries/language-code.bdic`
|
||||
then you should call this api with `ses.setSpellCheckerDictionaryDownloadURL('https://example.com/dictionaries/')`. Please
|
||||
note the trailing slash. The URL to the dictionaries is formed as `${url}${filename}`.
|
||||
|
||||
**Note:** On macOS the OS spellchecker is used and therefore we do not download any dictionary files. This API is a no-op on macOS.
|
||||
|
||||
#### `ses.listWordsInSpellCheckerDictionary()`
|
||||
|
||||
Returns `Promise<String[]>` - An array of all words in app's custom dictionary.
|
||||
Resolves when the full dictionary is loaded from disk.
|
||||
|
||||
#### `ses.addWordToSpellCheckerDictionary(word)`
|
||||
|
||||
* `word` String - The word you want to add to the dictionary
|
||||
@@ -567,6 +576,10 @@ code to the `setSpellCheckerLanaguages` API that isn't in this array will result
|
||||
|
||||
A [`Cookies`](cookies.md) object for this session.
|
||||
|
||||
#### `ses.serviceWorkers` _Readonly_
|
||||
|
||||
A [`ServiceWorkers`](service-workers.md) object for this session.
|
||||
|
||||
#### `ses.webRequest` _Readonly_
|
||||
|
||||
A [`WebRequest`](web-request.md) object for this session.
|
||||
|
||||
5
docs/api/structures/service-worker-info.md
Normal file
5
docs/api/structures/service-worker-info.md
Normal file
@@ -0,0 +1,5 @@
|
||||
# ServiceWorkerInfo Object
|
||||
|
||||
* `scriptUrl` String - The full URL to the script that this service worker runs
|
||||
* `scope` String - The base URL that this service worker is active for.
|
||||
* `renderProcessId` Number - The virtual ID of the process that this service worker is running in. This is not an OS level PID. This aligns with the ID set used for `webContents.getProcessId()`.
|
||||
@@ -404,8 +404,6 @@ Returns `Boolean` - whether or not this device has the ability to use Touch ID.
|
||||
|
||||
**NOTE:** This API will return `false` on macOS systems older than Sierra 10.12.2.
|
||||
|
||||
**[Deprecated](modernization/property-updates.md)**
|
||||
|
||||
### `systemPreferences.promptTouchID(reason)` _macOS_
|
||||
|
||||
* `reason` String - The reason you are asking for Touch ID authentication
|
||||
|
||||
@@ -146,6 +146,7 @@ response are visible by the time this listener is fired.
|
||||
* `timestamp` Double
|
||||
* `statusLine` String
|
||||
* `statusCode` Integer
|
||||
* `requestHeaders` Record<string, string>
|
||||
* `responseHeaders` Record<string, string[]> (optional)
|
||||
* `callback` Function
|
||||
* `headersReceivedResponse` Object
|
||||
@@ -228,6 +229,7 @@ redirect is about to occur.
|
||||
* `fromCache` Boolean
|
||||
* `statusCode` Integer
|
||||
* `statusLine` String
|
||||
* `error` String
|
||||
|
||||
The `listener` will be called with `listener(details)` when a request is
|
||||
completed.
|
||||
|
||||
@@ -92,10 +92,14 @@ template("electron_extra_paks") {
|
||||
}
|
||||
if (enable_electron_extensions) {
|
||||
sources += [
|
||||
"$root_gen_dir/chrome/component_extension_resources.pak",
|
||||
"$root_gen_dir/extensions/extensions_renderer_resources.pak",
|
||||
"$root_gen_dir/extensions/extensions_resources.pak",
|
||||
]
|
||||
deps += [ "//extensions:extensions_resources" ]
|
||||
deps += [
|
||||
"//chrome/browser/resources:component_extension_resources",
|
||||
"//extensions:extensions_resources",
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,7 +17,8 @@
|
||||
<part file="electron_strings.grdp" />
|
||||
</messages>
|
||||
<includes>
|
||||
<include name="IDR_CONTENT_SHELL_DEVTOOLS_DISCOVERY_PAGE" file="${target_gen_dir}\shell_devtools_discovery_page.html" use_base_dir="false" type="BINDATA" />
|
||||
<include name="IDR_CONTENT_SHELL_DEVTOOLS_DISCOVERY_PAGE" file="${target_gen_dir}/shell_devtools_discovery_page.html" use_base_dir="false" type="BINDATA" />
|
||||
<include name="IDR_PDF_MANIFEST" file="../chrome/browser/resources/pdf/manifest.json" type="BINDATA" />
|
||||
</includes>
|
||||
</release>
|
||||
</grit>
|
||||
|
||||
@@ -45,6 +45,7 @@ auto_filenames = {
|
||||
"docs/api/remote.md",
|
||||
"docs/api/sandbox-option.md",
|
||||
"docs/api/screen.md",
|
||||
"docs/api/service-workers.md",
|
||||
"docs/api/session.md",
|
||||
"docs/api/shell.md",
|
||||
"docs/api/structures",
|
||||
@@ -110,6 +111,7 @@ auto_filenames = {
|
||||
"docs/api/structures/remove-password.md",
|
||||
"docs/api/structures/scrubber-item.md",
|
||||
"docs/api/structures/segmented-control-segment.md",
|
||||
"docs/api/structures/service-worker-info.md",
|
||||
"docs/api/structures/shared-worker-info.md",
|
||||
"docs/api/structures/shortcut-details.md",
|
||||
"docs/api/structures/size.md",
|
||||
|
||||
@@ -88,6 +88,8 @@ filenames = {
|
||||
"shell/browser/api/electron_api_protocol.h",
|
||||
"shell/browser/api/electron_api_screen.cc",
|
||||
"shell/browser/api/electron_api_screen.h",
|
||||
"shell/browser/api/electron_api_service_worker_context.cc",
|
||||
"shell/browser/api/electron_api_service_worker_context.h",
|
||||
"shell/browser/api/electron_api_session.cc",
|
||||
"shell/browser/api/electron_api_session.h",
|
||||
"shell/browser/api/electron_api_system_preferences.cc",
|
||||
@@ -234,12 +236,15 @@ filenames = {
|
||||
"shell/browser/net/node_stream_loader.h",
|
||||
"shell/browser/net/proxying_url_loader_factory.cc",
|
||||
"shell/browser/net/proxying_url_loader_factory.h",
|
||||
"shell/browser/net/proxying_websocket.cc",
|
||||
"shell/browser/net/proxying_websocket.h",
|
||||
"shell/browser/net/resolve_proxy_helper.cc",
|
||||
"shell/browser/net/resolve_proxy_helper.h",
|
||||
"shell/browser/net/system_network_context_manager.cc",
|
||||
"shell/browser/net/system_network_context_manager.h",
|
||||
"shell/browser/net/url_pipe_loader.cc",
|
||||
"shell/browser/net/url_pipe_loader.h",
|
||||
"shell/browser/net/web_request_api_interface.h",
|
||||
"shell/browser/network_hints_handler_impl.cc",
|
||||
"shell/browser/network_hints_handler_impl.h",
|
||||
"shell/browser/node_debugger.cc",
|
||||
@@ -276,6 +281,8 @@ filenames = {
|
||||
"shell/browser/notifications/win/win32_notification.h",
|
||||
"shell/browser/notifications/win/windows_toast_notification.cc",
|
||||
"shell/browser/notifications/win/windows_toast_notification.h",
|
||||
"shell/browser/plugins/plugin_utils.cc",
|
||||
"shell/browser/plugins/plugin_utils.h",
|
||||
"shell/browser/pref_store_delegate.cc",
|
||||
"shell/browser/pref_store_delegate.h",
|
||||
"shell/browser/relauncher.cc",
|
||||
@@ -551,6 +558,7 @@ filenames = {
|
||||
"shell/common/skia_util.h",
|
||||
"shell/common/v8_value_converter.cc",
|
||||
"shell/common/v8_value_converter.h",
|
||||
"shell/common/world_ids.h",
|
||||
"shell/renderer/api/context_bridge/render_frame_context_bridge_store.cc",
|
||||
"shell/renderer/api/context_bridge/render_frame_context_bridge_store.h",
|
||||
"shell/renderer/api/electron_api_context_bridge.cc",
|
||||
@@ -591,14 +599,18 @@ filenames = {
|
||||
]
|
||||
|
||||
lib_sources_extensions = [
|
||||
"shell/browser/extensions/api/resources_private/resources_private_api.cc",
|
||||
"shell/browser/extensions/api/resources_private/resources_private_api.h",
|
||||
"shell/browser/extensions/api/runtime/electron_runtime_api_delegate.cc",
|
||||
"shell/browser/extensions/api/runtime/electron_runtime_api_delegate.h",
|
||||
"shell/browser/extensions/api/tabs/tabs_api.cc",
|
||||
"shell/browser/extensions/api/tabs/tabs_api.h",
|
||||
"shell/browser/extensions/electron_extensions_browser_client.cc",
|
||||
"shell/browser/extensions/electron_extensions_browser_client.h",
|
||||
"shell/browser/extensions/api/streams_private/streams_private_api.cc",
|
||||
"shell/browser/extensions/api/streams_private/streams_private_api.h",
|
||||
"shell/browser/extensions/electron_browser_context_keyed_service_factories.cc",
|
||||
"shell/browser/extensions/electron_browser_context_keyed_service_factories.h",
|
||||
"shell/browser/extensions/electron_component_extension_resource_manager.cc",
|
||||
"shell/browser/extensions/electron_component_extension_resource_manager.h",
|
||||
"shell/browser/extensions/electron_display_info_provider.cc",
|
||||
"shell/browser/extensions/electron_display_info_provider.h",
|
||||
"shell/browser/extensions/electron_extension_host_delegate.cc",
|
||||
@@ -611,24 +623,26 @@ filenames = {
|
||||
"shell/browser/extensions/electron_extension_system_factory.h",
|
||||
"shell/browser/extensions/electron_extension_web_contents_observer.cc",
|
||||
"shell/browser/extensions/electron_extension_web_contents_observer.h",
|
||||
"shell/browser/extensions/electron_navigation_ui_data.cc",
|
||||
"shell/browser/extensions/electron_navigation_ui_data.h",
|
||||
"shell/browser/extensions/electron_process_manager_delegate.cc",
|
||||
"shell/browser/extensions/electron_process_manager_delegate.h",
|
||||
"shell/browser/extensions/electron_extensions_api_client.cc",
|
||||
"shell/browser/extensions/electron_extensions_api_client.h",
|
||||
"shell/browser/extensions/electron_extensions_browser_api_provider.cc",
|
||||
"shell/browser/extensions/electron_extensions_browser_api_provider.h",
|
||||
"shell/browser/extensions/electron_extensions_browser_client.cc",
|
||||
"shell/browser/extensions/electron_extensions_browser_client.h",
|
||||
"shell/browser/extensions/electron_messaging_delegate.cc",
|
||||
"shell/browser/extensions/electron_messaging_delegate.h",
|
||||
"shell/browser/extensions/electron_navigation_ui_data.cc",
|
||||
"shell/browser/extensions/electron_navigation_ui_data.h",
|
||||
"shell/browser/extensions/electron_process_manager_delegate.cc",
|
||||
"shell/browser/extensions/electron_process_manager_delegate.h",
|
||||
"shell/common/extensions/electron_extensions_api_provider.cc",
|
||||
"shell/common/extensions/electron_extensions_api_provider.h",
|
||||
"shell/common/extensions/electron_extensions_client.cc",
|
||||
"shell/common/extensions/electron_extensions_client.h",
|
||||
"shell/renderer/extensions/electron_extensions_renderer_client.cc",
|
||||
"shell/renderer/extensions/electron_extensions_renderer_client.h",
|
||||
"shell/renderer/extensions/electron_extensions_dispatcher_delegate.cc",
|
||||
"shell/renderer/extensions/electron_extensions_dispatcher_delegate.h",
|
||||
"shell/renderer/extensions/electron_extensions_renderer_client.cc",
|
||||
"shell/renderer/extensions/electron_extensions_renderer_client.h",
|
||||
]
|
||||
|
||||
app_sources = [
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
const { EventEmitter } = require('events')
|
||||
const { app, deprecate } = require('electron')
|
||||
const { fromPartition, Session, Cookies, NetLog, Protocol } = process.electronBinding('session')
|
||||
const { fromPartition, Session, Cookies, NetLog, Protocol, ServiceWorkerContext } = process.electronBinding('session')
|
||||
|
||||
// Public API.
|
||||
Object.defineProperties(exports, {
|
||||
@@ -16,8 +16,9 @@ Object.defineProperties(exports, {
|
||||
}
|
||||
})
|
||||
|
||||
Object.setPrototypeOf(Session.prototype, EventEmitter.prototype)
|
||||
Object.setPrototypeOf(Cookies.prototype, EventEmitter.prototype)
|
||||
Object.setPrototypeOf(ServiceWorkerContext.prototype, EventEmitter.prototype)
|
||||
Object.setPrototypeOf(Session.prototype, EventEmitter.prototype)
|
||||
|
||||
Session.prototype._init = function () {
|
||||
app.emit('session-created', this)
|
||||
|
||||
@@ -18,8 +18,10 @@ require('@electron/internal/common/init')
|
||||
if (process.platform === 'win32') {
|
||||
// Redirect node's console to use our own implementations, since node can not
|
||||
// handle console output when running as GUI program.
|
||||
const consoleLog = (format: any, ...args: any[]) => {
|
||||
return process.log(util.format(format, ...args) + '\n')
|
||||
const consoleLog = (...args: any[]) => {
|
||||
// @ts-ignore this typing is incorrect; 'format' is an optional parameter
|
||||
// See https://nodejs.org/api/util.html#util_util_format_format_args
|
||||
return process.log(util.format(...args) + '\n')
|
||||
}
|
||||
const streamWrite: NodeJS.WritableStream['write'] = function (chunk: Buffer | string, encoding?: any, callback?: Function) {
|
||||
if (Buffer.isBuffer(chunk)) {
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
const binding = process.electronBinding('crash_reporter')
|
||||
|
||||
class CrashReporter {
|
||||
contructor () {
|
||||
constructor () {
|
||||
this.productName = null
|
||||
this.crashesDirectory = null
|
||||
}
|
||||
|
||||
@@ -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.")
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "electron",
|
||||
"version": "9.0.0-nightly.20200205",
|
||||
"version": "9.0.0-beta.5",
|
||||
"repository": "https://github.com/electron/electron",
|
||||
"description": "Build cross platform desktop apps with JavaScript, HTML, and CSS",
|
||||
"devDependencies": {
|
||||
@@ -19,6 +19,7 @@
|
||||
"@types/semver": "^6.0.1",
|
||||
"@types/send": "^0.14.5",
|
||||
"@types/split": "^1.0.0",
|
||||
"@types/uuid": "^3.4.6",
|
||||
"@types/webpack": "^4.4.32",
|
||||
"@types/webpack-env": "^1.13.9",
|
||||
"@typescript-eslint/eslint-plugin": "^2.6.0",
|
||||
|
||||
@@ -31,11 +31,12 @@ scroll_bounce_flag.patch
|
||||
mas-cfisobjc.patch
|
||||
mas-cgdisplayusesforcetogray.patch
|
||||
mas-audiodeviceduck.patch
|
||||
mas_disable_remote_layer.patch
|
||||
mas_disable_remote_accessibility.patch
|
||||
mas_disable_custom_window_frame.patch
|
||||
chrome_key_systems.patch
|
||||
allow_nested_error_trackers.patch
|
||||
blink_initialization_order.patch
|
||||
add_didinstallconditionalfeatures.patch
|
||||
ssl_security_state_tab_helper.patch
|
||||
desktop_media_list.patch
|
||||
proxy_config_monitor.patch
|
||||
@@ -81,3 +82,7 @@ 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
|
||||
use_electron_resources_in_pdf_util.patch
|
||||
hack_plugin_response_interceptor_to_point_to_electron.patch
|
||||
fix_route_mouse_event_navigations_through_the_web_contents_delegate.patch
|
||||
feat_add_support_for_overriding_the_base_spellchecker_download_url.patch
|
||||
|
||||
137
patches/chromium/add_didinstallconditionalfeatures.patch
Normal file
137
patches/chromium/add_didinstallconditionalfeatures.patch
Normal 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; }
|
||||
@@ -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();
|
||||
}
|
||||
@@ -6,6 +6,18 @@ Subject: chore: use electron resources not chrome for spellchecker
|
||||
spellchecker uses a few IDS_ resources. We need to load these from
|
||||
Electrons grit header instead of Chromes
|
||||
|
||||
diff --git a/chrome/browser/BUILD.gn b/chrome/browser/BUILD.gn
|
||||
index d730660c086f..ba9b098d848e 100644
|
||||
--- a/chrome/browser/BUILD.gn
|
||||
+++ b/chrome/browser/BUILD.gn
|
||||
@@ -5049,6 +5049,7 @@ jumbo_split_static_library("browser") {
|
||||
deps += [
|
||||
"//components/spellcheck/browser",
|
||||
"//components/spellcheck/common",
|
||||
+ "//electron:resources",
|
||||
]
|
||||
|
||||
if (!is_android) {
|
||||
diff --git a/chrome/browser/spellchecker/spellcheck_factory.cc b/chrome/browser/spellchecker/spellcheck_factory.cc
|
||||
index 48ac0a24efde0cb7d3ba71c8b8bdf5178f606e80..e2beefc276098fdc8f1cdab2e0edb8fae4ee67ca 100644
|
||||
--- a/chrome/browser/spellchecker/spellcheck_factory.cc
|
||||
@@ -19,6 +31,18 @@ index 48ac0a24efde0cb7d3ba71c8b8bdf5178f606e80..e2beefc276098fdc8f1cdab2e0edb8fa
|
||||
#include "components/keyed_service/content/browser_context_dependency_manager.h"
|
||||
#include "components/pref_registry/pref_registry_syncable.h"
|
||||
#include "components/prefs/pref_service.h"
|
||||
diff --git a/components/language/core/browser/BUILD.gn b/components/language/core/browser/BUILD.gn
|
||||
index f28230ea94fe..c10eea103852 100644
|
||||
--- a/components/language/core/browser/BUILD.gn
|
||||
+++ b/components/language/core/browser/BUILD.gn
|
||||
@@ -31,6 +31,7 @@ static_library("browser") {
|
||||
"//components/pref_registry",
|
||||
"//components/prefs",
|
||||
"//components/strings",
|
||||
+ "//electron:resources",
|
||||
"//ui/base",
|
||||
]
|
||||
}
|
||||
diff --git a/components/language/core/browser/language_prefs.cc b/components/language/core/browser/language_prefs.cc
|
||||
index 7e06f689632ae67e3e17d7985c6e7b6ea0057f3c..0b4676f4c40b4a0eda927a51016ec91ec230291d 100644
|
||||
--- a/components/language/core/browser/language_prefs.cc
|
||||
|
||||
@@ -0,0 +1,58 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Samuel Attard <sattard@slack-corp.com>
|
||||
Date: Tue, 25 Feb 2020 13:28:30 -0800
|
||||
Subject: feat: add support for overriding the base spellchecker download URL
|
||||
|
||||
This patch is required as the testing-only method we were using does not
|
||||
take into account the dictionary name and therefore will not work for
|
||||
production use cases. This is unlikely to be upstreamed as the change
|
||||
is entirely in //chrome.
|
||||
|
||||
diff --git a/chrome/browser/spellchecker/spellcheck_hunspell_dictionary.cc b/chrome/browser/spellchecker/spellcheck_hunspell_dictionary.cc
|
||||
index 0fb84989f9b2f84ec2a2589dda3d91cf59c0adda..9ff5b33d2885c5532e1496711c27a01c8502725c 100644
|
||||
--- a/chrome/browser/spellchecker/spellcheck_hunspell_dictionary.cc
|
||||
+++ b/chrome/browser/spellchecker/spellcheck_hunspell_dictionary.cc
|
||||
@@ -48,6 +48,9 @@ namespace {
|
||||
base::LazyInstance<GURL>::Leaky g_download_url_for_testing =
|
||||
LAZY_INSTANCE_INITIALIZER;
|
||||
|
||||
+base::LazyInstance<GURL>::Leaky g_base_download_url_override =
|
||||
+ LAZY_INSTANCE_INITIALIZER;
|
||||
+
|
||||
// Close the file.
|
||||
void CloseDictionary(base::File file) {
|
||||
base::ScopedBlockingCall scoped_blocking_call(FROM_HERE,
|
||||
@@ -247,6 +250,10 @@ void SpellcheckHunspellDictionary::SetDownloadURLForTesting(const GURL url) {
|
||||
g_download_url_for_testing.Get() = url;
|
||||
}
|
||||
|
||||
+void SpellcheckHunspellDictionary::SetBaseDownloadURL(const GURL url) {
|
||||
+ g_base_download_url_override.Get() = url;
|
||||
+}
|
||||
+
|
||||
GURL SpellcheckHunspellDictionary::GetDictionaryURL() {
|
||||
if (g_download_url_for_testing.Get() != GURL())
|
||||
return g_download_url_for_testing.Get();
|
||||
@@ -254,6 +261,9 @@ GURL SpellcheckHunspellDictionary::GetDictionaryURL() {
|
||||
std::string bdict_file = dictionary_file_.path.BaseName().MaybeAsASCII();
|
||||
DCHECK(!bdict_file.empty());
|
||||
|
||||
+ if (g_base_download_url_override.Get() != GURL())
|
||||
+ return GURL(g_base_download_url_override.Get().spec() + base::ToLowerASCII(bdict_file));
|
||||
+
|
||||
static const char kDownloadServerUrl[] =
|
||||
"https://redirector.gvt1.com/edgedl/chrome/dict/";
|
||||
|
||||
diff --git a/chrome/browser/spellchecker/spellcheck_hunspell_dictionary.h b/chrome/browser/spellchecker/spellcheck_hunspell_dictionary.h
|
||||
index 4af3201238dfec14bd5a4241b662ca52799e6862..4662bdc08b54304a7f8b2995f60fea9dc5617fff 100644
|
||||
--- a/chrome/browser/spellchecker/spellcheck_hunspell_dictionary.h
|
||||
+++ b/chrome/browser/spellchecker/spellcheck_hunspell_dictionary.h
|
||||
@@ -85,6 +85,8 @@ class SpellcheckHunspellDictionary
|
||||
// Tests use this method to set a custom URL for downloading dictionaries.
|
||||
static void SetDownloadURLForTesting(const GURL url);
|
||||
|
||||
+ static void SetBaseDownloadURL(const GURL url);
|
||||
+
|
||||
private:
|
||||
// Dictionary download status.
|
||||
enum DownloadStatus {
|
||||
@@ -0,0 +1,34 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Samuel Attard <sattard@slack-corp.com>
|
||||
Date: Fri, 14 Feb 2020 13:35:47 -0800
|
||||
Subject: fix: route mouse event navigations through the web_contents delegate
|
||||
|
||||
This ensures that embedders can handle browser-side mouse navigations
|
||||
themselves. We need this so that we can correctly ensure that processes
|
||||
are not restarted for in-document navigations.
|
||||
|
||||
Refs: https://chromium-review.googlesource.com/c/chromium/src/+/1769525
|
||||
|
||||
This patch can be removed once app.allowRendererProcessReuse is forced
|
||||
to true as then Chromiums assumptions around processes become correct.
|
||||
|
||||
diff --git a/content/browser/web_contents/web_contents_impl.cc b/content/browser/web_contents/web_contents_impl.cc
|
||||
index 70d735dcc38734edaaf6221cd40c49beb6d2e37e..9cd7368966c20b9e9306c41e455c002d686d3013 100644
|
||||
--- a/content/browser/web_contents/web_contents_impl.cc
|
||||
+++ b/content/browser/web_contents/web_contents_impl.cc
|
||||
@@ -2347,11 +2347,13 @@ bool WebContentsImpl::HandleMouseEvent(const blink::WebMouseEvent& event) {
|
||||
WebContentsImpl* outermost = GetOutermostWebContents();
|
||||
if (event.button == blink::WebPointerProperties::Button::kBack &&
|
||||
outermost->controller_.CanGoBack()) {
|
||||
- outermost->controller_.GoBack();
|
||||
+ if (delegate_->OnGoToEntryOffset(-1))
|
||||
+ outermost->controller_.GoBack();
|
||||
return true;
|
||||
} else if (event.button == blink::WebPointerProperties::Button::kForward &&
|
||||
outermost->controller_.CanGoForward()) {
|
||||
- outermost->controller_.GoForward();
|
||||
+ if (delegate_->OnGoToEntryOffset(1))
|
||||
+ outermost->controller_.GoForward();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Jeremy Apthorp <nornagon@nornagon.net>
|
||||
Date: Mon, 10 Feb 2020 11:52:23 -0800
|
||||
Subject: hack plugin response interceptor to point to electron
|
||||
|
||||
chrome's streams_private_api does prerender and other things and would
|
||||
require a largeish patch to get working, so just redirect it to our
|
||||
implementation instead.
|
||||
|
||||
diff --git a/chrome/browser/plugins/plugin_response_interceptor_url_loader_throttle.cc b/chrome/browser/plugins/plugin_response_interceptor_url_loader_throttle.cc
|
||||
index 1c9aeb8fa71d054159c2ccccccbe57aa474d417e..0bd6412f2c79f77f936720b1a0795b50ecefd26c 100644
|
||||
--- a/chrome/browser/plugins/plugin_response_interceptor_url_loader_throttle.cc
|
||||
+++ b/chrome/browser/plugins/plugin_response_interceptor_url_loader_throttle.cc
|
||||
@@ -8,8 +8,8 @@
|
||||
#include "base/feature_list.h"
|
||||
#include "base/guid.h"
|
||||
#include "base/task/post_task.h"
|
||||
-#include "chrome/browser/extensions/api/streams_private/streams_private_api.h"
|
||||
-#include "chrome/browser/plugins/plugin_utils.h"
|
||||
+#include "electron/shell/browser/extensions/api/streams_private/streams_private_api.h"
|
||||
+#include "electron/shell/browser/plugins/plugin_utils.h"
|
||||
#include "content/public/browser/browser_task_traits.h"
|
||||
#include "content/public/browser/browser_thread.h"
|
||||
#include "content/public/browser/download_utils.h"
|
||||
137
patches/chromium/mas_disable_remote_layer.patch
Normal file
137
patches/chromium/mas_disable_remote_layer.patch
Normal file
@@ -0,0 +1,137 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Cheng Zhao <zcbenz@gmail.com>
|
||||
Date: Thu, 20 Sep 2018 17:48:49 -0700
|
||||
Subject: mas_disable_remote_layer.patch
|
||||
|
||||
Disable remote layer APIs (CAContext and CALayerHost) for MAS build.
|
||||
|
||||
Accordin to ccameron:
|
||||
|
||||
For apps that spend a lot of time watching video (especially fullscreen video),
|
||||
the power/battery usage will likely increase 1.5x to 2x. For something that is,
|
||||
e.g, scrolling, it'll be smaller, more like 1.15x or 1.25x.
|
||||
|
||||
In terms of performance, the impact will likely be fairly small -- any app that
|
||||
could hit 60fps before will likely still be able to hit 60fps. There may even be
|
||||
cases where performance improves when disabling remote CoreAnimation (remote
|
||||
CoreAnimation is really only about battery usage).
|
||||
|
||||
diff --git a/gpu/ipc/service/image_transport_surface_overlay_mac.mm b/gpu/ipc/service/image_transport_surface_overlay_mac.mm
|
||||
index c1af03a268dc..b883883ad52b 100644
|
||||
--- a/gpu/ipc/service/image_transport_surface_overlay_mac.mm
|
||||
+++ b/gpu/ipc/service/image_transport_surface_overlay_mac.mm
|
||||
@@ -63,6 +63,7 @@
|
||||
template <typename BaseClass>
|
||||
bool ImageTransportSurfaceOverlayMacBase<BaseClass>::Initialize(
|
||||
gl::GLSurfaceFormat format) {
|
||||
+#ifndef MAS_BUILD
|
||||
// Create the CAContext to send this to the GPU process, and the layer for
|
||||
// the context.
|
||||
if (use_remote_layer_api_) {
|
||||
@@ -71,6 +72,7 @@
|
||||
[CAContext contextWithCGSConnection:connection_id options:@{}] retain]);
|
||||
[ca_context_ setLayer:ca_layer_tree_coordinator_->GetCALayerForDisplay()];
|
||||
}
|
||||
+#endif
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -139,7 +141,9 @@
|
||||
"GLImpl", static_cast<int>(gl::GetGLImplementation()),
|
||||
"width", pixel_size_.width());
|
||||
if (use_remote_layer_api_) {
|
||||
+#ifndef MAS_BUILD
|
||||
params.ca_layer_params.ca_context_id = [ca_context_ contextId];
|
||||
+#endif
|
||||
} else {
|
||||
IOSurfaceRef io_surface =
|
||||
ca_layer_tree_coordinator_->GetIOSurfaceForDisplay();
|
||||
diff --git a/gpu/ipc/service/image_transport_surface_overlay_mac.h b/gpu/ipc/service/image_transport_surface_overlay_mac.h
|
||||
index f65ad035e90c..9edb62e713e8 100644
|
||||
--- a/gpu/ipc/service/image_transport_surface_overlay_mac.h
|
||||
+++ b/gpu/ipc/service/image_transport_surface_overlay_mac.h
|
||||
@@ -20,7 +20,9 @@
|
||||
#include "ui/gl/gl_surface_egl.h"
|
||||
#endif
|
||||
|
||||
+#ifndef MAS_BUILD
|
||||
@class CAContext;
|
||||
+#endif
|
||||
@class CALayer;
|
||||
|
||||
namespace ui {
|
||||
@@ -97,7 +99,9 @@ class ImageTransportSurfaceOverlayMacBase : public BaseClass,
|
||||
base::WeakPtr<ImageTransportSurfaceDelegate> delegate_;
|
||||
|
||||
bool use_remote_layer_api_;
|
||||
+#ifndef MAS_BUILD
|
||||
base::scoped_nsobject<CAContext> ca_context_;
|
||||
+#endif
|
||||
std::unique_ptr<ui::CALayerTreeCoordinator> ca_layer_tree_coordinator_;
|
||||
|
||||
gfx::Size pixel_size_;
|
||||
diff --git a/ui/accelerated_widget_mac/display_ca_layer_tree.mm b/ui/accelerated_widget_mac/display_ca_layer_tree.mm
|
||||
index 60abe639bd9c..c38eed5fbdef 100644
|
||||
--- a/ui/accelerated_widget_mac/display_ca_layer_tree.mm
|
||||
+++ b/ui/accelerated_widget_mac/display_ca_layer_tree.mm
|
||||
@@ -98,6 +98,7 @@ - (void)setContentsChanged;
|
||||
}
|
||||
|
||||
void DisplayCALayerTree::GotCALayerFrame(uint32_t ca_context_id) {
|
||||
+#ifndef MAS_BUILD
|
||||
// Early-out if the remote layer has not changed.
|
||||
if ([remote_layer_ contextId] == ca_context_id)
|
||||
return;
|
||||
@@ -122,6 +123,9 @@ - (void)setContentsChanged;
|
||||
[io_surface_layer_ removeFromSuperlayer];
|
||||
io_surface_layer_.reset();
|
||||
}
|
||||
+#else
|
||||
+ NOTREACHED() << "Remote layer is being used in MAS build";
|
||||
+#endif
|
||||
}
|
||||
|
||||
void DisplayCALayerTree::GotIOSurfaceFrame(
|
||||
diff --git a/ui/base/cocoa/remote_layer_api.h b/ui/base/cocoa/remote_layer_api.h
|
||||
index 2057fe69d1bb..2aba330fc488 100644
|
||||
--- a/ui/base/cocoa/remote_layer_api.h
|
||||
+++ b/ui/base/cocoa/remote_layer_api.h
|
||||
@@ -13,6 +13,7 @@
|
||||
|
||||
#include "ui/base/ui_base_export.h"
|
||||
|
||||
+#ifndef MAS_BUILD
|
||||
// The CGSConnectionID is used to create the CAContext in the process that is
|
||||
// going to share the CALayers that it is rendering to another process to
|
||||
// display.
|
||||
@@ -50,6 +51,8 @@ typedef uint32_t CAContextID;
|
||||
|
||||
#endif // __OBJC__
|
||||
|
||||
+#endif // MAS_BUILD
|
||||
+
|
||||
namespace ui {
|
||||
|
||||
// This function will check if all of the interfaces listed above are supported
|
||||
diff --git a/ui/base/cocoa/remote_layer_api.mm b/ui/base/cocoa/remote_layer_api.mm
|
||||
index bbaf9f466f49..8c846ce9523a 100644
|
||||
--- a/ui/base/cocoa/remote_layer_api.mm
|
||||
+++ b/ui/base/cocoa/remote_layer_api.mm
|
||||
@@ -12,6 +12,7 @@
|
||||
namespace ui {
|
||||
|
||||
bool RemoteLayerAPISupported() {
|
||||
+#ifndef MAS_BUILD
|
||||
static bool disabled_at_command_line =
|
||||
base::CommandLine::ForCurrentProcess()->HasSwitch(
|
||||
switches::kDisableRemoteCoreAnimation);
|
||||
@@ -46,6 +47,9 @@ bool RemoteLayerAPISupported() {
|
||||
|
||||
// If everything is there, we should be able to use the API.
|
||||
return true;
|
||||
+#else
|
||||
+ return false;
|
||||
+#endif // MAS_BUILD
|
||||
}
|
||||
|
||||
} // namespace
|
||||
22
patches/chromium/use_electron_resources_in_pdf_util.patch
Normal file
22
patches/chromium/use_electron_resources_in_pdf_util.patch
Normal file
@@ -0,0 +1,22 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Jeremy Apthorp <nornagon@nornagon.net>
|
||||
Date: Mon, 10 Feb 2020 10:37:48 -0800
|
||||
Subject: use electron resources in pdf_util
|
||||
|
||||
Without this, the ID for IDR_PDF_MANIFEST will be wrong on linux
|
||||
and cause a DCHECK(), since the resource will be loaded as an empty
|
||||
string.
|
||||
|
||||
diff --git a/chrome/browser/pdf/pdf_extension_util.cc b/chrome/browser/pdf/pdf_extension_util.cc
|
||||
index 877d0ba2f48359243527ddebf1d91132b3d5c455..cd69de498c4968ade0ffabf45b72d4d63b70b10f 100644
|
||||
--- a/chrome/browser/pdf/pdf_extension_util.cc
|
||||
+++ b/chrome/browser/pdf/pdf_extension_util.cc
|
||||
@@ -6,7 +6,7 @@
|
||||
|
||||
#include "base/strings/string_util.h"
|
||||
#include "chrome/common/chrome_content_client.h"
|
||||
-#include "chrome/grit/browser_resources.h"
|
||||
+#include "electron/grit/electron_resources.h"
|
||||
#include "ui/base/resource/resource_bundle.h"
|
||||
|
||||
namespace pdf_extension_util {
|
||||
@@ -7,3 +7,4 @@ workaround_an_undefined_symbol_error.patch
|
||||
do_not_export_private_v8_symbols_on_windows.patch
|
||||
revert_cleanup_switch_offset_of_to_offsetof_where_possible.patch
|
||||
fix_build_deprecated_attirbute_for_older_msvc_versions.patch
|
||||
fix_bug_in_receiver_maps_inference.patch
|
||||
|
||||
19
patches/v8/fix_bug_in_receiver_maps_inference.patch
Normal file
19
patches/v8/fix_bug_in_receiver_maps_inference.patch
Normal file
@@ -0,0 +1,19 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Samuel Attard <sattard@slack-corp.com>
|
||||
Date: Thu, 27 Feb 2020 11:47:31 -0800
|
||||
Subject: Fix bug in receiver maps inference
|
||||
|
||||
Refs: https://chromium-review.googlesource.com/c/v8/v8/+/2062404
|
||||
|
||||
diff --git a/src/compiler/node-properties.cc b/src/compiler/node-properties.cc
|
||||
index f43a348bb2d5b803270e42f64a3c790c52a3581b..ab4ced69ab60d6078aeb27c3d8b97e87400687ce 100644
|
||||
--- a/src/compiler/node-properties.cc
|
||||
+++ b/src/compiler/node-properties.cc
|
||||
@@ -386,6 +386,7 @@ NodeProperties::InferReceiverMapsResult NodeProperties::InferReceiverMapsUnsafe(
|
||||
// We reached the allocation of the {receiver}.
|
||||
return kNoReceiverMaps;
|
||||
}
|
||||
+ result = kUnreliableReceiverMaps; // JSCreate can have side-effect.
|
||||
break;
|
||||
}
|
||||
case IrOpcode::kJSCreatePromise: {
|
||||
@@ -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({
|
||||
|
||||
@@ -120,8 +120,8 @@ def extract_zip(zip_path, destination):
|
||||
def make_zip(zip_file_path, files, dirs):
|
||||
safe_unlink(zip_file_path)
|
||||
if sys.platform == 'darwin':
|
||||
files += dirs
|
||||
execute(['zip', '-r', '-y', zip_file_path] + files)
|
||||
allfiles = files + dirs
|
||||
execute(['zip', '-r', '-y', zip_file_path] + allfiles)
|
||||
else:
|
||||
zip_file = zipfile.ZipFile(zip_file_path, "w", zipfile.ZIP_DEFLATED,
|
||||
allowZip64=True)
|
||||
|
||||
@@ -2,10 +2,16 @@ const cp = require('child_process')
|
||||
const fs = require('fs')
|
||||
const path = require('path')
|
||||
|
||||
const args = require('minimist')(process.argv.slice(2), {
|
||||
boolean: ['default'],
|
||||
string: ['jUnitDir']
|
||||
})
|
||||
|
||||
const BASE = path.resolve(__dirname, '../..')
|
||||
const DISABLED_TESTS = require('./node-disabled-tests.json')
|
||||
const NODE_DIR = path.resolve(BASE, 'third_party', 'electron_node')
|
||||
const NPX_CMD = process.platform === 'win32' ? 'npx.cmd' : 'npx'
|
||||
const JUNIT_DIR = process.argv[2] ? path.resolve(process.argv[2]) : null
|
||||
const JUNIT_DIR = args.jUnitDir ? path.resolve(args.jUnitDir) : null
|
||||
const TAP_FILE_NAME = 'test.tap'
|
||||
|
||||
const utils = require('./lib/utils')
|
||||
@@ -15,10 +21,43 @@ if (!process.mainModule) {
|
||||
throw new Error('Must call the node spec runner directly')
|
||||
}
|
||||
|
||||
async function main () {
|
||||
const DISABLED_TESTS = require('./node-disabled-tests.json')
|
||||
const defaultOptions = [
|
||||
'tools/test.py',
|
||||
'-p',
|
||||
'tap',
|
||||
'--logfile',
|
||||
TAP_FILE_NAME,
|
||||
'--mode=debug',
|
||||
'default',
|
||||
`--skip-tests=${DISABLED_TESTS.join(',')}`,
|
||||
'--shell',
|
||||
utils.getAbsoluteElectronExec(),
|
||||
'-J'
|
||||
]
|
||||
|
||||
const testChild = cp.spawn('python', ['tools/test.py', '--verbose', '-p', 'tap', '--logfile', TAP_FILE_NAME, '--mode=debug', 'default', `--skip-tests=${DISABLED_TESTS.join(',')}`, '--shell', utils.getAbsoluteElectronExec(), '-J'], {
|
||||
const getCustomOptions = () => {
|
||||
let customOptions = ['tools/test.py']
|
||||
|
||||
// Add all custom arguments.
|
||||
const extra = process.argv.slice(2)
|
||||
if (extra) {
|
||||
customOptions = customOptions.concat(extra)
|
||||
}
|
||||
|
||||
// We need this unilaterally or Node.js will try
|
||||
// to run from out/Release/node.
|
||||
customOptions = customOptions.concat([
|
||||
'--shell',
|
||||
utils.getAbsoluteElectronExec()
|
||||
])
|
||||
|
||||
return customOptions
|
||||
}
|
||||
|
||||
async function main () {
|
||||
const options = args.default ? defaultOptions : getCustomOptions()
|
||||
|
||||
const testChild = cp.spawn('python', options, {
|
||||
env: {
|
||||
...process.env,
|
||||
ELECTRON_RUN_AS_NODE: 'true',
|
||||
|
||||
@@ -23,6 +23,11 @@ const circleCIJobs = [
|
||||
'osx-publish'
|
||||
]
|
||||
|
||||
const circleCIPublishWorkflows = [
|
||||
'linux-publish',
|
||||
'macos-publish'
|
||||
]
|
||||
|
||||
const vstsArmJobs = [
|
||||
'electron-arm-testing',
|
||||
'electron-arm64-testing',
|
||||
@@ -87,13 +92,18 @@ async function circleCIcall (targetBranch, job, options) {
|
||||
if (workflowId === -1) {
|
||||
return
|
||||
}
|
||||
console.log(`CircleCI release build workflow running at https://circleci.com/workflow-run/${workflowId} for ${job}.`)
|
||||
const jobNumber = await getCircleCIJobNumber(workflowId)
|
||||
if (jobNumber === -1) {
|
||||
return
|
||||
const workFlowUrl = `https://circleci.com/workflow-run/${workflowId}`
|
||||
if (options.runningPublishWorkflows) {
|
||||
console.log(`CircleCI release workflow request for ${job} successful. Check ${workFlowUrl} for status.`)
|
||||
} else {
|
||||
console.log(`CircleCI release build workflow running at https://circleci.com/workflow-run/${workflowId} for ${job}.`)
|
||||
const jobNumber = await getCircleCIJobNumber(workflowId)
|
||||
if (jobNumber === -1) {
|
||||
return
|
||||
}
|
||||
const jobUrl = `https://circleci.com/gh/electron/electron/${jobNumber}`
|
||||
console.log(`CircleCI release build request for ${job} successful. Check ${jobUrl} for status.`)
|
||||
}
|
||||
const jobUrl = `https://circleci.com/gh/electron/electron/${jobNumber}`
|
||||
console.log(`CircleCI release build request for ${job} successful. Check ${jobUrl} for status.`)
|
||||
} catch (err) {
|
||||
console.log('Error calling CircleCI: ', err)
|
||||
}
|
||||
@@ -232,7 +242,8 @@ function buildCircleCI (targetBranch, options) {
|
||||
assert(circleCIJobs.includes(options.job), `Unknown CircleCI job name: ${options.job}. Valid values are: ${circleCIJobs}.`)
|
||||
circleCIcall(targetBranch, options.job, options)
|
||||
} else {
|
||||
circleCIJobs.forEach((job) => circleCIcall(targetBranch, job, options))
|
||||
options.runningPublishWorkflows = true
|
||||
circleCIPublishWorkflows.forEach((job) => circleCIcall(targetBranch, job, options))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -18,7 +18,7 @@ const CHECK_INTERVAL = 5000
|
||||
|
||||
const CACHE_DIR = path.resolve(__dirname, '.cache')
|
||||
const NO_NOTES = 'No notes'
|
||||
const FOLLOW_REPOS = [ 'electron/electron', 'electron/libchromiumcontent', 'electron/node' ]
|
||||
const FOLLOW_REPOS = [ 'electron/electron', 'electron/node' ]
|
||||
|
||||
const breakTypes = new Set(['breaking-change'])
|
||||
const docTypes = new Set(['doc', 'docs'])
|
||||
@@ -341,44 +341,6 @@ const addRepoToPool = async (pool, repo, from, to) => {
|
||||
**** Other Repos
|
||||
***/
|
||||
|
||||
// other repos - gyp
|
||||
|
||||
const getGypSubmoduleRef = async (dir, point) => {
|
||||
// example: '160000 commit 028b0af83076cec898f4ebce208b7fadb715656e libchromiumcontent'
|
||||
const response = await runGit(
|
||||
path.dirname(dir),
|
||||
['ls-tree', '-t', point, path.basename(dir)]
|
||||
)
|
||||
|
||||
const line = response.split('\n').filter(line => line.startsWith('160000')).shift()
|
||||
const tokens = line ? line.split(/\s/).map(token => token.trim()) : null
|
||||
const ref = tokens && tokens.length >= 3 ? tokens[2] : null
|
||||
|
||||
return ref
|
||||
}
|
||||
|
||||
const getDependencyCommitsGyp = async (pool, fromRef, toRef) => {
|
||||
const commits = []
|
||||
|
||||
const repos = [{
|
||||
owner: 'electron',
|
||||
repo: 'libchromiumcontent',
|
||||
dir: path.resolve(ELECTRON_VERSION, 'vendor', 'libchromiumcontent')
|
||||
}, {
|
||||
owner: 'electron',
|
||||
repo: 'node',
|
||||
dir: path.resolve(ELECTRON_VERSION, 'vendor', 'node')
|
||||
}]
|
||||
|
||||
for (const repo of repos) {
|
||||
const from = await getGypSubmoduleRef(repo.dir, fromRef)
|
||||
const to = await getGypSubmoduleRef(repo.dir, toRef)
|
||||
await addRepoToPool(pool, repo, from, to)
|
||||
}
|
||||
|
||||
return commits
|
||||
}
|
||||
|
||||
// other repos - gn
|
||||
|
||||
const getDepsVariable = async (ref, key) => {
|
||||
@@ -416,17 +378,6 @@ const getDependencyCommitsGN = async (pool, fromRef, toRef) => {
|
||||
}
|
||||
}
|
||||
|
||||
// other repos - controller
|
||||
|
||||
const getDependencyCommits = async (pool, from, to) => {
|
||||
const filename = path.resolve(ELECTRON_VERSION, 'vendor', 'libchromiumcontent')
|
||||
const useGyp = fs.existsSync(filename)
|
||||
|
||||
return useGyp
|
||||
? getDependencyCommitsGyp(pool, from, to)
|
||||
: getDependencyCommitsGN(pool, from, to)
|
||||
}
|
||||
|
||||
// Changes are interesting if they make a change relative to a previous
|
||||
// release in the same series. For example if you fix a Y.0.0 bug, that
|
||||
// should be included in the Y.0.1 notes even if it's also tropped back
|
||||
@@ -474,7 +425,7 @@ const getNotes = async (fromRef, toRef, newVersion) => {
|
||||
semver.major(fromRef) === semver.major(toRef)
|
||||
|
||||
if (includeDeps) {
|
||||
await getDependencyCommits(pool, fromRef, toRef)
|
||||
await getDependencyCommitsGN(pool, fromRef, toRef)
|
||||
}
|
||||
|
||||
// remove any old commits
|
||||
|
||||
@@ -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')
|
||||
@@ -204,13 +203,17 @@ async function runMainProcessElectronTests () {
|
||||
exe = 'python'
|
||||
}
|
||||
|
||||
const { status } = childProcess.spawnSync(exe, runnerArgs, {
|
||||
const { status, signal } = childProcess.spawnSync(exe, runnerArgs, {
|
||||
cwd: path.resolve(__dirname, '../..'),
|
||||
stdio: 'inherit'
|
||||
})
|
||||
if (status !== 0) {
|
||||
const textStatus = process.platform === 'win32' ? `0x${status.toString(16)}` : status.toString()
|
||||
console.log(`${fail} Electron tests failed with code ${textStatus}.`)
|
||||
if (status) {
|
||||
const textStatus = process.platform === 'win32' ? `0x${status.toString(16)}` : status.toString()
|
||||
console.log(`${fail} Electron tests failed with code ${textStatus}.`)
|
||||
} else {
|
||||
console.log(`${fail} Electron tests failed with kill signal ${signal}.`)
|
||||
}
|
||||
process.exit(1)
|
||||
}
|
||||
console.log(`${pass} Electron main process tests passed.`)
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -33,12 +33,13 @@
|
||||
#endif // defined(WIDEVINE_CDM_AVAILABLE)
|
||||
|
||||
#if BUILDFLAG(ENABLE_PDF_VIEWER)
|
||||
#include "pdf/pdf.h" // nogncheck
|
||||
#include "pdf/pdf_ppapi.h" // nogncheck
|
||||
#include "shell/common/electron_constants.h" // nogncheck
|
||||
#endif // BUILDFLAG(ENABLE_PDF_VIEWER)
|
||||
#include "pdf/pdf.h" // nogncheck
|
||||
#include "pdf/pdf_ppapi.h" // nogncheck
|
||||
#include "shell/common/electron_constants.h"
|
||||
#endif // BUILDFLAG(ENABLE_PDF_VIEWER)
|
||||
|
||||
#if BUILDFLAG(ENABLE_PLUGINS)
|
||||
#include "content/public/browser/plugin_service.h"
|
||||
#include "content/public/common/pepper_plugin_info.h"
|
||||
#include "ppapi/shared_impl/ppapi_permissions.h"
|
||||
#endif // BUILDFLAG(ENABLE_PLUGINS)
|
||||
@@ -155,7 +156,8 @@ void ComputeBuiltInPlugins(std::vector<content::PepperPluginInfo>* plugins) {
|
||||
pdf_info.is_out_of_process = true;
|
||||
pdf_info.name = "Chromium PDF Viewer";
|
||||
pdf_info.description = "Portable Document Format";
|
||||
pdf_info.path = base::FilePath(FILE_PATH_LITERAL("internal-pdf-viewer"));
|
||||
// This isn't a real file path; it's just used as a unique identifier.
|
||||
pdf_info.path = base::FilePath(kPdfPluginPath);
|
||||
content::WebPluginMimeType pdf_mime_type(kPdfPluginMimeType, "pdf",
|
||||
"Portable Document Format");
|
||||
pdf_info.mime_types.push_back(pdf_mime_type);
|
||||
@@ -166,6 +168,21 @@ void ComputeBuiltInPlugins(std::vector<content::PepperPluginInfo>* plugins) {
|
||||
chrome_pdf::PPP_ShutdownModule;
|
||||
pdf_info.permissions = ppapi::PERMISSION_PDF | ppapi::PERMISSION_DEV;
|
||||
plugins->push_back(pdf_info);
|
||||
|
||||
// NB. in Chrome, this plugin isn't registered until the PDF extension is
|
||||
// loaded. However, in Electron, we load the PDF extension unconditionally
|
||||
// when it is enabled in the build, so we're OK to load the plugin eagerly
|
||||
// here.
|
||||
content::WebPluginInfo info;
|
||||
info.type = content::WebPluginInfo::PLUGIN_TYPE_BROWSER_PLUGIN;
|
||||
info.name = base::UTF8ToUTF16("Chromium PDF Viewer");
|
||||
// This isn't a real file path; it's just used as a unique identifier.
|
||||
info.path = base::FilePath::FromUTF8Unsafe(extension_misc::kPdfExtensionId);
|
||||
info.background_color = content::WebPluginInfo::kDefaultBackgroundColor;
|
||||
info.mime_types.emplace_back("application/pdf", "pdf",
|
||||
"Portable Document Format");
|
||||
content::PluginService::GetInstance()->RefreshPlugins();
|
||||
content::PluginService::GetInstance()->RegisterInternalPlugin(info, true);
|
||||
#endif // BUILDFLAG(ENABLE_PDF_VIEWER)
|
||||
}
|
||||
#endif // BUILDFLAG(ENABLE_PLUGINS)
|
||||
|
||||
@@ -118,15 +118,6 @@ void LoadResourceBundle(const std::string& locale) {
|
||||
bundle.ReloadLocaleResources(locale);
|
||||
bundle.AddDataPackFromPath(pak_dir.Append(FILE_PATH_LITERAL("resources.pak")),
|
||||
ui::SCALE_FACTOR_NONE);
|
||||
#if BUILDFLAG(ENABLE_PDF_VIEWER)
|
||||
NOTIMPLEMENTED()
|
||||
<< "Hi, whoever's fixing PDF support! Thanks! The pdf "
|
||||
"viewer resources haven't been ported over to the GN build yet, so "
|
||||
"you'll probably need to change this bit of code.";
|
||||
bundle.AddDataPackFromPath(
|
||||
pak_dir.Append(FILE_PATH_LITERAL("pdf_viewer_resources.pak")),
|
||||
ui::GetSupportedScaleFactors()[0]);
|
||||
#endif // BUILDFLAG(ENABLE_PDF_VIEWER)
|
||||
}
|
||||
|
||||
ElectronMainDelegate::ElectronMainDelegate() = default;
|
||||
@@ -224,6 +215,21 @@ bool ElectronMainDelegate::BasicStartupComplete(int* exit_code) {
|
||||
<< " is not supported. See https://crbug.com/638180.";
|
||||
#endif
|
||||
|
||||
#if defined(MAS_BUILD)
|
||||
// In MAS build we are using --disable-remote-core-animation.
|
||||
//
|
||||
// According to ccameron:
|
||||
// If you're running with --disable-remote-core-animation, you may want to
|
||||
// also run with --disable-gpu-memory-buffer-compositor-resources as well.
|
||||
// That flag makes it so we use regular GL textures instead of IOSurfaces
|
||||
// for compositor resources. IOSurfaces are very heavyweight to
|
||||
// create/destroy, but they can be displayed directly by CoreAnimation (and
|
||||
// --disable-remote-core-animation makes it so we don't use this property,
|
||||
// so they're just heavyweight with no upside).
|
||||
command_line->AppendSwitch(
|
||||
::switches::kDisableGpuMemoryBufferCompositorResources);
|
||||
#endif
|
||||
|
||||
content_client_ = std::make_unique<ElectronContentClient>();
|
||||
SetContentClient(content_client_.get());
|
||||
|
||||
|
||||
@@ -82,7 +82,7 @@ void ElectronMainDelegate::SetUpBundleOverrides() {
|
||||
|
||||
void RegisterAtomCrApp() {
|
||||
// Force the NSApplication subclass to be used.
|
||||
[ElectronApplication sharedApplication];
|
||||
[AtomApplication sharedApplication];
|
||||
}
|
||||
|
||||
} // namespace electron
|
||||
|
||||
@@ -880,6 +880,9 @@ void App::SetPath(gin_helper::ErrorThrower thrower,
|
||||
if (key == DIR_USER_DATA) {
|
||||
succeed |= base::PathService::OverrideAndCreateIfNeeded(
|
||||
chrome::DIR_USER_DATA, path, true, false);
|
||||
succeed |= base::PathService::Override(
|
||||
chrome::DIR_APP_DICTIONARIES,
|
||||
path.Append(base::FilePath::FromUTF8Unsafe("Dictionaries")));
|
||||
}
|
||||
}
|
||||
if (!succeed)
|
||||
|
||||
154
shell/browser/api/electron_api_service_worker_context.cc
Normal file
154
shell/browser/api/electron_api_service_worker_context.cc
Normal file
@@ -0,0 +1,154 @@
|
||||
// Copyright (c) 2019 Slack Technologies, Inc.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "shell/browser/api/electron_api_service_worker_context.h"
|
||||
|
||||
#include <string>
|
||||
#include <utility>
|
||||
|
||||
#include "chrome/browser/browser_process.h"
|
||||
#include "content/public/browser/console_message.h"
|
||||
#include "content/public/browser/storage_partition.h"
|
||||
#include "gin/data_object_builder.h"
|
||||
#include "gin/handle.h"
|
||||
#include "shell/browser/electron_browser_context.h"
|
||||
#include "shell/common/gin_converters/value_converter.h"
|
||||
#include "shell/common/gin_helper/dictionary.h"
|
||||
#include "shell/common/gin_helper/object_template_builder.h"
|
||||
#include "shell/common/node_includes.h"
|
||||
|
||||
namespace electron {
|
||||
|
||||
namespace api {
|
||||
|
||||
namespace {
|
||||
|
||||
std::string MessageSourceToString(
|
||||
const blink::mojom::ConsoleMessageSource source) {
|
||||
if (source == blink::mojom::ConsoleMessageSource::kXml)
|
||||
return "xml";
|
||||
if (source == blink::mojom::ConsoleMessageSource::kJavaScript)
|
||||
return "javascript";
|
||||
if (source == blink::mojom::ConsoleMessageSource::kNetwork)
|
||||
return "network";
|
||||
if (source == blink::mojom::ConsoleMessageSource::kConsoleApi)
|
||||
return "console-api";
|
||||
if (source == blink::mojom::ConsoleMessageSource::kStorage)
|
||||
return "storage";
|
||||
if (source == blink::mojom::ConsoleMessageSource::kAppCache)
|
||||
return "app-cache";
|
||||
if (source == blink::mojom::ConsoleMessageSource::kRendering)
|
||||
return "rendering";
|
||||
if (source == blink::mojom::ConsoleMessageSource::kSecurity)
|
||||
return "security";
|
||||
if (source == blink::mojom::ConsoleMessageSource::kDeprecation)
|
||||
return "deprecation";
|
||||
if (source == blink::mojom::ConsoleMessageSource::kWorker)
|
||||
return "worker";
|
||||
if (source == blink::mojom::ConsoleMessageSource::kViolation)
|
||||
return "violation";
|
||||
if (source == blink::mojom::ConsoleMessageSource::kIntervention)
|
||||
return "intervention";
|
||||
if (source == blink::mojom::ConsoleMessageSource::kRecommendation)
|
||||
return "recommendation";
|
||||
return "other";
|
||||
}
|
||||
|
||||
v8::Local<v8::Value> ServiceWorkerRunningInfoToDict(
|
||||
v8::Isolate* isolate,
|
||||
const content::ServiceWorkerRunningInfo& info) {
|
||||
return gin::DataObjectBuilder(isolate)
|
||||
.Set("scriptUrl", info.script_url.spec())
|
||||
.Set("scope", info.scope.spec())
|
||||
.Set("renderProcessId", info.render_process_id)
|
||||
.Build();
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
ServiceWorkerContext::ServiceWorkerContext(
|
||||
v8::Isolate* isolate,
|
||||
ElectronBrowserContext* browser_context)
|
||||
: browser_context_(browser_context), weak_ptr_factory_(this) {
|
||||
Init(isolate);
|
||||
service_worker_context_ =
|
||||
content::BrowserContext::GetDefaultStoragePartition(browser_context_)
|
||||
->GetServiceWorkerContext();
|
||||
service_worker_context_->AddObserver(this);
|
||||
}
|
||||
|
||||
ServiceWorkerContext::~ServiceWorkerContext() {
|
||||
service_worker_context_->RemoveObserver(this);
|
||||
}
|
||||
|
||||
void ServiceWorkerContext::OnReportConsoleMessage(
|
||||
int64_t version_id,
|
||||
const content::ConsoleMessage& message) {
|
||||
Emit("console-message",
|
||||
gin::DataObjectBuilder(v8::Isolate::GetCurrent())
|
||||
.Set("versionId", version_id)
|
||||
.Set("source", MessageSourceToString(message.source))
|
||||
.Set("level", static_cast<int32_t>(message.message_level))
|
||||
.Set("message", message.message)
|
||||
.Set("lineNumber", message.line_number)
|
||||
.Set("sourceUrl", message.source_url.spec())
|
||||
.Build());
|
||||
}
|
||||
|
||||
void ServiceWorkerContext::OnDestruct(content::ServiceWorkerContext* context) {
|
||||
if (context == service_worker_context_) {
|
||||
delete this;
|
||||
}
|
||||
}
|
||||
|
||||
v8::Local<v8::Value> ServiceWorkerContext::GetAllRunningWorkerInfo(
|
||||
v8::Isolate* isolate) {
|
||||
gin::DataObjectBuilder builder(isolate);
|
||||
const base::flat_map<int64_t, content::ServiceWorkerRunningInfo>& info_map =
|
||||
service_worker_context_->GetRunningServiceWorkerInfos();
|
||||
for (auto iter = info_map.begin(); iter != info_map.end(); ++iter) {
|
||||
builder.Set(
|
||||
std::to_string(iter->first),
|
||||
ServiceWorkerRunningInfoToDict(isolate, std::move(iter->second)));
|
||||
}
|
||||
return builder.Build();
|
||||
}
|
||||
|
||||
v8::Local<v8::Value> ServiceWorkerContext::GetWorkerInfoFromID(
|
||||
gin_helper::ErrorThrower thrower,
|
||||
int64_t version_id) {
|
||||
const base::flat_map<int64_t, content::ServiceWorkerRunningInfo>& info_map =
|
||||
service_worker_context_->GetRunningServiceWorkerInfos();
|
||||
auto iter = info_map.find(version_id);
|
||||
if (iter == info_map.end()) {
|
||||
thrower.ThrowError("Could not find service worker with that version_id");
|
||||
return v8::Local<v8::Value>();
|
||||
}
|
||||
return ServiceWorkerRunningInfoToDict(thrower.isolate(),
|
||||
std::move(iter->second));
|
||||
}
|
||||
|
||||
// static
|
||||
gin::Handle<ServiceWorkerContext> ServiceWorkerContext::Create(
|
||||
v8::Isolate* isolate,
|
||||
ElectronBrowserContext* browser_context) {
|
||||
return gin::CreateHandle(isolate,
|
||||
new ServiceWorkerContext(isolate, browser_context));
|
||||
}
|
||||
|
||||
// static
|
||||
void ServiceWorkerContext::BuildPrototype(
|
||||
v8::Isolate* isolate,
|
||||
v8::Local<v8::FunctionTemplate> prototype) {
|
||||
prototype->SetClassName(gin::StringToV8(isolate, "ServiceWorkerContext"));
|
||||
gin_helper::ObjectTemplateBuilder(isolate, prototype->PrototypeTemplate())
|
||||
.SetMethod("getAllRunning",
|
||||
&ServiceWorkerContext::GetAllRunningWorkerInfo)
|
||||
.SetMethod("getFromVersionID",
|
||||
&ServiceWorkerContext::GetWorkerInfoFromID);
|
||||
}
|
||||
|
||||
} // namespace api
|
||||
|
||||
} // namespace electron
|
||||
58
shell/browser/api/electron_api_service_worker_context.h
Normal file
58
shell/browser/api/electron_api_service_worker_context.h
Normal file
@@ -0,0 +1,58 @@
|
||||
// Copyright (c) 2019 Slack Technologies, Inc.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef SHELL_BROWSER_API_ELECTRON_API_SERVICE_WORKER_CONTEXT_H_
|
||||
#define SHELL_BROWSER_API_ELECTRON_API_SERVICE_WORKER_CONTEXT_H_
|
||||
|
||||
#include "content/public/browser/service_worker_context.h"
|
||||
#include "content/public/browser/service_worker_context_observer.h"
|
||||
#include "gin/handle.h"
|
||||
#include "shell/common/gin_helper/trackable_object.h"
|
||||
|
||||
namespace electron {
|
||||
|
||||
class ElectronBrowserContext;
|
||||
|
||||
namespace api {
|
||||
|
||||
class ServiceWorkerContext
|
||||
: public gin_helper::TrackableObject<ServiceWorkerContext>,
|
||||
public content::ServiceWorkerContextObserver {
|
||||
public:
|
||||
static gin::Handle<ServiceWorkerContext> Create(
|
||||
v8::Isolate* isolate,
|
||||
ElectronBrowserContext* browser_context);
|
||||
|
||||
static void BuildPrototype(v8::Isolate* isolate,
|
||||
v8::Local<v8::FunctionTemplate> prototype);
|
||||
|
||||
v8::Local<v8::Value> GetAllRunningWorkerInfo(v8::Isolate* isolate);
|
||||
v8::Local<v8::Value> GetWorkerInfoFromID(gin_helper::ErrorThrower thrower,
|
||||
int64_t version_id);
|
||||
|
||||
// content::ServiceWorkerContextObserver
|
||||
void OnReportConsoleMessage(int64_t version_id,
|
||||
const content::ConsoleMessage& message) override;
|
||||
void OnDestruct(content::ServiceWorkerContext* context) override;
|
||||
|
||||
protected:
|
||||
explicit ServiceWorkerContext(v8::Isolate* isolate,
|
||||
ElectronBrowserContext* browser_context);
|
||||
~ServiceWorkerContext() override;
|
||||
|
||||
private:
|
||||
ElectronBrowserContext* browser_context_;
|
||||
|
||||
content::ServiceWorkerContext* service_worker_context_;
|
||||
|
||||
base::WeakPtrFactory<ServiceWorkerContext> weak_ptr_factory_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(ServiceWorkerContext);
|
||||
};
|
||||
|
||||
} // namespace api
|
||||
|
||||
} // namespace electron
|
||||
|
||||
#endif // SHELL_BROWSER_API_ELECTRON_API_SERVICE_WORKER_CONTEXT_H_
|
||||
@@ -7,6 +7,7 @@
|
||||
#include <algorithm>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <set>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
@@ -45,6 +46,7 @@
|
||||
#include "shell/browser/api/electron_api_download_item.h"
|
||||
#include "shell/browser/api/electron_api_net_log.h"
|
||||
#include "shell/browser/api/electron_api_protocol.h"
|
||||
#include "shell/browser/api/electron_api_service_worker_context.h"
|
||||
#include "shell/browser/api/electron_api_web_request.h"
|
||||
#include "shell/browser/browser.h"
|
||||
#include "shell/browser/electron_browser_context.h"
|
||||
@@ -226,6 +228,42 @@ void DestroyGlobalHandle(v8::Isolate* isolate,
|
||||
}
|
||||
}
|
||||
|
||||
class DictionaryObserver final : public SpellcheckCustomDictionary::Observer {
|
||||
private:
|
||||
std::unique_ptr<gin_helper::Promise<std::set<std::string>>> promise_;
|
||||
base::WeakPtr<SpellcheckService> spellcheck_;
|
||||
|
||||
public:
|
||||
DictionaryObserver(gin_helper::Promise<std::set<std::string>> promise,
|
||||
base::WeakPtr<SpellcheckService> spellcheck)
|
||||
: spellcheck_(spellcheck) {
|
||||
promise_ = std::make_unique<gin_helper::Promise<std::set<std::string>>>(
|
||||
std::move(promise));
|
||||
if (spellcheck_)
|
||||
spellcheck_->GetCustomDictionary()->AddObserver(this);
|
||||
}
|
||||
|
||||
~DictionaryObserver() {
|
||||
if (spellcheck_)
|
||||
spellcheck_->GetCustomDictionary()->RemoveObserver(this);
|
||||
}
|
||||
|
||||
void OnCustomDictionaryLoaded() override {
|
||||
if (spellcheck_) {
|
||||
promise_->Resolve(spellcheck_->GetCustomDictionary()->GetWords());
|
||||
} else {
|
||||
promise_->RejectWithErrorMessage(
|
||||
"Spellcheck in unexpected state: failed to load custom dictionary.");
|
||||
}
|
||||
delete this;
|
||||
}
|
||||
|
||||
void OnCustomDictionaryChanged(
|
||||
const SpellcheckCustomDictionary::Change& dictionary_change) override {
|
||||
// noop
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
Session::Session(v8::Isolate* isolate, ElectronBrowserContext* browser_context)
|
||||
@@ -660,7 +698,8 @@ v8::Local<v8::Value> Session::GetAllExtensions() {
|
||||
auto installed_extensions = registry->GenerateInstalledExtensionsSet();
|
||||
std::vector<const extensions::Extension*> extensions_vector;
|
||||
for (const auto& extension : *installed_extensions) {
|
||||
extensions_vector.emplace_back(extension.get());
|
||||
if (extension->location() != extensions::Manifest::COMPONENT)
|
||||
extensions_vector.emplace_back(extension.get());
|
||||
}
|
||||
return gin::ConvertToV8(isolate(), extensions_vector);
|
||||
}
|
||||
@@ -678,6 +717,15 @@ v8::Local<v8::Value> Session::Protocol(v8::Isolate* isolate) {
|
||||
return v8::Local<v8::Value>::New(isolate, protocol_);
|
||||
}
|
||||
|
||||
v8::Local<v8::Value> Session::ServiceWorkerContext(v8::Isolate* isolate) {
|
||||
if (service_worker_context_.IsEmpty()) {
|
||||
v8::Local<v8::Value> handle;
|
||||
handle = ServiceWorkerContext::Create(isolate, browser_context()).ToV8();
|
||||
service_worker_context_.Reset(isolate, handle);
|
||||
}
|
||||
return v8::Local<v8::Value>::New(isolate, service_worker_context_);
|
||||
}
|
||||
|
||||
v8::Local<v8::Value> Session::WebRequest(v8::Isolate* isolate) {
|
||||
if (web_request_.IsEmpty()) {
|
||||
auto handle = WebRequest::Create(isolate, browser_context());
|
||||
@@ -763,7 +811,30 @@ void SetSpellCheckerDictionaryDownloadURL(gin_helper::ErrorThrower thrower,
|
||||
"valid URL");
|
||||
return;
|
||||
}
|
||||
SpellcheckHunspellDictionary::SetDownloadURLForTesting(url);
|
||||
SpellcheckHunspellDictionary::SetBaseDownloadURL(url);
|
||||
}
|
||||
|
||||
v8::Local<v8::Promise> Session::ListWordsInSpellCheckerDictionary() {
|
||||
gin_helper::Promise<std::set<std::string>> promise(isolate());
|
||||
v8::Local<v8::Promise> handle = promise.GetHandle();
|
||||
|
||||
SpellcheckService* spellcheck =
|
||||
SpellcheckServiceFactory::GetForContext(browser_context_.get());
|
||||
|
||||
if (!spellcheck)
|
||||
promise.RejectWithErrorMessage(
|
||||
"Spellcheck in unexpected state: failed to load custom dictionary.");
|
||||
|
||||
if (spellcheck->GetCustomDictionary()->IsLoaded()) {
|
||||
promise.Resolve(spellcheck->GetCustomDictionary()->GetWords());
|
||||
} else {
|
||||
new DictionaryObserver(std::move(promise), spellcheck->GetWeakPtr());
|
||||
// Dictionary loads by default asynchronously,
|
||||
// call the load function anyways just to be sure.
|
||||
spellcheck->GetCustomDictionary()->Load();
|
||||
}
|
||||
|
||||
return handle;
|
||||
}
|
||||
|
||||
bool Session::AddWordToSpellCheckerDictionary(const std::string& word) {
|
||||
@@ -865,6 +936,8 @@ void Session::BuildPrototype(v8::Isolate* isolate,
|
||||
&spellcheck::SpellCheckLanguages)
|
||||
.SetMethod("setSpellCheckerDictionaryDownloadURL",
|
||||
&SetSpellCheckerDictionaryDownloadURL)
|
||||
.SetMethod("listWordsInSpellCheckerDictionary",
|
||||
&Session::ListWordsInSpellCheckerDictionary)
|
||||
.SetMethod("addWordToSpellCheckerDictionary",
|
||||
&Session::AddWordToSpellCheckerDictionary)
|
||||
#endif
|
||||
@@ -872,6 +945,7 @@ void Session::BuildPrototype(v8::Isolate* isolate,
|
||||
.SetProperty("cookies", &Session::Cookies)
|
||||
.SetProperty("netLog", &Session::NetLog)
|
||||
.SetProperty("protocol", &Session::Protocol)
|
||||
.SetProperty("serviceWorkers", &Session::ServiceWorkerContext)
|
||||
.SetProperty("webRequest", &Session::WebRequest);
|
||||
}
|
||||
|
||||
@@ -884,6 +958,7 @@ namespace {
|
||||
using electron::api::Cookies;
|
||||
using electron::api::NetLog;
|
||||
using electron::api::Protocol;
|
||||
using electron::api::ServiceWorkerContext;
|
||||
using electron::api::Session;
|
||||
|
||||
v8::Local<v8::Value> FromPartition(const std::string& partition,
|
||||
@@ -916,6 +991,9 @@ void Initialize(v8::Local<v8::Object> exports,
|
||||
dict.Set(
|
||||
"Protocol",
|
||||
Protocol::GetConstructor(isolate)->GetFunction(context).ToLocalChecked());
|
||||
dict.Set("ServiceWorkerContext", ServiceWorkerContext::GetConstructor(isolate)
|
||||
->GetFunction(context)
|
||||
.ToLocalChecked());
|
||||
dict.SetMethod("fromPartition", &FromPartition);
|
||||
}
|
||||
|
||||
|
||||
@@ -87,6 +87,7 @@ class Session : public gin_helper::TrackableObject<Session>,
|
||||
std::vector<base::FilePath::StringType> GetPreloads() const;
|
||||
v8::Local<v8::Value> Cookies(v8::Isolate* isolate);
|
||||
v8::Local<v8::Value> Protocol(v8::Isolate* isolate);
|
||||
v8::Local<v8::Value> ServiceWorkerContext(v8::Isolate* isolate);
|
||||
v8::Local<v8::Value> WebRequest(v8::Isolate* isolate);
|
||||
v8::Local<v8::Value> NetLog(v8::Isolate* isolate);
|
||||
void Preconnect(const gin_helper::Dictionary& options,
|
||||
@@ -95,6 +96,7 @@ class Session : public gin_helper::TrackableObject<Session>,
|
||||
base::Value GetSpellCheckerLanguages();
|
||||
void SetSpellCheckerLanguages(gin_helper::ErrorThrower thrower,
|
||||
const std::vector<std::string>& languages);
|
||||
v8::Local<v8::Promise> ListWordsInSpellCheckerDictionary();
|
||||
bool AddWordToSpellCheckerDictionary(const std::string& word);
|
||||
#endif
|
||||
|
||||
@@ -118,6 +120,7 @@ class Session : public gin_helper::TrackableObject<Session>,
|
||||
v8::Global<v8::Value> cookies_;
|
||||
v8::Global<v8::Value> protocol_;
|
||||
v8::Global<v8::Value> net_log_;
|
||||
v8::Global<v8::Value> service_worker_context_;
|
||||
|
||||
// Cached object.
|
||||
v8::Global<v8::Value> web_request_;
|
||||
|
||||
@@ -1803,18 +1803,21 @@ void WebContents::Print(gin_helper::Arguments* args) {
|
||||
settings.SetIntKey(printing::kSettingMarginsType, margin_type);
|
||||
|
||||
if (margin_type == printing::CUSTOM_MARGINS) {
|
||||
base::Value custom_margins(base::Value::Type::DICTIONARY);
|
||||
int top = 0;
|
||||
margins.Get("top", &top);
|
||||
settings.SetIntKey(printing::kSettingMarginTop, top);
|
||||
custom_margins.SetIntKey(printing::kSettingMarginTop, top);
|
||||
int bottom = 0;
|
||||
margins.Get("bottom", &bottom);
|
||||
settings.SetIntKey(printing::kSettingMarginBottom, bottom);
|
||||
custom_margins.SetIntKey(printing::kSettingMarginBottom, bottom);
|
||||
int left = 0;
|
||||
margins.Get("left", &left);
|
||||
settings.SetIntKey(printing::kSettingMarginLeft, left);
|
||||
custom_margins.SetIntKey(printing::kSettingMarginLeft, left);
|
||||
int right = 0;
|
||||
margins.Get("right", &right);
|
||||
settings.SetIntKey(printing::kSettingMarginRight, right);
|
||||
custom_margins.SetIntKey(printing::kSettingMarginRight, right);
|
||||
settings.SetPath(printing::kSettingMarginsCustom,
|
||||
std::move(custom_margins));
|
||||
}
|
||||
} else {
|
||||
settings.SetIntKey(printing::kSettingMarginsType,
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
#include "gin/arguments.h"
|
||||
#include "gin/handle.h"
|
||||
#include "gin/wrappable.h"
|
||||
#include "shell/browser/net/proxying_url_loader_factory.h"
|
||||
#include "shell/browser/net/web_request_api_interface.h"
|
||||
|
||||
namespace content {
|
||||
class BrowserContext;
|
||||
@@ -49,10 +49,6 @@ class WebRequest : public gin::Wrappable<WebRequest>, public WebRequestAPI {
|
||||
v8::Isolate* isolate) override;
|
||||
const char* GetTypeName() override;
|
||||
|
||||
private:
|
||||
WebRequest(v8::Isolate* isolate, content::BrowserContext* browser_context);
|
||||
~WebRequest() override;
|
||||
|
||||
// WebRequestAPI:
|
||||
bool HasListener() const override;
|
||||
int OnBeforeRequest(extensions::WebRequestInfo* info,
|
||||
@@ -86,6 +82,10 @@ class WebRequest : public gin::Wrappable<WebRequest>, public WebRequestAPI {
|
||||
int net_error) override;
|
||||
void OnRequestWillBeDestroyed(extensions::WebRequestInfo* info) override;
|
||||
|
||||
private:
|
||||
WebRequest(v8::Isolate* isolate, content::BrowserContext* browser_context);
|
||||
~WebRequest() override;
|
||||
|
||||
enum SimpleEvent {
|
||||
kOnSendHeaders,
|
||||
kOnBeforeRedirect,
|
||||
|
||||
@@ -29,20 +29,19 @@
|
||||
namespace electron {
|
||||
|
||||
void Browser::SetShutdownHandler(base::Callback<bool()> handler) {
|
||||
[[ElectronApplication sharedApplication]
|
||||
setShutdownHandler:std::move(handler)];
|
||||
[[AtomApplication sharedApplication] setShutdownHandler:std::move(handler)];
|
||||
}
|
||||
|
||||
void Browser::Focus() {
|
||||
[[ElectronApplication sharedApplication] activateIgnoringOtherApps:NO];
|
||||
[[AtomApplication sharedApplication] activateIgnoringOtherApps:NO];
|
||||
}
|
||||
|
||||
void Browser::Hide() {
|
||||
[[ElectronApplication sharedApplication] hide:nil];
|
||||
[[AtomApplication sharedApplication] hide:nil];
|
||||
}
|
||||
|
||||
void Browser::Show() {
|
||||
[[ElectronApplication sharedApplication] unhide:nil];
|
||||
[[AtomApplication sharedApplication] unhide:nil];
|
||||
}
|
||||
|
||||
void Browser::AddRecentDocument(const base::FilePath& path) {
|
||||
@@ -163,7 +162,7 @@ void Browser::SetUserActivity(const std::string& type,
|
||||
std::string url_string;
|
||||
args->GetNext(&url_string);
|
||||
|
||||
[[ElectronApplication sharedApplication]
|
||||
[[AtomApplication sharedApplication]
|
||||
setCurrentActivity:base::SysUTF8ToNSString(type)
|
||||
withUserInfo:DictionaryValueToNSDictionary(user_info)
|
||||
withWebpageURL:net::NSURLWithGURL(GURL(url_string))];
|
||||
@@ -171,21 +170,21 @@ void Browser::SetUserActivity(const std::string& type,
|
||||
|
||||
std::string Browser::GetCurrentActivityType() {
|
||||
NSUserActivity* userActivity =
|
||||
[[ElectronApplication sharedApplication] getCurrentActivity];
|
||||
[[AtomApplication sharedApplication] getCurrentActivity];
|
||||
return base::SysNSStringToUTF8(userActivity.activityType);
|
||||
}
|
||||
|
||||
void Browser::InvalidateCurrentActivity() {
|
||||
[[ElectronApplication sharedApplication] invalidateCurrentActivity];
|
||||
[[AtomApplication sharedApplication] invalidateCurrentActivity];
|
||||
}
|
||||
|
||||
void Browser::ResignCurrentActivity() {
|
||||
[[ElectronApplication sharedApplication] resignCurrentActivity];
|
||||
[[AtomApplication sharedApplication] resignCurrentActivity];
|
||||
}
|
||||
|
||||
void Browser::UpdateCurrentActivity(const std::string& type,
|
||||
base::DictionaryValue user_info) {
|
||||
[[ElectronApplication sharedApplication]
|
||||
[[AtomApplication sharedApplication]
|
||||
updateCurrentActivity:base::SysUTF8ToNSString(type)
|
||||
withUserInfo:DictionaryValueToNSDictionary(user_info)];
|
||||
}
|
||||
@@ -291,17 +290,16 @@ std::string Browser::GetExecutableFileProductName() const {
|
||||
}
|
||||
|
||||
int Browser::DockBounce(BounceType type) {
|
||||
return [[ElectronApplication sharedApplication]
|
||||
return [[AtomApplication sharedApplication]
|
||||
requestUserAttention:static_cast<NSRequestUserAttentionType>(type)];
|
||||
}
|
||||
|
||||
void Browser::DockCancelBounce(int request_id) {
|
||||
[[ElectronApplication sharedApplication]
|
||||
cancelUserAttentionRequest:request_id];
|
||||
[[AtomApplication sharedApplication] cancelUserAttentionRequest:request_id];
|
||||
}
|
||||
|
||||
void Browser::DockSetBadgeText(const std::string& label) {
|
||||
NSDockTile* tile = [[ElectronApplication sharedApplication] dockTile];
|
||||
NSDockTile* tile = [[AtomApplication sharedApplication] dockTile];
|
||||
[tile setBadgeLabel:base::SysUTF8ToNSString(label)];
|
||||
}
|
||||
|
||||
@@ -312,7 +310,7 @@ void Browser::DockDownloadFinished(const std::string& filePath) {
|
||||
}
|
||||
|
||||
std::string Browser::DockGetBadgeText() {
|
||||
NSDockTile* tile = [[ElectronApplication sharedApplication] dockTile];
|
||||
NSDockTile* tile = [[AtomApplication sharedApplication] dockTile];
|
||||
return base::SysNSStringToUTF8([tile badgeLabel]);
|
||||
}
|
||||
|
||||
@@ -371,7 +369,7 @@ void Browser::DockSetMenu(ElectronMenuModel* model) {
|
||||
}
|
||||
|
||||
void Browser::DockSetIcon(const gfx::Image& image) {
|
||||
[[ElectronApplication sharedApplication]
|
||||
[[AtomApplication sharedApplication]
|
||||
setApplicationIconImage:image.AsNSImage()];
|
||||
}
|
||||
|
||||
@@ -394,7 +392,7 @@ void Browser::ShowAboutPanel() {
|
||||
options = [NSDictionary dictionaryWithDictionary:mutable_options];
|
||||
}
|
||||
|
||||
[[ElectronApplication sharedApplication]
|
||||
[[AtomApplication sharedApplication]
|
||||
orderFrontStandardAboutPanelWithOptions:options];
|
||||
}
|
||||
|
||||
@@ -411,7 +409,7 @@ void Browser::SetAboutPanelOptions(base::DictionaryValue options) {
|
||||
}
|
||||
|
||||
void Browser::ShowEmojiPanel() {
|
||||
[[ElectronApplication sharedApplication] orderFrontCharacterPalette:nil];
|
||||
[[AtomApplication sharedApplication] orderFrontCharacterPalette:nil];
|
||||
}
|
||||
|
||||
bool Browser::IsEmojiPanelSupported() {
|
||||
|
||||
@@ -292,8 +292,21 @@ content::WebContents* CommonWebContentsDelegate::OpenURLFromTab(
|
||||
load_url_params.should_replace_current_entry =
|
||||
params.should_replace_current_entry;
|
||||
load_url_params.is_renderer_initiated = params.is_renderer_initiated;
|
||||
load_url_params.started_from_context_menu = params.started_from_context_menu;
|
||||
load_url_params.initiator_origin = params.initiator_origin;
|
||||
load_url_params.should_clear_history_list = true;
|
||||
load_url_params.source_site_instance = params.source_site_instance;
|
||||
load_url_params.frame_tree_node_id = params.frame_tree_node_id;
|
||||
load_url_params.redirect_chain = params.redirect_chain;
|
||||
load_url_params.has_user_gesture = params.user_gesture;
|
||||
load_url_params.blob_url_loader_factory = params.blob_url_loader_factory;
|
||||
load_url_params.href_translate = params.href_translate;
|
||||
load_url_params.reload_type = params.reload_type;
|
||||
|
||||
if (params.post_data) {
|
||||
load_url_params.load_type =
|
||||
content::NavigationController::LOAD_TYPE_HTTP_POST;
|
||||
load_url_params.post_data = params.post_data;
|
||||
}
|
||||
|
||||
source->GetController().LoadURLWithParams(load_url_params);
|
||||
return source;
|
||||
|
||||
@@ -49,6 +49,7 @@
|
||||
#include "extensions/common/constants.h"
|
||||
#include "net/base/escape.h"
|
||||
#include "net/ssl/ssl_cert_request_info.h"
|
||||
#include "ppapi/buildflags/buildflags.h"
|
||||
#include "ppapi/host/ppapi_host.h"
|
||||
#include "printing/buildflags/buildflags.h"
|
||||
#include "services/device/public/cpp/geolocation/location_provider.h"
|
||||
@@ -75,6 +76,7 @@
|
||||
#include "shell/browser/net/network_context_service.h"
|
||||
#include "shell/browser/net/network_context_service_factory.h"
|
||||
#include "shell/browser/net/proxying_url_loader_factory.h"
|
||||
#include "shell/browser/net/proxying_websocket.h"
|
||||
#include "shell/browser/net/system_network_context_manager.h"
|
||||
#include "shell/browser/network_hints_handler_impl.h"
|
||||
#include "shell/browser/notifications/notification_presenter.h"
|
||||
@@ -128,13 +130,29 @@
|
||||
#endif // BUILDFLAG(ENABLE_PRINTING)
|
||||
|
||||
#if BUILDFLAG(ENABLE_ELECTRON_EXTENSIONS)
|
||||
#include "chrome/common/webui_url_constants.h"
|
||||
#include "content/public/browser/child_process_security_policy.h"
|
||||
#include "content/public/browser/file_url_loader.h"
|
||||
#include "content/public/browser/web_ui_url_loader_factory.h"
|
||||
#include "extensions/browser/api/mime_handler_private/mime_handler_private.h"
|
||||
#include "extensions/browser/extension_host.h"
|
||||
#include "extensions/browser/extension_message_filter.h"
|
||||
#include "extensions/browser/extension_navigation_throttle.h"
|
||||
#include "extensions/browser/extension_registry.h"
|
||||
#include "extensions/browser/guest_view/extensions_guest_view_message_filter.h"
|
||||
#include "extensions/browser/guest_view/mime_handler_view/mime_handler_view_guest.h"
|
||||
#include "extensions/browser/info_map.h"
|
||||
#include "extensions/browser/process_manager.h"
|
||||
#include "extensions/browser/process_map.h"
|
||||
#include "extensions/common/api/mime_handler.mojom.h"
|
||||
#include "extensions/common/extension.h"
|
||||
#include "shell/browser/extensions/electron_extension_system.h"
|
||||
#include "shell/browser/extensions/electron_extension_web_contents_observer.h"
|
||||
#endif
|
||||
|
||||
#if BUILDFLAG(ENABLE_PLUGINS)
|
||||
#include "chrome/browser/plugins/plugin_response_interceptor_url_loader_throttle.h" // nogncheck
|
||||
#include "shell/browser/plugins/plugin_utils.h"
|
||||
#endif
|
||||
|
||||
#if defined(OS_MACOSX)
|
||||
@@ -186,6 +204,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
|
||||
@@ -385,6 +460,8 @@ void ElectronBrowserClient::RenderProcessWillLaunch(
|
||||
#if BUILDFLAG(ENABLE_ELECTRON_EXTENSIONS)
|
||||
host->AddFilter(
|
||||
new extensions::ExtensionMessageFilter(process_id, browser_context));
|
||||
host->AddFilter(new extensions::ExtensionsGuestViewMessageFilter(
|
||||
process_id, browser_context));
|
||||
#endif
|
||||
|
||||
ProcessPreferences prefs;
|
||||
@@ -727,6 +804,7 @@ void ElectronBrowserClient::GetAdditionalAllowedSchemesForFileSystem(
|
||||
additional_schemes->insert(additional_schemes->end(), schemes_list.begin(),
|
||||
schemes_list.end());
|
||||
additional_schemes->push_back(content::kChromeDevToolsScheme);
|
||||
additional_schemes->push_back(content::kChromeUIScheme);
|
||||
}
|
||||
|
||||
void ElectronBrowserClient::GetAdditionalWebUISchemes(
|
||||
@@ -760,6 +838,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
|
||||
@@ -1052,28 +1164,160 @@ void ElectronBrowserClient::RegisterNonNetworkNavigationURLLoaderFactories(
|
||||
protocol->RegisterURLLoaderFactories(factories);
|
||||
}
|
||||
|
||||
#if BUILDFLAG(ENABLE_ELECTRON_EXTENSIONS)
|
||||
namespace {
|
||||
|
||||
// The FileURLLoaderFactory provided to the extension background pages.
|
||||
// Checks with the ChildProcessSecurityPolicy to validate the file access.
|
||||
class FileURLLoaderFactory : public network::mojom::URLLoaderFactory {
|
||||
public:
|
||||
explicit FileURLLoaderFactory(int child_id) : child_id_(child_id) {}
|
||||
|
||||
private:
|
||||
// network::mojom::URLLoaderFactory:
|
||||
void CreateLoaderAndStart(
|
||||
mojo::PendingReceiver<network::mojom::URLLoader> loader,
|
||||
int32_t routing_id,
|
||||
int32_t request_id,
|
||||
uint32_t options,
|
||||
const network::ResourceRequest& request,
|
||||
mojo::PendingRemote<network::mojom::URLLoaderClient> client,
|
||||
const net::MutableNetworkTrafficAnnotationTag& traffic_annotation)
|
||||
override {
|
||||
if (!content::ChildProcessSecurityPolicy::GetInstance()->CanRequestURL(
|
||||
child_id_, request.url)) {
|
||||
mojo::Remote<network::mojom::URLLoaderClient>(std::move(client))
|
||||
->OnComplete(
|
||||
network::URLLoaderCompletionStatus(net::ERR_ACCESS_DENIED));
|
||||
return;
|
||||
}
|
||||
content::CreateFileURLLoaderBypassingSecurityChecks(
|
||||
request, std::move(loader), std::move(client),
|
||||
/*observer=*/nullptr,
|
||||
/* allow_directory_listing */ true);
|
||||
}
|
||||
|
||||
void Clone(
|
||||
mojo::PendingReceiver<network::mojom::URLLoaderFactory> loader) override {
|
||||
receivers_.Add(this, std::move(loader));
|
||||
}
|
||||
|
||||
int child_id_;
|
||||
mojo::ReceiverSet<network::mojom::URLLoaderFactory> receivers_;
|
||||
DISALLOW_COPY_AND_ASSIGN(FileURLLoaderFactory);
|
||||
};
|
||||
|
||||
} // namespace
|
||||
#endif // BUILDFLAG(ENABLE_ELECTRON_EXTENSIONS)
|
||||
|
||||
void ElectronBrowserClient::RegisterNonNetworkSubresourceURLLoaderFactories(
|
||||
int render_process_id,
|
||||
int render_frame_id,
|
||||
NonNetworkURLLoaderFactoryMap* factories) {
|
||||
#if BUILDFLAG(ENABLE_ELECTRON_EXTENSIONS)
|
||||
auto factory = extensions::CreateExtensionURLLoaderFactory(render_process_id,
|
||||
render_frame_id);
|
||||
if (factory)
|
||||
factories->emplace(extensions::kExtensionScheme, std::move(factory));
|
||||
#endif
|
||||
|
||||
// Chromium may call this even when NetworkService is not enabled.
|
||||
content::RenderFrameHost* frame_host =
|
||||
content::RenderFrameHost::FromID(render_process_id, render_frame_id);
|
||||
content::WebContents* web_contents =
|
||||
content::WebContents::FromRenderFrameHost(frame_host);
|
||||
|
||||
if (web_contents) {
|
||||
api::Protocol* protocol = api::Protocol::FromWrappedClass(
|
||||
v8::Isolate::GetCurrent(), web_contents->GetBrowserContext());
|
||||
if (protocol)
|
||||
protocol->RegisterURLLoaderFactories(factories);
|
||||
}
|
||||
#if BUILDFLAG(ENABLE_ELECTRON_EXTENSIONS)
|
||||
auto factory = extensions::CreateExtensionURLLoaderFactory(render_process_id,
|
||||
render_frame_id);
|
||||
if (factory)
|
||||
factories->emplace(extensions::kExtensionScheme, std::move(factory));
|
||||
|
||||
if (!web_contents)
|
||||
return;
|
||||
|
||||
extensions::ElectronExtensionWebContentsObserver* web_observer =
|
||||
extensions::ElectronExtensionWebContentsObserver::FromWebContents(
|
||||
web_contents);
|
||||
|
||||
// There is nothing to do if no ElectronExtensionWebContentsObserver is
|
||||
// attached to the |web_contents|.
|
||||
if (!web_observer)
|
||||
return;
|
||||
|
||||
const extensions::Extension* extension =
|
||||
web_observer->GetExtensionFromFrame(frame_host, false);
|
||||
if (!extension)
|
||||
return;
|
||||
|
||||
// Support for chrome:// scheme if appropriate.
|
||||
if (extension->is_extension() &&
|
||||
extensions::Manifest::IsComponentLocation(extension->location())) {
|
||||
// Components of chrome that are implemented as extensions or platform apps
|
||||
// are allowed to use chrome://resources/ and chrome://theme/ URLs.
|
||||
factories->emplace(
|
||||
content::kChromeUIScheme,
|
||||
content::CreateWebUIURLLoader(frame_host, content::kChromeUIScheme,
|
||||
{content::kChromeUIResourcesHost}));
|
||||
}
|
||||
|
||||
// Extension with a background page get file access that gets approval from
|
||||
// ChildProcessSecurityPolicy.
|
||||
extensions::ExtensionHost* host =
|
||||
extensions::ProcessManager::Get(web_contents->GetBrowserContext())
|
||||
->GetBackgroundHostForExtension(extension->id());
|
||||
if (host) {
|
||||
factories->emplace(url::kFileScheme, std::make_unique<FileURLLoaderFactory>(
|
||||
render_process_id));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
bool ElectronBrowserClient::ShouldTreatURLSchemeAsFirstPartyWhenTopLevel(
|
||||
base::StringPiece scheme,
|
||||
bool is_embedded_origin_secure) {
|
||||
if (is_embedded_origin_secure && scheme == content::kChromeUIScheme)
|
||||
return true;
|
||||
#if BUILDFLAG(ENABLE_ELECTRON_EXTENSIONS)
|
||||
return scheme == extensions::kExtensionScheme;
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
bool ElectronBrowserClient::WillInterceptWebSocket(
|
||||
content::RenderFrameHost* frame) {
|
||||
if (!frame)
|
||||
return false;
|
||||
|
||||
v8::Isolate* isolate = v8::Isolate::GetCurrent();
|
||||
auto* browser_context = frame->GetProcess()->GetBrowserContext();
|
||||
auto web_request = api::WebRequest::FromOrCreate(isolate, browser_context);
|
||||
|
||||
// NOTE: Some unit test environments do not initialize
|
||||
// BrowserContextKeyedAPI factories for e.g. WebRequest.
|
||||
if (!web_request.get())
|
||||
return false;
|
||||
|
||||
return web_request->HasListener();
|
||||
}
|
||||
|
||||
void ElectronBrowserClient::CreateWebSocket(
|
||||
content::RenderFrameHost* frame,
|
||||
WebSocketFactory factory,
|
||||
const GURL& url,
|
||||
const net::SiteForCookies& site_for_cookies,
|
||||
const base::Optional<std::string>& user_agent,
|
||||
mojo::PendingRemote<network::mojom::WebSocketHandshakeClient>
|
||||
handshake_client) {
|
||||
v8::Isolate* isolate = v8::Isolate::GetCurrent();
|
||||
auto* browser_context = frame->GetProcess()->GetBrowserContext();
|
||||
auto web_request = api::WebRequest::FromOrCreate(isolate, browser_context);
|
||||
DCHECK(web_request.get());
|
||||
ProxyingWebSocket::StartProxying(
|
||||
web_request.get(), std::move(factory), url,
|
||||
site_for_cookies.RepresentativeUrl(), user_agent,
|
||||
std::move(handshake_client), true, frame->GetProcess()->GetID(),
|
||||
frame->GetRoutingID(), frame->GetLastCommittedOrigin(), browser_context,
|
||||
&next_id_);
|
||||
}
|
||||
|
||||
bool ElectronBrowserClient::WillCreateURLLoaderFactory(
|
||||
@@ -1118,7 +1362,7 @@ bool ElectronBrowserClient::WillCreateURLLoaderFactory(
|
||||
|
||||
new ProxyingURLLoaderFactory(
|
||||
web_request.get(), protocol->intercept_handlers(), browser_context,
|
||||
render_process_id, std::move(navigation_ui_data),
|
||||
render_process_id, &next_id_, std::move(navigation_ui_data),
|
||||
std::move(navigation_id), std::move(proxied_receiver),
|
||||
std::move(target_factory_remote), std::move(header_client_receiver),
|
||||
type);
|
||||
@@ -1202,11 +1446,31 @@ void ElectronBrowserClient::BindHostReceiverForRenderer(
|
||||
#endif
|
||||
}
|
||||
|
||||
#if BUILDFLAG(ENABLE_ELECTRON_EXTENSIONS)
|
||||
void BindMimeHandlerService(
|
||||
content::RenderFrameHost* frame_host,
|
||||
mojo::PendingReceiver<extensions::mime_handler::MimeHandlerService>
|
||||
receiver) {
|
||||
content::WebContents* contents =
|
||||
content::WebContents::FromRenderFrameHost(frame_host);
|
||||
auto* guest_view =
|
||||
extensions::MimeHandlerViewGuest::FromWebContents(contents);
|
||||
if (!guest_view)
|
||||
return;
|
||||
extensions::MimeHandlerServiceImpl::Create(guest_view->GetStreamWeakPtr(),
|
||||
std::move(receiver));
|
||||
}
|
||||
#endif
|
||||
|
||||
void ElectronBrowserClient::RegisterBrowserInterfaceBindersForFrame(
|
||||
content::RenderFrameHost* render_frame_host,
|
||||
service_manager::BinderMapWithContext<content::RenderFrameHost*>* map) {
|
||||
map->Add<network_hints::mojom::NetworkHintsHandler>(
|
||||
base::BindRepeating(&BindNetworkHintsHandler));
|
||||
#if BUILDFLAG(ENABLE_ELECTRON_EXTENSIONS)
|
||||
map->Add<extensions::mime_handler::MimeHandlerService>(
|
||||
base::BindRepeating(&BindMimeHandlerService));
|
||||
#endif
|
||||
}
|
||||
|
||||
std::unique_ptr<content::LoginDelegate>
|
||||
@@ -1224,4 +1488,35 @@ ElectronBrowserClient::CreateLoginDelegate(
|
||||
first_auth_attempt, std::move(auth_required_callback));
|
||||
}
|
||||
|
||||
std::vector<std::unique_ptr<blink::URLLoaderThrottle>>
|
||||
ElectronBrowserClient::CreateURLLoaderThrottles(
|
||||
const network::ResourceRequest& request,
|
||||
content::BrowserContext* browser_context,
|
||||
const base::RepeatingCallback<content::WebContents*()>& wc_getter,
|
||||
content::NavigationUIData* navigation_ui_data,
|
||||
int frame_tree_node_id) {
|
||||
DCHECK_CURRENTLY_ON(BrowserThread::UI);
|
||||
|
||||
std::vector<std::unique_ptr<blink::URLLoaderThrottle>> result;
|
||||
|
||||
#if BUILDFLAG(ENABLE_PLUGINS) && BUILDFLAG(ENABLE_ELECTRON_EXTENSIONS)
|
||||
result.push_back(std::make_unique<PluginResponseInterceptorURLLoaderThrottle>(
|
||||
request.resource_type, frame_tree_node_id));
|
||||
#endif
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
base::flat_set<std::string>
|
||||
ElectronBrowserClient::GetPluginMimeTypesWithExternalHandlers(
|
||||
content::BrowserContext* browser_context) {
|
||||
base::flat_set<std::string> mime_types;
|
||||
#if BUILDFLAG(ENABLE_PLUGINS) && BUILDFLAG(ENABLE_ELECTRON_EXTENSIONS)
|
||||
auto map = PluginUtils::GetMimeTypeToExtensionIdMap(browser_context);
|
||||
for (const auto& pair : map)
|
||||
mime_types.insert(pair.first);
|
||||
#endif
|
||||
return mime_types;
|
||||
}
|
||||
|
||||
} // namespace electron
|
||||
|
||||
@@ -173,6 +173,15 @@ class ElectronBrowserClient : public content::ContentBrowserClient,
|
||||
int render_process_id,
|
||||
int render_frame_id,
|
||||
NonNetworkURLLoaderFactoryMap* factories) override;
|
||||
void CreateWebSocket(
|
||||
content::RenderFrameHost* frame,
|
||||
WebSocketFactory factory,
|
||||
const GURL& url,
|
||||
const net::SiteForCookies& site_for_cookies,
|
||||
const base::Optional<std::string>& user_agent,
|
||||
mojo::PendingRemote<network::mojom::WebSocketHandshakeClient>
|
||||
handshake_client) override;
|
||||
bool WillInterceptWebSocket(content::RenderFrameHost*) override;
|
||||
bool WillCreateURLLoaderFactory(
|
||||
content::BrowserContext* browser_context,
|
||||
content::RenderFrameHost* frame,
|
||||
@@ -186,6 +195,9 @@ class ElectronBrowserClient : public content::ContentBrowserClient,
|
||||
bool* bypass_redirect_checks,
|
||||
bool* disable_secure_dns,
|
||||
network::mojom::URLLoaderFactoryOverridePtr* factory_override) override;
|
||||
bool ShouldTreatURLSchemeAsFirstPartyWhenTopLevel(
|
||||
base::StringPiece scheme,
|
||||
bool is_embedded_origin_secure) override;
|
||||
void OverrideURLLoaderFactoryParams(
|
||||
content::BrowserContext* browser_context,
|
||||
const url::Origin& origin,
|
||||
@@ -221,6 +233,19 @@ 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;
|
||||
std::vector<std::unique_ptr<blink::URLLoaderThrottle>>
|
||||
CreateURLLoaderThrottles(
|
||||
const network::ResourceRequest& request,
|
||||
content::BrowserContext* browser_context,
|
||||
const base::RepeatingCallback<content::WebContents*()>& wc_getter,
|
||||
content::NavigationUIData* navigation_ui_data,
|
||||
int frame_tree_node_id) override;
|
||||
base::flat_set<std::string> GetPluginMimeTypesWithExternalHandlers(
|
||||
content::BrowserContext* browser_context) override;
|
||||
|
||||
// content::RenderProcessHostObserver:
|
||||
void RenderProcessHostDestroyed(content::RenderProcessHost* host) override;
|
||||
@@ -284,7 +309,11 @@ class ElectronBrowserClient : public content::ContentBrowserClient,
|
||||
|
||||
std::string user_agent_override_ = "";
|
||||
|
||||
bool disable_process_restart_tricks_ = false;
|
||||
bool disable_process_restart_tricks_ = true;
|
||||
|
||||
// Simple shared ID generator, used by ProxyingURLLoaderFactory and
|
||||
// ProxyingWebSocket classes.
|
||||
uint64_t next_id_ = 0;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(ElectronBrowserClient);
|
||||
};
|
||||
|
||||
@@ -119,6 +119,9 @@ ElectronBrowserContext::ElectronBrowserContext(const std::string& partition,
|
||||
path_ = path_.Append(base::FilePath::FromUTF8Unsafe(GetApplicationName()));
|
||||
base::PathService::Override(DIR_USER_DATA, path_);
|
||||
base::PathService::Override(chrome::DIR_USER_DATA, path_);
|
||||
base::PathService::Override(
|
||||
chrome::DIR_APP_DICTIONARIES,
|
||||
path_.Append(base::FilePath::FromUTF8Unsafe("Dictionaries")));
|
||||
}
|
||||
|
||||
if (!in_memory && !partition.empty())
|
||||
|
||||
@@ -35,7 +35,7 @@ void ElectronBrowserMainParts::FreeAppDelegate() {
|
||||
}
|
||||
|
||||
void ElectronBrowserMainParts::RegisterURLHandler() {
|
||||
[[ElectronApplication sharedApplication] registerURLHandler];
|
||||
[[AtomApplication sharedApplication] registerURLHandler];
|
||||
}
|
||||
|
||||
// Replicates NSApplicationMain, but doesn't start a run loop.
|
||||
|
||||
@@ -93,6 +93,7 @@ void ElectronJavaScriptDialogManager::RunJavaScriptDialog(
|
||||
|
||||
electron::MessageBoxSettings settings;
|
||||
settings.parent_window = window;
|
||||
settings.checkbox_label = checkbox;
|
||||
settings.buttons = buttons;
|
||||
settings.default_id = default_id;
|
||||
settings.cancel_id = cancel_id;
|
||||
|
||||
35
shell/browser/extensions/api/BUILD.gn
Normal file
35
shell/browser/extensions/api/BUILD.gn
Normal file
@@ -0,0 +1,35 @@
|
||||
# Copyright 2018 The Chromium Authors. All rights reserved.
|
||||
# Use of this source code is governed by a BSD-style license that can be
|
||||
# found in the LICENSE file.
|
||||
|
||||
import("//extensions/buildflags/buildflags.gni")
|
||||
import("//tools/json_schema_compiler/json_schema_api.gni")
|
||||
|
||||
assert(enable_extensions,
|
||||
"Cannot depend on extensions because enable_extensions=false.")
|
||||
|
||||
function_registration("api_registration") {
|
||||
sources = [
|
||||
"//electron/shell/common/extensions/api/extension.json",
|
||||
"//electron/shell/common/extensions/api/resources_private.idl",
|
||||
"//electron/shell/common/extensions/api/tabs.json",
|
||||
]
|
||||
impl_dir = "//electron/shell/browser/extensions/api"
|
||||
configs = [ "//build/config:precompiled_headers" ]
|
||||
bundle_name = "Electron"
|
||||
root_namespace = "extensions::api::%(namespace)s"
|
||||
schema_include_rules = "extensions/common/api:extensions::api::%(namespace)s"
|
||||
|
||||
deps = [
|
||||
# Different APIs include headers from these targets.
|
||||
"//components/zoom",
|
||||
"//content/public/browser",
|
||||
"//extensions/browser",
|
||||
|
||||
# Different APIs include some headers from chrome/common that in turn
|
||||
# include generated headers from these targets.
|
||||
# TODO(brettw) this should be made unnecessary if possible.
|
||||
"//electron/shell/common/extensions/api",
|
||||
]
|
||||
deps += [ "//extensions/common/api" ]
|
||||
}
|
||||
@@ -0,0 +1,113 @@
|
||||
// Copyright 2015 The Chromium Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "shell/browser/extensions/api/resources_private/resources_private_api.h"
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
|
||||
#include "base/values.h"
|
||||
#include "chrome/browser/browser_process.h"
|
||||
#include "chrome/common/extensions/api/resources_private.h"
|
||||
#include "chrome/grit/generated_resources.h"
|
||||
#include "components/strings/grit/components_strings.h"
|
||||
#include "components/zoom/page_zoom_constants.h"
|
||||
#include "pdf/buildflags.h"
|
||||
#include "printing/buildflags/buildflags.h"
|
||||
#include "ui/base/l10n/l10n_util.h"
|
||||
#include "ui/base/webui/web_ui_util.h"
|
||||
|
||||
#if BUILDFLAG(ENABLE_PDF)
|
||||
#include "pdf/pdf_features.h"
|
||||
#endif // BUILDFLAG(ENABLE_PDF)
|
||||
|
||||
// To add a new component to this API, simply:
|
||||
// 1. Add your component to the Component enum in
|
||||
// chrome/common/extensions/api/resources_private.idl
|
||||
// 2. Create an AddStringsForMyComponent(base::DictionaryValue * dict) method.
|
||||
// 3. Tie in that method to the switch statement in Run()
|
||||
|
||||
namespace extensions {
|
||||
|
||||
namespace {
|
||||
|
||||
void AddStringsForPdf(base::DictionaryValue* dict) {
|
||||
#if BUILDFLAG(ENABLE_PDF)
|
||||
static constexpr webui::LocalizedString kPdfResources[] = {
|
||||
{"passwordDialogTitle", IDS_PDF_PASSWORD_DIALOG_TITLE},
|
||||
{"passwordPrompt", IDS_PDF_NEED_PASSWORD},
|
||||
{"passwordSubmit", IDS_PDF_PASSWORD_SUBMIT},
|
||||
{"passwordInvalid", IDS_PDF_PASSWORD_INVALID},
|
||||
{"pageLoading", IDS_PDF_PAGE_LOADING},
|
||||
{"pageLoadFailed", IDS_PDF_PAGE_LOAD_FAILED},
|
||||
{"errorDialogTitle", IDS_PDF_ERROR_DIALOG_TITLE},
|
||||
{"pageReload", IDS_PDF_PAGE_RELOAD_BUTTON},
|
||||
{"bookmarks", IDS_PDF_BOOKMARKS},
|
||||
{"labelPageNumber", IDS_PDF_LABEL_PAGE_NUMBER},
|
||||
{"tooltipRotateCW", IDS_PDF_TOOLTIP_ROTATE_CW},
|
||||
{"tooltipDownload", IDS_PDF_TOOLTIP_DOWNLOAD},
|
||||
{"tooltipPrint", IDS_PDF_TOOLTIP_PRINT},
|
||||
{"tooltipFitToPage", IDS_PDF_TOOLTIP_FIT_PAGE},
|
||||
{"tooltipFitToWidth", IDS_PDF_TOOLTIP_FIT_WIDTH},
|
||||
{"tooltipZoomIn", IDS_PDF_TOOLTIP_ZOOM_IN},
|
||||
{"tooltipZoomOut", IDS_PDF_TOOLTIP_ZOOM_OUT},
|
||||
};
|
||||
for (const auto& resource : kPdfResources)
|
||||
dict->SetString(resource.name, l10n_util::GetStringUTF16(resource.id));
|
||||
|
||||
dict->SetString("presetZoomFactors", zoom::GetPresetZoomFactorsAsJSON());
|
||||
#endif // BUILDFLAG(ENABLE_PDF)
|
||||
}
|
||||
|
||||
void AddAdditionalDataForPdf(base::DictionaryValue* dict) {
|
||||
#if BUILDFLAG(ENABLE_PDF)
|
||||
dict->SetKey("pdfFormSaveEnabled",
|
||||
base::Value(base::FeatureList::IsEnabled(
|
||||
chrome_pdf::features::kSaveEditedPDFForm)));
|
||||
dict->SetKey("pdfAnnotationsEnabled",
|
||||
base::Value(base::FeatureList::IsEnabled(
|
||||
chrome_pdf::features::kPDFAnnotations)));
|
||||
|
||||
// TODO(nornagon): enable printing once it works.
|
||||
bool enable_printing = false;
|
||||
dict->SetKey("printingEnabled", base::Value(enable_printing));
|
||||
#endif // BUILDFLAG(ENABLE_PDF)
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
namespace get_strings = api::resources_private::GetStrings;
|
||||
|
||||
ResourcesPrivateGetStringsFunction::ResourcesPrivateGetStringsFunction() {}
|
||||
|
||||
ResourcesPrivateGetStringsFunction::~ResourcesPrivateGetStringsFunction() {}
|
||||
|
||||
ExtensionFunction::ResponseAction ResourcesPrivateGetStringsFunction::Run() {
|
||||
std::unique_ptr<get_strings::Params> params(
|
||||
get_strings::Params::Create(*args_));
|
||||
auto dict = std::make_unique<base::DictionaryValue>();
|
||||
|
||||
api::resources_private::Component component = params->component;
|
||||
|
||||
switch (component) {
|
||||
case api::resources_private::COMPONENT_PDF:
|
||||
AddStringsForPdf(dict.get());
|
||||
AddAdditionalDataForPdf(dict.get());
|
||||
break;
|
||||
case api::resources_private::COMPONENT_IDENTITY:
|
||||
NOTREACHED();
|
||||
break;
|
||||
case api::resources_private::COMPONENT_NONE:
|
||||
NOTREACHED();
|
||||
break;
|
||||
}
|
||||
|
||||
const std::string& app_locale = g_browser_process->GetApplicationLocale();
|
||||
webui::SetLoadTimeDataDefaults(app_locale, dict.get());
|
||||
|
||||
return RespondNow(OneArgument(std::move(dict)));
|
||||
}
|
||||
|
||||
} // namespace extensions
|
||||
@@ -0,0 +1,31 @@
|
||||
// Copyright 2015 The Chromium Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef SHELL_BROWSER_EXTENSIONS_API_RESOURCES_PRIVATE_RESOURCES_PRIVATE_API_H_
|
||||
#define SHELL_BROWSER_EXTENSIONS_API_RESOURCES_PRIVATE_RESOURCES_PRIVATE_API_H_
|
||||
|
||||
#include "base/macros.h"
|
||||
#include "extensions/browser/extension_function.h"
|
||||
|
||||
namespace extensions {
|
||||
|
||||
class ResourcesPrivateGetStringsFunction : public ExtensionFunction {
|
||||
public:
|
||||
DECLARE_EXTENSION_FUNCTION("resourcesPrivate.getStrings",
|
||||
RESOURCESPRIVATE_GETSTRINGS)
|
||||
ResourcesPrivateGetStringsFunction();
|
||||
|
||||
protected:
|
||||
~ResourcesPrivateGetStringsFunction() override;
|
||||
|
||||
// Override from ExtensionFunction:
|
||||
ExtensionFunction::ResponseAction Run() override;
|
||||
|
||||
private:
|
||||
DISALLOW_COPY_AND_ASSIGN(ResourcesPrivateGetStringsFunction);
|
||||
};
|
||||
|
||||
} // namespace extensions
|
||||
|
||||
#endif // SHELL_BROWSER_EXTENSIONS_API_RESOURCES_PRIVATE_RESOURCES_PRIVATE_API_H_
|
||||
@@ -0,0 +1,74 @@
|
||||
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "electron/shell/browser/extensions/api/streams_private/streams_private_api.h"
|
||||
|
||||
#include <utility>
|
||||
|
||||
#include "content/public/browser/browser_thread.h"
|
||||
#include "content/public/browser/render_frame_host.h"
|
||||
#include "content/public/browser/web_contents.h"
|
||||
#include "extensions/browser/extension_registry.h"
|
||||
#include "extensions/browser/guest_view/mime_handler_view/mime_handler_stream_manager.h"
|
||||
#include "extensions/browser/guest_view/mime_handler_view/mime_handler_view_guest.h"
|
||||
#include "extensions/common/manifest_handlers/mime_types_handler.h"
|
||||
#include "shell/browser/api/electron_api_web_contents.h"
|
||||
|
||||
namespace extensions {
|
||||
|
||||
void StreamsPrivateAPI::SendExecuteMimeTypeHandlerEvent(
|
||||
const std::string& extension_id,
|
||||
const std::string& view_id,
|
||||
bool embedded,
|
||||
int frame_tree_node_id,
|
||||
int render_process_id,
|
||||
int render_frame_id,
|
||||
content::mojom::TransferrableURLLoaderPtr transferrable_loader,
|
||||
const GURL& original_url) {
|
||||
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
|
||||
|
||||
content::WebContents* web_contents = nullptr;
|
||||
if (frame_tree_node_id != -1) {
|
||||
web_contents =
|
||||
content::WebContents::FromFrameTreeNodeId(frame_tree_node_id);
|
||||
} else {
|
||||
web_contents = content::WebContents::FromRenderFrameHost(
|
||||
content::RenderFrameHost::FromID(render_process_id, render_frame_id));
|
||||
}
|
||||
if (!web_contents)
|
||||
return;
|
||||
|
||||
auto* browser_context = web_contents->GetBrowserContext();
|
||||
|
||||
const extensions::Extension* extension =
|
||||
extensions::ExtensionRegistry::Get(browser_context)
|
||||
->enabled_extensions()
|
||||
.GetByID(extension_id);
|
||||
if (!extension)
|
||||
return;
|
||||
|
||||
MimeTypesHandler* handler = MimeTypesHandler::GetHandler(extension);
|
||||
if (!handler->HasPlugin())
|
||||
return;
|
||||
|
||||
// If the mime handler uses MimeHandlerViewGuest, the MimeHandlerViewGuest
|
||||
// will take ownership of the stream.
|
||||
GURL handler_url(
|
||||
extensions::Extension::GetBaseURLFromExtensionId(extension_id).spec() +
|
||||
handler->handler_url());
|
||||
int tab_id = -1;
|
||||
auto* api_contents = electron::api::WebContents::FromWrappedClass(
|
||||
v8::Isolate::GetCurrent(), web_contents);
|
||||
if (api_contents)
|
||||
tab_id = api_contents->ID();
|
||||
std::unique_ptr<extensions::StreamContainer> stream_container(
|
||||
new extensions::StreamContainer(
|
||||
tab_id, embedded, handler_url, extension_id,
|
||||
std::move(transferrable_loader), original_url));
|
||||
extensions::MimeHandlerStreamManager::Get(browser_context)
|
||||
->AddStream(view_id, std::move(stream_container), frame_tree_node_id,
|
||||
render_process_id, render_frame_id);
|
||||
}
|
||||
|
||||
} // namespace extensions
|
||||
@@ -0,0 +1,44 @@
|
||||
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef SHELL_BROWSER_EXTENSIONS_API_STREAMS_PRIVATE_STREAMS_PRIVATE_API_H_
|
||||
#define SHELL_BROWSER_EXTENSIONS_API_STREAMS_PRIVATE_STREAMS_PRIVATE_API_H_
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
#include "base/macros.h"
|
||||
#include "content/public/common/transferrable_url_loader.mojom.h"
|
||||
|
||||
namespace extensions {
|
||||
|
||||
// TODO(devlin): This is now only used for the MimeTypesHandler API. We should
|
||||
// rename and move it to make that clear. https://crbug.com/890401.
|
||||
class StreamsPrivateAPI {
|
||||
public:
|
||||
// Send the onExecuteMimeTypeHandler event to |extension_id|. If the viewer is
|
||||
// being opened in a BrowserPlugin, specify a non-empty |view_id| of the
|
||||
// plugin. |embedded| should be set to whether the document is embedded
|
||||
// within another document. The |frame_tree_node_id| parameter is used for the
|
||||
// top level plugins case. (PDF, etc). If this parameter has a valid value
|
||||
// then it overrides the |render_process_id| and |render_frame_id| parameters.
|
||||
// The |render_process_id| is the id of the renderer process. The
|
||||
// |render_frame_id| is the routing id of the RenderFrameHost.
|
||||
//
|
||||
// If the network service is not enabled, |stream| is used; otherwise,
|
||||
// |transferrable_loader| and |original_url| are used instead.
|
||||
static void SendExecuteMimeTypeHandlerEvent(
|
||||
const std::string& extension_id,
|
||||
const std::string& view_id,
|
||||
bool embedded,
|
||||
int frame_tree_node_id,
|
||||
int render_process_id,
|
||||
int render_frame_id,
|
||||
content::mojom::TransferrableURLLoaderPtr transferrable_loader,
|
||||
const GURL& original_url);
|
||||
};
|
||||
|
||||
} // namespace extensions
|
||||
|
||||
#endif // SHELL_BROWSER_EXTENSIONS_API_STREAMS_PRIVATE_STREAMS_PRIVATE_API_H_
|
||||
@@ -12,13 +12,48 @@
|
||||
#include "extensions/common/manifest_constants.h"
|
||||
#include "extensions/common/permissions/permissions_data.h"
|
||||
#include "shell/browser/api/electron_api_web_contents.h"
|
||||
#include "shell/browser/web_contents_zoom_controller.h"
|
||||
#include "shell/common/extensions/api/tabs.h"
|
||||
#include "third_party/blink/public/common/page/page_zoom.h"
|
||||
|
||||
using electron::WebContentsZoomController;
|
||||
|
||||
namespace extensions {
|
||||
|
||||
namespace tabs = api::tabs;
|
||||
|
||||
const char kFrameNotFoundError[] = "No frame with id * in tab *.";
|
||||
const char kPerOriginOnlyInAutomaticError[] =
|
||||
"Can only set scope to "
|
||||
"\"per-origin\" in \"automatic\" mode.";
|
||||
|
||||
using api::extension_types::InjectDetails;
|
||||
|
||||
namespace {
|
||||
void ZoomModeToZoomSettings(WebContentsZoomController::ZoomMode zoom_mode,
|
||||
api::tabs::ZoomSettings* zoom_settings) {
|
||||
DCHECK(zoom_settings);
|
||||
switch (zoom_mode) {
|
||||
case WebContentsZoomController::ZoomMode::DEFAULT:
|
||||
zoom_settings->mode = api::tabs::ZOOM_SETTINGS_MODE_AUTOMATIC;
|
||||
zoom_settings->scope = api::tabs::ZOOM_SETTINGS_SCOPE_PER_ORIGIN;
|
||||
break;
|
||||
case WebContentsZoomController::ZoomMode::ISOLATED:
|
||||
zoom_settings->mode = api::tabs::ZOOM_SETTINGS_MODE_AUTOMATIC;
|
||||
zoom_settings->scope = api::tabs::ZOOM_SETTINGS_SCOPE_PER_TAB;
|
||||
break;
|
||||
case WebContentsZoomController::ZoomMode::MANUAL:
|
||||
zoom_settings->mode = api::tabs::ZOOM_SETTINGS_MODE_MANUAL;
|
||||
zoom_settings->scope = api::tabs::ZOOM_SETTINGS_SCOPE_PER_TAB;
|
||||
break;
|
||||
case WebContentsZoomController::ZoomMode::DISABLED:
|
||||
zoom_settings->mode = api::tabs::ZOOM_SETTINGS_MODE_DISABLED;
|
||||
zoom_settings->scope = api::tabs::ZOOM_SETTINGS_SCOPE_PER_TAB;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} // namespace
|
||||
|
||||
ExecuteCodeInTabFunction::ExecuteCodeInTabFunction() : execute_tab_id_(-1) {}
|
||||
|
||||
ExecuteCodeInTabFunction::~ExecuteCodeInTabFunction() {}
|
||||
@@ -130,4 +165,149 @@ bool TabsExecuteScriptFunction::ShouldInsertCSS() const {
|
||||
return false;
|
||||
}
|
||||
|
||||
ExtensionFunction::ResponseAction TabsGetFunction::Run() {
|
||||
std::unique_ptr<tabs::Get::Params> params(tabs::Get::Params::Create(*args_));
|
||||
EXTENSION_FUNCTION_VALIDATE(params.get());
|
||||
int tab_id = params->tab_id;
|
||||
|
||||
auto* contents = electron::api::WebContents::FromWeakMapID(
|
||||
v8::Isolate::GetCurrent(), tab_id);
|
||||
if (!contents)
|
||||
return RespondNow(Error("No such tab"));
|
||||
|
||||
tabs::Tab tab;
|
||||
|
||||
tab.id.reset(new int(tab_id));
|
||||
// TODO(nornagon): in Chrome, the tab URL is only available to extensions
|
||||
// that have the "tabs" (or "activeTab") permission. We should do the same
|
||||
// permission check here.
|
||||
tab.url = std::make_unique<std::string>(
|
||||
contents->web_contents()->GetLastCommittedURL().spec());
|
||||
|
||||
return RespondNow(ArgumentList(tabs::Get::Results::Create(std::move(tab))));
|
||||
}
|
||||
|
||||
ExtensionFunction::ResponseAction TabsSetZoomFunction::Run() {
|
||||
std::unique_ptr<tabs::SetZoom::Params> params(
|
||||
tabs::SetZoom::Params::Create(*args_));
|
||||
EXTENSION_FUNCTION_VALIDATE(params);
|
||||
|
||||
int tab_id = params->tab_id ? *params->tab_id : -1;
|
||||
auto* contents = electron::api::WebContents::FromWeakMapID(
|
||||
v8::Isolate::GetCurrent(), tab_id);
|
||||
if (!contents)
|
||||
return RespondNow(Error("No such tab"));
|
||||
|
||||
auto* web_contents = contents->web_contents();
|
||||
GURL url(web_contents->GetVisibleURL());
|
||||
std::string error;
|
||||
if (extension()->permissions_data()->IsRestrictedUrl(url, &error))
|
||||
return RespondNow(Error(error));
|
||||
|
||||
auto* zoom_controller = contents->GetZoomController();
|
||||
double zoom_level =
|
||||
params->zoom_factor > 0
|
||||
? blink::PageZoomFactorToZoomLevel(params->zoom_factor)
|
||||
: blink::PageZoomFactorToZoomLevel(
|
||||
zoom_controller->GetDefaultZoomFactor());
|
||||
|
||||
zoom_controller->SetZoomLevel(zoom_level);
|
||||
|
||||
return RespondNow(NoArguments());
|
||||
}
|
||||
|
||||
ExtensionFunction::ResponseAction TabsGetZoomFunction::Run() {
|
||||
std::unique_ptr<tabs::GetZoom::Params> params(
|
||||
tabs::GetZoom::Params::Create(*args_));
|
||||
EXTENSION_FUNCTION_VALIDATE(params);
|
||||
|
||||
int tab_id = params->tab_id ? *params->tab_id : -1;
|
||||
auto* contents = electron::api::WebContents::FromWeakMapID(
|
||||
v8::Isolate::GetCurrent(), tab_id);
|
||||
if (!contents)
|
||||
return RespondNow(Error("No such tab"));
|
||||
|
||||
double zoom_level = contents->GetZoomController()->GetZoomLevel();
|
||||
double zoom_factor = blink::PageZoomLevelToZoomFactor(zoom_level);
|
||||
|
||||
return RespondNow(ArgumentList(tabs::GetZoom::Results::Create(zoom_factor)));
|
||||
}
|
||||
|
||||
ExtensionFunction::ResponseAction TabsGetZoomSettingsFunction::Run() {
|
||||
std::unique_ptr<tabs::GetZoomSettings::Params> params(
|
||||
tabs::GetZoomSettings::Params::Create(*args_));
|
||||
EXTENSION_FUNCTION_VALIDATE(params);
|
||||
|
||||
int tab_id = params->tab_id ? *params->tab_id : -1;
|
||||
auto* contents = electron::api::WebContents::FromWeakMapID(
|
||||
v8::Isolate::GetCurrent(), tab_id);
|
||||
if (!contents)
|
||||
return RespondNow(Error("No such tab"));
|
||||
|
||||
auto* zoom_controller = contents->GetZoomController();
|
||||
WebContentsZoomController::ZoomMode zoom_mode =
|
||||
contents->GetZoomController()->zoom_mode();
|
||||
api::tabs::ZoomSettings zoom_settings;
|
||||
ZoomModeToZoomSettings(zoom_mode, &zoom_settings);
|
||||
zoom_settings.default_zoom_factor.reset(
|
||||
new double(blink::PageZoomLevelToZoomFactor(
|
||||
zoom_controller->GetDefaultZoomLevel())));
|
||||
|
||||
return RespondNow(
|
||||
ArgumentList(api::tabs::GetZoomSettings::Results::Create(zoom_settings)));
|
||||
}
|
||||
|
||||
ExtensionFunction::ResponseAction TabsSetZoomSettingsFunction::Run() {
|
||||
using api::tabs::ZoomSettings;
|
||||
|
||||
std::unique_ptr<tabs::SetZoomSettings::Params> params(
|
||||
tabs::SetZoomSettings::Params::Create(*args_));
|
||||
EXTENSION_FUNCTION_VALIDATE(params);
|
||||
|
||||
int tab_id = params->tab_id ? *params->tab_id : -1;
|
||||
auto* contents = electron::api::WebContents::FromWeakMapID(
|
||||
v8::Isolate::GetCurrent(), tab_id);
|
||||
if (!contents)
|
||||
return RespondNow(Error("No such tab"));
|
||||
|
||||
std::string error;
|
||||
GURL url(contents->web_contents()->GetVisibleURL());
|
||||
if (extension()->permissions_data()->IsRestrictedUrl(url, &error))
|
||||
return RespondNow(Error(error));
|
||||
|
||||
// "per-origin" scope is only available in "automatic" mode.
|
||||
if (params->zoom_settings.scope == tabs::ZOOM_SETTINGS_SCOPE_PER_ORIGIN &&
|
||||
params->zoom_settings.mode != tabs::ZOOM_SETTINGS_MODE_AUTOMATIC &&
|
||||
params->zoom_settings.mode != tabs::ZOOM_SETTINGS_MODE_NONE) {
|
||||
return RespondNow(Error(kPerOriginOnlyInAutomaticError));
|
||||
}
|
||||
|
||||
// Determine the correct internal zoom mode to set |web_contents| to from the
|
||||
// user-specified |zoom_settings|.
|
||||
WebContentsZoomController::ZoomMode zoom_mode =
|
||||
WebContentsZoomController::ZoomMode::DEFAULT;
|
||||
switch (params->zoom_settings.mode) {
|
||||
case tabs::ZOOM_SETTINGS_MODE_NONE:
|
||||
case tabs::ZOOM_SETTINGS_MODE_AUTOMATIC:
|
||||
switch (params->zoom_settings.scope) {
|
||||
case tabs::ZOOM_SETTINGS_SCOPE_NONE:
|
||||
case tabs::ZOOM_SETTINGS_SCOPE_PER_ORIGIN:
|
||||
zoom_mode = WebContentsZoomController::ZoomMode::DEFAULT;
|
||||
break;
|
||||
case tabs::ZOOM_SETTINGS_SCOPE_PER_TAB:
|
||||
zoom_mode = WebContentsZoomController::ZoomMode::ISOLATED;
|
||||
}
|
||||
break;
|
||||
case tabs::ZOOM_SETTINGS_MODE_MANUAL:
|
||||
zoom_mode = WebContentsZoomController::ZoomMode::MANUAL;
|
||||
break;
|
||||
case tabs::ZOOM_SETTINGS_MODE_DISABLED:
|
||||
zoom_mode = WebContentsZoomController::ZoomMode::DISABLED;
|
||||
}
|
||||
|
||||
contents->GetZoomController()->SetZoomMode(zoom_mode);
|
||||
|
||||
return RespondNow(NoArguments());
|
||||
}
|
||||
|
||||
} // namespace extensions
|
||||
|
||||
@@ -44,6 +44,48 @@ class TabsExecuteScriptFunction : public ExecuteCodeInTabFunction {
|
||||
DECLARE_EXTENSION_FUNCTION("tabs.executeScript", TABS_EXECUTESCRIPT)
|
||||
};
|
||||
|
||||
class TabsGetFunction : public ExtensionFunction {
|
||||
~TabsGetFunction() override {}
|
||||
ResponseAction Run() override;
|
||||
DECLARE_EXTENSION_FUNCTION("tabs.get", TABS_GET)
|
||||
};
|
||||
|
||||
class TabsSetZoomFunction : public ExtensionFunction {
|
||||
private:
|
||||
~TabsSetZoomFunction() override {}
|
||||
|
||||
ResponseAction Run() override;
|
||||
|
||||
DECLARE_EXTENSION_FUNCTION("tabs.setZoom", TABS_SETZOOM)
|
||||
};
|
||||
|
||||
class TabsGetZoomFunction : public ExtensionFunction {
|
||||
private:
|
||||
~TabsGetZoomFunction() override {}
|
||||
|
||||
ResponseAction Run() override;
|
||||
|
||||
DECLARE_EXTENSION_FUNCTION("tabs.getZoom", TABS_GETZOOM)
|
||||
};
|
||||
|
||||
class TabsSetZoomSettingsFunction : public ExtensionFunction {
|
||||
private:
|
||||
~TabsSetZoomSettingsFunction() override {}
|
||||
|
||||
ResponseAction Run() override;
|
||||
|
||||
DECLARE_EXTENSION_FUNCTION("tabs.setZoomSettings", TABS_SETZOOMSETTINGS)
|
||||
};
|
||||
|
||||
class TabsGetZoomSettingsFunction : public ExtensionFunction {
|
||||
private:
|
||||
~TabsGetZoomSettingsFunction() override {}
|
||||
|
||||
ResponseAction Run() override;
|
||||
|
||||
DECLARE_EXTENSION_FUNCTION("tabs.getZoomSettings", TABS_GETZOOMSETTINGS)
|
||||
};
|
||||
|
||||
} // namespace extensions
|
||||
|
||||
#endif // SHELL_BROWSER_EXTENSIONS_API_TABS_TABS_API_H_
|
||||
|
||||
@@ -5,15 +5,12 @@
|
||||
#include "shell/browser/extensions/electron_browser_context_keyed_service_factories.h"
|
||||
|
||||
#include "extensions/browser/updater/update_service_factory.h"
|
||||
// #include "extensions/shell/browser/api/identity/identity_api.h"
|
||||
#include "shell/browser/extensions/electron_extension_system_factory.h"
|
||||
|
||||
namespace extensions {
|
||||
namespace electron {
|
||||
|
||||
void EnsureBrowserContextKeyedServiceFactoriesBuilt() {
|
||||
// IdentityAPI::GetFactoryInstance();
|
||||
|
||||
// TODO(rockot): Remove this once UpdateService is supported across all
|
||||
// extensions embedders (and namely chrome.)
|
||||
UpdateServiceFactory::GetInstance();
|
||||
|
||||
@@ -0,0 +1,89 @@
|
||||
// Copyright 2014 The Chromium Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "shell/browser/extensions/electron_component_extension_resource_manager.h"
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "base/logging.h"
|
||||
#include "base/path_service.h"
|
||||
#include "base/stl_util.h"
|
||||
#include "base/values.h"
|
||||
#include "build/build_config.h"
|
||||
#include "chrome/common/chrome_paths.h"
|
||||
#include "chrome/grit/component_extension_resources_map.h"
|
||||
|
||||
namespace extensions {
|
||||
|
||||
ElectronComponentExtensionResourceManager::
|
||||
ElectronComponentExtensionResourceManager() {
|
||||
AddComponentResourceEntries(kComponentExtensionResources,
|
||||
kComponentExtensionResourcesSize);
|
||||
}
|
||||
|
||||
ElectronComponentExtensionResourceManager::
|
||||
~ElectronComponentExtensionResourceManager() {}
|
||||
|
||||
bool ElectronComponentExtensionResourceManager::IsComponentExtensionResource(
|
||||
const base::FilePath& extension_path,
|
||||
const base::FilePath& resource_path,
|
||||
int* resource_id) const {
|
||||
base::FilePath directory_path = extension_path;
|
||||
base::FilePath resources_dir;
|
||||
base::FilePath relative_path;
|
||||
if (!base::PathService::Get(chrome::DIR_RESOURCES, &resources_dir) ||
|
||||
!resources_dir.AppendRelativePath(directory_path, &relative_path)) {
|
||||
return false;
|
||||
}
|
||||
relative_path = relative_path.Append(resource_path);
|
||||
relative_path = relative_path.NormalizePathSeparators();
|
||||
|
||||
auto entry = path_to_resource_id_.find(relative_path);
|
||||
if (entry != path_to_resource_id_.end()) {
|
||||
*resource_id = entry->second;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
const ui::TemplateReplacements*
|
||||
ElectronComponentExtensionResourceManager::GetTemplateReplacementsForExtension(
|
||||
const std::string& extension_id) const {
|
||||
auto it = extension_template_replacements_.find(extension_id);
|
||||
if (it == extension_template_replacements_.end()) {
|
||||
return nullptr;
|
||||
}
|
||||
return &it->second;
|
||||
}
|
||||
|
||||
void ElectronComponentExtensionResourceManager::AddComponentResourceEntries(
|
||||
const GritResourceMap* entries,
|
||||
size_t size) {
|
||||
base::FilePath gen_folder_path = base::FilePath().AppendASCII(
|
||||
"@out_folder@/gen/chrome/browser/resources/");
|
||||
gen_folder_path = gen_folder_path.NormalizePathSeparators();
|
||||
|
||||
for (size_t i = 0; i < size; ++i) {
|
||||
base::FilePath resource_path =
|
||||
base::FilePath().AppendASCII(entries[i].name);
|
||||
resource_path = resource_path.NormalizePathSeparators();
|
||||
|
||||
if (!gen_folder_path.IsParent(resource_path)) {
|
||||
DCHECK(!base::Contains(path_to_resource_id_, resource_path));
|
||||
path_to_resource_id_[resource_path] = entries[i].value;
|
||||
} else {
|
||||
// If the resource is a generated file, strip the generated folder's path,
|
||||
// so that it can be served from a normal URL (as if it were not
|
||||
// generated).
|
||||
base::FilePath effective_path =
|
||||
base::FilePath().AppendASCII(resource_path.AsUTF8Unsafe().substr(
|
||||
gen_folder_path.value().length()));
|
||||
DCHECK(!base::Contains(path_to_resource_id_, effective_path));
|
||||
path_to_resource_id_[effective_path] = entries[i].value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace extensions
|
||||
@@ -0,0 +1,50 @@
|
||||
// Copyright 2014 The Chromium Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef SHELL_BROWSER_EXTENSIONS_ELECTRON_COMPONENT_EXTENSION_RESOURCE_MANAGER_H_
|
||||
#define SHELL_BROWSER_EXTENSIONS_ELECTRON_COMPONENT_EXTENSION_RESOURCE_MANAGER_H_
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#include <map>
|
||||
#include <string>
|
||||
|
||||
#include "base/files/file_path.h"
|
||||
#include "base/macros.h"
|
||||
#include "extensions/browser/component_extension_resource_manager.h"
|
||||
|
||||
struct GritResourceMap;
|
||||
|
||||
namespace extensions {
|
||||
|
||||
class ElectronComponentExtensionResourceManager
|
||||
: public ComponentExtensionResourceManager {
|
||||
public:
|
||||
ElectronComponentExtensionResourceManager();
|
||||
~ElectronComponentExtensionResourceManager() override;
|
||||
|
||||
// Overridden from ComponentExtensionResourceManager:
|
||||
bool IsComponentExtensionResource(const base::FilePath& extension_path,
|
||||
const base::FilePath& resource_path,
|
||||
int* resource_id) const override;
|
||||
const ui::TemplateReplacements* GetTemplateReplacementsForExtension(
|
||||
const std::string& extension_id) const override;
|
||||
|
||||
private:
|
||||
void AddComponentResourceEntries(const GritResourceMap* entries, size_t size);
|
||||
|
||||
// A map from a resource path to the resource ID. Used by
|
||||
// IsComponentExtensionResource.
|
||||
std::map<base::FilePath, int> path_to_resource_id_;
|
||||
|
||||
// A map from an extension ID to its i18n template replacements.
|
||||
std::map<std::string, ui::TemplateReplacements>
|
||||
extension_template_replacements_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(ElectronComponentExtensionResourceManager);
|
||||
};
|
||||
|
||||
} // namespace extensions
|
||||
|
||||
#endif // SHELL_BROWSER_EXTENSIONS_ELECTRON_COMPONENT_EXTENSION_RESOURCE_MANAGER_H_
|
||||
@@ -49,6 +49,8 @@ class ElectronExtensionLoader : public ExtensionRegistrar::Delegate {
|
||||
void UnloadExtension(const ExtensionId& extension_id,
|
||||
extensions::UnloadedExtensionReason reason);
|
||||
|
||||
ExtensionRegistrar* registrar() { return &extension_registrar_; }
|
||||
|
||||
private:
|
||||
// If the extension loaded successfully, enables it. If it's an app, launches
|
||||
// it. If the load failed, updates ShellKeepAliveRequester.
|
||||
|
||||
@@ -11,7 +11,11 @@
|
||||
#include "base/bind.h"
|
||||
#include "base/files/file_path.h"
|
||||
#include "base/files/file_util.h"
|
||||
#include "base/json/json_string_value_serializer.h"
|
||||
#include "base/path_service.h"
|
||||
#include "base/task/post_task.h"
|
||||
#include "chrome/browser/pdf/pdf_extension_util.h"
|
||||
#include "chrome/common/chrome_paths.h"
|
||||
#include "content/public/browser/browser_context.h"
|
||||
#include "content/public/browser/browser_task_traits.h"
|
||||
#include "content/public/browser/browser_thread.h"
|
||||
@@ -84,6 +88,35 @@ void ElectronExtensionSystem::InitForRegularProfile(bool extensions_enabled) {
|
||||
app_sorting_ = std::make_unique<NullAppSorting>();
|
||||
extension_loader_ =
|
||||
std::make_unique<ElectronExtensionLoader>(browser_context_);
|
||||
|
||||
if (!browser_context_->IsOffTheRecord())
|
||||
LoadComponentExtensions();
|
||||
}
|
||||
|
||||
std::unique_ptr<base::DictionaryValue> ParseManifest(
|
||||
base::StringPiece manifest_contents) {
|
||||
JSONStringValueDeserializer deserializer(manifest_contents);
|
||||
std::unique_ptr<base::Value> manifest = deserializer.Deserialize(NULL, NULL);
|
||||
|
||||
if (!manifest.get() || !manifest->is_dict()) {
|
||||
LOG(ERROR) << "Failed to parse extension manifest.";
|
||||
return std::unique_ptr<base::DictionaryValue>();
|
||||
}
|
||||
return base::DictionaryValue::From(std::move(manifest));
|
||||
}
|
||||
|
||||
void ElectronExtensionSystem::LoadComponentExtensions() {
|
||||
std::string utf8_error;
|
||||
std::string pdf_manifest_string = pdf_extension_util::GetManifest();
|
||||
std::unique_ptr<base::DictionaryValue> pdf_manifest =
|
||||
ParseManifest(pdf_manifest_string);
|
||||
base::FilePath root_directory;
|
||||
CHECK(base::PathService::Get(chrome::DIR_RESOURCES, &root_directory));
|
||||
root_directory = root_directory.Append(FILE_PATH_LITERAL("pdf"));
|
||||
scoped_refptr<const Extension> pdf_extension = extensions::Extension::Create(
|
||||
root_directory, extensions::Manifest::COMPONENT, *pdf_manifest,
|
||||
extensions::Extension::REQUIRE_KEY, &utf8_error);
|
||||
extension_loader_->registrar()->AddExtension(pdf_extension);
|
||||
}
|
||||
|
||||
ExtensionService* ElectronExtensionSystem::extension_service() {
|
||||
|
||||
@@ -88,6 +88,8 @@ class ElectronExtensionSystem : public ExtensionSystem {
|
||||
private:
|
||||
void OnExtensionRegisteredWithRequestContexts(
|
||||
scoped_refptr<Extension> extension);
|
||||
void LoadComponentExtensions();
|
||||
|
||||
content::BrowserContext* browser_context_; // Not owned.
|
||||
|
||||
// Data to be accessed on the IO thread. Must outlive process_manager_.
|
||||
|
||||
@@ -5,12 +5,34 @@
|
||||
#include "shell/browser/extensions/electron_extensions_api_client.h"
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
#include "extensions/browser/guest_view/mime_handler_view/mime_handler_view_guest_delegate.h"
|
||||
#include "shell/browser/extensions/electron_extension_web_contents_observer.h"
|
||||
#include "shell/browser/extensions/electron_messaging_delegate.h"
|
||||
|
||||
namespace extensions {
|
||||
|
||||
class ElectronMimeHandlerViewGuestDelegate
|
||||
: public MimeHandlerViewGuestDelegate {
|
||||
public:
|
||||
ElectronMimeHandlerViewGuestDelegate() {}
|
||||
~ElectronMimeHandlerViewGuestDelegate() override {}
|
||||
|
||||
// MimeHandlerViewGuestDelegate.
|
||||
bool HandleContextMenu(content::WebContents* web_contents,
|
||||
const content::ContextMenuParams& params) override {
|
||||
// TODO(nornagon): surface this event to JS
|
||||
LOG(INFO) << "HCM";
|
||||
return true;
|
||||
}
|
||||
void RecordLoadMetric(bool in_main_frame,
|
||||
const std::string& mime_type) override {}
|
||||
|
||||
private:
|
||||
DISALLOW_COPY_AND_ASSIGN(ElectronMimeHandlerViewGuestDelegate);
|
||||
};
|
||||
|
||||
ElectronExtensionsAPIClient::ElectronExtensionsAPIClient() = default;
|
||||
ElectronExtensionsAPIClient::~ElectronExtensionsAPIClient() = default;
|
||||
|
||||
@@ -26,4 +48,10 @@ void ElectronExtensionsAPIClient::AttachWebContentsHelpers(
|
||||
web_contents);
|
||||
}
|
||||
|
||||
std::unique_ptr<MimeHandlerViewGuestDelegate>
|
||||
ElectronExtensionsAPIClient::CreateMimeHandlerViewGuestDelegate(
|
||||
MimeHandlerViewGuest* guest) const {
|
||||
return std::make_unique<ElectronMimeHandlerViewGuestDelegate>();
|
||||
}
|
||||
|
||||
} // namespace extensions
|
||||
|
||||
@@ -22,6 +22,9 @@ class ElectronExtensionsAPIClient : public ExtensionsAPIClient {
|
||||
MessagingDelegate* GetMessagingDelegate() override;
|
||||
void AttachWebContentsHelpers(
|
||||
content::WebContents* web_contents) const override;
|
||||
std::unique_ptr<MimeHandlerViewGuestDelegate>
|
||||
CreateMimeHandlerViewGuestDelegate(
|
||||
MimeHandlerViewGuest* guest) const override;
|
||||
|
||||
private:
|
||||
std::unique_ptr<ElectronMessagingDelegate> messaging_delegate_;
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
#include "shell/browser/extensions/electron_extensions_browser_api_provider.h"
|
||||
|
||||
#include "extensions/browser/extension_function_registry.h"
|
||||
#include "shell/browser/extensions/api/generated_api_registration.h"
|
||||
#include "shell/browser/extensions/api/tabs/tabs_api.h"
|
||||
|
||||
namespace extensions {
|
||||
@@ -16,11 +17,8 @@ ElectronExtensionsBrowserAPIProvider::~ElectronExtensionsBrowserAPIProvider() =
|
||||
|
||||
void ElectronExtensionsBrowserAPIProvider::RegisterExtensionFunctions(
|
||||
ExtensionFunctionRegistry* registry) {
|
||||
registry->RegisterFunction<TabsExecuteScriptFunction>();
|
||||
/*
|
||||
// Generated APIs from Electron.
|
||||
api::ElectronGeneratedFunctionRegistry::RegisterAll(registry);
|
||||
*/
|
||||
}
|
||||
|
||||
} // namespace extensions
|
||||
|
||||
@@ -8,8 +8,12 @@
|
||||
|
||||
#include "base/bind.h"
|
||||
#include "base/memory/ptr_util.h"
|
||||
#include "base/path_service.h"
|
||||
#include "base/task/post_task.h"
|
||||
#include "build/build_config.h"
|
||||
#include "chrome/browser/extensions/chrome_url_request_util.h"
|
||||
#include "chrome/common/chrome_paths.h"
|
||||
#include "chrome/common/extensions/chrome_manifest_url_handlers.h"
|
||||
#include "components/version_info/version_info.h"
|
||||
#include "content/public/browser/browser_context.h"
|
||||
#include "content/public/browser/browser_task_traits.h"
|
||||
@@ -20,17 +24,21 @@
|
||||
#include "extensions/browser/component_extension_resource_manager.h"
|
||||
#include "extensions/browser/core_extensions_browser_api_provider.h"
|
||||
#include "extensions/browser/event_router.h"
|
||||
#include "extensions/browser/extension_protocols.h"
|
||||
#include "extensions/browser/null_app_sorting.h"
|
||||
#include "extensions/browser/updater/null_extension_cache.h"
|
||||
#include "extensions/browser/url_request_util.h"
|
||||
#include "extensions/common/features/feature_channel.h"
|
||||
#include "extensions/common/file_util.h"
|
||||
#include "extensions/common/manifest_constants.h"
|
||||
#include "extensions/common/manifest_url_handlers.h"
|
||||
#include "net/base/mime_util.h"
|
||||
#include "services/network/public/mojom/url_loader.mojom.h"
|
||||
#include "shell/browser/browser.h"
|
||||
#include "shell/browser/electron_browser_client.h"
|
||||
#include "shell/browser/electron_browser_context.h"
|
||||
#include "shell/browser/extensions/api/runtime/electron_runtime_api_delegate.h"
|
||||
#include "shell/browser/extensions/electron_component_extension_resource_manager.h"
|
||||
#include "shell/browser/extensions/electron_extension_host_delegate.h"
|
||||
#include "shell/browser/extensions/electron_extension_system_factory.h"
|
||||
#include "shell/browser/extensions/electron_extension_web_contents_observer.h"
|
||||
@@ -38,9 +46,11 @@
|
||||
#include "shell/browser/extensions/electron_extensions_browser_api_provider.h"
|
||||
#include "shell/browser/extensions/electron_navigation_ui_data.h"
|
||||
#include "shell/browser/extensions/electron_process_manager_delegate.h"
|
||||
#include "ui/base/resource/resource_bundle.h"
|
||||
|
||||
using content::BrowserContext;
|
||||
using content::BrowserThread;
|
||||
using extensions::ExtensionsBrowserClient;
|
||||
|
||||
namespace electron {
|
||||
|
||||
@@ -51,6 +61,8 @@ ElectronExtensionsBrowserClient::ElectronExtensionsBrowserClient()
|
||||
// Electron does not have a concept of channel, so leave UNKNOWN to
|
||||
// enable all channel-dependent extension APIs.
|
||||
extensions::SetCurrentChannel(version_info::Channel::UNKNOWN);
|
||||
resource_manager_.reset(
|
||||
new extensions::ElectronComponentExtensionResourceManager());
|
||||
|
||||
AddAPIProvider(
|
||||
std::make_unique<extensions::CoreExtensionsBrowserAPIProvider>());
|
||||
@@ -127,7 +139,28 @@ base::FilePath ElectronExtensionsBrowserClient::GetBundleResourcePath(
|
||||
const base::FilePath& extension_resources_path,
|
||||
int* resource_id) const {
|
||||
*resource_id = 0;
|
||||
return base::FilePath();
|
||||
base::FilePath chrome_resources_path;
|
||||
if (!base::PathService::Get(chrome::DIR_RESOURCES, &chrome_resources_path))
|
||||
return base::FilePath();
|
||||
|
||||
// Since component extension resources are included in
|
||||
// component_extension_resources.pak file in |chrome_resources_path|,
|
||||
// calculate the extension |request_relative_path| against
|
||||
// |chrome_resources_path|.
|
||||
if (!chrome_resources_path.IsParent(extension_resources_path))
|
||||
return base::FilePath();
|
||||
|
||||
const base::FilePath request_relative_path =
|
||||
extensions::file_util::ExtensionURLToRelativeFilePath(request.url);
|
||||
if (!ExtensionsBrowserClient::Get()
|
||||
->GetComponentExtensionResourceManager()
|
||||
->IsComponentExtensionResource(extension_resources_path,
|
||||
request_relative_path, resource_id)) {
|
||||
return base::FilePath();
|
||||
}
|
||||
DCHECK_NE(0, *resource_id);
|
||||
|
||||
return request_relative_path;
|
||||
}
|
||||
|
||||
void ElectronExtensionsBrowserClient::LoadResourceFromResourceBundle(
|
||||
@@ -138,7 +171,9 @@ void ElectronExtensionsBrowserClient::LoadResourceFromResourceBundle(
|
||||
const std::string& content_security_policy,
|
||||
mojo::PendingRemote<network::mojom::URLLoaderClient> client,
|
||||
bool send_cors_header) {
|
||||
NOTREACHED() << "Load resources from bundles not supported.";
|
||||
extensions::chrome_url_request_util::LoadResourceFromResourceBundle(
|
||||
request, std::move(loader), resource_relative_path, resource_id,
|
||||
content_security_policy, std::move(client), send_cors_header);
|
||||
}
|
||||
|
||||
namespace {
|
||||
@@ -160,8 +195,7 @@ bool AllowCrossRendererResourceLoad(const GURL& url,
|
||||
// If there aren't any explicitly marked web accessible resources, the
|
||||
// load should be allowed only if it is by DevTools. A close approximation is
|
||||
// checking if the extension contains a DevTools page.
|
||||
if (extension && !extensions::ManifestURL::Get(
|
||||
extension, extensions::manifest_keys::kDevToolsPage)
|
||||
if (extension && !extensions::chrome_manifest_urls::GetDevToolsPage(extension)
|
||||
.is_empty()) {
|
||||
*allowed = true;
|
||||
return true;
|
||||
@@ -255,7 +289,7 @@ ElectronExtensionsBrowserClient::CreateRuntimeAPIDelegate(
|
||||
|
||||
const extensions::ComponentExtensionResourceManager*
|
||||
ElectronExtensionsBrowserClient::GetComponentExtensionResourceManager() {
|
||||
return NULL;
|
||||
return resource_manager_.get();
|
||||
}
|
||||
|
||||
void ElectronExtensionsBrowserClient::BroadcastEventToRenderers(
|
||||
|
||||
@@ -23,6 +23,7 @@ class KioskDelegate;
|
||||
class ProcessManagerDelegate;
|
||||
class ElectronProcessManagerDelegate;
|
||||
class ProcessMap;
|
||||
class ElectronComponentExtensionResourceManager;
|
||||
} // namespace extensions
|
||||
|
||||
namespace electron {
|
||||
@@ -138,6 +139,9 @@ class ElectronExtensionsBrowserClient
|
||||
// The extension cache used for download and installation.
|
||||
std::unique_ptr<extensions::ExtensionCache> extension_cache_;
|
||||
|
||||
std::unique_ptr<extensions::ElectronComponentExtensionResourceManager>
|
||||
resource_manager_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(ElectronExtensionsBrowserClient);
|
||||
};
|
||||
|
||||
|
||||
@@ -9,9 +9,9 @@
|
||||
#import <AVFoundation/AVFoundation.h>
|
||||
#import <LocalAuthentication/LocalAuthentication.h>
|
||||
|
||||
@interface ElectronApplication : NSApplication <CrAppProtocol,
|
||||
CrAppControlProtocol,
|
||||
NSUserActivityDelegate> {
|
||||
@interface AtomApplication : NSApplication <CrAppProtocol,
|
||||
CrAppControlProtocol,
|
||||
NSUserActivityDelegate> {
|
||||
@private
|
||||
BOOL handlingSendEvent_;
|
||||
base::scoped_nsobject<NSUserActivity> currentActivity_;
|
||||
@@ -20,7 +20,7 @@
|
||||
base::Callback<bool()> shouldShutdown_;
|
||||
}
|
||||
|
||||
+ (ElectronApplication*)sharedApplication;
|
||||
+ (AtomApplication*)sharedApplication;
|
||||
|
||||
- (void)setShutdownHandler:(base::Callback<bool()>)handler;
|
||||
- (void)registerURLHandler;
|
||||
|
||||
@@ -29,16 +29,16 @@ inline void dispatch_sync_main(dispatch_block_t block) {
|
||||
|
||||
} // namespace
|
||||
|
||||
@interface ElectronApplication () <NativeEventProcessor> {
|
||||
@interface AtomApplication () <NativeEventProcessor> {
|
||||
base::ObserverList<content::NativeEventProcessorObserver>::Unchecked
|
||||
observers_;
|
||||
}
|
||||
@end
|
||||
|
||||
@implementation ElectronApplication
|
||||
@implementation AtomApplication
|
||||
|
||||
+ (ElectronApplication*)sharedApplication {
|
||||
return (ElectronApplication*)[super sharedApplication];
|
||||
+ (AtomApplication*)sharedApplication {
|
||||
return (AtomApplication*)[super sharedApplication];
|
||||
}
|
||||
|
||||
- (void)terminate:(id)sender {
|
||||
|
||||
@@ -542,17 +542,27 @@ void NativeWindowMac::RepositionTrafficLights() {
|
||||
CGFloat buttonHeight = [close frame].size.height;
|
||||
CGFloat titleBarFrameHeight = buttonHeight + traffic_light_position_.y();
|
||||
CGRect titleBarRect = titleBarContainerView.frame;
|
||||
CGFloat titleBarWidth = NSWidth(titleBarRect);
|
||||
titleBarRect.size.height = titleBarFrameHeight;
|
||||
titleBarRect.origin.y = window.frame.size.height - titleBarFrameHeight;
|
||||
[titleBarContainerView setFrame:titleBarRect];
|
||||
|
||||
BOOL isRTL = [titleBarContainerView userInterfaceLayoutDirection] ==
|
||||
NSUserInterfaceLayoutDirectionRightToLeft;
|
||||
NSArray* windowButtons = @[ close, miniaturize, zoom ];
|
||||
const CGFloat space_between =
|
||||
[miniaturize frame].origin.x - [close frame].origin.x;
|
||||
for (NSUInteger i = 0; i < windowButtons.count; i++) {
|
||||
NSView* view = [windowButtons objectAtIndex:i];
|
||||
CGRect rect = [view frame];
|
||||
rect.origin.x = traffic_light_position_.x() + (i * space_between);
|
||||
if (isRTL) {
|
||||
CGFloat buttonWidth = NSWidth(rect);
|
||||
// origin is always top-left, even in RTL
|
||||
rect.origin.x = titleBarWidth - traffic_light_position_.x() +
|
||||
(i * space_between) - buttonWidth;
|
||||
} else {
|
||||
rect.origin.x = traffic_light_position_.x() + (i * space_between);
|
||||
}
|
||||
rect.origin.y = (titleBarFrameHeight - rect.size.height) / 2;
|
||||
[view setFrameOrigin:rect.origin];
|
||||
}
|
||||
@@ -578,7 +588,14 @@ void NativeWindowMac::SetContentView(views::View* view) {
|
||||
void NativeWindowMac::Close() {
|
||||
// When this is a sheet showing, performClose won't work.
|
||||
if (is_modal() && parent() && IsVisible()) {
|
||||
[parent()->GetNativeWindow().GetNativeNSWindow() endSheet:window_];
|
||||
NSWindow* window = parent()->GetNativeWindow().GetNativeNSWindow();
|
||||
if (NSWindow* sheetParent = [window sheetParent]) {
|
||||
base::ThreadTaskRunnerHandle::Get()->PostTask(
|
||||
FROM_HERE, base::BindOnce(base::RetainBlock(^{
|
||||
[sheetParent endSheet:window];
|
||||
})));
|
||||
}
|
||||
|
||||
// Manually emit close event (not triggered from close fn)
|
||||
NotifyWindowCloseButtonClicked();
|
||||
CloseImmediately();
|
||||
@@ -1455,8 +1472,7 @@ void NativeWindowMac::SetVibrancy(const std::string& type) {
|
||||
relativeTo:nil];
|
||||
}
|
||||
|
||||
std::string dep_warn =
|
||||
" has been deprecated and will be removed in a future version of macOS.";
|
||||
std::string dep_warn = " has been deprecated and removed as of macOS 10.15.";
|
||||
node::Environment* env =
|
||||
node::Environment::GetCurrent(v8::Isolate::GetCurrent());
|
||||
|
||||
@@ -1477,61 +1493,44 @@ void NativeWindowMac::SetVibrancy(const std::string& type) {
|
||||
}
|
||||
|
||||
if (@available(macOS 10.11, *)) {
|
||||
// TODO(codebytere): Use NSVisualEffectMaterial* constants directly once
|
||||
// they are available in the minimum SDK version
|
||||
if (type == "selection") {
|
||||
// NSVisualEffectMaterialSelection
|
||||
vibrancyType = static_cast<NSVisualEffectMaterial>(4);
|
||||
vibrancyType = NSVisualEffectMaterialSelection;
|
||||
} else if (type == "menu") {
|
||||
// NSVisualEffectMaterialMenu
|
||||
vibrancyType = static_cast<NSVisualEffectMaterial>(5);
|
||||
vibrancyType = NSVisualEffectMaterialMenu;
|
||||
} else if (type == "popover") {
|
||||
// NSVisualEffectMaterialPopover
|
||||
vibrancyType = static_cast<NSVisualEffectMaterial>(6);
|
||||
vibrancyType = NSVisualEffectMaterialPopover;
|
||||
} else if (type == "sidebar") {
|
||||
// NSVisualEffectMaterialSidebar
|
||||
vibrancyType = static_cast<NSVisualEffectMaterial>(7);
|
||||
vibrancyType = NSVisualEffectMaterialSidebar;
|
||||
} else if (type == "medium-light") {
|
||||
// NSVisualEffectMaterialMediumLight
|
||||
EmitWarning(env, "NSVisualEffectMaterialMediumLight" + dep_warn,
|
||||
"electron");
|
||||
vibrancyType = static_cast<NSVisualEffectMaterial>(8);
|
||||
vibrancyType = NSVisualEffectMaterialMediumLight;
|
||||
} else if (type == "ultra-dark") {
|
||||
// NSVisualEffectMaterialUltraDark
|
||||
EmitWarning(env, "NSVisualEffectMaterialUltraDark" + dep_warn,
|
||||
"electron");
|
||||
vibrancyType = static_cast<NSVisualEffectMaterial>(9);
|
||||
vibrancyType = NSVisualEffectMaterialUltraDark;
|
||||
}
|
||||
}
|
||||
|
||||
if (@available(macOS 10.14, *)) {
|
||||
if (type == "header") {
|
||||
// NSVisualEffectMaterialHeaderView
|
||||
vibrancyType = static_cast<NSVisualEffectMaterial>(10);
|
||||
vibrancyType = NSVisualEffectMaterialHeaderView;
|
||||
} else if (type == "sheet") {
|
||||
// NSVisualEffectMaterialSheet
|
||||
vibrancyType = static_cast<NSVisualEffectMaterial>(11);
|
||||
vibrancyType = NSVisualEffectMaterialSheet;
|
||||
} else if (type == "window") {
|
||||
// NSVisualEffectMaterialWindowBackground
|
||||
vibrancyType = static_cast<NSVisualEffectMaterial>(12);
|
||||
vibrancyType = NSVisualEffectMaterialWindowBackground;
|
||||
} else if (type == "hud") {
|
||||
// NSVisualEffectMaterialHUDWindow
|
||||
vibrancyType = static_cast<NSVisualEffectMaterial>(13);
|
||||
vibrancyType = NSVisualEffectMaterialHUDWindow;
|
||||
} else if (type == "fullscreen-ui") {
|
||||
// NSVisualEffectMaterialFullScreenUI
|
||||
vibrancyType = static_cast<NSVisualEffectMaterial>(16);
|
||||
vibrancyType = NSVisualEffectMaterialFullScreenUI;
|
||||
} else if (type == "tooltip") {
|
||||
// NSVisualEffectMaterialToolTip
|
||||
vibrancyType = static_cast<NSVisualEffectMaterial>(17);
|
||||
vibrancyType = NSVisualEffectMaterialToolTip;
|
||||
} else if (type == "content") {
|
||||
// NSVisualEffectMaterialContentBackground
|
||||
vibrancyType = static_cast<NSVisualEffectMaterial>(18);
|
||||
vibrancyType = NSVisualEffectMaterialContentBackground;
|
||||
} else if (type == "under-window") {
|
||||
// NSVisualEffectMaterialUnderWindowBackground
|
||||
vibrancyType = static_cast<NSVisualEffectMaterial>(21);
|
||||
vibrancyType = NSVisualEffectMaterialUnderWindowBackground;
|
||||
} else if (type == "under-page") {
|
||||
// NSVisualEffectMaterialUnderPageBackground
|
||||
vibrancyType = static_cast<NSVisualEffectMaterial>(22);
|
||||
vibrancyType = NSVisualEffectMaterialUnderPageBackground;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -21,12 +21,6 @@
|
||||
|
||||
namespace electron {
|
||||
|
||||
namespace {
|
||||
|
||||
int64_t g_request_id = 0;
|
||||
|
||||
} // namespace
|
||||
|
||||
ProxyingURLLoaderFactory::InProgressRequest::FollowRedirectParams::
|
||||
FollowRedirectParams() = default;
|
||||
ProxyingURLLoaderFactory::InProgressRequest::FollowRedirectParams::
|
||||
@@ -40,7 +34,7 @@ ProxyingURLLoaderFactory::InProgressRequest::InProgressRequest(
|
||||
uint32_t options,
|
||||
const network::ResourceRequest& request,
|
||||
const net::MutableNetworkTrafficAnnotationTag& traffic_annotation,
|
||||
network::mojom::URLLoaderRequest loader_request,
|
||||
mojo::PendingReceiver<network::mojom::URLLoader> loader_receiver,
|
||||
mojo::PendingRemote<network::mojom::URLLoaderClient> client)
|
||||
: factory_(factory),
|
||||
request_(request),
|
||||
@@ -50,7 +44,7 @@ ProxyingURLLoaderFactory::InProgressRequest::InProgressRequest(
|
||||
network_service_request_id_(network_service_request_id),
|
||||
options_(options),
|
||||
traffic_annotation_(traffic_annotation),
|
||||
proxied_loader_binding_(this, std::move(loader_request)),
|
||||
proxied_loader_receiver_(this, std::move(loader_receiver)),
|
||||
target_client_(std::move(client)),
|
||||
current_response_(network::mojom::URLResponseHead::New()),
|
||||
// Always use "extraHeaders" mode to be compatible with old APIs, except
|
||||
@@ -62,8 +56,24 @@ ProxyingURLLoaderFactory::InProgressRequest::InProgressRequest(
|
||||
&ProxyingURLLoaderFactory::InProgressRequest::OnRequestError,
|
||||
weak_factory_.GetWeakPtr(),
|
||||
network::URLLoaderCompletionStatus(net::ERR_ABORTED)));
|
||||
proxied_loader_receiver_.set_disconnect_handler(base::BindOnce(
|
||||
&ProxyingURLLoaderFactory::InProgressRequest::OnRequestError,
|
||||
weak_factory_.GetWeakPtr(),
|
||||
network::URLLoaderCompletionStatus(net::ERR_ABORTED)));
|
||||
}
|
||||
|
||||
ProxyingURLLoaderFactory::InProgressRequest::InProgressRequest(
|
||||
ProxyingURLLoaderFactory* factory,
|
||||
uint64_t request_id,
|
||||
const network::ResourceRequest& request)
|
||||
: factory_(factory),
|
||||
request_(request),
|
||||
original_initiator_(request.request_initiator),
|
||||
request_id_(request_id),
|
||||
proxied_loader_receiver_(this),
|
||||
for_cors_preflight_(true),
|
||||
has_any_extra_headers_listeners_(true) {}
|
||||
|
||||
ProxyingURLLoaderFactory::InProgressRequest::~InProgressRequest() {
|
||||
// This is important to ensure that no outstanding blocking requests continue
|
||||
// to reference state owned by this object.
|
||||
@@ -103,13 +113,13 @@ void ProxyingURLLoaderFactory::InProgressRequest::UpdateRequestInfo() {
|
||||
|
||||
current_request_uses_header_client_ =
|
||||
factory_->url_loader_header_client_receiver_.is_bound() &&
|
||||
network_service_request_id_ != 0 && has_any_extra_headers_listeners_;
|
||||
(for_cors_preflight_ || network_service_request_id_ != 0) &&
|
||||
has_any_extra_headers_listeners_;
|
||||
}
|
||||
|
||||
void ProxyingURLLoaderFactory::InProgressRequest::RestartInternal() {
|
||||
DCHECK_EQ(info_->url, request_.url)
|
||||
<< "UpdateRequestInfo must have been called first";
|
||||
request_completed_ = false;
|
||||
|
||||
// If the header client will be used, we start the request immediately, and
|
||||
// OnBeforeSendHeaders and OnSendHeaders will be handled there. Otherwise,
|
||||
@@ -118,6 +128,9 @@ void ProxyingURLLoaderFactory::InProgressRequest::RestartInternal() {
|
||||
if (current_request_uses_header_client_) {
|
||||
continuation = base::BindRepeating(
|
||||
&InProgressRequest::ContinueToStartRequest, weak_factory_.GetWeakPtr());
|
||||
} else if (for_cors_preflight_) {
|
||||
// In this case we do nothing because extensions should see nothing.
|
||||
return;
|
||||
} else {
|
||||
continuation =
|
||||
base::BindRepeating(&InProgressRequest::ContinueToBeforeSendHeaders,
|
||||
@@ -289,6 +302,15 @@ void ProxyingURLLoaderFactory::InProgressRequest::OnComplete(
|
||||
void ProxyingURLLoaderFactory::InProgressRequest::OnLoaderCreated(
|
||||
mojo::PendingReceiver<network::mojom::TrustedHeaderClient> receiver) {
|
||||
header_client_receiver_.Bind(std::move(receiver));
|
||||
if (for_cors_preflight_) {
|
||||
// In this case we don't have |target_loader_| and
|
||||
// |proxied_client_binding_|, and |receiver| is the only connection to the
|
||||
// network service, so we observe mojo connection errors.
|
||||
header_client_receiver_.set_disconnect_handler(base::BindOnce(
|
||||
&ProxyingURLLoaderFactory::InProgressRequest::OnRequestError,
|
||||
weak_factory_.GetWeakPtr(),
|
||||
network::URLLoaderCompletionStatus(net::ERR_FAILED)));
|
||||
}
|
||||
}
|
||||
|
||||
void ProxyingURLLoaderFactory::InProgressRequest::OnBeforeSendHeaders(
|
||||
@@ -310,6 +332,12 @@ void ProxyingURLLoaderFactory::InProgressRequest::OnHeadersReceived(
|
||||
OnHeadersReceivedCallback callback) {
|
||||
if (!current_request_uses_header_client_) {
|
||||
std::move(callback).Run(net::OK, base::nullopt, GURL());
|
||||
|
||||
if (for_cors_preflight_) {
|
||||
// CORS preflight is supported only when "extraHeaders" is specified.
|
||||
// Deletes |this|.
|
||||
factory_->RemoveRequest(network_service_request_id_, request_id_);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -323,6 +351,27 @@ void ProxyingURLLoaderFactory::InProgressRequest::OnHeadersReceived(
|
||||
weak_factory_.GetWeakPtr()));
|
||||
}
|
||||
|
||||
void ProxyingURLLoaderFactory::OnLoaderForCorsPreflightCreated(
|
||||
const network::ResourceRequest& request,
|
||||
mojo::PendingReceiver<network::mojom::TrustedHeaderClient> receiver) {
|
||||
// Please note that the URLLoader is now starting, without waiting for
|
||||
// additional signals from here. The URLLoader will be blocked before
|
||||
// sending HTTP request headers (TrustedHeaderClient.OnBeforeSendHeaders),
|
||||
// but the connection set up will be done before that. This is acceptable from
|
||||
// Web Request API because the extension has already allowed to set up
|
||||
// a connection to the same URL (i.e., the actual request), and distinguishing
|
||||
// two connections for the actual request and the preflight request before
|
||||
// sending request headers is very difficult.
|
||||
const uint64_t web_request_id = ++(*request_id_generator_);
|
||||
|
||||
auto result = requests_.insert(std::make_pair(
|
||||
web_request_id,
|
||||
std::make_unique<InProgressRequest>(this, web_request_id, request)));
|
||||
|
||||
result.first->second->OnLoaderCreated(std::move(receiver));
|
||||
result.first->second->Restart();
|
||||
}
|
||||
|
||||
void ProxyingURLLoaderFactory::InProgressRequest::ContinueToBeforeSendHeaders(
|
||||
int error_code) {
|
||||
if (error_code != net::OK) {
|
||||
@@ -331,6 +380,11 @@ void ProxyingURLLoaderFactory::InProgressRequest::ContinueToBeforeSendHeaders(
|
||||
}
|
||||
|
||||
if (!current_request_uses_header_client_ && !redirect_url_.is_empty()) {
|
||||
if (for_cors_preflight_) {
|
||||
// CORS preflight doesn't support redirect.
|
||||
OnRequestError(network::URLLoaderCompletionStatus(net::ERR_FAILED));
|
||||
return;
|
||||
}
|
||||
HandleBeforeRequestRedirect();
|
||||
return;
|
||||
}
|
||||
@@ -434,6 +488,13 @@ void ProxyingURLLoaderFactory::InProgressRequest::ContinueToStartRequest(
|
||||
if (header_client_receiver_.is_bound())
|
||||
header_client_receiver_.Resume();
|
||||
|
||||
if (for_cors_preflight_) {
|
||||
// For CORS preflight requests, we have already started the request in
|
||||
// the network service. We did block the request by blocking
|
||||
// |header_client_receiver_|, which we unblocked right above.
|
||||
return;
|
||||
}
|
||||
|
||||
if (!target_loader_.is_bound() && factory_->target_factory_.is_bound()) {
|
||||
// No extensions have cancelled us up to this point, so it's now OK to
|
||||
// initiate the real network request.
|
||||
@@ -472,15 +533,34 @@ void ProxyingURLLoaderFactory::InProgressRequest::
|
||||
current_response_->headers = override_headers_;
|
||||
}
|
||||
}
|
||||
|
||||
if (for_cors_preflight_ && !redirect_url_.is_empty()) {
|
||||
OnRequestError(network::URLLoaderCompletionStatus(net::ERR_FAILED));
|
||||
return;
|
||||
}
|
||||
|
||||
std::move(on_headers_received_callback_).Run(net::OK, headers, redirect_url_);
|
||||
override_headers_ = nullptr;
|
||||
|
||||
if (for_cors_preflight_) {
|
||||
// If this is for CORS preflight, there is no associated client. We notify
|
||||
// the completion here, and deletes |this|.
|
||||
info_->AddResponseInfoFromResourceResponse(*current_response_);
|
||||
factory_->web_request_api()->OnResponseStarted(&info_.value(), request_);
|
||||
factory_->web_request_api()->OnCompleted(&info_.value(), request_, net::OK);
|
||||
|
||||
// Deletes |this|.
|
||||
factory_->RemoveRequest(network_service_request_id_, request_id_);
|
||||
return;
|
||||
}
|
||||
|
||||
if (proxied_client_receiver_.is_bound())
|
||||
proxied_client_receiver_.Resume();
|
||||
}
|
||||
|
||||
void ProxyingURLLoaderFactory::InProgressRequest::ContinueToResponseStarted(
|
||||
int error_code) {
|
||||
DCHECK(!for_cors_preflight_);
|
||||
if (error_code != net::OK) {
|
||||
OnRequestError(network::URLLoaderCompletionStatus(error_code));
|
||||
return;
|
||||
@@ -552,8 +632,6 @@ void ProxyingURLLoaderFactory::InProgressRequest::ContinueToBeforeRedirect(
|
||||
// reset the request body manually.
|
||||
if (request_.method == net::HttpRequestHeaders::kGetMethod)
|
||||
request_.request_body = nullptr;
|
||||
|
||||
request_completed_ = true;
|
||||
}
|
||||
|
||||
void ProxyingURLLoaderFactory::InProgressRequest::
|
||||
@@ -662,11 +740,10 @@ void ProxyingURLLoaderFactory::InProgressRequest::
|
||||
|
||||
void ProxyingURLLoaderFactory::InProgressRequest::OnRequestError(
|
||||
const network::URLLoaderCompletionStatus& status) {
|
||||
if (!request_completed_) {
|
||||
if (target_client_)
|
||||
target_client_->OnComplete(status);
|
||||
factory_->web_request_api()->OnErrorOccurred(&info_.value(), request_,
|
||||
status.error_code);
|
||||
}
|
||||
factory_->web_request_api()->OnErrorOccurred(&info_.value(), request_,
|
||||
status.error_code);
|
||||
|
||||
// Deletes |this|.
|
||||
factory_->RemoveRequest(network_service_request_id_, request_id_);
|
||||
@@ -677,6 +754,7 @@ ProxyingURLLoaderFactory::ProxyingURLLoaderFactory(
|
||||
const HandlersMap& intercepted_handlers,
|
||||
content::BrowserContext* browser_context,
|
||||
int render_process_id,
|
||||
uint64_t* request_id_generator,
|
||||
std::unique_ptr<extensions::ExtensionNavigationUIData> navigation_ui_data,
|
||||
base::Optional<int64_t> navigation_id,
|
||||
network::mojom::URLLoaderFactoryRequest loader_request,
|
||||
@@ -688,6 +766,7 @@ ProxyingURLLoaderFactory::ProxyingURLLoaderFactory(
|
||||
intercepted_handlers_(intercepted_handlers),
|
||||
browser_context_(browser_context),
|
||||
render_process_id_(render_process_id),
|
||||
request_id_generator_(request_id_generator),
|
||||
navigation_ui_data_(std::move(navigation_ui_data)),
|
||||
navigation_id_(std::move(navigation_id)),
|
||||
loader_factory_type_(loader_factory_type) {
|
||||
@@ -765,7 +844,7 @@ void ProxyingURLLoaderFactory::CreateLoaderAndStart(
|
||||
// per-BrowserContext so extensions can make sense of it. Note that
|
||||
// |network_service_request_id_| by contrast is not necessarily unique, so we
|
||||
// don't use it for identity here.
|
||||
const uint64_t web_request_id = ++g_request_id;
|
||||
const uint64_t web_request_id = ++(*request_id_generator_);
|
||||
|
||||
// Notes: Chromium assumes that requests with zero-ID would never use the
|
||||
// "extraHeaders" code path, however in Electron requests started from
|
||||
|
||||
@@ -23,53 +23,12 @@
|
||||
#include "services/network/public/mojom/network_context.mojom.h"
|
||||
#include "services/network/public/mojom/url_loader.mojom.h"
|
||||
#include "services/network/public/mojom/url_response_head.mojom.h"
|
||||
#include "shell/browser/api/electron_api_web_request.h"
|
||||
#include "shell/browser/net/electron_url_loader_factory.h"
|
||||
#include "shell/browser/net/web_request_api_interface.h"
|
||||
|
||||
namespace electron {
|
||||
|
||||
// Defines the interface for WebRequest API, implemented by api::WebRequest.
|
||||
class WebRequestAPI {
|
||||
public:
|
||||
virtual ~WebRequestAPI() {}
|
||||
|
||||
using BeforeSendHeadersCallback =
|
||||
base::OnceCallback<void(const std::set<std::string>& removed_headers,
|
||||
const std::set<std::string>& set_headers,
|
||||
int error_code)>;
|
||||
|
||||
virtual bool HasListener() const = 0;
|
||||
virtual int OnBeforeRequest(extensions::WebRequestInfo* info,
|
||||
const network::ResourceRequest& request,
|
||||
net::CompletionOnceCallback callback,
|
||||
GURL* new_url) = 0;
|
||||
virtual int OnBeforeSendHeaders(extensions::WebRequestInfo* info,
|
||||
const network::ResourceRequest& request,
|
||||
BeforeSendHeadersCallback callback,
|
||||
net::HttpRequestHeaders* headers) = 0;
|
||||
virtual int OnHeadersReceived(
|
||||
extensions::WebRequestInfo* info,
|
||||
const network::ResourceRequest& request,
|
||||
net::CompletionOnceCallback callback,
|
||||
const net::HttpResponseHeaders* original_response_headers,
|
||||
scoped_refptr<net::HttpResponseHeaders>* override_response_headers,
|
||||
GURL* allowed_unsafe_redirect_url) = 0;
|
||||
virtual void OnSendHeaders(extensions::WebRequestInfo* info,
|
||||
const network::ResourceRequest& request,
|
||||
const net::HttpRequestHeaders& headers) = 0;
|
||||
virtual void OnBeforeRedirect(extensions::WebRequestInfo* info,
|
||||
const network::ResourceRequest& request,
|
||||
const GURL& new_location) = 0;
|
||||
virtual void OnResponseStarted(extensions::WebRequestInfo* info,
|
||||
const network::ResourceRequest& request) = 0;
|
||||
virtual void OnErrorOccurred(extensions::WebRequestInfo* info,
|
||||
const network::ResourceRequest& request,
|
||||
int net_error) = 0;
|
||||
virtual void OnCompleted(extensions::WebRequestInfo* info,
|
||||
const network::ResourceRequest& request,
|
||||
int net_error) = 0;
|
||||
virtual void OnRequestWillBeDestroyed(extensions::WebRequestInfo* info) = 0;
|
||||
};
|
||||
|
||||
// This class is responsible for following tasks when NetworkService is enabled:
|
||||
// 1. handling intercepted protocols;
|
||||
// 2. implementing webRequest module;
|
||||
@@ -84,6 +43,7 @@ class ProxyingURLLoaderFactory
|
||||
public network::mojom::URLLoaderClient,
|
||||
public network::mojom::TrustedHeaderClient {
|
||||
public:
|
||||
// For usual requests.
|
||||
InProgressRequest(
|
||||
ProxyingURLLoaderFactory* factory,
|
||||
int64_t web_request_id,
|
||||
@@ -92,8 +52,12 @@ class ProxyingURLLoaderFactory
|
||||
uint32_t options,
|
||||
const network::ResourceRequest& request,
|
||||
const net::MutableNetworkTrafficAnnotationTag& traffic_annotation,
|
||||
network::mojom::URLLoaderRequest loader_request,
|
||||
mojo::PendingReceiver<network::mojom::URLLoader> loader_receiver,
|
||||
mojo::PendingRemote<network::mojom::URLLoaderClient> client);
|
||||
// For CORS preflights.
|
||||
InProgressRequest(ProxyingURLLoaderFactory* factory,
|
||||
uint64_t request_id,
|
||||
const network::ResourceRequest& request);
|
||||
~InProgressRequest() override;
|
||||
|
||||
void Restart();
|
||||
@@ -152,12 +116,12 @@ class ProxyingURLLoaderFactory
|
||||
ProxyingURLLoaderFactory* factory_;
|
||||
network::ResourceRequest request_;
|
||||
const base::Optional<url::Origin> original_initiator_;
|
||||
const uint64_t request_id_;
|
||||
const int32_t routing_id_;
|
||||
const int32_t network_service_request_id_;
|
||||
const uint32_t options_;
|
||||
const uint64_t request_id_ = 0;
|
||||
const int32_t routing_id_ = 0;
|
||||
const int32_t network_service_request_id_ = 0;
|
||||
const uint32_t options_ = 0;
|
||||
const net::MutableNetworkTrafficAnnotationTag traffic_annotation_;
|
||||
mojo::Binding<network::mojom::URLLoader> proxied_loader_binding_;
|
||||
mojo::Receiver<network::mojom::URLLoader> proxied_loader_receiver_;
|
||||
mojo::Remote<network::mojom::URLLoaderClient> target_client_;
|
||||
|
||||
base::Optional<extensions::WebRequestInfo> info_;
|
||||
@@ -170,7 +134,7 @@ class ProxyingURLLoaderFactory
|
||||
this};
|
||||
network::mojom::URLLoaderPtr target_loader_;
|
||||
|
||||
bool request_completed_ = false;
|
||||
const bool for_cors_preflight_ = false;
|
||||
|
||||
// If |has_any_extra_headers_listeners_| is set to true, the request will be
|
||||
// sent with the network::mojom::kURLLoadOptionUseHeaderClient option, and
|
||||
@@ -210,6 +174,7 @@ class ProxyingURLLoaderFactory
|
||||
const HandlersMap& intercepted_handlers,
|
||||
content::BrowserContext* browser_context,
|
||||
int render_process_id,
|
||||
uint64_t* request_id_generator,
|
||||
std::unique_ptr<extensions::ExtensionNavigationUIData> navigation_ui_data,
|
||||
base::Optional<int64_t> navigation_id,
|
||||
network::mojom::URLLoaderFactoryRequest loader_request,
|
||||
@@ -241,7 +206,7 @@ class ProxyingURLLoaderFactory
|
||||
void OnLoaderForCorsPreflightCreated(
|
||||
const network::ResourceRequest& request,
|
||||
mojo::PendingReceiver<network::mojom::TrustedHeaderClient> receiver)
|
||||
override {}
|
||||
override;
|
||||
|
||||
WebRequestAPI* web_request_api() { return web_request_api_; }
|
||||
|
||||
@@ -269,6 +234,7 @@ class ProxyingURLLoaderFactory
|
||||
|
||||
content::BrowserContext* const browser_context_;
|
||||
const int render_process_id_;
|
||||
uint64_t* request_id_generator_; // managed by AtomBrowserClient
|
||||
std::unique_ptr<extensions::ExtensionNavigationUIData> navigation_ui_data_;
|
||||
base::Optional<int64_t> navigation_id_;
|
||||
mojo::ReceiverSet<network::mojom::URLLoaderFactory> proxy_receivers_;
|
||||
|
||||
456
shell/browser/net/proxying_websocket.cc
Normal file
456
shell/browser/net/proxying_websocket.cc
Normal file
@@ -0,0 +1,456 @@
|
||||
// Copyright 2020 The Chromium Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "electron/shell/browser/net/proxying_websocket.h"
|
||||
|
||||
#include <utility>
|
||||
|
||||
#include "base/bind.h"
|
||||
#include "base/strings/string_util.h"
|
||||
#include "base/strings/stringprintf.h"
|
||||
#include "components/keyed_service/content/browser_context_keyed_service_shutdown_notifier_factory.h"
|
||||
#include "content/public/browser/browser_thread.h"
|
||||
#include "extensions/browser/extension_navigation_ui_data.h"
|
||||
#include "net/base/ip_endpoint.h"
|
||||
#include "net/http/http_util.h"
|
||||
|
||||
namespace electron {
|
||||
|
||||
ProxyingWebSocket::ProxyingWebSocket(
|
||||
WebRequestAPI* web_request_api,
|
||||
WebSocketFactory factory,
|
||||
const network::ResourceRequest& request,
|
||||
mojo::PendingRemote<network::mojom::WebSocketHandshakeClient>
|
||||
handshake_client,
|
||||
bool has_extra_headers,
|
||||
int process_id,
|
||||
int render_frame_id,
|
||||
content::BrowserContext* browser_context,
|
||||
uint64_t* request_id_generator)
|
||||
: web_request_api_(web_request_api),
|
||||
request_(request),
|
||||
factory_(std::move(factory)),
|
||||
forwarding_handshake_client_(std::move(handshake_client)),
|
||||
request_headers_(request.headers),
|
||||
response_(network::mojom::URLResponseHead::New()),
|
||||
has_extra_headers_(has_extra_headers),
|
||||
info_(extensions::WebRequestInfoInitParams(
|
||||
++(*request_id_generator),
|
||||
process_id,
|
||||
render_frame_id,
|
||||
nullptr,
|
||||
MSG_ROUTING_NONE,
|
||||
request,
|
||||
/*is_download=*/false,
|
||||
/*is_async=*/true,
|
||||
/*is_service_worker_script=*/false,
|
||||
/*navigation_id=*/base::nullopt)) {}
|
||||
|
||||
ProxyingWebSocket::~ProxyingWebSocket() {
|
||||
if (on_before_send_headers_callback_) {
|
||||
std::move(on_before_send_headers_callback_)
|
||||
.Run(net::ERR_ABORTED, base::nullopt);
|
||||
}
|
||||
if (on_headers_received_callback_) {
|
||||
std::move(on_headers_received_callback_)
|
||||
.Run(net::ERR_ABORTED, base::nullopt, GURL());
|
||||
}
|
||||
}
|
||||
|
||||
void ProxyingWebSocket::Start() {
|
||||
// If the header client will be used, we start the request immediately, and
|
||||
// OnBeforeSendHeaders and OnSendHeaders will be handled there. Otherwise,
|
||||
// send these events before the request starts.
|
||||
base::RepeatingCallback<void(int)> continuation;
|
||||
if (has_extra_headers_) {
|
||||
continuation = base::BindRepeating(
|
||||
&ProxyingWebSocket::ContinueToStartRequest, weak_factory_.GetWeakPtr());
|
||||
} else {
|
||||
continuation =
|
||||
base::BindRepeating(&ProxyingWebSocket::OnBeforeRequestComplete,
|
||||
weak_factory_.GetWeakPtr());
|
||||
}
|
||||
|
||||
int result = web_request_api_->OnBeforeRequest(&info_, request_, continuation,
|
||||
&redirect_url_);
|
||||
|
||||
if (result == net::ERR_BLOCKED_BY_CLIENT) {
|
||||
OnError(result);
|
||||
return;
|
||||
}
|
||||
|
||||
if (result == net::ERR_IO_PENDING) {
|
||||
return;
|
||||
}
|
||||
|
||||
DCHECK_EQ(net::OK, result);
|
||||
continuation.Run(net::OK);
|
||||
}
|
||||
|
||||
void ProxyingWebSocket::OnOpeningHandshakeStarted(
|
||||
network::mojom::WebSocketHandshakeRequestPtr request) {
|
||||
DCHECK(forwarding_handshake_client_);
|
||||
forwarding_handshake_client_->OnOpeningHandshakeStarted(std::move(request));
|
||||
}
|
||||
|
||||
void ProxyingWebSocket::ContinueToHeadersReceived() {
|
||||
auto continuation =
|
||||
base::BindRepeating(&ProxyingWebSocket::OnHeadersReceivedComplete,
|
||||
weak_factory_.GetWeakPtr());
|
||||
info_.AddResponseInfoFromResourceResponse(*response_);
|
||||
int result = web_request_api_->OnHeadersReceived(
|
||||
&info_, request_, continuation, response_->headers.get(),
|
||||
&override_headers_, &redirect_url_);
|
||||
|
||||
if (result == net::ERR_BLOCKED_BY_CLIENT) {
|
||||
OnError(result);
|
||||
return;
|
||||
}
|
||||
|
||||
PauseIncomingMethodCallProcessing();
|
||||
if (result == net::ERR_IO_PENDING)
|
||||
return;
|
||||
|
||||
DCHECK_EQ(net::OK, result);
|
||||
OnHeadersReceivedComplete(net::OK);
|
||||
}
|
||||
|
||||
void ProxyingWebSocket::OnConnectionEstablished(
|
||||
mojo::PendingRemote<network::mojom::WebSocket> websocket,
|
||||
mojo::PendingReceiver<network::mojom::WebSocketClient> client_receiver,
|
||||
network::mojom::WebSocketHandshakeResponsePtr response,
|
||||
mojo::ScopedDataPipeConsumerHandle readable) {
|
||||
DCHECK(forwarding_handshake_client_);
|
||||
DCHECK(!is_done_);
|
||||
is_done_ = true;
|
||||
websocket_ = std::move(websocket);
|
||||
client_receiver_ = std::move(client_receiver);
|
||||
handshake_response_ = std::move(response);
|
||||
readable_ = std::move(readable);
|
||||
|
||||
response_->remote_endpoint = handshake_response_->remote_endpoint;
|
||||
|
||||
// response_->headers will be set in OnBeforeSendHeaders if
|
||||
// |receiver_as_header_client_| is set.
|
||||
if (receiver_as_header_client_.is_bound()) {
|
||||
ContinueToCompleted();
|
||||
return;
|
||||
}
|
||||
|
||||
response_->headers =
|
||||
base::MakeRefCounted<net::HttpResponseHeaders>(base::StringPrintf(
|
||||
"HTTP/%d.%d %d %s", handshake_response_->http_version.major_value(),
|
||||
handshake_response_->http_version.minor_value(),
|
||||
handshake_response_->status_code,
|
||||
handshake_response_->status_text.c_str()));
|
||||
for (const auto& header : handshake_response_->headers)
|
||||
response_->headers->AddHeader(header->name + ": " + header->value);
|
||||
|
||||
ContinueToHeadersReceived();
|
||||
}
|
||||
|
||||
void ProxyingWebSocket::ContinueToCompleted() {
|
||||
DCHECK(forwarding_handshake_client_);
|
||||
DCHECK(is_done_);
|
||||
web_request_api_->OnCompleted(&info_, request_, net::ERR_WS_UPGRADE);
|
||||
forwarding_handshake_client_->OnConnectionEstablished(
|
||||
std::move(websocket_), std::move(client_receiver_),
|
||||
std::move(handshake_response_), std::move(readable_));
|
||||
|
||||
// Deletes |this|.
|
||||
delete this;
|
||||
}
|
||||
|
||||
void ProxyingWebSocket::OnAuthRequired(
|
||||
const net::AuthChallengeInfo& auth_info,
|
||||
const scoped_refptr<net::HttpResponseHeaders>& headers,
|
||||
const net::IPEndPoint& remote_endpoint,
|
||||
OnAuthRequiredCallback callback) {
|
||||
if (!callback) {
|
||||
OnError(net::ERR_FAILED);
|
||||
return;
|
||||
}
|
||||
|
||||
response_->headers = headers;
|
||||
response_->remote_endpoint = remote_endpoint;
|
||||
auth_required_callback_ = std::move(callback);
|
||||
|
||||
auto continuation =
|
||||
base::BindRepeating(&ProxyingWebSocket::OnHeadersReceivedCompleteForAuth,
|
||||
weak_factory_.GetWeakPtr(), auth_info);
|
||||
info_.AddResponseInfoFromResourceResponse(*response_);
|
||||
int result = web_request_api_->OnHeadersReceived(
|
||||
&info_, request_, continuation, response_->headers.get(),
|
||||
&override_headers_, &redirect_url_);
|
||||
|
||||
if (result == net::ERR_BLOCKED_BY_CLIENT) {
|
||||
OnError(result);
|
||||
return;
|
||||
}
|
||||
|
||||
PauseIncomingMethodCallProcessing();
|
||||
if (result == net::ERR_IO_PENDING)
|
||||
return;
|
||||
|
||||
DCHECK_EQ(net::OK, result);
|
||||
OnHeadersReceivedCompleteForAuth(auth_info, net::OK);
|
||||
}
|
||||
|
||||
void ProxyingWebSocket::OnBeforeSendHeaders(
|
||||
const net::HttpRequestHeaders& headers,
|
||||
OnBeforeSendHeadersCallback callback) {
|
||||
DCHECK(receiver_as_header_client_.is_bound());
|
||||
|
||||
request_headers_ = headers;
|
||||
on_before_send_headers_callback_ = std::move(callback);
|
||||
OnBeforeRequestComplete(net::OK);
|
||||
}
|
||||
|
||||
void ProxyingWebSocket::OnHeadersReceived(const std::string& headers,
|
||||
const net::IPEndPoint& endpoint,
|
||||
OnHeadersReceivedCallback callback) {
|
||||
DCHECK(receiver_as_header_client_.is_bound());
|
||||
|
||||
on_headers_received_callback_ = std::move(callback);
|
||||
response_->headers = base::MakeRefCounted<net::HttpResponseHeaders>(headers);
|
||||
|
||||
ContinueToHeadersReceived();
|
||||
}
|
||||
|
||||
void ProxyingWebSocket::StartProxying(
|
||||
WebRequestAPI* web_request_api,
|
||||
WebSocketFactory factory,
|
||||
const GURL& url,
|
||||
const GURL& site_for_cookies,
|
||||
const base::Optional<std::string>& user_agent,
|
||||
mojo::PendingRemote<network::mojom::WebSocketHandshakeClient>
|
||||
handshake_client,
|
||||
bool has_extra_headers,
|
||||
int process_id,
|
||||
int render_frame_id,
|
||||
const url::Origin& origin,
|
||||
content::BrowserContext* browser_context,
|
||||
uint64_t* request_id_generator) {
|
||||
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
|
||||
network::ResourceRequest request;
|
||||
request.url = url;
|
||||
request.site_for_cookies = net::SiteForCookies::FromUrl(site_for_cookies);
|
||||
if (user_agent) {
|
||||
request.headers.SetHeader(net::HttpRequestHeaders::kUserAgent, *user_agent);
|
||||
}
|
||||
request.request_initiator = origin;
|
||||
|
||||
auto* proxy = new ProxyingWebSocket(
|
||||
web_request_api, std::move(factory), request, std::move(handshake_client),
|
||||
has_extra_headers, process_id, render_frame_id, browser_context,
|
||||
request_id_generator);
|
||||
proxy->Start();
|
||||
}
|
||||
|
||||
void ProxyingWebSocket::OnBeforeRequestComplete(int error_code) {
|
||||
DCHECK(receiver_as_header_client_.is_bound() ||
|
||||
!receiver_as_handshake_client_.is_bound());
|
||||
DCHECK(info_.url.SchemeIsWSOrWSS());
|
||||
if (error_code != net::OK) {
|
||||
OnError(error_code);
|
||||
return;
|
||||
}
|
||||
|
||||
auto continuation =
|
||||
base::BindRepeating(&ProxyingWebSocket::OnBeforeSendHeadersComplete,
|
||||
weak_factory_.GetWeakPtr());
|
||||
|
||||
info_.AddResponseInfoFromResourceResponse(*response_);
|
||||
int result = web_request_api_->OnBeforeSendHeaders(
|
||||
&info_, request_, continuation, &request_headers_);
|
||||
|
||||
if (result == net::ERR_BLOCKED_BY_CLIENT) {
|
||||
OnError(result);
|
||||
return;
|
||||
}
|
||||
|
||||
if (result == net::ERR_IO_PENDING)
|
||||
return;
|
||||
|
||||
DCHECK_EQ(net::OK, result);
|
||||
OnBeforeSendHeadersComplete(std::set<std::string>(), std::set<std::string>(),
|
||||
net::OK);
|
||||
}
|
||||
|
||||
void ProxyingWebSocket::OnBeforeSendHeadersComplete(
|
||||
const std::set<std::string>& removed_headers,
|
||||
const std::set<std::string>& set_headers,
|
||||
int error_code) {
|
||||
DCHECK(receiver_as_header_client_.is_bound() ||
|
||||
!receiver_as_handshake_client_.is_bound());
|
||||
if (error_code != net::OK) {
|
||||
OnError(error_code);
|
||||
return;
|
||||
}
|
||||
|
||||
if (receiver_as_header_client_.is_bound()) {
|
||||
CHECK(on_before_send_headers_callback_);
|
||||
std::move(on_before_send_headers_callback_)
|
||||
.Run(error_code, request_headers_);
|
||||
}
|
||||
|
||||
info_.AddResponseInfoFromResourceResponse(*response_);
|
||||
web_request_api_->OnSendHeaders(&info_, request_, request_headers_);
|
||||
|
||||
if (!receiver_as_header_client_.is_bound())
|
||||
ContinueToStartRequest(net::OK);
|
||||
}
|
||||
|
||||
void ProxyingWebSocket::ContinueToStartRequest(int error_code) {
|
||||
if (error_code != net::OK) {
|
||||
OnError(error_code);
|
||||
return;
|
||||
}
|
||||
|
||||
base::flat_set<std::string> used_header_names;
|
||||
std::vector<network::mojom::HttpHeaderPtr> additional_headers;
|
||||
for (net::HttpRequestHeaders::Iterator it(request_headers_); it.GetNext();) {
|
||||
additional_headers.push_back(
|
||||
network::mojom::HttpHeader::New(it.name(), it.value()));
|
||||
used_header_names.insert(base::ToLowerASCII(it.name()));
|
||||
}
|
||||
for (const auto& header : additional_headers_) {
|
||||
if (!used_header_names.contains(base::ToLowerASCII(header->name))) {
|
||||
additional_headers.push_back(
|
||||
network::mojom::HttpHeader::New(header->name, header->value));
|
||||
}
|
||||
}
|
||||
|
||||
mojo::PendingRemote<network::mojom::TrustedHeaderClient>
|
||||
trusted_header_client = mojo::NullRemote();
|
||||
if (has_extra_headers_) {
|
||||
trusted_header_client =
|
||||
receiver_as_header_client_.BindNewPipeAndPassRemote();
|
||||
}
|
||||
|
||||
std::move(factory_).Run(
|
||||
info_.url, std::move(additional_headers),
|
||||
receiver_as_handshake_client_.BindNewPipeAndPassRemote(),
|
||||
receiver_as_auth_handler_.BindNewPipeAndPassRemote(),
|
||||
std::move(trusted_header_client));
|
||||
|
||||
// Here we detect mojo connection errors on |receiver_as_handshake_client_|.
|
||||
// See also CreateWebSocket in
|
||||
// //network/services/public/mojom/network_context.mojom.
|
||||
receiver_as_handshake_client_.set_disconnect_with_reason_handler(
|
||||
base::BindOnce(&ProxyingWebSocket::OnMojoConnectionErrorWithCustomReason,
|
||||
base::Unretained(this)));
|
||||
forwarding_handshake_client_.set_disconnect_handler(base::BindOnce(
|
||||
&ProxyingWebSocket::OnMojoConnectionError, base::Unretained(this)));
|
||||
}
|
||||
|
||||
void ProxyingWebSocket::OnHeadersReceivedComplete(int error_code) {
|
||||
if (error_code != net::OK) {
|
||||
OnError(error_code);
|
||||
return;
|
||||
}
|
||||
|
||||
if (on_headers_received_callback_) {
|
||||
base::Optional<std::string> headers;
|
||||
if (override_headers_)
|
||||
headers = override_headers_->raw_headers();
|
||||
std::move(on_headers_received_callback_)
|
||||
.Run(net::OK, headers, base::nullopt);
|
||||
}
|
||||
|
||||
if (override_headers_) {
|
||||
response_->headers = override_headers_;
|
||||
override_headers_ = nullptr;
|
||||
}
|
||||
|
||||
ResumeIncomingMethodCallProcessing();
|
||||
info_.AddResponseInfoFromResourceResponse(*response_);
|
||||
web_request_api_->OnResponseStarted(&info_, request_);
|
||||
|
||||
if (!receiver_as_header_client_.is_bound())
|
||||
ContinueToCompleted();
|
||||
}
|
||||
|
||||
void ProxyingWebSocket::OnAuthRequiredComplete(
|
||||
extensions::ExtensionWebRequestEventRouter::AuthRequiredResponse rv) {
|
||||
CHECK(auth_required_callback_);
|
||||
ResumeIncomingMethodCallProcessing();
|
||||
switch (rv) {
|
||||
case extensions::ExtensionWebRequestEventRouter::AuthRequiredResponse::
|
||||
AUTH_REQUIRED_RESPONSE_NO_ACTION:
|
||||
case extensions::ExtensionWebRequestEventRouter::AuthRequiredResponse::
|
||||
AUTH_REQUIRED_RESPONSE_CANCEL_AUTH:
|
||||
std::move(auth_required_callback_).Run(base::nullopt);
|
||||
break;
|
||||
|
||||
case extensions::ExtensionWebRequestEventRouter::AuthRequiredResponse::
|
||||
AUTH_REQUIRED_RESPONSE_SET_AUTH:
|
||||
std::move(auth_required_callback_).Run(auth_credentials_);
|
||||
break;
|
||||
case extensions::ExtensionWebRequestEventRouter::AuthRequiredResponse::
|
||||
AUTH_REQUIRED_RESPONSE_IO_PENDING:
|
||||
NOTREACHED();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void ProxyingWebSocket::OnHeadersReceivedCompleteForAuth(
|
||||
const net::AuthChallengeInfo& auth_info,
|
||||
int rv) {
|
||||
if (rv != net::OK) {
|
||||
OnError(rv);
|
||||
return;
|
||||
}
|
||||
ResumeIncomingMethodCallProcessing();
|
||||
info_.AddResponseInfoFromResourceResponse(*response_);
|
||||
|
||||
auto continuation = base::BindRepeating(
|
||||
&ProxyingWebSocket::OnAuthRequiredComplete, weak_factory_.GetWeakPtr());
|
||||
auto auth_rv = extensions::ExtensionWebRequestEventRouter::
|
||||
AuthRequiredResponse::AUTH_REQUIRED_RESPONSE_IO_PENDING;
|
||||
PauseIncomingMethodCallProcessing();
|
||||
|
||||
OnAuthRequiredComplete(auth_rv);
|
||||
}
|
||||
|
||||
void ProxyingWebSocket::PauseIncomingMethodCallProcessing() {
|
||||
receiver_as_handshake_client_.Pause();
|
||||
receiver_as_auth_handler_.Pause();
|
||||
if (receiver_as_header_client_.is_bound())
|
||||
receiver_as_header_client_.Pause();
|
||||
}
|
||||
|
||||
void ProxyingWebSocket::ResumeIncomingMethodCallProcessing() {
|
||||
receiver_as_handshake_client_.Resume();
|
||||
receiver_as_auth_handler_.Resume();
|
||||
if (receiver_as_header_client_.is_bound())
|
||||
receiver_as_header_client_.Resume();
|
||||
}
|
||||
|
||||
void ProxyingWebSocket::OnError(int error_code) {
|
||||
if (!is_done_) {
|
||||
is_done_ = true;
|
||||
web_request_api_->OnErrorOccurred(&info_, request_, error_code);
|
||||
}
|
||||
|
||||
// Deletes |this|.
|
||||
delete this;
|
||||
}
|
||||
|
||||
void ProxyingWebSocket::OnMojoConnectionErrorWithCustomReason(
|
||||
uint32_t custom_reason,
|
||||
const std::string& description) {
|
||||
// Here we want to nofiy the custom reason to the client, which is why
|
||||
// we reset |forwarding_handshake_client_| manually.
|
||||
forwarding_handshake_client_.ResetWithReason(custom_reason, description);
|
||||
OnError(net::ERR_FAILED);
|
||||
// Deletes |this|.
|
||||
}
|
||||
|
||||
void ProxyingWebSocket::OnMojoConnectionError() {
|
||||
OnError(net::ERR_FAILED);
|
||||
// Deletes |this|.
|
||||
}
|
||||
|
||||
} // namespace electron
|
||||
165
shell/browser/net/proxying_websocket.h
Normal file
165
shell/browser/net/proxying_websocket.h
Normal file
@@ -0,0 +1,165 @@
|
||||
// Copyright 2020 The Chromium Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef SHELL_BROWSER_NET_PROXYING_WEBSOCKET_H_
|
||||
#define SHELL_BROWSER_NET_PROXYING_WEBSOCKET_H_
|
||||
|
||||
#include <memory>
|
||||
#include <set>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "base/optional.h"
|
||||
#include "components/keyed_service/core/keyed_service_shutdown_notifier.h"
|
||||
#include "extensions/browser/api/web_request/web_request_api.h"
|
||||
#include "extensions/browser/api/web_request/web_request_info.h"
|
||||
#include "mojo/public/cpp/bindings/pending_receiver.h"
|
||||
#include "mojo/public/cpp/bindings/receiver.h"
|
||||
#include "mojo/public/cpp/bindings/remote.h"
|
||||
#include "services/network/public/cpp/resource_request.h"
|
||||
#include "services/network/public/mojom/network_context.mojom.h"
|
||||
#include "services/network/public/mojom/websocket.mojom.h"
|
||||
#include "shell/browser/net/web_request_api_interface.h"
|
||||
#include "url/gurl.h"
|
||||
#include "url/origin.h"
|
||||
|
||||
namespace electron {
|
||||
|
||||
// A ProxyingWebSocket proxies a WebSocket connection and dispatches
|
||||
// WebRequest API events.
|
||||
//
|
||||
// The code is referenced from the
|
||||
// extensions::WebRequestProxyingWebSocket class.
|
||||
class ProxyingWebSocket : public network::mojom::WebSocketHandshakeClient,
|
||||
public network::mojom::AuthenticationHandler,
|
||||
public network::mojom::TrustedHeaderClient {
|
||||
public:
|
||||
using WebSocketFactory = content::ContentBrowserClient::WebSocketFactory;
|
||||
|
||||
ProxyingWebSocket(
|
||||
WebRequestAPI* web_request_api,
|
||||
WebSocketFactory factory,
|
||||
const network::ResourceRequest& request,
|
||||
mojo::PendingRemote<network::mojom::WebSocketHandshakeClient>
|
||||
handshake_client,
|
||||
bool has_extra_headers,
|
||||
int process_id,
|
||||
int render_frame_id,
|
||||
content::BrowserContext* browser_context,
|
||||
uint64_t* request_id_generator);
|
||||
~ProxyingWebSocket() override;
|
||||
|
||||
void Start();
|
||||
|
||||
// network::mojom::WebSocketHandshakeClient methods:
|
||||
void OnOpeningHandshakeStarted(
|
||||
network::mojom::WebSocketHandshakeRequestPtr request) override;
|
||||
void OnConnectionEstablished(
|
||||
mojo::PendingRemote<network::mojom::WebSocket> websocket,
|
||||
mojo::PendingReceiver<network::mojom::WebSocketClient> client_receiver,
|
||||
network::mojom::WebSocketHandshakeResponsePtr response,
|
||||
mojo::ScopedDataPipeConsumerHandle readable) override;
|
||||
|
||||
// network::mojom::AuthenticationHandler method:
|
||||
void OnAuthRequired(const net::AuthChallengeInfo& auth_info,
|
||||
const scoped_refptr<net::HttpResponseHeaders>& headers,
|
||||
const net::IPEndPoint& remote_endpoint,
|
||||
OnAuthRequiredCallback callback) override;
|
||||
|
||||
// network::mojom::TrustedHeaderClient methods:
|
||||
void OnBeforeSendHeaders(const net::HttpRequestHeaders& headers,
|
||||
OnBeforeSendHeadersCallback callback) override;
|
||||
void OnHeadersReceived(const std::string& headers,
|
||||
const net::IPEndPoint& endpoint,
|
||||
OnHeadersReceivedCallback callback) override;
|
||||
|
||||
static void StartProxying(
|
||||
WebRequestAPI* web_request_api,
|
||||
WebSocketFactory factory,
|
||||
const GURL& url,
|
||||
const GURL& site_for_cookies,
|
||||
const base::Optional<std::string>& user_agent,
|
||||
mojo::PendingRemote<network::mojom::WebSocketHandshakeClient>
|
||||
handshake_client,
|
||||
bool has_extra_headers,
|
||||
int process_id,
|
||||
int render_frame_id,
|
||||
const url::Origin& origin,
|
||||
content::BrowserContext* browser_context,
|
||||
uint64_t* request_id_generator);
|
||||
|
||||
WebRequestAPI* web_request_api() { return web_request_api_; }
|
||||
|
||||
private:
|
||||
void OnBeforeRequestComplete(int error_code);
|
||||
void OnBeforeSendHeadersComplete(const std::set<std::string>& removed_headers,
|
||||
const std::set<std::string>& set_headers,
|
||||
int error_code);
|
||||
void ContinueToStartRequest(int error_code);
|
||||
void OnHeadersReceivedComplete(int error_code);
|
||||
void ContinueToHeadersReceived();
|
||||
void OnAuthRequiredComplete(
|
||||
extensions::ExtensionWebRequestEventRouter::AuthRequiredResponse rv);
|
||||
void OnHeadersReceivedCompleteForAuth(const net::AuthChallengeInfo& auth_info,
|
||||
int rv);
|
||||
void ContinueToCompleted();
|
||||
|
||||
void PauseIncomingMethodCallProcessing();
|
||||
void ResumeIncomingMethodCallProcessing();
|
||||
void OnError(int result);
|
||||
// This is used for detecting errors on mojo connection with the network
|
||||
// service.
|
||||
void OnMojoConnectionErrorWithCustomReason(uint32_t custom_reason,
|
||||
const std::string& description);
|
||||
// This is used for detecting errors on mojo connection with original client
|
||||
// (i.e., renderer).
|
||||
void OnMojoConnectionError();
|
||||
|
||||
// Passed from api::WebRequest.
|
||||
WebRequestAPI* web_request_api_;
|
||||
|
||||
// Saved to feed the api::WebRequest.
|
||||
network::ResourceRequest request_;
|
||||
|
||||
WebSocketFactory factory_;
|
||||
mojo::Remote<network::mojom::WebSocketHandshakeClient>
|
||||
forwarding_handshake_client_;
|
||||
mojo::Receiver<network::mojom::WebSocketHandshakeClient>
|
||||
receiver_as_handshake_client_{this};
|
||||
mojo::Receiver<network::mojom::AuthenticationHandler>
|
||||
receiver_as_auth_handler_{this};
|
||||
mojo::Receiver<network::mojom::TrustedHeaderClient>
|
||||
receiver_as_header_client_{this};
|
||||
|
||||
net::HttpRequestHeaders request_headers_;
|
||||
network::mojom::URLResponseHeadPtr response_;
|
||||
net::AuthCredentials auth_credentials_;
|
||||
OnAuthRequiredCallback auth_required_callback_;
|
||||
scoped_refptr<net::HttpResponseHeaders> override_headers_;
|
||||
std::vector<network::mojom::HttpHeaderPtr> additional_headers_;
|
||||
|
||||
OnBeforeSendHeadersCallback on_before_send_headers_callback_;
|
||||
OnHeadersReceivedCallback on_headers_received_callback_;
|
||||
|
||||
GURL redirect_url_;
|
||||
bool is_done_ = false;
|
||||
bool has_extra_headers_;
|
||||
mojo::PendingRemote<network::mojom::WebSocket> websocket_;
|
||||
mojo::PendingReceiver<network::mojom::WebSocketClient> client_receiver_;
|
||||
network::mojom::WebSocketHandshakeResponsePtr handshake_response_ = nullptr;
|
||||
mojo::ScopedDataPipeConsumerHandle readable_;
|
||||
|
||||
extensions::WebRequestInfo info_;
|
||||
|
||||
// Notifies the proxy that the browser context has been shutdown.
|
||||
std::unique_ptr<KeyedServiceShutdownNotifier::Subscription>
|
||||
shutdown_notifier_;
|
||||
|
||||
base::WeakPtrFactory<ProxyingWebSocket> weak_factory_{this};
|
||||
DISALLOW_COPY_AND_ASSIGN(ProxyingWebSocket);
|
||||
};
|
||||
|
||||
} // namespace electron
|
||||
|
||||
#endif // SHELL_BROWSER_NET_PROXYING_WEBSOCKET_H_
|
||||
@@ -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;
|
||||
|
||||
61
shell/browser/net/web_request_api_interface.h
Normal file
61
shell/browser/net/web_request_api_interface.h
Normal file
@@ -0,0 +1,61 @@
|
||||
// Copyright (c) 2020 GitHub, Inc.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef SHELL_BROWSER_NET_WEB_REQUEST_API_INTERFACE_H_
|
||||
#define SHELL_BROWSER_NET_WEB_REQUEST_API_INTERFACE_H_
|
||||
|
||||
#include <set>
|
||||
#include <string>
|
||||
|
||||
#include "extensions/browser/api/web_request/web_request_info.h"
|
||||
#include "services/network/public/cpp/resource_request.h"
|
||||
|
||||
namespace electron {
|
||||
|
||||
// Defines the interface for WebRequest API, implemented by api::WebRequestNS.
|
||||
class WebRequestAPI {
|
||||
public:
|
||||
virtual ~WebRequestAPI() {}
|
||||
|
||||
using BeforeSendHeadersCallback =
|
||||
base::OnceCallback<void(const std::set<std::string>& removed_headers,
|
||||
const std::set<std::string>& set_headers,
|
||||
int error_code)>;
|
||||
|
||||
virtual bool HasListener() const = 0;
|
||||
virtual int OnBeforeRequest(extensions::WebRequestInfo* info,
|
||||
const network::ResourceRequest& request,
|
||||
net::CompletionOnceCallback callback,
|
||||
GURL* new_url) = 0;
|
||||
virtual int OnBeforeSendHeaders(extensions::WebRequestInfo* info,
|
||||
const network::ResourceRequest& request,
|
||||
BeforeSendHeadersCallback callback,
|
||||
net::HttpRequestHeaders* headers) = 0;
|
||||
virtual int OnHeadersReceived(
|
||||
extensions::WebRequestInfo* info,
|
||||
const network::ResourceRequest& request,
|
||||
net::CompletionOnceCallback callback,
|
||||
const net::HttpResponseHeaders* original_response_headers,
|
||||
scoped_refptr<net::HttpResponseHeaders>* override_response_headers,
|
||||
GURL* allowed_unsafe_redirect_url) = 0;
|
||||
virtual void OnSendHeaders(extensions::WebRequestInfo* info,
|
||||
const network::ResourceRequest& request,
|
||||
const net::HttpRequestHeaders& headers) = 0;
|
||||
virtual void OnBeforeRedirect(extensions::WebRequestInfo* info,
|
||||
const network::ResourceRequest& request,
|
||||
const GURL& new_location) = 0;
|
||||
virtual void OnResponseStarted(extensions::WebRequestInfo* info,
|
||||
const network::ResourceRequest& request) = 0;
|
||||
virtual void OnErrorOccurred(extensions::WebRequestInfo* info,
|
||||
const network::ResourceRequest& request,
|
||||
int net_error) = 0;
|
||||
virtual void OnCompleted(extensions::WebRequestInfo* info,
|
||||
const network::ResourceRequest& request,
|
||||
int net_error) = 0;
|
||||
virtual void OnRequestWillBeDestroyed(extensions::WebRequestInfo* info) = 0;
|
||||
};
|
||||
|
||||
} // namespace electron
|
||||
|
||||
#endif // SHELL_BROWSER_NET_WEB_REQUEST_API_INTERFACE_H_
|
||||
63
shell/browser/plugins/plugin_utils.cc
Normal file
63
shell/browser/plugins/plugin_utils.cc
Normal file
@@ -0,0 +1,63 @@
|
||||
// Copyright 2016 The Chromium Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "shell/browser/plugins/plugin_utils.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "base/values.h"
|
||||
#include "content/public/common/webplugininfo.h"
|
||||
#include "extensions/buildflags/buildflags.h"
|
||||
#include "url/gurl.h"
|
||||
#include "url/origin.h"
|
||||
|
||||
#if BUILDFLAG(ENABLE_EXTENSIONS)
|
||||
#include "extensions/browser/extension_registry.h"
|
||||
#include "extensions/browser/extension_util.h"
|
||||
#include "extensions/common/constants.h"
|
||||
#include "extensions/common/extension.h"
|
||||
#include "extensions/common/manifest_handlers/mime_types_handler.h"
|
||||
#endif
|
||||
|
||||
// static
|
||||
std::string PluginUtils::GetExtensionIdForMimeType(
|
||||
content::BrowserContext* browser_context,
|
||||
const std::string& mime_type) {
|
||||
auto map = GetMimeTypeToExtensionIdMap(browser_context);
|
||||
auto it = map.find(mime_type);
|
||||
if (it != map.end())
|
||||
return it->second;
|
||||
return std::string();
|
||||
}
|
||||
|
||||
base::flat_map<std::string, std::string>
|
||||
PluginUtils::GetMimeTypeToExtensionIdMap(
|
||||
content::BrowserContext* browser_context) {
|
||||
base::flat_map<std::string, std::string> mime_type_to_extension_id_map;
|
||||
#if BUILDFLAG(ENABLE_EXTENSIONS)
|
||||
std::vector<std::string> whitelist = MimeTypesHandler::GetMIMETypeWhitelist();
|
||||
// Go through the white-listed extensions and try to use them to intercept
|
||||
// the URL request.
|
||||
for (const std::string& extension_id : whitelist) {
|
||||
const extensions::Extension* extension =
|
||||
extensions::ExtensionRegistry::Get(browser_context)
|
||||
->enabled_extensions()
|
||||
.GetByID(extension_id);
|
||||
// The white-listed extension may not be installed, so we have to nullptr
|
||||
// check |extension|.
|
||||
if (!extension) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (MimeTypesHandler* handler = MimeTypesHandler::GetHandler(extension)) {
|
||||
for (const auto& supported_mime_type : handler->mime_type_set()) {
|
||||
DCHECK(!base::Contains(mime_type_to_extension_id_map,
|
||||
supported_mime_type));
|
||||
mime_type_to_extension_id_map[supported_mime_type] = extension_id;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return mime_type_to_extension_id_map;
|
||||
}
|
||||
34
shell/browser/plugins/plugin_utils.h
Normal file
34
shell/browser/plugins/plugin_utils.h
Normal file
@@ -0,0 +1,34 @@
|
||||
// Copyright 2016 The Chromium Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef SHELL_BROWSER_PLUGINS_PLUGIN_UTILS_H_
|
||||
#define SHELL_BROWSER_PLUGINS_PLUGIN_UTILS_H_
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "base/containers/flat_map.h"
|
||||
#include "base/macros.h"
|
||||
|
||||
namespace content {
|
||||
class BrowserContext;
|
||||
}
|
||||
|
||||
class PluginUtils {
|
||||
public:
|
||||
// If there's an extension that is allowed to handle |mime_type|, returns its
|
||||
// ID. Otherwise returns an empty string.
|
||||
static std::string GetExtensionIdForMimeType(
|
||||
content::BrowserContext* browser_context,
|
||||
const std::string& mime_type);
|
||||
|
||||
// Returns a map populated with MIME types that are handled by an extension as
|
||||
// keys and the corresponding extensions Ids as values.
|
||||
static base::flat_map<std::string, std::string> GetMimeTypeToExtensionIdMap(
|
||||
content::BrowserContext* browser_context);
|
||||
|
||||
private:
|
||||
DISALLOW_IMPLICIT_CONSTRUCTORS(PluginUtils);
|
||||
};
|
||||
|
||||
#endif // SHELL_BROWSER_PLUGINS_PLUGIN_UTILS_H_
|
||||
@@ -27,7 +27,7 @@
|
||||
<key>NSMainNibFile</key>
|
||||
<string>MainMenu</string>
|
||||
<key>NSPrincipalClass</key>
|
||||
<string>ElectronApplication</string>
|
||||
<string>AtomApplication</string>
|
||||
<key>NSSupportsAutomaticGraphicsSwitching</key>
|
||||
<true/>
|
||||
<key>NSHighResolutionCapable</key>
|
||||
|
||||
@@ -50,8 +50,8 @@ END
|
||||
//
|
||||
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
FILEVERSION 9,0,0,20200205
|
||||
PRODUCTVERSION 9,0,0,20200205
|
||||
FILEVERSION 9,0,0,5
|
||||
PRODUCTVERSION 9,0,0,5
|
||||
FILEFLAGSMASK 0x3fL
|
||||
#ifdef _DEBUG
|
||||
FILEFLAGS 0x1L
|
||||
|
||||
@@ -121,7 +121,18 @@ bool ScopedDisableResize::disable_resize_ = false;
|
||||
[NSButtonCell class], @"RenderWidgetHostViewCocoa"];
|
||||
|
||||
NSArray* children = [super accessibilityAttributeValue:attribute];
|
||||
return [children filteredArrayUsingPredicate:predicate];
|
||||
NSMutableArray* mutableChildren = [[children mutableCopy] autorelease];
|
||||
[mutableChildren filterUsingPredicate:predicate];
|
||||
|
||||
// We need to add the web contents: Without us doing so, VoiceOver
|
||||
// users will be able to navigate up the a11y tree, but not back down.
|
||||
// The content view contains the "web contents", which VoiceOver
|
||||
// immediately understands.
|
||||
NSView* contentView =
|
||||
[shell_->GetNativeWindow().GetNativeNSWindow() contentView];
|
||||
[mutableChildren addObject:contentView];
|
||||
|
||||
return mutableChildren;
|
||||
}
|
||||
|
||||
- (NSString*)accessibilityTitle {
|
||||
|
||||
@@ -50,11 +50,10 @@
|
||||
#include "ui/display/screen.h"
|
||||
|
||||
#if BUILDFLAG(ENABLE_ELECTRON_EXTENSIONS)
|
||||
#include "chrome/common/extensions/chrome_manifest_url_handlers.h"
|
||||
#include "content/public/browser/child_process_security_policy.h"
|
||||
#include "content/public/browser/render_process_host.h"
|
||||
#include "extensions/browser/extension_registry.h"
|
||||
#include "extensions/common/manifest_constants.h"
|
||||
#include "extensions/common/manifest_url_handlers.h"
|
||||
#include "extensions/common/permissions/permissions_data.h"
|
||||
#include "shell/browser/electron_browser_context.h"
|
||||
#endif
|
||||
@@ -601,8 +600,8 @@ void InspectableWebContentsImpl::AddDevToolsExtensionsToClient() {
|
||||
|
||||
base::ListValue results;
|
||||
for (auto& extension : registry->enabled_extensions()) {
|
||||
auto devtools_page_url = extensions::ManifestURL::Get(
|
||||
extension.get(), extensions::manifest_keys::kDevToolsPage);
|
||||
auto devtools_page_url =
|
||||
extensions::chrome_manifest_urls::GetDevToolsPage(extension.get());
|
||||
if (devtools_page_url.is_empty())
|
||||
continue;
|
||||
|
||||
|
||||
@@ -37,11 +37,8 @@ const char kRunAsNode[] = "ELECTRON_RUN_AS_NODE";
|
||||
|
||||
#if BUILDFLAG(ENABLE_PDF_VIEWER)
|
||||
const char kPdfPluginMimeType[] = "application/x-google-chrome-pdf";
|
||||
const char kPdfPluginPath[] = "chrome://pdf-viewer/";
|
||||
const char kPdfPluginSrc[] = "src";
|
||||
|
||||
const char kPdfViewerUIOrigin[] = "chrome://pdf-viewer/";
|
||||
const char kPdfViewerUIHost[] = "pdf-viewer";
|
||||
const base::FilePath::CharType kPdfPluginPath[] =
|
||||
FILE_PATH_LITERAL("internal-pdf-viewer");
|
||||
#endif // BUILDFLAG(ENABLE_PDF_VIEWER)
|
||||
|
||||
} // namespace electron
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
#ifndef SHELL_COMMON_ELECTRON_CONSTANTS_H_
|
||||
#define SHELL_COMMON_ELECTRON_CONSTANTS_H_
|
||||
|
||||
#include "base/files/file_path.h"
|
||||
#include "build/build_config.h"
|
||||
#include "electron/buildflags/buildflags.h"
|
||||
|
||||
@@ -39,12 +40,7 @@ extern const char kRunAsNode[];
|
||||
#if BUILDFLAG(ENABLE_PDF_VIEWER)
|
||||
// The MIME type used for the PDF plugin.
|
||||
extern const char kPdfPluginMimeType[];
|
||||
extern const char kPdfPluginPath[];
|
||||
extern const char kPdfPluginSrc[];
|
||||
|
||||
// Constants for PDF viewer webui.
|
||||
extern const char kPdfViewerUIOrigin[];
|
||||
extern const char kPdfViewerUIHost[];
|
||||
extern const base::FilePath::CharType kPdfPluginPath[];
|
||||
#endif // BUILDFLAG(ENABLE_PDF_VIEWER)
|
||||
|
||||
} // namespace electron
|
||||
|
||||
@@ -22,6 +22,7 @@ group("extensions_features") {
|
||||
public_deps = [
|
||||
":api_features",
|
||||
":manifest_features",
|
||||
":permission_features",
|
||||
|
||||
# TODO(devlin): It would be nicer to have this dependency hoisted up to
|
||||
# //extensions/common (since that's where it's consumed), but there's some
|
||||
@@ -36,6 +37,7 @@ group("extensions_features") {
|
||||
generated_json_strings("generated_api_json_strings") {
|
||||
sources = [
|
||||
"extension.json",
|
||||
"resources_private.idl",
|
||||
"tabs.json",
|
||||
]
|
||||
|
||||
@@ -50,7 +52,10 @@ generated_json_strings("generated_api_json_strings") {
|
||||
}
|
||||
|
||||
generated_types("generated_api_types") {
|
||||
sources = [ "tabs.json" ]
|
||||
sources = [
|
||||
"resources_private.idl",
|
||||
"tabs.json",
|
||||
]
|
||||
configs = [ "//build/config:precompiled_headers" ]
|
||||
schema_include_rules = "extensions/common/api:extensions::api::%(namespace)s"
|
||||
|
||||
@@ -73,3 +78,10 @@ json_features("api_features") {
|
||||
sources = [ "_api_features.json" ]
|
||||
visibility = [ ":extensions_features" ]
|
||||
}
|
||||
|
||||
json_features("permission_features") {
|
||||
feature_type = "PermissionFeature"
|
||||
method_name = "AddElectronPermissionFeatures"
|
||||
sources = [ "_permission_features.json" ]
|
||||
visibility = [ ":extensions_features" ]
|
||||
}
|
||||
|
||||
@@ -9,7 +9,27 @@
|
||||
"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"]
|
||||
}
|
||||
},
|
||||
"mimeHandlerViewGuestInternal": {
|
||||
"internal": true,
|
||||
"contexts": "all",
|
||||
"channel": "stable",
|
||||
"matches": ["<all_urls>"]
|
||||
},
|
||||
"resourcesPrivate": [{
|
||||
"dependencies": ["permission:resourcesPrivate"],
|
||||
"contexts": ["blessed_extension"]
|
||||
}, {
|
||||
"channel": "stable",
|
||||
"contexts": ["webui"],
|
||||
"matches": [
|
||||
"chrome://print/*"
|
||||
]
|
||||
}]
|
||||
}
|
||||
|
||||
9
shell/common/extensions/api/_permission_features.json
Normal file
9
shell/common/extensions/api/_permission_features.json
Normal file
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"resourcesPrivate": {
|
||||
"channel": "stable",
|
||||
"extension_types": [
|
||||
"extension"
|
||||
],
|
||||
"location": "component"
|
||||
}
|
||||
}
|
||||
@@ -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).",
|
||||
|
||||
23
shell/common/extensions/api/resources_private.idl
Normal file
23
shell/common/extensions/api/resources_private.idl
Normal file
@@ -0,0 +1,23 @@
|
||||
// Copyright 2015 The Chromium Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
// resourcesPrivate.
|
||||
namespace resourcesPrivate {
|
||||
enum Component { identity, pdf };
|
||||
|
||||
callback GetStringsCallback = void (object result);
|
||||
|
||||
interface Functions {
|
||||
// Gets localized strings for a component extension. Includes default WebUI
|
||||
// loadTimeData values for text and language settings (fontsize, fontfamily,
|
||||
// language, textdirection). See
|
||||
// chrome/browser/extensions/api/resources_private/resources_private_api.cc
|
||||
// for instructions on adding a new component to this API.
|
||||
//
|
||||
// |component| : Internal chrome component to get strings for.
|
||||
// |callback| : Called with a dictionary mapping names to strings.
|
||||
static void getStrings(Component component,
|
||||
GetStringsCallback callback);
|
||||
};
|
||||
};
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user