mirror of
https://github.com/electron/electron.git
synced 2026-02-19 03:14:51 -05:00
Compare commits
22 Commits
robo/explo
...
v8.0.0-bet
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6cfc05ded2 | ||
|
|
40e0e8e499 | ||
|
|
beff8b8b51 | ||
|
|
311723396a | ||
|
|
d39d75321a | ||
|
|
55201d7db6 | ||
|
|
ac46d5b16e | ||
|
|
a1fb069624 | ||
|
|
3aa33dd220 | ||
|
|
9b74d0d54a | ||
|
|
018fc2ca46 | ||
|
|
e286b78df7 | ||
|
|
f77bd19a70 | ||
|
|
cff63d32a0 | ||
|
|
a8e7696674 | ||
|
|
5fc689dc4e | ||
|
|
895bdc0ee0 | ||
|
|
c99f1d317e | ||
|
|
315e3e325d | ||
|
|
8acce4279b | ||
|
|
c8943cdc3c | ||
|
|
f74f009648 |
@@ -319,6 +319,8 @@ step-gn-check: &step-gn-check
|
||||
gn check out/Default //electron:electron_app
|
||||
gn check out/Default //electron:manifests
|
||||
gn check out/Default //electron/shell/common/api:mojo
|
||||
# Check the hunspell filenames
|
||||
node electron/script/gen-hunspell-filenames.js --check
|
||||
|
||||
step-electron-build: &step-electron-build
|
||||
run:
|
||||
@@ -534,6 +536,20 @@ step-mksnapshot-store: &step-mksnapshot-store
|
||||
path: src/out/Default/mksnapshot.zip
|
||||
destination: mksnapshot.zip
|
||||
|
||||
step-hunspell-build: &step-hunspell-build
|
||||
run:
|
||||
name: hunspell build
|
||||
command: |
|
||||
cd src
|
||||
if [ "$SKIP_DIST_ZIP" != "1" ]; then
|
||||
ninja -C out/Default electron:hunspell_dictionaries_zip -j $NUMBER_OF_NINJA_PROCESSES
|
||||
fi
|
||||
|
||||
step-hunspell-store: &step-hunspell-store
|
||||
store_artifacts:
|
||||
path: src/out/Default/hunspell_dictionaries.zip
|
||||
destination: hunspell_dictionaries.zip
|
||||
|
||||
step-maybe-generate-breakpad-symbols: &step-maybe-generate-breakpad-symbols
|
||||
run:
|
||||
name: Generate breakpad symbols
|
||||
@@ -693,7 +709,6 @@ step-minimize-workspace-size-from-checkout: &step-minimize-workspace-size-from-c
|
||||
rm -rf src/ios
|
||||
rm -rf src/third_party/blink/web_tests
|
||||
rm -rf src/third_party/blink/perf_tests
|
||||
rm -rf src/third_party/hunspell_dictionaries
|
||||
rm -rf src/third_party/WebKit/LayoutTests
|
||||
|
||||
# Save the src cache based on the deps hash
|
||||
@@ -704,6 +719,51 @@ step-save-src-cache: &step-save-src-cache
|
||||
key: v5-src-cache-{{ arch }}-{{ checksum "src/electron/.depshash" }}
|
||||
name: Persisting src cache
|
||||
|
||||
# Check for doc only change
|
||||
step-check-for-doc-only-change: &step-check-for-doc-only-change
|
||||
run:
|
||||
name: Check if commit is doc only change
|
||||
command: |
|
||||
cd src/electron
|
||||
node script/yarn install --frozen-lockfile
|
||||
if node script/doc-only-change.js --prNumber=$CIRCLE_PR_NUMBER --prURL=$CIRCLE_PULL_REQUEST; then
|
||||
#PR is doc only change; save file with value true to indicate doc only change
|
||||
echo "true" > .skip-ci-build
|
||||
else
|
||||
#PR is not a doc only change; create empty file to indicate check has been done
|
||||
touch .skip-ci-build
|
||||
fi
|
||||
|
||||
step-persist-doc-only-change: &step-persist-doc-only-change
|
||||
persist_to_workspace:
|
||||
root: .
|
||||
paths:
|
||||
- src/electron/.skip-ci-build
|
||||
|
||||
step-maybe-early-exit-doc-only-change: &step-maybe-early-exit-doc-only-change
|
||||
run:
|
||||
name: Shortcircuit build if doc only change
|
||||
command: |
|
||||
if [ -s src/electron/.skip-ci-build ]; then
|
||||
circleci-agent step halt
|
||||
fi
|
||||
|
||||
step-maybe-early-exit-no-doc-change: &step-maybe-early-exit-no-doc-change
|
||||
run:
|
||||
name: Shortcircuit job if change is not doc only
|
||||
command: |
|
||||
if [ ! -s src/electron/.skip-ci-build ]; then
|
||||
circleci-agent step halt
|
||||
fi
|
||||
|
||||
step-ts-compile: &step-ts-compile
|
||||
run:
|
||||
name: Run TS/JS compile on doc only change
|
||||
command: |
|
||||
cd src
|
||||
ninja -C out/Default electron:default_app_js -j $NUMBER_OF_NINJA_PROCESSES
|
||||
ninja -C out/Default electron:atom_js2c -j $NUMBER_OF_NINJA_PROCESSES
|
||||
|
||||
# Lists of steps.
|
||||
steps-lint: &steps-lint
|
||||
steps:
|
||||
@@ -752,6 +812,9 @@ steps-lint: &steps-lint
|
||||
steps-checkout-fast: &steps-checkout-fast
|
||||
steps:
|
||||
- *step-checkout-electron
|
||||
- *step-check-for-doc-only-change
|
||||
- *step-persist-doc-only-change
|
||||
- *step-maybe-early-exit-doc-only-change
|
||||
- *step-depot-tools-get
|
||||
- *step-depot-tools-add-to-path
|
||||
- *step-restore-brew-cache
|
||||
@@ -783,6 +846,9 @@ steps-checkout-fast: &steps-checkout-fast
|
||||
steps-checkout-and-save-cache: &steps-checkout-and-save-cache
|
||||
steps:
|
||||
- *step-checkout-electron
|
||||
- *step-check-for-doc-only-change
|
||||
- *step-persist-doc-only-change
|
||||
- *step-maybe-early-exit-doc-only-change
|
||||
- *step-depot-tools-get
|
||||
- *step-depot-tools-add-to-path
|
||||
- *step-restore-brew-cache
|
||||
@@ -813,6 +879,7 @@ steps-electron-gn-check: &steps-electron-gn-check
|
||||
steps:
|
||||
- attach_workspace:
|
||||
at: .
|
||||
- *step-maybe-early-exit-doc-only-change
|
||||
- *step-depot-tools-add-to-path
|
||||
- *step-setup-env-for-build
|
||||
- *step-gn-gen-default
|
||||
@@ -822,6 +889,7 @@ 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
|
||||
@@ -859,6 +927,10 @@ steps-electron-build: &steps-electron-build
|
||||
- *step-ffmpeg-build
|
||||
- *step-ffmpeg-store
|
||||
|
||||
# hunspell
|
||||
- *step-hunspell-build
|
||||
- *step-hunspell-store
|
||||
|
||||
# Save all data needed for a further tests run.
|
||||
- *step-persist-data-for-tests
|
||||
|
||||
@@ -875,6 +947,9 @@ steps-electron-build-with-inline-checkout-for-tests: &steps-electron-build-with-
|
||||
steps:
|
||||
# Checkout - Copied ffrom steps-checkout
|
||||
- *step-checkout-electron
|
||||
- *step-check-for-doc-only-change
|
||||
- *step-persist-doc-only-change
|
||||
- *step-maybe-early-exit-doc-only-change
|
||||
- *step-depot-tools-get
|
||||
- *step-depot-tools-add-to-path
|
||||
- *step-restore-brew-cache
|
||||
@@ -934,6 +1009,10 @@ steps-electron-build-with-inline-checkout-for-tests: &steps-electron-build-with-
|
||||
- *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
|
||||
|
||||
@@ -946,6 +1025,45 @@ steps-electron-build-with-inline-checkout-for-tests: &steps-electron-build-with-
|
||||
|
||||
- *step-maybe-notify-slack-failure
|
||||
|
||||
steps-electron-ts-compile-for-doc-change: &steps-electron-ts-compile-for-doc-change
|
||||
steps:
|
||||
# Checkout - Copied ffrom steps-checkout
|
||||
- *step-checkout-electron
|
||||
- *step-check-for-doc-only-change
|
||||
- *step-maybe-early-exit-no-doc-change
|
||||
- *step-depot-tools-get
|
||||
- *step-depot-tools-add-to-path
|
||||
- *step-restore-brew-cache
|
||||
- *step-get-more-space-on-mac
|
||||
- *step-install-gnutar-on-mac
|
||||
- *step-generate-deps-hash
|
||||
- *step-touch-sync-done
|
||||
- *step-maybe-restore-src-cache
|
||||
- *step-maybe-restore-git-cache
|
||||
- *step-set-git-cache-path
|
||||
# This sync call only runs if .circle-sync-done is an EMPTY file
|
||||
- *step-gclient-sync
|
||||
# These next few steps reset Electron to the correct commit regardless of which cache was restored
|
||||
- run:
|
||||
name: Wipe Electron
|
||||
command: rm -rf src/electron
|
||||
- *step-checkout-electron
|
||||
- *step-run-electron-only-hooks
|
||||
- *step-generate-deps-hash-cleanly
|
||||
- *step-mark-sync-done
|
||||
- *step-minimize-workspace-size-from-checkout
|
||||
|
||||
- *step-depot-tools-add-to-path
|
||||
- *step-setup-env-for-build
|
||||
- *step-restore-brew-cache
|
||||
- *step-get-more-space-on-mac
|
||||
- *step-install-npm-deps-on-mac
|
||||
- *step-fix-sync-on-mac
|
||||
- *step-gn-gen-default
|
||||
|
||||
#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
|
||||
@@ -984,6 +1102,10 @@ steps-electron-build-for-publish: &steps-electron-build-for-publish
|
||||
- *step-ffmpeg-build
|
||||
- *step-ffmpeg-store
|
||||
|
||||
# hunspell
|
||||
- *step-hunspell-build
|
||||
- *step-hunspell-store
|
||||
|
||||
# typescript defs
|
||||
- *step-maybe-generate-typescript-defs
|
||||
|
||||
@@ -1064,6 +1186,7 @@ steps-tests: &steps-tests
|
||||
steps:
|
||||
- attach_workspace:
|
||||
at: .
|
||||
- *step-maybe-early-exit-doc-only-change
|
||||
- *step-depot-tools-add-to-path
|
||||
- *step-electron-dist-unzip
|
||||
- *step-mksnapshot-unzip
|
||||
@@ -1106,6 +1229,7 @@ steps-test-nan: &steps-test-nan
|
||||
steps:
|
||||
- attach_workspace:
|
||||
at: .
|
||||
- *step-maybe-early-exit-doc-only-change
|
||||
- *step-depot-tools-add-to-path
|
||||
- *step-electron-dist-unzip
|
||||
- *step-setup-linux-for-headless-testing
|
||||
@@ -1121,6 +1245,7 @@ steps-test-node: &steps-test-node
|
||||
steps:
|
||||
- attach_workspace:
|
||||
at: .
|
||||
- *step-maybe-early-exit-doc-only-change
|
||||
- *step-depot-tools-add-to-path
|
||||
- *step-electron-dist-unzip
|
||||
- *step-setup-linux-for-headless-testing
|
||||
@@ -1146,6 +1271,13 @@ jobs:
|
||||
<<: *env-linux-medium
|
||||
<<: *steps-lint
|
||||
|
||||
ts-compile-doc-change:
|
||||
<<: *machine-linux-medium
|
||||
environment:
|
||||
<<: *env-linux-medium
|
||||
<<: *env-testing-build
|
||||
<<: *steps-electron-ts-compile-for-doc-change
|
||||
|
||||
# Layer 1: Checkout.
|
||||
linux-checkout-fast:
|
||||
<<: *machine-linux-2xlarge
|
||||
@@ -1917,6 +2049,7 @@ workflows:
|
||||
- linux-arm64-testing-gn-check:
|
||||
requires:
|
||||
- linux-checkout-fast
|
||||
- ts-compile-doc-change
|
||||
|
||||
build-mac:
|
||||
when: << pipeline.parameters.run-build-mac >>
|
||||
|
||||
31
BUILD.gn
31
BUILD.gn
@@ -1,6 +1,7 @@
|
||||
import("//build/config/locales.gni")
|
||||
import("//build/config/ui.gni")
|
||||
import("//build/config/win/manifest.gni")
|
||||
import("//components/spellcheck/spellcheck_build_features.gni")
|
||||
import("//content/public/app/mac_helpers.gni")
|
||||
import("//pdf/features.gni")
|
||||
import("//printing/buildflags/buildflags.gni")
|
||||
@@ -21,6 +22,7 @@ import("buildflags/buildflags.gni")
|
||||
import("electron_paks.gni")
|
||||
import("filenames.auto.gni")
|
||||
import("filenames.gni")
|
||||
import("filenames.hunspell.gni")
|
||||
|
||||
if (is_mac) {
|
||||
import("//build/config/mac/rules.gni")
|
||||
@@ -358,12 +360,12 @@ source_set("electron_lib") {
|
||||
"//chrome/app/resources:platform_locale_settings",
|
||||
"//chrome/services/printing/public/mojom",
|
||||
"//components/certificate_transparency",
|
||||
"//components/language/core/browser",
|
||||
"//components/net_log",
|
||||
"//components/network_hints/common",
|
||||
"//components/network_hints/renderer",
|
||||
"//components/network_session_configurator/common",
|
||||
"//components/prefs",
|
||||
"//components/spellcheck/renderer",
|
||||
"//components/viz/host",
|
||||
"//components/viz/service",
|
||||
"//content/public/browser",
|
||||
@@ -478,6 +480,10 @@ source_set("electron_lib") {
|
||||
]
|
||||
}
|
||||
|
||||
if (enable_builtin_spellchecker) {
|
||||
deps += [ "chromium_src:chrome_spellchecker" ]
|
||||
}
|
||||
|
||||
if (is_mac) {
|
||||
deps += [
|
||||
"//components/remote_cocoa/app_shim",
|
||||
@@ -1265,9 +1271,14 @@ template("dist_zip") {
|
||||
"outputs",
|
||||
"testonly",
|
||||
])
|
||||
flatten = false
|
||||
if (defined(invoker.flatten)) {
|
||||
flatten = invoker.flatten
|
||||
}
|
||||
args = rebase_path(outputs + [ _runtime_deps_file ], root_build_dir) + [
|
||||
target_cpu,
|
||||
target_os,
|
||||
"$flatten",
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -1353,6 +1364,24 @@ dist_zip("electron_mksnapshot_zip") {
|
||||
]
|
||||
}
|
||||
|
||||
copy("hunspell_dictionaries") {
|
||||
sources = hunspell_dictionaries + hunspell_licenses
|
||||
outputs = [
|
||||
"$target_gen_dir/electron_hunspell/{{source_file_part}}",
|
||||
]
|
||||
}
|
||||
|
||||
dist_zip("hunspell_dictionaries_zip") {
|
||||
data_deps = [
|
||||
":hunspell_dictionaries",
|
||||
]
|
||||
flatten = true
|
||||
|
||||
outputs = [
|
||||
"$root_build_dir/hunspell_dictionaries.zip",
|
||||
]
|
||||
}
|
||||
|
||||
group("electron") {
|
||||
public_deps = [
|
||||
":electron_app",
|
||||
|
||||
@@ -1 +1 @@
|
||||
8.0.0-nightly.20191023
|
||||
8.0.0-beta.2
|
||||
@@ -50,6 +50,12 @@ build_script:
|
||||
- ps: >-
|
||||
if(($env:APPVEYOR_PULL_REQUEST_HEAD_REPO_NAME -split "/")[0] -eq ($env:APPVEYOR_REPO_NAME -split "/")[0]) {
|
||||
Write-warning "Skipping PR build for branch"; Exit-AppveyorBuild
|
||||
} else {
|
||||
node script/yarn.js install --frozen-lockfile
|
||||
|
||||
if ($(node script/doc-only-change.js --prNumber=$env:APPVEYOR_PULL_REQUEST_NUMBER --prBranch=$env:APPVEYOR_REPO_BRANCH;$LASTEXITCODE -eq 0)) {
|
||||
Write-warning "Skipping build for doc only change"; Exit-AppveyorBuild
|
||||
}
|
||||
}
|
||||
- echo "Building $env:GN_CONFIG build"
|
||||
- git config --global core.longpaths true
|
||||
@@ -85,6 +91,7 @@ build_script:
|
||||
- ninja -C out/Default electron:electron_dist_zip
|
||||
- ninja -C out/Default shell_browser_ui_unittests
|
||||
- ninja -C out/Default electron:electron_mksnapshot_zip
|
||||
- ninja -C out/Default electron:hunspell_dictionaries_zip
|
||||
- ninja -C out/Default electron:electron_chromedriver_zip
|
||||
- ninja -C out/Default third_party/electron_node:headers
|
||||
- appveyor PushArtifact out/Default/dist.zip
|
||||
@@ -94,6 +101,7 @@ build_script:
|
||||
- 7z a node_headers.zip out\Default\gen\node_headers
|
||||
- appveyor PushArtifact node_headers.zip
|
||||
- appveyor PushArtifact out/Default/mksnapshot.zip
|
||||
- appveyor PushArtifact out/Default/hunspell_dictionaries.zip
|
||||
- appveyor PushArtifact out/Default/electron.lib
|
||||
- ps: >-
|
||||
if ($env:GN_CONFIG -eq 'release') {
|
||||
|
||||
@@ -46,13 +46,14 @@ def execute(argv):
|
||||
raise e
|
||||
|
||||
def main(argv):
|
||||
dist_zip, runtime_deps, target_cpu, target_os = argv
|
||||
dist_zip, runtime_deps, target_cpu, target_os, flatten_val = argv
|
||||
should_flatten = flatten_val == "true"
|
||||
dist_files = set()
|
||||
with open(runtime_deps) as f:
|
||||
for dep in f.readlines():
|
||||
dep = dep.strip()
|
||||
dist_files.add(dep)
|
||||
if sys.platform == 'darwin':
|
||||
if sys.platform == 'darwin' and not should_flatten:
|
||||
execute(['zip', '-r', '-y', dist_zip] + list(dist_files))
|
||||
else:
|
||||
with zipfile.ZipFile(dist_zip, 'w', zipfile.ZIP_DEFLATED, allowZip64=True) as z:
|
||||
@@ -67,7 +68,7 @@ def main(argv):
|
||||
basename = os.path.basename(dep)
|
||||
dirname = os.path.dirname(dep)
|
||||
arcname = os.path.join(dirname, 'chrome-sandbox') if basename == 'chrome_sandbox' else dep
|
||||
z.write(dep, arcname)
|
||||
z.write(dep, os.path.basename(arcname) if should_flatten else arcname)
|
||||
|
||||
if __name__ == '__main__':
|
||||
sys.exit(main(sys.argv[1:]))
|
||||
|
||||
@@ -19,6 +19,7 @@ buildflag_header("buildflags") {
|
||||
"ENABLE_TTS=$enable_tts",
|
||||
"ENABLE_COLOR_CHOOSER=$enable_color_chooser",
|
||||
"ENABLE_ELECTRON_EXTENSIONS=$enable_electron_extensions",
|
||||
"ENABLE_BUILTIN_SPELLCHECKER=$enable_builtin_spellchecker",
|
||||
"ENABLE_PICTURE_IN_PICTURE=$enable_picture_in_picture",
|
||||
"OVERRIDE_LOCATION_PROVIDER=$enable_fake_location_provider",
|
||||
]
|
||||
|
||||
@@ -33,4 +33,7 @@ declare_args() {
|
||||
|
||||
# Enable Chrome extensions support.
|
||||
enable_electron_extensions = false
|
||||
|
||||
# Enable Spellchecker support
|
||||
enable_builtin_spellchecker = true
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
# found in the LICENSE file.
|
||||
|
||||
import("//build/config/ui.gni")
|
||||
import("//components/spellcheck/spellcheck_build_features.gni")
|
||||
import("//electron/buildflags/buildflags.gni")
|
||||
import("//printing/buildflags/buildflags.gni")
|
||||
import("//third_party/widevine/cdm/widevine.gni")
|
||||
@@ -225,3 +226,52 @@ static_library("chrome") {
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
# This source set is just so we don't have to depend on all of //chrome/browser
|
||||
# You may have to add new files here during the upgrade if //chrome/browser/spellchecker
|
||||
# gets more files
|
||||
source_set("chrome_spellchecker") {
|
||||
sources = [
|
||||
"//chrome/browser/spellchecker/spell_check_host_chrome_impl.cc",
|
||||
"//chrome/browser/spellchecker/spell_check_host_chrome_impl.h",
|
||||
"//chrome/browser/spellchecker/spellcheck_custom_dictionary.cc",
|
||||
"//chrome/browser/spellchecker/spellcheck_custom_dictionary.h",
|
||||
"//chrome/browser/spellchecker/spellcheck_factory.cc",
|
||||
"//chrome/browser/spellchecker/spellcheck_factory.h",
|
||||
"//chrome/browser/spellchecker/spellcheck_hunspell_dictionary.cc",
|
||||
"//chrome/browser/spellchecker/spellcheck_hunspell_dictionary.h",
|
||||
"//chrome/browser/spellchecker/spellcheck_language_blacklist_policy_handler.cc",
|
||||
"//chrome/browser/spellchecker/spellcheck_language_blacklist_policy_handler.h",
|
||||
"//chrome/browser/spellchecker/spellcheck_language_policy_handler.cc",
|
||||
"//chrome/browser/spellchecker/spellcheck_language_policy_handler.h",
|
||||
"//chrome/browser/spellchecker/spellcheck_service.cc",
|
||||
"//chrome/browser/spellchecker/spellcheck_service.h",
|
||||
]
|
||||
|
||||
if (has_spellcheck_panel) {
|
||||
sources += [
|
||||
"//chrome/browser/spellchecker/spell_check_panel_host_impl.cc",
|
||||
"//chrome/browser/spellchecker/spell_check_panel_host_impl.h",
|
||||
]
|
||||
}
|
||||
|
||||
if (use_browser_spellchecker) {
|
||||
sources += [
|
||||
"//chrome/browser/spellchecker/spelling_request.cc",
|
||||
"//chrome/browser/spellchecker/spelling_request.h",
|
||||
]
|
||||
}
|
||||
|
||||
deps = [
|
||||
"//base:base_static",
|
||||
"//components/language/core/browser",
|
||||
"//components/spellcheck:buildflags",
|
||||
"//components/sync",
|
||||
]
|
||||
|
||||
public_deps = [
|
||||
"//components/spellcheck/browser",
|
||||
"//components/spellcheck/common",
|
||||
"//components/spellcheck/renderer",
|
||||
]
|
||||
}
|
||||
|
||||
@@ -385,6 +385,8 @@ It creates a new `BrowserWindow` with native properties as set by the `options`.
|
||||
* `accessibleTitle` String (optional) - An alternative title string provided only
|
||||
to accessibility tools such as screen readers. This string is not directly
|
||||
visible to users.
|
||||
* `spellcheck` Boolean (optional) - Whether to enable the builtin spellchecker.
|
||||
Default is `false`.
|
||||
|
||||
When setting minimum or maximum window size with `minWidth`/`maxWidth`/
|
||||
`minHeight`/`maxHeight`, it only constrains the users. It won't prevent you from
|
||||
|
||||
@@ -77,6 +77,7 @@ only the next time a message is sent to `channel`, after which it is removed.
|
||||
|
||||
* `channel` String
|
||||
* `listener` Function
|
||||
* `...args` any[]
|
||||
|
||||
Removes the specified `listener` from the listener array for the specified
|
||||
`channel`.
|
||||
|
||||
@@ -217,11 +217,15 @@ that all statistics are reported in Kilobytes.
|
||||
|
||||
Returns `String` - The version of the host operating system.
|
||||
|
||||
Examples:
|
||||
Example:
|
||||
|
||||
* `macOS` -> `10.13.6`
|
||||
* `Windows` -> `10.0.17763`
|
||||
* `Linux` -> `4.15.0-45-generic`
|
||||
```js
|
||||
const version = process.getSystemVersion()
|
||||
console.log(version)
|
||||
// On macOS -> '10.13.6'
|
||||
// On Windows -> '10.0.17763'
|
||||
// On Linux -> '4.15.0-45-generic'
|
||||
```
|
||||
|
||||
**Note:** It returns the actual operating system version instead of kernel version on macOS unlike `os.release()`.
|
||||
|
||||
|
||||
@@ -456,10 +456,38 @@ this session just before normal `preload` scripts run.
|
||||
Returns `String[]` an array of paths to preload scripts that have been
|
||||
registered.
|
||||
|
||||
#### `ses.setSpellCheckerLanguages(languages)`
|
||||
|
||||
* `languages` String[] - An array of language codes to enable the spellchecker for.
|
||||
|
||||
The built in spellchecker does not automatically detect what language a user is typing in. In order for the
|
||||
spell checker to correctly check their words you must call this API with an array of language codes. You can
|
||||
get the list of supported language codes with the `ses.availableSpellCheckerLanguages` property.
|
||||
|
||||
#### `ses.getSpellCheckerLanguages()`
|
||||
|
||||
Returns `String[]` - An array of language codes the spellchecker is enabled for. If this list is empty the spellchecker
|
||||
will fallback to using `en-US`. By default on launch if this setting is an empty list Electron will try to populate this
|
||||
setting with the current OS locale. This setting is persisted across restarts.
|
||||
|
||||
#### `ses.setSpellCheckerDictionaryDownloadURL(url)`
|
||||
|
||||
* `url` String - A base URL for Electron to download hunspell dictionaries from.
|
||||
|
||||
By default Electron will download hunspell dictionaries from the Chromium CDN. If you want to override this
|
||||
behavior you can use this API to point the dictionary downloader at your own hosted version of the hunspell
|
||||
dictionaries. We publish a `hunspell_dictionaries.zip` file with each release which contains the files you need
|
||||
to host here.
|
||||
|
||||
### Instance Properties
|
||||
|
||||
The following properties are available on instances of `Session`:
|
||||
|
||||
#### `ses.availableSpellCheckerLanguages` _Readonly_
|
||||
|
||||
A `String[]` array which consists of all the known available spell checker languages. Providing a language
|
||||
code to the `setSpellCheckerLanaguages` API that isn't in this array will result in an error.
|
||||
|
||||
#### `ses.cookies` _Readonly_
|
||||
|
||||
A [`Cookies`](cookies.md) object for this session.
|
||||
|
||||
@@ -570,6 +570,9 @@ Returns:
|
||||
* `titleText` String - Title or alt text of the selection that the context
|
||||
was invoked on.
|
||||
* `misspelledWord` String - The misspelled word under the cursor, if any.
|
||||
* `dictionarySuggestions` String[] - An array of suggested words to show the
|
||||
user to replace the `misspelledWord`. Only available if there is a misspelled
|
||||
word and spellchecker is enabled.
|
||||
* `frameCharset` String - The character encoding of the frame on which the
|
||||
menu was invoked.
|
||||
* `inputFieldType` String - If the context menu was invoked on an input
|
||||
|
||||
@@ -74,6 +74,17 @@ Sets the maximum and minimum layout-based (i.e. non-visual) zoom level.
|
||||
|
||||
Sets a provider for spell checking in input fields and text areas.
|
||||
|
||||
If you want to use this method you must disable the builtin spellchecker when you
|
||||
construct the window.
|
||||
|
||||
```js
|
||||
const mainWindow = new BrowserWindow({
|
||||
webPreferences: {
|
||||
spellcheck: false
|
||||
}
|
||||
})
|
||||
```
|
||||
|
||||
The `provider` must be an object that has a `spellCheck` method that accepts
|
||||
an array of individual words for spellchecking.
|
||||
The `spellCheck` function runs asynchronously and calls the `callback` function
|
||||
|
||||
@@ -54,13 +54,13 @@ at once, consider the [Chrome Tracing] tool.
|
||||
Chances are that your app could be a little leaner, faster, and generally less
|
||||
resource-hungry if you attempt these steps.
|
||||
|
||||
1) [Carelessly including modules](#1-carelessly-including-modules)
|
||||
2) [Loading and running code too soon](#2-loading-and-running-code-too-soon)
|
||||
3) [Blocking the main process](#3-blocking-the-main-process)
|
||||
4) [Blocking the renderer process](#4-blocking-the-renderer-process)
|
||||
5) [Unnecessary polyfills](#5-unnecessary-polyfills)
|
||||
6) [Unnecessary or blocking network requests](#6-unnecessary-or-blocking-network-requests)
|
||||
7) [Bundle your code](#7-bundle-your-code)
|
||||
1. [Carelessly including modules](#1-carelessly-including-modules)
|
||||
2. [Loading and running code too soon](#2-loading-and-running-code-too-soon)
|
||||
3. [Blocking the main process](#3-blocking-the-main-process)
|
||||
4. [Blocking the renderer process](#4-blocking-the-renderer-process)
|
||||
5. [Unnecessary polyfills](#5-unnecessary-polyfills)
|
||||
6. [Unnecessary or blocking network requests](#6-unnecessary-or-blocking-network-requests)
|
||||
7. [Bundle your code](#7-bundle-your-code)
|
||||
|
||||
## 1) Carelessly including modules
|
||||
|
||||
@@ -418,7 +418,6 @@ As of writing this article, the popular choices include [Webpack][webpack],
|
||||
[performance-cpu-prof]: ../images/performance-cpu-prof.png
|
||||
[performance-heap-prof]: ../images/performance-heap-prof.png
|
||||
[chrome-devtools-tutorial]: https://developers.google.com/web/tools/chrome-devtools/evaluate-performance/
|
||||
[chrome-tracing-tutorial]:
|
||||
[worker-threads]: https://nodejs.org/api/worker_threads.html
|
||||
[web-workers]: https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Using_web_workers
|
||||
[request-idle-callback]: https://developer.mozilla.org/en-US/docs/Web/API/Window/requestIdleCallback
|
||||
|
||||
@@ -69,4 +69,10 @@
|
||||
<message name="IDS_PICTURE_IN_PICTURE_PREVIOUS_TRACK_CONTROL_ACCESSIBLE_TEXT" desc="Accessible text label used for the controls button in the Picture-in-Picture window. The button invokes previous track action.">
|
||||
Previous track
|
||||
</message>
|
||||
<message name="IDS_SPELLCHECK_DICTIONARY" use_name_for_id="true">
|
||||
en-US
|
||||
</message>
|
||||
<message name="IDS_ACCEPT_LANGUAGES" use_name_for_id="true">
|
||||
en-US,en
|
||||
</message>
|
||||
</grit-part>
|
||||
|
||||
60
filenames.hunspell.gni
Normal file
60
filenames.hunspell.gni
Normal file
@@ -0,0 +1,60 @@
|
||||
hunspell_dictionaries = [
|
||||
"//third_party/hunspell_dictionaries/af-ZA-3-0.bdic",
|
||||
"//third_party/hunspell_dictionaries/bg-BG-3-0.bdic",
|
||||
"//third_party/hunspell_dictionaries/ca-ES-3-0.bdic",
|
||||
"//third_party/hunspell_dictionaries/cs-CZ-3-0.bdic",
|
||||
"//third_party/hunspell_dictionaries/cy-GB-1-0.bdic",
|
||||
"//third_party/hunspell_dictionaries/da-DK-3-0.bdic",
|
||||
"//third_party/hunspell_dictionaries/de-DE-3-0.bdic",
|
||||
"//third_party/hunspell_dictionaries/el-GR-3-0.bdic",
|
||||
"//third_party/hunspell_dictionaries/en-AU-8-0.bdic",
|
||||
"//third_party/hunspell_dictionaries/en-CA-8-0.bdic",
|
||||
"//third_party/hunspell_dictionaries/en-GB-8-0.bdic",
|
||||
"//third_party/hunspell_dictionaries/en-US-8-0.bdic",
|
||||
"//third_party/hunspell_dictionaries/es-ES-3-0.bdic",
|
||||
"//third_party/hunspell_dictionaries/et-EE-3-0.bdic",
|
||||
"//third_party/hunspell_dictionaries/fa-IR-8-0.bdic",
|
||||
"//third_party/hunspell_dictionaries/fo-FO-3-0.bdic",
|
||||
"//third_party/hunspell_dictionaries/fr-FR-3-0.bdic",
|
||||
"//third_party/hunspell_dictionaries/he-IL-3-0.bdic",
|
||||
"//third_party/hunspell_dictionaries/hi-IN-3-0.bdic",
|
||||
"//third_party/hunspell_dictionaries/hr-HR-3-0.bdic",
|
||||
"//third_party/hunspell_dictionaries/hu-HU-3-0.bdic",
|
||||
"//third_party/hunspell_dictionaries/hy-1-0.bdic",
|
||||
"//third_party/hunspell_dictionaries/id-ID-3-0.bdic",
|
||||
"//third_party/hunspell_dictionaries/it-IT-3-0.bdic",
|
||||
"//third_party/hunspell_dictionaries/ko-3-0.bdic",
|
||||
"//third_party/hunspell_dictionaries/lt-LT-3-0.bdic",
|
||||
"//third_party/hunspell_dictionaries/lv-LV-3-0.bdic",
|
||||
"//third_party/hunspell_dictionaries/nb-NO-3-0.bdic",
|
||||
"//third_party/hunspell_dictionaries/nl-NL-3-0.bdic",
|
||||
"//third_party/hunspell_dictionaries/pl-PL-3-0.bdic",
|
||||
"//third_party/hunspell_dictionaries/pt-BR-3-0.bdic",
|
||||
"//third_party/hunspell_dictionaries/pt-PT-3-0.bdic",
|
||||
"//third_party/hunspell_dictionaries/ro-RO-3-0.bdic",
|
||||
"//third_party/hunspell_dictionaries/ru-RU-3-0.bdic",
|
||||
"//third_party/hunspell_dictionaries/sh-3-0.bdic",
|
||||
"//third_party/hunspell_dictionaries/sh-4-0.bdic",
|
||||
"//third_party/hunspell_dictionaries/sk-SK-3-0.bdic",
|
||||
"//third_party/hunspell_dictionaries/sl-SI-3-0.bdic",
|
||||
"//third_party/hunspell_dictionaries/sq-3-0.bdic",
|
||||
"//third_party/hunspell_dictionaries/sr-3-0.bdic",
|
||||
"//third_party/hunspell_dictionaries/sr-4-0.bdic",
|
||||
"//third_party/hunspell_dictionaries/sv-SE-3-0.bdic",
|
||||
"//third_party/hunspell_dictionaries/ta-IN-3-0.bdic",
|
||||
"//third_party/hunspell_dictionaries/tg-TG-5-0.bdic",
|
||||
"//third_party/hunspell_dictionaries/tr-TR-4-0.bdic",
|
||||
"//third_party/hunspell_dictionaries/uk-UA-3-0.bdic",
|
||||
"//third_party/hunspell_dictionaries/vi-VN-3-0.bdic",
|
||||
"//third_party/hunspell_dictionaries/xx-XX-3-0.bdic",
|
||||
]
|
||||
|
||||
hunspell_licenses = [
|
||||
"//third_party/hunspell_dictionaries/COPYING",
|
||||
"//third_party/hunspell_dictionaries/COPYING.Apache",
|
||||
"//third_party/hunspell_dictionaries/COPYING.LESSER",
|
||||
"//third_party/hunspell_dictionaries/COPYING.LGPL",
|
||||
"//third_party/hunspell_dictionaries/COPYING.MIT",
|
||||
"//third_party/hunspell_dictionaries/COPYING.MPL",
|
||||
"//third_party/hunspell_dictionaries/LICENSE",
|
||||
]
|
||||
@@ -33,7 +33,7 @@ BrowserWindow.prototype._init = function () {
|
||||
|
||||
// Hide the auto-hide menu when webContents is focused.
|
||||
this.webContents.on('activate', () => {
|
||||
if (process.platform !== 'darwin' && this.isMenuBarAutoHide() && this.isMenuBarVisible()) {
|
||||
if (process.platform !== 'darwin' && this.autoHideMenuBar && this.isMenuBarVisible()) {
|
||||
this.setMenuBarVisibility(false)
|
||||
}
|
||||
})
|
||||
|
||||
@@ -71,7 +71,6 @@ const defaultPrintingSetting = {
|
||||
headerFooterEnabled: false,
|
||||
marginsType: 0,
|
||||
isFirstRequest: false,
|
||||
requestID: getNextId(),
|
||||
previewUIID: 0,
|
||||
previewModifiable: true,
|
||||
printToPDF: true,
|
||||
@@ -204,7 +203,10 @@ WebContents.prototype.executeJavaScript = function (code, hasUserGesture) {
|
||||
|
||||
// Translate the options of printToPDF.
|
||||
WebContents.prototype.printToPDF = function (options) {
|
||||
const printingSetting = Object.assign({}, defaultPrintingSetting)
|
||||
const printingSetting = {
|
||||
...defaultPrintingSetting,
|
||||
requestID: getNextId()
|
||||
}
|
||||
if (options.landscape) {
|
||||
printingSetting.landscape = options.landscape
|
||||
}
|
||||
|
||||
@@ -200,7 +200,7 @@ const attachGuest = function (event, embedderFrameId, elementInstanceId, guestIn
|
||||
nodeIntegrationInSubFrames: params.nodeintegrationinsubframes != null ? params.nodeintegrationinsubframes : false,
|
||||
enableRemoteModule: params.enableremotemodule,
|
||||
plugins: params.plugins,
|
||||
zoomFactor: embedder.getZoomFactor(),
|
||||
zoomFactor: embedder.zoomFactor,
|
||||
disablePopups: !params.allowpopups,
|
||||
webSecurity: !params.disablewebsecurity,
|
||||
enableBlinkFeatures: params.blinkfeatures,
|
||||
|
||||
@@ -309,7 +309,7 @@ const unwrapArgs = function (sender: electron.WebContents, frameId: number, cont
|
||||
v8Util.setHiddenValue(callIntoRenderer, 'location', meta.location)
|
||||
Object.defineProperty(callIntoRenderer, 'length', { value: meta.length })
|
||||
|
||||
v8Util.setRemoteCallbackFreer(callIntoRenderer, contextId, meta.id, sender)
|
||||
v8Util.setRemoteCallbackFreer(callIntoRenderer, frameId, contextId, meta.id, sender)
|
||||
rendererFunctions.set(objectId, callIntoRenderer)
|
||||
return callIntoRenderer
|
||||
}
|
||||
|
||||
@@ -120,7 +120,11 @@ export function injectTo (extensionId: string, context: any) {
|
||||
let targetExtensionId = extensionId
|
||||
let connectInfo = { name: '' }
|
||||
if (args.length === 1) {
|
||||
targetExtensionId = args[0]
|
||||
if (typeof args[0] === 'string') {
|
||||
targetExtensionId = args[0]
|
||||
} else {
|
||||
connectInfo = args[0]
|
||||
}
|
||||
} else if (args.length === 2) {
|
||||
[targetExtensionId, connectInfo] = args
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "electron",
|
||||
"version": "8.0.0-nightly.20191023",
|
||||
"version": "8.0.0-beta.2",
|
||||
"repository": "https://github.com/electron/electron",
|
||||
"description": "Build cross platform desktop apps with JavaScript, HTML, and CSS",
|
||||
"devDependencies": {
|
||||
@@ -129,6 +129,9 @@
|
||||
"node script/gen-filenames.js",
|
||||
"python script/check-trailing-whitespace.py --fix",
|
||||
"git add filenames.auto.gni"
|
||||
],
|
||||
"DEPS": [
|
||||
"node script/gen-hunspell-filenames.js"
|
||||
]
|
||||
},
|
||||
"dependencies": {
|
||||
|
||||
@@ -81,3 +81,5 @@ ui_views_fix_jumbo_build.patch
|
||||
export_fetchapi_mojo_traits_to_fix_component_build.patch
|
||||
build_fix_when_building_with_enable_plugins_false.patch
|
||||
add_zoom_limit_setters_to_webcontents.patch
|
||||
remove_usage_of_incognito_apis_in_the_spellchecker.patch
|
||||
chore_use_electron_resources_not_chrome_for_spellchecker.patch
|
||||
@@ -0,0 +1,34 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Samuel Attard <sattard@slack-corp.com>
|
||||
Date: Wed, 23 Oct 2019 14:17:18 -0700
|
||||
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/spellchecker/spellcheck_factory.cc b/chrome/browser/spellchecker/spellcheck_factory.cc
|
||||
index 48ac0a24efde0cb7d3ba71c8b8bdf5178f606e80..e2beefc276098fdc8f1cdab2e0edb8fae4ee67ca 100644
|
||||
--- a/chrome/browser/spellchecker/spellcheck_factory.cc
|
||||
+++ b/chrome/browser/spellchecker/spellcheck_factory.cc
|
||||
@@ -6,7 +6,7 @@
|
||||
|
||||
#include "chrome/browser/profiles/incognito_helpers.h"
|
||||
#include "chrome/browser/spellchecker/spellcheck_service.h"
|
||||
-#include "chrome/grit/locale_settings.h"
|
||||
+#include "electron/grit/electron_resources.h"
|
||||
#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/language_prefs.cc b/components/language/core/browser/language_prefs.cc
|
||||
index d5e4c09e1722232df44b112ce39cdacea03a4710..c6caf7eacd9eed439ab5167e51b9fcce5d6af664 100644
|
||||
--- a/components/language/core/browser/language_prefs.cc
|
||||
+++ b/components/language/core/browser/language_prefs.cc
|
||||
@@ -21,7 +21,7 @@
|
||||
#include "components/pref_registry/pref_registry_syncable.h"
|
||||
#include "components/prefs/pref_service.h"
|
||||
#include "components/prefs/scoped_user_pref_update.h"
|
||||
-#include "components/strings/grit/components_locale_settings.h"
|
||||
+#include "electron/grit/electron_resources.h"
|
||||
#include "ui/base/l10n/l10n_util.h"
|
||||
|
||||
namespace language {
|
||||
@@ -5,16 +5,20 @@ Subject: fix: disabling compositor recycling
|
||||
|
||||
Compositor recycling is useful for Chrome because there can be many tabs and spinning up a compositor for each one would be costly. In practice, Chrome uses the parent compositor code path of browser_compositor_view_mac.mm; the NSView of each tab is detached when it's hidden and attached when it's shown. For Electron, there is no parent compositor, so we're forced into the "own compositor" code path, which seems to be non-optimal and pretty ruthless in terms of the release of resources. Electron has no real concept of multiple tabs per window, so it should be okay to disable this ruthless recycling altogether in Electron.
|
||||
|
||||
diff --git a/content/browser/renderer_host/browser_compositor_view_mac.mm b/content/browser/renderer_host/browser_compositor_view_mac.mm
|
||||
index 18019d5794f688ca07b35a665cc9800bb1d3047a..60c7e980dd322ba012c564fca68848c3188ca5dc 100644
|
||||
--- a/content/browser/renderer_host/browser_compositor_view_mac.mm
|
||||
+++ b/content/browser/renderer_host/browser_compositor_view_mac.mm
|
||||
@@ -209,7 +209,7 @@
|
||||
}
|
||||
|
||||
void BrowserCompositorMac::SetRenderWidgetHostIsHidden(bool hidden) {
|
||||
- render_widget_host_is_hidden_ = hidden;
|
||||
+ render_widget_host_is_hidden_ = false;
|
||||
UpdateState();
|
||||
diff --git a/content/browser/renderer_host/render_widget_host_view_mac.mm b/content/browser/renderer_host/render_widget_host_view_mac.mm
|
||||
index de722efe61cb6823e62f1101b5aa3447f6795687..b258bbb12b5c607e3fec600fbc7bcb376eb00c72 100644
|
||||
--- a/content/browser/renderer_host/render_widget_host_view_mac.mm
|
||||
+++ b/content/browser/renderer_host/render_widget_host_view_mac.mm
|
||||
@@ -486,7 +486,11 @@
|
||||
return;
|
||||
|
||||
host()->WasHidden();
|
||||
- browser_compositor_->SetRenderWidgetHostIsHidden(true);
|
||||
+ // Consider the RWHV occluded only if it is not attached to a window
|
||||
+ // (e.g. unattached BrowserView). Otherwise we treat it as visible to
|
||||
+ // prevent unnecessary compositor recycling.
|
||||
+ const bool unattached = ![GetInProcessNSView() window];
|
||||
+ browser_compositor_->SetRenderWidgetHostIsHidden(unattached);
|
||||
}
|
||||
|
||||
void RenderWidgetHostViewMac::SetSize(const gfx::Size& size) {
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Samuel Attard <sattard@slack-corp.com>
|
||||
Date: Wed, 23 Oct 2019 11:43:58 -0700
|
||||
Subject: remove usage of incognito APIs in the spellchecker
|
||||
|
||||
chrome::GetBrowserContextRedirectedInIncognito is not available in
|
||||
Electron nor do we want it to be. We could potentially upstream a
|
||||
change to move more of //chrome spellchecker logic into //components so
|
||||
that we can further separate our dependency from //chrome.
|
||||
|
||||
diff --git a/chrome/browser/spellchecker/spellcheck_factory.cc b/chrome/browser/spellchecker/spellcheck_factory.cc
|
||||
index 5253d1f48e188b0339834c876378677b459e718e..48ac0a24efde0cb7d3ba71c8b8bdf5178f606e80 100644
|
||||
--- a/chrome/browser/spellchecker/spellcheck_factory.cc
|
||||
+++ b/chrome/browser/spellchecker/spellcheck_factory.cc
|
||||
@@ -78,7 +78,10 @@ void SpellcheckServiceFactory::RegisterProfilePrefs(
|
||||
|
||||
content::BrowserContext* SpellcheckServiceFactory::GetBrowserContextToUse(
|
||||
content::BrowserContext* context) const {
|
||||
+ return context;
|
||||
+#if 0
|
||||
return chrome::GetBrowserContextRedirectedInIncognito(context);
|
||||
+#endif
|
||||
}
|
||||
|
||||
bool SpellcheckServiceFactory::ServiceIsNULLWhileTesting() const {
|
||||
@@ -49,7 +49,8 @@ def hasTrailingWhiteSpace(filepath, fix):
|
||||
for num, line in enumerate(lines):
|
||||
fixed_lines.append(line.rstrip() + '\n')
|
||||
if not fix and line != line.rstrip():
|
||||
print("Trailing whitespace on line {} in file: {}".format(num + 1, filepath))
|
||||
print("Trailing whitespace on line {} in file: {}".format(
|
||||
num + 1, filepath))
|
||||
return True
|
||||
if fix:
|
||||
with open(filepath, 'w') as f:
|
||||
|
||||
58
script/doc-only-change.js
Normal file
58
script/doc-only-change.js
Normal file
@@ -0,0 +1,58 @@
|
||||
const args = require('minimist')(process.argv.slice(2))
|
||||
const octokit = require('@octokit/rest')()
|
||||
const path = require('path')
|
||||
|
||||
const SOURCE_ROOT = path.normalize(path.dirname(__dirname))
|
||||
|
||||
async function checkIfDocOnlyChange () {
|
||||
if (args.prNumber || args.prBranch || args.prURL) {
|
||||
try {
|
||||
let pullRequestNumber = args.prNumber
|
||||
if (!pullRequestNumber || isNaN(pullRequestNumber)) {
|
||||
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',
|
||||
repo: 'electron',
|
||||
state: 'open',
|
||||
head: `electron:${args.prBranch}`
|
||||
})
|
||||
if (prsForBranch.data.length === 1) {
|
||||
pullRequestNumber = prsForBranch.data[0].number
|
||||
} else {
|
||||
// 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({
|
||||
owner: 'electron', repo: 'electron', pull_number: pullRequestNumber
|
||||
})
|
||||
|
||||
const nonDocChange = filesChanged.data.find((fileInfo) => {
|
||||
const fileDirs = fileInfo.filename.split('/')
|
||||
if (fileDirs[0] !== 'docs') {
|
||||
return true
|
||||
}
|
||||
})
|
||||
if (nonDocChange) {
|
||||
process.exit(1)
|
||||
} else {
|
||||
process.exit(0)
|
||||
}
|
||||
} catch (ex) {
|
||||
console.error('Error getting list of files changed: ', ex)
|
||||
process.exit(-1)
|
||||
}
|
||||
} else {
|
||||
console.error(`Check if only the docs were changed for a commit.
|
||||
Usage: doc-only-change.js --prNumber=PR_NUMBER || --prBranch=PR_BRANCH || --prURL=PR_URL`)
|
||||
process.exit(-1)
|
||||
}
|
||||
}
|
||||
|
||||
checkIfDocOnlyChange()
|
||||
35
script/gen-hunspell-filenames.js
Normal file
35
script/gen-hunspell-filenames.js
Normal file
@@ -0,0 +1,35 @@
|
||||
const fs = require('fs')
|
||||
const path = require('path')
|
||||
|
||||
const check = process.argv.includes('--check')
|
||||
|
||||
const dictsPath = path.resolve(__dirname, '..', '..', 'third_party', 'hunspell_dictionaries')
|
||||
const gclientPath = 'third_party/hunspell_dictionaries'
|
||||
|
||||
const allFiles = fs.readdirSync(dictsPath)
|
||||
|
||||
const dictionaries = allFiles
|
||||
.filter(file => path.extname(file) === '.bdic')
|
||||
|
||||
const licenses = allFiles
|
||||
.filter(file => file.startsWith('LICENSE') || file.startsWith('COPYING'))
|
||||
|
||||
const content = `hunspell_dictionaries = [
|
||||
${dictionaries.map(f => `"//${path.posix.join(gclientPath, f)}"`).join(',\n ')},
|
||||
]
|
||||
|
||||
hunspell_licenses = [
|
||||
${licenses.map(f => `"//${path.posix.join(gclientPath, f)}"`).join(',\n ')},
|
||||
]
|
||||
`
|
||||
|
||||
const filenamesPath = path.resolve(__dirname, '..', 'filenames.hunspell.gni')
|
||||
|
||||
if (check) {
|
||||
const currentContent = fs.readFileSync(filenamesPath, 'utf8')
|
||||
if (currentContent !== content) {
|
||||
throw new Error('hunspell filenames need to be regenerated, latest generation does not match current file. Please run node gen-hunspell-filenames.js')
|
||||
}
|
||||
} else {
|
||||
fs.writeFileSync(filenamesPath, content)
|
||||
}
|
||||
@@ -27,6 +27,7 @@ addAllFiles(path.resolve(__dirname, '../patches'))
|
||||
|
||||
// Create Hash
|
||||
const hasher = crypto.createHash('SHA256')
|
||||
hasher.update(`HASH_VERSION:${HASH_VERSION}`)
|
||||
for (const file of filesToHash) {
|
||||
hasher.update(fs.readFileSync(file))
|
||||
}
|
||||
|
||||
@@ -8,7 +8,8 @@ def read_patch(patch_dir, patch_filename):
|
||||
"""Read a patch from |patch_dir/filename| and amend the commit message with
|
||||
metadata about the patch file it came from."""
|
||||
ret = []
|
||||
with codecs.open(os.path.join(patch_dir, patch_filename), encoding='utf-8') as f:
|
||||
patch_path = os.path.join(patch_dir, patch_filename)
|
||||
with codecs.open(patch_path, encoding='utf-8') as f:
|
||||
for l in f.readlines():
|
||||
if l.startswith('diff -'):
|
||||
ret.append('Patch-Filename: {}\n'.format(patch_filename))
|
||||
|
||||
@@ -54,7 +54,7 @@ async function handleGitCall (args, gitDir) {
|
||||
|
||||
async function getCurrentBranch (gitDir) {
|
||||
let branch = await handleGitCall(['rev-parse', '--abbrev-ref', 'HEAD'], gitDir)
|
||||
if (branch !== 'master' && !branch.match(/[0-9]+-[0-9]+-x/)) {
|
||||
if (branch !== 'master' && !branch.match(/[0-9]+-[0-9]+-x$/) && !branch.match(/[0-9]+-x-y$/)) {
|
||||
const lastCommit = await handleGitCall(['rev-parse', 'HEAD'], gitDir)
|
||||
const branches = (await handleGitCall([
|
||||
'branch',
|
||||
@@ -63,7 +63,7 @@ async function getCurrentBranch (gitDir) {
|
||||
'--remote'
|
||||
], gitDir)).split('\n')
|
||||
|
||||
branch = branches.filter(b => b.trim() === 'master' || b.match(/[0-9]+-[0-9]+-x/))[0]
|
||||
branch = branches.filter(b => b.trim() === 'master' || b.trim().match(/^[0-9]+-[0-9]+-x$/) || b.trim().match(/^[0-9]+-x-y$/))[0]
|
||||
if (!branch) {
|
||||
console.log(`${fail} no release branch exists for this ref`)
|
||||
process.exit(1)
|
||||
|
||||
@@ -311,7 +311,6 @@ function runRelease (targetBranch, options) {
|
||||
} else {
|
||||
buildCircleCI(targetBranch, options)
|
||||
buildAppVeyor(targetBranch, options)
|
||||
buildVSTS(targetBranch, options)
|
||||
}
|
||||
console.log(`${jobRequestedCount} jobs were requested.`)
|
||||
}
|
||||
|
||||
@@ -130,6 +130,7 @@ function assetsForVersion (version, validatingRelease) {
|
||||
`electron-${version}-win32-arm64.zip`,
|
||||
`electron-api.json`,
|
||||
`electron.d.ts`,
|
||||
`hunspell_dictionaries.zip`,
|
||||
`ffmpeg-${version}-darwin-x64.zip`,
|
||||
`ffmpeg-${version}-linux-arm64.zip`,
|
||||
`ffmpeg-${version}-linux-armv7l.zip`,
|
||||
|
||||
@@ -106,6 +106,11 @@ def main():
|
||||
shutil.copy2(os.path.join(OUT_DIR, 'mksnapshot.zip'), mksnapshot_zip)
|
||||
upload_electron(release, mksnapshot_zip, args)
|
||||
|
||||
if PLATFORM == 'linux' and get_target_arch() == 'x64':
|
||||
# Upload the hunspell dictionaries only from the linux x64 build
|
||||
hunspell_dictionaries_zip = os.path.join(OUT_DIR, 'hunspell_dictionaries.zip')
|
||||
upload_electron(release, hunspell_dictionaries_zip, args)
|
||||
|
||||
if not tag_exists and not args.upload_to_s3:
|
||||
# Upload symbols to symbol server.
|
||||
run_python_upload_script('upload-symbols.py')
|
||||
|
||||
@@ -901,9 +901,14 @@ void App::SetPath(gin_helper::ErrorThrower thrower,
|
||||
|
||||
bool succeed = false;
|
||||
int key = GetPathConstant(name);
|
||||
if (key >= 0)
|
||||
if (key >= 0) {
|
||||
succeed =
|
||||
base::PathService::OverrideAndCreateIfNeeded(key, path, true, false);
|
||||
if (key == DIR_USER_DATA) {
|
||||
succeed |= base::PathService::OverrideAndCreateIfNeeded(
|
||||
chrome::DIR_USER_DATA, path, true, false);
|
||||
}
|
||||
}
|
||||
if (!succeed)
|
||||
thrower.ThrowError("Failed to set path");
|
||||
}
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
#include "shell/browser/api/atom_api_top_level_window.h"
|
||||
#include "shell/browser/api/trackable_object.h"
|
||||
#include "shell/browser/ui/atom_menu_model.h"
|
||||
#include "shell/common/api/locker.h"
|
||||
|
||||
namespace electron {
|
||||
|
||||
|
||||
@@ -56,6 +56,9 @@ void MenuMac::PopupOnUI(const base::WeakPtr<NativeWindow>& native_window,
|
||||
int y,
|
||||
int positioning_item,
|
||||
base::Closure callback) {
|
||||
mate::Locker locker(isolate());
|
||||
v8::HandleScope handle_scope(isolate());
|
||||
|
||||
if (!native_window)
|
||||
return;
|
||||
NSWindow* nswindow = native_window->GetNativeWindow().GetNativeNSWindow();
|
||||
|
||||
@@ -25,6 +25,9 @@ void MenuViews::PopupAt(TopLevelWindow* window,
|
||||
int y,
|
||||
int positioning_item,
|
||||
const base::Closure& callback) {
|
||||
mate::Locker locker(isolate());
|
||||
v8::HandleScope handle_scope(isolate());
|
||||
|
||||
auto* native_window = static_cast<NativeWindowViews*>(window->window());
|
||||
if (!native_window)
|
||||
return;
|
||||
|
||||
@@ -69,6 +69,12 @@
|
||||
#include "shell/browser/extensions/atom_extension_system.h"
|
||||
#endif
|
||||
|
||||
#if BUILDFLAG(ENABLE_BUILTIN_SPELLCHECKER)
|
||||
#include "chrome/browser/spellchecker/spellcheck_hunspell_dictionary.h"
|
||||
#include "components/spellcheck/browser/pref_names.h"
|
||||
#include "components/spellcheck/common/spellcheck_common.h"
|
||||
#endif
|
||||
|
||||
using content::BrowserThread;
|
||||
using content::StoragePartition;
|
||||
|
||||
@@ -646,6 +652,42 @@ void Session::Preconnect(const mate::Dictionary& options,
|
||||
url, num_sockets_to_preconnect));
|
||||
}
|
||||
|
||||
#if BUILDFLAG(ENABLE_BUILTIN_SPELLCHECKER)
|
||||
base::Value Session::GetSpellCheckerLanguages() {
|
||||
return browser_context_->prefs()
|
||||
->Get(spellcheck::prefs::kSpellCheckDictionaries)
|
||||
->Clone();
|
||||
}
|
||||
|
||||
void Session::SetSpellCheckerLanguages(
|
||||
gin_helper::ErrorThrower thrower,
|
||||
const std::vector<std::string>& languages) {
|
||||
base::ListValue language_codes;
|
||||
for (const std::string& lang : languages) {
|
||||
std::string code = spellcheck::GetCorrespondingSpellCheckLanguage(lang);
|
||||
if (code.empty()) {
|
||||
thrower.ThrowError("Invalid language code provided: \"" + lang +
|
||||
"\" is not a valid language code");
|
||||
return;
|
||||
}
|
||||
language_codes.AppendString(code);
|
||||
}
|
||||
browser_context_->prefs()->Set(spellcheck::prefs::kSpellCheckDictionaries,
|
||||
language_codes);
|
||||
}
|
||||
|
||||
void SetSpellCheckerDictionaryDownloadURL(gin_helper::ErrorThrower thrower,
|
||||
const GURL& url) {
|
||||
if (!url.is_valid()) {
|
||||
thrower.ThrowError(
|
||||
"The URL you provided to setSpellCheckerDictionaryDownloadURL is not a "
|
||||
"valid URL");
|
||||
return;
|
||||
}
|
||||
SpellcheckHunspellDictionary::SetDownloadURLForTesting(url);
|
||||
}
|
||||
#endif
|
||||
|
||||
// static
|
||||
mate::Handle<Session> Session::CreateFrom(v8::Isolate* isolate,
|
||||
AtomBrowserContext* browser_context) {
|
||||
@@ -716,6 +758,14 @@ void Session::BuildPrototype(v8::Isolate* isolate,
|
||||
.SetMethod("getPreloads", &Session::GetPreloads)
|
||||
#if BUILDFLAG(ENABLE_ELECTRON_EXTENSIONS)
|
||||
.SetMethod("loadChromeExtension", &Session::LoadChromeExtension)
|
||||
#endif
|
||||
#if BUILDFLAG(ENABLE_BUILTIN_SPELLCHECKER)
|
||||
.SetMethod("getSpellCheckerLanguages", &Session::GetSpellCheckerLanguages)
|
||||
.SetMethod("setSpellCheckerLanguages", &Session::SetSpellCheckerLanguages)
|
||||
.SetProperty("availableSpellCheckerLanguages",
|
||||
&spellcheck::SpellCheckLanguages)
|
||||
.SetMethod("setSpellCheckerDictionaryDownloadURL",
|
||||
&SetSpellCheckerDictionaryDownloadURL)
|
||||
#endif
|
||||
.SetMethod("preconnect", &Session::Preconnect)
|
||||
.SetProperty("cookies", &Session::Cookies)
|
||||
|
||||
@@ -87,6 +87,11 @@ class Session : public mate::TrackableObject<Session>,
|
||||
v8::Local<v8::Value> WebRequest(v8::Isolate* isolate);
|
||||
v8::Local<v8::Value> NetLog(v8::Isolate* isolate);
|
||||
void Preconnect(const mate::Dictionary& options, mate::Arguments* args);
|
||||
#if BUILDFLAG(ENABLE_BUILTIN_SPELLCHECKER)
|
||||
base::Value GetSpellCheckerLanguages();
|
||||
void SetSpellCheckerLanguages(gin_helper::ErrorThrower thrower,
|
||||
const std::vector<std::string>& languages);
|
||||
#endif
|
||||
|
||||
#if BUILDFLAG(ENABLE_ELECTRON_EXTENSIONS)
|
||||
void LoadChromeExtension(const base::FilePath extension_path);
|
||||
|
||||
@@ -100,6 +100,11 @@
|
||||
#include "net/ssl/client_cert_store.h"
|
||||
#endif
|
||||
|
||||
#if BUILDFLAG(ENABLE_BUILTIN_SPELLCHECKER)
|
||||
#include "chrome/browser/spellchecker/spell_check_host_chrome_impl.h" // nogncheck
|
||||
#include "components/spellcheck/common/spellcheck.mojom.h" // nogncheck
|
||||
#endif
|
||||
|
||||
#if BUILDFLAG(ENABLE_PEPPER_FLASH)
|
||||
#include "chrome/browser/renderer_host/pepper/chrome_browser_pepper_host_factory.h"
|
||||
#endif // BUILDFLAG(ENABLE_PEPPER_FLASH)
|
||||
@@ -768,6 +773,18 @@ network::mojom::NetworkContext* AtomBrowserClient::GetSystemNetworkContext() {
|
||||
return g_browser_process->system_network_context_manager()->GetContext();
|
||||
}
|
||||
|
||||
#if BUILDFLAG(ENABLE_BUILTIN_SPELLCHECKER)
|
||||
void AtomBrowserClient::BindHostReceiverForRenderer(
|
||||
content::RenderProcessHost* render_process_host,
|
||||
mojo::GenericPendingReceiver receiver) {
|
||||
if (auto host_receiver = receiver.As<spellcheck::mojom::SpellCheckHost>()) {
|
||||
SpellCheckHostChromeImpl::Create(render_process_host->GetID(),
|
||||
std::move(host_receiver));
|
||||
return;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
base::Optional<service_manager::Manifest>
|
||||
AtomBrowserClient::GetServiceManifestOverlay(base::StringPiece name) {
|
||||
if (name == content::mojom::kBrowserServiceName)
|
||||
|
||||
@@ -148,6 +148,11 @@ class AtomBrowserClient : public content::ContentBrowserClient,
|
||||
bool in_memory,
|
||||
const base::FilePath& relative_partition_path) override;
|
||||
network::mojom::NetworkContext* GetSystemNetworkContext() override;
|
||||
#if BUILDFLAG(ENABLE_BUILTIN_SPELLCHECKER)
|
||||
void BindHostReceiverForRenderer(
|
||||
content::RenderProcessHost* render_process_host,
|
||||
mojo::GenericPendingReceiver receiver) override;
|
||||
#endif
|
||||
base::Optional<service_manager::Manifest> GetServiceManifestOverlay(
|
||||
base::StringPiece name) override;
|
||||
content::MediaObserver* GetMediaObserver() override;
|
||||
|
||||
@@ -47,8 +47,6 @@
|
||||
#include "shell/common/options_switches.h"
|
||||
|
||||
#if BUILDFLAG(ENABLE_ELECTRON_EXTENSIONS)
|
||||
#include "components/pref_registry/pref_registry_syncable.h"
|
||||
#include "components/user_prefs/user_prefs.h"
|
||||
#include "extensions/browser/browser_context_keyed_service_factories.h"
|
||||
#include "extensions/browser/extension_pref_store.h"
|
||||
#include "extensions/browser/extension_pref_value_map_factory.h"
|
||||
@@ -62,6 +60,19 @@
|
||||
#include "shell/common/extensions/atom_extensions_client.h"
|
||||
#endif // BUILDFLAG(ENABLE_ELECTRON_EXTENSIONS)
|
||||
|
||||
#if BUILDFLAG(ENABLE_ELECTRON_EXTENSIONS) || \
|
||||
BUILDFLAG(ENABLE_BUILTIN_SPELLCHECKER)
|
||||
#include "components/pref_registry/pref_registry_syncable.h"
|
||||
#include "components/user_prefs/user_prefs.h"
|
||||
#endif
|
||||
|
||||
#if BUILDFLAG(ENABLE_BUILTIN_SPELLCHECKER)
|
||||
#include "base/i18n/rtl.h"
|
||||
#include "components/language/core/browser/language_prefs.h"
|
||||
#include "components/spellcheck/browser/pref_names.h"
|
||||
#include "components/spellcheck/common/spellcheck_common.h"
|
||||
#endif
|
||||
|
||||
using content::BrowserThread;
|
||||
|
||||
namespace electron {
|
||||
@@ -101,6 +112,7 @@ AtomBrowserContext::AtomBrowserContext(const std::string& partition,
|
||||
base::PathService::Get(DIR_APP_DATA, &path_);
|
||||
path_ = path_.Append(base::FilePath::FromUTF8Unsafe(GetApplicationName()));
|
||||
base::PathService::Override(DIR_USER_DATA, path_);
|
||||
base::PathService::Override(chrome::DIR_USER_DATA, path_);
|
||||
}
|
||||
|
||||
if (!in_memory && !partition.empty())
|
||||
@@ -155,7 +167,10 @@ void AtomBrowserContext::InitPrefs() {
|
||||
ExtensionPrefValueMapFactory::GetForBrowserContext(this),
|
||||
IsOffTheRecord());
|
||||
prefs_factory.set_extension_prefs(ext_pref_store);
|
||||
#endif
|
||||
|
||||
#if BUILDFLAG(ENABLE_ELECTRON_EXTENSIONS) || \
|
||||
BUILDFLAG(ENABLE_BUILTIN_SPELLCHECKER)
|
||||
auto registry = WrapRefCounted(new user_prefs::PrefRegistrySyncable);
|
||||
#else
|
||||
auto registry = WrapRefCounted(new PrefRegistrySimple);
|
||||
@@ -176,13 +191,36 @@ void AtomBrowserContext::InitPrefs() {
|
||||
extensions::ExtensionPrefs::RegisterProfilePrefs(registry.get());
|
||||
#endif
|
||||
|
||||
#if BUILDFLAG(ENABLE_BUILTIN_SPELLCHECKER)
|
||||
BrowserContextDependencyManager::GetInstance()
|
||||
->RegisterProfilePrefsForServices(registry.get());
|
||||
|
||||
language::LanguagePrefs::RegisterProfilePrefs(registry.get());
|
||||
#endif
|
||||
|
||||
prefs_ = prefs_factory.Create(
|
||||
registry.get(),
|
||||
std::make_unique<PrefStoreDelegate>(weak_factory_.GetWeakPtr()));
|
||||
prefs_->UpdateCommandLinePrefStore(new ValueMapPrefStore);
|
||||
#if BUILDFLAG(ENABLE_ELECTRON_EXTENSIONS)
|
||||
#if BUILDFLAG(ENABLE_ELECTRON_EXTENSIONS) || \
|
||||
BUILDFLAG(ENABLE_BUILTIN_SPELLCHECKER)
|
||||
user_prefs::UserPrefs::Set(this, prefs_.get());
|
||||
#endif
|
||||
|
||||
#if BUILDFLAG(ENABLE_BUILTIN_SPELLCHECKER)
|
||||
auto* current_dictionaries =
|
||||
prefs()->Get(spellcheck::prefs::kSpellCheckDictionaries);
|
||||
// No configured dictionaries, the default will be en-US
|
||||
if (current_dictionaries->GetList().size() == 0) {
|
||||
std::string default_code = spellcheck::GetCorrespondingSpellCheckLanguage(
|
||||
base::i18n::GetConfiguredLocale());
|
||||
if (!default_code.empty()) {
|
||||
base::ListValue language_codes;
|
||||
language_codes.AppendString(default_code);
|
||||
prefs()->Set(spellcheck::prefs::kSpellCheckDictionaries, language_codes);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void AtomBrowserContext::SetUserAgent(const std::string& user_agent) {
|
||||
|
||||
@@ -103,6 +103,10 @@
|
||||
#include "shell/common/extensions/atom_extensions_client.h"
|
||||
#endif // BUILDFLAG(ENABLE_ELECTRON_EXTENSIONS)
|
||||
|
||||
#if BUILDFLAG(ENABLE_BUILTIN_SPELLCHECKER)
|
||||
#include "chrome/browser/spellchecker/spellcheck_factory.h" // nogncheck
|
||||
#endif
|
||||
|
||||
namespace electron {
|
||||
|
||||
namespace {
|
||||
@@ -442,6 +446,10 @@ void AtomBrowserMainParts::PreMainMessageLoopRun() {
|
||||
extensions::electron::EnsureBrowserContextKeyedServiceFactoriesBuilt();
|
||||
#endif
|
||||
|
||||
#if BUILDFLAG(ENABLE_BUILTIN_SPELLCHECKER)
|
||||
SpellcheckServiceFactory::GetInstance();
|
||||
#endif
|
||||
|
||||
// url::Add*Scheme are not threadsafe, this helps prevent data races.
|
||||
url::LockSchemeRegistries();
|
||||
|
||||
|
||||
@@ -50,8 +50,8 @@ END
|
||||
//
|
||||
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
FILEVERSION 8,0,0,20191023
|
||||
PRODUCTVERSION 8,0,0,20191023
|
||||
FILEVERSION 8,0,0,2
|
||||
PRODUCTVERSION 8,0,0,2
|
||||
FILEFLAGSMASK 0x3fL
|
||||
#ifdef _DEBUG
|
||||
FILEFLAGS 0x1L
|
||||
|
||||
@@ -54,9 +54,9 @@ class FileChooserDialog {
|
||||
if (!settings.button_label.empty())
|
||||
confirm_text = settings.button_label.c_str();
|
||||
else if (action == GTK_FILE_CHOOSER_ACTION_SAVE)
|
||||
confirm_text = gtk_util::kOpenLabel;
|
||||
else if (action == GTK_FILE_CHOOSER_ACTION_OPEN)
|
||||
confirm_text = gtk_util::kSaveLabel;
|
||||
else if (action == GTK_FILE_CHOOSER_ACTION_OPEN)
|
||||
confirm_text = gtk_util::kOpenLabel;
|
||||
|
||||
dialog_ = gtk_file_chooser_dialog_new(
|
||||
settings.title.c_str(), nullptr, action, gtk_util::kCancelLabel,
|
||||
|
||||
@@ -144,6 +144,9 @@ WebContentsPreferences::WebContentsPreferences(
|
||||
SetDefaultBoolIfUndefined(options::kScrollBounce, false);
|
||||
#endif
|
||||
SetDefaultBoolIfUndefined(options::kOffscreen, false);
|
||||
#if BUILDFLAG(ENABLE_BUILTIN_SPELLCHECKER)
|
||||
SetDefaultBoolIfUndefined(options::kSpellcheck, false);
|
||||
#endif
|
||||
|
||||
// If this is a <webview> tag, and the embedder is offscreen-rendered, then
|
||||
// this WebContents is also offscreen-rendered.
|
||||
@@ -414,6 +417,12 @@ void WebContentsPreferences::AppendCommandLineSwitches(
|
||||
if (IsEnabled(options::kNodeIntegrationInSubFrames))
|
||||
command_line->AppendSwitch(switches::kNodeIntegrationInSubFrames);
|
||||
|
||||
#if BUILDFLAG(ENABLE_BUILTIN_SPELLCHECKER)
|
||||
if (IsEnabled(options::kSpellcheck)) {
|
||||
command_line->AppendSwitch(switches::kEnableSpellcheck);
|
||||
}
|
||||
#endif
|
||||
|
||||
// We are appending args to a webContents so let's save the current state
|
||||
// of our preferences object so that during the lifetime of the WebContents
|
||||
// we can fetch the options used to initally configure the WebContents
|
||||
|
||||
@@ -16,29 +16,37 @@ namespace electron {
|
||||
// static
|
||||
void RemoteCallbackFreer::BindTo(v8::Isolate* isolate,
|
||||
v8::Local<v8::Object> target,
|
||||
int frame_id,
|
||||
const std::string& context_id,
|
||||
int object_id,
|
||||
content::WebContents* web_contents) {
|
||||
new RemoteCallbackFreer(isolate, target, context_id, object_id, web_contents);
|
||||
new RemoteCallbackFreer(isolate, target, frame_id, context_id, object_id,
|
||||
web_contents);
|
||||
}
|
||||
|
||||
RemoteCallbackFreer::RemoteCallbackFreer(v8::Isolate* isolate,
|
||||
v8::Local<v8::Object> target,
|
||||
int frame_id,
|
||||
const std::string& context_id,
|
||||
int object_id,
|
||||
content::WebContents* web_contents)
|
||||
: ObjectLifeMonitor(isolate, target),
|
||||
content::WebContentsObserver(web_contents),
|
||||
frame_id_(frame_id),
|
||||
context_id_(context_id),
|
||||
object_id_(object_id) {}
|
||||
|
||||
RemoteCallbackFreer::~RemoteCallbackFreer() = default;
|
||||
|
||||
void RemoteCallbackFreer::RunDestructor() {
|
||||
auto* frame_host = web_contents()->GetMainFrame();
|
||||
if (frame_host) {
|
||||
auto frames = web_contents()->GetAllFrames();
|
||||
auto iter = std::find_if(frames.begin(), frames.end(), [this](auto* f) {
|
||||
return f->GetRoutingID() == frame_id_;
|
||||
});
|
||||
|
||||
if (iter != frames.end() && (*iter)->IsRenderFrameLive()) {
|
||||
mojom::ElectronRendererAssociatedPtr electron_ptr;
|
||||
frame_host->GetRemoteAssociatedInterfaces()->GetInterface(
|
||||
(*iter)->GetRemoteAssociatedInterfaces()->GetInterface(
|
||||
mojo::MakeRequest(&electron_ptr));
|
||||
electron_ptr->DereferenceRemoteJSCallback(context_id_, object_id_);
|
||||
}
|
||||
|
||||
@@ -17,6 +17,7 @@ class RemoteCallbackFreer : public ObjectLifeMonitor,
|
||||
public:
|
||||
static void BindTo(v8::Isolate* isolate,
|
||||
v8::Local<v8::Object> target,
|
||||
int frame_id,
|
||||
const std::string& context_id,
|
||||
int object_id,
|
||||
content::WebContents* web_conents);
|
||||
@@ -24,6 +25,7 @@ class RemoteCallbackFreer : public ObjectLifeMonitor,
|
||||
protected:
|
||||
RemoteCallbackFreer(v8::Isolate* isolate,
|
||||
v8::Local<v8::Object> target,
|
||||
int frame_id,
|
||||
const std::string& context_id,
|
||||
int object_id,
|
||||
content::WebContents* web_conents);
|
||||
@@ -35,6 +37,7 @@ class RemoteCallbackFreer : public ObjectLifeMonitor,
|
||||
void RenderViewDeleted(content::RenderViewHost*) override;
|
||||
|
||||
private:
|
||||
int frame_id_;
|
||||
std::string context_id_;
|
||||
int object_id_;
|
||||
|
||||
|
||||
@@ -119,6 +119,9 @@ v8::Local<v8::Value> Converter<ContextMenuParamsWithWebContents>::ToV8(
|
||||
dict.Set("selectionText", params.selection_text);
|
||||
dict.Set("titleText", params.title_text);
|
||||
dict.Set("misspelledWord", params.misspelled_word);
|
||||
#if BUILDFLAG(ENABLE_BUILTIN_SPELLCHECKER)
|
||||
dict.Set("dictionarySuggestions", params.dictionary_suggestions);
|
||||
#endif
|
||||
dict.Set("frameCharset", params.frame_charset);
|
||||
dict.Set("inputFieldType", params.input_field_type);
|
||||
dict.Set("menuSourceType", params.source_type);
|
||||
|
||||
@@ -173,6 +173,10 @@ const char kWebGL[] = "webgl";
|
||||
// navigation.
|
||||
const char kNavigateOnDragDrop[] = "navigateOnDragDrop";
|
||||
|
||||
#if BUILDFLAG(ENABLE_BUILTIN_SPELLCHECKER)
|
||||
const char kSpellcheck[] = "spellcheck";
|
||||
#endif
|
||||
|
||||
#if BUILDFLAG(ENABLE_REMOTE_MODULE)
|
||||
const char kEnableRemoteModule[] = "enableRemoteModule";
|
||||
#endif
|
||||
@@ -267,6 +271,10 @@ const char kAuthNegotiateDelegateWhitelist[] =
|
||||
// If set, include the port in generated Kerberos SPNs.
|
||||
const char kEnableAuthNegotiatePort[] = "enable-auth-negotiate-port";
|
||||
|
||||
#if BUILDFLAG(ENABLE_BUILTIN_SPELLCHECKER)
|
||||
const char kEnableSpellcheck[] = "enable-spellcheck";
|
||||
#endif
|
||||
|
||||
#if BUILDFLAG(ENABLE_REMOTE_MODULE)
|
||||
const char kEnableRemoteModule[] = "enable-remote-module";
|
||||
#endif
|
||||
|
||||
@@ -84,6 +84,10 @@ extern const char kTextAreasAreResizable[];
|
||||
extern const char kWebGL[];
|
||||
extern const char kNavigateOnDragDrop[];
|
||||
|
||||
#if BUILDFLAG(ENABLE_BUILTIN_SPELLCHECKER)
|
||||
extern const char kSpellcheck[];
|
||||
#endif
|
||||
|
||||
#if BUILDFLAG(ENABLE_REMOTE_MODULE)
|
||||
extern const char kEnableRemoteModule[];
|
||||
#endif
|
||||
@@ -134,6 +138,10 @@ extern const char kAuthServerWhitelist[];
|
||||
extern const char kAuthNegotiateDelegateWhitelist[];
|
||||
extern const char kEnableAuthNegotiatePort[];
|
||||
|
||||
#if BUILDFLAG(ENABLE_BUILTIN_SPELLCHECKER)
|
||||
extern const char kEnableSpellcheck[];
|
||||
#endif
|
||||
|
||||
#if BUILDFLAG(ENABLE_REMOTE_MODULE)
|
||||
extern const char kEnableRemoteModule[];
|
||||
#endif
|
||||
|
||||
@@ -121,7 +121,9 @@ void AtomRendererClient::DidCreateScriptContext(
|
||||
node::tracing::TraceEventHelper::SetAgent(node::CreateAgent());
|
||||
|
||||
// Setup node environment for each window.
|
||||
DCHECK(node::InitializeContext(renderer_context));
|
||||
bool initialized = node::InitializeContext(renderer_context);
|
||||
CHECK(initialized);
|
||||
|
||||
node::Environment* env =
|
||||
node_bindings_->CreateEnvironment(renderer_context, nullptr, true);
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "base/command_line.h"
|
||||
@@ -46,6 +47,11 @@
|
||||
#include <shlobj.h>
|
||||
#endif
|
||||
|
||||
#if BUILDFLAG(ENABLE_BUILTIN_SPELLCHECKER)
|
||||
#include "components/spellcheck/renderer/spellcheck.h"
|
||||
#include "components/spellcheck/renderer/spellcheck_provider.h"
|
||||
#endif
|
||||
|
||||
#if BUILDFLAG(ENABLE_PDF_VIEWER)
|
||||
#include "shell/common/atom_constants.h"
|
||||
#endif // BUILDFLAG(ENABLE_PDF_VIEWER)
|
||||
@@ -149,6 +155,11 @@ void RendererClientBase::RenderThreadStarted() {
|
||||
thread->AddObserver(extensions_renderer_client_->GetDispatcher());
|
||||
#endif
|
||||
|
||||
#if BUILDFLAG(ENABLE_BUILTIN_SPELLCHECKER)
|
||||
if (command_line->HasSwitch(switches::kEnableSpellcheck))
|
||||
spellcheck_ = std::make_unique<SpellCheck>(®istry_, this);
|
||||
#endif
|
||||
|
||||
blink::WebCustomElement::AddEmbedderCustomElementName("webview");
|
||||
blink::WebCustomElement::AddEmbedderCustomElementName("browserplugin");
|
||||
|
||||
@@ -263,8 +274,37 @@ void RendererClientBase::RenderFrameCreated(
|
||||
|
||||
dispatcher->OnRenderFrameCreated(render_frame);
|
||||
#endif
|
||||
|
||||
#if BUILDFLAG(ENABLE_BUILTIN_SPELLCHECKER)
|
||||
auto* command_line = base::CommandLine::ForCurrentProcess();
|
||||
if (command_line->HasSwitch(switches::kEnableSpellcheck))
|
||||
new SpellCheckProvider(render_frame, spellcheck_.get(), this);
|
||||
#endif
|
||||
}
|
||||
|
||||
#if BUILDFLAG(ENABLE_BUILTIN_SPELLCHECKER)
|
||||
void RendererClientBase::BindReceiverOnMainThread(
|
||||
mojo::GenericPendingReceiver receiver) {
|
||||
// TODO(crbug.com/977637): Get rid of the use of BinderRegistry here. This is
|
||||
// only used to bind a spellcheck interface.
|
||||
std::string interface_name = *receiver.interface_name();
|
||||
auto pipe = receiver.PassPipe();
|
||||
registry_.TryBindInterface(interface_name, &pipe);
|
||||
}
|
||||
|
||||
void RendererClientBase::GetInterface(
|
||||
const std::string& interface_name,
|
||||
mojo::ScopedMessagePipeHandle interface_pipe) {
|
||||
// TODO(crbug.com/977637): Get rid of the use of this implementation of
|
||||
// |service_manager::LocalInterfaceProvider|. This was done only to avoid
|
||||
// churning spellcheck code while eliminating the "chrome" and
|
||||
// "chrome_renderer" services. Spellcheck is (and should remain) the only
|
||||
// consumer of this implementation.
|
||||
content::RenderThread::Get()->BindHostReceiver(
|
||||
mojo::GenericPendingReceiver(interface_name, std::move(interface_pipe)));
|
||||
}
|
||||
#endif
|
||||
|
||||
void RendererClientBase::DidClearWindowObject(
|
||||
content::RenderFrame* render_frame) {
|
||||
// Make sure every page will get a script context created.
|
||||
|
||||
@@ -19,6 +19,13 @@
|
||||
#include "chrome/renderer/media/chrome_key_systems_provider.h" // nogncheck
|
||||
#endif
|
||||
|
||||
#if BUILDFLAG(ENABLE_BUILTIN_SPELLCHECKER)
|
||||
#include "services/service_manager/public/cpp/binder_registry.h"
|
||||
#include "services/service_manager/public/cpp/local_interface_provider.h"
|
||||
|
||||
class SpellCheck;
|
||||
#endif
|
||||
|
||||
namespace network_hints {
|
||||
class PrescientNetworkingDispatcher;
|
||||
}
|
||||
@@ -35,11 +42,24 @@ namespace electron {
|
||||
class AtomExtensionsRendererClient;
|
||||
#endif
|
||||
|
||||
class RendererClientBase : public content::ContentRendererClient {
|
||||
class RendererClientBase : public content::ContentRendererClient
|
||||
#if BUILDFLAG(ENABLE_BUILTIN_SPELLCHECKER)
|
||||
,
|
||||
public service_manager::LocalInterfaceProvider
|
||||
#endif
|
||||
{
|
||||
public:
|
||||
RendererClientBase();
|
||||
~RendererClientBase() override;
|
||||
|
||||
#if BUILDFLAG(ENABLE_BUILTIN_SPELLCHECKER)
|
||||
// service_manager::LocalInterfaceProvider implementation.
|
||||
void GetInterface(const std::string& name,
|
||||
mojo::ScopedMessagePipeHandle request_handle) override;
|
||||
|
||||
void BindReceiverOnMainThread(mojo::GenericPendingReceiver receiver) override;
|
||||
#endif
|
||||
|
||||
virtual void DidCreateScriptContext(v8::Handle<v8::Context> context,
|
||||
content::RenderFrame* render_frame);
|
||||
virtual void WillReleaseScriptContext(v8::Handle<v8::Context> context,
|
||||
@@ -108,6 +128,11 @@ class RendererClientBase : public content::ContentRendererClient {
|
||||
std::string renderer_client_id_;
|
||||
// An increasing ID used for indentifying an V8 context in this process.
|
||||
int64_t next_context_id_ = 0;
|
||||
|
||||
#if BUILDFLAG(ENABLE_BUILTIN_SPELLCHECKER)
|
||||
std::unique_ptr<SpellCheck> spellcheck_;
|
||||
service_manager::BinderRegistry registry_;
|
||||
#endif
|
||||
};
|
||||
|
||||
} // namespace electron
|
||||
|
||||
@@ -48,7 +48,8 @@ void WebWorkerObserver::ContextCreated(v8::Local<v8::Context> worker_context) {
|
||||
node_bindings_->PrepareMessageLoop();
|
||||
|
||||
// Setup node environment for each window.
|
||||
DCHECK(node::InitializeContext(worker_context));
|
||||
bool initialized = node::InitializeContext(worker_context);
|
||||
CHECK(initialized);
|
||||
node::Environment* env =
|
||||
node_bindings_->CreateEnvironment(worker_context, nullptr, true);
|
||||
|
||||
|
||||
@@ -1402,6 +1402,19 @@ describe('webContents module', () => {
|
||||
const data = await w.webContents.printToPDF({})
|
||||
expect(data).to.be.an.instanceof(Buffer).that.is.not.empty()
|
||||
})
|
||||
|
||||
it('does not crash when called multiple times', async () => {
|
||||
const w = new BrowserWindow({ show: false, webPreferences: { sandbox: true } })
|
||||
await w.loadURL('data:text/html,<h1>Hello, World!</h1>')
|
||||
const promises = []
|
||||
for (let i = 0; i < 2; i++) {
|
||||
promises.push(w.webContents.printToPDF({}))
|
||||
}
|
||||
const results = await Promise.all(promises)
|
||||
for (const data of results) {
|
||||
expect(data).to.be.an.instanceof(Buffer).that.is.not.empty()
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
describe('PictureInPicture video', () => {
|
||||
|
||||
@@ -109,6 +109,20 @@ ifdescribe(!process.electronBinding('features').isExtensionsEnabled())('chrome e
|
||||
|
||||
afterEach(() => closeWindow(w).then(() => { w = null as unknown as BrowserWindow }))
|
||||
|
||||
it('chrome.runtime.connect parses arguments properly', async function () {
|
||||
await w.loadURL('about:blank')
|
||||
|
||||
const promise = emittedOnce(w.webContents, 'console-message')
|
||||
|
||||
const message = { method: 'connect' }
|
||||
w.webContents.executeJavaScript(`window.postMessage('${JSON.stringify(message)}', '*')`)
|
||||
|
||||
const [,, responseString] = await promise
|
||||
const response = JSON.parse(responseString)
|
||||
|
||||
expect(response).to.be.true()
|
||||
})
|
||||
|
||||
it('runtime.getManifest returns extension manifest', async () => {
|
||||
const actualManifest = (() => {
|
||||
const data = fs.readFileSync(path.join(fixtures, 'extensions/chrome-api/manifest.json'), 'utf-8')
|
||||
|
||||
11
spec/fixtures/extensions/chrome-api/main.js
vendored
11
spec/fixtures/extensions/chrome-api/main.js
vendored
@@ -5,6 +5,17 @@ chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
|
||||
})
|
||||
|
||||
const testMap = {
|
||||
connect () {
|
||||
let success = false
|
||||
try {
|
||||
chrome.runtime.connect(chrome.runtime.id)
|
||||
chrome.runtime.connect(chrome.runtime.id, { name: 'content-script' })
|
||||
chrome.runtime.connect({ name: 'content-script' })
|
||||
success = true
|
||||
} finally {
|
||||
console.log(JSON.stringify(success))
|
||||
}
|
||||
},
|
||||
getManifest () {
|
||||
const manifest = chrome.runtime.getManifest()
|
||||
console.log(JSON.stringify(manifest))
|
||||
|
||||
2
typings/internal-ambient.d.ts
vendored
2
typings/internal-ambient.d.ts
vendored
@@ -30,7 +30,7 @@ declare namespace NodeJS {
|
||||
deleteHiddenValue(obj: any, key: string): void;
|
||||
requestGarbageCollectionForTesting(): void;
|
||||
createDoubleIDWeakMap(): any;
|
||||
setRemoteCallbackFreer(fn: Function, contextId: String, id: number, sender: any): void
|
||||
setRemoteCallbackFreer(fn: Function, frameId: number, contextId: String, id: number, sender: any): void
|
||||
}
|
||||
|
||||
interface Process {
|
||||
|
||||
Reference in New Issue
Block a user