Compare commits

..

38 Commits

Author SHA1 Message Date
Electron Bot
8cf55a674e Bump v9.0.0-beta.24 2020-05-11 08:31:56 -07:00
Erick Zhao
4542e2eef9 docs: document supported extensions apis (#22021) (#23434)
* docs: document supported extensions apis

* Update extensions.md

* Update README.md

* Apply suggestions from code review

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

Co-authored-by: Mark Lee <malept@users.noreply.github.com>

Co-authored-by: Jeremy Apthorp <jeremya@chromium.org>
Co-authored-by: Mark Lee <malept@users.noreply.github.com>
2020-05-11 10:49:32 +09:00
trop[bot]
5009538045 fix: do not initialize extension system in in-memory sessions (#23472)
* fix: do not initialize any extension related logic in OffTheRecord contexts

* chore: fix linting

Co-authored-by: Samuel Attard <samuel.r.attard@gmail.com>
2020-05-08 12:43:07 -07:00
Jeremy Apthorp
2f8150891b fix: crashReporter incompatible with sandbox on Linux (#23265) (#23461) 2020-05-08 11:41:42 -07:00
Charles Kerr
4b9df8c248 feat: add force option to app.focus() (#22612) (#23447)
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2020-05-07 12:16:24 -07:00
trop[bot]
0920d01c9c fix: multiple extension filters on macOS (#23450)
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2020-05-07 11:57:45 -07:00
Electron Bot
520e0bcc43 chore: bump chromium in DEPS to 83.0.4103.45 (#23446) 2020-05-07 08:56:40 -07:00
Electron Bot
6be41c2f8e Bump v9.0.0-beta.23 2020-05-07 08:32:03 -07:00
Electron Bot
b997c562f7 chore: bump chromium in DEPS to 83.0.4103.44 (#23424) 2020-05-06 11:00:45 -07:00
Electron Bot
2c9fe0b951 chore: bump chromium to 83.0.4103.42 (9-x-y) (#23416)
* chore: bump chromium in DEPS to 83.0.4103.42

* update patches

Co-authored-by: Electron Bot <anonymous@electronjs.org>
2020-05-05 10:35:19 -07:00
Charles Kerr
4445182739 chore: remove redundant release note items. (#23408)
Backport of #23335. See that PR for details.
2020-05-05 08:38:16 -07:00
Charles Kerr
e549aec5fc fix: respect system language preferences on Win/macOS (#23247) (#23405)
This commit fixes https://github.com/electron/electron/issues/18829

Previously the full preferences set to OS was not given to Chromium.

Also, this commit improves fallback font selection for CJK text.
Chromium uses browser languages to determine fallback fonts on Windows,
especially kanji/han characters in CJK.

For instance, when user sets 'en-US, ja-JP' to Accept-Language,
while Chromium chooses Japanese font for kanji text, but Electron
chooses Chinese font.  This is because only the first language was given
to Accept-Language on Electron.

This patch is based on https://github.com/electron/electron/pull/15532

Co-authored-by: Nitish Sakhawalkar <nitsakh@icloud.com>
Co-authored-by: Kasumi Hanazuki <kasumi@rollingapple.net>

Co-authored-by: Nitish Sakhawalkar <nitsakh@icloud.com>
Co-authored-by: Kasumi Hanazuki <kasumi@rollingapple.net>

Co-authored-by: Sorah Fukumori <her@sorah.jp>
Co-authored-by: Nitish Sakhawalkar <nitsakh@icloud.com>
Co-authored-by: Kasumi Hanazuki <kasumi@rollingapple.net>
2020-05-04 19:41:17 -07:00
trop[bot]
c1311480c0 fix: guard pdf behind correct buildflags (#23406)
Co-authored-by: deepak1556 <hop2deep@gmail.com>
2020-05-04 19:38:24 -07:00
Shelley Vohr
6c78c9274a refactor: return null when passing empty menu templates (#23401) 2020-05-04 14:39:58 -05:00
Electron Bot
d50fb2938b chore: bump chromium to 83.0.4103.41 (9-x-y) (#23378)
* chore: bump chromium in DEPS to 83.0.4103.38

* chore: bump chromium in DEPS to 83.0.4103.39

* chore: bump chromium in DEPS to 83.0.4103.40

* chore: bump chromium in DEPS to 83.0.4103.41
2020-05-04 08:13:12 -07:00
trop[bot]
5414c8dd7e fix: hold browser_context instead of render_frame_host to fix lifetime issues (#23375)
Co-authored-by: Paul Frazee <pfrazee@gmail.com>
2020-05-03 16:19:52 -07:00
trop[bot]
ee68e1a787 fix: ensure guest-embedder map is updated when webview is removed (#23374)
There are use cases of webview where the container holding the webview is not
actually destroyed first, instead just webview gets removed from DOM, in such
situations the browser process map is not updated accordingly and holds reference
to stale guest contents, and any window operations like scroll, resize or keyboard
events that has to chain through browser embedder will lead to UAF crash.

Ref: https://github.com/microsoft/vscode/issues/92420

Co-authored-by: deepak1556 <hop2deep@gmail.com>
2020-05-01 12:32:35 -07:00
Charles Kerr
e3d4f999ca fix: undo and redo broken in webviews (#23370)
* fix: undo and redo broken in webviews

Backport upstream fix https://chromium-review.googlesource.com/c/chromium/src/+/2135187 to 9-x-y.

* chore: re-run git-export-patches to refresh patch
2020-04-30 17:18:27 -05:00
trop[bot]
b62df312f2 docs: event.newGuest for new-window in WebContents and webContents in BrowsweWindow's constructor (#23356)
* docs: `newGuest` in `WebContents` and `webContents` in `BrowsweWindow`

According to the example codes in the documentation of `new-window`
event in `WebContents`, `webContents` in `BrowsweWindow` constructor
options and `newGuest` in `event` argument of `new-window` handler are
both existing but documented. This patch is for adding the related
documentations. Also, it provides typescript-definitations for these
two properties.

* Remove the documnent of `webContents` in BrowserWindow constructor option.

Co-authored-by: Sean Lee <sean.l@canva.com>
2020-04-30 15:42:14 -05:00
trop[bot]
9ba491116c ci: make sure msedge isn't running at end of woa test (#23361)
Co-authored-by: John Kleinschmidt <jkleinsc@github.com>
2020-04-30 14:14:20 -04:00
Electron Bot
c74dd6eee7 chore: bump chromium in DEPS to 83.0.4103.36 (#23348) 2020-04-30 11:02:09 -07:00
Electron Bot
2d888dc7b5 Bump v9.0.0-beta.22 2020-04-30 08:33:00 -07:00
trop[bot]
1024544573 fix: do not leak IPC or context bridge promises (#23338)
Co-authored-by: Samuel Attard <samuel.r.attard@gmail.com>
2020-04-29 17:23:25 -07:00
trop[bot]
ebbd3081b9 fix: build when some buildflags are disabled (#23337)
Co-authored-by: deepak1556 <hop2deep@gmail.com>
2020-04-29 16:09:42 -07:00
trop[bot]
dc3dc81beb feat: support fullScreen BrowserWindow property (#23330)
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2020-04-29 12:16:11 -07:00
Electron Bot
6babb8a9fe chore: bump chromium in DEPS to 83.0.4103.34 (#23326) 2020-04-29 14:06:23 -04:00
trop[bot]
088e23d604 menu-item.md remove duplicate options (#23296)
Co-authored-by: szTheory <szTheory@users.noreply.github.com>
2020-04-28 23:17:11 -07:00
Electron Bot
d0a764bd16 chore: bump chromium to 83.0.4103.31 (9-x-y) (#23270)
* chore: bump chromium in DEPS to 83.0.4103.27

* chore: bump chromium in DEPS to 83.0.4103.28

* chore: bump chromium in DEPS to 83.0.4103.29

* chore: bump chromium in DEPS to 83.0.4103.30

* chore: bump chromium in DEPS to 83.0.4103.31

* update patches

Co-authored-by: Electron Bot <anonymous@electronjs.org>
2020-04-28 17:20:24 -07:00
Electron Bot
d47b788e03 Bump v9.0.0-beta.21 2020-04-27 18:23:30 -07:00
Samuel Attard
a985865f65 refactor: port window-setup to use ctx bridge instead of being run in the main world (#23299)
* refactor: port parts of window-setup to use ctx bridge instead of being run in the main world (#23194)

* refactor: port parts of window-setup to use ctx bridge instead of being run in the main world

* chore: update ctx bridge specs for new base numbers

* refactor: port window.open and window.opener to use ctx bridge instead of hole punching (#23235)

* refactor: port window.open and window.opener to use ctx bridge instead of hole punching

* refactor: only run the isolated init bundle when webview is enabled
2020-04-27 14:42:14 -07:00
trop[bot]
729019b974 style: use build/include_directory for NOLINT (#23300)
build/include linter was splitted to build/include_directory at
depot_tools upstream.

https://crrev.com/c/2159690
https://crbug.com/1073191

Co-authored-by: Sorah Fukumori <her@sorah.jp>
2020-04-27 13:28:41 -07:00
Electron Bot
e83d6be20c Bump v9.0.0-beta.20 2020-04-27 08:58:50 -07:00
trop[bot]
69eddfb2f9 fix: set default menu in will-finish-launching event (#23263)
Co-authored-by: Cheng Zhao <zcbenz@gmail.com>
2020-04-24 20:43:46 +09:00
Electron Bot
71c3c2b65e chore: bump chromium in DEPS to 83.0.4103.26 (#23256) 2020-04-23 14:03:37 -04:00
trop[bot]
cf230bc709 ci: robustify doc only change check (#23259)
Co-authored-by: John Kleinschmidt <jkleinsc@github.com>
2020-04-23 10:54:46 -07:00
Charles Kerr
6d3a6ce307 docs: minor grammar & spelling fixes (#22851) (#23262) 2020-04-23 10:52:51 -07:00
Charles Kerr
3d8b2af151 refactor: precache the IsWindowStateEvent() XAtom (#22706) (#23260)
* refactor: precache the IsWindowStateEvent() atom

XAtoms never change after creation so we can perload the atoms we need.
This is useful in WindowStateWatcher's XEvent handler, which is called
on every XEvent, e.g. mouse movement...

* empty commit for ci
2020-04-23 10:50:09 -07:00
shelley vohr
45174dfc19 feat: add property support for remainder of BrowserWindow (#23208)
Adds property-based support for the remainder of primitive getter/setter pairs on `BrowserWindow`.

Namely:
- `win.simpleFullScreen`
- `win.title`
- `win.visibleOnAllWorkspaces`
- `win.documentEdited`
- `win.representedFilename`
- `win.shadow`
- `win.kiosk`
- `win.menuBarVisible`
2020-04-23 10:34:20 -07:00
188 changed files with 4542 additions and 3378 deletions

View File

@@ -3,6 +3,7 @@ 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("//extensions/buildflags/buildflags.gni")
import("//pdf/features.gni")
import("//ppapi/buildflags/buildflags.gni")
import("//printing/buildflags/buildflags.gni")
@@ -58,6 +59,17 @@ if (is_mas_build) {
"It doesn't make sense to build a MAS build on a non-mac platform")
}
if (enable_pdf_viewer) {
assert(enable_pdf, "PDF viewer support requires enable_pdf=true")
assert(enable_electron_extensions,
"PDF viewer support requires enable_electron_extensions=true")
}
if (enable_electron_extensions) {
assert(enable_extensions,
"Chrome extension support requires enable_extensions=true")
}
config("branding") {
defines = [
"ELECTRON_PRODUCT_NAME=\"$electron_product_name\"",
@@ -324,13 +336,17 @@ source_set("electron_lib") {
"//chrome/app/resources:platform_locale_settings",
"//chrome/services/printing/public/mojom",
"//components/certificate_transparency",
"//components/crash/core/app",
"//components/language/core/browser",
"//components/net_log",
"//components/network_hints/browser",
"//components/network_hints/common:mojo_bindings",
"//components/network_hints/renderer",
"//components/network_session_configurator/common",
"//components/pref_registry",
"//components/prefs",
"//components/upload_list",
"//components/user_prefs",
"//components/viz/host",
"//components/viz/service",
"//content/public/browser",
@@ -443,10 +459,15 @@ source_set("electron_lib") {
]
}
if (is_linux) {
deps += [ "//components/crash/content/browser" ]
}
if (is_mac) {
deps += [
"//components/remote_cocoa/app_shim",
"//content/common:mac_helpers",
"//third_party/crashpad/crashpad/client",
"//ui/accelerated_widget_mac",
]
@@ -468,11 +489,7 @@ source_set("electron_lib") {
]
if (is_mas_build) {
sources += [ "shell/browser/api/electron_api_app_mas.mm" ]
sources -= [
"shell/browser/auto_updater_mac.mm",
"shell/common/crash_reporter/crash_reporter_mac.h",
"shell/common/crash_reporter/crash_reporter_mac.mm",
]
sources -= [ "shell/browser/auto_updater_mac.mm" ]
defines += [ "MAS_BUILD" ]
} else {
libs += [
@@ -495,7 +512,6 @@ source_set("electron_lib") {
"//build/config/linux/gtk",
"//dbus",
"//device/bluetooth",
"//third_party/breakpad:client",
"//ui/events/devices/x11",
"//ui/events/platform/x11",
"//ui/gtk",
@@ -509,7 +525,6 @@ source_set("electron_lib") {
]
}
configs += [ ":gio_unix" ]
include_dirs += [ "//third_party/breakpad" ]
configs += [ "//build/config/linux:x11" ]
defines += [
# Disable warnings for g_settings_list_schemas.
@@ -525,6 +540,7 @@ source_set("electron_lib") {
if (is_win) {
libs += [ "dwmapi.lib" ]
deps += [
"//components/crash/core/app:crash_export_thunks",
"//ui/native_theme:native_theme_browser",
"//ui/views/controls/webview",
"//ui/wm",
@@ -536,14 +552,6 @@ source_set("electron_lib") {
]
}
if ((is_mac && !is_mas_build) || is_win) {
sources += [
"shell/common/crash_reporter/crash_reporter_crashpad.cc",
"shell/common/crash_reporter/crash_reporter_crashpad.h",
]
deps += [ "//third_party/crashpad/crashpad/client" ]
}
if (enable_plugins) {
deps += [ "chromium_src:plugins" ]
sources += [
@@ -634,15 +642,6 @@ source_set("electron_lib") {
deps += [ "//components/printing/common:mojo_interfaces" ]
}
deps += [
"//components/pref_registry",
"//components/user_prefs",
"//extensions/browser",
"//extensions/browser:core_api_provider",
"//extensions/common",
"//extensions/common:core_api_provider",
"//extensions/renderer",
]
if (enable_electron_extensions) {
sources += filenames.lib_sources_extensions
deps += [
@@ -651,6 +650,11 @@ source_set("electron_lib") {
"shell/common/extensions/api:extensions_features",
"//chrome/browser/resources:component_extension_resources",
"//components/zoom",
"//extensions/browser",
"//extensions/browser:core_api_provider",
"//extensions/common",
"//extensions/common:core_api_provider",
"//extensions/renderer",
]
}
@@ -764,11 +768,17 @@ if (is_mac) {
}
bundle_data("electron_crashpad_helper") {
sources = [ "$root_out_dir/crashpad_handler" ]
sources = [ "$root_out_dir/chrome_crashpad_handler" ]
outputs = [ "{{bundle_resources_dir}}/{{source_file_part}}" ]
outputs = [ "{{bundle_contents_dir}}/Helpers/{{source_file_part}}" ]
public_deps = [ "//third_party/crashpad/crashpad/handler:crashpad_handler" ]
public_deps = [ "//components/crash/core/app:chrome_crashpad_handler" ]
if (is_asan) {
# crashpad_handler requires the ASan runtime at its @executable_path.
sources += [ "$root_out_dir/libclang_rt.asan_osx_dynamic.dylib" ]
public_deps += [ "//build/config/sanitizers:copy_asan_runtime" ]
}
}
mac_framework_bundle("electron_framework") {
@@ -777,6 +787,7 @@ if (is_mac) {
framework_contents = [
"Resources",
"Libraries",
"Helpers",
]
public_deps = [
":electron_framework_libraries",
@@ -1044,6 +1055,7 @@ if (is_mac) {
":electron_app_manifest",
":electron_lib",
":packed_resources",
"//components/crash/core/app",
"//content:sandbox_helper_win",
"//electron/buildflags",
"//ui/strings",
@@ -1073,6 +1085,11 @@ if (is_mac) {
"shell/browser/resources/win/resource.h",
]
deps += [
"//components/browser_watcher:browser_watcher_client",
"//components/crash/core/app:run_as_crashpad_handler",
]
libs = [
"comctl32.lib",
"uiautomationcore.lib",

2
DEPS
View File

@@ -12,7 +12,7 @@ gclient_gn_args = [
vars = {
'chromium_version':
'83.0.4103.24',
'83.0.4103.45',
'node_version':
'v12.14.1',
'nan_version':

View File

@@ -1 +1 @@
9.0.0-beta.19
9.0.0-beta.24

View File

@@ -88,5 +88,6 @@ steps:
- powershell: |
Get-Process | Where Name Like "electron*" | Stop-Process
Get-Process | Where Name Like "MicrosoftEdge*" | Stop-Process
Get-Process | Where Name Like "msedge*" | Stop-Process
displayName: 'Kill processes left running from last test run'
condition: always()

View File

@@ -20,7 +20,3 @@ angle_enable_vulkan_validation_layers = false
dawn_enable_vulkan_validation_layers = false
is_cfi = false
enable_osr = true
enable_electron_extensions = true

View File

@@ -32,7 +32,7 @@ declare_args() {
enable_pepper_flash = true
# Enable Chrome extensions support.
enable_electron_extensions = false
enable_electron_extensions = true
# Enable Spellchecker support
enable_builtin_spellchecker = true

View File

@@ -14,6 +14,8 @@ static_library("chrome") {
sources = [
"//chrome/browser/browser_process.cc",
"//chrome/browser/browser_process.h",
"//chrome/browser/crash_upload_list/crash_upload_list_crashpad.cc",
"//chrome/browser/crash_upload_list/crash_upload_list_crashpad.h",
"//chrome/browser/devtools/devtools_contents_resizing_strategy.cc",
"//chrome/browser/devtools/devtools_contents_resizing_strategy.h",
"//chrome/browser/devtools/devtools_embedder_message_dispatcher.cc",
@@ -55,6 +57,8 @@ static_library("chrome") {
"//chrome/browser/ui/views/autofill/autofill_popup_view_utils.h",
"//chrome/browser/win/chrome_process_finder.cc",
"//chrome/browser/win/chrome_process_finder.h",
"//chrome/child/v8_crashpad_support_win.cc",
"//chrome/child/v8_crashpad_support_win.h",
"//extensions/browser/app_window/size_constraints.cc",
"//extensions/browser/app_window/size_constraints.h",
]
@@ -239,17 +243,22 @@ static_library("chrome") {
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",
"//chrome/renderer/extensions/tabs_hooks_delegate.h",
"//chrome/renderer/pepper/chrome_pdf_print_client.cc",
"//chrome/renderer/pepper/chrome_pdf_print_client.h",
]
if (enable_pdf_viewer) {
sources += [
"//chrome/browser/pdf/pdf_extension_util.cc",
"//chrome/browser/pdf/pdf_extension_util.h",
"//chrome/renderer/pepper/chrome_pdf_print_client.cc",
"//chrome/renderer/pepper/chrome_pdf_print_client.h",
]
}
}
}
@@ -268,12 +277,14 @@ source_set("plugins") {
"//chrome/browser/renderer_host/pepper/pepper_isolated_file_system_message_filter.h",
]
deps += [
"//components/pdf/browser",
"//media:media_buildflags",
"//ppapi/buildflags",
"//ppapi/proxy:ipc",
"//services/device/public/mojom",
]
if (enable_pdf_viewer) {
deps += [ "//components/pdf/browser" ]
}
if (enable_pepper_flash) {
sources += [
"//chrome/browser/renderer_host/pepper/pepper_flash_browser_host.cc",
@@ -319,9 +330,11 @@ source_set("plugins") {
"//chrome/renderer/pepper/pepper_flash_font_file_host.cc",
"//chrome/renderer/pepper/pepper_flash_font_file_host.h",
]
if (enable_pdf_viewer) {
deps += [ "//components/pdf/renderer" ]
}
}
deps += [
"//components/pdf/renderer",
"//components/strings",
"//media:media_buildflags",
"//ppapi/host",

View File

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

View File

@@ -54,7 +54,7 @@ The `Super` key is mapped to the `Windows` key on Windows and Linux and
* `0` to `9`
* `A` to `Z`
* `F1` to `F24`
* Punctuations like `~`, `!`, `@`, `#`, `$`, etc.
* Punctuation like `~`, `!`, `@`, `#`, `$`, etc.
* `Plus`
* `Space`
* `Tab`

View File

@@ -75,7 +75,7 @@ Returns:
* `event` Event
Emitted when all windows have been closed and the application will quit.
Calling `event.preventDefault()` will prevent the default behaviour, which is
Calling `event.preventDefault()` will prevent the default behavior, which is
terminating the application.
See the description of the `window-all-closed` event for the differences between
@@ -204,7 +204,7 @@ Returns:
[`NSUserActivity.activityType`][activity-type].
* `userInfo` unknown - Contains app-specific state stored by the activity.
Emitted when [Handoff][handoff] is about to be resumed on another device. If you need to update the state to be transferred, you should call `event.preventDefault()` immediately, construct a new `userInfo` dictionary and call `app.updateCurrentActiviy()` in a timely manner. Otherwise, the operation will fail and `continue-activity-error` will be called.
Emitted when [Handoff][handoff] is about to be resumed on another device. If you need to update the state to be transferred, you should call `event.preventDefault()` immediately, construct a new `userInfo` dictionary and call `app.updateCurrentActivity()` in a timely manner. Otherwise, the operation will fail and `continue-activity-error` will be called.
### Event: 'new-window-for-tab' _macOS_
@@ -554,11 +554,17 @@ Returns `Promise<void>` - fulfilled when Electron is initialized.
May be used as a convenient alternative to checking `app.isReady()`
and subscribing to the `ready` event if the app is not ready yet.
### `app.focus()`
### `app.focus([options])`
* `options` Object (optional)
* `steal` Boolean _macOS_ - Make the receiver the active app even if another app is
currently active.
On Linux, focuses on the first visible window. On macOS, makes the application
the active app. On Windows, focuses on the application's first window.
You should seek to use the `steal` option as sparingly as possible.
### `app.hide()` _macOS_
Hides all application windows without minimizing them.
@@ -602,6 +608,7 @@ Returns `String` - The current application directory.
* `videos` Directory for a user's videos.
* `logs` Directory for your app's log folder.
* `pepperFlashSystemPlugin` Full path to the system version of the Pepper Flash plugin.
* `crashDumps` Directory where crash dumps are stored.
Returns `String` - A path to a special directory or file associated with `name`. On
failure, an `Error` is thrown.
@@ -1021,7 +1028,7 @@ This method can only be called before app is ready.
By default, Chromium disables 3D APIs (e.g. WebGL) until restart on a per
domain basis if the GPU processes crashes too frequently. This function
disables that behaviour.
disables that behavior.
This method can only be called before app is ready.
@@ -1190,7 +1197,7 @@ Show the app's about panel options. These options can be overridden with `app.se
* `website` String (optional) _Linux_ - The app's website.
* `iconPath` String (optional) _Linux_ _Windows_ - Path to the app's icon. On Linux, will be shown as 64x64 pixels while retaining aspect ratio.
Set the about panel options. This will override the values defined in the app's `.plist` file on MacOS. See the [Apple docs][about-panel-options] for more details. On Linux, values must be set in order to be shown; there are no defaults.
Set the about panel options. This will override the values defined in the app's `.plist` file on macOS. See the [Apple docs][about-panel-options] for more details. On Linux, values must be set in order to be shown; there are no defaults.
If you do not set `credits` but still wish to surface them in your app, AppKit will look for a file named "Credits.html", "Credits.rtf", and "Credits.rtfd", in that order, in the bundle returned by the NSBundle class method main. The first file found is used, and if none is found, the info area is left blank. See Apple [documentation](https://developer.apple.com/documentation/appkit/nsaboutpaneloptioncredits?language=objc) for more information.

View File

@@ -177,7 +177,7 @@ It creates a new `BrowserWindow` with native properties as set by the `options`.
* `simpleFullscreen` Boolean (optional) - Use pre-Lion fullscreen on macOS. Default is `false`.
* `skipTaskbar` Boolean (optional) - Whether to show the window in taskbar. Default is
`false`.
* `kiosk` Boolean (optional) - The kiosk mode. Default is `false`.
* `kiosk` Boolean (optional) - Whether the window is in kiosk mode. Default is `false`.
* `title` String (optional) - Default window title. Default is `"Electron"`. If the HTML tag `<title>` is defined in the HTML file loaded by `loadURL()`, this property will be ignored.
* `icon` ([NativeImage](native-image.md) | String) (optional) - The window icon. On Windows it is
recommended to use `ICO` icons to get best visual effects, you can also
@@ -207,7 +207,7 @@ It creates a new `BrowserWindow` with native properties as set by the `options`.
* `opacity` Number (optional) - Set the initial opacity of the window, between 0.0 (fully
transparent) and 1.0 (fully opaque). This is only implemented on Windows and macOS.
* `darkTheme` Boolean (optional) - Forces using dark theme for the window, only works on
some GTK+3 desktop environments. Default is `false`.
some GTK desktop environments. Default is `false`.
* `transparent` Boolean (optional) - Makes the window [transparent](frameless-window.md#transparent-window).
Default is `false`. On Windows, does not work unless the window is frameless.
* `type` String (optional) - The type of window, default is normal window. See more about
@@ -803,6 +803,51 @@ A `Boolean` property that determines whether the window menu bar should hide its
If the menu bar is already visible, setting this property to `true` won't
hide it immediately.
#### `win.simpleFullScreen`
A `Boolean` property that determines whether the window is in simple (pre-Lion) fullscreen mode.
#### `win.fullScreen`
A `Boolean` property that determines whether the window is in fullscreen mode.
#### `win.visibleOnAllWorkspaces`
A `Boolean` property that determines whether the window is visible on all workspaces.
**Note:** Always returns false on Windows.
#### `win.shadow`
A `Boolean` property that determines whether the window has a shadow.
#### `win.menuBarVisible` _Windows_ _Linux_
A `Boolean` property that determines whether the menu bar should be visible.
**Note:** If the menu bar is auto-hide, users can still bring up the menu bar by pressing the single `Alt` key.
#### `win.kiosk`
A `Boolean` property that determines whether the window is in kiosk mode.
#### `win.documentEdited` _macOS_
A `Boolean` property that specifies whether the windows document has been edited.
The icon in title bar will become gray when set to `true`.
#### `win.representedFilename` _macOS_
A `String` property that determines the pathname of the file the window represents,
and the icon of the file will show in window's title bar.
#### `win.title`
A `String` property that determines the title of the native window.
**Note:** The title of the web page can be different from the title of the native window.
#### `win.minimizable`
A `Boolean` property that determines whether the window can be manually minimized by user.
@@ -958,7 +1003,7 @@ Returns `Boolean` - Whether the window is in fullscreen mode.
Enters or leaves simple fullscreen mode.
Simple fullscreen mode emulates the native fullscreen behavior found in versions of Mac OS X prior to Lion (10.7).
Simple fullscreen mode emulates the native fullscreen behavior found in versions of macOS prior to Lion (10.7).
#### `win.isSimpleFullScreen()` _macOS_
@@ -1282,7 +1327,7 @@ Makes the window not show in the taskbar.
* `flag` Boolean
Enters or leaves the kiosk mode.
Enters or leaves kiosk mode.
#### `win.isKiosk()`

View File

@@ -4,18 +4,13 @@
Process: [Main](../glossary.md#main-process), [Renderer](../glossary.md#renderer-process)
The following is an example of automatically submitting a crash report to a
remote server:
The following is an example of setting up Electron to automatically submit
crash reports to a remote server:
```javascript
const { crashReporter } = require('electron')
crashReporter.start({
productName: 'YourName',
companyName: 'YourCompany',
submitURL: 'https://your-domain.com/url-to-submit',
uploadToServer: true
})
crashReporter.start({ submitURL: 'https://your-domain.com/url-to-submit' })
```
For setting up a server to accept and process crash reports, you can use
@@ -30,11 +25,19 @@ Or use a 3rd party hosted solution:
* [Sentry](https://docs.sentry.io/clients/electron)
* [BugSplat](https://www.bugsplat.com/docs/platforms/electron)
Crash reports are saved locally in an application-specific temp directory folder.
For a `productName` of `YourName`, crash reports will be stored in a folder
named `YourName Crashes` inside the temp directory. You can customize this temp
directory location for your app by calling the `app.setPath('temp', '/my/custom/temp')`
API before starting the crash reporter.
Crash reports are stored temporarily before being uploaded in a directory
underneath the app's user data directory (called 'Crashpad' on Windows and Mac,
or 'Crash Reports' on Linux). You can override this directory by calling
`app.setPath('crashDumps', '/path/to/crashes')` before starting the crash
reporter.
On Windows and macOS, Electron uses
[crashpad](https://chromium.googlesource.com/crashpad/crashpad/+/master/README.md)
to monitor and report crashes. On Linux, Electron uses
[breakpad](https://chromium.googlesource.com/breakpad/breakpad/+/master/). This
is an implementation detail driven by Chromium, and it may change in future. In
particular, crashpad is newer and will likely eventually replace breakpad on
all platforms.
## Methods
@@ -43,40 +46,68 @@ The `crashReporter` module has the following methods:
### `crashReporter.start(options)`
* `options` Object
* `companyName` String
* `submitURL` String - URL that crash reports will be sent to as POST.
* `productName` String (optional) - Defaults to `app.name`.
* `uploadToServer` Boolean (optional) - Whether crash reports should be sent to the server. Default is `true`.
* `ignoreSystemCrashHandler` Boolean (optional) - Default is `false`.
* `extra` Record<String, String> (optional) - An object you can define that will be sent along with the
report. Only string properties are sent correctly. Nested objects are not
supported. When using Windows, the property names and values must be fewer than 64 characters.
* `crashesDirectory` String (optional) - Directory to store the crash reports temporarily (only used when the crash reporter is started via `process.crashReporter.start`).
* `companyName` String (optional) _Deprecated_ - Deprecated alias for
`{ globalExtra: { _companyName: ... } }`.
* `uploadToServer` Boolean (optional) - Whether crash reports should be sent
to the server. If false, crash reports will be collected and stored in the
crashes directory, but not uploaded. Default is `true`.
* `ignoreSystemCrashHandler` Boolean (optional) - If true, crashes generated
in the main process will not be forwarded to the system crash handler.
Default is `false`.
* `rateLimit` Boolean (optional) _macOS_ _Windows_ - If true, limit the
number of crashes uploaded to 1/hour. Default is `false`.
* `compress` Boolean (optional) _macOS_ _Windows_ - If true, crash reports
will be compressed and uploaded with `Content-Encoding: gzip`. Not all
collection servers support compressed payloads. Default is `false`.
* `extra` Record<String, String> (optional) - Extra string key/value
annotations that will be sent along with crash reports that are generated
in the main process. Only string values are supported. Crashes generated in
child processes will not contain these extra
parameters to crash reports generated from child processes, call
[`addExtraParameter`](#crashreporteraddextraparameterkey-value) from the
child process.
* `globalExtra` Record<String, String> (optional) - Extra string key/value
annotations that will be sent along with any crash reports generated in any
process. These annotations cannot be changed once the crash reporter has
been started. If a key is present in both the global extra parameters and
the process-specific extra parameters, then the global one will take
precedence. By default, `productName` and the app version are included, as
well as the Electron version.
You are required to call this method before using any other `crashReporter` APIs
and in each process (main/renderer) from which you want to collect crash reports.
You can pass different options to `crashReporter.start` when calling from different processes.
This method must be called before using any other `crashReporter` APIs. Once
initialized this way, the crashpad handler collects crashes from all
subsequently created processes. The crash reporter cannot be disabled once
started.
**Note** Child processes created via the `child_process` module will not have access to the Electron modules.
Therefore, to collect crash reports from them, use `process.crashReporter.start` instead. Pass the same options as above
along with an additional one called `crashesDirectory` that should point to a directory to store the crash
reports temporarily. You can test this out by calling `process.crash()` to crash the child process.
This method should be called as early as possible in app startup, preferably
before `app.on('ready')`. If the crash reporter is not initialized at the time
a renderer process is created, then that renderer process will not be monitored
by the crash reporter.
**Note:** If you need send additional/updated `extra` parameters after your
first call `start` you can call `addExtraParameter` on macOS or call `start`
again with the new/updated `extra` parameters on Linux and Windows.
**Note:** You can test out the crash reporter by generating a crash using
`process.crash()`.
**Note:** On macOS and windows, Electron uses a new `crashpad` client for crash collection and reporting.
If you want to enable crash reporting, initializing `crashpad` from the main process using `crashReporter.start` is required
regardless of which process you want to collect crashes from. Once initialized this way, the crashpad handler collects
crashes from all processes. You still have to call `crashReporter.start` from the renderer or child process, otherwise crashes from
them will get reported without `companyName`, `productName` or any of the `extra` information.
**Note:** If you need to send additional/updated `extra` parameters after your
first call `start` you can call `addExtraParameter`.
**Note:** Parameters passed in `extra`, `globalExtra` or set with
`addExtraParameter` have limits on the length of the keys and values. Key names
must be at most 39 bytes long, and values must be no longer than 127 bytes.
Keys with names longer than the maximum will be silently ignored. Key values
longer than the maximum length will be truncated.
**Note:** Calling this method from the renderer process is deprecated.
### `crashReporter.getLastCrashReport()`
Returns [`CrashReport`](structures/crash-report.md):
Returns [`CrashReport`](structures/crash-report.md) - The date and ID of the
last crash report. Only crash reports that have been uploaded will be returned;
even if a crash report is present on disk it will not be returned until it is
uploaded. In the case that there are no uploaded reports, `null` is returned.
Returns the date and ID of the last crash report. Only crash reports that have been uploaded will be returned; even if a crash report is present on disk it will not be returned until it is uploaded. In the case that there are no uploaded reports, `null` is returned.
**Note:** Calling this method from the renderer process is deprecated.
### `crashReporter.getUploadedReports()`
@@ -85,43 +116,61 @@ Returns [`CrashReport[]`](structures/crash-report.md):
Returns all uploaded crash reports. Each report contains the date and uploaded
ID.
**Note:** Calling this method from the renderer process is deprecated.
### `crashReporter.getUploadToServer()`
Returns `Boolean` - Whether reports should be submitted to the server. Set through
the `start` method or `setUploadToServer`.
**Note:** This API can only be called from the main process.
**Note:** Calling this method from the renderer process is deprecated.
### `crashReporter.setUploadToServer(uploadToServer)`
* `uploadToServer` Boolean _macOS_ - Whether reports should be submitted to the server.
* `uploadToServer` Boolean - Whether reports should be submitted to the server.
This would normally be controlled by user preferences. This has no effect if
called before `start` is called.
**Note:** This API can only be called from the main process.
**Note:** Calling this method from the renderer process is deprecated.
### `crashReporter.addExtraParameter(key, value)` _macOS_ _Windows_
### `crashReporter.getCrashesDirectory()` _Deprecated_
* `key` String - Parameter key, must be less than 64 characters long.
* `value` String - Parameter value, must be less than 64 characters long.
Returns `String` - The directory where crashes are temporarily stored before being uploaded.
Set an extra parameter to be sent with the crash report. The values
specified here will be sent in addition to any values set via the `extra` option when `start` was called. This API is only available on macOS and windows, if you need to add/update extra parameters on Linux after your first call to `start` you can call `start` again with the updated `extra` options.
**Note:** This method is deprecated, use `app.getPath('crashDumps')` instead.
### `crashReporter.removeExtraParameter(key)` _macOS_ _Windows_
### `crashReporter.addExtraParameter(key, value)`
* `key` String - Parameter key, must be less than 64 characters long.
* `key` String - Parameter key, must be no longer than 39 bytes.
* `value` String - Parameter value, must be no longer than 127 bytes.
Remove a extra parameter from the current set of parameters so that it will not be sent with the crash report.
Set an extra parameter to be sent with the crash report. The values specified
here will be sent in addition to any values set via the `extra` option when
`start` was called.
Parameters added in this fashion (or via the `extra` parameter to
`crashReporter.start`) are specific to the calling process. Adding extra
parameters in the main process will not cause those parameters to be sent along
with crashes from renderer or other child processes. Similarly, adding extra
parameters in a renderer process will not result in those parameters being sent
with crashes that occur in other renderer processes or in the main process.
**Note:** Parameters have limits on the length of the keys and values. Key
names must be no longer than 39 bytes, and values must be no longer than 127
bytes. Keys with names longer than the maximum will be silently ignored. Key
values longer than the maximum length will be truncated.
### `crashReporter.removeExtraParameter(key)`
* `key` String - Parameter key, must be no longer than 39 bytes.
Remove a extra parameter from the current set of parameters. Future crashes
will not include this parameter.
### `crashReporter.getParameters()`
See all of the current parameters being passed to the crash reporter.
### `crashReporter.getCrashesDirectory()`
Returns `String` - The directory where crashes are temporarily stored before being uploaded.
Returns `Record<String, String>` - The current 'extra' parameters of the crash reporter.
## Crash Report Payload

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

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

View File

@@ -52,7 +52,7 @@ win.show()
Uses custom drawn close, and miniaturize buttons that display
when hovering in the top left of the window. The fullscreen button
is not available due to restrictions of frameless windows as they
interface with Apple's MacOS window masks. These custom buttons prevent
interface with Apple's macOS window masks. These custom buttons prevent
issues with mouse events that occur with the standard window toolbar buttons.
This option is only applicable for frameless windows.
@@ -158,7 +158,7 @@ buttons in titlebar non-draggable.
## Text selection
In a frameless window the dragging behaviour may conflict with selecting text.
In a frameless window the dragging behavior may conflict with selecting text.
For example, when you drag the titlebar you may accidentally select the text on
the titlebar. To prevent this, you need to disable text selection within a
draggable area like this:

View File

@@ -14,7 +14,7 @@ See [`Menu`](menu.md) for examples.
* `menuItem` MenuItem
* `browserWindow` [BrowserWindow](browser-window.md)
* `event` [KeyboardEvent](structures/keyboard-event.md)
* `role` String (optional) - Can be `undo`, `redo`, `cut`, `copy`, `paste`, `pasteAndMatchStyle`, `delete`, `selectAll`, `reload`, `forceReload`, `toggleDevTools`, `resetZoom`, `zoomIn`, `zoomOut`, `togglefullscreen`, `window`, `minimize`, `close`, `help`, `about`, `services`, `hide`, `hideOthers`, `unhide`, `quit`, `startSpeaking`, `stopSpeaking`, `minimize`, `zoom`, `front`, `appMenu`, `fileMenu`, `editMenu`, `viewMenu`, `recentDocuments`, `toggleTabBar`, `selectNextTab`, `selectPreviousTab`, `mergeAllWindows`, `clearRecentDocuments`, `moveTabToNewWindow` or `windowMenu` - Define the action of the menu item, when specified the
* `role` String (optional) - Can be `undo`, `redo`, `cut`, `copy`, `paste`, `pasteAndMatchStyle`, `delete`, `selectAll`, `reload`, `forceReload`, `toggleDevTools`, `resetZoom`, `zoomIn`, `zoomOut`, `togglefullscreen`, `window`, `minimize`, `close`, `help`, `about`, `services`, `hide`, `hideOthers`, `unhide`, `quit`, `startSpeaking`, `stopSpeaking`, `zoom`, `front`, `appMenu`, `fileMenu`, `editMenu`, `viewMenu`, `recentDocuments`, `toggleTabBar`, `selectNextTab`, `selectPreviousTab`, `mergeAllWindows`, `clearRecentDocuments`, `moveTabToNewWindow` or `windowMenu` - Define the action of the menu item, when specified the
`click` property will be ignored. See [roles](#roles).
* `type` String (optional) - Can be `normal`, `separator`, `submenu`, `checkbox` or
`radio`.
@@ -117,7 +117,7 @@ When specifying a `role` on macOS, `label` and `accelerator` are the only
options that will affect the menu item. All other options will be ignored.
Lowercase `role`, e.g. `toggledevtools`, is still supported.
**Nota Bene:** The `enabled` and `visibility` properties are not available for top-level menu items in the tray on MacOS.
**Nota Bene:** The `enabled` and `visibility` properties are not available for top-level menu items in the tray on macOS.
### Instance Properties
@@ -151,7 +151,7 @@ A `String` indicating the type of the item. Can be `normal`, `separator`, `subme
#### `menuItem.role`
A `String` (optional) indicating the item's role, if set. Can be `undo`, `redo`, `cut`, `copy`, `paste`, `pasteAndMatchStyle`, `delete`, `selectAll`, `reload`, `forceReload`, `toggleDevTools`, `resetZoom`, `zoomIn`, `zoomOut`, `togglefullscreen`, `window`, `minimize`, `close`, `help`, `about`, `services`, `hide`, `hideOthers`, `unhide`, `quit`, `startSpeaking`, `stopSpeaking`, `close`, `minimize`, `zoom`, `front`, `appMenu`, `fileMenu`, `editMenu`, `viewMenu`, `recentDocuments`, `toggleTabBar`, `selectNextTab`, `selectPreviousTab`, `mergeAllWindows`, `clearRecentDocuments`, `moveTabToNewWindow` or `windowMenu`
A `String` (optional) indicating the item's role, if set. Can be `undo`, `redo`, `cut`, `copy`, `paste`, `pasteAndMatchStyle`, `delete`, `selectAll`, `reload`, `forceReload`, `toggleDevTools`, `resetZoom`, `zoomIn`, `zoomOut`, `togglefullscreen`, `window`, `minimize`, `close`, `help`, `about`, `services`, `hide`, `hideOthers`, `unhide`, `quit`, `startSpeaking`, `stopSpeaking`, `zoom`, `front`, `appMenu`, `fileMenu`, `editMenu`, `viewMenu`, `recentDocuments`, `toggleTabBar`, `selectNextTab`, `selectPreviousTab`, `mergeAllWindows`, `clearRecentDocuments`, `moveTabToNewWindow` or `windowMenu`
#### `menuItem.accelerator`

View File

@@ -5,14 +5,7 @@ The Electron team is currently undergoing an initiative to convert separate gett
## Candidates
* `BrowserWindow`
* `fullscreen`
* `simpleFullscreen`
* `alwaysOnTop`
* `title`
* `documentEdited`
* `hasShadow`
* `menubarVisible`
* `visibleOnAllWorkspaces`
* `crashReporter` module
* `uploadToServer`
* `webFrame` modules

View File

@@ -51,7 +51,7 @@ app.whenReady().then(() => {
In the above code the [`BrowserWindow`](browser-window.md) that was created has Node.js disabled and can communicate
only via IPC. The use of this option stops Electron from creating a Node.js runtime in the renderer. Also,
within this new window `window.open` follows the native behaviour (by default Electron creates a [`BrowserWindow`](browser-window.md)
within this new window `window.open` follows the native behavior (by default Electron creates a [`BrowserWindow`](browser-window.md)
and returns a proxy to this via `window.open`).
[`app.enableSandbox`](app.md#appenablesandbox-experimental) can be used to force `sandbox: true` for all `BrowserWindow` instances.

View File

@@ -0,0 +1,4 @@
# NewWindowEvent Object extends `Event`
* `newGuest` BrowserWindow (optional)

View File

@@ -326,7 +326,7 @@ This API is only available on macOS 10.14 Mojave or newer.
* `window-frame-text` - The text in the window's titlebar area.
Returns `String` - The system color setting in RGB hexadecimal form (`#ABCDEF`).
See the [Windows docs][windows-colors] and the [MacOS docs][macos-colors] for more details.
See the [Windows docs][windows-colors] and the [macOS docs][macos-colors] for more details.
The following colors are only available on macOS 10.14: `find-highlight`, `selected-content-background`, `separator`, `unemphasized-selected-content-background`, `unemphasized-selected-text-background`, and `unemphasized-selected-text`.

View File

@@ -138,7 +138,7 @@ Emitted when page receives favicon urls.
Returns:
* `event` Event
* `event` NewWindowEvent
* `url` String
* `frameName` String
* `disposition` String - Can be `default`, `foreground-tab`, `background-tab`,

View File

@@ -2,13 +2,124 @@
Breaking changes will be documented here, and deprecation warnings added to JS code where possible, at least [one major version](tutorial/electron-versioning.md#semver) before the change is made.
## `FIXME` comments
### Types of Breaking Changes
The `FIXME` string is used in code comments to denote things that should be fixed for future releases. See https://github.com/electron/electron/search?q=fixme
This document uses the following convention to categorize breaking changes:
- **API Changed:** An API was changed in such a way that code that has not been updated is guaranteed to throw an exception.
- **Behavior Changed:** The behavior of Electron has changed, but not in such a way that an exception will necessarily be thrown.
- **Default Changed:** Code depending on the old default may break, not necessarily throwing an exception. The old behavior can be restored by explicitly specifying the value.
- **Deprecated:** An API was marked as deprecated. The API will continue to function, but will emit a deprecation warning, and will be removed in a future release.
- **Removed:** An API or feature was removed, and is no longer supported by Electron.
## Planned Breaking API Changes (12.0)
### Removed: `crashReporter` methods in the renderer process
The following `crashReporter` methods are no longer available in the renderer
process:
- `crashReporter.start`
- `crashReporter.getLastCrashReport`
- `crashReporter.getUploadedReports`
- `crashReporter.getUploadToServer`
- `crashReporter.setUploadToServer`
- `crashReporter.getCrashesDirectory`
They should be called only from the main process.
See [#23265](https://github.com/electron/electron/pull/23265) for more details.
## Planned Breaking API Changes (11.0)
## Planned Breaking API Changes (10.0)
### Deprecated: `companyName` argument to `crashReporter.start()`
The `companyName` argument to `crashReporter.start()`, which was previously
required, is now optional, and further, is deprecated. To get the same
behavior in a non-deprecated way, you can pass a `companyName` value in
`globalExtra`.
```js
// Deprecated in Electron 10
crashReporter.start({ companyName: 'Umbrella Corporation' })
// Replace with
crashReporter.start({ globalExtra: { _companyName: 'Umbrella Corporation' } })
```
### Deprecated: `crashReporter.getCrashesDirectory()`
The `crashReporter.getCrashesDirectory` method has been deprecated. Usage
should be replaced by `app.getPath('crashDumps')`.
```js
// Deprecated in Electron 10
crashReporter.getCrashesDirectory()
// Replace with
app.getPath('crashDumps')
```
### Deprecated: `crashReporter` methods in the renderer process
Calling the following `crashReporter` methods from the renderer process is
deprecated:
- `crashReporter.start`
- `crashReporter.getLastCrashReport`
- `crashReporter.getUploadedReports`
- `crashReporter.getUploadToServer`
- `crashReporter.setUploadToServer`
- `crashReporter.getCrashesDirectory`
The only non-deprecated methods remaining in the `crashReporter` module in the
renderer are `addExtraParameter`, `removeExtraParameter` and `getParameters`.
All above methods remain non-deprecated when called from the main process.
See [#23265](https://github.com/electron/electron/pull/23265) for more details.
### Removed: Browser Window Affinity
The `affinity` option when constructing a new `BrowserWindow` will be removed
as part of our plan to more closely align with Chromium's process model for security,
performance and maintainability.
For more detailed information see [#18397](https://github.com/electron/electron/issues/18397).
### Default Changed: `enableRemoteModule` defaults to `false`
In Electron 9, using the remote module without explicitly enabling it via the
`enableRemoteModule` WebPreferences option began emitting a warning. In
Electron 10, the remote module is now disabled by default. To use the remote
module, `enableRemoteModule: true` must be specified in WebPreferences:
```js
const w = new BrowserWindow({
webPreferences: {
enableRemoteModule: true
}
})
```
We [recommend moving away from the remote
module](https://medium.com/@nornagon/electrons-remote-module-considered-harmful-70d69500f31).
## Planned Breaking API Changes (9.0)
### `<webview>.getWebContents()`
### Default Changed: Loading non-context-aware native modules in the renderer process is disabled by default
As of Electron 9 we do not allow loading of non-context-aware native modules in
the renderer process. This is to improve security, performance and maintainability
of Electron as a project.
If this impacts you, you can temporarily set `app.allowRendererProcessReuse` to `false`
to revert to the old behavior. This flag will only be an option until Electron 11 so
you should plan to update your native modules to be context aware.
For more detailed information see [#18397](https://github.com/electron/electron/issues/18397).
### Removed: `<webview>.getWebContents()`
This API, which was deprecated in Electron 8.0, is now removed.
@@ -20,7 +131,7 @@ const { remote } = require('electron')
remote.webContents.fromId(webview.getWebContentsId())
```
### `webFrame.setLayoutZoomLevelLimits()`
### Removed: `webFrame.setLayoutZoomLevelLimits()`
Chromium has removed support for changing the layout zoom level limits, and it
is beyond Electron's capacity to maintain it. The function was deprecated in
@@ -28,7 +139,7 @@ Electron 8.x, and has been removed in Electron 9.x. The layout zoom level limits
are now fixed at a minimum of 0.25 and a maximum of 5.0, as defined
[here](https://chromium.googlesource.com/chromium/src/+/938b37a6d2886bf8335fc7db792f1eb46c65b2ae/third_party/blink/common/page/page_zoom.cc#11).
### Sending non-JS objects over IPC now throws an exception
### Behavior Changed: Sending non-JS objects over IPC now throws an exception
In Electron 8.0, IPC was changed to use the Structured Clone Algorithm,
bringing significant performance improvements. To help ease the transition, the
@@ -44,9 +155,14 @@ In Electron 9.0, the old serialization algorithm has been removed, and sending
such non-serializable objects will now throw an "object could not be cloned"
error.
### API Changed: `shell.openItem` is now `shell.openPath`
The `shell.openItem` API has been replaced with an asynchronous `shell.openPath` API.
You can see the original API proposal and reasoning [here](https://github.com/electron/governance/blob/master/wg-api/spec-documents/shell-openitem.md).
## Planned Breaking API Changes (8.0)
### Values sent over IPC are now serialized with Structured Clone Algorithm
### Behavior Changed: Values sent over IPC are now serialized with Structured Clone Algorithm
The algorithm used to serialize objects sent over IPC (through
`ipcRenderer.send`, `ipcRenderer.sendSync`, `WebContents.send` and related
@@ -97,7 +213,7 @@ these kinds of objects will throw a 'could not be cloned' error.
[SCA]: https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Structured_clone_algorithm
### `<webview>.getWebContents()`
### Deprecated: `<webview>.getWebContents()`
This API is implemented using the `remote` module, which has both performance
and security implications. Therefore its usage should be explicit.
@@ -138,7 +254,7 @@ const { ipcRenderer } = require('electron')
ipcRenderer.invoke('openDevTools', webview.getWebContentsId())
```
### `webFrame.setLayoutZoomLevelLimits()`
### Deprecated: `webFrame.setLayoutZoomLevelLimits()`
Chromium has removed support for changing the layout zoom level limits, and it
is beyond Electron's capacity to maintain it. The function will emit a warning
@@ -148,7 +264,7 @@ limits are now fixed at a minimum of 0.25 and a maximum of 5.0, as defined
## Planned Breaking API Changes (7.0)
### Node Headers URL
### Deprecated: Atom.io Node Headers URL
This is the URL specified as `disturl` in a `.npmrc` file or as the `--dist-url`
command line flag when building native Node modules. Both will be supported for
@@ -158,7 +274,7 @@ Deprecated: https://atom.io/download/electron
Replace with: https://electronjs.org/headers
### `session.clearAuthCache(options)`
### API Changed: `session.clearAuthCache()` no longer accepts options
The `session.clearAuthCache` API no longer accepts options for what to clear, and instead unconditionally clears the whole cache.
@@ -169,25 +285,25 @@ session.clearAuthCache({ type: 'password' })
session.clearAuthCache()
```
### `powerMonitor.querySystemIdleState`
### API Changed: `powerMonitor.querySystemIdleState` is now `powerMonitor.getSystemIdleState`
```js
// Removed in Electron 7.0
powerMonitor.querySystemIdleState(threshold, callback)
// Replace with synchronous API
const idleState = getSystemIdleState(threshold)
const idleState = powerMonitor.getSystemIdleState(threshold)
```
### `powerMonitor.querySystemIdleTime`
### API Changed: `powerMonitor.querySystemIdleTime` is now `powerMonitor.getSystemIdleState`
```js
// Removed in Electron 7.0
powerMonitor.querySystemIdleTime(callback)
// Replace with synchronous API
const idleTime = getSystemIdleTime()
const idleTime = powerMonitor.getSystemIdleTime()
```
### webFrame Isolated World APIs
### API Changed: `webFrame.setIsolatedWorldInfo` replaces separate methods
```js
// Removed in Electron 7.0
@@ -204,11 +320,11 @@ webFrame.setIsolatedWorldInfo(
})
```
### Removal of deprecated `marked` property on getBlinkMemoryInfo
### Removed: `marked` property on `getBlinkMemoryInfo`
This property was removed in Chromium 77, and as such is no longer available.
### `webkitdirectory` attribute for `<input type="file"/>`
### Behavior Changed: `webkitdirectory` attribute for `<input type="file"/>` now lists directory contents
The `webkitdirectory` property on HTML file inputs allows them to select folders.
Previous versions of Electron had an incorrect implementation where the `event.target.files`
@@ -241,9 +357,10 @@ In Electron 7, this now returns a `FileList` with a `File` object for:
Note that `webkitdirectory` no longer exposes the path to the selected folder.
If you require the path to the selected folder rather than the folder contents,
see the `dialog.showOpenDialog` API ([link](https://github.com/electron/electron/blob/master/docs/api/dialog.md#dialogshowopendialogbrowserwindow-options)).
## Planned Breaking API Changes (6.0)
### `win.setMenu(null)`
### API Changed: `win.setMenu(null)` is now `win.removeMenu()`
```js
// Deprecated
@@ -252,7 +369,7 @@ win.setMenu(null)
win.removeMenu()
```
### `contentTracing.getTraceBufferUsage()`
### API Changed: `contentTracing.getTraceBufferUsage()` is now a promise
```js
// Deprecated
@@ -265,7 +382,7 @@ contentTracing.getTraceBufferUsage().then(infoObject => {
})
```
### `electron.screen` in renderer process
### API Changed: `electron.screen` in the renderer process should be accessed via `remote`
```js
// Deprecated
@@ -274,7 +391,7 @@ require('electron').screen
require('electron').remote.screen
```
### `require` in sandboxed renderers
### API Changed: `require()`ing node builtins in sandboxed renderers no longer implicitly loads the `remote` version
```js
// Deprecated
@@ -298,25 +415,25 @@ require('path')
require('electron').remote.require('path')
```
### `powerMonitor.querySystemIdleState`
### Deprecated: `powerMonitor.querySystemIdleState` replaced with `powerMonitor.getSystemIdleState`
```js
// Deprecated
powerMonitor.querySystemIdleState(threshold, callback)
// Replace with synchronous API
const idleState = getSystemIdleState(threshold)
const idleState = powerMonitor.getSystemIdleState(threshold)
```
### `powerMonitor.querySystemIdleTime`
### Deprecated: `powerMonitor.querySystemIdleTime` replaced with `powerMonitor.getSystemIdleTime`
```js
// Deprecated
powerMonitor.querySystemIdleTime(callback)
// Replace with synchronous API
const idleTime = getSystemIdleTime()
const idleTime = powerMonitor.getSystemIdleTime()
```
### `app.enableMixedSandbox`
### Deprecated: `app.enableMixedSandbox()` is no longer needed
```js
// Deprecated
@@ -325,7 +442,7 @@ app.enableMixedSandbox()
Mixed-sandbox mode is now enabled by default.
### `Tray`
### Deprecated: `Tray.setHighlightMode`
Under macOS Catalina our former Tray implementation breaks.
Apple's native substitute doesn't support changing the highlighting behavior.
@@ -338,7 +455,7 @@ tray.setHighlightMode(mode)
## Planned Breaking API Changes (5.0)
### `new BrowserWindow({ webPreferences })`
### Default Changed: `nodeIntegration` and `webviewTag` default to false, `contextIsolation` defaults to true
The following `webPreferences` option default values are deprecated in favor of the new defaults listed below.
@@ -358,16 +475,16 @@ const w = new BrowserWindow({
})
```
### `nativeWindowOpen`
### Behavior Changed: `nodeIntegration` in child windows opened via `nativeWindowOpen`
Child windows opened with the `nativeWindowOpen` option will always have Node.js integration disabled, unless `nodeIntegrationInSubFrames` is `true.
Child windows opened with the `nativeWindowOpen` option will always have Node.js integration disabled, unless `nodeIntegrationInSubFrames` is `true`.
### Privileged Schemes Registration
### API Changed: Registering privileged schemes must now be done before app ready
Renderer process APIs `webFrame.setRegisterURLSchemeAsPrivileged` and `webFrame.registerURLSchemeAsBypassingCSP` as well as browser process API `protocol.registerStandardSchemes` have been removed.
Renderer process APIs `webFrame.registerURLSchemeAsPrivileged` and `webFrame.registerURLSchemeAsBypassingCSP` as well as browser process API `protocol.registerStandardSchemes` have been removed.
A new API, `protocol.registerSchemesAsPrivileged` has been added and should be used for registering custom schemes with the required privileges. Custom schemes are required to be registered before app ready.
### webFrame Isolated World APIs
### Deprecated: `webFrame.setIsolatedWorld*` replaced with `webFrame.setIsolatedWorldInfo`
```js
// Deprecated
@@ -384,7 +501,7 @@ webFrame.setIsolatedWorldInfo(
})
```
## `webFrame.setSpellCheckProvider`
### API Changed: `webFrame.setSpellCheckProvider` now takes an asynchronous callback
The `spellCheck` callback is now asynchronous, and `autoCorrectWord` parameter has been removed.
```js
// Deprecated

View File

@@ -25,7 +25,7 @@ Follow the guidelines below for building Electron on Linux.
Doing so permits installing Node on your own home directory as a standard user.
Or try repositories such as [NodeSource](https://nodesource.com/blog/nodejs-v012-iojs-and-the-nodesource-linux-repositories).
* [clang](https://clang.llvm.org/get_started.html) 3.4 or later.
* Development headers of GTK+ and libnotify.
* Development headers of GTK 3 and libnotify.
On Ubuntu, install the following libraries:

View File

@@ -42,7 +42,7 @@ $ pip install pyobjc
If you're developing Electron and don't plan to redistribute your
custom Electron build, you may skip this section.
Official Electron builds are built with [Xcode 9.4.1](http://adcdownload.apple.com/Developer_Tools/Xcode_9.4.1/Xcode_9.4.1.xip), and the MacOS 10.13 SDK. Building with a newer SDK works too, but the releases currently use the 10.13 SDK.
Official Electron builds are built with [Xcode 9.4.1](http://adcdownload.apple.com/Developer_Tools/Xcode_9.4.1/Xcode_9.4.1.xip), and the macOS 10.13 SDK. Building with a newer SDK works too, but the releases currently use the 10.13 SDK.
## Building Electron

View File

@@ -20,7 +20,7 @@ you prefer a graphical interface.
tail calls, and other compiler optimizations.
* **Xcode**: In addition to Xcode, also install the Xcode command line tools.
They include LLDB, the default debugger in Xcode on Mac OS X. It supports
They include LLDB, the default debugger in Xcode on macOS. It supports
debugging C, Objective-C and C++ on the desktop and iOS devices and simulator.
* **.lldbinit**: Create or edit `~/.lldbinit` to allow Chromium code to be properly source-mapped.

View File

@@ -35,7 +35,7 @@ $ git fetch upstream
Build steps and dependencies differ slightly depending on your operating system.
See these detailed guides on building Electron locally:
* [Building on MacOS](https://electronjs.org/docs/development/build-instructions-macos)
* [Building on macOS](https://electronjs.org/docs/development/build-instructions-macos)
* [Building on Linux](https://electronjs.org/docs/development/build-instructions-linux)
* [Building on Windows](https://electronjs.org/docs/development/build-instructions-windows)

View File

@@ -324,7 +324,7 @@ app.whenReady().then(() => {
// Quit when all windows are closed.
app.on('window-all-closed', function () {
// On OS X it is common for applications and their menu bar
// On macOS it is common for applications and their menu bar
// to stay active until the user quits explicitly with Cmd + Q
const reopenMenuItem = findReopenMenuItem()
if (reopenMenuItem) reopenMenuItem.enabled = true
@@ -335,7 +335,7 @@ app.on('window-all-closed', function () {
})
app.on('activate', function () {
// On OS X it's common to re-create a window in the app when the
// On macOS it is common to re-create a window in the app when the
// dock icon is clicked and there are no other windows open.
if (mainWindow === null) {
createWindow()

View File

@@ -46,7 +46,7 @@ app.whenReady().then(createWindow)
// Quit when all windows are closed.
app.on('window-all-closed', function () {
// On OS X it is common for applications and their menu bar
// On macOS it is common for applications and their menu bar
// to stay active until the user quits explicitly with Cmd + Q
if (process.platform !== 'darwin') {
app.quit()
@@ -54,7 +54,7 @@ app.on('window-all-closed', function () {
})
app.on('activate', function () {
// On OS X it's common to re-create a window in the app when the
// On macOS it is common to re-create a window in the app when the
// dock icon is clicked and there are no other windows open.
if (mainWindow === null) {
createWindow()

View File

@@ -37,7 +37,7 @@ app.whenReady().then(createWindow)
// Quit when all windows are closed.
app.on('window-all-closed', function () {
// On OS X it is common for applications and their menu bar
// On macOS it is common for applications and their menu bar
// to stay active until the user quits explicitly with Cmd + Q
if (process.platform !== 'darwin') {
app.quit()
@@ -45,7 +45,7 @@ app.on('window-all-closed', function () {
})
app.on('activate', function () {
// On OS X it's common to re-create a window in the app when the
// On macOS it is common to re-create a window in the app when the
// dock icon is clicked and there are no other windows open.
if (mainWindow === null) {
createWindow()

View File

@@ -37,7 +37,7 @@ app.whenReady().then(createWindow)
// Quit when all windows are closed.
app.on('window-all-closed', function () {
// On OS X it is common for applications and their menu bar
// On macOS it is common for applications and their menu bar
// to stay active until the user quits explicitly with Cmd + Q
if (process.platform !== 'darwin') {
app.quit()
@@ -45,7 +45,7 @@ app.on('window-all-closed', function () {
})
app.on('activate', function () {
// On OS X it's common to re-create a window in the app when the
// On macOS it is common to re-create a window in the app when the
// dock icon is clicked and there are no other windows open.
if (mainWindow === null) {
createWindow()

View File

@@ -37,7 +37,7 @@ app.whenReady().then(createWindow)
// Quit when all windows are closed.
app.on('window-all-closed', function () {
// On OS X it is common for applications and their menu bar
// On macOS it is common for applications and their menu bar
// to stay active until the user quits explicitly with Cmd + Q
if (process.platform !== 'darwin') {
app.quit()
@@ -45,7 +45,7 @@ app.on('window-all-closed', function () {
})
app.on('activate', function () {
// On OS X it's common to re-create a window in the app when the
// On macOS it is common to re-create a window in the app when the
// dock icon is clicked and there are no other windows open.
if (mainWindow === null) {
createWindow()

View File

@@ -37,7 +37,7 @@ app.whenReady().then(createWindow)
// Quit when all windows are closed.
app.on('window-all-closed', function () {
// On OS X it is common for applications and their menu bar
// On macOS it is common for applications and their menu bar
// to stay active until the user quits explicitly with Cmd + Q
if (process.platform !== 'darwin') {
app.quit()
@@ -45,7 +45,7 @@ app.on('window-all-closed', function () {
})
app.on('activate', function () {
// On OS X it's common to re-create a window in the app when the
// On macOS it is common to re-create a window in the app when the
// dock icon is clicked and there are no other windows open.
if (mainWindow === null) {
createWindow()

View File

@@ -36,7 +36,7 @@ app.whenReady().then(createWindow)
// Quit when all windows are closed.
app.on('window-all-closed', function () {
// On OS X it is common for applications and their menu bar
// On macOS it is common for applications and their menu bar
// to stay active until the user quits explicitly with Cmd + Q
if (process.platform !== 'darwin') {
app.quit()
@@ -44,7 +44,7 @@ app.on('window-all-closed', function () {
})
app.on('activate', function () {
// On OS X it's common to re-create a window in the app when the
// On macOS it is common to re-create a window in the app when the
// dock icon is clicked and there are no other windows open.
if (mainWindow === null) {
createWindow()

View File

@@ -37,7 +37,7 @@ app.whenReady().then(createWindow)
// Quit when all windows are closed.
app.on('window-all-closed', function () {
// On OS X it is common for applications and their menu bar
// On macOS it is common for applications and their menu bar
// to stay active until the user quits explicitly with Cmd + Q
if (process.platform !== 'darwin') {
app.quit()
@@ -45,7 +45,7 @@ app.on('window-all-closed', function () {
})
app.on('activate', function () {
// On OS X it's common to re-create a window in the app when the
// On macOS it is common to re-create a window in the app when the
// dock icon is clicked and there are no other windows open.
if (mainWindow === null) {
createWindow()

View File

@@ -37,7 +37,7 @@ app.whenReady().then(createWindow)
// Quit when all windows are closed.
app.on('window-all-closed', function () {
// On OS X it is common for applications and their menu bar
// On macOS it is common for applications and their menu bar
// to stay active until the user quits explicitly with Cmd + Q
if (process.platform !== 'darwin') {
app.quit()
@@ -45,7 +45,7 @@ app.on('window-all-closed', function () {
})
app.on('activate', function () {
// On OS X it's common to re-create a window in the app when the
// On macOS it is common to re-create a window in the app when the
// dock icon is clicked and there are no other windows open.
if (mainWindow === null) {
createWindow()

View File

@@ -38,7 +38,7 @@ app.whenReady().then(createWindow)
// Quit when all windows are closed.
app.on('window-all-closed', function () {
// On OS X it is common for applications and their menu bar
// On macOS it is common for applications and their menu bar
// to stay active until the user quits explicitly with Cmd + Q
if (process.platform !== 'darwin') {
app.quit()
@@ -46,7 +46,7 @@ app.on('window-all-closed', function () {
})
app.on('activate', function () {
// On OS X it's common to re-create a window in the app when the
// On macOS it is common to re-create a window in the app when the
// dock icon is clicked and there are no other windows open.
if (mainWindow === null) {
createWindow()

View File

@@ -38,7 +38,7 @@ app.whenReady().then(createWindow)
// Quit when all windows are closed.
app.on('window-all-closed', function () {
// On OS X it is common for applications and their menu bar
// On macOS it is common for applications and their menu bar
// to stay active until the user quits explicitly with Cmd + Q
if (process.platform !== 'darwin') {
app.quit()
@@ -46,7 +46,7 @@ app.on('window-all-closed', function () {
})
app.on('activate', function () {
// On OS X it's common to re-create a window in the app when the
// On macOS it is common to re-create a window in the app when the
// dock icon is clicked and there are no other windows open.
if (mainWindow === null) {
createWindow()

View File

@@ -37,7 +37,7 @@ app.whenReady().then(createWindow)
// Quit when all windows are closed.
app.on('window-all-closed', function () {
// On OS X it is common for applications and their menu bar
// On macOS it is common for applications and their menu bar
// to stay active until the user quits explicitly with Cmd + Q
if (process.platform !== 'darwin') {
app.quit()
@@ -45,7 +45,7 @@ app.on('window-all-closed', function () {
})
app.on('activate', function () {
// On OS X it's common to re-create a window in the app when the
// On macOS it is common to re-create a window in the app when the
// dock icon is clicked and there are no other windows open.
if (mainWindow === null) {
createWindow()

View File

@@ -37,7 +37,7 @@ app.whenReady().then(createWindow)
// Quit when all windows are closed.
app.on('window-all-closed', function () {
// On OS X it is common for applications and their menu bar
// On macOS it is common for applications and their menu bar
// to stay active until the user quits explicitly with Cmd + Q
if (process.platform !== 'darwin') {
app.quit()
@@ -45,7 +45,7 @@ app.on('window-all-closed', function () {
})
app.on('activate', function () {
// On OS X it's common to re-create a window in the app when the
// On macOS it is common to re-create a window in the app when the
// dock icon is clicked and there are no other windows open.
if (mainWindow === null) {
createWindow()

View File

@@ -5,7 +5,7 @@
</head>
<body>
<h2>Create a new window</h2>
<h3>Supports: Win, MacOS, Linux <span>|</span> Process: Main</h3>
<h3>Supports: Win, macOS, Linux <span>|</span> Process: Main</h3>
<button id="new-window">View Demo</button>
<p>The <code>BrowserWindow</code> module gives you the ability to create new windows in your app. This main process module can be used from the renderer process with the <code>remote</code> module, as is shown in this demo.</p>
<p>There are a lot of options when creating a new window. A few are in this demo, but visit the <a id="browser-window-link" href="">documentation<span>(opens in new window)</span></a>

View File

@@ -37,7 +37,7 @@ app.whenReady().then(createWindow)
// Quit when all windows are closed.
app.on('window-all-closed', function () {
// On OS X it is common for applications and their menu bar
// On macOS it is common for applications and their menu bar
// to stay active until the user quits explicitly with Cmd + Q
if (process.platform !== 'darwin') {
app.quit()
@@ -45,7 +45,7 @@ app.on('window-all-closed', function () {
})
app.on('activate', function () {
// On OS X it's common to re-create a window in the app when the
// On macOS it is common to re-create a window in the app when the
// dock icon is clicked and there are no other windows open.
if (mainWindow === null) {
createWindow()

View File

@@ -37,7 +37,7 @@ app.whenReady().then(createWindow)
// Quit when all windows are closed.
app.on('window-all-closed', function () {
// On OS X it is common for applications and their menu bar
// On macOS it is common for applications and their menu bar
// to stay active until the user quits explicitly with Cmd + Q
if (process.platform !== 'darwin') {
app.quit()
@@ -45,7 +45,7 @@ app.on('window-all-closed', function () {
})
app.on('activate', function () {
// On OS X it's common to re-create a window in the app when the
// On macOS it is common to re-create a window in the app when the
// dock icon is clicked and there are no other windows open.
if (mainWindow === null) {
createWindow()

View File

@@ -76,7 +76,7 @@ that cache folder to provide custom builds of Electron or to avoid making contac
with the network at all.
* Linux: `$XDG_CACHE_HOME` or `~/.cache/electron/`
* MacOS: `~/Library/Caches/electron/`
* macOS: `~/Library/Caches/electron/`
* Windows: `$LOCALAPPDATA/electron/Cache` or `~/AppData/Local/electron/Cache/`
On environments that have been using older versions of Electron, you might find the

View File

@@ -1,4 +1,4 @@
# MacOS Dock
# macOS Dock
Electron has APIs to configure the app's icon in the macOS Dock. A macOS-only
API exists to create a custom dock menu, but

View File

@@ -49,7 +49,7 @@ The library file `widevinecdm.dll` will be under
`Program Files(x86)/Google/Chrome/Application/CHROME_VERSION/WidevineCdm/_platform_specific/win_(x86|x64)/`
directory.
### On MacOS
### On macOS
The library file `libwidevinecdm.dylib` will be under
`/Applications/Google Chrome.app/Contents/Versions/CHROME_VERSION/Google Chrome Framework.framework/Versions/A/Libraries/WidevineCdm/_platform_specific/mac_(x86|x64)/`

View File

@@ -21,6 +21,7 @@ auto_filenames = {
"docs/api/dock.md",
"docs/api/download-item.md",
"docs/api/environment-variables.md",
"docs/api/extensions.md",
"docs/api/file-object.md",
"docs/api/frameless-window.md",
"docs/api/global-shortcut.md",
@@ -96,6 +97,7 @@ auto_filenames = {
"docs/api/structures/mime-typed-buffer.md",
"docs/api/structures/mouse-input-event.md",
"docs/api/structures/mouse-wheel-input-event.md",
"docs/api/structures/new-window-event.md",
"docs/api/structures/notification-action.md",
"docs/api/structures/point.md",
"docs/api/structures/printer-info.md",
@@ -136,14 +138,13 @@ auto_filenames = {
"lib/common/api/module-list.ts",
"lib/common/api/native-image.js",
"lib/common/api/shell.js",
"lib/common/crash-reporter.js",
"lib/common/define-properties.ts",
"lib/common/electron-binding-setup.ts",
"lib/common/type-utils.ts",
"lib/common/web-view-methods.ts",
"lib/common/webpack-globals-provider.ts",
"lib/renderer/api/context-bridge.ts",
"lib/renderer/api/crash-reporter.js",
"lib/renderer/api/crash-reporter.ts",
"lib/renderer/api/desktop-capturer.ts",
"lib/renderer/api/ipc-renderer.ts",
"lib/renderer/api/remote.js",
@@ -178,11 +179,8 @@ auto_filenames = {
isolated_bundle_deps = [
"lib/common/electron-binding-setup.ts",
"lib/isolated_renderer/init.js",
"lib/renderer/ipc-renderer-internal-utils.ts",
"lib/renderer/ipc-renderer-internal.ts",
"lib/renderer/web-view/web-view-constants.ts",
"lib/renderer/web-view/web-view-element.ts",
"lib/renderer/window-setup.ts",
"package.json",
"tsconfig.electron.json",
"tsconfig.json",
@@ -192,6 +190,7 @@ auto_filenames = {
"lib/common/electron-binding-setup.ts",
"lib/common/webpack-globals-provider.ts",
"lib/content_script/init.js",
"lib/renderer/api/context-bridge.ts",
"lib/renderer/chrome-api.ts",
"lib/renderer/extensions/event.ts",
"lib/renderer/extensions/i18n.ts",
@@ -214,7 +213,7 @@ auto_filenames = {
"lib/browser/api/browser-view.js",
"lib/browser/api/browser-window.js",
"lib/browser/api/content-tracing.js",
"lib/browser/api/crash-reporter.js",
"lib/browser/api/crash-reporter.ts",
"lib/browser/api/dialog.js",
"lib/browser/api/exports/electron.ts",
"lib/browser/api/global-shortcut.js",
@@ -250,7 +249,6 @@ auto_filenames = {
"lib/browser/api/web-contents.js",
"lib/browser/chrome-extension-shim.js",
"lib/browser/chrome-extension.js",
"lib/browser/crash-reporter-init.js",
"lib/browser/default-menu.ts",
"lib/browser/desktop-capturer.ts",
"lib/browser/devtools.ts",
@@ -270,7 +268,6 @@ auto_filenames = {
"lib/common/api/module-list.ts",
"lib/common/api/native-image.js",
"lib/common/api/shell.js",
"lib/common/crash-reporter.js",
"lib/common/define-properties.ts",
"lib/common/electron-binding-setup.ts",
"lib/common/init.ts",
@@ -293,7 +290,6 @@ auto_filenames = {
"lib/common/api/module-list.ts",
"lib/common/api/native-image.js",
"lib/common/api/shell.js",
"lib/common/crash-reporter.js",
"lib/common/define-properties.ts",
"lib/common/electron-binding-setup.ts",
"lib/common/init.ts",
@@ -302,7 +298,7 @@ auto_filenames = {
"lib/common/web-view-methods.ts",
"lib/common/webpack-globals-provider.ts",
"lib/renderer/api/context-bridge.ts",
"lib/renderer/api/crash-reporter.js",
"lib/renderer/api/crash-reporter.ts",
"lib/renderer/api/desktop-capturer.ts",
"lib/renderer/api/exports/electron.ts",
"lib/renderer/api/ipc-renderer.ts",
@@ -342,7 +338,6 @@ auto_filenames = {
"lib/common/api/module-list.ts",
"lib/common/api/native-image.js",
"lib/common/api/shell.js",
"lib/common/crash-reporter.js",
"lib/common/define-properties.ts",
"lib/common/electron-binding-setup.ts",
"lib/common/init.ts",
@@ -350,7 +345,7 @@ auto_filenames = {
"lib/common/type-utils.ts",
"lib/common/webpack-globals-provider.ts",
"lib/renderer/api/context-bridge.ts",
"lib/renderer/api/crash-reporter.js",
"lib/renderer/api/crash-reporter.ts",
"lib/renderer/api/desktop-capturer.ts",
"lib/renderer/api/exports/electron.ts",
"lib/renderer/api/ipc-renderer.ts",

View File

@@ -31,6 +31,8 @@ filenames = {
"shell/app/command_line_args.h",
"shell/app/electron_content_client.cc",
"shell/app/electron_content_client.h",
"shell/app/electron_crash_reporter_client.cc",
"shell/app/electron_crash_reporter_client.h",
"shell/app/electron_main_delegate.cc",
"shell/app/electron_main_delegate.h",
"shell/app/electron_main_delegate_mac.h",
@@ -51,6 +53,8 @@ filenames = {
"shell/browser/api/electron_api_content_tracing.cc",
"shell/browser/api/electron_api_cookies.cc",
"shell/browser/api/electron_api_cookies.h",
"shell/browser/api/electron_api_crash_reporter.cc",
"shell/browser/api/electron_api_crash_reporter.h",
"shell/browser/api/electron_api_data_pipe_holder.cc",
"shell/browser/api/electron_api_data_pipe_holder.h",
"shell/browser/api/electron_api_debugger.cc",
@@ -164,7 +168,6 @@ filenames = {
"shell/browser/electron_javascript_dialog_manager.h",
"shell/browser/electron_navigation_throttle.cc",
"shell/browser/electron_navigation_throttle.h",
"shell/browser/electron_paths.h",
"shell/browser/electron_permission_manager.cc",
"shell/browser/electron_permission_manager.h",
"shell/browser/electron_quota_permission_context.cc",
@@ -433,7 +436,6 @@ filenames = {
"shell/common/api/electron_api_clipboard.h",
"shell/common/api/electron_api_clipboard_mac.mm",
"shell/common/api/electron_api_command_line.cc",
"shell/common/api/electron_api_crash_reporter.cc",
"shell/common/api/electron_api_key_weak_map.h",
"shell/common/api/electron_api_native_image.cc",
"shell/common/api/electron_api_native_image.h",
@@ -456,22 +458,13 @@ filenames = {
"shell/common/asar/scoped_temporary_file.h",
"shell/common/color_util.cc",
"shell/common/color_util.h",
"shell/common/crash_reporter/crash_reporter.cc",
"shell/common/crash_reporter/crash_reporter.h",
"shell/common/crash_reporter/crash_reporter_linux.cc",
"shell/common/crash_reporter/crash_reporter_linux.h",
"shell/common/crash_reporter/crash_reporter_mac.h",
"shell/common/crash_reporter/crash_reporter_mac.mm",
"shell/common/crash_reporter/crash_reporter_win.cc",
"shell/common/crash_reporter/crash_reporter_win.h",
"shell/common/crash_reporter/linux/crash_dump_handler.cc",
"shell/common/crash_reporter/linux/crash_dump_handler.h",
"shell/common/crash_reporter/win/crash_service_main.cc",
"shell/common/crash_reporter/win/crash_service_main.h",
"shell/common/crash_keys.cc",
"shell/common/crash_keys.h",
"shell/common/electron_command_line.cc",
"shell/common/electron_command_line.h",
"shell/common/electron_constants.cc",
"shell/common/electron_constants.h",
"shell/common/electron_paths.h",
"shell/common/gin_converters/accelerator_converter.cc",
"shell/common/gin_converters/accelerator_converter.h",
"shell/common/gin_converters/blink_converter.cc",
@@ -479,8 +472,6 @@ filenames = {
"shell/common/gin_converters/callback_converter.h",
"shell/common/gin_converters/content_converter.cc",
"shell/common/gin_converters/content_converter.h",
"shell/common/gin_converters/extension_converter.cc",
"shell/common/gin_converters/extension_converter.h",
"shell/common/gin_converters/file_dialog_converter.cc",
"shell/common/gin_converters/file_dialog_converter.h",
"shell/common/gin_converters/file_path_converter.h",
@@ -495,6 +486,8 @@ filenames = {
"shell/common/gin_converters/net_converter.cc",
"shell/common/gin_converters/net_converter.h",
"shell/common/gin_converters/std_converter.h",
"shell/common/gin_converters/time_converter.cc",
"shell/common/gin_converters/time_converter.h",
"shell/common/gin_converters/value_converter.cc",
"shell/common/gin_converters/value_converter.h",
"shell/common/gin_helper/arguments.cc",
@@ -531,6 +524,10 @@ filenames = {
"shell/common/key_weak_map.h",
"shell/common/keyboard_util.cc",
"shell/common/keyboard_util.h",
"shell/common/language_util.h",
"shell/common/language_util_linux.cc",
"shell/common/language_util_mac.mm",
"shell/common/language_util_win.cc",
"shell/common/mac/main_application_bundle.h",
"shell/common/mac/main_application_bundle.mm",
"shell/common/mouse_util.cc",
@@ -565,6 +562,7 @@ filenames = {
"shell/renderer/api/context_bridge/render_frame_function_store.h",
"shell/renderer/api/electron_api_context_bridge.cc",
"shell/renderer/api/electron_api_context_bridge.h",
"shell/renderer/api/electron_api_crash_reporter_renderer.cc",
"shell/renderer/api/electron_api_renderer_ipc.cc",
"shell/renderer/api/electron_api_spell_check_client.cc",
"shell/renderer/api/electron_api_spell_check_client.h",
@@ -645,6 +643,8 @@ filenames = {
"shell/common/extensions/electron_extensions_api_provider.h",
"shell/common/extensions/electron_extensions_client.cc",
"shell/common/extensions/electron_extensions_client.h",
"shell/common/gin_converters/extension_converter.cc",
"shell/common/gin_converters/extension_converter.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",

View File

@@ -92,43 +92,6 @@ BrowserWindow.prototype._init = function () {
return this.webContents.devToolsWebContents;
}
});
// Properties
Object.defineProperty(this, 'autoHideMenuBar', {
get: () => this.isMenuBarAutoHide(),
set: (autoHide) => this.setAutoHideMenuBar(autoHide)
});
Object.defineProperty(this, 'minimizable', {
get: () => this.isMinimizable(),
set: (min) => this.setMinimizable(min)
});
Object.defineProperty(this, 'maximizable', {
get: () => this.isMaximizable(),
set: (max) => this.setMaximizable(max)
});
Object.defineProperty(this, 'resizable', {
get: () => this.isResizable(),
set: (res) => this.setResizable(res)
});
Object.defineProperty(this, 'fullScreenable', {
get: () => this.isFullScreenable(),
set: (full) => this.setFullScreenable(full)
});
Object.defineProperty(this, 'closable', {
get: () => this.isClosable(),
set: (close) => this.setClosable(close)
});
Object.defineProperty(this, 'movable', {
get: () => this.isMovable(),
set: (move) => this.setMovable(move)
});
};
const isBrowserWindow = (win) => {

View File

@@ -1,12 +0,0 @@
'use strict';
const CrashReporter = require('@electron/internal/common/crash-reporter');
const { crashReporterInit } = require('@electron/internal/browser/crash-reporter-init');
class CrashReporterMain extends CrashReporter {
init (options) {
return crashReporterInit(options);
}
}
module.exports = new CrashReporterMain();

View File

@@ -0,0 +1,83 @@
import { app } from 'electron';
const binding = process.electronBinding('crash_reporter');
class CrashReporter {
start (options: Electron.CrashReporterStartOptions) {
const {
productName = app.name,
companyName = undefined,
extra = {},
globalExtra = {},
ignoreSystemCrashHandler = false,
submitURL = undefined,
uploadToServer = true,
rateLimit = false,
compress = false
} = options || {};
if (submitURL == null) throw new Error('submitURL is a required option to crashReporter.start');
const appVersion = app.getVersion();
if (companyName && globalExtra._companyName == null) globalExtra._companyName = companyName;
const globalExtraAmended = {
_productName: productName,
_version: appVersion,
...globalExtra
};
binding.start(submitURL, uploadToServer,
ignoreSystemCrashHandler, rateLimit, compress, globalExtraAmended, extra, false);
}
getLastCrashReport () {
const reports = this.getUploadedReports()
.sort((a, b) => {
const ats = (a && a.date) ? new Date(a.date).getTime() : 0;
const bts = (b && b.date) ? new Date(b.date).getTime() : 0;
return bts - ats;
});
return (reports.length > 0) ? reports[0] : null;
}
getUploadedReports (): Electron.CrashReport[] {
return binding.getUploadedReports();
}
getCrashesDirectory () {
return app.getPath('crashDumps');
}
getUploadToServer () {
if (process.type === 'browser') {
return binding.getUploadToServer();
} else {
throw new Error('getUploadToServer can only be called from the main process');
}
}
setUploadToServer (uploadToServer: boolean) {
if (process.type === 'browser') {
return binding.setUploadToServer(uploadToServer);
} else {
throw new Error('setUploadToServer can only be called from the main process');
}
}
addExtraParameter (key: string, value: string) {
binding.addExtraParameter(key, value);
}
removeExtraParameter (key: string) {
binding.removeExtraParameter(key);
}
getParameters () {
return binding.getParameters();
}
}
export default new CrashReporter();

View File

@@ -17,6 +17,88 @@ TopLevelWindow.prototype._init = function () {
}
};
// Properties
Object.defineProperty(TopLevelWindow.prototype, 'autoHideMenuBar', {
get: function () { return this.isMenuBarAutoHide(); },
set: function (autoHide) { this.setAutoHideMenuBar(autoHide); }
});
Object.defineProperty(TopLevelWindow.prototype, 'visibleOnAllWorkspaces', {
get: function () { return this.isVisibleOnAllWorkspaces(); },
set: function (visible) { this.setVisibleOnAllWorkspaces(visible); }
});
Object.defineProperty(TopLevelWindow.prototype, 'fullScreen', {
get: function () { return this.isFullScreen(); },
set: function (full) { this.setFullScreen(full); }
});
Object.defineProperty(TopLevelWindow.prototype, 'simpleFullScreen', {
get: function () { return this.isSimpleFullScreen(); },
set: function (simple) { this.setSimpleFullScreen(simple); }
});
Object.defineProperty(TopLevelWindow.prototype, 'kiosk', {
get: function () { return this.isKiosk(); },
set: function (kiosk) { this.setKiosk(kiosk); }
});
Object.defineProperty(TopLevelWindow.prototype, 'documentEdited', {
get: function () { return this.isFullscreen(); },
set: function (edited) { this.setDocumentEdited(edited); }
});
Object.defineProperty(TopLevelWindow.prototype, 'shadow', {
get: function () { return this.hasShadow(); },
set: function (shadow) { this.setHasShadow(shadow); }
});
Object.defineProperty(TopLevelWindow.prototype, 'representedFilename', {
get: function () { return this.getRepresentedFilename(); },
set: function (filename) { this.setRepresentedFilename(filename); }
});
Object.defineProperty(TopLevelWindow.prototype, 'minimizable', {
get: function () { return this.isMinimizable(); },
set: function (min) { this.setMinimizable(min); }
});
Object.defineProperty(TopLevelWindow.prototype, 'title', {
get: function () { return this.getTitle(); },
set: function (title) { this.setTitle(title); }
});
Object.defineProperty(TopLevelWindow.prototype, 'maximizable', {
get: function () { return this.isMaximizable(); },
set: function (max) { this.setMaximizable(max); }
});
Object.defineProperty(TopLevelWindow.prototype, 'resizable', {
get: function () { return this.isResizable(); },
set: function (res) { this.setResizable(res); }
});
Object.defineProperty(TopLevelWindow.prototype, 'menuBarVisible', {
get: function () { return this.isMenuBarVisible(); },
set: function (visible) { this.setMenuBarVisibility(visible); }
});
Object.defineProperty(TopLevelWindow.prototype, 'fullScreenable', {
get: function () { return this.isFullScreenable(); },
set: function (full) { this.setFullScreenable(full); }
});
Object.defineProperty(TopLevelWindow.prototype, 'closable', {
get: function () { return this.isClosable(); },
set: function (close) { this.setClosable(close); }
});
Object.defineProperty(TopLevelWindow.prototype, 'movable', {
get: function () { return this.isMovable(); },
set: function (move) { this.setMovable(move); }
});
TopLevelWindow.getFocusedWindow = () => {
return TopLevelWindow.getAllWindows().find((win) => win.isFocused());
};

View File

@@ -528,6 +528,11 @@ WebContents.prototype._init = function () {
const referrer = { url: '', policy: 'default' };
internalWindowOpen(event, url, referrer, frameName, disposition, options);
});
const prefs = this.getWebPreferences() || {};
if (prefs.webviewTag && prefs.contextIsolation) {
electron.deprecate.log('Security Warning: A WebContents was just created with both webviewTag and contextIsolation enabled. This combination is fundamentally less secure and effectively bypasses the protections of contextIsolation. We strongly recommend you move away from webviews to OOPIF or BrowserView in order for your app to be more secure');
}
}
this.on('login', (event, ...args) => {

View File

@@ -1,25 +0,0 @@
'use strict';
const { app } = require('electron');
const path = require('path');
const getTempDirectory = function () {
try {
return app.getPath('temp');
} catch {
// Delibrately laze-load the os module, this file is on the hot
// path when booting Electron and os takes between 5 - 8ms to load and we do not need it yet
return require('os').tmpdir();
}
};
exports.crashReporterInit = function (options) {
const productName = options.productName || app.name;
const crashesDirectory = path.join(getTempDirectory(), `${productName} Crashes`);
return {
productName,
crashesDirectory,
appVersion: app.getVersion()
};
};

View File

@@ -266,6 +266,9 @@ const attachGuest = function (event, embedderFrameId, elementInstanceId, guestIn
// Remove an guest-embedder relationship.
const detachGuest = function (embedder, guestInstanceId) {
const guestInstance = guestInstances[guestInstanceId];
if (!guestInstance) return;
if (embedder !== guestInstance.embedder) {
return;
}
@@ -356,6 +359,10 @@ handleMessage('ELECTRON_GUEST_VIEW_MANAGER_ATTACH_GUEST', function (event, embed
}
});
handleMessageSync('ELECTRON_GUEST_VIEW_MANAGER_DETACH_GUEST', function (event, guestInstanceId) {
return detachGuest(event.sender, guestInstanceId);
});
// this message is sent by the actual <webview>
ipcMainInternal.on('ELECTRON_GUEST_VIEW_MANAGER_FOCUS_CHANGE', function (event, focus, guestInstanceId) {
const guest = getGuest(guestInstanceId);

View File

@@ -203,10 +203,9 @@ const { setDefaultApplicationMenu } = require('@electron/internal/browser/defaul
// Create default menu.
//
// Note that the task must be added before loading any app, so we can make sure
// the call is maded before any user window is created, otherwise the default
// menu may show even when user explicitly hides the menu.
app.whenReady().then(setDefaultApplicationMenu);
// The |will-finish-launching| event is emitted before |ready| event, so default
// menu is set before any user window is created.
app.once('will-finish-launching', setDefaultApplicationMenu);
if (packagePath) {
// Finally load app's main.js and transfer control to C++.

View File

@@ -7,7 +7,6 @@ const eventBinding = process.electronBinding('event');
const clipboard = process.electronBinding('clipboard');
const features = process.electronBinding('features');
const { crashReporterInit } = require('@electron/internal/browser/crash-reporter-init');
const { ipcMainInternal } = require('@electron/internal/browser/ipc-main-internal');
const ipcMainUtils = require('@electron/internal/browser/ipc-main-internal-utils');
const guestViewManager = require('@electron/internal/browser/guest-view-manager');
@@ -37,10 +36,6 @@ ipcMainInternal.on('ELECTRON_BROWSER_WINDOW_CLOSE', function (event) {
event.returnValue = null;
});
ipcMainUtils.handleSync('ELECTRON_CRASH_REPORTER_INIT', function (event, options) {
return crashReporterInit(options);
});
ipcMainInternal.handle('ELECTRON_BROWSER_GET_LAST_WEB_PREFERENCES', function (event) {
return event.sender.getLastWebPreferences();
});
@@ -135,3 +130,23 @@ ipcMainUtils.handleSync('ELECTRON_BROWSER_SANDBOX_LOAD', async function (event)
ipcMainInternal.on('ELECTRON_BROWSER_PRELOAD_ERROR', function (event, preloadPath, error) {
event.sender.emit('preload-error', event, preloadPath, error);
});
ipcMainUtils.handleSync('ELECTRON_CRASH_REPORTER_GET_LAST_CRASH_REPORT', () => {
return electron.crashReporter.getLastCrashReport();
});
ipcMainUtils.handleSync('ELECTRON_CRASH_REPORTER_GET_UPLOADED_REPORTS', () => {
return electron.crashReporter.getUploadedReports();
});
ipcMainUtils.handleSync('ELECTRON_CRASH_REPORTER_GET_UPLOAD_TO_SERVER', () => {
return electron.crashReporter.getUploadToServer();
});
ipcMainUtils.handleSync('ELECTRON_CRASH_REPORTER_SET_UPLOAD_TO_SERVER', (event, uploadToServer) => {
return electron.crashReporter.setUploadToServer(uploadToServer);
});
ipcMainUtils.handleSync('ELECTRON_CRASH_REPORTER_GET_CRASHES_DIRECTORY', () => {
return electron.crashReporter.getCrashesDirectory();
});

View File

@@ -1,98 +0,0 @@
'use strict';
const binding = process.electronBinding('crash_reporter');
class CrashReporter {
constructor () {
this.productName = null;
this.crashesDirectory = null;
}
init (options) {
throw new Error('Not implemented');
}
start (options) {
if (options == null) options = {};
const {
productName,
companyName,
extra = {},
ignoreSystemCrashHandler = false,
submitURL,
uploadToServer = true
} = options;
if (companyName == null) throw new Error('companyName is a required option to crashReporter.start');
if (submitURL == null) throw new Error('submitURL is a required option to crashReporter.start');
const ret = this.init({
submitURL,
productName
});
this.productName = ret.productName;
this.crashesDirectory = ret.crashesDirectory;
if (extra._productName == null) extra._productName = ret.productName;
if (extra._companyName == null) extra._companyName = companyName;
if (extra._version == null) extra._version = ret.appVersion;
binding.start(ret.productName, companyName, submitURL, ret.crashesDirectory, uploadToServer, ignoreSystemCrashHandler, extra);
}
getLastCrashReport () {
const reports = this.getUploadedReports()
.sort((a, b) => {
const ats = (a && a.date) ? new Date(a.date).getTime() : 0;
const bts = (b && b.date) ? new Date(b.date).getTime() : 0;
return bts - ats;
});
return (reports.length > 0) ? reports[0] : null;
}
getUploadedReports () {
const crashDir = this.getCrashesDirectory();
if (!crashDir) {
throw new Error('crashReporter has not been started');
}
return binding.getUploadedReports(crashDir);
}
getCrashesDirectory () {
return this.crashesDirectory;
}
getUploadToServer () {
if (process.type === 'browser') {
return binding.getUploadToServer();
} else {
throw new Error('getUploadToServer can only be called from the main process');
}
}
setUploadToServer (uploadToServer) {
if (process.type === 'browser') {
return binding.setUploadToServer(uploadToServer);
} else {
throw new Error('setUploadToServer can only be called from the main process');
}
}
addExtraParameter (key, value) {
binding.addExtraParameter(key, value);
}
removeExtraParameter (key) {
binding.removeExtraParameter(key);
}
getParameters () {
return binding.getParameters();
}
}
module.exports = CrashReporter;

View File

@@ -6,10 +6,6 @@ process.electronBinding = require('@electron/internal/common/electron-binding-se
const v8Util = process.electronBinding('v8_util');
// The `lib/renderer/ipc-renderer-internal.js` module looks for the ipc object in the
// "ipc-internal" hidden value
v8Util.setHiddenValue(global, 'ipc-internal', v8Util.getHiddenValue(isolatedWorld, 'ipc-internal'));
const webViewImpl = v8Util.getHiddenValue(isolatedWorld, 'web-view-impl');
if (webViewImpl) {
@@ -17,11 +13,3 @@ if (webViewImpl) {
const { setupWebView } = require('@electron/internal/renderer/web-view/web-view-element');
setupWebView(v8Util, webViewImpl);
}
const isolatedWorldArgs = v8Util.getHiddenValue(isolatedWorld, 'isolated-world-args');
if (isolatedWorldArgs) {
const { guestInstanceId, isHiddenPage, openerId, usesNativeWindowOpen } = isolatedWorldArgs;
const { windowSetup } = require('@electron/internal/renderer/window-setup');
windowSetup(guestInstanceId, openerId, isHiddenPage, usesNativeWindowOpen);
}

View File

@@ -18,3 +18,17 @@ const contextBridge = {
if (!binding._debugGCMaps) delete contextBridge.debugGC;
export default contextBridge;
export const internalContextBridge = {
contextIsolationEnabled,
overrideGlobalValueFromIsolatedWorld: (keys: string[], value: any) => {
return binding._overrideGlobalValueFromIsolatedWorld(keys, value, false);
},
overrideGlobalValueWithDynamicPropsFromIsolatedWorld: (keys: string[], value: any) => {
return binding._overrideGlobalValueFromIsolatedWorld(keys, value, true);
},
overrideGlobalPropertyFromIsolatedWorld: (keys: string[], getter: Function, setter?: Function) => {
return binding._overrideGlobalPropertyFromIsolatedWorld(keys, getter, setter || null);
},
isInMainWorld: () => binding._isCalledFromMainWorld() as boolean
};

View File

@@ -1,12 +0,0 @@
'use strict';
const CrashReporter = require('@electron/internal/common/crash-reporter');
const ipcRendererUtils = require('@electron/internal/renderer/ipc-renderer-internal-utils');
class CrashReporterRenderer extends CrashReporter {
init (options) {
return ipcRendererUtils.invokeSync('ELECTRON_CRASH_REPORTER_INIT', options);
}
}
module.exports = new CrashReporterRenderer();

View File

@@ -0,0 +1,50 @@
import { invokeSync } from '../ipc-renderer-internal-utils';
import { deprecate } from 'electron';
const binding = process.electronBinding('crash_reporter');
export default {
start (options: Electron.CrashReporterStartOptions) {
deprecate.log('crashReporter.start is deprecated in the renderer process. Call it from the main process instead.');
for (const [k, v] of Object.entries(options.extra || {})) {
binding.addExtraParameter(k, String(v));
}
},
getLastCrashReport (): Electron.CrashReport | null {
deprecate.log('crashReporter.getLastCrashReport is deprecated in the renderer process. Call it from the main process instead.');
return invokeSync('ELECTRON_CRASH_REPORTER_GET_LAST_CRASH_REPORT');
},
getUploadedReports () {
deprecate.log('crashReporter.getUploadedReports is deprecated in the renderer process. Call it from the main process instead.');
return invokeSync('ELECTRON_CRASH_REPORTER_GET_UPLOADED_REPORTS');
},
getUploadToServer () {
deprecate.log('crashReporter.getUploadToServer is deprecated in the renderer process. Call it from the main process instead.');
return invokeSync('ELECTRON_CRASH_REPORTER_GET_UPLOAD_TO_SERVER');
},
setUploadToServer (uploadToServer: boolean) {
deprecate.log('crashReporter.setUploadToServer is deprecated in the renderer process. Call it from the main process instead.');
return invokeSync('ELECTRON_CRASH_REPORTER_SET_UPLOAD_TO_SERVER', uploadToServer);
},
getCrashesDirectory () {
deprecate.log('crashReporter.getCrashesDirectory is deprecated in the renderer process. Call it from the main process instead.');
return invokeSync('ELECTRON_CRASH_REPORTER_GET_CRASHES_DIRECTORY');
},
addExtraParameter (key: string, value: string) {
binding.addExtraParameter(key, value);
},
removeExtraParameter (key: string) {
binding.removeExtraParameter(key);
},
getParameters () {
return binding.getParameters();
}
};

View File

@@ -1,5 +1,6 @@
import { webFrame, IpcMessageEvent } from 'electron';
import { ipcRendererInternal } from '@electron/internal/renderer/ipc-renderer-internal';
import * as ipcRendererUtils from '@electron/internal/renderer/ipc-renderer-internal-utils';
import { WebViewImpl } from '@electron/internal/renderer/web-view/web-view-impl';
@@ -105,8 +106,13 @@ export function attachGuest (
ipcRendererInternal.invoke('ELECTRON_GUEST_VIEW_MANAGER_ATTACH_GUEST', embedderFrameId, elementInstanceId, guestInstanceId, params);
}
export function detachGuest (guestInstanceId: number) {
return ipcRendererUtils.invokeSync('ELECTRON_GUEST_VIEW_MANAGER_DETACH_GUEST', guestInstanceId);
}
export const guestViewInternalModule = {
deregisterEvents,
createGuest,
attachGuest
attachGuest,
detachGuest
};

View File

@@ -66,6 +66,9 @@ const defineWebViewElement = (v8Util: NodeJS.V8UtilBinding, webViewImpl: typeof
return;
}
guestViewInternal.deregisterEvents(internal.viewInstanceId);
if (internal.guestInstanceId) {
guestViewInternal.detachGuest(internal.guestInstanceId);
}
internal.elementAttached = false;
this.internalInstanceId = 0;
internal.reset();

View File

@@ -1,11 +1,10 @@
import { ipcRendererInternal } from '@electron/internal/renderer/ipc-renderer-internal';
import * as ipcRendererUtils from '@electron/internal/renderer/ipc-renderer-internal-utils';
import { internalContextBridge } from '@electron/internal/renderer/api/context-bridge';
// This file implements the following APIs:
// - window.history.back()
// - window.history.forward()
// - window.history.go()
// - window.history.length
const { contextIsolationEnabled } = internalContextBridge;
// This file implements the following APIs over the ctx bridge:
// - window.open()
// - window.opener.blur()
// - window.opener.close()
@@ -13,7 +12,12 @@ import * as ipcRendererUtils from '@electron/internal/renderer/ipc-renderer-inte
// - window.opener.focus()
// - window.opener.location
// - window.opener.print()
// - window.opener.closed
// - window.opener.postMessage()
// - window.history.back()
// - window.history.forward()
// - window.history.go()
// - window.history.length
// - window.prompt()
// - document.hidden
// - document.visibilityState
@@ -30,13 +34,13 @@ const toString = (value: any) => {
const windowProxies = new Map<number, BrowserWindowProxy>();
const getOrCreateProxy = (guestId: number) => {
const getOrCreateProxy = (guestId: number): SafelyBoundBrowserWindowProxy => {
let proxy = windowProxies.get(guestId);
if (proxy == null) {
proxy = new BrowserWindowProxy(guestId);
windowProxies.set(guestId, proxy);
}
return proxy;
return proxy.getSafe();
};
const removeProxy = (guestId: number) => {
@@ -64,6 +68,8 @@ class LocationProxy {
*/
private static ProxyProperty<T> (target: LocationProxy, propertyKey: LocationProperties) {
Object.defineProperty(target, propertyKey, {
enumerable: true,
configurable: true,
get: function (this: LocationProxy): T | string {
const guestURL = this.getGuestURL();
const value = guestURL ? guestURL[propertyKey] : '';
@@ -82,6 +88,30 @@ class LocationProxy {
});
}
public getSafe = () => {
const that = this;
return {
get href () { return that.href; },
set href (newValue) { that.href = newValue; },
get hash () { return that.hash; },
set hash (newValue) { that.hash = newValue; },
get host () { return that.host; },
set host (newValue) { that.host = newValue; },
get hostname () { return that.hostname; },
set hostname (newValue) { that.hostname = newValue; },
get origin () { return that.origin; },
set origin (newValue) { that.origin = newValue; },
get pathname () { return that.pathname; },
set pathname (newValue) { that.pathname = newValue; },
get port () { return that.port; },
set port (newValue) { that.port = newValue; },
get protocol () { return that.protocol; },
set protocol (newValue) { that.protocol = newValue; },
get search () { return that.search; },
set search (newValue) { that.search = newValue; }
};
}
constructor (guestId: number) {
// eslint will consider the constructor "useless"
// unless we assign them in the body. It's fine, that's what
@@ -114,6 +144,17 @@ class LocationProxy {
}
}
interface SafelyBoundBrowserWindowProxy {
location: WindowProxy['location'];
blur: WindowProxy['blur'];
close: WindowProxy['close'];
eval: typeof eval; // eslint-disable-line no-eval
focus: WindowProxy['focus'];
print: WindowProxy['print'];
postMessage: WindowProxy['postMessage'];
closed: boolean;
}
class BrowserWindowProxy {
public closed: boolean = false
@@ -124,7 +165,7 @@ class BrowserWindowProxy {
// so for now, we'll have to make do with an "any" in the mix.
// https://github.com/Microsoft/TypeScript/issues/2521
public get location (): LocationProxy | any {
return this._location;
return this._location.getSafe();
}
public set location (url: string | any) {
url = resolveURL(url, this.location.href);
@@ -141,27 +182,48 @@ class BrowserWindowProxy {
});
}
public close () {
public getSafe = (): SafelyBoundBrowserWindowProxy => {
const that = this;
return {
postMessage: this.postMessage,
blur: this.blur,
close: this.close,
focus: this.focus,
print: this.print,
eval: this.eval,
get location () {
return that.location;
},
set location (url: string | any) {
that.location = url;
},
get closed () {
return that.closed;
}
};
}
public close = () => {
this._invokeWindowMethod('destroy');
}
public focus () {
public focus = () => {
this._invokeWindowMethod('focus');
}
public blur () {
public blur = () => {
this._invokeWindowMethod('blur');
}
public print () {
public print = () => {
this._invokeWebContentsMethod('print');
}
public postMessage (message: any, targetOrigin: string) {
public postMessage = (message: any, targetOrigin: string) => {
ipcRendererInternal.invoke('ELECTRON_GUEST_WINDOW_MANAGER_WINDOW_POSTMESSAGE', this.guestId, message, toString(targetOrigin), window.location.origin);
}
public eval (code: string) {
public eval = (code: string) => {
this._invokeWebContentsMethod('executeJavaScript', code);
}
@@ -182,9 +244,11 @@ export const windowSetup = (
window.close = function () {
ipcRendererInternal.send('ELECTRON_BROWSER_WINDOW_CLOSE');
};
if (contextIsolationEnabled) internalContextBridge.overrideGlobalValueFromIsolatedWorld(['close'], window.close);
}
if (!usesNativeWindowOpen) {
// TODO(MarshallOfSound): Make compatible with ctx isolation without hole-punch
// Make the browser window or guest view emit "new-window" event.
(window as any).open = function (url?: string, frameName?: string, features?: string) {
if (url != null && url !== '') {
@@ -197,16 +261,19 @@ export const windowSetup = (
return null;
}
};
if (contextIsolationEnabled) internalContextBridge.overrideGlobalValueWithDynamicPropsFromIsolatedWorld(['open'], window.open);
}
if (openerId != null) {
window.opener = getOrCreateProxy(openerId);
if (contextIsolationEnabled) internalContextBridge.overrideGlobalValueWithDynamicPropsFromIsolatedWorld(['opener'], window.opener);
}
// But we do not support prompt().
window.prompt = function () {
throw new Error('prompt() is and will not be supported.');
};
if (contextIsolationEnabled) internalContextBridge.overrideGlobalValueFromIsolatedWorld(['prompt'], window.prompt);
if (!usesNativeWindowOpen || openerId != null) {
ipcRendererInternal.on('ELECTRON_GUEST_WINDOW_POSTMESSAGE', function (
@@ -233,21 +300,24 @@ export const windowSetup = (
window.history.back = function () {
ipcRendererInternal.send('ELECTRON_NAVIGATION_CONTROLLER_GO_BACK');
};
if (contextIsolationEnabled) internalContextBridge.overrideGlobalValueFromIsolatedWorld(['history', 'back'], window.history.back);
window.history.forward = function () {
ipcRendererInternal.send('ELECTRON_NAVIGATION_CONTROLLER_GO_FORWARD');
};
if (contextIsolationEnabled) internalContextBridge.overrideGlobalValueFromIsolatedWorld(['history', 'forward'], window.history.forward);
window.history.go = function (offset: number) {
ipcRendererInternal.send('ELECTRON_NAVIGATION_CONTROLLER_GO_TO_OFFSET', +offset);
};
if (contextIsolationEnabled) internalContextBridge.overrideGlobalValueFromIsolatedWorld(['history', 'go'], window.history.go);
const getHistoryLength = () => ipcRendererInternal.sendSync('ELECTRON_NAVIGATION_CONTROLLER_LENGTH');
Object.defineProperty(window.history, 'length', {
get: function () {
return ipcRendererInternal.sendSync('ELECTRON_NAVIGATION_CONTROLLER_LENGTH');
},
get: getHistoryLength,
set () {}
});
if (contextIsolationEnabled) internalContextBridge.overrideGlobalPropertyFromIsolatedWorld(['history', 'length'], getHistoryLength);
}
if (guestInstanceId != null) {
@@ -269,16 +339,16 @@ export const windowSetup = (
});
// Make document.hidden and document.visibilityState return the correct value.
const getDocumentHidden = () => cachedVisibilityState !== 'visible';
Object.defineProperty(document, 'hidden', {
get: function () {
return cachedVisibilityState !== 'visible';
}
get: getDocumentHidden
});
if (contextIsolationEnabled) internalContextBridge.overrideGlobalPropertyFromIsolatedWorld(['document', 'hidden'], getDocumentHidden);
const getDocumentVisibilityState = () => cachedVisibilityState;
Object.defineProperty(document, 'visibilityState', {
get: function () {
return cachedVisibilityState;
}
get: getDocumentVisibilityState
});
if (contextIsolationEnabled) internalContextBridge.overrideGlobalPropertyFromIsolatedWorld(['document', 'visibilityState'], getDocumentVisibilityState);
}
};

View File

@@ -1,6 +1,6 @@
{
"name": "electron",
"version": "9.0.0-beta.19",
"version": "9.0.0-beta.24",
"repository": "https://github.com/electron/electron",
"description": "Build cross platform desktop apps with JavaScript, HTML, and CSS",
"devDependencies": {
@@ -9,6 +9,7 @@
"@octokit/rest": "^16.3.2",
"@primer/octicons": "^9.1.1",
"@types/basic-auth": "^1.1.2",
"@types/busboy": "^0.2.3",
"@types/chai": "^4.1.7",
"@types/chai-as-promised": "^7.1.0",
"@types/dirty-chai": "^2.0.0",
@@ -16,6 +17,7 @@
"@types/fs-extra": "^5.0.5",
"@types/mocha": "^5.2.6",
"@types/node": "^12.0.10",
"@types/rimraf": "^3.0.0",
"@types/semver": "^6.0.1",
"@types/send": "^0.14.5",
"@types/split": "^1.0.0",
@@ -139,7 +141,6 @@
]
},
"dependencies": {
"@types/multiparty": "^0.0.32",
"@types/temp": "^0.8.34"
}
}

View File

@@ -92,3 +92,9 @@ fix_account_for_print_preview_disabled_when_printing_to_pdf.patch
web_contents.patch
ui_gtk_public_header.patch
layoutng_make_hittestresult_localpoint_for_inline_element.patch
fix-ensure-edit-cmds-to-sent-focused-WebContents.patch
crash_allow_setting_more_options.patch
breakpad_disable_upload_compression.patch
breakpad_treat_node_processes_as_browser_processes.patch
upload_list_add_loadsync_method.patch
breakpad_allow_getting_string_values_for_crash_keys.patch

View File

@@ -0,0 +1,29 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Jeremy Apthorp <nornagon@nornagon.net>
Date: Tue, 5 May 2020 12:36:39 -0700
Subject: breakpad: allow getting string values for crash keys
Linux is currently recording both crashpad and breakpad keys on linux
(because upstream is experimenting with crashpad-on-linux). We can fetch
the string values for crashpad keys on win/mac, and they're easily
available on linux too, this just exposes them.
Should be upstreamed, or failing that, deleted once crashpad is enabled
on linux. If removing this patch doesn't cause a compile failure, it's
fine to delete!
diff --git a/components/crash/core/common/crash_key.h b/components/crash/core/common/crash_key.h
index 9d193ea962e919d4509eef296c900e47059761f4..225b8ce822a42d31d59bc89aab473710384c3010 100644
--- a/components/crash/core/common/crash_key.h
+++ b/components/crash/core/common/crash_key.h
@@ -212,6 +212,10 @@ class CrashKeyStringCombined : public internal::CrashKeyStringCombinedImpl {
crashpad_key_.Set(value);
}
+ const base::StringPiece value() const {
+ return crashpad_key_.value();
+ }
+
private:
CrashKeyStringBreakpad<MaxLength> breakpad_key_;
crashpad::StringAnnotation<MaxLength> crashpad_key_;

View File

@@ -0,0 +1,49 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Jeremy Apthorp <nornagon@nornagon.net>
Date: Wed, 29 Apr 2020 16:28:35 -0700
Subject: breakpad: disable upload compression
Our prior implementation of breakpad uploading did not compress files on
upload. In order to maintain that behavior, this disables compression in
//components/crash.
Ideally, this would be made configurable.
diff --git a/components/crash/core/app/breakpad_linux.cc b/components/crash/core/app/breakpad_linux.cc
index 364af690879d79d25d118d5b2fdbaabe21a1c52d..390cca9edc26d3153c8dbc86024cb50097d7ac78 100644
--- a/components/crash/core/app/breakpad_linux.cc
+++ b/components/crash/core/app/breakpad_linux.cc
@@ -1334,6 +1334,7 @@ void ExecUploadProcessOrTerminate(const BreakpadInfo& info,
#else // defined(OS_CHROMEOS)
+ /*
// Compress |dumpfile| with gzip.
const pid_t gzip_child = sys_fork();
if (gzip_child < 0) {
@@ -1377,13 +1378,16 @@ void ExecUploadProcessOrTerminate(const BreakpadInfo& info,
WriteLog(msg, sizeof(msg) - 1);
sys__exit(1);
}
+ */
// The --header argument to wget looks like:
// --header=Content-Encoding: gzip
// --header=Content-Type: multipart/form-data; boundary=XYZ
// where the boundary has two fewer leading '-' chars
+ /*
static const char header_content_encoding[] =
"--header=Content-Encoding: gzip";
+ */
static const char header_msg[] =
"--header=Content-Type: multipart/form-data; boundary=";
const size_t header_content_type_size =
@@ -1412,7 +1416,7 @@ void ExecUploadProcessOrTerminate(const BreakpadInfo& info,
static const char kWgetBinary[] = "/usr/bin/wget";
const char* args[] = {
kWgetBinary,
- header_content_encoding,
+ //header_content_encoding,
header_content_type,
post_file,
upload_url,

View File

@@ -0,0 +1,45 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Jeremy Apthorp <nornagon@nornagon.net>
Date: Thu, 30 Apr 2020 17:04:13 -0700
Subject: breakpad: treat node processes as browser processes
On Linux, to avoid the need to pass breakpad FDs to child node processes
spawned by child_process.fork(), each child process must re-initialize
breakpad independently, as a "browser" process. This patches
//components/crash so that it will correctly report 'ptype=node' as a
crash annotation.
diff --git a/components/crash/core/app/breakpad_linux.cc b/components/crash/core/app/breakpad_linux.cc
index 390cca9edc26d3153c8dbc86024cb50097d7ac78..2ae2429e6054f2d54e785c49a49fc243469bb72b 100644
--- a/components/crash/core/app/breakpad_linux.cc
+++ b/components/crash/core/app/breakpad_linux.cc
@@ -722,8 +722,13 @@ bool CrashDone(const MinidumpDescriptor& minidump,
log_path[log_path_len] = '\0';
info.log_filename = log_path;
#endif
- info.process_type = "browser";
- info.process_type_length = 7;
+ if (g_is_node) {
+ info.process_type = "node";
+ info.process_type_length = 4;
+ } else {
+ info.process_type = "browser";
+ info.process_type_length = 7;
+ }
info.distro = base::g_linux_distro;
info.distro_length = my_strlen(base::g_linux_distro);
info.upload = upload;
@@ -2050,8 +2055,13 @@ void InitCrashReporter(const std::string& process_type) {
process_type == kWebViewSingleProcessType ||
process_type == kBrowserProcessType ||
#endif
+ process_type == "node" ||
process_type.empty();
+ if (process_type == "node") {
+ g_is_node = true;
+ }
+
std::string upload_url;
if (GetCrashReporterClient()->GetUploadUrl(&upload_url))
SetUploadURL(upload_url);

View File

@@ -7,7 +7,7 @@ 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 023024e81c99d09efc0d1530a6c9ae3f1acf3abe..9cff221f4927bec68eb93353cfcc4c9af153ac8e 100644
index b3f8ac152722daf79878d83f14d2ee0bf625004c..e70d15134e8ffe75311da48dfa222f4d3d85bf2d 100644
--- a/chrome/browser/BUILD.gn
+++ b/chrome/browser/BUILD.gn
@@ -5331,6 +5331,7 @@ jumbo_static_library("browser") {

View File

@@ -0,0 +1,201 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Jeremy Apthorp <jeremya@chromium.org>
Date: Thu, 30 Apr 2020 10:08:06 -0700
Subject: crash: allow setting more options
This allows the client of //components/crash to set upload url,
rate-limiting, compression and global annotations.
This should be upstreamed.
diff --git a/components/crash/core/app/breakpad_linux.cc b/components/crash/core/app/breakpad_linux.cc
index 192b0a7f137f311abb6a991f997e11f5eba52256..364af690879d79d25d118d5b2fdbaabe21a1c52d 100644
--- a/components/crash/core/app/breakpad_linux.cc
+++ b/components/crash/core/app/breakpad_linux.cc
@@ -103,9 +103,18 @@ namespace {
// while we do have functions to deal with uint64_t's.
uint64_t g_crash_loop_before_time = 0;
#else
-const char kUploadURL[] = "https://clients2.google.com/cr/report";
+const char kDefaultUploadURL[] = "https://clients2.google.com/cr/report";
+char* g_upload_url = nullptr;
#endif
+void SetUploadURL(const std::string& url) {
+ const size_t url_len = url.size() + 1;
+ DCHECK(!g_upload_url);
+ g_upload_url = new char[url_len];
+ strncpy(g_upload_url, url.c_str(), url_len);
+}
+
+bool g_is_node = false;
bool g_is_crash_reporter_enabled = false;
uint64_t g_process_start_time = 0;
pid_t g_pid = 0;
@@ -1398,13 +1407,15 @@ void ExecUploadProcessOrTerminate(const BreakpadInfo& info,
char* status_fd_path =
StringFromPrefixAndUint("/dev/fd/", upload_status_fd, allocator);
+ const char* upload_url = g_upload_url ? g_upload_url : kDefaultUploadURL;
+
static const char kWgetBinary[] = "/usr/bin/wget";
const char* args[] = {
kWgetBinary,
header_content_encoding,
header_content_type,
post_file,
- kUploadURL,
+ upload_url,
"--timeout=10", // Set a timeout so we don't hang forever.
"--tries=1", // Don't retry if the upload fails.
"-O", // Output reply to the file descriptor path.
@@ -2037,6 +2048,10 @@ void InitCrashReporter(const std::string& process_type) {
#endif
process_type.empty();
+ std::string upload_url;
+ if (GetCrashReporterClient()->GetUploadUrl(&upload_url))
+ SetUploadURL(upload_url);
+
if (is_browser_process) {
bool enable_breakpad = GetCrashReporterClient()->GetCollectStatsConsent() ||
GetCrashReporterClient()->IsRunningUnattended();
diff --git a/components/crash/core/app/crash_reporter_client.cc b/components/crash/core/app/crash_reporter_client.cc
index e778f68af30f8c071d1360d06b553cc957160c5b..b7f6ca60ef9c2367989d39e1268bf9f9a517951c 100644
--- a/components/crash/core/app/crash_reporter_client.cc
+++ b/components/crash/core/app/crash_reporter_client.cc
@@ -148,6 +148,17 @@ bool CrashReporterClient::ReportingIsEnforcedByPolicy(bool* breakpad_enabled) {
return false;
}
+bool CrashReporterClient::GetShouldRateLimit() {
+ return true;
+}
+
+bool CrashReporterClient::GetShouldCompressUploads() {
+ return true;
+}
+
+void CrashReporterClient::GetProcessSimpleAnnotations(std::map<std::string, std::string>* annotations) {
+}
+
#if defined(OS_ANDROID)
unsigned int CrashReporterClient::GetCrashDumpPercentage() {
return 100;
@@ -196,6 +207,10 @@ void CrashReporterClient::GetSanitizationInformation(
}
#endif
+bool CrashReporterClient::GetUploadUrl(std::string* url) {
+ return false;
+}
+
bool CrashReporterClient::ShouldMonitorCrashHandlerExpensively() {
return false;
}
diff --git a/components/crash/core/app/crash_reporter_client.h b/components/crash/core/app/crash_reporter_client.h
index 9cc78fc2584061d26fd1e83b3ebf5ada0a12c138..aa63d7b95c37e4a143283450798b8bd500dc17a1 100644
--- a/components/crash/core/app/crash_reporter_client.h
+++ b/components/crash/core/app/crash_reporter_client.h
@@ -5,6 +5,7 @@
#ifndef COMPONENTS_CRASH_CORE_APP_CRASH_REPORTER_CLIENT_H_
#define COMPONENTS_CRASH_CORE_APP_CRASH_REPORTER_CLIENT_H_
+#include <map>
#include <string>
#include "base/strings/string16.h"
@@ -153,6 +154,19 @@ class CrashReporterClient {
// that case, |breakpad_enabled| is set to the value enforced by policies.
virtual bool ReportingIsEnforcedByPolicy(bool* breakpad_enabled);
+ // Returns true if crash uploads should be rate limited. If false, no
+ // throttling will be applied for uploads.
+ virtual bool GetShouldRateLimit();
+
+ // Returns true if crash uploads should be compressed with gzip. If false,
+ // reports will be uploaded uncompressed.
+ virtual bool GetShouldCompressUploads();
+
+ // Allows the client to add or edit global annotations passed to the crashpad
+ // handler.
+ virtual void GetProcessSimpleAnnotations(
+ std::map<std::string, std::string>* annotations);
+
#if defined(OS_ANDROID)
// Used by WebView to sample crashes without generating the unwanted dumps. If
// the returned value is less than 100, crash dumping will be sampled to that
@@ -194,6 +208,9 @@ class CrashReporterClient {
bool* sanitize_stacks);
#endif
+ // Override the default upload url. Returns true if overridden.
+ virtual bool GetUploadUrl(std::string* url);
+
// This method should return true to configure a crash reporter capable of
// monitoring itself for its own crashes to do so, even if self-monitoring
// would be expensive. "Expensive" self-monitoring dedicates an additional
diff --git a/components/crash/core/app/crashpad_mac.mm b/components/crash/core/app/crashpad_mac.mm
index b579521d55860823722df2ee849f6b1628b3c950..f4f71e5174cf8fb706a2f8385252ba877d1a03a7 100644
--- a/components/crash/core/app/crashpad_mac.mm
+++ b/components/crash/core/app/crashpad_mac.mm
@@ -67,6 +67,8 @@ std::map<std::string, std::string> GetProcessSimpleAnnotations() {
} // @autoreleasepool
return process_annotations;
}();
+ CrashReporterClient* crash_reporter_client = GetCrashReporterClient();
+ crash_reporter_client->GetProcessSimpleAnnotations(&annotations);
return annotations;
}
@@ -140,9 +142,17 @@ base::FilePath PlatformCrashpadInitialization(
#else
std::string url;
#endif
+ crash_reporter_client->GetUploadUrl(&url);
std::vector<std::string> arguments;
+ if (!crash_reporter_client->GetShouldRateLimit()) {
+ arguments.push_back("--no-rate-limit");
+ }
+ if (!crash_reporter_client->GetShouldCompressUploads()) {
+ arguments.push_back("--no-upload-gzip");
+ }
+
if (crash_reporter_client->ShouldMonitorCrashHandlerExpensively()) {
arguments.push_back("--monitor-self");
}
diff --git a/components/crash/core/app/crashpad_win.cc b/components/crash/core/app/crashpad_win.cc
index 669f5bea844d75f0e5c34b58994f4cfb8e856af0..8c1fb8fb8f2e02466b51ef08de25b056f8b2052d 100644
--- a/components/crash/core/app/crashpad_win.cc
+++ b/components/crash/core/app/crashpad_win.cc
@@ -84,12 +84,14 @@ base::FilePath PlatformCrashpadInitialization(
std::map<std::string, std::string> process_annotations;
GetPlatformCrashpadAnnotations(&process_annotations);
+ crash_reporter_client->GetProcessSimpleAnnotations(&process_annotations);
#if BUILDFLAG(GOOGLE_CHROME_BRANDING)
std::string url = "https://clients2.google.com/cr/report";
#else
std::string url;
#endif
+ crash_reporter_client->GetUploadUrl(&url);
// Allow the crash server to be overridden for testing. If the variable
// isn't present in the environment then the default URL will remain.
@@ -126,6 +128,13 @@ base::FilePath PlatformCrashpadInitialization(
std::vector<std::string> arguments(start_arguments);
+ if (!crash_reporter_client->GetShouldRateLimit()) {
+ arguments.push_back("--no-rate-limit");
+ }
+ if (!crash_reporter_client->GetShouldCompressUploads()) {
+ arguments.push_back("--no-upload-gzip");
+ }
+
if (crash_reporter_client->ShouldMonitorCrashHandlerExpensively()) {
arguments.push_back("--monitor-self");
for (const std::string& start_argument : start_arguments) {

View File

@@ -66,7 +66,7 @@ index cb69e08c0185f55497089505ed5b226e57140321..362f28accc248248f3bcb54955c23528
!command_line->HasSwitch(switches::kUIDisablePartialSwap);
#if defined(OS_MACOSX)
diff --git a/components/viz/service/display/gl_renderer.cc b/components/viz/service/display/gl_renderer.cc
index ceb0c4ecbe0401c0190ba683bac479392726207b..a4b41b16a2850b899fa815bd49ac6625adb68e93 100644
index 5062680dac94c24aa4c6ad3f8508b5a2a25dad54..31700af38ea7d309dfe85fde69d0eb0566346ba1 100644
--- a/components/viz/service/display/gl_renderer.cc
+++ b/components/viz/service/display/gl_renderer.cc
@@ -84,6 +84,9 @@
@@ -79,7 +79,7 @@ index ceb0c4ecbe0401c0190ba683bac479392726207b..a4b41b16a2850b899fa815bd49ac6625
namespace viz {
namespace {
@@ -588,8 +591,9 @@ void GLRenderer::DoDrawQuad(const DrawQuad* quad,
@@ -581,8 +584,9 @@ void GLRenderer::DoDrawQuad(const DrawQuad* quad,
void GLRenderer::DrawDebugBorderQuad(const DebugBorderDrawQuad* quad) {
SetBlendEnabled(quad->ShouldDrawWithBlending());
@@ -91,7 +91,7 @@ index ceb0c4ecbe0401c0190ba683bac479392726207b..a4b41b16a2850b899fa815bd49ac6625
// Use the full quad_rect for debug quads to not move the edges based on
// partial swaps.
@@ -1547,7 +1551,8 @@ void GLRenderer::ChooseRPDQProgram(DrawRenderPassDrawQuadParams* params,
@@ -1540,7 +1544,8 @@ void GLRenderer::ChooseRPDQProgram(DrawRenderPassDrawQuadParams* params,
params->use_color_matrix, tint_gl_composited_content_,
params->apply_shader_based_rounded_corner &&
ShouldApplyRoundedCorner(params->quad)),
@@ -101,7 +101,7 @@ index ceb0c4ecbe0401c0190ba683bac479392726207b..a4b41b16a2850b899fa815bd49ac6625
}
void GLRenderer::UpdateRPDQUniforms(DrawRenderPassDrawQuadParams* params) {
@@ -2018,7 +2023,8 @@ void GLRenderer::DrawSolidColorQuad(const SolidColorDrawQuad* quad,
@@ -2011,7 +2016,8 @@ void GLRenderer::DrawSolidColorQuad(const SolidColorDrawQuad* quad,
SetUseProgram(ProgramKey::SolidColor(use_aa ? USE_AA : NO_AA,
tint_gl_composited_content_,
ShouldApplyRoundedCorner(quad)),
@@ -111,7 +111,7 @@ index ceb0c4ecbe0401c0190ba683bac479392726207b..a4b41b16a2850b899fa815bd49ac6625
SetShaderColor(color, opacity);
if (current_program_->rounded_corner_rect_location() != -1) {
SetShaderRoundedCorner(
@@ -2173,7 +2179,8 @@ void GLRenderer::DrawContentQuadAA(const ContentDrawQuadBase* quad,
@@ -2166,7 +2172,8 @@ void GLRenderer::DrawContentQuadAA(const ContentDrawQuadBase* quad,
: NON_PREMULTIPLIED_ALPHA,
false, false, tint_gl_composited_content_,
ShouldApplyRoundedCorner(quad)),
@@ -121,7 +121,7 @@ index ceb0c4ecbe0401c0190ba683bac479392726207b..a4b41b16a2850b899fa815bd49ac6625
if (current_program_->tint_color_matrix_location() != -1) {
auto matrix = cc::DebugColors::TintCompositedContentColorTransformMatrix();
@@ -2269,7 +2276,8 @@ void GLRenderer::DrawContentQuadNoAA(const ContentDrawQuadBase* quad,
@@ -2262,7 +2269,8 @@ void GLRenderer::DrawContentQuadNoAA(const ContentDrawQuadBase* quad,
!quad->ShouldDrawWithBlending(), has_tex_clamp_rect,
tint_gl_composited_content_,
ShouldApplyRoundedCorner(quad)),
@@ -131,7 +131,7 @@ index ceb0c4ecbe0401c0190ba683bac479392726207b..a4b41b16a2850b899fa815bd49ac6625
if (current_program_->tint_color_matrix_location() != -1) {
auto matrix = cc::DebugColors::TintCompositedContentColorTransformMatrix();
@@ -2371,7 +2379,7 @@ void GLRenderer::DrawYUVVideoQuad(const YUVVideoDrawQuad* quad,
@@ -2364,7 +2372,7 @@ void GLRenderer::DrawYUVVideoQuad(const YUVVideoDrawQuad* quad,
// The source color space should never be RGB.
DCHECK_NE(src_color_space, src_color_space.GetAsFullRangeRGB());
@@ -140,7 +140,7 @@ index ceb0c4ecbe0401c0190ba683bac479392726207b..a4b41b16a2850b899fa815bd49ac6625
#if defined(OS_WIN)
// Force sRGB output on Windows for overlay candidate video quads to match
@@ -2535,7 +2543,8 @@ void GLRenderer::DrawStreamVideoQuad(const StreamVideoDrawQuad* quad,
@@ -2528,7 +2536,8 @@ void GLRenderer::DrawStreamVideoQuad(const StreamVideoDrawQuad* quad,
SetUseProgram(ProgramKey::VideoStream(tex_coord_precision,
ShouldApplyRoundedCorner(quad)),
@@ -150,7 +150,7 @@ index ceb0c4ecbe0401c0190ba683bac479392726207b..a4b41b16a2850b899fa815bd49ac6625
DCHECK_EQ(GL_TEXTURE0, GetActiveTextureUnit(gl_));
gl_->BindTexture(GL_TEXTURE_EXTERNAL_OES, lock.texture_id());
@@ -2600,8 +2609,8 @@ void GLRenderer::FlushTextureQuadCache(BoundGeometry flush_binding) {
@@ -2593,8 +2602,8 @@ void GLRenderer::FlushTextureQuadCache(BoundGeometry flush_binding) {
draw_cache_.nearest_neighbor ? GL_NEAREST : GL_LINEAR);
// Bind the program to the GL state.
@@ -161,7 +161,7 @@ index ceb0c4ecbe0401c0190ba683bac479392726207b..a4b41b16a2850b899fa815bd49ac6625
if (current_program_->rounded_corner_rect_location() != -1) {
SetShaderRoundedCorner(
@@ -3340,7 +3349,9 @@ void GLRenderer::PrepareGeometry(BoundGeometry binding) {
@@ -3333,7 +3342,9 @@ void GLRenderer::PrepareGeometry(BoundGeometry binding) {
void GLRenderer::SetUseProgram(const ProgramKey& program_key_no_color,
const gfx::ColorSpace& src_color_space,
const gfx::ColorSpace& dst_color_space) {
@@ -172,7 +172,7 @@ index ceb0c4ecbe0401c0190ba683bac479392726207b..a4b41b16a2850b899fa815bd49ac6625
// If the input color space is PQ, and it did not specify a white level,
// override it with the frame's white level.
@@ -3722,9 +3733,9 @@ void GLRenderer::CopyRenderPassDrawQuadToOverlayResource(
@@ -3715,9 +3726,9 @@ void GLRenderer::CopyRenderPassDrawQuadToOverlayResource(
cc::MathUtil::CheckedRoundUp(iosurface_height, iosurface_multiple);
}
@@ -185,7 +185,7 @@ index ceb0c4ecbe0401c0190ba683bac479392726207b..a4b41b16a2850b899fa815bd49ac6625
*new_bounds = gfx::RectF(updated_dst_rect.origin(),
gfx::SizeF((*overlay_texture)->texture.size()));
@@ -3943,8 +3954,8 @@ void GLRenderer::FlushOverdrawFeedback(const gfx::Rect& output_rect) {
@@ -3936,8 +3947,8 @@ void GLRenderer::FlushOverdrawFeedback(const gfx::Rect& output_rect) {
PrepareGeometry(SHARED_BINDING);
@@ -196,7 +196,7 @@ index ceb0c4ecbe0401c0190ba683bac479392726207b..a4b41b16a2850b899fa815bd49ac6625
gfx::Transform render_matrix;
render_matrix.Translate(0.5 * output_rect.width() + output_rect.x(),
@@ -4053,3 +4064,5 @@ gfx::Size GLRenderer::GetRenderPassBackingPixelSize(
@@ -4046,3 +4057,5 @@ gfx::Size GLRenderer::GetRenderPassBackingPixelSize(
}
} // namespace viz

View File

@@ -0,0 +1,216 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Shelley Vohr <shelley.vohr@gmail.com>
Date: Thu, 30 Apr 2020 13:39:46 -0500
Subject: fix: ensure edit cmds to sent focused WebContents
Fixes an issue whereby some edit commands were not being
sent to the focused WebContents. This fixes the issue by
adding the malfunctioning commands to RenderFrameHostDelegate
and then calling them that way.
diff --git a/content/browser/frame_host/interstitial_page_impl.cc b/content/browser/frame_host/interstitial_page_impl.cc
index 72f9b6d582345736d1b0b05f52925e8e036cf131..7fecac21ea36670a20bc2b317cfe11eb5e0b2524 100644
--- a/content/browser/frame_host/interstitial_page_impl.cc
+++ b/content/browser/frame_host/interstitial_page_impl.cc
@@ -451,6 +451,22 @@ void InterstitialPageImpl::ExecuteEditCommand(
input_handler->ExecuteEditCommand(command, value);
}
+void InterstitialPageImpl::Undo() {
+ auto* input_handler = GetFocusedFrameInputHandler();
+ if (!input_handler)
+ return;
+ input_handler->Undo();
+ RecordAction(base::UserMetricsAction("Undo"));
+}
+
+void InterstitialPageImpl::Redo() {
+ auto* input_handler = GetFocusedFrameInputHandler();
+ if (!input_handler)
+ return;
+ input_handler->Redo();
+ RecordAction(base::UserMetricsAction("Redo"));
+}
+
void InterstitialPageImpl::Copy() {
auto* input_handler = GetFocusedFrameInputHandler();
if (!input_handler)
@@ -467,6 +483,14 @@ void InterstitialPageImpl::Paste() {
RecordAction(base::UserMetricsAction("Paste"));
}
+void InterstitialPageImpl::PasteAndMatchStyle() {
+ auto* input_handler = GetFocusedFrameInputHandler();
+ if (!input_handler)
+ return;
+ input_handler->PasteAndMatchStyle();
+ RecordAction(base::UserMetricsAction("PasteAndMatchStyle"));
+}
+
void InterstitialPageImpl::SelectAll() {
auto* input_handler = GetFocusedFrameInputHandler();
if (!input_handler)
diff --git a/content/browser/frame_host/interstitial_page_impl.h b/content/browser/frame_host/interstitial_page_impl.h
index e645cd75128085e15c1213df206847dd02fb5a83..095ae4dffb1f576a8ceefd2a4ab9f8f93473e460 100644
--- a/content/browser/frame_host/interstitial_page_impl.h
+++ b/content/browser/frame_host/interstitial_page_impl.h
@@ -119,9 +119,12 @@ class CONTENT_EXPORT InterstitialPageImpl : public InterstitialPage,
ui::AXMode GetAccessibilityMode() override;
void ExecuteEditCommand(const std::string& command,
const base::Optional<base::string16>& value) override;
+ void Undo() override;
+ void Redo() override;
void Cut() override;
void Copy() override;
void Paste() override;
+ void PasteAndMatchStyle() override;
void SelectAll() override;
RenderFrameHostDelegate* CreateNewWindow(
RenderFrameHost* opener,
diff --git a/content/browser/renderer_host/render_widget_host_delegate.h b/content/browser/renderer_host/render_widget_host_delegate.h
index 234baaefaa36a2a64f7c365462c44807b0a1eabb..ef04420a733ef3d2bdc7d50af1d149db337494a4 100644
--- a/content/browser/renderer_host/render_widget_host_delegate.h
+++ b/content/browser/renderer_host/render_widget_host_delegate.h
@@ -148,9 +148,12 @@ class CONTENT_EXPORT RenderWidgetHostDelegate {
virtual void ExecuteEditCommand(
const std::string& command,
const base::Optional<base::string16>& value) = 0;
+ virtual void Undo() = 0;
+ virtual void Redo() = 0;
virtual void Cut() = 0;
virtual void Copy() = 0;
virtual void Paste() = 0;
+ virtual void PasteAndMatchStyle() = 0;
virtual void SelectAll() = 0;
// Requests the renderer to move the selection extent to a new position.
diff --git a/content/browser/renderer_host/render_widget_host_unittest.cc b/content/browser/renderer_host/render_widget_host_unittest.cc
index 5697455918f9aa2f4225eba1a5566950e34ec410..f5a7fdaa218742249cde04c73bcab43de0d83eed 100644
--- a/content/browser/renderer_host/render_widget_host_unittest.cc
+++ b/content/browser/renderer_host/render_widget_host_unittest.cc
@@ -426,9 +426,12 @@ class MockRenderWidgetHostDelegate : public RenderWidgetHostDelegate {
const std::string& command,
const base::Optional<base::string16>& value) override {}
+ void Undo() override {}
+ void Redo() override {}
void Cut() override {}
void Copy() override {}
void Paste() override {}
+ void PasteAndMatchStyle() override {}
void SelectAll() override {}
private:
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 472869202ff8a62d854c9ca39ca9f14e2f91e8cf..17e3fe40522e088057eaf01a290b658a0b6d1d01 100644
--- a/content/browser/renderer_host/render_widget_host_view_mac.mm
+++ b/content/browser/renderer_host/render_widget_host_view_mac.mm
@@ -1799,15 +1799,15 @@ void RenderWidgetHostViewMac::ExecuteEditCommand(const std::string& command) {
}
void RenderWidgetHostViewMac::Undo() {
- WebContents* web_contents = GetWebContents();
- if (web_contents)
- web_contents->Undo();
+ if (auto* delegate = GetFocusedRenderWidgetHostDelegate()) {
+ delegate->Undo();
+ }
}
void RenderWidgetHostViewMac::Redo() {
- WebContents* web_contents = GetWebContents();
- if (web_contents)
- web_contents->Redo();
+ if (auto* delegate = GetFocusedRenderWidgetHostDelegate()) {
+ delegate->Redo();
+ }
}
void RenderWidgetHostViewMac::Cut() {
@@ -1835,9 +1835,9 @@ void RenderWidgetHostViewMac::Paste() {
}
void RenderWidgetHostViewMac::PasteAndMatchStyle() {
- WebContents* web_contents = GetWebContents();
- if (web_contents)
- web_contents->PasteAndMatchStyle();
+ if (auto* delegate = GetFocusedRenderWidgetHostDelegate()) {
+ delegate->PasteAndMatchStyle();
+ }
}
void RenderWidgetHostViewMac::SelectAll() {
diff --git a/content/browser/renderer_host/render_widget_host_view_mac_editcommand_helper_unittest.mm b/content/browser/renderer_host/render_widget_host_view_mac_editcommand_helper_unittest.mm
index 760e47e9edd7b92b7bc6074f6da9c76048be8f28..2b0f1135e584852048081629eb6297e4e1fcc574 100644
--- a/content/browser/renderer_host/render_widget_host_view_mac_editcommand_helper_unittest.mm
+++ b/content/browser/renderer_host/render_widget_host_view_mac_editcommand_helper_unittest.mm
@@ -91,9 +91,12 @@ class RenderWidgetHostDelegateEditCommandCounter
const base::Optional<base::string16>& value) override {
edit_command_message_count_++;
}
+ void Undo() override {}
+ void Redo() override {}
void Cut() override {}
void Copy() override {}
void Paste() override {}
+ void PasteAndMatchStyle() override {}
void SelectAll() override {}
};
diff --git a/content/browser/renderer_host/text_input_client_mac_unittest.mm b/content/browser/renderer_host/text_input_client_mac_unittest.mm
index 158e0507af7433e16c47227e7519b12e14554f1b..e7b8109cdc78e76d737bd0c067f8d33e0c171117 100644
--- a/content/browser/renderer_host/text_input_client_mac_unittest.mm
+++ b/content/browser/renderer_host/text_input_client_mac_unittest.mm
@@ -40,9 +40,12 @@ class MockRenderWidgetHostDelegate : public RenderWidgetHostDelegate {
void ExecuteEditCommand(
const std::string& command,
const base::Optional<base::string16>& value) override {}
+ void Undo() override {}
+ void Redo() override {}
void Cut() override {}
void Copy() override {}
void Paste() override {}
+ void PasteAndMatchStyle() override {}
void SelectAll() override {}
};
diff --git a/content/test/mock_render_widget_host_delegate.cc b/content/test/mock_render_widget_host_delegate.cc
index 8e7922a2e83b1272e93fbd7c8c5323ad7ed9c3a7..4aa08a55c036569e39d4d02254b347d8470462af 100644
--- a/content/test/mock_render_widget_host_delegate.cc
+++ b/content/test/mock_render_widget_host_delegate.cc
@@ -31,12 +31,18 @@ void MockRenderWidgetHostDelegate::ExecuteEditCommand(
const std::string& command,
const base::Optional<base::string16>& value) {}
+void MockRenderWidgetHostDelegate::Undo() {}
+
+void MockRenderWidgetHostDelegate::Redo() {}
+
void MockRenderWidgetHostDelegate::Cut() {}
void MockRenderWidgetHostDelegate::Copy() {}
void MockRenderWidgetHostDelegate::Paste() {}
+void MockRenderWidgetHostDelegate::PasteAndMatchStyle() {}
+
void MockRenderWidgetHostDelegate::SelectAll() {}
void MockRenderWidgetHostDelegate::CreateInputEventRouter() {
diff --git a/content/test/mock_render_widget_host_delegate.h b/content/test/mock_render_widget_host_delegate.h
index 5cdc010273f0bd03419c14046ee6cb8603a29dbf..16273c2ec761668249277a0be77aa429bcba1aef 100644
--- a/content/test/mock_render_widget_host_delegate.h
+++ b/content/test/mock_render_widget_host_delegate.h
@@ -42,9 +42,12 @@ class MockRenderWidgetHostDelegate : public RenderWidgetHostDelegate {
const NativeWebKeyboardEvent& event) override;
void ExecuteEditCommand(const std::string& command,
const base::Optional<base::string16>& value) override;
+ void Undo() override;
+ void Redo() override;
void Cut() override;
void Copy() override;
void Paste() override;
+ void PasteAndMatchStyle() override;
void SelectAll() override;
RenderWidgetHostInputEventRouter* GetInputEventRouter() override;
RenderWidgetHostImpl* GetFocusedRenderWidgetHost(

View File

@@ -71,10 +71,10 @@ index f0b9f9634264e9073f22560903307332986df2fe..934fa63595053156b446dbc5fdccb196
render_frame_host_ =
frame_tree_node_->render_manager()->GetFrameHostForNavigation(this);
diff --git a/content/browser/frame_host/render_frame_host_manager.cc b/content/browser/frame_host/render_frame_host_manager.cc
index f76a633c85c8e53d99c1280d359b6ddcf6bcfbbc..676f70c59f75d47c94902eba3776949b749f267f 100644
index 4c370c23a2217b45d7f023708305b3d1b115790a..9a3a207eab69464f35ffd39b75417311a9102cc2 100644
--- a/content/browser/frame_host/render_frame_host_manager.cc
+++ b/content/browser/frame_host/render_frame_host_manager.cc
@@ -2392,6 +2392,16 @@ bool RenderFrameHostManager::InitRenderView(
@@ -2391,6 +2391,16 @@ bool RenderFrameHostManager::InitRenderView(
scoped_refptr<SiteInstance>
RenderFrameHostManager::GetSiteInstanceForNavigationRequest(
NavigationRequest* request) {
@@ -91,7 +91,7 @@ index f76a633c85c8e53d99c1280d359b6ddcf6bcfbbc..676f70c59f75d47c94902eba3776949b
SiteInstance* current_site_instance = render_frame_host_->GetSiteInstance();
// All children of MHTML documents must be MHTML documents. They all live in
@@ -2411,10 +2421,60 @@ RenderFrameHostManager::GetSiteInstanceForNavigationRequest(
@@ -2410,10 +2420,60 @@ RenderFrameHostManager::GetSiteInstanceForNavigationRequest(
//
// TODO(clamy): We should also consider as a candidate SiteInstance the
// speculative SiteInstance that was computed on redirects.
@@ -156,7 +156,7 @@ index f76a633c85c8e53d99c1280d359b6ddcf6bcfbbc..676f70c59f75d47c94902eba3776949b
// Account for renderer-initiated reload as well.
// Needed as a workaround for https://crbug.com/1045524, remove it when it is
@@ -2456,6 +2516,8 @@ RenderFrameHostManager::GetSiteInstanceForNavigationRequest(
@@ -2455,6 +2515,8 @@ RenderFrameHostManager::GetSiteInstanceForNavigationRequest(
request->dest_site_instance() != dest_site_instance) {
request->ResetStateForSiteInstanceChange();
}

View File

@@ -0,0 +1,38 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Jeremy Apthorp <jeremya@chromium.org>
Date: Fri, 1 May 2020 18:25:59 -0700
Subject: upload_list: add LoadSync method
This allows synchronous loading of the upload list, which is required by
the crashReporter.getUploadedReports() API. The synchronous version is
deprecated, and this API should be removed once the deprecated behavior
is no longer supported.
diff --git a/components/upload_list/upload_list.cc b/components/upload_list/upload_list.cc
index ea718a40f80bc65eb9b25259d6e02c9322c54e48..9d9f9919efcefa83e6fd5b3e8447ec901cfa1388 100644
--- a/components/upload_list/upload_list.cc
+++ b/components/upload_list/upload_list.cc
@@ -70,6 +70,10 @@ void UploadList::Load(base::OnceClosure callback) {
base::BindOnce(&UploadList::OnLoadComplete, this));
}
+void UploadList::LoadSync() {
+ uploads_ = LoadUploadList();
+}
+
void UploadList::Clear(const base::Time& begin,
const base::Time& end,
base::OnceClosure callback) {
diff --git a/components/upload_list/upload_list.h b/components/upload_list/upload_list.h
index 20358339df63ae2bb8b955870c5daf51b65f19f7..7cf89626bea8ee9436f15366446f053a479ac438 100644
--- a/components/upload_list/upload_list.h
+++ b/components/upload_list/upload_list.h
@@ -73,6 +73,8 @@ class UploadList : public base::RefCountedThreadSafe<UploadList> {
// overwrite the previously supplied one, and the first will not be called.
void Load(base::OnceClosure callback);
+ void LoadSync();
+
// Clears any data associated with the upload list, where the upload time or
// capture time falls within the given range.
void Clear(const base::Time& begin,

View File

@@ -22,7 +22,6 @@ fix_do_not_define_debugoptions_s_constructors_in_header.patch
build_modify_js2c_py_to_allow_injection_of_original-fs_and_custom_embedder_js.patch
refactor_allow_embedder_overriding_of_internal_fs_calls.patch
chore_prevent_warn_non_context-aware_native_modules_being_loaded.patch
inherit_electron_crashpad_pipe_name_in_child_process.patch
chore_read_nobrowserglobals_from_global_not_process.patch
chore_split_createenvironment_into_createenvironment_and.patch
build_bring_back_node_with_ltcg_configuration.patch

View File

@@ -1,22 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Cheng Zhao <zcbenz@gmail.com>
Date: Tue, 4 Jun 2019 17:42:11 +0900
Subject: Inherit ELECTRON_CRASHPAD_PIPE_NAME in child process
This is required for crashReporter to work correctly in node process.
diff --git a/lib/child_process.js b/lib/child_process.js
index d5d97c9da90281e0c24fe97a4914db12d685c7bc..a6d058c92dff927cd2fc6bcb2bb304e9ca497a31 100644
--- a/lib/child_process.js
+++ b/lib/child_process.js
@@ -107,6 +107,10 @@ function fork(modulePath /* , args, options */) {
options.env = Object.create(options.env || process.env)
options.env.ELECTRON_RUN_AS_NODE = 1;
+ if (process.platform === 'win32') {
+ options.env.ELECTRON_CRASHPAD_PIPE_NAME = process.env.ELECTRON_CRASHPAD_PIPE_NAME;
+ }
+
if (!options.execPath && process.type && process.platform == 'darwin') {
options.execPath = process.helperExecPath;
}

View File

@@ -39,7 +39,7 @@ async function checkIfDocOnlyChange () {
return true;
}
});
if (nonDocChange) {
if (nonDocChange || filesChanged.data.length === 0) {
process.exit(1);
} else {
process.exit(0);

View File

@@ -144,8 +144,8 @@ async function getReleaseNotes (range, newVersion, explicitLinks) {
async function main () {
const opts = minimist(process.argv.slice(2), {
boolean: [ 'explicit-links', 'help' ],
string: [ 'version' ]
boolean: ['explicit-links', 'help'],
string: ['version']
});
opts.range = opts._.shift();
if (opts.help || !opts.range) {

View File

@@ -1,5 +1,7 @@
#!/usr/bin/env node
'use strict';
const childProcess = require('child_process');
const fs = require('fs');
const os = require('os');
@@ -18,14 +20,55 @@ const CHECK_INTERVAL = 5000;
const CACHE_DIR = path.resolve(__dirname, '.cache');
const NO_NOTES = 'No notes';
const FOLLOW_REPOS = [ 'electron/electron', 'electron/node' ];
const FOLLOW_REPOS = ['electron/electron', 'electron/node'];
const breakTypes = new Set(['breaking-change']);
const docTypes = new Set(['doc', 'docs']);
const featTypes = new Set(['feat', 'feature']);
const fixTypes = new Set(['fix']);
const otherTypes = new Set(['spec', 'build', 'test', 'chore', 'deps', 'refactor', 'tools', 'vendor', 'perf', 'style', 'ci']);
const knownTypes = new Set([...breakTypes.keys(), ...docTypes.keys(), ...featTypes.keys(), ...fixTypes.keys(), ...otherTypes.keys()]);
const knownTypes = new Set([...docTypes.keys(), ...featTypes.keys(), ...fixTypes.keys(), ...otherTypes.keys()]);
/**
***
**/
// link to a GitHub item, e.g. an issue or pull request
class GHKey {
constructor (owner, repo, number) {
this.owner = owner;
this.repo = repo;
this.number = number;
}
}
class Commit {
constructor (hash, owner, repo) {
this.hash = hash; // string
this.owner = owner; // string
this.repo = repo; // string
this.body = null; // string
this.isBreakingChange = false;
this.issueNumber = null; // number
this.note = null; // string
this.prKeys = new Set(); // GHKey
this.revertHash = null; // string
this.semanticType = null; // string
this.subject = null; // string
}
}
class Pool {
constructor () {
this.commits = []; // Array<Commit>
this.processedHashes = new Set();
this.pulls = {}; // GHKey.number => octokit pull object
}
}
/**
***
**/
const runGit = async (dir, args) => {
const response = await GitProcess.exec(args, dir);
@@ -39,24 +82,8 @@ const getCommonAncestor = async (dir, point1, point2) => {
return runGit(dir, ['merge-base', point1, point2]);
};
const setPullRequest = (commit, owner, repo, number) => {
if (!owner || !repo || !number) {
throw new Error(JSON.stringify({ owner, repo, number }, null, 2));
}
if (!commit.originalPr) {
commit.originalPr = commit.pr;
}
commit.pr = { owner, repo, number };
if (!commit.originalPr) {
commit.originalPr = commit.pr;
}
};
const getNoteFromClerk = async (number, owner, repo) => {
const comments = await getComments(number, owner, repo);
const getNoteFromClerk = async (ghKey) => {
const comments = await getComments(ghKey);
if (!comments || !comments.data) return;
const CLERK_LOGIN = 'release-clerk[bot]';
@@ -128,15 +155,17 @@ const getNoteFromBody = body => {
/**
* Looks for our project's conventions in the commit message:
*
* 'semantic: some description' -- sets type, subject
* 'semantic: some description' -- sets semanticType, subject
* 'some description (#99999)' -- sets subject, pr
* 'Fixes #3333' -- sets issueNumber
* 'Merge pull request #99999 from ${branchname}' -- sets pr
* 'This reverts commit ${sha}' -- sets revertHash
* line starting with 'BREAKING CHANGE' in body -- sets breakingChange
* line starting with 'BREAKING CHANGE' in body -- sets isBreakingChange
* 'Backport of #99999' -- sets pr
*/
const parseCommitMessage = (commitMessage, owner, repo, commit = {}) => {
const parseCommitMessage = (commitMessage, commit) => {
const { owner, repo } = commit;
// split commitMessage into subject & body
let subject = commitMessage;
let body = '';
@@ -146,10 +175,6 @@ const parseCommitMessage = (commitMessage, owner, repo, commit = {}) => {
subject = subject.slice(0, pos).trim();
}
if (!commit.originalSubject) {
commit.originalSubject = subject;
}
if (body) {
commit.body = body;
@@ -160,50 +185,36 @@ const parseCommitMessage = (commitMessage, owner, repo, commit = {}) => {
// if the subject ends in ' (#dddd)', treat it as a pull request id
let match;
if ((match = subject.match(/^(.*)\s\(#(\d+)\)$/))) {
setPullRequest(commit, owner, repo, parseInt(match[2]));
commit.prKeys.add(new GHKey(owner, repo, parseInt(match[2])));
subject = match[1];
}
// if the subject begins with 'word:', treat it as a semantic commit
if ((match = subject.match(/^(\w+):\s(.*)$/))) {
const type = match[1].toLocaleLowerCase();
if (knownTypes.has(type)) {
commit.type = type;
const semanticType = match[1].toLocaleLowerCase();
if (knownTypes.has(semanticType)) {
commit.semanticType = semanticType;
subject = match[2];
}
}
// Check for GitHub commit message that indicates a PR
if ((match = subject.match(/^Merge pull request #(\d+) from (.*)$/))) {
setPullRequest(commit, owner, repo, parseInt(match[1]));
commit.pr.branch = match[2].trim();
commit.prKeys.add(new GHKey(owner, repo, parseInt(match[1])));
}
// Check for a trop comment that indicates a PR
if ((match = commitMessage.match(/\bBackport of #(\d+)\b/))) {
setPullRequest(commit, owner, repo, parseInt(match[1]));
// Check for a comment that indicates a PR
const backportPattern = /(?:^|\n)(?:manual |manually )?backport.*(?:#(\d+)|\/pull\/(\d+))/im;
if ((match = commitMessage.match(backportPattern))) {
// This might be the first or second capture group depending on if it's a link or not.
const backportNumber = match[1] ? parseInt(match[1], 10) : parseInt(match[2], 10);
commit.prKeys.add(new GHKey(owner, repo, backportNumber));
}
// https://help.github.com/articles/closing-issues-using-keywords/
if ((match = subject.match(/\b(?:close|closes|closed|fix|fixes|fixed|resolve|resolves|resolved|for)\s#(\d+)\b/))) {
if ((match = body.match(/\b(?:close|closes|closed|fix|fixes|fixed|resolve|resolves|resolved|for)\s#(\d+)\b/i))) {
commit.issueNumber = parseInt(match[1]);
if (!commit.type) {
commit.type = 'fix';
}
}
// look for 'fixes' in markdown; e.g. 'Fixes [#8952](https://github.com/electron/electron/issues/8952)'
if (!commit.issueNumber && ((match = commitMessage.match(/Fixes \[#(\d+)\]\(https:\/\/github.com\/(\w+)\/(\w+)\/issues\/(\d+)\)/)))) {
commit.issueNumber = parseInt(match[1]);
if (commit.pr && commit.pr.number === commit.issueNumber) {
commit.pr = null;
}
if (commit.originalPr && commit.originalPr.number === commit.issueNumber) {
commit.originalPr = null;
}
if (!commit.type) {
commit.type = 'fix';
}
commit.semanticType = commit.semanticType || 'fix';
}
// https://www.conventionalcommits.org/en
@@ -211,7 +222,7 @@ const parseCommitMessage = (commitMessage, owner, repo, commit = {}) => {
.split(/\r?\n/) // split into lines
.map(line => line.trim())
.some(line => line.startsWith('BREAKING CHANGE'))) {
commit.type = 'breaking-change';
commit.isBreakingChange = true;
}
// Check for a reversion commit
@@ -219,75 +230,35 @@ const parseCommitMessage = (commitMessage, owner, repo, commit = {}) => {
commit.revertHash = match[1];
}
// Edge case: manual backport where commit has `owner/repo#pull` notation
if (commitMessage.toLowerCase().includes('backport') &&
((match = commitMessage.match(/\b(\w+)\/(\w+)#(\d+)\b/)))) {
const [ , owner, repo, number ] = match;
if (FOLLOW_REPOS.includes(`${owner}/${repo}`)) {
setPullRequest(commit, owner, repo, number);
}
}
// Edge case: manual backport where commit has a link to the backport PR
if (commitMessage.includes('ackport') &&
((match = commitMessage.match(/https:\/\/github\.com\/(\w+)\/(\w+)\/pull\/(\d+)/)))) {
const [ , owner, repo, number ] = match;
if (FOLLOW_REPOS.includes(`${owner}/${repo}`)) {
setPullRequest(commit, owner, repo, number);
}
}
// Legacy commits: pre-semantic commits
if (!commit.type || commit.type === 'chore') {
const commitMessageLC = commitMessage.toLocaleLowerCase();
if ((match = commitMessageLC.match(/\bchore\((\w+)\):/))) {
// example: 'Chore(docs): description'
commit.type = knownTypes.has(match[1]) ? match[1] : 'chore';
} else if (commitMessageLC.match(/\b(?:fix|fixes|fixed)/)) {
// example: 'fix a bug'
commit.type = 'fix';
} else if (commitMessageLC.match(/\[(?:docs|doc)\]/)) {
// example: '[docs]
commit.type = 'doc';
}
}
commit.subject = subject.trim();
return commit;
};
const parsePullText = (pull, commit) => parseCommitMessage(`${pull.data.title}\n\n${pull.data.body}`, commit);
const getLocalCommitHashes = async (dir, ref) => {
const args = ['log', '-z', `--format=%H`, ref];
return (await runGit(dir, args)).split(`\0`).map(hash => hash.trim());
const args = ['log', '-z', '--format=%H', ref];
return (await runGit(dir, args)).split('\0').map(hash => hash.trim());
};
/*
* possible properties:
* breakingChange, email, hash, issueNumber, originalSubject, parentHashes,
* pr { owner, repo, number, branch }, revertHash, subject, type
*/
const getLocalCommitDetails = async (module, point1, point2) => {
// return an array of Commits
const getLocalCommits = async (module, point1, point2) => {
const { owner, repo, dir } = module;
const fieldSep = '||';
const format = ['%H', '%P', '%aE', '%B'].join(fieldSep);
const format = ['%H', '%B'].join(fieldSep);
const args = ['log', '-z', '--cherry-pick', '--right-only', '--first-parent', `--format=${format}`, `${point1}..${point2}`];
const commits = (await runGit(dir, args)).split(`\0`).map(field => field.trim());
const details = [];
for (const commit of commits) {
if (!commit) {
const logs = (await runGit(dir, args)).split('\0').map(field => field.trim());
const commits = [];
for (const log of logs) {
if (!log) {
continue;
}
const [ hash, parentHashes, email, commitMessage ] = commit.split(fieldSep, 4).map(field => field.trim());
details.push(parseCommitMessage(commitMessage, owner, repo, {
email,
hash,
owner,
repo,
parentHashes: parentHashes.split()
}));
const [hash, message] = log.split(fieldSep, 2).map(field => field.trim());
commits.push(parseCommitMessage(message, new Commit(hash, owner, repo)));
}
return details;
return commits;
};
const checkCache = async (name, operation) => {
@@ -295,6 +266,7 @@ const checkCache = async (name, operation) => {
if (fs.existsSync(filename)) {
return JSON.parse(fs.readFileSync(filename, 'utf8'));
}
process.stdout.write('.');
const response = await operation();
if (response) {
fs.writeFileSync(filename, JSON.stringify(response));
@@ -317,13 +289,15 @@ async function runRetryable (fn, maxRetries) {
if (lastError.status !== 404) throw lastError;
}
const getPullRequest = async (number, owner, repo) => {
const getPullRequest = async (ghKey) => {
const { number, owner, repo } = ghKey;
const name = `${owner}-${repo}-pull-${number}`;
const retryableFunc = () => octokit.pulls.get({ pull_number: number, owner, repo });
return checkCache(name, () => runRetryable(retryableFunc, MAX_FAIL_COUNT));
};
const getComments = async (number, owner, repo) => {
const getComments = async (ghKey) => {
const { number, owner, repo } = ghKey;
const name = `${owner}-${repo}-issue-${number}-comments`;
const retryableFunc = () => octokit.issues.listComments({ issue_number: number, owner, repo, per_page: 100 });
return checkCache(name, () => runRetryable(retryableFunc, MAX_FAIL_COUNT));
@@ -331,10 +305,24 @@ const getComments = async (number, owner, repo) => {
const addRepoToPool = async (pool, repo, from, to) => {
const commonAncestor = await getCommonAncestor(repo.dir, from, to);
// add the commits
const oldHashes = await getLocalCommitHashes(repo.dir, from);
oldHashes.forEach(hash => { pool.processedHashes.add(hash); });
const commits = await getLocalCommitDetails(repo, commonAncestor, to);
const commits = await getLocalCommits(repo, commonAncestor, to);
pool.commits.push(...commits);
// add the pulls
for (const commit of commits) {
let prKey;
for (prKey of commit.prKeys.values()) {
const pull = await getPullRequest(prKey);
if (!pull || !pull.data) break; // couldn't get it
if (pool.pulls[prKey.number]) break; // already have it
pool.pulls[prKey.number] = pull;
parsePullText(pull, commit);
}
}
};
/***
@@ -400,6 +388,26 @@ const shouldIncludeMultibranchChanges = (version) => {
return show;
};
function getOldestMajorBranchOfPull (pull) {
return pull.data.labels
.map(label => label.name.match(/merged\/(\d+)-(\d+)-x/) || label.name.match(/merged\/(\d+)-x-y/))
.filter(label => !!label)
.map(label => parseInt(label[1]))
.filter(major => !!major)
.sort()
.shift();
}
function getOldestMajorBranchOfCommit (commit, pool) {
return [ ...commit.prKeys.values() ]
.map(prKey => pool.pulls[prKey.number])
.filter(pull => !!pull)
.map(pull => getOldestMajorBranchOfPull(pull))
.filter(major => !!major)
.sort()
.shift();
}
/***
**** Main
***/
@@ -409,10 +417,7 @@ const getNotes = async (fromRef, toRef, newVersion) => {
fs.mkdirSync(CACHE_DIR);
}
const pool = {
processedHashes: new Set(),
commits: []
};
const pool = new Pool();
// get the electron/electron commits
const electron = { owner: 'electron', repo: 'electron', dir: ELECTRON_VERSION };
@@ -449,43 +454,16 @@ const getNotes = async (fromRef, toRef, newVersion) => {
pool.processedHashes.add(revertHash);
}
// scrape PRs for release note 'Notes:' comments
// ensure the commit has a note
for (const commit of pool.commits) {
let pr = commit.pr;
let prSubject;
while (pr && !commit.note) {
const note = await getNoteFromClerk(pr.number, pr.owner, pr.repo);
if (note) {
commit.note = note;
}
// if we already have all the data we need, stop scraping the PRs
if (commit.note && commit.type && prSubject) {
for (const prKey of commit.prKeys.values()) {
commit.note = commit.note || await getNoteFromClerk(prKey);
if (commit.note) {
break;
}
const prData = await getPullRequest(pr.number, pr.owner, pr.repo);
if (!prData || !prData.data) {
break;
}
// try to pull a release note from the pull comment
const prParsed = parseCommitMessage(`${prData.data.title}\n\n${prData.data.body}`, pr.owner, pr.repo);
if (!commit.note) {
commit.note = prParsed.note;
}
if (!commit.type || prParsed.type === 'breaking-change') {
commit.type = prParsed.type;
}
prSubject = prSubject || prParsed.subject;
pr = prParsed.pr && (prParsed.pr.number !== pr.number) ? prParsed.pr : null;
}
// if we still don't have a note, it's because someone missed a 'Notes:
// comment in a PR somewhere... use the PR subject as a fallback.
commit.note = commit.note || prSubject;
// use a fallback note in case someone missed a 'Notes' comment
commit.note = commit.note || commit.subject;
}
// remove non-user-facing commits
@@ -494,41 +472,9 @@ const getNotes = async (fromRef, toRef, newVersion) => {
.filter(commit => !((commit.note || commit.subject).match(/^[Bb]ump v\d+\.\d+\.\d+/)));
if (!shouldIncludeMultibranchChanges(newVersion)) {
// load all the prDatas
await Promise.all(
pool.commits.map(commit => new Promise(async (resolve) => {
const { pr } = commit;
if (typeof pr === 'object') {
const prData = await getPullRequest(pr.number, pr.owner, pr.repo);
if (prData) {
commit.prData = prData;
}
}
resolve();
}))
);
// remove items that already landed in a previous major/minor series
const currentMajor = semver.parse(newVersion).major;
pool.commits = pool.commits
.filter(commit => {
if (!commit.prData) {
return true;
}
const reducer = (accumulator, current) => {
if (!semver.valid(accumulator)) { return current; }
if (!semver.valid(current)) { return accumulator; }
return semver.lt(accumulator, current) ? accumulator : current;
};
const earliestRelease = commit.prData.data.labels
.map(label => label.name.match(/merged\/(\d+)-(\d+)-x/))
.filter(label => !!label)
.map(label => `${label[1]}.${label[2]}.0`)
.reduce(reducer, null);
if (!semver.valid(earliestRelease)) {
return true;
}
return semver.diff(earliestRelease, newVersion).includes('patch');
});
.filter(commit => getOldestMajorBranchOfCommit(commit, pool) >= currentMajor);
}
pool.commits = removeSupercededChromiumUpdates(pool.commits);
@@ -544,11 +490,11 @@ const getNotes = async (fromRef, toRef, newVersion) => {
};
pool.commits.forEach(commit => {
const str = commit.type;
if (!str) {
notes.unknown.push(commit);
} else if (breakTypes.has(str)) {
const str = commit.semanticType;
if (commit.isBreakingChange) {
notes.breaking.push(commit);
} else if (!str) {
notes.unknown.push(commit);
} else if (docTypes.has(str)) {
notes.docs.push(commit);
} else if (featTypes.has(str)) {
@@ -572,8 +518,8 @@ const removeSupercededChromiumUpdates = (commits) => {
// keep the newest update.
if (updates.length) {
updates.sort((a, b) => a.originalPr.number - b.originalPr.number);
keepers.push(updates.pop());
const compare = (a, b) => (a.note || a.subject).localeCompare(b.note || b.subject);
keepers.push(updates.sort(compare).pop());
}
return keepers;
@@ -585,21 +531,22 @@ const removeSupercededChromiumUpdates = (commits) => {
const renderLink = (commit, explicitLinks) => {
let link;
const pr = commit.originalPr;
if (pr) {
const { owner, repo, number } = pr;
const url = `https://github.com/${owner}/${repo}/pull/${number}`;
const text = owner === 'electron' && repo === 'electron'
? `#${number}`
: `${owner}/${repo}#${number}`;
link = explicitLinks ? `[${text}](${url})` : text;
} else {
const { owner, repo, hash } = commit;
const { owner, repo } = commit;
const keyIt = commit.prKeys.values().next();
if (keyIt.done) /* no PRs */ {
const { hash } = commit;
const url = `https://github.com/${owner}/${repo}/commit/${hash}`;
const text = owner === 'electron' && repo === 'electron'
? `${hash.slice(0, 8)}`
: `${owner}/${repo}@${hash.slice(0, 8)}`;
link = explicitLinks ? `[${text}](${url})` : text;
} else {
const { number } = keyIt.value;
const url = `https://github.com/${owner}/${repo}/pull/${number}`;
const text = owner === 'electron' && repo === 'electron'
? `#${number}`
: `${owner}/${repo}#${number}`;
link = explicitLinks ? `[${text}](${url})` : text;
}
return link;
};
@@ -616,22 +563,22 @@ const renderCommit = (commit, explicitLinks) => {
}
const commonVerbs = {
'Added': [ 'Add' ],
'Backported': [ 'Backport' ],
'Cleaned': [ 'Clean' ],
'Disabled': [ 'Disable' ],
'Ensured': [ 'Ensure' ],
'Exported': [ 'Export' ],
'Fixed': [ 'Fix', 'Fixes' ],
'Handled': [ 'Handle' ],
'Improved': [ 'Improve' ],
'Made': [ 'Make' ],
'Removed': [ 'Remove' ],
'Repaired': [ 'Repair' ],
'Reverted': [ 'Revert' ],
'Stopped': [ 'Stop' ],
'Updated': [ 'Update' ],
'Upgraded': [ 'Upgrade' ]
Added: ['Add'],
Backported: ['Backport'],
Cleaned: ['Clean'],
Disabled: ['Disable'],
Ensured: ['Ensure'],
Exported: ['Export'],
Fixed: ['Fix', 'Fixes'],
Handled: ['Handle'],
Improved: ['Improve'],
Made: ['Make'],
Removed: ['Remove'],
Repaired: ['Repair'],
Reverted: ['Revert'],
Stopped: ['Stop'],
Updated: ['Update'],
Upgraded: ['Upgrade']
};
for (const [key, values] of Object.entries(commonVerbs)) {
for (const value of values) {
@@ -649,7 +596,7 @@ const renderCommit = (commit, explicitLinks) => {
};
const renderNotes = (notes, explicitLinks) => {
const rendered = [ `# Release Notes for ${notes.name}\n\n` ];
const rendered = [`# Release Notes for ${notes.name}\n\n`];
const renderSection = (title, commits) => {
if (commits.length === 0) {

View File

@@ -3,11 +3,14 @@ Electron.app/Contents/
Electron.app/Contents/Frameworks/
Electron.app/Contents/Frameworks/Electron Framework.framework/
Electron.app/Contents/Frameworks/Electron Framework.framework/Electron Framework
Electron.app/Contents/Frameworks/Electron Framework.framework/Helpers
Electron.app/Contents/Frameworks/Electron Framework.framework/Libraries
Electron.app/Contents/Frameworks/Electron Framework.framework/Resources
Electron.app/Contents/Frameworks/Electron Framework.framework/Versions/
Electron.app/Contents/Frameworks/Electron Framework.framework/Versions/A/
Electron.app/Contents/Frameworks/Electron Framework.framework/Versions/A/Electron Framework
Electron.app/Contents/Frameworks/Electron Framework.framework/Versions/A/Helpers/
Electron.app/Contents/Frameworks/Electron Framework.framework/Versions/A/Helpers/chrome_crashpad_handler
Electron.app/Contents/Frameworks/Electron Framework.framework/Versions/A/Libraries/
Electron.app/Contents/Frameworks/Electron Framework.framework/Versions/A/Libraries/libEGL.dylib
Electron.app/Contents/Frameworks/Electron Framework.framework/Versions/A/Libraries/libGLESv2.dylib
@@ -31,7 +34,6 @@ Electron.app/Contents/Frameworks/Electron Framework.framework/Versions/A/Resourc
Electron.app/Contents/Frameworks/Electron Framework.framework/Versions/A/Resources/ca.lproj/locale.pak
Electron.app/Contents/Frameworks/Electron Framework.framework/Versions/A/Resources/chrome_100_percent.pak
Electron.app/Contents/Frameworks/Electron Framework.framework/Versions/A/Resources/chrome_200_percent.pak
Electron.app/Contents/Frameworks/Electron Framework.framework/Versions/A/Resources/crashpad_handler
Electron.app/Contents/Frameworks/Electron Framework.framework/Versions/A/Resources/cs.lproj/
Electron.app/Contents/Frameworks/Electron Framework.framework/Versions/A/Resources/cs.lproj/locale.pak
Electron.app/Contents/Frameworks/Electron Framework.framework/Versions/A/Resources/da.lproj/

View File

@@ -3,6 +3,7 @@ Electron.app/Contents/
Electron.app/Contents/Frameworks/
Electron.app/Contents/Frameworks/Electron Framework.framework/
Electron.app/Contents/Frameworks/Electron Framework.framework/Electron Framework
Electron.app/Contents/Frameworks/Electron Framework.framework/Helpers
Electron.app/Contents/Frameworks/Electron Framework.framework/Libraries
Electron.app/Contents/Frameworks/Electron Framework.framework/Resources
Electron.app/Contents/Frameworks/Electron Framework.framework/Versions/

View File

@@ -19,13 +19,13 @@
#include "electron/buildflags/buildflags.h"
#include "extensions/common/constants.h"
#include "ppapi/buildflags/buildflags.h"
#include "shell/browser/electron_paths.h"
#include "shell/common/electron_paths.h"
#include "shell/common/options_switches.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/base/resource/resource_bundle.h"
#include "url/url_constants.h"
// In SHARED_INTERMEDIATE_DIR.
#include "widevine_cdm_version.h" // NOLINT(build/include)
#include "widevine_cdm_version.h" // NOLINT(build/include_directory)
#if defined(WIDEVINE_CDM_AVAILABLE)
#include "base/native_library.h"

View File

@@ -0,0 +1,209 @@
// Copyright 2013 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/app/electron_crash_reporter_client.h"
#include <map>
#include <memory>
#include <string>
#include "base/command_line.h"
#include "base/environment.h"
#include "base/files/file_path.h"
#include "base/logging.h"
#include "base/path_service.h"
#include "base/strings/string_split.h"
#include "base/strings/utf_string_conversions.h"
#include "base/threading/thread_restrictions.h"
#include "build/build_config.h"
#include "chrome/common/chrome_paths.h"
#include "components/crash/core/common/crash_keys.h"
#include "components/upload_list/crash_upload_list.h"
#include "content/public/common/content_switches.h"
#include "electron/electron_version.h"
#include "services/service_manager/embedder/switches.h"
#include "shell/common/electron_paths.h"
#if defined(OS_POSIX) && !defined(OS_MACOSX)
#include "components/version_info/version_info_values.h"
#endif
#if defined(OS_POSIX)
#include "base/debug/dump_without_crashing.h"
#endif
namespace {
ElectronCrashReporterClient* Instance() {
static base::NoDestructor<ElectronCrashReporterClient> crash_client;
return crash_client.get();
}
} // namespace
// static
void ElectronCrashReporterClient::Create() {
crash_reporter::SetCrashReporterClient(Instance());
// By setting the BREAKPAD_DUMP_LOCATION environment variable, an alternate
// location to write crash dumps can be set.
std::unique_ptr<base::Environment> env(base::Environment::Create());
std::string alternate_crash_dump_location;
base::FilePath crash_dumps_dir_path;
if (env->GetVar("BREAKPAD_DUMP_LOCATION", &alternate_crash_dump_location)) {
crash_dumps_dir_path =
base::FilePath::FromUTF8Unsafe(alternate_crash_dump_location);
}
if (!crash_dumps_dir_path.empty()) {
base::ThreadRestrictions::ScopedAllowIO allow_io;
base::PathService::Override(electron::DIR_CRASH_DUMPS,
crash_dumps_dir_path);
}
}
// static
ElectronCrashReporterClient* ElectronCrashReporterClient::Get() {
return Instance();
}
void ElectronCrashReporterClient::SetCollectStatsConsent(bool upload_allowed) {
collect_stats_consent_ = upload_allowed;
}
void ElectronCrashReporterClient::SetUploadUrl(const std::string& url) {
upload_url_ = url;
}
void ElectronCrashReporterClient::SetShouldRateLimit(bool rate_limit) {
rate_limit_ = rate_limit;
}
void ElectronCrashReporterClient::SetShouldCompressUploads(bool compress) {
compress_uploads_ = compress;
}
void ElectronCrashReporterClient::SetGlobalAnnotations(
const std::map<std::string, std::string>& annotations) {
global_annotations_ = annotations;
}
ElectronCrashReporterClient::ElectronCrashReporterClient() {}
ElectronCrashReporterClient::~ElectronCrashReporterClient() {}
#if defined(OS_LINUX)
void ElectronCrashReporterClient::SetCrashReporterClientIdFromGUID(
const std::string& client_guid) {
crash_keys::SetMetricsClientIdFromGUID(client_guid);
}
void ElectronCrashReporterClient::GetProductNameAndVersion(
const char** product_name,
const char** version) {
DCHECK(product_name);
DCHECK(version);
*product_name = ELECTRON_PRODUCT_NAME;
*version = ELECTRON_VERSION_STRING;
}
void ElectronCrashReporterClient::GetProductNameAndVersion(
std::string* product_name,
std::string* version,
std::string* channel) {
const char* c_product_name;
const char* c_version;
GetProductNameAndVersion(&c_product_name, &c_version);
*product_name = c_product_name;
*version = c_version;
*channel = "";
}
base::FilePath ElectronCrashReporterClient::GetReporterLogFilename() {
return base::FilePath(CrashUploadList::kReporterLogFilename);
}
#endif
#if defined(OS_WIN)
void ElectronCrashReporterClient::GetProductNameAndVersion(
const base::string16& exe_path,
base::string16* product_name,
base::string16* version,
base::string16* special_build,
base::string16* channel_name) {
*product_name = base::UTF8ToUTF16(ELECTRON_PRODUCT_NAME);
*version = base::UTF8ToUTF16(ELECTRON_VERSION_STRING);
}
#endif
#if defined(OS_WIN)
bool ElectronCrashReporterClient::GetCrashDumpLocation(
base::string16* crash_dir_str) {
base::FilePath crash_dir;
if (!base::PathService::Get(electron::DIR_CRASH_DUMPS, &crash_dir))
return false;
*crash_dir_str = crash_dir.value();
return true;
}
#else
bool ElectronCrashReporterClient::GetCrashDumpLocation(
base::FilePath* crash_dir) {
return base::PathService::Get(electron::DIR_CRASH_DUMPS, crash_dir);
}
#endif
#if defined(OS_MACOSX) || defined(OS_LINUX)
bool ElectronCrashReporterClient::GetCrashMetricsLocation(
base::FilePath* metrics_dir) {
return base::PathService::Get(electron::DIR_USER_DATA, metrics_dir);
}
#endif // OS_MACOSX || OS_LINUX
bool ElectronCrashReporterClient::IsRunningUnattended() {
return false;
}
bool ElectronCrashReporterClient::GetCollectStatsConsent() {
return collect_stats_consent_;
}
#if defined(OS_MACOSX)
bool ElectronCrashReporterClient::ReportingIsEnforcedByPolicy(
bool* breakpad_enabled) {
return false;
}
#endif
bool ElectronCrashReporterClient::GetShouldRateLimit() {
return rate_limit_;
}
bool ElectronCrashReporterClient::GetShouldCompressUploads() {
return compress_uploads_;
}
void ElectronCrashReporterClient::GetProcessSimpleAnnotations(
std::map<std::string, std::string>* annotations) {
*annotations = global_annotations_;
(*annotations)["prod"] = ELECTRON_PRODUCT_NAME;
(*annotations)["ver"] = ELECTRON_VERSION_STRING;
}
#if defined(OS_LINUX) || defined(OS_MACOSX)
bool ElectronCrashReporterClient::ShouldMonitorCrashHandlerExpensively() {
return false;
}
#endif // OS_LINUX
bool ElectronCrashReporterClient::GetUploadUrl(std::string* url) {
*url = upload_url_;
return true;
}
bool ElectronCrashReporterClient::EnableBreakpadForProcess(
const std::string& process_type) {
return process_type == switches::kRendererProcess ||
process_type == switches::kPpapiPluginProcess ||
process_type == service_manager::switches::kZygoteProcess ||
process_type == switches::kGpuProcess ||
process_type == switches::kUtilityProcess || process_type == "node";
}

View File

@@ -0,0 +1,96 @@
// Copyright 2013 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_APP_ELECTRON_CRASH_REPORTER_CLIENT_H_
#define SHELL_APP_ELECTRON_CRASH_REPORTER_CLIENT_H_
#include <map>
#include <string>
#include "base/compiler_specific.h"
#include "base/macros.h"
#include "base/no_destructor.h"
#include "build/build_config.h"
#include "components/crash/core/app/crash_reporter_client.h"
class ElectronCrashReporterClient : public crash_reporter::CrashReporterClient {
public:
static void Create();
static ElectronCrashReporterClient* Get();
void SetCollectStatsConsent(bool upload_allowed);
void SetUploadUrl(const std::string& url);
void SetShouldRateLimit(bool rate_limit);
void SetShouldCompressUploads(bool compress_uploads);
void SetGlobalAnnotations(
const std::map<std::string, std::string>& annotations);
// crash_reporter::CrashReporterClient implementation.
#if defined(OS_LINUX)
void SetCrashReporterClientIdFromGUID(
const std::string& client_guid) override;
void GetProductNameAndVersion(const char** product_name,
const char** version) override;
void GetProductNameAndVersion(std::string* product_name,
std::string* version,
std::string* channel) override;
base::FilePath GetReporterLogFilename() override;
#endif
#if defined(OS_WIN)
void GetProductNameAndVersion(const base::string16& exe_path,
base::string16* product_name,
base::string16* version,
base::string16* special_build,
base::string16* channel_name) override;
#endif
#if defined(OS_WIN)
bool GetCrashDumpLocation(base::string16* crash_dir) override;
#else
bool GetCrashDumpLocation(base::FilePath* crash_dir) override;
#endif
#if defined(OS_MACOSX) || defined(OS_LINUX)
bool GetCrashMetricsLocation(base::FilePath* metrics_dir) override;
#endif
bool IsRunningUnattended() override;
bool GetCollectStatsConsent() override;
bool GetShouldRateLimit() override;
bool GetShouldCompressUploads() override;
void GetProcessSimpleAnnotations(
std::map<std::string, std::string>* annotations) override;
#if defined(OS_MACOSX)
bool ReportingIsEnforcedByPolicy(bool* breakpad_enabled) override;
#endif
#if defined(OS_MACOSX) || defined(OS_LINUX)
bool ShouldMonitorCrashHandlerExpensively() override;
#endif
bool EnableBreakpadForProcess(const std::string& process_type) override;
bool GetUploadUrl(std::string* url) override;
private:
friend class base::NoDestructor<ElectronCrashReporterClient>;
std::string upload_url_;
bool collect_stats_consent_;
bool rate_limit_ = false;
bool compress_uploads_ = false;
std::map<std::string, std::string> global_annotations_;
ElectronCrashReporterClient();
~ElectronCrashReporterClient() override;
DISALLOW_COPY_AND_ASSIGN(ElectronCrashReporterClient);
};
#endif // SHELL_APP_ELECTRON_CRASH_REPORTER_CLIENT_H_

View File

@@ -7,6 +7,8 @@
#include <algorithm>
#include <cstdlib>
#include <memory>
#include <string>
#include <utility>
#include <vector>
#if defined(OS_WIN)
@@ -21,11 +23,15 @@
#include "base/process/launch.h"
#include "base/strings/utf_string_conversions.h"
#include "base/win/windows_version.h"
#include "components/browser_watcher/exit_code_watcher_win.h"
#include "components/crash/core/app/crash_switches.h"
#include "components/crash/core/app/run_as_crashpad_handler_win.h"
#include "content/public/app/sandbox_helper_win.h"
#include "sandbox/win/src/sandbox_types.h"
#include "shell/app/command_line_args.h"
#include "shell/app/electron_main_delegate.h"
#include "shell/common/crash_reporter/win/crash_service_main.h"
#include "third_party/crashpad/crashpad/util/win/initial_client_data.h"
#elif defined(OS_LINUX) // defined(OS_WIN)
#include <unistd.h>
#include <cstdio>
@@ -51,6 +57,13 @@
namespace {
#if defined(OS_WIN)
// Redefined here so we don't have to introduce a dependency on //content
// from //electron:electron_app
const char kUserDataDir[] = "user-data-dir";
const char kProcessType[] = "type";
#endif
ALLOW_UNUSED_TYPE bool IsEnvSet(const char* name) {
#if defined(OS_WIN)
size_t required_size;
@@ -138,10 +151,49 @@ int APIENTRY wWinMain(HINSTANCE instance, HINSTANCE, wchar_t* cmd, int) {
#endif
base::CommandLine::Init(argv.size(), argv.data());
const base::CommandLine& cmd_line = *base::CommandLine::ForCurrentProcess();
if (cmd_line.GetSwitchValueASCII("type") ==
crash_reporter::kCrashpadProcess) {
return crash_service::Main(&argv);
const base::CommandLine* command_line =
base::CommandLine::ForCurrentProcess();
const std::string process_type =
command_line->GetSwitchValueASCII(kProcessType);
if (process_type == crash_reporter::switches::kCrashpadHandler) {
// Check if we should monitor the exit code of this process
std::unique_ptr<browser_watcher::ExitCodeWatcher> exit_code_watcher;
// Retrieve the client process from the command line
crashpad::InitialClientData initial_client_data;
if (initial_client_data.InitializeFromString(
command_line->GetSwitchValueASCII("initial-client-data"))) {
// Setup exit code watcher to monitor the parent process
HANDLE duplicate_handle = INVALID_HANDLE_VALUE;
if (DuplicateHandle(
::GetCurrentProcess(), initial_client_data.client_process(),
::GetCurrentProcess(), &duplicate_handle,
PROCESS_QUERY_INFORMATION, FALSE, DUPLICATE_SAME_ACCESS)) {
base::Process parent_process(duplicate_handle);
exit_code_watcher =
std::make_unique<browser_watcher::ExitCodeWatcher>();
if (exit_code_watcher->Initialize(std::move(parent_process))) {
exit_code_watcher->StartWatching();
}
}
}
// The handler process must always be passed the user data dir on the
// command line.
DCHECK(command_line->HasSwitch(kUserDataDir));
base::FilePath user_data_dir =
command_line->GetSwitchValuePath(kUserDataDir);
int crashpad_status = crash_reporter::RunAsCrashpadHandler(
*command_line, user_data_dir, kProcessType, kUserDataDir);
if (crashpad_status != 0 && exit_code_watcher) {
// Crashpad failed to initialize, explicitly stop the exit code watcher
// so the crashpad-handler process can exit with an error
exit_code_watcher->StopWatching();
}
return crashpad_status;
}
if (!electron::CheckCommandLineArguments(arguments.argc, arguments.argv))

View File

@@ -15,11 +15,16 @@
#include "base/command_line.h"
#include "base/debug/stack_trace.h"
#include "base/environment.h"
#include "base/files/file_util.h"
#include "base/logging.h"
#include "base/mac/bundle_locations.h"
#include "base/path_service.h"
#include "base/strings/string_split.h"
#include "chrome/common/chrome_paths.h"
#include "components/content_settings/core/common/content_settings_pattern.h"
#include "components/crash/core/app/crashpad.h"
#include "components/crash/core/common/crash_key.h"
#include "components/crash/core/common/crash_keys.h"
#include "content/public/common/content_switches.h"
#include "electron/buildflags/buildflags.h"
#include "extensions/common/constants.h"
@@ -28,10 +33,14 @@
#include "services/service_manager/sandbox/switches.h"
#include "services/tracing/public/cpp/stack_sampling/tracing_sampler_profiler.h"
#include "shell/app/electron_content_client.h"
#include "shell/app/electron_crash_reporter_client.h"
#include "shell/browser/api/electron_api_crash_reporter.h"
#include "shell/browser/electron_browser_client.h"
#include "shell/browser/electron_gpu_client.h"
#include "shell/browser/feature_list.h"
#include "shell/browser/relauncher.h"
#include "shell/common/crash_keys.h"
#include "shell/common/electron_paths.h"
#include "shell/common/options_switches.h"
#include "shell/renderer/electron_renderer_client.h"
#include "shell/renderer/electron_sandboxed_renderer_client.h"
@@ -46,9 +55,13 @@
#if defined(OS_WIN)
#include "base/win/win_util.h"
#if defined(_WIN64)
#include "shell/common/crash_reporter/crash_reporter_win.h"
#include "chrome/child/v8_crashpad_support_win.h"
#endif
#if defined(OS_LINUX)
#include "components/crash/core/app/breakpad_linux.h"
#include "v8/include/v8-wasm-trap-handler-posix.h"
#include "v8/include/v8.h"
#endif
namespace electron {
@@ -71,7 +84,7 @@ bool IsSandboxEnabled(base::CommandLine* command_line) {
// and resources loaded.
bool SubprocessNeedsResourceBundle(const std::string& process_type) {
return
#if defined(OS_POSIX) && !defined(OS_MACOSX)
#if defined(OS_LINUX)
// The zygote process opens the resources for the renderers.
process_type == service_manager::switches::kZygoteProcess ||
#endif
@@ -98,6 +111,41 @@ void InvalidParameterHandler(const wchar_t*,
} // namespace
// TODO(nornagon): move path provider overriding to its own file in
// shell/common
namespace electron {
bool GetDefaultCrashDumpsPath(base::FilePath* path) {
base::FilePath cur;
if (!base::PathService::Get(DIR_USER_DATA, &cur))
return false;
#if defined(OS_MACOSX) || defined(OS_WIN)
cur = cur.Append(FILE_PATH_LITERAL("Crashpad"));
#else
cur = cur.Append(FILE_PATH_LITERAL("Crash Reports"));
#endif
// TODO(bauerb): http://crbug.com/259796
base::ThreadRestrictions::ScopedAllowIO allow_io;
if (!base::PathExists(cur) && !base::CreateDirectory(cur))
return false;
*path = cur;
return true;
}
bool ElectronPathProvider(int key, base::FilePath* path) {
if (key == DIR_CRASH_DUMPS) {
return GetDefaultCrashDumpsPath(path);
}
return false;
}
void RegisterPathProvider() {
base::PathService::RegisterProvider(ElectronPathProvider, PATH_START,
PATH_END);
}
} // namespace electron
void LoadResourceBundle(const std::string& locale) {
const bool initialized = ui::ResourceBundle::HasSharedInstance();
if (initialized)
@@ -134,9 +182,7 @@ bool ElectronMainDelegate::BasicStartupComplete(int* exit_code) {
logging::LoggingSettings settings;
#if defined(OS_WIN)
#if defined(_WIN64)
crash_reporter::CrashReporterWin::SetUnhandledExceptionFilter();
#endif
v8_crashpad_support::SetUp();
// On Windows the terminal returns immediately, so we add a new line to
// prevent output in the same line as the prompt.
@@ -185,6 +231,8 @@ bool ElectronMainDelegate::BasicStartupComplete(int* exit_code) {
tracing::TracingSamplerProfiler::CreateOnMainThread();
chrome::RegisterPathProvider();
electron::RegisterPathProvider();
#if BUILDFLAG(ENABLE_ELECTRON_EXTENSIONS)
ContentSettingsPattern::SetNonWildcardDomainNonPortSchemes(
kNonWildcardDomainNonPortSchemes, kNonWildcardDomainNonPortSchemesSize);
@@ -272,6 +320,10 @@ void ElectronMainDelegate::PreSandboxStartup() {
std::string process_type =
command_line->GetSwitchValueASCII(::switches::kProcessType);
#if !defined(MAS_BUILD)
crash_reporter::InitializeCrashKeys();
#endif
// Initialize ResourceBundle which handles files loaded from external
// sources. The language should have been passed in to us from the
// browser process as a command line flag.
@@ -280,17 +332,40 @@ void ElectronMainDelegate::PreSandboxStartup() {
LoadResourceBundle(locale);
}
// Only append arguments for browser process.
if (!IsBrowserProcess(command_line))
return;
#if defined(OS_WIN) || (defined(OS_MACOSX) && !defined(MAS_BUILD))
// In the main process, we wait for JS to call crashReporter.start() before
// initializing crashpad. If we're in the renderer, we want to initialize it
// immediately at boot.
if (!process_type.empty()) {
ElectronCrashReporterClient::Create();
crash_reporter::InitializeCrashpad(false, process_type);
}
#endif
// Allow file:// URIs to read other file:// URIs by default.
command_line->AppendSwitch(::switches::kAllowFileAccessFromFiles);
#if defined(OS_LINUX)
if (process_type != service_manager::switches::kZygoteProcess &&
!process_type.empty()) {
ElectronCrashReporterClient::Create();
breakpad::InitCrashReporter(process_type);
}
#endif
#if !defined(MAS_BUILD)
crash_keys::SetCrashKeysFromCommandLine(*command_line);
crash_keys::SetPlatformCrashKey();
#endif
if (IsBrowserProcess(command_line)) {
// Only append arguments for browser process.
// Allow file:// URIs to read other file:// URIs by default.
command_line->AppendSwitch(::switches::kAllowFileAccessFromFiles);
#if defined(OS_MACOSX)
// Enable AVFoundation.
command_line->AppendSwitch("enable-avfoundation");
// Enable AVFoundation.
command_line->AppendSwitch("enable-avfoundation");
#endif
}
}
void ElectronMainDelegate::PreCreateMainMessageLoop() {
@@ -350,4 +425,20 @@ bool ElectronMainDelegate::ShouldLockSchemeRegistry() {
return false;
}
#if defined(OS_LINUX)
void ElectronMainDelegate::ZygoteForked() {
// Needs to be called after we have DIR_USER_DATA. BrowserMain sets
// this up for the browser process in a different manner.
ElectronCrashReporterClient::Create();
const base::CommandLine* command_line =
base::CommandLine::ForCurrentProcess();
std::string process_type =
command_line->GetSwitchValueASCII(::switches::kProcessType);
breakpad::InitCrashReporter(process_type);
// Reset the command line for the newly spawned process.
crash_keys::SetCrashKeysFromCommandLine(*command_line);
}
#endif // defined(OS_LINUX)
} // namespace electron

View File

@@ -41,6 +41,9 @@ class ElectronMainDelegate : public content::ContentMainDelegate {
const content::MainFunctionParams& main_function_params) override;
bool ShouldCreateFeatureList() override;
bool ShouldLockSchemeRegistry() override;
#if defined(OS_LINUX)
void ZygoteForked() override;
#endif
private:
#if defined(OS_MACOSX)

View File

@@ -15,6 +15,7 @@
#include "base/strings/sys_string_conversions.h"
#include "content/common/mac_helpers.h"
#include "content/public/common/content_paths.h"
#include "ppapi/buildflags/buildflags.h"
#include "shell/browser/mac/electron_application.h"
#include "shell/common/application_info.h"
#include "shell/common/mac/main_application_bundle.h"
@@ -40,9 +41,11 @@ base::FilePath GetHelperAppPath(const base::FilePath& frameworks_path,
} else if (base::EndsWith(path.value(), content::kMacHelperSuffix_gpu,
base::CompareCase::SENSITIVE)) {
helper_name += content::kMacHelperSuffix_gpu;
#if BUILDFLAG(ENABLE_PLUGINS)
} else if (base::EndsWith(path.value(), content::kMacHelperSuffix_plugin,
base::CompareCase::SENSITIVE)) {
helper_name += content::kMacHelperSuffix_plugin;
#endif
}
return frameworks_path.Append(name + " " + helper_name + ".app")

View File

@@ -4,29 +4,39 @@
#include "shell/app/node_main.h"
#include <map>
#include <memory>
#include <string>
#include <utility>
#include "base/base_switches.h"
#include "base/command_line.h"
#include "base/feature_list.h"
#include "base/task/thread_pool/thread_pool_instance.h"
#include "base/threading/thread_task_runner_handle.h"
#include "components/crash/core/app/crashpad.h"
#include "content/public/common/content_switches.h"
#include "electron/electron_version.h"
#include "gin/array_buffer.h"
#include "gin/public/isolate_holder.h"
#include "gin/v8_initializer.h"
#include "shell/app/electron_crash_reporter_client.h"
#include "shell/app/uv_task_runner.h"
#include "shell/browser/api/electron_api_crash_reporter.h"
#include "shell/browser/javascript_environment.h"
#include "shell/browser/node_debugger.h"
#include "shell/common/api/electron_bindings.h"
#include "shell/common/crash_reporter/crash_reporter.h"
#include "shell/common/crash_keys.h"
#include "shell/common/gin_helper/dictionary.h"
#include "shell/common/node_bindings.h"
#include "shell/common/node_includes.h"
#if defined(_WIN64)
#include "shell/common/crash_reporter/crash_reporter_win.h"
#if defined(OS_LINUX)
#include "components/crash/core/app/breakpad_linux.h"
#endif
#if defined(OS_WIN)
#include "chrome/child/v8_crashpad_support_win.h"
#endif
namespace {
@@ -42,19 +52,64 @@ bool AllowWasmCodeGenerationCallback(v8::Local<v8::Context> context,
namespace electron {
#if !defined(OS_LINUX)
void AddExtraParameter(const std::string& key, const std::string& value) {
crash_reporter::CrashReporter::GetInstance()->AddExtraParameter(key, value);
}
#if defined(OS_LINUX)
void CrashReporterStart(gin_helper::Dictionary options) {
std::string submit_url;
bool upload_to_server = true;
bool ignore_system_crash_handler = false;
bool rate_limit = false;
bool compress = false;
std::map<std::string, std::string> global_extra;
std::map<std::string, std::string> extra;
options.Get("submitURL", &submit_url);
options.Get("uploadToServer", &upload_to_server);
options.Get("ignoreSystemCrashHandler", &ignore_system_crash_handler);
options.Get("rateLimit", &rate_limit);
options.Get("compress", &compress);
options.Get("extra", &extra);
options.Get("globalExtra", &global_extra);
void RemoveExtraParameter(const std::string& key) {
crash_reporter::CrashReporter::GetInstance()->RemoveExtraParameter(key);
std::string product_name;
if (options.Get("productName", &product_name))
global_extra["_productName"] = product_name;
std::string company_name;
if (options.Get("companyName", &company_name))
global_extra["_companyName"] = company_name;
api::crash_reporter::Start(submit_url, upload_to_server,
ignore_system_crash_handler, rate_limit, compress,
global_extra, extra, true);
}
#endif
v8::Local<v8::Value> GetParameters(v8::Isolate* isolate) {
std::map<std::string, std::string> keys;
#if !defined(MAS_BUILD)
electron::crash_keys::GetCrashKeys(&keys);
#endif
return gin::ConvertToV8(isolate, keys);
}
int NodeMain(int argc, char* argv[]) {
base::CommandLine::Init(argc, argv);
#if defined(OS_WIN)
v8_crashpad_support::SetUp();
#endif
#if !defined(MAS_BUILD)
ElectronCrashReporterClient::Create();
#endif
#if defined(OS_WIN) || (defined(OS_MACOSX) && !defined(MAS_BUILD))
crash_reporter::InitializeCrashpad(false, "node");
#endif
#if !defined(MAS_BUILD)
crash_keys::SetCrashKeysFromCommandLine(
*base::CommandLine::ForCurrentProcess());
crash_keys::SetPlatformCrashKey();
#endif
int exit_code = 1;
{
// Feed gin::PerIsolateData with a task runner.
@@ -68,10 +123,6 @@ int NodeMain(int argc, char* argv[]) {
feature_list->InitializeFromCommandLine("", "");
base::FeatureList::SetInstance(std::move(feature_list));
#if defined(_WIN64)
crash_reporter::CrashReporterWin::SetUnhandledExceptionFilter();
#endif
// Explicitly register electron's builtin modules.
NodeBindings::RegisterBuiltinModules();
@@ -122,13 +173,15 @@ int NodeMain(int argc, char* argv[]) {
// Setup process.crashReporter.start in child node processes
gin_helper::Dictionary reporter = gin::Dictionary::CreateEmpty(isolate);
reporter.SetMethod("start", &crash_reporter::CrashReporter::StartInstance);
#if !defined(OS_LINUX)
reporter.SetMethod("addExtraParameter", &AddExtraParameter);
reporter.SetMethod("removeExtraParameter", &RemoveExtraParameter);
#if defined(OS_LINUX)
reporter.SetMethod("start", &CrashReporterStart);
#endif
reporter.SetMethod("getParameters", &GetParameters);
reporter.SetMethod("addExtraParameter", &electron::crash_keys::SetCrashKey);
reporter.SetMethod("removeExtraParameter",
&electron::crash_keys::ClearCrashKey);
process.Set("crashReporter", reporter);
gin_helper::Dictionary versions;

View File

@@ -10,7 +10,7 @@
#include "base/callback.h"
#include "base/location.h"
#include "base/single_thread_task_runner.h"
#include "uv.h" // NOLINT(build/include)
#include "uv.h" // NOLINT(build/include_directory)
namespace electron {

View File

@@ -39,11 +39,11 @@
#include "shell/browser/api/gpuinfo_manager.h"
#include "shell/browser/electron_browser_context.h"
#include "shell/browser/electron_browser_main_parts.h"
#include "shell/browser/electron_paths.h"
#include "shell/browser/login_handler.h"
#include "shell/browser/relauncher.h"
#include "shell/common/application_info.h"
#include "shell/common/electron_command_line.h"
#include "shell/common/electron_paths.h"
#include "shell/common/gin_converters/callback_converter.h"
#include "shell/common/gin_converters/file_path_converter.h"
#include "shell/common/gin_converters/gurl_converter.h"
@@ -403,6 +403,8 @@ int GetPathConstant(const std::string& name) {
return DIR_USER_CACHE;
else if (name == "logs")
return DIR_APP_LOGS;
else if (name == "crashDumps")
return DIR_CRASH_DUMPS;
else if (name == "home")
return base::DIR_HOME;
else if (name == "temp")

View File

@@ -6,7 +6,7 @@
#include "base/path_service.h"
#include "shell/browser/api/electron_api_app.h"
#include "shell/browser/electron_paths.h"
#include "shell/common/electron_paths.h"
#import <Cocoa/Cocoa.h>

View File

@@ -9,28 +9,12 @@
#include "shell/browser/native_window.h"
#include "shell/browser/window_list.h"
#include "shell/common/gin_converters/callback_converter.h"
#include "shell/common/gin_converters/time_converter.h"
#include "shell/common/gin_helper/dictionary.h"
#include "shell/common/gin_helper/event_emitter_caller.h"
#include "shell/common/gin_helper/object_template_builder.h"
#include "shell/common/node_includes.h"
namespace gin {
template <>
struct Converter<base::Time> {
static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
const base::Time& val) {
v8::MaybeLocal<v8::Value> date =
v8::Date::New(isolate->GetCurrentContext(), val.ToJsTime());
if (date.IsEmpty())
return v8::Null(isolate);
else
return date.ToLocalChecked();
}
};
} // namespace gin
namespace electron {
namespace api {

View File

@@ -0,0 +1,216 @@
// Copyright (c) 2013 GitHub, 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_crash_reporter.h"
#include <limits>
#include <map>
#include <string>
#include <utility>
#include <vector>
#include "base/bind.h"
#include "base/command_line.h"
#include "base/no_destructor.h"
#include "base/path_service.h"
#include "base/strings/utf_string_conversions.h"
#include "base/threading/thread_restrictions.h"
#include "chrome/browser/crash_upload_list/crash_upload_list_crashpad.h"
#include "chrome/common/chrome_paths.h"
#include "components/crash/core/app/crashpad.h"
#include "components/crash/core/common/crash_key.h"
#include "components/upload_list/crash_upload_list.h"
#include "components/upload_list/text_log_upload_list.h"
#include "content/public/common/content_switches.h"
#include "gin/arguments.h"
#include "gin/data_object_builder.h"
#include "services/service_manager/embedder/switches.h"
#include "shell/app/electron_crash_reporter_client.h"
#include "shell/common/crash_keys.h"
#include "shell/common/electron_paths.h"
#include "shell/common/gin_converters/callback_converter.h"
#include "shell/common/gin_converters/file_path_converter.h"
#include "shell/common/gin_converters/time_converter.h"
#include "shell/common/gin_helper/dictionary.h"
#include "shell/common/node_includes.h"
#include "third_party/crashpad/crashpad/client/crashpad_info.h"
#if defined(OS_LINUX)
#include "components/crash/core/app/breakpad_linux.h"
#include "v8/include/v8-wasm-trap-handler-posix.h"
#include "v8/include/v8.h"
#endif
namespace {
#if defined(OS_LINUX)
std::map<std::string, std::string>& GetGlobalCrashKeysMutable() {
static base::NoDestructor<std::map<std::string, std::string>>
global_crash_keys;
return *global_crash_keys;
}
#endif // defined(OS_LINUX)
bool g_crash_reporter_initialized = false;
} // namespace
namespace electron {
namespace api {
namespace crash_reporter {
bool IsCrashReporterEnabled() {
return g_crash_reporter_initialized;
}
#if defined(OS_LINUX)
const std::map<std::string, std::string>& GetGlobalCrashKeys() {
return GetGlobalCrashKeysMutable();
}
#endif
void Start(const std::string& submit_url,
bool upload_to_server,
bool ignore_system_crash_handler,
bool rate_limit,
bool compress,
const std::map<std::string, std::string>& global_extra,
const std::map<std::string, std::string>& extra,
bool is_node_process) {
#if !defined(MAS_BUILD)
if (g_crash_reporter_initialized)
return;
g_crash_reporter_initialized = true;
ElectronCrashReporterClient::Create();
ElectronCrashReporterClient::Get()->SetUploadUrl(submit_url);
ElectronCrashReporterClient::Get()->SetCollectStatsConsent(upload_to_server);
ElectronCrashReporterClient::Get()->SetShouldRateLimit(rate_limit);
ElectronCrashReporterClient::Get()->SetShouldCompressUploads(compress);
ElectronCrashReporterClient::Get()->SetGlobalAnnotations(global_extra);
auto* command_line = base::CommandLine::ForCurrentProcess();
std::string process_type =
is_node_process
? "node"
: command_line->GetSwitchValueASCII(::switches::kProcessType);
#if defined(OS_LINUX)
auto& global_crash_keys = GetGlobalCrashKeysMutable();
for (const auto& pair : global_extra) {
global_crash_keys[pair.first] = pair.second;
}
for (const auto& pair : extra)
electron::crash_keys::SetCrashKey(pair.first, pair.second);
for (const auto& pair : global_extra)
electron::crash_keys::SetCrashKey(pair.first, pair.second);
breakpad::InitCrashReporter(process_type);
#elif defined(OS_MACOSX)
for (const auto& pair : extra)
electron::crash_keys::SetCrashKey(pair.first, pair.second);
::crash_reporter::InitializeCrashpad(process_type.empty(), process_type);
if (ignore_system_crash_handler) {
crashpad::CrashpadInfo::GetCrashpadInfo()
->set_system_crash_reporter_forwarding(crashpad::TriState::kDisabled);
}
#elif defined(OS_WIN)
for (const auto& pair : extra)
electron::crash_keys::SetCrashKey(pair.first, pair.second);
base::FilePath user_data_dir;
base::PathService::Get(DIR_USER_DATA, &user_data_dir);
::crash_reporter::InitializeCrashpadWithEmbeddedHandler(
process_type.empty(), process_type,
base::UTF16ToUTF8(user_data_dir.value()), base::FilePath());
#endif
#endif
}
} // namespace crash_reporter
} // namespace api
} // namespace electron
namespace {
#if defined(MAS_BUILD)
void GetUploadedReports(
base::OnceCallback<void(v8::Local<v8::Value>)> callback) {
std::move(callback).Run(v8::Array::New(v8::Isolate::GetCurrent()));
}
#else
scoped_refptr<UploadList> CreateCrashUploadList() {
#if defined(OS_MACOSX) || defined(OS_WIN)
return new CrashUploadListCrashpad();
#else
base::FilePath crash_dir_path;
base::PathService::Get(electron::DIR_CRASH_DUMPS, &crash_dir_path);
base::FilePath upload_log_path =
crash_dir_path.AppendASCII(CrashUploadList::kReporterLogFilename);
return new TextLogUploadList(upload_log_path);
#endif // defined(OS_MACOSX) || defined(OS_WIN)
}
v8::Local<v8::Value> GetUploadedReports(v8::Isolate* isolate) {
auto list = CreateCrashUploadList();
// TODO(nornagon): switch to using Load() instead of LoadSync() once the
// synchronous version of getUploadedReports is deprecated so we can remove
// our patch.
{
base::ThreadRestrictions::ScopedAllowIO allow_io;
list->LoadSync();
}
std::vector<UploadList::UploadInfo> uploads;
constexpr size_t kMaxUploadReportsToList = std::numeric_limits<size_t>::max();
list->GetUploads(kMaxUploadReportsToList, &uploads);
std::vector<v8::Local<v8::Object>> result;
for (const auto& upload : uploads) {
result.push_back(gin::DataObjectBuilder(isolate)
.Set("date", upload.upload_time)
.Set("id", upload.upload_id)
.Build());
}
v8::Local<v8::Value> v8_result = gin::ConvertToV8(isolate, result);
return v8_result;
}
#endif
void SetUploadToServer(bool upload) {
#if !defined(MAS_BUILD)
ElectronCrashReporterClient::Get()->SetCollectStatsConsent(upload);
#endif
}
bool GetUploadToServer() {
#if defined(MAS_BUILD)
return false;
#else
return ElectronCrashReporterClient::Get()->GetCollectStatsConsent();
#endif
}
v8::Local<v8::Value> GetParameters(v8::Isolate* isolate) {
std::map<std::string, std::string> keys;
#if !defined(MAS_BUILD)
electron::crash_keys::GetCrashKeys(&keys);
#endif
return gin::ConvertToV8(isolate, keys);
}
void Initialize(v8::Local<v8::Object> exports,
v8::Local<v8::Value> unused,
v8::Local<v8::Context> context,
void* priv) {
gin_helper::Dictionary dict(context->GetIsolate(), exports);
dict.SetMethod("start", &electron::api::crash_reporter::Start);
dict.SetMethod("addExtraParameter", &electron::crash_keys::SetCrashKey);
dict.SetMethod("removeExtraParameter", &electron::crash_keys::ClearCrashKey);
dict.SetMethod("getParameters", &GetParameters);
dict.SetMethod("getUploadedReports", &GetUploadedReports);
dict.SetMethod("setUploadToServer", &SetUploadToServer);
dict.SetMethod("getUploadToServer", &GetUploadToServer);
}
} // namespace
NODE_LINKED_MODULE_CONTEXT_AWARE(atom_browser_crash_reporter, Initialize)

View File

@@ -0,0 +1,40 @@
// Copyright (c) 2020 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_CRASH_REPORTER_H_
#define SHELL_BROWSER_API_ELECTRON_API_CRASH_REPORTER_H_
#include <map>
#include <string>
#include "base/files/file_path.h"
namespace electron {
namespace api {
namespace crash_reporter {
bool IsCrashReporterEnabled();
#if defined(OS_LINUX)
const std::map<std::string, std::string>& GetGlobalCrashKeys();
#endif
// JS bindings API; exposed publicly because it's also called from node_main.cc
void Start(const std::string& submit_url,
bool upload_to_server,
bool ignore_system_crash_handler,
bool rate_limit,
bool compress,
const std::map<std::string, std::string>& global_extra,
const std::map<std::string, std::string>& extra,
bool is_node_process);
} // namespace crash_reporter
} // namespace api
} // namespace electron
#endif // SHELL_BROWSER_API_ELECTRON_API_CRASH_REPORTER_H_

View File

@@ -684,10 +684,16 @@ void TopLevelWindow::SetMenu(v8::Isolate* isolate, v8::Local<v8::Value> value) {
gin::V8ToString(isolate, object->GetConstructorName()) == "Menu" &&
gin::ConvertFromV8(isolate, value, &menu) && !menu.IsEmpty()) {
menu_.Reset(isolate, menu.ToV8());
window_->SetMenu(menu->model());
// We only want to update the menu if the menu has a non-zero item count,
// or we risk crashes.
if (menu->model()->GetItemCount() == 0) {
RemoveMenu();
} else {
window_->SetMenu(menu->model());
}
} else if (value->IsNull()) {
menu_.Reset();
window_->SetMenu(nullptr);
RemoveMenu();
} else {
isolate->ThrowException(
v8::Exception::TypeError(gin::StringToV8(isolate, "Invalid Menu")));

View File

@@ -82,6 +82,7 @@
#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/language_util.h"
#include "shell/common/mouse_util.h"
#include "shell/common/node_includes.h"
#include "shell/common/options_switches.h"
@@ -91,6 +92,8 @@
#include "third_party/blink/public/mojom/favicon/favicon_url.mojom.h"
#include "third_party/blink/public/mojom/frame/find_in_page.mojom.h"
#include "third_party/blink/public/mojom/frame/fullscreen.mojom.h"
#include "third_party/blink/public/mojom/messaging/transferable_message.mojom.h"
#include "third_party/blink/public/mojom/renderer_preferences.mojom.h"
#include "ui/base/cursor/cursor.h"
#include "ui/base/mojom/cursor_type.mojom-shared.h"
#include "ui/display/screen.h"
@@ -112,7 +115,6 @@
#endif
#if defined(OS_LINUX) || defined(OS_WIN)
#include "third_party/blink/public/mojom/renderer_preferences.mojom.h"
#include "ui/gfx/font_render_params.h"
#endif
@@ -526,7 +528,22 @@ void WebContents::InitWithSessionAndOptions(
managed_web_contents()->GetView()->SetDelegate(this);
auto* prefs = web_contents()->GetMutableRendererPrefs();
prefs->accept_languages = g_browser_process->GetApplicationLocale();
// Collect preferred languages from OS and browser process. accept_languages
// effects HTTP header, navigator.languages, and CJK fallback font selection.
//
// Note that an application locale set to the browser process might be
// different with the one set to the preference list.
// (e.g. overridden with --lang)
std::string accept_languages =
g_browser_process->GetApplicationLocale() + ",";
for (auto const& language : electron::GetPreferredLanguages()) {
if (language == g_browser_process->GetApplicationLocale())
continue;
accept_languages += language + ",";
}
accept_languages.pop_back();
prefs->accept_languages = accept_languages;
#if defined(OS_LINUX) || defined(OS_WIN)
// Update font settings.

View File

@@ -34,7 +34,7 @@
#if BUILDFLAG(ENABLE_PRINTING)
#include "chrome/browser/printing/print_view_manager_basic.h"
#include "components/printing/common/print_messages.h"
#include "printing/backend/print_backend.h"
#include "printing/backend/print_backend.h" // nogncheck
#include "shell/browser/printing/print_preview_message_handler.h"
#if defined(OS_WIN)

View File

@@ -17,11 +17,11 @@
#include "base/threading/thread_task_runner_handle.h"
#include "shell/browser/browser_observer.h"
#include "shell/browser/electron_browser_main_parts.h"
#include "shell/browser/electron_paths.h"
#include "shell/browser/login_handler.h"
#include "shell/browser/native_window.h"
#include "shell/browser/window_list.h"
#include "shell/common/application_info.h"
#include "shell/common/electron_paths.h"
#include "shell/common/gin_helper/arguments.h"
namespace electron {

View File

@@ -57,7 +57,7 @@ class Browser : public WindowListObserver {
void Shutdown();
// Focus the application.
void Focus();
void Focus(gin_helper::Arguments* args);
// Returns the version of the executable (or bundle).
std::string GetVersion() const;

Some files were not shown because too many files have changed in this diff Show More